From daa093043fcca581cb65e36f203d8e243349e3b4 Mon Sep 17 00:00:00 2001 From: Zaarin Date: Fri, 4 Sep 2026 11:03:08 +0200 Subject: [PATCH 1/6] WIP --- config/sym_extern.us.txt | 13 +- config/sym_ovl_export.us.txt | 6 +- config/symbols.field.us.txt | 10 +- include/game.h | 43 ++- include/psxsdk/libgpu.h | 7 +- src/field/field.c | 2 - src/field/field2.c | 10 +- src/field/field_event.c | 489 ++++++++++++++++++++++++++++++++--- src/field/field_opcodes.c | 79 +++--- src/field/field_private.h | 19 +- 10 files changed, 575 insertions(+), 103 deletions(-) diff --git a/config/sym_extern.us.txt b/config/sym_extern.us.txt index 73e3f8b7..1214267c 100644 --- a/config/sym_extern.us.txt +++ b/config/sym_extern.us.txt @@ -8,6 +8,7 @@ g_RewardMenuTable = 0x800697EC; g_EntityToLine = 0x8007078C; g_BattleMode = 0x800707BE; g_FieldScriptSyncWaitEntity = 0x80071A88; +g_PosCursorDisabled = 0x80071C1C; g_FieldMusicLock = 0x800716D4; g_FieldWaitCounter = 0x800716DC; g_SavedFieldScriptPC = 0x80071748; @@ -17,25 +18,26 @@ g_CurrentEntity = 0x800722C4; D_800730CC = 0x800730CC; g_MateriaData = 0x800730D0; g_FieldMapVars = 0x80075E24; +g_FieldModelAnimStatus = 0x800756E8; g_FieldText = 0x8007E7A8; g_FieldLines = 0x8007E7AC; g_EntityToModel = 0x8007EB98; g_EntitySplitJoinState = 0x80081D90; g_CharacterLock = 0x80081DC4; +g_FieldModelEffAnimSpeed = 0x80082248; g_FieldScriptPC = 0x800831FC; +g_FieldModelAnimId = 0x8008325C; g_WindowToEntity = 0x8008326C; g_WindowData = 0x80083274; g_FieldScriptSyncState = 0x800833F8; g_FieldLineCount = 0x80095D84; +g_FieldPaletteBuffer = 0x80095DE0; D_80099788 = 0x80099788; D_8009A000 = 0x8009A000; D_8009A004 = 0x8009A004; D_8009A008 = 0x8009A008; D_8009A00C = 0x8009A00C; g_PartyMenuTables = 0x8009A0C8; -g_ActiveCharacters = 0x8009D84C; -g_CharacterLevelData = 0x8009D7E4; -g_BattleItemsEarned = 0x8009D808; g_FieldScriptPriority = 0x8009A1C4; g_FieldState = 0x8009ABF4; g_CharIdToEntity = 0x8009AD30; @@ -44,7 +46,10 @@ g_FieldModelCount = 0x8009C6C4; g_FieldScripts = 0x8009C6DC; g_pFieldState = 0x8009C6E0; Savemap = 0x8009C6E4; +g_CharacterLevelData = 0x8009D7E4; +g_BattleItemsEarned = 0x8009D808; g_DebugLevel = 0x8009D820; +g_FieldModelBaseAnimSpeed = 0x8009D828; func_800A0000 = 0x800A0000; func_800A0030 = 0x800A0030; func_800A00BC = 0x800A00BC; @@ -94,10 +99,10 @@ D_800708C4 = 0x800708C4; D_80082268 = 0x80082268; D_80082460 = 0x80082460; D_80082484 = 0x80082484; +D_8009D58A = 0x8009D58A; D_8009D7D8 = 0x8009D7D8; D_8009D7DC = 0x8009D7DC; D_8009D7E0 = 0x8009D7E0; D_8009D7ED = 0x8009D7ED; D_8009D7EE = 0x8009D7EE; -D_8009D58A = 0x8009D58A; D_80167938 = 0x80167938; diff --git a/config/sym_ovl_export.us.txt b/config/sym_ovl_export.us.txt index ddf91d64..8aee2c33 100644 --- a/config/sym_ovl_export.us.txt +++ b/config/sym_ovl_export.us.txt @@ -1512,9 +1512,9 @@ FieldEnablePartyModels = 0x800bb1b4; FieldEventOpcodeCycle = 0x800bb3a8; FieldUpdateAnimationState = 0x800bbbcc; FieldEventRequestRun = 0x800bbf74; -ResetFieldRenderState = 0x800bc338; -UpdateFieldExitArrows = 0x800bc438; -DrawFieldExitArrow = 0x800bc4d4; +ResetPositionCursorPrimitives = 0x800bc338; +UpdatePositionCursor = 0x800bc438; +DrawPositionCursor = 0x800bc4d4; DebugUpdateActor = 0x800bc9fc; DebugPrintOpcode = 0x800bead4; FieldDebugAddParseValueToPage2 = 0x800beca4; diff --git a/config/symbols.field.us.txt b/config/symbols.field.us.txt index 6620af0f..dcc31213 100644 --- a/config/symbols.field.us.txt +++ b/config/symbols.field.us.txt @@ -189,9 +189,9 @@ FieldEnablePartyModels = 0x800BB1B4; FieldEventOpcodeCycle = 0x800BB3A8; FieldUpdateAnimationState = 0x800BBBCC; FieldEventRequestRun = 0x800BBF74; -ResetFieldRenderState = 0x800BC338; -UpdateFieldExitArrows = 0x800BC438; -DrawFieldExitArrow = 0x800BC4D4; +ResetPositionCursorPrimitives = 0x800BC338; +UpdatePositionCursor = 0x800BC438; +DrawPositionCursor = 0x800BC4D4; DebugUpdateActor = 0x800BC9FC; DebugPrintOpcode = 0x800BEAD4; FieldDebugAddParseValueToPage2 = 0x800BECA4; @@ -545,6 +545,7 @@ g_DebugMessageBuffer = 0x800E4288; g_FieldRain = 0x800E42D8; // size:0x600 g_RainForce = 0x800E48D8; g_EntityForSplitJoin = 0x800E48F0; +g_PosCursorPrims = 0x800E48F4; // size:0x50 g_WindowString = 0x800E4944; // size:0x400 g_FieldMoviePlayed = 0x800E4D44; g_WindowReplaceBankAddr = 0x800E4D48; @@ -553,7 +554,10 @@ g_WindowExtraRows = 0x801142CC; // size:0x8 SavedScriptIds = 0x801142D4; // size:0x180 g_FieldKeyState = 0x80114454; //size:0x4 g_WindowWaitTime = 0x8011445C; +g_PosCursorX = 0x80114464; +g_PosCursorY = 0x80114468; g_WindowTextBudget = 0x80114470; // size:0x8 g_WindowFastForwardLevel = 0x80114480; // size:0x8 +g_PosCursorPrimId = 0x80114490; g_WindowBuffer = 0x801144DC; // size:0x40 g_WindowBufferPos = 0x8011451C; // size:0x8 diff --git a/include/game.h b/include/game.h index 01c646a0..8a6e5976 100644 --- a/include/game.h +++ b/include/game.h @@ -177,6 +177,20 @@ typedef enum { WSTATE_WAIT_NEXT_WINDOW, } WindowState; +typedef enum { + ANIMSTATUS_DEFAULT_LOOP, // Loop and track animId/effAnimSpeed. + ANIMSTATUS_SCRIPTED_LOOP, // Loop current requested animation without + // re-tracking defaults. + ANIMSTATUS_PLAY_ONCE_SYNC, // Blocking one-shot. + ANIMSTATUS_HOLD_FRAME, // Freeze on last frame. + ANIMSTATUS_PLAY_ONCE_SYNC_DONE, // Blocking one-shot finished, waiting for + // script-side consumption. + ANIMSTATUS_PLAY_ONCE_THEN_RESET, // Non-blocking one-shot, return to + // DEFAULT_LOOP when done. + ANIMSTATUS_PLAY_ONCE_THEN_HOLD, // Non-blocking one-shot, go to HOLD_FRAME + // when done. +} ModelAnimationStatus; + typedef struct { s16 x1; s16 y1; @@ -840,14 +854,14 @@ typedef struct { u8 unk67; // Uses PADx macros in libetc.h // Raw states ignore custom key mapping set by player. - u32 activeKeysRaw; // Currently active keys. - u32 activeKeysPrevRaw; // activeKeysRaw from last frame. - u32 pressedKeysRaw; // Was inactive last frame. - u32 releasedKeysRaw; // Was active last frame. - u32 activeKeys; - u32 activeKeysPrev; - u32 pressedKeys; - u32 releasedKeys; + s32 activeKeysRaw; // Currently active keys. + s32 activeKeysPrevRaw; // activeKeysRaw from last frame. + s32 pressedKeysRaw; // Was inactive last frame. + s32 releasedKeysRaw; // Was active last frame. + s32 activeKeys; + s32 activeKeysPrev; + s32 pressedKeys; + s32 releasedKeys; s16 currentMovieFrame; // Set by SHAKE to enable a randomized camera shake effect. FieldShakeData shakeX; @@ -975,7 +989,8 @@ extern u8 D_800708D0[][0x1C]; // kernel-region table, by attack/effect id extern AttackData D_800722CC[]; // magic/summon/skill table extern WeaponRecord g_WeaponTable[]; // 0x800738A0, by weapon id extern FieldEntity g_FieldEntity[]; -extern u8 D_800756E8[]; // per-model flags, indexed by field model id +extern u8 + g_FieldModelAnimStatus[16]; // per-model flags, indexed by field model id extern s32 D_800756F8[]; extern Unk80075D00* D_80075D00; extern int D_80075DEC; // buffer index, either 0 or 1 @@ -991,19 +1006,23 @@ extern s8 D_8007EBDC; extern u8 D_8007EBE0; // field debug mode extern u8 g_CharacterLock; // mirror of the UC opcode's control-lock flag extern u8 g_EntitySplitJoinState[48]; // states for SPLIT and JOIN opcodes -extern s16 D_80082248[]; // per-model current animation playback speed +extern s16 + g_FieldModelEffAnimSpeed[16]; // per-model current animation playback speed extern u8 D_80083184[0x40]; extern u8 D_800831C4[]; // Magic Order table from kernel.bin section 3. extern u16 g_FieldScriptPC[48]; // program counters for active entity scripts -extern u8 D_8008325C[]; // per-model default animation id (DFANM) +extern u8 g_FieldModelAnimId[16]; // per-model default animation id (DFANM) extern u8 g_WindowToEntity[4]; extern WindowData g_WindowData[4]; +extern u8 D_8008325C[16]; extern u8 D_8008326C[4]; extern s32 D_80083338; + extern u8 g_FieldScriptSyncState[48][8]; // sync states of entity scripts per // priority level extern FieldModelLoaderData* g_FieldModelLoaderData; extern s16 g_FieldLineCount; +extern u16 g_FieldPaletteBuffer[64][16]; extern s8 D_80095DCC; extern volatile u16 D_80095DD4; extern s16 g_PlayerModelId; @@ -1041,7 +1060,7 @@ extern u8 D_8009D60E; extern u8 g_DebugLevel; // field debug related extern CharacterLevelData g_CharacterLevelData[3]; extern u8 D_8009D824; -extern s16 D_8009D828[]; // per-model base animation speed +extern s16 g_FieldModelBaseAnimSpeed[16]; // per-model base animation speed extern s16 D_8009D85C[]; // record fields, stride 0x440 extern BattleItemReward g_BattleItemsEarned[4]; extern u8 D_8009D8F8[]; diff --git a/include/psxsdk/libgpu.h b/include/psxsdk/libgpu.h index 23746c2d..892baa59 100644 --- a/include/psxsdk/libgpu.h +++ b/include/psxsdk/libgpu.h @@ -134,8 +134,10 @@ extern int (*GPU_printf)(); /* printf() object */ ((tge) ? setcode(p, getcode(p) | 0x01) : setcode(p, getcode(p) & ~0x01)) #define getTPage(tp, abr, x, y) \ - ((((tp) & 0x3) << 7) | (((abr) & 0x3) << 5) | (((y) & 0x100) >> 4) | \ - (((x) & 0x3ff) >> 6) | (((y) & 0x200) << 2)) + ((GetGraphType()==1||GetGraphType()==2)? \ + ((((tp)&0x3)<<9)|(((abr)&0x3)<<7)|(((y)&0x300)>>3)|(((x)&0x3ff)>>6)): \ + ((((tp)&0x3)<<7)|(((abr)&0x3)<<5)|(((y)&0x100)>>4)|(((x)&0x3ff)>>6)| \ + (((y)&0x200)<<2))) #define getClut(x, y) ((y << 6) | ((x >> 4) & 0x3f)) @@ -644,4 +646,5 @@ extern DISPENV* SetDefDispEnv(DISPENV* env, int x, int y, int w, int h); extern DRAWENV* SetDefDrawEnv(DRAWENV* env, int x, int y, int w, int h); extern TIM_IMAGE* ReadTIM(TIM_IMAGE* timimg); +extern int GetGraphType(void); #endif diff --git a/src/field/field.c b/src/field/field.c index bb8d699d..8cd91a21 100644 --- a/src/field/field.c +++ b/src/field/field.c @@ -38,8 +38,6 @@ extern s32 (*g_FieldOpcodes[256])(void); extern u8 g_EntityForSplitJoin; extern s16 D_800DF120[][2]; extern char g_DebugMessageBuffer[]; // debug value transformed into text - -extern u8 D_80114498[]; extern u32 g_FieldKeyState; void AddBackgroundToRender(struct FieldRenderData* buf); diff --git a/src/field/field2.c b/src/field/field2.c index 50fdf145..ca8f5f88 100644 --- a/src/field/field2.c +++ b/src/field/field2.c @@ -3,6 +3,8 @@ #include extern u8 D_800E08C0[]; +extern char D_800E0628[]; +extern char D_800E0630[]; extern u8 g_DialogDigitCharacters[16]; extern u8 g_WindowReplaceBank[4][8]; extern u16 g_WindowReplaceBankAddr[4][8]; @@ -19,8 +21,6 @@ extern s16 g_WindowBufferPos[4]; extern u8 g_WindowBuffer[4][16]; extern s16 g_WindowTotalRowsHeight[4]; extern char g_FieldDebugDigits[16]; -extern s8 D_800E0628; -extern s8 D_800E0630; extern u16 g_FieldDebugRb; extern s16 g_FieldDebugRChars; extern s16 g_FieldDebugRLines; @@ -1212,13 +1212,13 @@ void InitFieldDebugPages(void) { SetStrToDebugRow(5, 6, " Info OFF"); FieldDebugPageHide(5); FieldDebugPageInit(4, 0x6C, 0x52, 0x6C, 0x52); - AddStrNextDebugRow(4, &D_800E0628); + AddStrNextDebugRow(4, D_800E0628); FieldDebugPageHide(4); FieldDebugPageInit(3, 0x6C, 0xA4, 0x6C, 0x5C); - AddStrNextDebugRow(3, &D_800E0630); + AddStrNextDebugRow(3, D_800E0630); FieldDebugPageHide(3); FieldDebugPageInit(1, 0, 0, 0x6C, 0xCA); - AddStrNextDebugRow(1, &D_800E0628); + AddStrNextDebugRow(1, D_800E0628); FieldDebugPageHide(1); D_80099FFC = 3; D_8007EBCC = 4; diff --git a/src/field/field_event.c b/src/field/field_event.c index 6b916c0e..837b8948 100644 --- a/src/field/field_event.c +++ b/src/field/field_event.c @@ -6,8 +6,17 @@ extern s32 (*g_FieldOpcodes[256])(void); extern u8 g_EntityForSplitJoin; extern char g_DebugMessageBuffer[]; -extern u8 D_80114498[]; - +extern u8 D_80114498[48]; +extern u8 g_PosCursorDisabled; +extern POLY_FT4 g_PosCursorPrims[2]; +extern s16 g_PosCursorX; +extern s16 g_PosCursorY; +extern u8 g_PosCursorPrimId; +extern char D_800E0628[]; // "Actor:" +extern char g_DebugText[]; +extern u8 D_800716D4; + +void DebugPrintToFieldWindow(const char* str); void FieldEventOpcodeCycle(void); void FieldUpdateAnimationState(void); u8 FieldEventRequestRun(s16 entityId, s16 priority, s16 scriptId); @@ -18,13 +27,49 @@ void SetStrToDebugRow(s32 page, s16 row, const char* str); void FieldDebugStringCopy(char* dst, const char* src); void FieldDebugStringConcat(char* dest, char* src); void InitFieldDebugPages(void); +void FieldEventClearAkaoStruct(void); +void FieldWindowResetAll(void); +void FieldInitDefaultValues(void); +void FieldEventRunInit(void); +void ResetPositionCursorPrimitives(void); +void UpdatePositionCursor(OT_TYPE* ot); +void DrawPositionCursor(OT_TYPE* ot); + +void FieldEventInit(FieldState* fieldState, FieldEntity* fieldModels, + FieldScriptHeader* fieldScripts) { + g_pFieldState = fieldState; + g_FieldModels = fieldModels; + g_FieldScripts = fieldScripts; + D_80095DCC = 0; + D_8007EBE0 = 1; + D_8009FE8C = 0; + if ((fieldState->activeKeysRaw >> 16) & PADselect) { + D_80095DCC = 1; + D_80099FFC = 4; + } + if (fieldScripts->eventDataVersion < 2) { + SystemError('K', 10); + } + if (fieldScripts->eventDataVersion > 2 || fieldScripts->eventVersion > 5) { + SystemError('K', 12); + } + if (fieldScripts->eventVersion < 5) { + SystemError('K', 11); + } + FieldWindowResetAll(); + FieldInitDefaultValues(); + FieldEventRunInit(); + if (!D_800716D4) { + FieldEventClearAkaoStruct(); + D_8009A000[0] = 242; + SystemAkaoExecute(); + } +} -INCLUDE_ASM("asm/us/field/nonmatchings/field_event", FieldEventInit); - -void FieldEventUpdate(s32 arg0) { +void FieldEventUpdate(OT_TYPE* ot) { if (D_8007EBE0) { FieldWindowResetTextAll(); - ResetFieldRenderState(); + ResetPositionCursorPrimitives(); FieldDebugInitBuffers(); InitFieldDebugPages(); D_80095DCC = 0; @@ -46,16 +91,291 @@ void FieldEventUpdate(s32 arg0) { } } if (g_WindowCount) { - SystemMenuDrawDialog(g_WindowData, 4, arg0, g_pFieldState->renderBuffer ^ 1); + SystemMenuDrawDialog( + g_WindowData, 4, ot, g_pFieldState->renderBuffer ^ 1); } - UpdateFieldExitArrows(arg0); + UpdatePositionCursor(ot); } -INCLUDE_ASM("asm/us/field/nonmatchings/field_event", FieldInitDefaultValues); +void FieldInitDefaultValues(void) { + s32 i, j; + + g_pFieldState->eventCmd = EVTCMD_NONE; + g_pFieldState->eventCmdParam = 0; + g_pFieldState->movieCommandState = MOVCMD_IDLE; + g_pFieldState->modelCount = g_FieldScripts->numModels; + g_pFieldState->pcModelId = 0; + g_pFieldState->idleAnimId = 0; + g_pFieldState->walkAnimId = 1; + g_pFieldState->runAnimId = 2; + g_pFieldState->characterLock = 0; + g_CharacterLock = 0; + g_pFieldState->suspendWalkAndAnim = 0; + g_pFieldState->menuDisabled = 0; + g_pFieldState->unk35 = 0; + g_pFieldState->battlesDisabled = 0; + g_pFieldState->mapJumpDisabled = 0; + g_pFieldState->scrloSet = 0; + g_pFieldState->nextFieldMusic = 0; + g_pFieldState->nextBattleMusic = 0; + g_pFieldState->unk40 = 0; + g_pFieldState->battleMode2 = 0; + g_pFieldState->battleMode1 = 0; + g_pFieldState->encounterTableId = 0; + g_pFieldState->viewOffsetNumSteps = 0; + g_pFieldState->viewOffsetCurrentStep = 0; + g_pFieldState->viewOffsetMode = OMODE_INSTANT; + g_pFieldState->viewOffsetStart = 0; + g_pFieldState->viewOffsetTarget = 0; + g_pFieldState->shakeX.enabled = 0; + g_pFieldState->shakeY.enabled = 0; + g_pFieldState->shakeX.segmentActive = 0; + g_pFieldState->shakeY.segmentActive = 0; + g_pFieldState->shakeX.amplitude = 0; + g_pFieldState->shakeY.amplitude = 0; + g_pFieldState->shakeX.numStepsPerSegment = 0; + g_pFieldState->shakeY.numStepsPerSegment = 0; + g_pFieldState->shakeX.currentStep = 0; + g_pFieldState->shakeY.currentStep = 0; + g_pFieldState->backgroundMovieEnabled = 0; + g_pFieldState->cameraScrollMode = SCRL_OFF; + g_pFieldState->currentFieldScale = g_FieldScripts->scale; + + for (i = 0; i < 256; i++) { + g_FieldMapVars[i] = 0; + } + + for (i = 0; i < 8; i++) { + for (j = 0; j < g_FieldScripts->numEntities; j++) { + g_SavedFieldScriptPC[j][i] = 0; + g_FieldScriptSyncState[j][i] = SYNC_NONE; + g_FieldScriptSyncWaitEntity[j][i] = 0xFF; + SavedScriptIds[j][i] = 0; + } + } + + for (i = 0; i < g_FieldScripts->numEntities; i++) { + g_FieldScriptPriority[i] = 7; + g_EntityToModel[i] = 0xFF; + g_FieldWaitCounter[i] = 0; + g_EntitySplitJoinState[i] = 0; + g_EntityToLine[i] = 0xFF; + D_80114498[i] = 0; + } + + for (i = 0; i < g_FieldScripts->numModels; i++) { + g_FieldModels[i].charId = 0; + g_FieldModels[i].PosX = 0; + g_FieldModels[i].PosY = 0; + g_FieldModels[i].PosZ = 0; + g_FieldModels[i].PosI = 0; + g_FieldModels[i].MoveEndI = 0; + g_FieldModels[i].MoveDir = 0; + g_FieldModels[i].Dir = 0; + g_FieldModels[i].TurnType = 0; + g_FieldModels[i].TurnSteps = 0; + g_FieldModels[i].TurnStep = 0; + g_FieldModels[i].TurnStart = 0; + g_FieldModels[i].TurnEnd = 0; + g_FieldModels[i].OffsetX = 0; + g_FieldModels[i].OffsetY = 0; + g_FieldModels[i].OffsetZ = 0; + g_FieldModels[i].OffsetStartX = 0; + g_FieldModels[i].OffsetStartY = 0; + g_FieldModels[i].OffsetStartZ = 0; + g_FieldModels[i].OffsetEndX = 0; + g_FieldModels[i].OffsetEndY = 0; + g_FieldModels[i].OffsetEndZ = 0; + g_FieldModels[i].OffsetSteps = 0; + g_FieldModels[i].OffsetStep = 0; + g_FieldModels[i].OfsType = OMODE_INSTANT; + g_FieldModels[i].activeAnimId = 0; + g_FieldModels[i].animSpeed = 16; + g_FieldModels[i].MoveEndX = 0; + g_FieldModels[i].MoveEndY = 0; + g_FieldModels[i].MoveEndZ = 0; + g_FieldModels[i].animCurrentFrame = 0; + g_FieldModels[i].animLastFrame = 0; + g_FieldModels[i].visible = 0; + g_FieldModels[i].MoveSpeed = + 1024 * g_pFieldState->currentFieldScale / 512; + g_FieldModels[i].scriptedMoveMode = SMODE_NONE; + g_FieldModels[i].ActionArg = 0; + g_FieldModels[i].ActionState = 0; + g_FieldModels[i].requestTalkScript = 0; + g_FieldModels[i].requestPushScript = 0; + g_FieldModels[i].SolidOff = 0; + g_FieldModels[i].TalkOff = 0; + g_FieldModels[i].DirLock = 0; + g_FieldModels[i].SolidRange = + 30 * g_pFieldState->currentFieldScale / 512; + g_FieldModels[i].TalkRange = + 80 * g_pFieldState->currentFieldScale / 512; + g_FieldModelAnimId[i] = 0; + g_FieldModelAnimStatus[i] = ANIMSTATUS_DEFAULT_LOOP; + g_FieldModelBaseAnimSpeed[i] = 16; + g_FieldModelEffAnimSpeed[i] = 16; + g_FieldModels[i].KawaiOp1 = 0; + g_FieldModels[i].KawaiOp0 = 0; + g_FieldModels[i].KawaiDataOffset = 0; + g_FieldModels[i].BlinkOn = 0; + g_FieldModels[i].KawaiA = 0; + } + + for (i = 0; i < 64; i++) { + g_pFieldState->backgroundLayerVisibility[i] = 0; + } + for (i = 0; i < 64; i++) { + g_pFieldState->blockedAccesses[i] = 0; + } + for (i = 0; i < 64; i++) { + for (j = 0; j < 16; j++) { + g_FieldPaletteBuffer[i][j] = 0; + } + } + + for (i = 0; i < 32; i++) { + g_FieldLines[i].requestTalkScript = 0; + g_FieldLines[i].requestPushScript = 0; + g_FieldLines[i].across = 0; + g_FieldLines[i].touch = 0; + g_FieldLines[i].requestTouchOnScript = 0; + g_FieldLines[i].requestTouchOffScript = 0; + g_FieldLines[i].isActive = 0; + g_FieldLines[i].entityId = 0; + g_FieldLines[i].slipDisabled = 0; + g_FieldLines[i].pos.x1 = 0; + g_FieldLines[i].pos.y1 = 0; + g_FieldLines[i].pos.z1 = 0; + g_FieldLines[i].pos.x2 = 0; + g_FieldLines[i].pos.y2 = 0; + g_FieldLines[i].pos.z2 = 0; + } + g_FieldLineCount = 0; + for (i = 0; i < 9; i++) { + g_CharIdToEntity[i] = 0xFF; + } + g_EntityForSplitJoin = 0xFF; + g_PosCursorDisabled = 0; + Savemap.memory_bank_1[31] |= 3; // Locks PHS and save menus +} + +void FieldEventRunInit(void) { + g_FieldModelCount = 0; + for (g_CurrentEntity = 0; g_CurrentEntity < g_FieldScripts->numEntities; + g_CurrentEntity++) { + s16 extrasHeaderSize; + + if (D_80071E24 & 3) { + FieldDebugStringCopy(g_DebugText, D_800E0628); + FieldDebugStringConcat( + g_DebugText, GET_ENTITY_NAME(g_CurrentEntity)); + if (D_80071E24 & 1) { + SetStrToDebugRow(4, 0, g_DebugText); + } + if (D_80071E24 & 2) { + DebugPrintToFieldWindow(g_DebugText); + } + } -INCLUDE_ASM("asm/us/field/nonmatchings/field_event", FieldEventRunInit); + extrasHeaderSize = g_FieldScripts->numExtras * 4; + GET_FIELD_SCRIPT_OFFSET( + g_FieldScriptPC[g_CurrentEntity], 0, + 8 * g_FieldScripts->numEntities + 64 * g_CurrentEntity, + extrasHeaderSize); + + // Keep executing the init script until we reach 0x00 = RET opcode. + while ((g_FieldCurrentOpcode = + ((u8*)g_FieldScripts)[g_FieldScriptPC[g_CurrentEntity]]) != + 0) { + g_FieldOpcodes[g_FieldCurrentOpcode](); + } + g_FieldScriptPC[g_CurrentEntity]++; // Advance PC to the start of the + // next script. + } + g_CurrentEntity = 0; +} -INCLUDE_ASM("asm/us/field/nonmatchings/field_event", FieldEnablePartyModels); +extern void* D_8007E770; +extern /*?*/s32 D_8007EB98; +extern /*?*/s32 D_8009AD30; +extern s32 D_8009C544; +extern void* D_8009C6DC; + +void FieldEnablePartyModels(void) +{ + s16 temp_v0_3; + s16 var_a1; + s16 var_a2; + s16 var_a2_2; + s16 var_v0_2; + s16 var_v0_4; + s32 temp_a0_2; + s32 temp_v0_4; + s32 temp_v1_2; + s32 var_v0; + s32 var_v0_3; + s32 var_v0_5; + u8 temp_a0; + u8 temp_a0_3; + u8 temp_v0; + u8 temp_v0_2; + u8 temp_v1; + + var_a2 = 0; + var_v0 = 0 << 0x10; + do { + temp_v0 = D_8009D391[var_v0 >> 0x10]; + if ((temp_v0 != 0xFF) && (temp_v0_2 = *(&D_8009AD30 + temp_v0), (temp_v0_2 != 0xFF))) { + temp_a0 = *(&D_8007EB98 + temp_v0_2); + var_v0_2 = var_a2 + 1; + if (temp_a0 != 0xFF) { + var_v0_2 = var_a2 + 1; + if ((s32) temp_a0 < (s32) D_8007E770->unk2) { + g_FieldModelLoaderData[temp_a0].npcFlag = 1; + goto block_6; + } + } + } else { +block_6: + var_v0_2 = var_a2 + 1; + } + var_a2 = var_v0_2; + var_v0 = var_a2 << 0x10; + } while (var_v0_2 < 3); + var_a2_2 = 0; + if (D_8007E770->unk2 != 0) { + var_v0_3 = 0 << 0x10; + do { + temp_a0_2 = var_v0_3 >> 0x10; + temp_v1 = g_FieldModelLoaderData[temp_a0_2].npcFlag; + var_v0_4 = var_a2_2 + 1; + if (temp_v1 == 0) { + var_a1 = 0; + if ((s32) temp_v1 < (s32) D_8009C6DC->unk2) { + var_v0_5 = 0 << 0x10; + do { + temp_v0_4 = var_v0_5 >> 0x10; + temp_a0_3 = *(&D_8007EB98 + temp_v0_4); + if (temp_a0_3 == temp_a0_2) { + *(&D_8007EB98 + temp_v0_4) = 0xFF; + temp_v1_2 = temp_a0_3 * 0x84; + (temp_v1_2 + D_8009C544)->unk5C = 0; + (temp_v1_2 + D_8009C544)->unk59 = 1; + (temp_v1_2 + D_8009C544)->unk5B = 1; + } + temp_v0_3 = var_a1 + 1; + var_a1 = temp_v0_3; + var_v0_5 = var_a1 << 0x10; + } while (temp_v0_3 < (s32) D_8009C6DC->unk2); + } + var_v0_4 = var_a2_2 + 1; + } + var_a2_2 = var_v0_4; + var_v0_3 = var_a2_2 << 0x10; + } while (var_v0_4 < (s32) D_8007E770->unk2); + } +} void FieldEventOpcodeCycle(void) { s32 i, j, count; @@ -197,12 +517,16 @@ void FieldUpdateAnimationState(void) { for (i = 0; i < g_FieldScripts->numEntities; i++) { if (g_EntityToModel[i] != 0xFF && - (g_pFieldState->pcModelId != g_EntityToModel[i] || g_pFieldState->characterLock)) { - switch (D_800756E8[g_EntityToModel[i]]) { - case 0: - if (g_FieldModels[g_EntityToModel[i]].activeAnimId != D_8008325C[g_EntityToModel[i]]) { - g_FieldModels[g_EntityToModel[i]].activeAnimId = D_8008325C[g_EntityToModel[i]]; - g_FieldModels[g_EntityToModel[i]].animSpeed = D_80082248[g_EntityToModel[i]]; + (g_pFieldState->pcModelId != g_EntityToModel[i] || + g_pFieldState->characterLock)) { + switch (g_FieldModelAnimStatus[g_EntityToModel[i]]) { + case ANIMSTATUS_DEFAULT_LOOP: + if (g_FieldModels[g_EntityToModel[i]].activeAnimId != + g_FieldModelAnimId[g_EntityToModel[i]]) { + g_FieldModels[g_EntityToModel[i]].activeAnimId = + g_FieldModelAnimId[g_EntityToModel[i]]; + g_FieldModels[g_EntityToModel[i]].animSpeed = + g_FieldModelEffAnimSpeed[g_EntityToModel[i]]; g_FieldModels[g_EntityToModel[i]].animCurrentFrame = 0; modelEntryId = g_FieldModelLoaderData[g_EntityToModel[i]].modelEntryIndex; model = &g_FieldModelData->modelEntries[modelEntryId]; @@ -221,35 +545,38 @@ void FieldUpdateAnimationState(void) { } } break; - case 1: + case ANIMSTATUS_SCRIPTED_LOOP: if ((g_FieldModels[g_EntityToModel[i]].animCurrentFrame >> 4) >= g_FieldModels[g_EntityToModel[i]].animLastFrame) { g_FieldModels[g_EntityToModel[i]].animCurrentFrame = 0; } break; - case 2: + case ANIMSTATUS_PLAY_ONCE_SYNC: if ((g_FieldModels[g_EntityToModel[i]].animCurrentFrame >> 4) >= g_FieldModels[g_EntityToModel[i]].animLastFrame) { - D_800756E8[g_EntityToModel[i]] = 4; + g_FieldModelAnimStatus[g_EntityToModel[i]] = + ANIMSTATUS_PLAY_ONCE_SYNC_DONE; g_FieldModels[g_EntityToModel[i]].animCurrentFrame = g_FieldModels[g_EntityToModel[i]].animLastFrame << 4; } break; - case 3: - case 4: + case ANIMSTATUS_HOLD_FRAME: + case ANIMSTATUS_PLAY_ONCE_SYNC_DONE: g_FieldModels[g_EntityToModel[i]].animCurrentFrame = g_FieldModels[g_EntityToModel[i]].animLastFrame << 4; break; - case 5: + case ANIMSTATUS_PLAY_ONCE_THEN_RESET: if ((g_FieldModels[g_EntityToModel[i]].animCurrentFrame >> 4) >= g_FieldModels[g_EntityToModel[i]].animLastFrame) { - D_800756E8[g_EntityToModel[i]] = 0; + g_FieldModelAnimStatus[g_EntityToModel[i]] = + ANIMSTATUS_DEFAULT_LOOP; } break; - case 6: + case ANIMSTATUS_PLAY_ONCE_THEN_HOLD: if ((g_FieldModels[g_EntityToModel[i]].animCurrentFrame >> 4) >= g_FieldModels[g_EntityToModel[i]].animLastFrame) { - D_800756E8[g_EntityToModel[i]] = 3; + g_FieldModelAnimStatus[g_EntityToModel[i]] = + ANIMSTATUS_HOLD_FRAME; } break; } @@ -284,8 +611,8 @@ u8 FieldEventRequestRun(s16 entityId, s16 priority, s16 scriptId) { FieldDebugStringCopy(g_DebugMessageBuffer, "TochOFF="); break; } - // Prints entity name. - FieldDebugStringConcat(g_DebugMessageBuffer, (char*)g_FieldScripts + sizeof(FieldScriptHeader) + entityId * 8); + + FieldDebugStringConcat(g_DebugMessageBuffer, GET_ENTITY_NAME(entityId)); FieldDebugAddParseValueToPage2(g_DebugMessageBuffer, 0, 0); } @@ -302,7 +629,8 @@ u8 FieldEventRequestRun(s16 entityId, s16 priority, s16 scriptId) { entityDataSize = entityId * 64; entityDataSize += g_FieldScripts->numEntities * 8; - GET_FIELD_SCRIPT_PC(offset, scriptOffset, entityDataSize, extrasHeaderSize); + GET_FIELD_SCRIPT_OFFSET( + offset, scriptOffset, entityDataSize, extrasHeaderSize); // Empty event scripts consist of just a RET (0x00) opcode. if (((u8*)g_FieldScripts)[offset] != 0) { @@ -343,8 +671,105 @@ u8 FieldEventRequestRun(s16 entityId, s16 priority, s16 scriptId) { return 0; } -INCLUDE_ASM("asm/us/field/nonmatchings/field_event", ResetFieldRenderState); +void ResetPositionCursorPrimitives(void) { + s16 tpage; + + g_PosCursorX = 32767; + g_PosCursorY = 32767; + g_PosCursorPrimId = 0; + setPolyFT4(&g_PosCursorPrims[0]); + setPolyFT4(&g_PosCursorPrims[1]); + setSemiTrans(&g_PosCursorPrims[0], 0); + setSemiTrans(&g_PosCursorPrims[1], 0); + setShadeTex(&g_PosCursorPrims[0], 1); + setShadeTex(&g_PosCursorPrims[1], 1); + tpage = getTPage(0, 0, 960, 256); + g_PosCursorPrims[1].tpage = tpage; + g_PosCursorPrims[0].tpage = tpage; + g_PosCursorPrims[1].clut = getClut(256, 481); + g_PosCursorPrims[0].clut = getClut(256, 481); + g_PosCursorPrims[0].r0 = 0; + g_PosCursorPrims[1].r0 = 0; + g_PosCursorPrims[0].g0 = 0; + g_PosCursorPrims[1].g0 = 0; + g_PosCursorPrims[0].b0 = 0; + g_PosCursorPrims[1].b0 = 0; +} -INCLUDE_ASM("asm/us/field/nonmatchings/field_event", UpdateFieldExitArrows); +void UpdatePositionCursor(OT_TYPE* ot) { + if (g_pFieldState->pressedKeys & PADselect) { + Savemap.memory_bank_4[30] ^= 1; + } + if (((Savemap.memory_bank_4[30] == 1) && (!g_pFieldState->characterLock)) || + Savemap.memory_bank_4[30] & 2) { + DrawPositionCursor(ot); + } +} -INCLUDE_ASM("asm/us/field/nonmatchings/field_event", DrawFieldExitArrow); +void DrawPositionCursor(OT_TYPE* ot) { + s16 x, y; + + if (!g_PosCursorDisabled && + ((g_PosCursorX != 32767) || (g_PosCursorY != 32767))) { + if (g_PosCursorX > 320) { + x = 320; + } else { + x = g_PosCursorX; + } + if (g_PosCursorX < 0) { + x = 0; + } + if (g_PosCursorY > 224) { + y = 224; + } else { + y = g_PosCursorY; + } + if (g_PosCursorY < 0) { + y = 0; + } + g_PosCursorPrimId ^= 1; + // Rotate cursor about the Y axis when player is on right edge of + // screen. + if (x > 290) { + g_PosCursorPrims[g_PosCursorPrimId].u0 = 143; + g_PosCursorPrims[g_PosCursorPrimId].u1 = 127; + g_PosCursorPrims[g_PosCursorPrimId].u2 = 143; + g_PosCursorPrims[g_PosCursorPrimId].u3 = 127; + g_PosCursorPrims[g_PosCursorPrimId].x0 = x - 16; + g_PosCursorPrims[g_PosCursorPrimId].x1 = x; + g_PosCursorPrims[g_PosCursorPrimId].x2 = x - 16; + g_PosCursorPrims[g_PosCursorPrimId].x3 = x; + } else { + g_PosCursorPrims[g_PosCursorPrimId].u0 = 128; + g_PosCursorPrims[g_PosCursorPrimId].u1 = 144; + g_PosCursorPrims[g_PosCursorPrimId].u2 = 128; + g_PosCursorPrims[g_PosCursorPrimId].u3 = 144; + g_PosCursorPrims[g_PosCursorPrimId].x0 = x; + g_PosCursorPrims[g_PosCursorPrimId].x1 = x + 16; + g_PosCursorPrims[g_PosCursorPrimId].x2 = x; + g_PosCursorPrims[g_PosCursorPrimId].x3 = x + 16; + } + // Rotate cursor about the X axis when player is at the top of the + // screen. + if (y <= 16) { + g_PosCursorPrims[g_PosCursorPrimId].v0 = 111; + g_PosCursorPrims[g_PosCursorPrimId].v1 = 111; + g_PosCursorPrims[g_PosCursorPrimId].v2 = 95; + g_PosCursorPrims[g_PosCursorPrimId].v3 = 95; + g_PosCursorPrims[g_PosCursorPrimId].y0 = y; + g_PosCursorPrims[g_PosCursorPrimId].y1 = y; + g_PosCursorPrims[g_PosCursorPrimId].y2 = y + 16; + g_PosCursorPrims[g_PosCursorPrimId].y3 = y + 16; + } else { + g_PosCursorPrims[g_PosCursorPrimId].v0 = 96; + g_PosCursorPrims[g_PosCursorPrimId].v1 = 96; + g_PosCursorPrims[g_PosCursorPrimId].v2 = 112; + g_PosCursorPrims[g_PosCursorPrimId].v3 = 112; + g_PosCursorPrims[g_PosCursorPrimId].y0 = y - 16; + g_PosCursorPrims[g_PosCursorPrimId].y1 = y - 16; + g_PosCursorPrims[g_PosCursorPrimId].y2 = y; + g_PosCursorPrims[g_PosCursorPrimId].y3 = y; + } + addPrim(ot, &g_PosCursorPrims[g_PosCursorPrimId]); + } +} diff --git a/src/field/field_opcodes.c b/src/field/field_opcodes.c index e41761de..048862a7 100644 --- a/src/field/field_opcodes.c +++ b/src/field/field_opcodes.c @@ -34,14 +34,14 @@ extern u8 D_80114498[]; extern u8 g_RandomTableStep; extern u8 g_RandomTableIndex; extern u8 g_RandomTable[256]; +extern char D_800E0628[]; +extern char D_800E0630[]; extern char g_DebugText[]; extern char g_DebugMessageBuffer[]; -extern char D_800E0628[]; extern s8 D_800716C8; extern s16 D_80071E38; extern s16 D_80071E3C; extern u32 D_80075E10; -extern s8 D_800E0630; extern SVECTOR (*D_800E4274)[3]; extern u8* D_800E48E0; @@ -94,7 +94,7 @@ void DebugUpdateActor(s16 arg0, s16 entityId) { FieldDebugStringCopy(g_DebugText, "ctrl:"); } - FieldDebugStringConcat(g_DebugText, (char*)g_FieldScripts + 32 + (entityId * 8)); + FieldDebugStringConcat(g_DebugText, GET_ENTITY_NAME(entityId)); if (D_8009FE8C | (D_80071E24 & 1)) { SetStrToDebugRow(arg0, 0, g_DebugText); } @@ -192,7 +192,8 @@ void DebugUpdateActor(s16 arg0, s16 entityId) { if (D_80071E24 & 2) { DebugPrintToFieldWindow(g_DebugText); } - FieldDebugStringU8hex(D_800756E8[g_EntityToModel[entityId]], g_DebugText); + FieldDebugStringU8hex( + g_FieldModelAnimStatus[g_EntityToModel[entityId]], g_DebugText); FieldDebugStringConcat(g_DebugText, "am"); FieldDebugStringU16hex(g_FieldModels[g_EntityToModel[entityId]].activeAnimId, g_DebugMessageBuffer); FieldDebugStringConcat(g_DebugText, g_DebugMessageBuffer); @@ -550,7 +551,7 @@ void DebugPrintOpcode(const char* name, s32 arg1) { var_s1 = arg1; if (!(D_80071E24 & 4) || (D_80114498[g_CurrentEntity] != 0)) { - FieldDebugStringCopy(g_DebugText, &D_800E0630); + FieldDebugStringCopy(g_DebugText, D_800E0630); FieldDebugStringConcat(g_DebugText, name); if (g_DebugLevel & 1) { SetStrToDebugRow(3, 0, g_DebugText); @@ -1906,7 +1907,7 @@ s32 FieldEventRequest(s16 type, u8 target, u8 priority, u8 scriptId) { if (g_DebugLevel & 3) { FieldDebugStringCopy(g_DebugMessageBuffer, "rq="); - FieldDebugStringConcat(g_DebugMessageBuffer, (char*)g_FieldScripts + sizeof(FieldScriptHeader) + target * 8); + FieldDebugStringConcat(g_DebugMessageBuffer, GET_ENTITY_NAME(target)); FieldDebugStringConcat(g_DebugMessageBuffer, "/"); FieldDebugAddParseValueToPage2(g_DebugMessageBuffer, scriptId, 2); } @@ -1972,8 +1973,10 @@ s32 FieldEventRequest(s16 type, u8 target, u8 priority, u8 scriptId) { entityDataSize = target * 64; extrasHeaderSize = (s16)(g_FieldScripts->numExtras * 4); - GET_FIELD_SCRIPT_PC(g_SavedFieldScriptPC[target][priority], scriptOffset, - entityDataSize + (g_FieldScripts->numEntities << 3), extrasHeaderSize); + GET_FIELD_SCRIPT_OFFSET( + g_SavedFieldScriptPC[target][priority], scriptOffset, + entityDataSize + (g_FieldScripts->numEntities << 3), + extrasHeaderSize); if (g_DebugLevel & 3) { FieldDebugAddParseValueToPage2("rq=send", 0, 0); @@ -2002,8 +2005,10 @@ s32 FieldEventRequest(s16 type, u8 target, u8 priority, u8 scriptId) { entityDataSize = target * 64; extrasHeaderSize = (s16)(g_FieldScripts->numExtras * 4); - GET_FIELD_SCRIPT_PC(g_FieldScriptPC[target], scriptOffset, entityDataSize + (g_FieldScripts->numEntities << 3), - extrasHeaderSize); + GET_FIELD_SCRIPT_OFFSET( + g_FieldScriptPC[target], scriptOffset, + entityDataSize + (g_FieldScripts->numEntities << 3), + extrasHeaderSize); g_FieldScriptPriority[target] = priority; @@ -2108,8 +2113,10 @@ s32 OpcodeFuncRetto(void) { scriptId *= 2; extrasHeaderSize = (s16)(g_FieldScripts->numExtras * 4); - GET_FIELD_SCRIPT_PC(g_FieldScriptPC[g_CurrentEntity], scriptId, - (g_FieldScripts->numEntities * 8) + (g_CurrentEntity * 64), extrasHeaderSize); + GET_FIELD_SCRIPT_OFFSET( + g_FieldScriptPC[g_CurrentEntity], scriptId, + (g_FieldScripts->numEntities * 8) + (g_CurrentEntity * 64), + extrasHeaderSize); g_FieldScriptPriority[g_CurrentEntity] = priority; if (g_DebugLevel & 3) { @@ -2436,7 +2443,8 @@ s32 OpcodeFuncUc(void) { } g_CharacterLock = g_pFieldState->characterLock = GET_PARAM_U8(1); if (g_CharacterLock == 0) { - D_800756E8[g_pFieldState->pcModelId] = 0; + g_FieldModelAnimStatus[g_pFieldState->pcModelId] = + ANIMSTATUS_DEFAULT_LOOP; } PC_INC(2); return 0; @@ -2532,11 +2540,13 @@ s32 OpcodeFuncDfanm(void) { DebugPrintOpcode("dfanm", 2); } if (g_EntityToModel[g_CurrentEntity] != 0xFF) { - D_8008325C[g_EntityToModel[g_CurrentEntity]] = GET_PARAM_U8(1); - D_80082248[g_EntityToModel[g_CurrentEntity]] = D_8009D828[g_EntityToModel[g_CurrentEntity]] / GET_PARAM_U8(2); + g_FieldModelAnimId[g_EntityToModel[g_CurrentEntity]] = GET_PARAM_U8(1); + g_FieldModelEffAnimSpeed[g_EntityToModel[g_CurrentEntity]] = + g_FieldModelBaseAnimSpeed[g_EntityToModel[g_CurrentEntity]] / + GET_PARAM_U8(2); modelIdx = g_EntityToModel[g_CurrentEntity]; - if (D_800756E8[modelIdx] == 3) { - D_800756E8[modelIdx] = 0; + if (g_FieldModelAnimStatus[modelIdx] == ANIMSTATUS_HOLD_FRAME) { + g_FieldModelAnimStatus[modelIdx] = ANIMSTATUS_DEFAULT_LOOP; } } PC_INC(3); @@ -2580,7 +2590,8 @@ void StartModelAnimation(void) { g_FieldModels[g_EntityToModel[g_CurrentEntity]].activeAnimId = GET_PARAM_U8(1); g_FieldModels[g_EntityToModel[g_CurrentEntity]].animSpeed = - D_8009D828[g_EntityToModel[g_CurrentEntity]] / GET_PARAM_U8(2); + g_FieldModelBaseAnimSpeed[g_EntityToModel[g_CurrentEntity]] / + GET_PARAM_U8(2); g_FieldModels[g_EntityToModel[g_CurrentEntity]].animCurrentFrame = 0; modelIdx = g_EntityToModel[g_CurrentEntity]; model = &g_FieldModelData->modelEntries[g_FieldModelLoaderData[modelIdx].modelEntryIndex]; @@ -2606,20 +2617,20 @@ s32 OpcodeFuncAnime(void) { return 0; } - switch (D_800756E8[g_EntityToModel[g_CurrentEntity]]) { - case 0: - case 1: - case 3: + switch (g_FieldModelAnimStatus[g_EntityToModel[g_CurrentEntity]]) { + case ANIMSTATUS_DEFAULT_LOOP: + case ANIMSTATUS_SCRIPTED_LOOP: + case ANIMSTATUS_HOLD_FRAME: StartModelAnimation(); if (g_FieldCurrentOpcode == 0xAE) { - D_800756E8[g_EntityToModel[g_CurrentEntity]] = 5; + g_FieldModelAnimStatus[g_EntityToModel[g_CurrentEntity]] = 5; PC_INC(3); return 0; } - D_800756E8[g_EntityToModel[g_CurrentEntity]] = 2; + g_FieldModelAnimStatus[g_EntityToModel[g_CurrentEntity]] = 2; break; - case 4: - D_800756E8[g_EntityToModel[g_CurrentEntity]] = 0; + case ANIMSTATUS_PLAY_ONCE_SYNC_DONE: + g_FieldModelAnimStatus[g_EntityToModel[g_CurrentEntity]] = 0; PC_INC(3); return 0; } @@ -2642,20 +2653,20 @@ s32 OpcodeFuncAnimEx(void) { return 0; } - switch (D_800756E8[g_EntityToModel[g_CurrentEntity]]) { - case 0: - case 1: - case 3: + switch (g_FieldModelAnimStatus[g_EntityToModel[g_CurrentEntity]]) { + case ANIMSTATUS_DEFAULT_LOOP: + case ANIMSTATUS_SCRIPTED_LOOP: + case ANIMSTATUS_HOLD_FRAME: StartModelAnimation(); if (g_FieldCurrentOpcode == 0xAF) { - D_800756E8[g_EntityToModel[g_CurrentEntity]] = 6; + g_FieldModelAnimStatus[g_EntityToModel[g_CurrentEntity]] = 6; PC_INC(3); return 0; } - D_800756E8[g_EntityToModel[g_CurrentEntity]] = 2; + g_FieldModelAnimStatus[g_EntityToModel[g_CurrentEntity]] = 2; break; - case 4: - D_800756E8[g_EntityToModel[g_CurrentEntity]] = 3; + case ANIMSTATUS_PLAY_ONCE_SYNC_DONE: + g_FieldModelAnimStatus[g_EntityToModel[g_CurrentEntity]] = 3; PC_INC(3); return 0; } diff --git a/src/field/field_private.h b/src/field/field_private.h index dac5ea1f..ba8c94b5 100644 --- a/src/field/field_private.h +++ b/src/field/field_private.h @@ -1,11 +1,18 @@ #ifndef FIELD_PRIVATE_H #define FIELD_PRIVATE_H -#define GET_FIELD_SCRIPT_PC(dst, scriptOffset, entityDataOffset, extrasHeaderSize) \ - (dst) = *((u8*)((scriptOffset) + (entityDataOffset) + (extrasHeaderSize) + (s32)g_FieldScripts) + \ - sizeof(FieldScriptHeader)); \ - (dst) |= *((u8*)((scriptOffset) + ((entityDataOffset) + (s32)g_FieldScripts) + (extrasHeaderSize)) + \ - sizeof(FieldScriptHeader) + 1) \ - << 8 +#define GET_ENTITY_NAME(entityId) \ + ((char*)g_FieldScripts + sizeof(FieldScriptHeader) + (entityId) * 8) + +#define GET_FIELD_SCRIPT_OFFSET( \ + dst, scriptOffset, entityDataOffset, extrasHeaderSize) \ + (dst) = *((u8*)((scriptOffset) + (entityDataOffset) + (extrasHeaderSize) + \ + (s32)g_FieldScripts) + \ + sizeof(FieldScriptHeader)); \ + (dst) |= \ + *((u8*)((scriptOffset) + ((entityDataOffset) + (s32)g_FieldScripts) + \ + (extrasHeaderSize)) + \ + sizeof(FieldScriptHeader) + 1) \ + << 8 #endif From b2a97a58f86440f8ba0435feeb59d3b3a1d31b02 Mon Sep 17 00:00:00 2001 From: Zaarin Date: Fri, 4 Sep 2026 11:05:57 +0200 Subject: [PATCH 2/6] WIP --- src/field/field_event.c | 81 +---------------------------------------- 1 file changed, 1 insertion(+), 80 deletions(-) diff --git a/src/field/field_event.c b/src/field/field_event.c index 837b8948..db945da5 100644 --- a/src/field/field_event.c +++ b/src/field/field_event.c @@ -296,86 +296,7 @@ void FieldEventRunInit(void) { g_CurrentEntity = 0; } -extern void* D_8007E770; -extern /*?*/s32 D_8007EB98; -extern /*?*/s32 D_8009AD30; -extern s32 D_8009C544; -extern void* D_8009C6DC; - -void FieldEnablePartyModels(void) -{ - s16 temp_v0_3; - s16 var_a1; - s16 var_a2; - s16 var_a2_2; - s16 var_v0_2; - s16 var_v0_4; - s32 temp_a0_2; - s32 temp_v0_4; - s32 temp_v1_2; - s32 var_v0; - s32 var_v0_3; - s32 var_v0_5; - u8 temp_a0; - u8 temp_a0_3; - u8 temp_v0; - u8 temp_v0_2; - u8 temp_v1; - - var_a2 = 0; - var_v0 = 0 << 0x10; - do { - temp_v0 = D_8009D391[var_v0 >> 0x10]; - if ((temp_v0 != 0xFF) && (temp_v0_2 = *(&D_8009AD30 + temp_v0), (temp_v0_2 != 0xFF))) { - temp_a0 = *(&D_8007EB98 + temp_v0_2); - var_v0_2 = var_a2 + 1; - if (temp_a0 != 0xFF) { - var_v0_2 = var_a2 + 1; - if ((s32) temp_a0 < (s32) D_8007E770->unk2) { - g_FieldModelLoaderData[temp_a0].npcFlag = 1; - goto block_6; - } - } - } else { -block_6: - var_v0_2 = var_a2 + 1; - } - var_a2 = var_v0_2; - var_v0 = var_a2 << 0x10; - } while (var_v0_2 < 3); - var_a2_2 = 0; - if (D_8007E770->unk2 != 0) { - var_v0_3 = 0 << 0x10; - do { - temp_a0_2 = var_v0_3 >> 0x10; - temp_v1 = g_FieldModelLoaderData[temp_a0_2].npcFlag; - var_v0_4 = var_a2_2 + 1; - if (temp_v1 == 0) { - var_a1 = 0; - if ((s32) temp_v1 < (s32) D_8009C6DC->unk2) { - var_v0_5 = 0 << 0x10; - do { - temp_v0_4 = var_v0_5 >> 0x10; - temp_a0_3 = *(&D_8007EB98 + temp_v0_4); - if (temp_a0_3 == temp_a0_2) { - *(&D_8007EB98 + temp_v0_4) = 0xFF; - temp_v1_2 = temp_a0_3 * 0x84; - (temp_v1_2 + D_8009C544)->unk5C = 0; - (temp_v1_2 + D_8009C544)->unk59 = 1; - (temp_v1_2 + D_8009C544)->unk5B = 1; - } - temp_v0_3 = var_a1 + 1; - var_a1 = temp_v0_3; - var_v0_5 = var_a1 << 0x10; - } while (temp_v0_3 < (s32) D_8009C6DC->unk2); - } - var_v0_4 = var_a2_2 + 1; - } - var_a2_2 = var_v0_4; - var_v0_3 = var_a2_2 << 0x10; - } while (var_v0_4 < (s32) D_8007E770->unk2); - } -} +INCLUDE_ASM("asm/us/field/nonmatchings/field_event", FieldEnablePartyModels); void FieldEventOpcodeCycle(void) { s32 i, j, count; From e03b42349a5d4d8892d29932729a994fbff71471 Mon Sep 17 00:00:00 2001 From: Zaarin Date: Fri, 4 Sep 2026 11:42:49 +0200 Subject: [PATCH 3/6] Format --- include/game.h | 16 +++++----- src/field/field_event.c | 61 +++++++++++++-------------------------- src/field/field_opcodes.c | 30 +++++++------------ src/field/field_private.h | 19 +++++------- 4 files changed, 44 insertions(+), 82 deletions(-) diff --git a/include/game.h b/include/game.h index 8a6e5976..f1db322f 100644 --- a/include/game.h +++ b/include/game.h @@ -989,8 +989,7 @@ extern u8 D_800708D0[][0x1C]; // kernel-region table, by attack/effect id extern AttackData D_800722CC[]; // magic/summon/skill table extern WeaponRecord g_WeaponTable[]; // 0x800738A0, by weapon id extern FieldEntity g_FieldEntity[]; -extern u8 - g_FieldModelAnimStatus[16]; // per-model flags, indexed by field model id +extern u8 g_FieldModelAnimStatus[16]; // per-model flags, indexed by field model id extern s32 D_800756F8[]; extern Unk80075D00* D_80075D00; extern int D_80075DEC; // buffer index, either 0 or 1 @@ -1003,14 +1002,13 @@ extern DISPENV D_8007EB68[2]; extern u8 g_EntityToModel[48]; // entity id -> model id (0xFF: none) extern s8 D_8007EBCC; extern s8 D_8007EBDC; -extern u8 D_8007EBE0; // field debug mode -extern u8 g_CharacterLock; // mirror of the UC opcode's control-lock flag -extern u8 g_EntitySplitJoinState[48]; // states for SPLIT and JOIN opcodes -extern s16 - g_FieldModelEffAnimSpeed[16]; // per-model current animation playback speed +extern u8 D_8007EBE0; // field debug mode +extern u8 g_CharacterLock; // mirror of the UC opcode's control-lock flag +extern u8 g_EntitySplitJoinState[48]; // states for SPLIT and JOIN opcodes +extern s16 g_FieldModelEffAnimSpeed[16]; // per-model current animation playback speed extern u8 D_80083184[0x40]; -extern u8 D_800831C4[]; // Magic Order table from kernel.bin section 3. -extern u16 g_FieldScriptPC[48]; // program counters for active entity scripts +extern u8 D_800831C4[]; // Magic Order table from kernel.bin section 3. +extern u16 g_FieldScriptPC[48]; // program counters for active entity scripts extern u8 g_FieldModelAnimId[16]; // per-model default animation id (DFANM) extern u8 g_WindowToEntity[4]; extern WindowData g_WindowData[4]; diff --git a/src/field/field_event.c b/src/field/field_event.c index db945da5..35d6a6a2 100644 --- a/src/field/field_event.c +++ b/src/field/field_event.c @@ -35,8 +35,7 @@ void ResetPositionCursorPrimitives(void); void UpdatePositionCursor(OT_TYPE* ot); void DrawPositionCursor(OT_TYPE* ot); -void FieldEventInit(FieldState* fieldState, FieldEntity* fieldModels, - FieldScriptHeader* fieldScripts) { +void FieldEventInit(FieldState* fieldState, FieldEntity* fieldModels, FieldScriptHeader* fieldScripts) { g_pFieldState = fieldState; g_FieldModels = fieldModels; g_FieldScripts = fieldScripts; @@ -91,8 +90,7 @@ void FieldEventUpdate(OT_TYPE* ot) { } } if (g_WindowCount) { - SystemMenuDrawDialog( - g_WindowData, 4, ot, g_pFieldState->renderBuffer ^ 1); + SystemMenuDrawDialog(g_WindowData, 4, ot, g_pFieldState->renderBuffer ^ 1); } UpdatePositionCursor(ot); } @@ -197,8 +195,7 @@ void FieldInitDefaultValues(void) { g_FieldModels[i].animCurrentFrame = 0; g_FieldModels[i].animLastFrame = 0; g_FieldModels[i].visible = 0; - g_FieldModels[i].MoveSpeed = - 1024 * g_pFieldState->currentFieldScale / 512; + g_FieldModels[i].MoveSpeed = 1024 * g_pFieldState->currentFieldScale / 512; g_FieldModels[i].scriptedMoveMode = SMODE_NONE; g_FieldModels[i].ActionArg = 0; g_FieldModels[i].ActionState = 0; @@ -207,10 +204,8 @@ void FieldInitDefaultValues(void) { g_FieldModels[i].SolidOff = 0; g_FieldModels[i].TalkOff = 0; g_FieldModels[i].DirLock = 0; - g_FieldModels[i].SolidRange = - 30 * g_pFieldState->currentFieldScale / 512; - g_FieldModels[i].TalkRange = - 80 * g_pFieldState->currentFieldScale / 512; + g_FieldModels[i].SolidRange = 30 * g_pFieldState->currentFieldScale / 512; + g_FieldModels[i].TalkRange = 80 * g_pFieldState->currentFieldScale / 512; g_FieldModelAnimId[i] = 0; g_FieldModelAnimStatus[i] = ANIMSTATUS_DEFAULT_LOOP; g_FieldModelBaseAnimSpeed[i] = 16; @@ -262,14 +257,12 @@ void FieldInitDefaultValues(void) { void FieldEventRunInit(void) { g_FieldModelCount = 0; - for (g_CurrentEntity = 0; g_CurrentEntity < g_FieldScripts->numEntities; - g_CurrentEntity++) { + for (g_CurrentEntity = 0; g_CurrentEntity < g_FieldScripts->numEntities; g_CurrentEntity++) { s16 extrasHeaderSize; if (D_80071E24 & 3) { FieldDebugStringCopy(g_DebugText, D_800E0628); - FieldDebugStringConcat( - g_DebugText, GET_ENTITY_NAME(g_CurrentEntity)); + FieldDebugStringConcat(g_DebugText, GET_ENTITY_NAME(g_CurrentEntity)); if (D_80071E24 & 1) { SetStrToDebugRow(4, 0, g_DebugText); } @@ -279,15 +272,11 @@ void FieldEventRunInit(void) { } extrasHeaderSize = g_FieldScripts->numExtras * 4; - GET_FIELD_SCRIPT_OFFSET( - g_FieldScriptPC[g_CurrentEntity], 0, - 8 * g_FieldScripts->numEntities + 64 * g_CurrentEntity, - extrasHeaderSize); + GET_FIELD_SCRIPT_OFFSET(g_FieldScriptPC[g_CurrentEntity], 0, + 8 * g_FieldScripts->numEntities + 64 * g_CurrentEntity, extrasHeaderSize); // Keep executing the init script until we reach 0x00 = RET opcode. - while ((g_FieldCurrentOpcode = - ((u8*)g_FieldScripts)[g_FieldScriptPC[g_CurrentEntity]]) != - 0) { + while ((g_FieldCurrentOpcode = ((u8*)g_FieldScripts)[g_FieldScriptPC[g_CurrentEntity]]) != 0) { g_FieldOpcodes[g_FieldCurrentOpcode](); } g_FieldScriptPC[g_CurrentEntity]++; // Advance PC to the start of the @@ -438,16 +427,12 @@ void FieldUpdateAnimationState(void) { for (i = 0; i < g_FieldScripts->numEntities; i++) { if (g_EntityToModel[i] != 0xFF && - (g_pFieldState->pcModelId != g_EntityToModel[i] || - g_pFieldState->characterLock)) { + (g_pFieldState->pcModelId != g_EntityToModel[i] || g_pFieldState->characterLock)) { switch (g_FieldModelAnimStatus[g_EntityToModel[i]]) { case ANIMSTATUS_DEFAULT_LOOP: - if (g_FieldModels[g_EntityToModel[i]].activeAnimId != - g_FieldModelAnimId[g_EntityToModel[i]]) { - g_FieldModels[g_EntityToModel[i]].activeAnimId = - g_FieldModelAnimId[g_EntityToModel[i]]; - g_FieldModels[g_EntityToModel[i]].animSpeed = - g_FieldModelEffAnimSpeed[g_EntityToModel[i]]; + if (g_FieldModels[g_EntityToModel[i]].activeAnimId != g_FieldModelAnimId[g_EntityToModel[i]]) { + g_FieldModels[g_EntityToModel[i]].activeAnimId = g_FieldModelAnimId[g_EntityToModel[i]]; + g_FieldModels[g_EntityToModel[i]].animSpeed = g_FieldModelEffAnimSpeed[g_EntityToModel[i]]; g_FieldModels[g_EntityToModel[i]].animCurrentFrame = 0; modelEntryId = g_FieldModelLoaderData[g_EntityToModel[i]].modelEntryIndex; model = &g_FieldModelData->modelEntries[modelEntryId]; @@ -475,8 +460,7 @@ void FieldUpdateAnimationState(void) { case ANIMSTATUS_PLAY_ONCE_SYNC: if ((g_FieldModels[g_EntityToModel[i]].animCurrentFrame >> 4) >= g_FieldModels[g_EntityToModel[i]].animLastFrame) { - g_FieldModelAnimStatus[g_EntityToModel[i]] = - ANIMSTATUS_PLAY_ONCE_SYNC_DONE; + g_FieldModelAnimStatus[g_EntityToModel[i]] = ANIMSTATUS_PLAY_ONCE_SYNC_DONE; g_FieldModels[g_EntityToModel[i]].animCurrentFrame = g_FieldModels[g_EntityToModel[i]].animLastFrame << 4; } @@ -489,15 +473,13 @@ void FieldUpdateAnimationState(void) { case ANIMSTATUS_PLAY_ONCE_THEN_RESET: if ((g_FieldModels[g_EntityToModel[i]].animCurrentFrame >> 4) >= g_FieldModels[g_EntityToModel[i]].animLastFrame) { - g_FieldModelAnimStatus[g_EntityToModel[i]] = - ANIMSTATUS_DEFAULT_LOOP; + g_FieldModelAnimStatus[g_EntityToModel[i]] = ANIMSTATUS_DEFAULT_LOOP; } break; case ANIMSTATUS_PLAY_ONCE_THEN_HOLD: if ((g_FieldModels[g_EntityToModel[i]].animCurrentFrame >> 4) >= g_FieldModels[g_EntityToModel[i]].animLastFrame) { - g_FieldModelAnimStatus[g_EntityToModel[i]] = - ANIMSTATUS_HOLD_FRAME; + g_FieldModelAnimStatus[g_EntityToModel[i]] = ANIMSTATUS_HOLD_FRAME; } break; } @@ -550,8 +532,7 @@ u8 FieldEventRequestRun(s16 entityId, s16 priority, s16 scriptId) { entityDataSize = entityId * 64; entityDataSize += g_FieldScripts->numEntities * 8; - GET_FIELD_SCRIPT_OFFSET( - offset, scriptOffset, entityDataSize, extrasHeaderSize); + GET_FIELD_SCRIPT_OFFSET(offset, scriptOffset, entityDataSize, extrasHeaderSize); // Empty event scripts consist of just a RET (0x00) opcode. if (((u8*)g_FieldScripts)[offset] != 0) { @@ -621,8 +602,7 @@ void UpdatePositionCursor(OT_TYPE* ot) { if (g_pFieldState->pressedKeys & PADselect) { Savemap.memory_bank_4[30] ^= 1; } - if (((Savemap.memory_bank_4[30] == 1) && (!g_pFieldState->characterLock)) || - Savemap.memory_bank_4[30] & 2) { + if (((Savemap.memory_bank_4[30] == 1) && (!g_pFieldState->characterLock)) || Savemap.memory_bank_4[30] & 2) { DrawPositionCursor(ot); } } @@ -630,8 +610,7 @@ void UpdatePositionCursor(OT_TYPE* ot) { void DrawPositionCursor(OT_TYPE* ot) { s16 x, y; - if (!g_PosCursorDisabled && - ((g_PosCursorX != 32767) || (g_PosCursorY != 32767))) { + if (!g_PosCursorDisabled && ((g_PosCursorX != 32767) || (g_PosCursorY != 32767))) { if (g_PosCursorX > 320) { x = 320; } else { diff --git a/src/field/field_opcodes.c b/src/field/field_opcodes.c index 048862a7..41de11b0 100644 --- a/src/field/field_opcodes.c +++ b/src/field/field_opcodes.c @@ -192,8 +192,7 @@ void DebugUpdateActor(s16 arg0, s16 entityId) { if (D_80071E24 & 2) { DebugPrintToFieldWindow(g_DebugText); } - FieldDebugStringU8hex( - g_FieldModelAnimStatus[g_EntityToModel[entityId]], g_DebugText); + FieldDebugStringU8hex(g_FieldModelAnimStatus[g_EntityToModel[entityId]], g_DebugText); FieldDebugStringConcat(g_DebugText, "am"); FieldDebugStringU16hex(g_FieldModels[g_EntityToModel[entityId]].activeAnimId, g_DebugMessageBuffer); FieldDebugStringConcat(g_DebugText, g_DebugMessageBuffer); @@ -1973,10 +1972,8 @@ s32 FieldEventRequest(s16 type, u8 target, u8 priority, u8 scriptId) { entityDataSize = target * 64; extrasHeaderSize = (s16)(g_FieldScripts->numExtras * 4); - GET_FIELD_SCRIPT_OFFSET( - g_SavedFieldScriptPC[target][priority], scriptOffset, - entityDataSize + (g_FieldScripts->numEntities << 3), - extrasHeaderSize); + GET_FIELD_SCRIPT_OFFSET(g_SavedFieldScriptPC[target][priority], scriptOffset, + entityDataSize + (g_FieldScripts->numEntities << 3), extrasHeaderSize); if (g_DebugLevel & 3) { FieldDebugAddParseValueToPage2("rq=send", 0, 0); @@ -2005,10 +2002,8 @@ s32 FieldEventRequest(s16 type, u8 target, u8 priority, u8 scriptId) { entityDataSize = target * 64; extrasHeaderSize = (s16)(g_FieldScripts->numExtras * 4); - GET_FIELD_SCRIPT_OFFSET( - g_FieldScriptPC[target], scriptOffset, - entityDataSize + (g_FieldScripts->numEntities << 3), - extrasHeaderSize); + GET_FIELD_SCRIPT_OFFSET(g_FieldScriptPC[target], scriptOffset, + entityDataSize + (g_FieldScripts->numEntities << 3), extrasHeaderSize); g_FieldScriptPriority[target] = priority; @@ -2113,10 +2108,8 @@ s32 OpcodeFuncRetto(void) { scriptId *= 2; extrasHeaderSize = (s16)(g_FieldScripts->numExtras * 4); - GET_FIELD_SCRIPT_OFFSET( - g_FieldScriptPC[g_CurrentEntity], scriptId, - (g_FieldScripts->numEntities * 8) + (g_CurrentEntity * 64), - extrasHeaderSize); + GET_FIELD_SCRIPT_OFFSET(g_FieldScriptPC[g_CurrentEntity], scriptId, + (g_FieldScripts->numEntities * 8) + (g_CurrentEntity * 64), extrasHeaderSize); g_FieldScriptPriority[g_CurrentEntity] = priority; if (g_DebugLevel & 3) { @@ -2443,8 +2436,7 @@ s32 OpcodeFuncUc(void) { } g_CharacterLock = g_pFieldState->characterLock = GET_PARAM_U8(1); if (g_CharacterLock == 0) { - g_FieldModelAnimStatus[g_pFieldState->pcModelId] = - ANIMSTATUS_DEFAULT_LOOP; + g_FieldModelAnimStatus[g_pFieldState->pcModelId] = ANIMSTATUS_DEFAULT_LOOP; } PC_INC(2); return 0; @@ -2542,8 +2534,7 @@ s32 OpcodeFuncDfanm(void) { if (g_EntityToModel[g_CurrentEntity] != 0xFF) { g_FieldModelAnimId[g_EntityToModel[g_CurrentEntity]] = GET_PARAM_U8(1); g_FieldModelEffAnimSpeed[g_EntityToModel[g_CurrentEntity]] = - g_FieldModelBaseAnimSpeed[g_EntityToModel[g_CurrentEntity]] / - GET_PARAM_U8(2); + g_FieldModelBaseAnimSpeed[g_EntityToModel[g_CurrentEntity]] / GET_PARAM_U8(2); modelIdx = g_EntityToModel[g_CurrentEntity]; if (g_FieldModelAnimStatus[modelIdx] == ANIMSTATUS_HOLD_FRAME) { g_FieldModelAnimStatus[modelIdx] = ANIMSTATUS_DEFAULT_LOOP; @@ -2590,8 +2581,7 @@ void StartModelAnimation(void) { g_FieldModels[g_EntityToModel[g_CurrentEntity]].activeAnimId = GET_PARAM_U8(1); g_FieldModels[g_EntityToModel[g_CurrentEntity]].animSpeed = - g_FieldModelBaseAnimSpeed[g_EntityToModel[g_CurrentEntity]] / - GET_PARAM_U8(2); + g_FieldModelBaseAnimSpeed[g_EntityToModel[g_CurrentEntity]] / GET_PARAM_U8(2); g_FieldModels[g_EntityToModel[g_CurrentEntity]].animCurrentFrame = 0; modelIdx = g_EntityToModel[g_CurrentEntity]; model = &g_FieldModelData->modelEntries[g_FieldModelLoaderData[modelIdx].modelEntryIndex]; diff --git a/src/field/field_private.h b/src/field/field_private.h index ba8c94b5..fe86b6de 100644 --- a/src/field/field_private.h +++ b/src/field/field_private.h @@ -1,18 +1,13 @@ #ifndef FIELD_PRIVATE_H #define FIELD_PRIVATE_H -#define GET_ENTITY_NAME(entityId) \ - ((char*)g_FieldScripts + sizeof(FieldScriptHeader) + (entityId) * 8) +#define GET_ENTITY_NAME(entityId) ((char*)g_FieldScripts + sizeof(FieldScriptHeader) + (entityId) * 8) -#define GET_FIELD_SCRIPT_OFFSET( \ - dst, scriptOffset, entityDataOffset, extrasHeaderSize) \ - (dst) = *((u8*)((scriptOffset) + (entityDataOffset) + (extrasHeaderSize) + \ - (s32)g_FieldScripts) + \ - sizeof(FieldScriptHeader)); \ - (dst) |= \ - *((u8*)((scriptOffset) + ((entityDataOffset) + (s32)g_FieldScripts) + \ - (extrasHeaderSize)) + \ - sizeof(FieldScriptHeader) + 1) \ - << 8 +#define GET_FIELD_SCRIPT_OFFSET(dst, scriptOffset, entityDataOffset, extrasHeaderSize) \ + (dst) = *((u8*)((scriptOffset) + (entityDataOffset) + (extrasHeaderSize) + (s32)g_FieldScripts) + \ + sizeof(FieldScriptHeader)); \ + (dst) |= *((u8*)((scriptOffset) + ((entityDataOffset) + (s32)g_FieldScripts) + (extrasHeaderSize)) + \ + sizeof(FieldScriptHeader) + 1) \ + << 8 #endif From 4d22cce1f3c6e916d9002f8984841934e1da980f Mon Sep 17 00:00:00 2001 From: Zaarin Date: Fri, 4 Sep 2026 11:46:35 +0200 Subject: [PATCH 4/6] Missing symbol --- config/sym_extern.us.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/sym_extern.us.txt b/config/sym_extern.us.txt index 1214267c..f15f22ae 100644 --- a/config/sym_extern.us.txt +++ b/config/sym_extern.us.txt @@ -26,6 +26,7 @@ g_EntitySplitJoinState = 0x80081D90; g_CharacterLock = 0x80081DC4; g_FieldModelEffAnimSpeed = 0x80082248; g_FieldScriptPC = 0x800831FC; + g_FieldModelAnimId = 0x8008325C; g_WindowToEntity = 0x8008326C; g_WindowData = 0x80083274; @@ -50,6 +51,7 @@ g_CharacterLevelData = 0x8009D7E4; g_BattleItemsEarned = 0x8009D808; g_DebugLevel = 0x8009D820; g_FieldModelBaseAnimSpeed = 0x8009D828; +g_ActiveCharacters = 0x8009D84C; func_800A0000 = 0x800A0000; func_800A0030 = 0x800A0030; func_800A00BC = 0x800A00BC; From 65cfbb5fbfef7c5e8191dc06fddce928002d8ef5 Mon Sep 17 00:00:00 2001 From: Zaarin Date: Mon, 7 Sep 2026 23:47:53 +0200 Subject: [PATCH 5/6] Formatting --- src/field/field_event.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/field/field_event.c b/src/field/field_event.c index 35d6a6a2..54752c2a 100644 --- a/src/field/field_event.c +++ b/src/field/field_event.c @@ -142,7 +142,6 @@ void FieldInitDefaultValues(void) { for (i = 0; i < 256; i++) { g_FieldMapVars[i] = 0; } - for (i = 0; i < 8; i++) { for (j = 0; j < g_FieldScripts->numEntities; j++) { g_SavedFieldScriptPC[j][i] = 0; @@ -151,7 +150,6 @@ void FieldInitDefaultValues(void) { SavedScriptIds[j][i] = 0; } } - for (i = 0; i < g_FieldScripts->numEntities; i++) { g_FieldScriptPriority[i] = 7; g_EntityToModel[i] = 0xFF; @@ -160,7 +158,6 @@ void FieldInitDefaultValues(void) { g_EntityToLine[i] = 0xFF; D_80114498[i] = 0; } - for (i = 0; i < g_FieldScripts->numModels; i++) { g_FieldModels[i].charId = 0; g_FieldModels[i].PosX = 0; @@ -216,7 +213,6 @@ void FieldInitDefaultValues(void) { g_FieldModels[i].BlinkOn = 0; g_FieldModels[i].KawaiA = 0; } - for (i = 0; i < 64; i++) { g_pFieldState->backgroundLayerVisibility[i] = 0; } @@ -228,7 +224,6 @@ void FieldInitDefaultValues(void) { g_FieldPaletteBuffer[i][j] = 0; } } - for (i = 0; i < 32; i++) { g_FieldLines[i].requestTalkScript = 0; g_FieldLines[i].requestPushScript = 0; @@ -628,8 +623,7 @@ void DrawPositionCursor(OT_TYPE* ot) { y = 0; } g_PosCursorPrimId ^= 1; - // Rotate cursor about the Y axis when player is on right edge of - // screen. + // Rotate cursor about the Y axis when player is on right edge of screen. if (x > 290) { g_PosCursorPrims[g_PosCursorPrimId].u0 = 143; g_PosCursorPrims[g_PosCursorPrimId].u1 = 127; @@ -649,8 +643,7 @@ void DrawPositionCursor(OT_TYPE* ot) { g_PosCursorPrims[g_PosCursorPrimId].x2 = x; g_PosCursorPrims[g_PosCursorPrimId].x3 = x + 16; } - // Rotate cursor about the X axis when player is at the top of the - // screen. + // Rotate cursor about the X axis when player is at the top of the screen. if (y <= 16) { g_PosCursorPrims[g_PosCursorPrimId].v0 = 111; g_PosCursorPrims[g_PosCursorPrimId].v1 = 111; From a61af302db6a516e2e4b8b53b772453297e29a3f Mon Sep 17 00:00:00 2001 From: Zaarin Date: Tue, 8 Sep 2026 00:08:49 +0200 Subject: [PATCH 6/6] More formatting --- include/game.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/game.h b/include/game.h index f1db322f..bd10e447 100644 --- a/include/game.h +++ b/include/game.h @@ -1059,7 +1059,7 @@ extern u8 g_DebugLevel; // field debug related extern CharacterLevelData g_CharacterLevelData[3]; extern u8 D_8009D824; extern s16 g_FieldModelBaseAnimSpeed[16]; // per-model base animation speed -extern s16 D_8009D85C[]; // record fields, stride 0x440 +extern s16 D_8009D85C[]; // record fields, stride 0x440 extern BattleItemReward g_BattleItemsEarned[4]; extern u8 D_8009D8F8[]; extern u32 D_8009D260;