Alchemy

src/field

games/tbs/src/field on GitHub

The Field guide explains this folder.

Folders

curve_data.c

games/tbs/src/field/curve_data.c

Globals

gCurve_SampleIndexTable

const u8 gCurve_SampleIndexTable[256]

The sample Curve_LookupSampleByTable reads at each position: 0, 1 or 2, split along two diagonals.

Used by Curve_LookupSampleByTable, Curve_LookupSampleByTableReversed.

Line 29

Also, globals without a comment: gCurve_LerpWeightTable.

facing.c

games/tbs/src/field/facing.c

Globals

gMap_TileDissolveOrder

const u8 gMap_TileDissolveOrder[64]

The order in which the 64 pixels of a sprite's tile in OBJ VRAM dissolve; read by Map_RenderAnimatedTileFrame (objects.c).

Used by Map_RenderAnimatedTileFrame.

Line 68

gMap_TileDissolveTail

const u16 gMap_TileDissolveTail

Two bytes after the dissolve order; no code in The Broken Seal names them.

Line 76

gCamera_FixedViewMatrix

const s32 gCamera_FixedViewMatrix[12]

The fixed camera's view matrix (Q16): identity with a -0.8 shear of y by x. ObjectSystem_UpdateCameraFixed applies it while battle commands are chosen.

Used by ObjectSystem_UpdateCameraFixed.

Line 80

gScriptObject_CycleTable

const s32 gScriptObject_CycleTable[32]

One period of a triangle wave, which bobs a floating object up and down. Object_UpdateAllThumb reads it at half the object's phase, scaled by its gravity.

Used by Object_UpdateAllThumb.

Line 90

gScript_MainScript

const s32 gScript_MainScript[1]

The idle script an object returns to when its own one ends: a lone SC_END, which reloads it. Script_End (SC_END) points an object here.

Used by Script_End.

Line 99

gScript_MainScriptTail

const s16 gScript_MainScriptTail[8]

Halfwords that follow the main script; no code in The Broken Seal names them.

Line 105

gWorldMap_KeyHeadings

const u16 gWorldMap_KeyHeadings[16]

The heading for each state of the direction pad (bits 4-7 of the keys); 0xffff means no direction is held, or only an opposite pair. Read by FieldObject_UpdatePlayerControl, Object_MoveOnWorldMap and Object_MoveByKeys.

Used by FieldObject_UpdatePlayerControl, Object_MoveByKeys, Object_MoveOnWorldMap.

Line 113

gWorldMap_FootprintActions

const s32 gWorldMap_FootprintActions[6]

Two scripts for the world map's footprint and dust effects: wait 120 or 30 frames, then release the object. FieldObject_UpdatePlayerControl starts the first and Object_MoveOnWorldMap the second (three words in).

Used by FieldObject_UpdatePlayerControl, Object_MoveOnWorldMap.

Line 121

gWorldMap_KeyYaws

const s32 gWorldMap_KeyYaws[16]

The world map camera's turn rate for each state of the direction pad, read by Object_MoveOnWorldMap.

Used by Object_MoveOnWorldMap.

Line 128

Also, globals without a comment: gAnimationFacing_Kind1, gAnimationFacing_Kind22, gAnimationFacing_Kind2, gAnimationFacing_Kind3, gAnimationFacing_Kind5, gAnimationFacing_Kind8, gAnimationFacing_Kind88, gAnimationFacing_Kind4, gAnimationFacing_Kind6.

field.c

games/tbs/src/field/field.c

The field object: the engine of the field and the world map. It draws and animates sprites, keeps the 64 field objects and runs their scripts, moves the player by the keys, loads, draws and scrolls the maps, and answers what the ground is like under a point. field_internal.h holds what the parts share; the parts under field/ are included here in the order their code has in the ROM. Camelot's own files are not recoverable: the ROM shows one object, and these parts are ours, cut where one family ends and the next begins.

README.md in this folder gives the words, prefixes and spellings the parts use. Where to start:

  Sprites         sprite_draw.c: Sprite_ComposeAnimationFrame,
                  Render_PlaceProjectedSprite; animation.c:
                  ResourceObject_Create, AnimationObjects_SelectAnimation
  Objects         objects.c: FieldObject_Create, ObjectSystem_Initialize;
                  object_motion.c: Object_UpdateAllThumb,
                  Object_SetMoveTarget
  Object scripts  script_commands.c (the SC_ commands of objcmd.h);
                  player_control.c: FieldObject_UpdatePlayerControl
  Maps            map_layers.c: Map_LoadLayeredScene,
                  Map_UpdateLayerScroll; world_map.c:
                  Map_InitializePerspectiveScene, WorldMap_UpdateView
  Ground          terrain.c: Map_GetTerrainHeight, Map_CheckObjectStep,
                  GetWorldMapCollision

field_internal.h

games/tbs/src/field/field_internal.h

Enumerations

AnimationCommand

enum AnimationCommand

Animation script commands. A script is pairs of bytes, a command and its argument; a command below 239 shows that frame for arg frames at normal speed (the timer counts sixteenths, less AnimationEntry.step each frame).

Value=
ANIM_CMD_END239blank the layer and stop its script
ANIM_CMD_SET_KIND240use facing table arg
ANIM_CMD_HOLD241stay on this command and frame for good
ANIM_CMD_WAIT245keep the current frame arg frames longer
ANIM_CMD_JUMP253continue at script position arg
ANIM_CMD_PLAY254switch to animation arg
ANIM_CMD_BLANK255show nothing for arg

Line 83

Macros

TARGET_UNSET

#define TARGET_UNSET ((s32)0x80000000)

A movement target coordinate that is not set.

Used by Camera_FollowLeaderInBounds, FieldObject_UpdatePlayerControl, Object_IsTargetUnset, Object_MoveByKeys, Object_MoveOnWorldMap, Object_SetMoveTarget, Object_SetPositionAndResetMotion, Object_UpdateAll, Object_UpdateAllMotion, Object_UpdateAllThumb.

Line 111

griddata.c

games/tbs/src/field/griddata.c

Globals

gBattle_FormationPlacementScale

const struct SpriteScale gBattle_FormationPlacementScale

The sprite viewer's (x, y) sprite scale, 1.0 each (Q16), which Battle_PlaceActorsByFormationKind reads.

Used by Battle_PlaceActorsByFormationKind.

Line 7

lucky_dice.c

games/tbs/src/field/lucky_dice.c

Functions

Runtime_BlankDisplayAndRun

s32 Runtime_BlankDisplayAndRun(void)

Starts the Lucky Dice minigame: leaves only the backdrop on screen, starts song MUS_009 and plays until the player quits. Returns 0. Reached through Runtime_BlankDisplayAndRunFar from RunLuckyDice (object/object/scene.c), which saves background palettes 14 and 15 around it and passes an entrance this function does not take.

Line 31

Camera_ResetSceneDefaults

void Camera_ResetSceneDefaults(void)

Puts the 3D camera back at its scene defaults: at the origin, unturned, pitched to 152 and 510 units away, following nothing. Recomputes the eye and sets the projection's focal length (250), near plane and far plane. Called only by LuckyDice_Run, once the camera's heap block is allocated; writes gCameraWork's fields and gProjection.

Used by LuckyDice_Run.

Line 43

FixedPoint_Multiply8_8

UNUSED s32 FixedPoint_Multiply8_8(s32 leftValue, s32 rightValue)

Multiplies two 8.8 fixed-point values, rounding toward zero.

Line 77

Math_ScaleByRatio

UNUSED s16 Math_ScaleByRatio(s16 numerator, s16 denominator)

Divides two 8.8 fixed-point values.

Line 99

FixedPoint_Reciprocal

UNUSED s16 FixedPoint_Reciprocal(s16 value)

The reciprocal of an 8.8 fixed-point value.

Line 109

Graphics_ScaleRgb555Buffer

s32 Graphics_ScaleRgb555Buffer(u16 *source, u16 *destination, s32 scale, s32 count)

Copies count RGB555 colours from source to destination with each channel multiplied by scale (16.16: 0 is black, 0x10000 unchanged), for fades. Returns 0. Called only by LuckyDice_Run, to fade both palettes in and out.

Used by LuckyDice_Run.

Line 208

LuckyDice_Run

void LuckyDice_Run(void)

Runs the Lucky Dice minigame until the player quits or cannot afford a throw. Each throw costs ten coins per level of the party's average. Two dice are thrown onto a board of six rows; each die's face and the row it stops in give four numbers. Four of a kind pays 5 times the bet (15 or 25 times when it matches one of the two lucky numbers shown at the top), three of a kind 3 times, two pairs twice and one pair the bet back. Called by Runtime_BlankDisplayAndRun. Takes the bet from and pays the winnings into gGameState.coins, resets the scheduler's task table, and frees the five heap slots it allocates before it returns.

Used by Runtime_BlankDisplayAndRun.

Line 252

Structures

LuckyDiceSprites

struct LuckyDiceSprites

The used prefix of Lucky Dice's 0x618-byte work block (heap slot 45): its sprites and windows. The allocation extends beyond these members.

FieldDeclared as
filleru8 filler[200]Lucky Dice never touches these bytes
objstruct OamShadow obj[128]copied to OAM each frame
coinsWindowstruct UiWindow *coinsWindowthe player's coins
winningsWindowstruct UiWindow *winningsWindowthe winnings of the last throw
helpWindowstruct UiWindow *helpWindowthe Throw and Quit buttons

Used by LuckyDice_Run.

Line 180

Enumerations

LuckyDiceState

enum LuckyDiceState

What the Lucky Dice screen is doing.

Value=
LUCKY_DICE_AIMthe dice wait to be thrown; Up and Down raise them
LUCKY_DICE_ROLLthe dice fly, bounce and settle
LUCKY_DICE_RESULTthe four numbers and the result are shown
LUCKY_DICE_PAYOUTthe winnings move into the coins

Line 198

Macros, without a comment: DICE_COIN_X, DICE_COIN_W, DICE_WIN_W, DICE_COIN_X, DICE_COIN_W, DICE_WIN_W, DICE_COIN_X, DICE_COIN_W, DICE_WIN_W, DICE_LABEL_X, DICE_LABEL_X, DICE_LABEL_X, DICE_HELP_X, DICE_HELP_W, DICE_HELP_X, DICE_HELP_W, DICE_HELP_X, DICE_HELP_W, DICE_HELP_X, DICE_HELP_W, DICE_WIN_X, DICE_WIN_NUM_X, DICE_WIN_LABEL_X, DICE_KIND_X, DICE_WIN_X, DICE_WIN_NUM_X, DICE_WIN_LABEL_X, DICE_KIND_X, DICE_COUNT, DICE_FACE_COUNT, DICE_RESULT_COUNT, DICE_BET_PER_LEVEL.

mapdata.c

games/tbs/src/field/mapdata.c

Map terrain: the height curve of each cell kind and the world map's terrain behaviour.

Globals

gMap_TerrainHeightFunctions

const TerrainHeightFn gMap_TerrainHeightFunctions[16]

Terrain height functions, chosen by the low four bits of a cell's first collision byte and called with (the remaining samples, x within the cell, y within the cell). Each reads only the arguments it needs. Read by Map_GetTerrainHeight and Map_CheckObjectStep (terrain.c).

Used by Map_CheckObjectStep, Map_GetTerrainHeight.

Line 14

gWorldMap_DirectionOffsets

const s8 gWorldMap_DirectionOffsets[8][2]

The eight compass directions as (x, y) offsets of radius 40. No code in The Broken Seal names it.

Line 46

gWorldMap_UnitScale

const u32 gWorldMap_UnitScale[2]

Two 1.0s (Q16). No code in The Broken Seal names it; The Lost Age's battle effects read its copy as a unit scale.

Line 53

Also, globals without a comment: gWorldMap_TerrainBehaviorTable.

object_script.c

games/tbs/src/field/object_script.c

Field object scripts: the ones the engine starts itself, and the command table.

Globals

gObjectDispatch_DefaultScript

const s32 gObjectDispatch_DefaultScript[]

The script FieldObject_Create gives every new object: it does nothing and returns to the idle script.

Used by FieldObject_Create.

Line 14

gObjectDispatch_KeyCheckScript

const s32 gObjectDispatch_KeyCheckScript[]

Runs SC_KEY_COUNT every frame; started by ObjectDispatch_StartKeyCheck. This and the scripts below each repeat one command every frame.

Used by ObjectDispatch_StartKeyCheck.

Line 20

gObjectDispatch_KeysScript

const s32 gObjectDispatch_KeysScript[]

Started by ObjectDispatch_StartMoveByKeys.

Used by ObjectDispatch_StartMoveByKeys.

Line 27

gObjectDispatch_PlayerScript

const s32 gObjectDispatch_PlayerScript[]

Started by ObjectDispatch_StartPlayerControl.

Used by ObjectDispatch_StartPlayerControl.

Line 34

gObjectDispatch_WorldMapScript

const s32 gObjectDispatch_WorldMapScript[]

Started by ObjectDispatch_StartWorldMapControl.

Used by ObjectDispatch_StartWorldMapControl.

Line 41

gObjectDispatch_CameraScript

const s32 gObjectDispatch_CameraScript[]

Started by ObjectDispatch_StartCamera.

Used by ObjectDispatch_StartCamera.

Line 48

gObjectDispatch_ApproachLinkScript

const s32 gObjectDispatch_ApproachLinkScript[]

Started by ObjectDispatch_StartApproachLink.

Used by ObjectDispatch_StartApproachLink.

Line 55

gObjectDispatch_EndScript

const s32 gObjectDispatch_EndScript[]

The idle script ObjectDispatch_StartIdle gives an object.

Used by ObjectDispatch_StartIdle.

Line 62

gScriptObject_CommandTable

const ScriptCommand gScriptObject_CommandTable[47]

The handler for each script command number; 0x24 onwards act as SC_END. Object_UpdateAll (update.c) and Object_UpdateAllThumb (object_motion.c) call through it.

Used by Object_UpdateAll, Object_UpdateAllThumb.

Line 69

operand.c

games/tbs/src/field/operand.c

Script work values: the handler SC_SET, SC_ADD and SC_CMP call for each.

Globals

gScript_OperandHandlerTable

const OperandFunc gScript_OperandHandlerTable[41]

The handler for each work value number (enum ScriptWork).

Used by Script_ApplyOperandCommand.

Line 9

update.c

games/tbs/src/field/update.c

Functions

Object_UpdateAll

void Object_UpdateAll(void)

Advances the eight script-driven objects by one frame. For each live one: run its hook, then its script (unless it waits or is paused); steer it towards its target, or brake it when it has none; apply gravity and bounce off the ground; detect arrival at the target; and turn it to face the way it moves. Copied to RAM and run from there. Writes each object's position, velocity and facing, and unsets its target on arrival. Only Object_RunUpdateAllFromHeap copies and runs it, and nothing calls that; the field runs Object_UpdateAllThumb instead.

Used by Object_RunUpdateAllFromHeap.

Line 36

Macros

IWRAM_ENTRY

#define IWRAM_ENTRY(type, offset) ((type)(IwramIrqMain + (offset)))

Calls a resident IWRAM routine at its absolute address, which this code still reaches when it runs from its copy in RAM.

Line 16

Also, macros without a comment: OBJECT_SLOTS, TARGET_UNSET, TURN_MAX, IwramSqrt, IwramRatioMulQ14.

Globals, without a comment: gObjectSlots.

Declarations, without a comment: ArcTan2FarArm, IwramSqrtFarArm, IwramRatioMulQ14FarArm.

vertices.c

games/tbs/src/field/vertices.c

Functions

Transform_UpdateVertices

void Transform_UpdateVertices(struct Position *eye, struct Position *target, struct ScanVertex *line, struct BgAffine *affine)

Builds the world map's per-scanline affine table for one frame: the ground plane seen from eye towards target. line points at the 160 scanlines' ground terms, whose rotation terms stay cached while the yaw (gScanlineAngle) is unchanged; affine receives each line's parameters twice, for BG2 and then BG3, as the HBlank DMA writes both. Copied to RAM (heap slot 46) by Map_InitializePerspectiveScene, which runs it once, and run from there each frame by WorldMap_UpdateView into the affine page of the frame's parity. Writes gScanlineAngle when the yaw changes.

Line 88

Structures

RuntimeUnusedEntry

struct RuntimeUnusedEntry

An eight-byte runtime entry contains the ldr/bx instructions and a target word. Entries this routine does not call keep their target word opaque.

FieldDeclared as
stubu32 stub
targetu32 target

Line 12

RuntimeMathBinaryEntry

struct RuntimeMathBinaryEntry

A runtime table entry whose two-argument target this routine calls, the arctangent.

FieldDeclared as
stubu32 stub
targets32 (*target)(s32 x, s32 y)

Line 19

RuntimeMathUnaryEntry

struct RuntimeMathUnaryEntry

A runtime table entry whose one-argument target this routine calls, the sine or the cosine.

FieldDeclared as
stubu32 stub
targets32 (*target)(s32 angle)

Line 26

RuntimeMathTable

struct RuntimeMathTable

The runtime table's prefix through Trig_Cos, in its assembly order. This routine runs from a RAM copy and calls the target words, not the ROM stubs.

FieldDeclared as
precedingstruct RuntimeUnusedEntry preceding[8]
atan2struct RuntimeMathBinaryEntry atan2
squareRootsstruct RuntimeUnusedEntry squareRoots[2]
sinstruct RuntimeMathUnaryEntry sin
cosstruct RuntimeMathUnaryEntry cos

Used by FarCall_RuntimeTable.

Line 33

Position

struct Position

The camera's eye or target point, as this routine reads it.

FieldDeclared as
xs32 x
ys32 y
zs32 z

Used by Transform_UpdateVertices.

Line 52

ScanVertex

struct ScanVertex

One scanline of the world map's ground plane. WorldMap_BuildScanlineTable fills x (the line's width scale) and z (its depth); the rest caches the rotation terms this routine computes from them for the current angle.

FieldDeclared as
xs32 xthe line's width scale
zs32 zthe line's depth
dxs32 dxthe texture x offset from the origin, before >> 8
dzs32 dzthe texture y offset from the origin, before >> 8
us16 uthe cached BG2PA
vs16 vthe cached BG2PC

Used by Transform_UpdateVertices.

Line 61

BgAffine

struct BgAffine

One background's affine registers, BG2PA to BG2Y.

FieldDeclared as
pas16 pa
pbs16 pbnot written by this routine
pcs16 pc
pds16 pdnot written by this routine
xs32 x
ys32 y

Used by Transform_UpdateVertices.

Line 71

Macros, without a comment: VISIBLE_SCANLINES.

Globals, without a comment: FarCall_RuntimeTable, gScanlineAngle.

world_map_resources.c

games/tbs/src/field/world_map_resources.c

World map graphics: a palette and five tile sets for each of its two looks.

Globals

gWorldMap_GraphicsResources

u32 gWorldMap_GraphicsResources[2][6]

Each set is a palette and five tile sets; WorldMap_LoadGraphics takes the second set when the cell it loads at has terrain kind 21, and keeps the set's row in the perspective work's resources. Not const: the loader reads it through a u32 *.

Line 12

On this page