diff --git a/.gitignore b/.gitignore
index 4bee27d..b5d4651 100644
--- a/.gitignore
+++ b/.gitignore
@@ -107,3 +107,6 @@ sub.bat
# Misc
changes.md
TODO.md
+.vimrc
+ed.bat
+
diff --git a/README.md b/README.md
index 92682a5..3f1d0a1 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@ At this moment, you can track the following:
* Player stats (HP, MP, RISK, STR, INT, AGL, range, walking/running speed)
* Player status effects
* Player location (area name, room name)
+* Enemy tracking (name, HP, MP)
* In-game timer (with 1 second precision)
* Kill List and Weapon Usage list
* Map and Chest completion (**real-time!**)
@@ -37,7 +38,7 @@ Currently, *VSTrack* can work with [ePSXe][epsxe-emulator] and [BizHawk][bizhawk
To use *VSTrack* you'll need:
* One of the supported emulators:
* **ePSXe** version *1.9.25* or *2.0.5*
- * **BizHawk** version *2.4.2*
+ * **BizHawk** version *2.6.1*
* Copy of the game:
* **Vagrant Story** NTSC-US version *(SLUS-01040)* 1
@@ -52,7 +53,7 @@ No installation is required. Just copy the executable into preffered folder, and
When you'll see the start menu, press key `1-3` to choose emulator version you're using to play the game, or `0` to exit. If your selection was correct, you should see some basic game information in the console window.
-Alternatively, you can pass preferred emulator number as a command-line parameter, so if you want to use *VSTrack* with `BizHawk 2.4.2`, type:
+Alternatively, you can pass preferred emulator number as a command-line parameter, so if you want to use *VSTrack* with `BizHawk 2.6.1`, type:
```bash
vstrack.exe 3
```
diff --git a/includes/vst_actors.h b/includes/vst_actors.h
new file mode 100644
index 0000000..af816e1
--- /dev/null
+++ b/includes/vst_actors.h
@@ -0,0 +1,345 @@
+#ifndef _VST_ACTORS_H
+#define _VST_ACTORS_H
+
+#define OFFSET_ACTOR_DATA_POINTERS 0x800F1928
+#define OFFSET_ACTOR_DATA_FIRST_NODE 0x8011f9f0
+#define MAX_ACTORS_NUMBER 15
+#define ACTORS_NAMES_LIST_LENGTH 108
+
+char *ActorsNamesList[ACTORS_NAMES_LIST_LENGTH] = { //
+ "Air Elemental", //
+ "Arch Dragon", //
+ "Ashley Riot", //
+ "Asura", //
+ "Bandit", //
+ "Basilisk", //
+ "Bat", //
+ "Bejart", //
+ "Blood Lizard", //
+ "Callo Merlose", //
+ "City Gaurd", //
+ "Crimson Blade", //
+ "Damascus Crab", //
+ "Damascus Golem", //
+ "Dao", //
+ "Dark Crusader", //
+ "Dark Dragon", //
+ "Dark Elemental", //
+ "Dark Skeleton", //
+ "Dark Eye", //
+ "Dead Crimson Blade", //
+ "Death", //
+ "Djinn", //
+ "Dragon", //
+ "Dragon Zombie", //
+ "Duane", //
+ "Duke Bardorba", //
+ "Dullahan", //
+ "Dummy", //
+ "Earth Dragon", //
+ "Earth Elemental", //
+ "Fire Elemental", //
+ "Flame Dragon", //
+ "Gargoyle", //
+ "Ghast", //
+ "Ghost", //
+ "Ghoul", //
+ "Giant Crab", //
+ "Goblin", //
+ "Goblin Leader", //
+ "Golem", //
+ "Goodwin", //
+ "Gremlin", //
+ "Grissom", //
+ "Guildenstern", //
+ "Harpy", //
+ "Hellhound", //
+ "Ichthious", //
+ "Ifrit", //
+ "Imp", //
+ "Iron Crab", //
+ "Iron Golem", //
+ "John Hardin", //
+ "Joshua Bardorba", //
+ "Kali", //
+ "Last Crusader", //
+ "Lich", //
+ "Lich Lord", //
+ "Lizardman", //
+ "Lord Joshua", //
+ "Mandel", //
+ "Marco Riot", //
+ "Marid", //
+ "Matrix Ashley", //
+ "Matrix Merlose", //
+ "Mimic", //
+ "Minotaur", //
+ "Minotaur Lord", //
+ "Minotaur Zombie", //
+ "Mullenkamp Soldier", // change 'ü' to 'u'?
+ "Mummy", //
+ "Neesa", //
+ "Nightmare", //
+ "Nightstalker", //
+ "Ogre", //
+ "Ogre Lord", //
+ "Ogre Zombie", //
+ "Orc", //
+ "Orc Leader", //
+ "Poison Slime", //
+ "Quicksilver", //
+ "Ravana", //
+ "Rosencrantz", //
+ "Sackheim", //
+ "Samantha", //
+ "Sarjik", //
+ "Shadow", //
+ "Shrieker", //
+ "Silver Wolf", //
+ "Skeleton", //
+ "Skeleton Knight", //
+ "Sky Dragon", //
+ "Slime", //
+ "Snow Dragon", //
+ "Stirge", //
+ "Sydney Losstarot", // probably not used in this form (look below)
+ "Sydney", //
+ "Tia Riot", //
+ "Tieger", //
+ "Water Elemental", //
+ "Wraith", //
+ "Wyvern", //
+ "Wyvern Knight", //
+ "Wyvern Queen", //
+ "Zombie", //
+ "Zombie Fighter", //
+ "Zombie Knight", //
+ "Zombie Mage"
+};
+
+void
+ReadActorPointer(u32 *ActorPointer, usize ActorNumber)
+{
+ usize BytesToRead = sizeof(u32);
+
+ ReadGameMemory(processID,
+ OFFSET_ACTOR_DATA_POINTERS + (ActorNumber * sizeof(u32)), BytesToRead,
+ ActorPointer);
+}
+
+void
+ReadActorData(actor_data *ActorData, u32 ActorPointer)
+{
+ usize BytesToRead = sizeof(actor_data);
+
+ ReadGameMemory(processID, (usize) ActorPointer, BytesToRead, ActorData);
+}
+
+void
+ReadNextActorPointer(u32 *ActorPointerCur, u32 *ActorPointerNext)
+{
+ actor_data ActorDataTemp;
+ ReadActorData(&ActorDataTemp, *ActorPointerCur);
+ *ActorPointerNext = ActorDataTemp.NextActorPtr;
+}
+
+BOOL
+IsActorNameValid(char *ActorName)
+{
+ for (int i = 0; i < ACTORS_NAMES_LIST_LENGTH; i++)
+ {
+
+ if (strcmp(ActorName, ActorsNamesList[i]) == 0)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+PrintActorsDataOld()
+{
+ sprintf(szBuffer, "\nACTIVE ACTORS:\n");
+ WriteToBackBuffer();
+
+ actor_data ActorData;
+ u32 ActorPointer = 0;
+ u32 ActiveActorMarker = 0;
+
+ // ReadActiveActorMarker(OFFSET_ACTIVE_ACTOR_MARKER, &ActiveActorMarker);
+ // sprintf(szBuffer, "ActiveActorMarker: 0x%x\n", ActiveActorMarker);
+ // WriteToBackBuffer();
+
+ for (int i = 2; i < MAX_ACTORS_NUMBER; i++)
+ {
+ ReadActorPointer(&ActorPointer, i);
+ if (ActorPointer)
+ {
+ ReadActorData(&ActorData, ActorPointer);
+
+ // u32 NameOffset = ActorPointer + (u32) offsetof(actor_data, Name);
+ ReadActorName(ActorData.NamePointer);
+
+ if (IsActorNameValid(ActorName))
+ {
+ u16 HPCur = ActorData.HPCur;
+ u16 HPMax = ActorData.HPMax;
+ u16 MPCur = ActorData.MPCur;
+ u16 MPMax = ActorData.MPMax;
+
+ if (GameStatus == GAME_STATUS_CUTSCENE && HPMax == 100 &&
+ MPMax == 100) // cutscene
+ {
+ return;
+ }
+
+ if (HPCur == 0)
+ {
+ continue;
+ }
+
+ sprintf(szBuffer, "%s -- ", ActorName);
+ WriteToBackBuffer();
+
+ sprintf(szBuffer, "HP %d/%d ", HPCur, HPMax);
+ WriteToBackBuffer();
+
+ if (MPMax > 0)
+ {
+ sprintf(szBuffer, "MP %d/%d ", MPCur, MPMax);
+ }
+
+ sprintf(szBuffer, "ADDR 0x%x ", ActorPointer);
+ WriteToBackBuffer();
+
+ sprintf(szBuffer, "\n");
+ WriteToBackBuffer();
+ }
+ }
+ }
+}
+
+void
+PrintActorsData()
+{
+ sprintf(szBuffer, "\nACTIVE ACTORS:\n");
+ WriteToBackBuffer();
+
+ actor_data ActorData;
+ u32 ActorPointerCur = OFFSET_ACTOR_DATA_POINTERS;
+ u32 ActorPointerNext = 0x000000;
+
+ // sprintf(szBuffer, "ADDR 0x%x\n", ActorPointerCur);
+ // WriteToBackBuffer();
+
+ ReadNextActorPointer(&ActorPointerCur, &ActorPointerNext);
+ while (ActorPointerNext)
+ {
+ ReadActorData(&ActorData, ActorPointerNext);
+
+ ReadActorName(ActorData.NamePointer);
+
+ u16 HPCur = ActorData.HPCur;
+ u16 HPMax = ActorData.HPMax;
+ u16 MPCur = ActorData.MPCur;
+ u16 MPMax = ActorData.MPMax;
+
+ if (GameStatus == GAME_STATUS_CUTSCENE && HPMax == 100 &&
+ MPMax == 100) // cutscene
+ {
+ return;
+ }
+
+ sprintf(szBuffer, "0x%x -- ", ActorPointerNext);
+ WriteToBackBuffer();
+
+ sprintf(szBuffer, "%s -- ", ActorName);
+ WriteToBackBuffer();
+
+ if (HPCur == 0)
+ {
+ sprintf(szBuffer, "Dead ");
+ WriteToBackBuffer();
+ }
+ else
+ {
+ sprintf(szBuffer, "HP %d/%d ", HPCur, HPMax);
+ WriteToBackBuffer();
+
+ if (MPMax > 0)
+ {
+ sprintf(szBuffer, "MP %d/%d ", MPCur, MPMax);
+ WriteToBackBuffer();
+ }
+ }
+ sprintf(szBuffer, "\n");
+ WriteToBackBuffer();
+
+ ActorPointerCur = ActorPointerNext;
+ ReadNextActorPointer(&ActorPointerCur, &ActorPointerNext);
+ }
+}
+
+void
+WriteActorsData()
+{
+ FILE *fpActorsData = fopen("game_data/map/enemy_data.txt", "w");
+
+ fprintf(fpActorsData, "Active Enemies\n");
+
+ actor_data ActorData;
+ // Use this one if you want to include player data:
+ // u32 ActorPointerCur = OFFSET_ACTOR_DATA_POINTERS;
+ u32 ActorPointerCur = OFFSET_ACTOR_DATA_FIRST_NODE;
+ u32 ActorPointerNext = 0x000000;
+
+ // sprintf(fpActorsData, "ADDR 0x%x\n", ActorPointerCur);
+ // WriteToBackBuffer();
+
+ ReadNextActorPointer(&ActorPointerCur, &ActorPointerNext);
+ while (ActorPointerNext)
+ {
+ ReadActorData(&ActorData, ActorPointerNext);
+
+ ReadActorName(ActorData.NamePointer);
+
+ u16 HPCur = ActorData.HPCur;
+ u16 HPMax = ActorData.HPMax;
+ u16 MPCur = ActorData.MPCur;
+ u16 MPMax = ActorData.MPMax;
+
+ if (GameStatus == GAME_STATUS_CUTSCENE && HPMax == 100 &&
+ MPMax == 100) // cutscene
+ {
+ return;
+ }
+
+ // fprintf(fpActorsData, "0x%x -- ", ActorPointerNext);
+
+ fprintf(fpActorsData, "%s -- ", ActorName);
+
+ if (HPCur == 0)
+ {
+ fprintf(fpActorsData, "Dead ");
+ }
+ else
+ {
+ fprintf(fpActorsData, "HP %d/%d ", HPCur, HPMax);
+
+ if (MPMax > 0)
+ {
+ fprintf(fpActorsData, "MP %d/%d ", MPCur, MPMax);
+ }
+ }
+ fprintf(fpActorsData, "\n");
+
+ ActorPointerCur = ActorPointerNext;
+ ReadNextActorPointer(&ActorPointerCur, &ActorPointerNext);
+ }
+
+ fclose(fpActorsData);
+}
+
+#endif
+
diff --git a/includes/vst_emulation.h b/includes/vst_emulation.h
index 7ea27d0..fd9c09c 100644
--- a/includes/vst_emulation.h
+++ b/includes/vst_emulation.h
@@ -6,11 +6,81 @@
// EMU_OFFSET = PSX_OFFSET + EMU_BASE_ADDRESS - PSX_TO_EMU
// PSX_OFFSET = PSX_TO_EMU + EMU_OFFSET - EMU_BASE_ADDRESS
-#define PSX_TO_EPSXE_1925 0x7F974960
-#define PSX_TO_EPSXE_2050 0x7F57DFE0
+#define PSX_TO_EPSXE_1925 0x7f974960
+#define PSX_TO_EPSXE_2050 0x7f57dfe0
-#define PSX_TO_BIZHAWK_2320 0x7FEE2780
-#define PSX_TO_BIZHAWK_2410 0x7FCF2070
-#define PSX_TO_BIZHAWK_2420 0x7FCF2070
+#define PSX_TO_BIZHAWK_2320 0x7fee2780
+#define PSX_TO_BIZHAWK_2410 0x7fcf2070
+#define PSX_TO_BIZHAWK_2420 0x7fcf2070
+#define PSX_TO_BIZHAWK_2520 0x7fcef080
+#define PSX_TO_BIZHAWK_2610 0x7fcef080
+
+// GameStatus flag:
+// 1=Normal,
+// 2=TargetSphere
+// 3=CutScene
+// 4=?
+// 5=MenuScreen
+// 6=QuickMenu
+// 7=FirstPersonView
+// 8=TrapPanel/HealPanel
+// 9=TreasureChest/Container
+// A=DrawingWeapon
+// B=OperateLockedDoor
+// C=?
+
+#define OFFSET_GAME_STATUS 0x800f196c
+
+#define GAME_STATUS_NORMAL 0x0001
+#define GAME_STATUS_BATTLE 0x0002
+#define GAME_STATUS_CUTSCENE 0x0003
+#define GAME_STATUS_MENU_SCREEN 0x0005
+#define GAME_STATUS_QUICK_MENU 0x0006
+#define GAME_STATUS_FP_VIEW 0x0007
+#define GAME_STATUS_ACTIVATE_PANEL 0x0008
+#define GAME_STATUS_OPEN_CONTAINER 0x0009
+#define GAME_STATUS_DRAW_WEAPON 0x000a
+#define GAME_STATUS_USE_OPEN_DOOR 0x000b
+#define GAME_STATUS_END_OF_TURN 0x000c
+
+char *GameStatusNameList[17] = {
+ "Normal", // 1
+ "Battle", // 2
+ "Cut-scene", // 3
+ "???", // 4
+ "Menu Screen", // 5
+ "Quick Menu", // 6
+ "First Person View", // 7
+ "Activate Panel", // 8
+ "Open Container", // 9
+ "Draw Weapon", // 10
+ "Use Locked Door", // 11
+ "End of Turn", // 12
+ "???", // 13
+ "???", // 14
+ "???", // 15
+ "???", // 16
+ "???" // 17
+};
+
+void
+ReadGameStatus(u16 *GameStatus)
+{
+
+ usize BytesToRead = sizeof(u16);
+
+ ReadGameMemory(processID, OFFSET_GAME_STATUS, BytesToRead, GameStatus);
+}
+
+void
+PrintGameStatus(u16 *GameStatus)
+{
+ sprintf(szBuffer, "\nGAME STATUS:\n");
+ WriteToBackBuffer();
+
+ sprintf(szBuffer, "#%d -- %s\n", *GameStatus,
+ GameStatusNameList[*GameStatus - 1]);
+ WriteToBackBuffer();
+}
#endif
diff --git a/includes/vst_equipment.h b/includes/vst_equipment.h
index ac6118f..c7b0ada 100644
--- a/includes/vst_equipment.h
+++ b/includes/vst_equipment.h
@@ -750,7 +750,7 @@ PrintBladeLeveling(u8 BladeNumber)
default:
{
sprintf_s(
- szBuffer, _countof(szBuffer), "\n\nNo leveling weapon equipped\n\n");
+ szBuffer, _countof(szBuffer), "\nNo leveling weapon equipped\n\n");
WriteToBackBuffer();
}
}
diff --git a/includes/vst_gazette.h b/includes/vst_gazette.h
index 5982cb5..172353d 100644
--- a/includes/vst_gazette.h
+++ b/includes/vst_gazette.h
@@ -184,7 +184,7 @@ ReadKillList()
void
PrintKillList()
{
- sprintf_s(szBuffer, _countof(szBuffer), "\n== KILL LIST ==\n\n");
+ sprintf_s(szBuffer, _countof(szBuffer), "\nKILL LIST:\n");
WriteToBackBuffer();
sprintf_s(szBuffer, _countof(szBuffer), "Human: %5i\n", KillListCur.Human);
WriteToBackBuffer();
@@ -239,7 +239,7 @@ ReadWeaponUsage()
void
PrintWeaponUsage()
{
- sprintf_s(szBuffer, _countof(szBuffer), "\n== WEAPON USAGE ==\n\n");
+ sprintf_s(szBuffer, _countof(szBuffer), "\nWEAPON USAGE:\n");
WriteToBackBuffer();
sprintf_s(szBuffer, _countof(szBuffer), "Dagger: %5i\n",
WeaponUsageCur.Dagger);
@@ -558,7 +558,7 @@ void
PrintChestCount(u8 *ChestCount)
{
u16 ChestCountScore = (*ChestCount * 100) / CHEST_COUNT_MAX;
- sprintf_s(szBuffer, _countof(szBuffer), "\n\n== CHEST COUNT ==\n\n");
+ sprintf_s(szBuffer, _countof(szBuffer), "\nCHEST COUNT:\n");
WriteToBackBuffer();
sprintf_s(szBuffer, _countof(szBuffer), "%i/%i ( %i%% )\n", *ChestCount,
@@ -585,7 +585,7 @@ void
PrintMapCount(u16 *MapCount)
{
u16 MapCountScore = (*MapCount * 100) / MAP_COUNT_MAX;
- sprintf_s(szBuffer, _countof(szBuffer), "\n\n== ROOM COUNT ==\n\n");
+ sprintf_s(szBuffer, _countof(szBuffer), "\nROOM COUNT:\n");
WriteToBackBuffer();
sprintf_s(szBuffer, _countof(szBuffer), "%i/%i ( %i%% )\n", *MapCount,
@@ -608,4 +608,4 @@ WriteMapCount(u16 *MapCount)
fclose(fpMapCount);
}
-#endif
\ No newline at end of file
+#endif
diff --git a/includes/vst_init.h b/includes/vst_init.h
index 6e15e16..d36c8c3 100644
--- a/includes/vst_init.h
+++ b/includes/vst_init.h
@@ -14,6 +14,8 @@ char szExeName[MAX_PATH];
// In-game data
+u16 GameStatus;
+
// Time
game_time GameTimeCur = { -1 };
game_time GameTimePrev = { -1 };
@@ -116,4 +118,11 @@ BOOL GameOver = FALSE; // set to TRUE when the last boss is dead
// Input
u16 ControllerInputCur;
u16 ControllerInputPrev;
+
+buttons_timers ButtonsTimers;
+
+// Actors in the room
+#define ACTOR_NAME_LENGTH 20
+char ActorName[ACTOR_NAME_LENGTH];
+
#endif
diff --git a/includes/vst_input.h b/includes/vst_input.h
index fa8d2ea..f53ef50 100644
--- a/includes/vst_input.h
+++ b/includes/vst_input.h
@@ -3,6 +3,7 @@
// Controller input
#define OFFSET_CONTROLLER_INPUT 0x8005E1C0
+#define OFFSET_BUTTONS_TIMERS 0x80055C90
#define MASK_CONTROLLER_INPUT_L2 0x0001
#define MASK_CONTROLLER_INPUT_R2 0x0002
@@ -68,12 +69,20 @@ ReadControllerInput(u16 *ControllerInput)
processID, OFFSET_CONTROLLER_INPUT, BytesToRead, ControllerInput);
}
+void
+ReadButtonsTimers(buttons_timers *ButtonsTimers)
+{
+ usize BytesToRead = sizeof(buttons_timers);
+
+ ReadGameMemory(processID, OFFSET_BUTTONS_TIMERS, BytesToRead, ButtonsTimers);
+}
+
void
PrintControllerInput(u16 *ControllerInput)
{
u16 Input = *ControllerInput;
- sprintf(szBuffer, "\n-- Controller Input --\n\n");
+ sprintf(szBuffer, "\nCONTROLLER INPUT:\n");
WriteToBackBuffer();
if (!Input) // if the register is empty, skip to the end
@@ -87,7 +96,8 @@ PrintControllerInput(u16 *ControllerInput)
{
if (ControllerInputMasks[i] & Input)
{
- sprintf(szBuffer, "%s ", ControllerInputNames[i]);
+ sprintf(szBuffer, "%s(%d) ", ControllerInputNames[i],
+ ButtonsTimers.Timers[i]);
WriteToBackBuffer();
}
}
@@ -95,6 +105,7 @@ PrintControllerInput(u16 *ControllerInput)
WriteToBackBuffer();
}
}
+
void
WriteControllerInput(u16 *ControllerInput)
{
diff --git a/includes/vst_location.h b/includes/vst_location.h
index 00fee1d..b810d36 100644
--- a/includes/vst_location.h
+++ b/includes/vst_location.h
@@ -566,7 +566,7 @@ PrintLocation()
u8 ZoneNumber = LocationCur.ZoneNumber;
u8 MapNumber = LocationCur.MapNumber;
- sprintf(szBuffer, "\n\n== LOCATION ==\n\n");
+ sprintf(szBuffer, "\n\nLOCATION:\n");
WriteToBackBuffer();
sprintf_s(szBuffer, _countof(szBuffer), "%s, %s ( Zone %i, Map %i )\n",
@@ -584,4 +584,4 @@ IsThisTheLastBossMap()
return FALSE;
}
-#endif
\ No newline at end of file
+#endif
diff --git a/includes/vst_player.h b/includes/vst_player.h
index 8788a0e..a6151f1 100644
--- a/includes/vst_player.h
+++ b/includes/vst_player.h
@@ -14,7 +14,7 @@
#define OFFSET_PLAYER_PTR_00_SHP_HDR 0x8011FA34 // ptr00ShpHdr
#define OFFSET_PLAYER_PTR_WEAPON_WEP_HDR 0x8011FA38 // ptrWeaponWEPHdr
#define OFFSET_PLAYER_PTR_00_SHP_DATA 0x8011FA3C // ptr00ShpData
-#define OFFSET_PLAYER_CHARACTER_NAME \
+#define OFFSET_PLAYER_CHARACTER_NAME \
0x8011FA40 // CharacterName $18str "Ashley Riot"
// Main stats
@@ -29,7 +29,7 @@
#define OFFSET_PLAYER_INT_ORIGINAL 0x8011FA68 // OriginalINT
#define OFFSET_PLAYER_AGL_EQUIPPED 0x8011FA6A // EquippedAGL
#define OFFSET_PLAYER_AGL_ORIGINAL 0x8011FA6C // OriginalAGL
-#define OFFSET_PLAYER_WALKING_SPEED_WITH_BOX \
+#define OFFSET_PLAYER_WALKING_SPEED_WITH_BOX \
0x8011FA71 // WalkingSpeedWhenCarryingBoxes
#define OFFSET_PLAYER_RUNNING_SPEED 0x8011FA73 // RunningSpeed
#define OFFSET_PLAYER_RANGE 0x8011FA78 // range
@@ -111,8 +111,8 @@ u32 StatusEffectMasks[32] = { //
void
ReadPlayerStats(player_stats *PlayerStats)
{
- usize Offset =
- (usize)(OFFSET_PLAYER_HP_CURRENT - PSX_TO_EMU + processBaseAddress);
+ // usize Offset =
+ // (usize)(OFFSET_PLAYER_HP_CURRENT - PSX_TO_EMU + processBaseAddress);
usize BytesToRead = sizeof(player_stats);
@@ -204,7 +204,7 @@ PrintPlayerStats(player_stats *PlayerStats)
AGL_Buff = '-';
}
- sprintf(szBuffer, "\n\n== PLAYER STATS ==\n\n");
+ sprintf(szBuffer, "\n\nPLAYER STATS:\n");
WriteToBackBuffer();
sprintf(szBuffer,
@@ -238,7 +238,7 @@ PrintPlayerEffects(status_effects *PlayerEffects)
{
status_effects Effects = *PlayerEffects;
- sprintf(szBuffer, "\n-- Status Effects --\n\n");
+ sprintf(szBuffer, "\nSTATUS EFFECTS:\n");
WriteToBackBuffer();
u32 StatusEffectMask = Effects.EffectID;
diff --git a/includes/vst_time.h b/includes/vst_time.h
index 337f713..509ac75 100644
--- a/includes/vst_time.h
+++ b/includes/vst_time.h
@@ -12,7 +12,7 @@ PrintGameTimeShort(game_time *GameTime)
u8 Minutes = GameTime->Minutes;
u8 Hours = GameTime->Hours;
- sprintf_s(szBuffer, _countof(szBuffer), "\n\n== GAME TIME ==\n\n");
+ sprintf_s(szBuffer, _countof(szBuffer), "\nGAME TIME:\n");
WriteToBackBuffer();
sprintf_s(szBuffer, _countof(szBuffer), "%02i:%02i:%02i\n", Hours, Minutes,
@@ -27,7 +27,7 @@ PrintGameTimeRecord(game_time *RecordTime)
u8 Minutes = RecordTime->Minutes;
u8 Hours = RecordTime->Hours;
- fprintf(stdout, "\n== RECORD TIME ==\n\n");
+ fprintf(stdout, "\nRECORD TIME:\n");
fprintf(stdout, "%02i:%02i:%02i\n", Hours, Minutes, Seconds);
}
@@ -101,4 +101,4 @@ IsItLater(game_time *TimeOld, game_time *TimeNew)
return New > Old;
}
-#endif
\ No newline at end of file
+#endif
diff --git a/includes/vst_translate.h b/includes/vst_translate.h
index 2bc7c81..e88cb79 100644
--- a/includes/vst_translate.h
+++ b/includes/vst_translate.h
@@ -22,7 +22,7 @@ char TranslationTableChars[125] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'Â', 'Ä', 'Ç', 'È', 'É', 'Ê', 'Ë',
'Ì', 'Î', 'Ò', 'Ó', 'Ô', 'Ö', 'Ù', 'Ú', 'Û', 'Ü', 'ß', 'æ', 'à', 'á', 'â',
'ä', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ò', 'ó', 'ô', 'ö', 'ù',
- 'ú', 'û', 'ü', ' ', '!', '"', '%', '\'', '(', ')', '{', '}', '[', ']', ';',
+ 'ú', 'û', 'u', ' ', '!', '"', '%', '\'', '(', ')', '{', '}', '[', ']', ';',
':', ',', '.', '/', '\\', '<', '>', '?', '-', '+', '\n' };
void
@@ -69,6 +69,44 @@ ReadWeaponName()
}
}
+void
+ReadActorName(u32 NameOffset)
+{
+ ActorName[0] = '\0';
+
+ char ActorNameHex[ACTOR_NAME_LENGTH];
+ usize BytesToRead = (usize) ACTOR_NAME_LENGTH;
+
+ usize BytesRead =
+ ReadGameMemory(processID, NameOffset, BytesToRead, ActorNameHex);
+
+ for (int i = 0, k = 0; i < ACTOR_NAME_LENGTH; ++i)
+ {
+ u8 *HexCode = (u8 *) &ActorNameHex[i];
+ if (*HexCode == 0xE7 || *HexCode == 0x00)
+ {
+ ActorName[k] = '\0';
+ break;
+ }
+
+ if (*HexCode == 0xFA && *(HexCode + 1) == 0x06)
+ {
+ ActorName[k++] = ' ';
+ i++;
+ continue;
+ }
+
+ for (int j = 0, size = _countof(TranslationTableHex); j < size; ++j)
+ {
+ if (TranslationTableHex[j] == (char) *HexCode)
+ {
+ ActorName[k++] = TranslationTableChars[j];
+ break;
+ }
+ }
+ }
+}
+
void
ReadWeaponNumber()
{
@@ -95,8 +133,8 @@ void
PrintWeaponName()
{
sprintf_s(
- szBuffer, _countof(szBuffer), "\n\nWeapon name: %s\n\n", nameWeaponCur);
+ szBuffer, _countof(szBuffer), "\nWEAPON NAME:\n%s\n", nameWeaponCur);
WriteToBackBuffer();
}
-#endif
\ No newline at end of file
+#endif
diff --git a/includes/vst_types.h b/includes/vst_types.h
index 07b0d19..34c2859 100644
--- a/includes/vst_types.h
+++ b/includes/vst_types.h
@@ -275,4 +275,69 @@ typedef struct
u8 Map;
} map_flag_check;
+/*
+#pragma pack(push, 1)
+typedef struct
+{
+ u32 L2;
+ u32 R2;
+ u32 L1;
+ u32 R1;
+ u32 Triangle;
+ u32 Circle;
+ u32 Cross;
+ u32 Square;
+ u32 Select;
+ u32 L3;
+ u32 R3;
+ u32 Start;
+ u32 Up;
+ u32 Right;
+ u32 Down;
+ u32 Left;
+} buttons_timers;
+#pragma pack(pop)
+*/
+
+#pragma pack(push, 1)
+typedef struct
+{
+ u32 Timers[16];
+} buttons_timers;
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+typedef struct
+{
+ u32 NextActorPtr; // 0
+ u8 _padding1[40]; // 4
+ u16 PosX; // 44 (0x2c)
+ u16 PosY; // 46 (0x2e)
+ u8 _padding2[12]; // 48 (0x30)
+ u32 NamePointer; // 60 (0x3c)
+ u8 _padding3[16]; // 64 (0x40)
+ char Name[20]; // 80 (0x50)
+ u8 _padding4[4]; // 100 (0x64)
+ u16 HPCur; // 104 (0x68)
+ u16 HPMax; // 106 (0x6a)
+ u16 MPCur; // 108 (0x6c)
+ u16 MPMax; // 110 (0x6e)
+ u16 Risk; // 112 (0x70)
+ u16 STRCur; // 114 (0x72)
+ u16 STRMax; // 116 (0x74)
+ u16 INTCur; // 118 (0x76)
+ u16 INTMax; // 120 (0x78)
+ u16 AGLCur; // 122 (0x7a)
+ u16 AGLMax; // 124 (0x7c)
+ u8 _padding5[14]; // 126 (0x7e)
+ char WeaponName[18]; // 140 (0x8c)
+} actor_data;
+#pragma pack(pop)
+
+typedef struct
+{
+ u32 ActorPointer;
+ BOOL IsDead;
+} actor_status;
+
#endif
diff --git a/main.c b/main.c
index 422bb2d..12eeb28 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -16,6 +17,7 @@
#include "includes/vst_time.h"
#include "includes/vst_player.h"
#include "includes/vst_input.h"
+#include "includes/vst_actors.h"
#include "includes/vst_location.h"
#include "includes/vst_gazette.h"
#include "includes/vst_debug.h"
@@ -37,7 +39,7 @@ main(int argc, char *argv[])
fprintf(stdout, "1. ePSXe 1.9.25\n");
fprintf(stdout, "2. ePSXe 2.0.50\n");
- fprintf(stdout, "3. BizHawk 2.4.2\n\n");
+ fprintf(stdout, "3. BizHawk 2.6.1\n\n");
fprintf(stdout, "0. Exit\n\n");
scanf_s("%2s", ver_s, (unsigned) _countof(ver_s));
@@ -75,7 +77,7 @@ main(int argc, char *argv[])
}
case 3:
{
- PSX_TO_EMU = PSX_TO_BIZHAWK_2420;
+ PSX_TO_EMU = PSX_TO_BIZHAWK_2610;
sprintf_s(szExeName, MAX_PATH, "EmuHawk.exe");
sprintf_s(szModuleName, MAX_PATH, "octoshock.dll");
break;
@@ -167,6 +169,11 @@ main(int argc, char *argv[])
GameTimePrev = GameTimeCur;
ReadGameTime(&GameTimeCur);
+ // GAME STATUS
+ ReadGameStatus(&GameStatus);
+#ifdef DEBUG
+ PrintGameStatus(&GameStatus);
+#endif
// Check if the time progressed
if (GameTimeChanged(&GameTimePrev, &GameTimeCur))
{
@@ -232,8 +239,11 @@ main(int argc, char *argv[])
WriteLocation();
}
#ifdef DEBUG
- PrintLocation();
+ // PrintLocation();
+ PrintActorsData();
#endif
+ // ACTORS IN THE ROOM
+ WriteActorsData();
// STATS
statsPlayerPrev = statsPlayerCur;
@@ -243,7 +253,7 @@ main(int argc, char *argv[])
WritePlayerStats(&statsPlayerCur);
}
#ifdef DEBUG
- PrintPlayerStats(&statsPlayerCur);
+ // PrintPlayerStats(&statsPlayerCur);
#endif
effectsPlayerPrev = effectsPlayerCur;
@@ -256,13 +266,13 @@ main(int argc, char *argv[])
#ifdef DEBUG
PrintPlayerEffects(&effectsPlayerCur);
#endif
-
+ ReadButtonsTimers(&ButtonsTimers);
ControllerInputPrev = ControllerInputCur;
ReadControllerInput(&ControllerInputCur);
- if (ControllerInputChanged())
- {
- WriteControllerInput(&ControllerInputCur);
- }
+ // if (ControllerInputChanged())
+ // {
+ // WriteControllerInput(&ControllerInputCur);
+ // }
#ifdef DEBUG
PrintControllerInput(&ControllerInputCur);
#endif
@@ -321,7 +331,7 @@ main(int argc, char *argv[])
#ifdef DEBUG
sprintf_s(
- szBuffer, _countof(szBuffer), "Weapon number: %zi\n", WeaponNumber);
+ szBuffer, _countof(szBuffer), "WEAPON NUMBER: %zi\n", WeaponNumber);
WriteToBackBuffer();
#endif
@@ -391,10 +401,9 @@ main(int argc, char *argv[])
}
else
{
-
sprintf_s(szBuffer, _countof(szBuffer),
"============================\n"
- "== VSTracker v0.3.3-alpha ==\n"
+ "== VSTracker v0.4.0-alpha ==\n"
"============================\n");
WriteToBackBuffer();
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..9cfd643
--- /dev/null
+++ b/makefile
@@ -0,0 +1,6 @@
+main.obj: main.c
+ cl /c /nologo /DDEBUG /Zi main.c
+vst.exe: main.obj
+ @cl main.c /Fe: vst /DDEBUG /nologo /Zi /link user32.lib psapi.lib Wtsapi32.lib Advapi32.lib
+ @echo Bulding and linking...
+