16. Using custom memory zone fields
Let’s see for example the parameters of LoadCamera Script commands. I didn’t find any default memory zone fields in the sources that would refer to them. That is why I loaded Tomb4 data source into Trng Patcher, and then searched for “LoadCamera”. This is what I got:
4B0635: LoadCamera_Room:
4B0635: DB 0FFh,0,0
4B07D0: Mex_LoadCameras:
4B07D0: DB 'LOC_473BE0',0
533978: LoadCamera_SrcX:
533978: DD ?
53397C: LoadCamera_SrcY:
53397C: DD ?
533980: LoadCamera_SrcZ:
533980: DD ?
533984: LoadCameraTargetX:
533984: DD ?
533988: LoadCameraTargetY:
533988: DD ?
53398C: LoadCameraTargetZ:
53398C: DD ?
“Mex” means “message”, I don’t care about that field now, but the other fields are eventually the well-known fields of the LoadCamera Script command. (Src = source.)
DB means the field has a little size (B refers to BYTE), so it would be a BYTE or a char variable.
DD means the field has a big size (D refers to DWORD), so it would be a DWORD or an int variable.
We can carry these fields this way into Plugin_trng.cpp – let’s say for example LoadCamera_SrcX:
Code:
int *pLoadCamera_SrcX = (int*) 0x533978;
As you can see:
- LoadCamera_SrcX is treated like a pointer, it got a “*p” sign.
- As I said, it is an „int”. That is the size of *pLoadCamera_SrcX.
- 533978 field of Tomb4 data is referred with Sign 0x.
- “int” size also needs to be added for 533978, with *, in brackets.
Now you can use *pLoadCamera_SrcX (with *!) as the variable that hosts the “Source X” value of the loadcamera. – An example, which forces the “Timer” parameter value of the Flipeffect into this field:
Code:
case 502:
//new loadcamera
{
int *pLoadCamera_SrcX = (int*) 0x533978;
*pLoadCamera_SrcX = Timer;
}
break;
Notes:
- That free choice problem again, what I just said. I mean, for example, when I worked with Layer1 and Layer2 colors, I had to search for the proper fields in Tomb4 data, because the available Layer1/2 color fields in structures.h didn’t do what I wanted.
- An interesting situation:
Code:
typedef struct StrSlot {
WORD TotMesh; // 0
WORD IndexFirstMesh; // 2
int IndexFirstTree; // 4
int IndexFirstFrame; // 8
void *pProcInitialise; // 0C
void *pProcControl; // 10
void *pProcFloor; // 14
void *pProcCeiling; // 18
void *pProcDraw; // 1C
void *pProcCollision; // 20
WORD DistanceForMIP; // 24
WORD IndexFirstAnim; // 26
short Vitality; // 28
WORD DistanceDetectLara; // 2A
WORD ss_Unknown3; // 2C
WORD FootStep; // 2E
WORD TestGuard; // 30
WORD Flags; // 32 (FSLOT_ flags)
void *pProcDrawExtras; // 34
int ShatterableMeshes; // 38
int ss_Unknown5; // 3C
}SlotFields;
The “void” sign of “nothing”, “no size” looks odd for the structure elements. So if you work with them, then you need to follow the same trick, like:
Code:
GET.pSlot->pProcDrawExtras = (int*) 4613568;
I mean, the value of 4613568 (whatever it is, it is not important now) is naturally has some size, it cannot be “no size”, it needs an int or a DWORD size. We solved it with that (int*) sign.