7#if LANGUAGE == LANGUAGE_JAPANESE
8#define TARGET_MYSTERY_NAME_COPY UiText_DecodeMessage
9#define TARGET_MYSTERY_NAME_CAPACITY 10
11#define TARGET_MYSTERY_NAME_COPY UiText_CopyMessageString
12#define TARGET_MYSTERY_NAME_CAPACITY 14
32 u16 spreadActorIds[14];
33 u8 spreadTrackIndices[8];
48 register struct UiWindow *conditionWindow
asm(
"r9");
92 if (mode == 2 || mode == 4)
97 if (mode == 2 || mode == 4)
102 for (i = 0; i < 6; i++)
103 cursorTracks[i].flags = 0;
106 for (i = 0; i <= 5 && battle->
partyUnits[i] != 0xFF; i++) {
107 candidateIds[targetCount] = battle->
partyUnits[i];
110 }
else if (mode == 4) {
111 candidateIds[0] = (
u16)selection;
114 for (i = 0; i <= 5 && battle->
enemyIds[i] != 0xFF; i++) {
115 candidateIds[targetCount] = battle->
enemyIds[i];
120 candidateIds[targetCount] = 0xFF;
121 candidateCount = targetCount;
126 for (j = 0; j < targetCount; j++) {
129 if (candidateIds[j] == 0xFE)
134 if (candidate->
hp == 0) {
135 selection = candidateIds[j];
140 if (candidate->
poison != 0)
153 candidate->
haunt != 0)
158 selection = candidateIds[j];
163 for (j = 0; j < targetCount; j++) {
164 if (candidateIds[j] == selection)
167 if (j != targetCount)
171 targetIndex = (targetCount - 1) / 2;
172 while (candidateIds[targetIndex] == 0xFE ||
175 targetIndex = targetIndex + targetCount - 1;
176 targetIndex %= targetCount;
181 cursorTracks[0].
flags = 8;
182 cursorTracks[0].
x = (
u8)actorPosition.
x;
183 cursorTracks[0].
y = 0x80;
187 firstSprite = cursorSprites;
190 s32 t = targetIndex * 2;
204 *(
u16 *)((
u8 *)candidateIds + t),
207 ((
s32 *)firstSprite)[1] = 0x40002000;
208 ((
s32 *)firstSprite)[2] = 0;
213 y = selectedPosition.
y;
214 if (cursorTracks[0].flags & 1) {
215 cursorX = (selectedPosition.
x + cursorTracks[0].
x) / 2;
216 cursorY = (y + cursorTracks[0].
y) / 2;
217 if ((selectedPosition.
x - cursorX < 0
218 ? -(selectedPosition.
x - cursorX)
219 : selectedPosition.
x - cursorX) <= 7)
221 selectedPosition.
x = cursorX;
222 cursorTracks[0].
x = (
u8)cursorX;
223 cursorTracks[0].
y = (
u8)cursorY;
224 selectedPosition.
y = cursorY;
225 }
else if ((
u8)cursorTracks[0].flags <= 3) {
226 cursorTracks[0].
x = (
u8)selectedPosition.
x;
227 selectedPosition.
y = y;
228 cursorTracks[0].
y = (
u8)y;
229 cursorTracks[0].
flags = 1;
231 selectedPosition.
x = cursorTracks[0].
x;
232 selectedPosition.
y = cursorTracks[0].
y;
233 cursorTracks[0].
flags = (
u8)(cursorTracks[0].flags - 4);
234 if (cursorTracks[0].flags <= 3)
235 cursorTracks[0].
flags = 1;
237 firstSprite->
x = selectedPosition.
x - 8;
238 firstSprite->
y = (
u8)(selectedPosition.
y - 16);
248#if !(LANGUAGE == LANGUAGE_SPANISH) && !(LANGUAGE == LANGUAGE_ITALIAN)
273 for (i = 0; i < 6; i++)
274 cursorTracks[i].flags &= (
u8)~2;
275 for (i = 0; (
u32)i < spread; i++) {
278 if (n < candidateCount && candidateIds[n] != 0xFE) {
279 spreadActorIds[targetCount] = candidateIds[n];
280 cursorTracks[i].
flags |= 2;
281 if (cursorTracks[i].index != i) {
282 cursorTracks[i].
flags &= (
u8)~1;
285 spreadTrackIndices[targetCount] = (
u8)i;
288 if (i != 0 && (n = targetIndex - i) >= 0 && candidateIds[n] != 0xFE) {
289 spreadActorIds[targetCount] = candidateIds[n];
290 cursorTracks[6 - i].
flags |= 2;
291 if (cursorTracks[6 - i].index != -i) {
292 cursorTracks[6 - i].
flags &= (
u8)~1;
293 cursorTracks[6 - i].
index = (
s8)-i;
295 spreadTrackIndices[targetCount] = (
u8)(6 - i);
300 for (i = 0; i < 6; i++) {
301 if ((cursorTracks[i].flags & 2) == 0)
302 cursorTracks[i].
index = 6;
304 spreadActorIds[targetCount] = 0xFF;
306 if (candidateIds[targetIndex] <= 7) {
310 candidateIds[targetIndex],
312 if (conditionWindow != 0)
318 anchor = selectedPosition.
x / 8;
319 helpColumn = anchor - 4;
320#if (LANGUAGE == LANGUAGE_SPANISH) || (LANGUAGE == LANGUAGE_ITALIAN)
334#elif (LANGUAGE == LANGUAGE_FRENCH)
338#elif (LANGUAGE == LANGUAGE_JAPANESE)
356 anchor = selectedPosition.
x / 8;
357 helpColumn = anchor - 7;
362#if (LANGUAGE == LANGUAGE_SPANISH) || (LANGUAGE == LANGUAGE_ITALIAN)
366 conditionWindow, 0, 0);
370 conditionWindow, 0, 0);
374 conditionWindow, 0, 0);
378 conditionWindow, 0, 0);
383 conditionWindow, 0, 0);
387 conditionWindow, 48, 0);
393 anchor = selectedPosition.
x / 8;
394 helpColumn = anchor - 7;
400 conditionWindow, 0, 0);
403 conditionWindow, 48, 0);
409 anchor = selectedPosition.
x / 8;
410 helpColumn = anchor - 7;
423 anchor = selectedPosition.
x / 8;
424 helpColumn = anchor - 7;
440 if (unit->
sleep != 0)
454 anchor = selectedPosition.
x / 8;
455 helpColumn = anchor - 7;
456#if (LANGUAGE == LANGUAGE_SPANISH) || (LANGUAGE == LANGUAGE_ITALIAN)
458 if (anchor + 10 > 29)
468#elif (LANGUAGE == LANGUAGE_JAPANESE)
483 conditionWindow, 0, 0);
486 if (unit->
stun != 0) {
491 if (unit->
sleep != 0) {
519 if (unit->
sleep != 0)
525 if (unit->
haunt != 0)
535 anchor = selectedPosition.
x / 8;
536 helpColumn = anchor - 7;
537#if (LANGUAGE == LANGUAGE_SPANISH) || (LANGUAGE == LANGUAGE_ITALIAN)
539 if (anchor + 10 > 29)
549#elif (LANGUAGE == LANGUAGE_JAPANESE)
569 conditionWindow, 0, count * 8);
572 if (unit->
stun != 0) {
577 if (unit->
sleep != 0) {
592 if (unit->
haunt != 0) {
608 target =
UnitGetFar(candidateIds[targetIndex]);
610 candidateIds[targetIndex],
614 width = MsgMysteryPersonName;
620 for (i = 0; i <= 13; i++) {
621 targetName[i] = n = target->
name[i];
628 namePosition.
x -= width / 2;
630 if (namePosition.
x + width > 224)
631 namePosition.
x = 224 - width;
632 if (namePosition.
x < 0)
639 if (drawCursors != 0) {
640 for (i = 1; i < targetCount; i++) {
641 marker = &firstSprite[i];
642 track = &cursorTracks[spreadTrackIndices[i]];
647 *marker = *firstSprite;
648 if (track->
flags & 1) {
649 s32 x = (markerPosition.
x + track->
x) / 2;
650 s32 y = (markerPosition.
y + track->
y) / 2;
652 markerPosition.
x = x;
654 markerPosition.
y = y;
658 s32 y = marker->
y + 8;
661 markerPosition.
x = x;
663 markerPosition.
y = y;
667 marker->
x = markerPosition.
x - 8;
668 marker->
y = markerPosition.
y - 12;
673 marker->
param = matrix;
690 if (pressed &
KEY_A) {
694 id = candidateIds[targetIndex];
697 for (k = 0; k <= 5 && battle->
partyUnits[k] != 0xFF; k++) {
704 for (k = 0; k <= 5 && battle->
enemyIds[k] != 0xFF; k++) {
711 targetIndex = result;
717 targetIndex %= candidateCount;
718 }
while (candidateIds[targetIndex] == 0xFE);
724 targetIndex = targetIndex + candidateCount - 1;
725 targetIndex %= candidateCount;
726 }
while (candidateIds[targetIndex] == 0xFE);
741 if (conditionWindow != 0)
What every part of the menu object shares: its includes, edition values, macros and the link round st...
#define ABILITY_RANGE_ALL
BattleAct.range of an ability that reaches every unit on the side, each as if aimed at.
struct BattleWork * gBattleWork
static s32 * EffectPosition_Coordinates(struct EffectPosition *position)
Returns the position's three coordinates as an array.
void BattlePres_SetActorModesFar(u16 *actors, s32 mode)
s32 BattleMotion_ProjectConditionalPositionFar(s32 id, s32 *projected)
struct BattleUnit * UnitGetFar(u32 owner)
s32 GameFlag_TestFar(s32 flag)
void AudioCommand_PlayFar(s32 id)
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
volatile u32 gFrameCount
Frames WaitFrames has finished.
s32 UiText_GetWideStringWidth(u16 *text)
Returns the width in pixels of a zero-terminated string of 16-bit character codes: 4 for a space,...
void UiText_RenderWideStringAtOffset(u16 *text, struct UiWindow *window, s32 x, s32 y)
Draws a zero-terminated string of 16-bit character codes into a text canvas window at pixel (x,...
volatile u32 gKeysPressed
Keys that went down this frame.
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
s32 AffineMatrix_BuildForEffect(struct AffineTransform *source)
Hands out the next OAM affine matrix for a sprite drawn with source's scale and rotation and fills it...
void Runtime_PushSlotEntry(void *slotEntry, s32 slot)
Links a sprite entry into depth slot slot (clamped to 0..255) for this frame.
#define SE_MENU_CURSOR_MOVE
A unit in battle: a party member's or an enemy's stats, Psynergy, items, Djinn and ailments.
u8 grimReaper
The Grim Reaper's countdown: 7 when cursed, down one at each turn's end; at 0 the unit falls.
u8 psySeal
bits: 7..3 Luff (16 when cast, minus 8 a turn) | 2..0 Bind's turns (7 when cast).
s16 maxPp
0 to 1999 for a character, 9999 for an enemy (UnitCalc)
s8 poison
1 poisoned, 2 deadly poison
u8 name[0x0f]
The name, one byte a character, ending in 0.
u8 haunt
set while an evil spirit grips the unit
s16 hp
current HP, 0 when downed
u8 classId
Who the unit is: a character's id (ISAAC to JENNA, below 8) or an enemy's id (BattleUnitSet).
s16 maxHp
0 to 1999 for a character, 9999 for an enemy (UnitCalc)
u8 delusion
Delusion to sleep: the turns each status has left, 7 when it lands; each may end sooner at the end of...
The battle's own work: its enemies, units and their objects, the turn's actions, the spoils,...
s16 partyUnits[7]
ends with BATTLE_UNIT_LIST_END
s16 enemyIds[BATTLE_ENEMY_CAPACITY+1]
ends with BATTLE_UNIT_LIST_END
A target marker's track: where it is, its state flags and the target it follows.
A point projected onto the screen, with its depth.
A selection screen sprite: a list link and its OAM attributes.
A window: a framed rectangle of the tilemap with its sprite outputs, its opening or closing animation...
void UiText_DrawStringAtOffset(const u8 *text, const struct UiWindow *work, s32 offsetX, s32 offsetY)
Draws a byte string as tiles in window work at pixel (offsetX, offsetY) of its interior.
void UiText_DrawNumberInWindow(s32 value, s32 width, struct UiWindow *window, s32 x, s32 y)
Draws a number (width as UiText_FormatNumber) into a window's tilemap at pixel (x,...
void UiWork_SetParamNibble(s32 param)
Sets the text colour (0 to 15) of drawn text.
void UiText_DrawCharacterAtOffset(s32 message, const struct UiWindow *window, u32 offsetX, u32 offsetY)
Decodes a message and draws it as tiles in a window at pixel (offsetX, offsetY) of its interior.
const u8 gOwnerStatus_HpString[]
const u8 gOwnerStatus_PpString[]
const u8 gOwnerStatus_SlashString[]
s32 System_GetLanguage(void)
s32 VramCache_AllocEntry(s32 size)
Takes a free cache entry, gives it size bytes of sprite VRAM and returns its number.
s32 VramCache_Reload(s32 no, s32 src)
Copies src again into entry no's VRAM, keeping its size.
s32 Resource_ResetEntry(u32 no)
Frees cache entry no: its blocks go back and the entry is marked free (offset 0xffff).
#define TARGET_MYSTERY_NAME_CAPACITY
s32 BattleTarget_RunSelection(s32 selection, s32 mode, u32 spread, u32 kind)
Chooses a party/enemy target and animates its selection markers.
#define TARGET_MYSTERY_NAME_COPY
s32 Ui_ClearVramBlock(void)
Clears the text canvas to transparent.
void UiWork_Finalize(struct UiWindow *window, s32 instant)
Closes a window: clears its contents and remembers its last rectangle.
struct UiWindow * UiWindow_Create(s32 x, s32 y, s32 width, s32 height, s32 attrs)
Opens a window at tile (x, y) of width by height tiles in the first free window slot,...