summaryrefslogtreecommitdiff
path: root/src/battle_interface.c
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2020-01-10 16:32:32 -0500
committerPikalaxALT <pikalaxalt@gmail.com>2020-01-10 16:32:32 -0500
commit3e79c7890fe3196f3c9142a796e18f9b628dd762 (patch)
tree47c9cbd6107cdab808f6e1d5472c92b64a98fe59 /src/battle_interface.c
parent1a246cc567f91d3975a7b9ca26a74afd06245bc9 (diff)
through UpdateLvlInHealthbox
Diffstat (limited to 'src/battle_interface.c')
-rw-r--r--src/battle_interface.c383
1 files changed, 383 insertions, 0 deletions
diff --git a/src/battle_interface.c b/src/battle_interface.c
new file mode 100644
index 000000000..fd4f9af3e
--- /dev/null
+++ b/src/battle_interface.c
@@ -0,0 +1,383 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "battle_interface.h"
+#include "graphics.h"
+#include "pokemon_summary_screen.h"
+#include "string_util.h"
+#include "strings.h"
+#include "text.h"
+
+void SpriteCB_HealthBoxOther(struct Sprite * sprite);
+const u8 *GetHealthboxElementGfxPtr(u8 which);
+u8 *AddTextPrinterAndCreateWindowOnHealthbox(const u8 *str, u32 x, u32 y, u32 *windowId);
+void RemoveWindowOnHealthbox(u32 windowId);
+void TextIntoHealthboxObject(void *dest, u8 *windowTileData, s32 windowWidth);
+void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent);
+
+extern const struct SpriteTemplate sHealthboxPlayerSpriteTemplates[];
+extern const struct SpriteTemplate sHealthboxOpponentSpriteTemplates[];
+extern const struct SpriteTemplate sHealthboxSafariSpriteTemplate;
+extern const struct SpriteTemplate gUnknown_82602F8[];
+extern const struct SubspriteTable gUnknown_82603C4[];
+extern const u8 gUnknown_826051C[16];
+extern const u8 gUnknown_826052C[20];
+extern const u8 gUnknown_8260542[20];
+
+void sub_8047B0C(s16 number, u16 *dest, bool8 unk)
+{
+ s8 i, j;
+ u8 buff[4];
+
+ for (i = 0; i < 4; i++)
+ {
+ buff[i] = 0;
+ }
+
+ for (i = 3; ; i--)
+ {
+ if (number > 0)
+ {
+ buff[i] = number % 10;
+ number /= 10;
+ }
+ else
+ {
+ for (; i > -1; i--)
+ {
+ buff[i] = 0xFF;
+ }
+ if (buff[3] == 0xFF)
+ buff[3] = 0;
+ break;
+ }
+ }
+
+
+
+ if (!unk)
+ {
+ for (i = 0, j = 0; i < 4; i++)
+ {
+ if (buff[j] == 0xFF)
+ {
+ dest[j + 0x00] &= 0xFC00;
+ dest[j + 0x00] |= 0x1E;
+ dest[i + 0x20] &= 0xFC00;
+ dest[i + 0x20] |= 0x1E;
+ }
+ else
+ {
+ dest[j + 0x00] &= 0xFC00;
+ dest[j + 0x00] |= 0x14 + buff[j];
+ dest[i + 0x20] &= 0xFC00;
+ dest[i + 0x20] |= 0x34 + buff[i];
+ }
+ j++;
+ }
+ }
+ else
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (buff[i] == 0xFF)
+ {
+ dest[i + 0x00] &= 0xFC00;
+ dest[i + 0x00] |= 0x1E;
+ dest[i + 0x20] &= 0xFC00;
+ dest[i + 0x20] |= 0x1E;
+ }
+ else
+ {
+ dest[i + 0x00] &= 0xFC00;
+ dest[i + 0x00] |= 0x14 + buff[i];
+ dest[i + 0x20] &= 0xFC00;
+ dest[i + 0x20] |= 0x34 + buff[i];
+ }
+ }
+ }
+}
+
+void sub_8047CAC(s16 num1, s16 num2, u16 *dest)
+{
+ dest[4] = 0x1E;
+ sub_8047B0C(num2, &dest[0], FALSE);
+ sub_8047B0C(num1, &dest[5], TRUE);
+}
+
+// Because the healthbox is too large to fit into one sprite, it is divided into two sprites.
+// healthboxLeft or healthboxMain is the left part that is used as the 'main' sprite.
+// healthboxRight or healthboxOther is the right part of the healthbox.
+// There's also the third sprite under name of healthbarSprite that refers to the healthbar visible on the healtbox.
+
+// data fields for healthboxMain
+// oam.affineParam holds healthboxRight spriteId
+#define hMain_HealthBarSpriteId data[5]
+#define hMain_Battler data[6]
+#define hMain_Data7 data[7]
+
+// data fields for healthboxRight
+#define hOther_HealthBoxSpriteId data[5]
+
+// data fields for healthbar
+#define hBar_HealthBoxSpriteId data[5]
+#define hBar_Data6 data[6]
+
+u8 CreateBattlerHealthboxSprites(u8 a)
+{
+ s16 data6 = 0;
+ u8 healthboxLeftSpriteId;
+ u8 healthboxRightSpriteId;
+ u8 healthbarSpriteId;
+ struct Sprite *sprite;
+
+ if (!IsDoubleBattle())
+ {
+ if (GetBattlerSide(a) == 0)
+ {
+ healthboxLeftSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[0], 240, 160, 1);
+ healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[0], 240, 160, 1);
+
+ gSprites[healthboxLeftSpriteId].oam.shape = 0;
+ gSprites[healthboxRightSpriteId].oam.shape = 0;
+ gSprites[healthboxRightSpriteId].oam.tileNum += 64;
+ }
+ else
+ {
+ healthboxLeftSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[0], 240, 160, 1);
+ healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[0], 240, 160, 1);
+
+ gSprites[healthboxRightSpriteId].oam.tileNum += 32;
+ data6 = 2;
+ }
+
+ gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId;
+ gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId;
+ gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther;
+ }
+ else
+ {
+ if (GetBattlerSide(a) == 0)
+ {
+ healthboxLeftSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1);
+ healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1);
+
+ gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId;
+ gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId;
+ gSprites[healthboxRightSpriteId].oam.tileNum += 32;
+ gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther;
+ data6 = 1;
+ }
+ else
+ {
+ healthboxLeftSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1);
+ healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1);
+
+ gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId;
+ gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId;
+ gSprites[healthboxRightSpriteId].oam.tileNum += 32;
+ gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther;
+ data6 = 2;
+ }
+ }
+ healthbarSpriteId = CreateSpriteAtEnd(&gUnknown_82602F8[gBattlerPositions[a]], 140, 60, 0);
+ sprite = &gSprites[healthbarSpriteId];
+ SetSubspriteTables(sprite, &gUnknown_82603C4[GetBattlerSide(a)]);
+ sprite->subspriteMode = 2;
+ sprite->oam.priority = 1;
+ CpuCopy32(GetHealthboxElementGfxPtr(1), OBJ_VRAM0 + sprite->oam.tileNum * 32, 64);
+
+ gSprites[healthboxLeftSpriteId].hBar_HealthBoxSpriteId = healthbarSpriteId;
+ gSprites[healthboxLeftSpriteId].hBar_Data6 = a;
+ gSprites[healthboxLeftSpriteId].invisible = TRUE;
+ gSprites[healthboxRightSpriteId].invisible = TRUE;
+ sprite->data[5] = healthboxLeftSpriteId;
+ sprite->data[6] = data6;
+ sprite->invisible = TRUE;
+
+ return healthboxLeftSpriteId;
+}
+
+u8 CreateSafariPlayerHealthboxSprites(void)
+{
+ u8 healthboxLeftSpriteId = CreateSprite(&sHealthboxSafariSpriteTemplate, 240, 160, 1);
+ u8 healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxSafariSpriteTemplate, 240, 160, 1);
+
+ gSprites[healthboxLeftSpriteId].oam.shape = ST_OAM_SQUARE;
+ gSprites[healthboxRightSpriteId].oam.shape = ST_OAM_SQUARE;
+ gSprites[healthboxRightSpriteId].oam.tileNum += 0x40;
+ gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId;
+ gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId;
+ gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther;
+ return healthboxLeftSpriteId;
+}
+
+const u8 *GetHealthboxElementGfxPtr(u8 elementId)
+{
+ return gHealthboxElementsGfxTable[elementId];
+}
+
+// Syncs the position of healthbar accordingly with the healthbox.
+void SpriteCB_HealthBar(struct Sprite *sprite)
+{
+ u8 r5 = sprite->data[5];
+
+ switch (sprite->data[6])
+ {
+ case 0:
+ sprite->pos1.x = gSprites[r5].pos1.x + 16;
+ sprite->pos1.y = gSprites[r5].pos1.y;
+ break;
+ case 1:
+ sprite->pos1.x = gSprites[r5].pos1.x + 16;
+ sprite->pos1.y = gSprites[r5].pos1.y;
+ break;
+ default:
+ case 2:
+ sprite->pos1.x = gSprites[r5].pos1.x + 8;
+ sprite->pos1.y = gSprites[r5].pos1.y;
+ break;
+ }
+ sprite->pos2.x = gSprites[r5].pos2.x;
+ sprite->pos2.y = gSprites[r5].pos2.y;
+}
+
+void SpriteCB_HealthBoxOther(struct Sprite *sprite)
+{
+ u8 healthboxMainSpriteId = sprite->hOther_HealthBoxSpriteId;
+
+ sprite->pos1.x = gSprites[healthboxMainSpriteId].pos1.x + 64;
+ sprite->pos1.y = gSprites[healthboxMainSpriteId].pos1.y;
+
+ sprite->pos2.x = gSprites[healthboxMainSpriteId].pos2.x;
+ sprite->pos2.y = gSprites[healthboxMainSpriteId].pos2.y;
+}
+
+void SetBattleBarStruct(u8 battlerId, u8 healthboxSpriteId, s32 maxVal, s32 oldVal, s32 receivedValue)
+{
+ gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId = healthboxSpriteId;
+ gBattleSpritesDataPtr->battleBars[battlerId].maxValue = maxVal;
+ gBattleSpritesDataPtr->battleBars[battlerId].oldValue = oldVal;
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue = receivedValue;
+ gBattleSpritesDataPtr->battleBars[battlerId].currValue = -32768;
+}
+
+void SetHealthboxSpriteInvisible(u8 healthboxSpriteId)
+{
+ gSprites[healthboxSpriteId].invisible = TRUE;
+ gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = TRUE;
+ gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = TRUE;
+}
+
+void SetHealthboxSpriteVisible(u8 healthboxSpriteId)
+{
+ gSprites[healthboxSpriteId].invisible = FALSE;
+ gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = FALSE;
+ gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = FALSE;
+}
+
+void UpdateSpritePos(u8 spriteId, s16 x, s16 y)
+{
+ gSprites[spriteId].pos1.x = x;
+ gSprites[spriteId].pos1.y = y;
+}
+
+void DestoryHealthboxSprite(u8 healthboxSpriteId)
+{
+ DestroySprite(&gSprites[gSprites[healthboxSpriteId].oam.affineParam]);
+ DestroySprite(&gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId]);
+ DestroySprite(&gSprites[healthboxSpriteId]);
+}
+
+void DummyBattleInterfaceFunc(u8 healthboxSpriteId, bool8 isDoubleBattleBattlerOnly)
+{
+
+}
+
+void UpdateOamPriorityInAllHealthboxes(u8 priority)
+{
+ s32 i;
+
+ for (i = 0; i < gBattlersCount; i++)
+ {
+ u8 healthboxLeftSpriteId = gHealthboxSpriteIds[i];
+ u8 healthboxRightSpriteId = gSprites[gHealthboxSpriteIds[i]].oam.affineParam;
+ u8 healthbarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId;
+
+ gSprites[healthboxLeftSpriteId].oam.priority = priority;
+ gSprites[healthboxRightSpriteId].oam.priority = priority;
+ gSprites[healthbarSpriteId].oam.priority = priority;
+ }
+}
+
+void InitBattlerHealthboxCoords(u8 battler)
+{
+ s16 x = 0, y = 0;
+
+ if (!IsDoubleBattle())
+ {
+ if (GetBattlerSide(battler) != B_SIDE_PLAYER)
+ x = 44, y = 30;
+ else
+ x = 158, y = 88;
+ }
+ else
+ {
+ switch (GetBattlerPosition(battler))
+ {
+ case B_POSITION_PLAYER_LEFT:
+ x = 159, y = 75;
+ break;
+ case B_POSITION_PLAYER_RIGHT:
+ x = 171, y = 100;
+ break;
+ case B_POSITION_OPPONENT_LEFT:
+ x = 44, y = 19;
+ break;
+ case B_POSITION_OPPONENT_RIGHT:
+ x = 32, y = 44;
+ break;
+ }
+ }
+
+ UpdateSpritePos(gHealthboxSpriteIds[battler], x, y);
+}
+
+void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
+{
+ u32 windowId, spriteTileNum;
+ u8 *windowTileData;
+ u8 text[16];
+ u32 xPos, var1;
+ void *objVram;
+
+ memcpy(text, gUnknown_826051C, 16);
+
+ xPos = (u32) ConvertIntToDecimalStringN(text + 2, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
+ // Alright, that part was unmatchable. It's basically doing:
+ // xPos = 5 * (3 - (u32)(&text[2]));
+ xPos--;
+ xPos--;
+ xPos -= ((u32)(text));
+ var1 = (3 - xPos);
+ xPos = 4 * var1;
+ xPos += var1;
+
+ windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, xPos, 3, &windowId);
+ spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP;
+
+ if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER)
+ {
+ objVram = (void*)(OBJ_VRAM0);
+ if (!IsDoubleBattle())
+ objVram += spriteTileNum + 0x820;
+ else
+ objVram += spriteTileNum + 0x420;
+ }
+ else
+ {
+ objVram = (void*)(OBJ_VRAM0);
+ objVram += spriteTileNum + 0x400;
+ }
+ TextIntoHealthboxObject(objVram, windowTileData, 3);
+ RemoveWindowOnHealthbox(windowId);
+}