Author Topic: [FF7]getting player's position reliably  (Read 3971 times)

hay

  • *
  • Posts: 211
  • If I had a buggy, I'd cross the southern desert
    • View Profile
[FF7]getting player's position reliably
« on: 2018-01-14 02:50:01 »
Anyone got player's current field/world position/face direction reliably? I can see there's an address for faster walking on gamehacking.org and I've found camera format along with walkmesh in here http://q-gears.sourceforge.net/gears.pdf but I don't see much world map info there. Any help?
« Last Edit: 2018-01-14 03:28:27 by hay »

DLPB_

  • Banned
  • *
  • Posts: 11006
    • View Profile
Re: [FF7]getting player's position reliably
« Reply #1 on: 2018-01-14 12:34:57 »
My tool, Ochu, will do it. See tools.

hay

  • *
  • Posts: 211
  • If I had a buggy, I'd cross the southern desert
    • View Profile
Re: [FF7]getting player's position reliably
« Reply #2 on: 2018-01-14 17:08:13 »
Thanks, I'll poke it around.

hay

  • *
  • Posts: 211
  • If I had a buggy, I'd cross the southern desert
    • View Profile
Re: [FF7]getting player's position reliably
« Reply #3 on: 2018-01-15 03:44:13 »
That's the thing, thank you. I'm super impressed how far this modding scene have progressed.
I'll reverse Ochu if I have too, but before that it's worth to ask: any chance of finding it's source code or any references online? Pretty please, I need it HARD. Seriously, it's got about 15% of functonality I need, which would take me an assload of time to reverse.
« Last Edit: 2018-01-15 04:00:49 by hay »

DLPB_

  • Banned
  • *
  • Posts: 11006
    • View Profile
Re: [FF7]getting player's position reliably
« Reply #4 on: 2018-01-15 04:04:43 »
I don't really want to release all the source for it right now, but if you give me specifics, I can at least give you what you need.  The source is Delphi anyway, so may not be as much use to you as you think.

hay

  • *
  • Posts: 211
  • If I had a buggy, I'd cross the southern desert
    • View Profile
Re: [FF7]getting player's position reliably
« Reply #5 on: 2018-01-15 04:19:56 »
Fair enough, this could work even better. I'm no good with Delphi at all.

1. How do you triangulate which addresses to read for example for player's position? Are those fixed offsets every time game is launched, or do you use method of tracking them throughout address space? I assume you know the data layout of the allocated memory and I would like to know it too.

2. How do you triangulate data needed for the save state function? There's certain data arrangement and a way to reach it. Ochu is more stable than my GPU drivers so I assume you got this thing tight.


Let's assume Example 1 where I'd like to make a difficulty setting mod which would include respawns for easy levels. Before a fight I make a savestate, after failure I load it up.

Let's assume Example 2 where I'd like to make a fast-travel sort of mod which would allow player to speak to a certain inserted npc and be moved between fields in a predictable, static pattern.
« Last Edit: 2018-01-15 04:27:15 by hay »

hay

  • *
  • Posts: 211
  • If I had a buggy, I'd cross the southern desert
    • View Profile
Re: [FF7]getting player's position reliably
« Reply #6 on: 2018-01-15 08:01:59 »
I've taken a look at something promising http://blackchocobo.sourceforge.net/wiki/index.php?title=Savemap . But it's written that it's only for read reference.

Let's assume I'd like to rebuild the qhimm wiki along the way. Be rough with me, encyclopedic if you need.
« Last Edit: 2018-01-15 08:35:26 by hay »

DLPB_

  • Banned
  • *
  • Posts: 11006
    • View Profile
Re: [FF7]getting player's position reliably
« Reply #7 on: 2018-01-15 13:36:29 »
I am not sure what you mean by "triangulation".  There is no such thing here.  It's just reading values from static memory addresses.

It's too much messing to say how the savestate works - but suffice to say, I backup the Savemap and temp map
Code: [Select]
SaveMapArray: Array [0..$10F6] of byte;
LastSaveMapArray: Array [0..$10F6] of byte;

TempBankArray: Array [0..$FF] of byte;
LastTempBankArray: Array [0..$FF] of byte;

SaveMap = $DBFD38;  //Save map ends DC0E2C /Bank1/2 starts  DC08DC
TempBank = $CC14D0;

and then restore it before calling the operation that initiates a field / wm jump. The game engine does the rest.  This will never be fool proof, because the game engine was never designed to be loaded in-between scenes and so on.  It can break the game in certain places, but generally it works very well - especially for debugging purposes.  There is no easy method for "save state saving".  I invented my own format and procedure for doing it.

Code: [Select]
   Case TargetModule Of
        1: begin // Field to Field
           Wword($CC0D8A,pWord(@FieldArray[254]) ^); //Screen ID
           Wsint($CC0D8C,pLongint(@FieldArray[0 + (15 * CharacterID)])^ div 4096); //X
           Wsint($CC0D8E,pLongint(@FieldArray[4 + (15 * CharacterID)])^ div 4096); //Y
           Wword($CC0DAA,pWord(@FieldArray[12 + (15 * CharacterID)])^ );           //T
           Wbyte($CC0DAC,pByte(@FieldArray[14 + (15 * CharacterID)])^ );           //D
           end;

        3: Wword($CC0D8A, 45); // Set jump to World Map
        4: Wword($CC0D8A, 30); // Set jump to Submarine
        5: Wword($CC0D8A, 60); // Set jump to Snowfield
          else

        End;

      Wbyte($CC0D89, 1); // Initiate Field jump
     
      end else // Current location is world map
           if TargetModule = 1 then // World Map to Field
           begin
           Wword($CC0D8A,pWord(@FieldArray[254]) ^); //Screen ID
           Wsint($CC0D8C,pLongint(@FieldArray[0 + (15 * CharacterID)])^ div 4096); //X
           Wsint($CC0D8E,pLongint(@FieldArray[4 + (15 * CharacterID)])^ div 4096); //Y
           Wword($CC0DAA,pWord(@FieldArray[12 + (15 * CharacterID)])^ );           //T
           Wbyte($CC0DAC,pByte(@FieldArray[14 + (15 * CharacterID)])^ );           //D

           Wbyte($CC1644, 0); //may not be needed, but setting to 0 just in case.
           Wbyte($E3A884, 0); //This decides the type of jump. 00 = field/normal world map jump. 01 = Battle. 02 = fmv.
                               //Battle ID is set at E3A88C
           Wbyte($E045E4, 3); //Initiate wm jump - Wbyte($E045F0, 1);
                               // 03 = jump to field. 04 = jump to submerged submarine. 05 = Jump to World map.
           end;

I'd help more but I am really busy with The Reunion.

hay

  • *
  • Posts: 211
  • If I had a buggy, I'd cross the southern desert
    • View Profile
Re: [FF7]getting player's position reliably
« Reply #8 on: 2018-01-15 20:34:29 »
I am not sure what you mean by "triangulation".  There is no such thing here.  It's just reading values from static memory addresses.
A basic, few-step method of obtaining those addresses based on their neighbourhood or execution pattern. But I guess solid addresses are even better.


Code: [Select]
Wword($CC0D8A,pWord(@FieldArray[254]) ^); //Screen IDI assume:
Wword = write word function
$CC0D8A = target address
pWord = pointer to a word type
@FieldArray[254] = 254th element in field array?
^ = i have no idea what it does

Quote
I'd help more but I am really busy with The Reunion.
You've already helped quite a lot, thanks! But don't think I'll stop asking questions :D If there's any way I can work that back in some way, I might be useful sometimes.

DLPB_

  • Banned
  • *
  • Posts: 11006
    • View Profile
Re: [FF7]getting player's position reliably
« Reply #9 on: 2018-01-15 21:08:14 »
It's just part of my system for saving and retrieving stored values.  What counts are the base addresses.

hay

  • *
  • Posts: 211
  • If I had a buggy, I'd cross the southern desert
    • View Profile
Re: [FF7]getting player's position reliably
« Reply #10 on: 2018-01-15 21:11:12 »
Yeah, I get it, just wanted to be sure if I read that correctly.