summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/gba/defines.h49
-rw-r--r--include/gba/gba.h57
-rw-r--r--include/gba/syscall.h4
-rw-r--r--include/gba/types.h70
-rw-r--r--include/global.h6
-rw-r--r--include/main.h45
-rw-r--r--include/sprite.h242
7 files changed, 417 insertions, 56 deletions
diff --git a/include/gba/defines.h b/include/gba/defines.h
new file mode 100644
index 000000000..005efb079
--- /dev/null
+++ b/include/gba/defines.h
@@ -0,0 +1,49 @@
+#ifndef GUARD_GBA_DEFINES
+#define GUARD_GBA_DEFINES
+
+#include <stddef.h>
+
+#define TRUE 1
+#define FALSE 0
+
+#define IWRAM_DATA __attribute__((section("iwram_data")))
+#define EWRAM_DATA __attribute__((section("ewram_data")))
+
+#define ALIGNED(n) __attribute__((aligned(n)))
+
+// The original build process placed COMMON data (i.e. uninitialized globals)
+// in IWRAM after the static variables.
+// When ld places COMMON variables in the output, it aligns the variable
+// according to the size of the variable, with a maximum alignment of 16. This
+// results in large alignment values.
+// Initialized variables are aligned according to the size of the largest
+// primitive type in the object, so their alignment will often be smaller.
+// However, we cannot use COMMON data in pokeruby because the order of COMMON
+// data in the output is not reliable. Instead, we need to initialize the
+// variables so that their order in the source file is preserved in the output.
+// But using initialized variables brings us into conflict with those large
+// alignment values.
+// These macros allow us to get around this by manually specifying what the
+// alignment would be if the variable were uninitialized.
+#define COMM(decl, n) IWRAM_DATA ALIGNED(1 << n) decl = {0};
+#define COMM_2(decl) COMM(decl, 2)
+#define COMM_4(decl) COMM(decl, 4)
+
+#define SOUND_INFO_PTR (*(struct SoundInfo **)0x3007FF0)
+#define INTR_CHECK (*(u16 *)0x3007FF8)
+#define INTR_VECTOR (*(void **)0x3007FFC)
+
+#define OBJ_VRAM0 0x6010000 // when BG is in tilemap mode
+#define OBJ_VRAM1 0x6014000 // when BG is in bitmap mode
+
+#define OAM 0x7000000
+
+#define DISPLAY_WIDTH 240
+#define DISPLAY_HEIGHT 160
+
+#define TILE_SIZE_4BPP 32
+#define TILE_SIZE_8BPP 64
+
+#define TOTAL_OBJ_TILE_COUNT 1024
+
+#endif // GUARD_GBA_DEFINES
diff --git a/include/gba/gba.h b/include/gba/gba.h
index 06067dacf..26342cf88 100644
--- a/include/gba/gba.h
+++ b/include/gba/gba.h
@@ -1,63 +1,10 @@
#ifndef GUARD_GBA_GBA_H
#define GUARD_GBA_GBA_H
-#include <stddef.h>
-
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef signed char s8;
-typedef signed short s16;
-typedef signed int s32;
-
-typedef volatile u8 vu8;
-typedef volatile u16 vu16;
-typedef volatile u32 vu32;
-typedef volatile s8 vs8;
-typedef volatile s16 vs16;
-typedef volatile s32 vs32;
-
-typedef float f32;
-typedef double f64;
-
-typedef u8 bool8;
-typedef u16 bool16;
-typedef u32 bool32;
-
-#define TRUE 1
-#define FALSE 0
-
-#define IWRAM_DATA __attribute__((section("iwram_data")))
-#define EWRAM_DATA __attribute__((section("ewram_data")))
-
-#define ALIGNED(n) __attribute__((aligned(n)))
-
-// The original build process placed COMMON data (i.e. uninitialized globals)
-// in IWRAM after the static variables.
-// When ld places COMMON variables in the output, it aligns the variable
-// according to the size of the variable, with a maximum alignment of 16. This
-// results in large alignment values.
-// Initialized variables are aligned according to the size of the largest
-// primitive type in the object, so their alignment will often be smaller.
-// However, we cannot use COMMON data in pokeruby because the order of COMMON
-// data in the output is not reliable. Instead, we need to initialize the
-// variables so that their order in the source file is preserved in the output.
-// But using initialized variables brings us into conflict with those large
-// alignment values.
-// These macros allow us to get around this by manually specifying what the
-// alignment would be if the variable were uninitialized.
-#define COMM(decl, n) IWRAM_DATA ALIGNED(1 << n) decl = {0};
-#define COMM_0(decl) COMM(decl, 0)
-#define COMM_1(decl) COMM(decl, 1)
-#define COMM_2(decl) COMM(decl, 2)
-#define COMM_4(decl) COMM(decl, 4)
-
+#include "gba/defines.h"
#include "gba/io_reg.h"
+#include "gba/types.h"
#include "gba/syscall.h"
#include "gba/macro.h"
-#define SOUND_INFO_PTR (*(struct SoundInfo **)0x3007FF0)
-#define INTR_CHECK (*(u16 *)0x3007FF8)
-#define INTR_VECTOR (*(void **)0x3007FFC)
-
#endif // GUARD_GBA_GBA_H
diff --git a/include/gba/syscall.h b/include/gba/syscall.h
index 9b2b81311..8ef82c0e4 100644
--- a/include/gba/syscall.h
+++ b/include/gba/syscall.h
@@ -15,12 +15,14 @@ void SoftReset(u32 resetFlags);
void RegisterRamReset(u32 resetFlags);
+void VBlankIntrWait(void);
+
#define CPU_SET_SRC_FIXED 0x01000000
#define CPU_SET_16BIT 0x00000000
#define CPU_SET_32BIT 0x04000000
void CpuSet(void *src, void *dest, u32 control);
-void VBlankIntrWait(void);
+void ObjAffineSet(struct ObjAffineSrcData *src, void *dest, s32 count, s32 offset);
#endif // GUARD_GBA_SYSCALL_H
diff --git a/include/gba/types.h b/include/gba/types.h
new file mode 100644
index 000000000..4e1ab3003
--- /dev/null
+++ b/include/gba/types.h
@@ -0,0 +1,70 @@
+#ifndef GUARD_GBA_TYPES_H
+#define GUARD_GBA_TYPES_H
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef signed char s8;
+typedef signed short s16;
+typedef signed int s32;
+
+typedef volatile u8 vu8;
+typedef volatile u16 vu16;
+typedef volatile u32 vu32;
+typedef volatile s8 vs8;
+typedef volatile s16 vs16;
+typedef volatile s32 vs32;
+
+typedef float f32;
+typedef double f64;
+
+typedef u8 bool8;
+typedef u16 bool16;
+typedef u32 bool32;
+
+struct OamData
+{
+ u32 y:8;
+ u32 affineMode:2;
+ u32 objMode:2;
+ u32 mosaic:1;
+ u32 bpp:1;
+ u32 shape:2;
+
+ u32 x:9;
+ u32 matrixNum:5; // bits 3/4 are h-flip/v-flip if not in affine mode
+ u32 size:2;
+
+ u16 tileNum:10;
+ u16 priority:2;
+ u16 paletteNum:4;
+ u16 affineParam;
+};
+
+#define ST_OAM_OBJ_NORMAL 0
+#define ST_OAM_OBJ_BLEND 1
+#define ST_OAM_OBJ_WINDOW 2
+
+#define ST_OAM_AFFINE_OFF 0
+#define ST_OAM_AFFINE_NORMAL 1
+#define ST_OAM_AFFINE_ERASE 2
+#define ST_OAM_AFFINE_DOUBLE 3
+
+#define ST_OAM_AFFINE_ON_MASK 1
+#define ST_OAM_AFFINE_DOUBLE_MASK 2
+
+#define ST_OAM_4BPP 0
+#define ST_OAM_8BPP 1
+
+#define ST_OAM_SQUARE 0
+#define ST_OAM_H_RECTANGLE 1
+#define ST_OAM_V_RECTANGLE 2
+
+struct ObjAffineSrcData
+{
+ s16 xScale;
+ s16 yScale;
+ u16 rotation;
+};
+
+#endif // GUARD_GBA_TYPES_H
diff --git a/include/global.h b/include/global.h
index 79c9e771f..b4a88ef5f 100644
--- a/include/global.h
+++ b/include/global.h
@@ -17,6 +17,12 @@ enum
FEMALE
};
+struct Coords16
+{
+ s16 x;
+ s16 y;
+};
+
struct Time
{
s16 days;
diff --git a/include/main.h b/include/main.h
new file mode 100644
index 000000000..06480af43
--- /dev/null
+++ b/include/main.h
@@ -0,0 +1,45 @@
+#ifndef GUARD_MAIN_H
+#define GUARD_MAIN_H
+
+#include "global.h"
+
+typedef void (*MainCallback)(void);
+typedef void (*IntrCallback)(void);
+typedef void (*IntrFunc)(void);
+
+struct Main
+{
+ MainCallback callback1;
+ MainCallback callback2;
+
+ u32 field_8;
+
+ IntrCallback vblankCallback;
+ IntrCallback hblankCallback;
+ IntrCallback vcountCallback;
+ IntrCallback serialCallback;
+
+ vu16 intrCheck;
+
+ u32 vblankCounter1;
+ u32 vblankCounter2;
+
+ u16 heldKeysRaw; // held keys without L=A remapping
+ u16 newKeysRaw; // newly pressed keys without L=A remapping
+ u16 heldKeys; // held keys with L=A remapping
+ u16 newKeys; // newly pressed keys with L=A remapping
+ u16 newAndRepeatedKeys; // newly pressed keys plus key repeat
+ u16 keyRepeatCounter; // counts down to 0, triggering key repeat
+ bool16 watchedKeysPressed; // whether one of the watched keys was pressed
+ u16 watchedKeysMask; // bit mask for watched keys
+
+ u8 objCount;
+
+ struct OamData oamBuffer[128];
+
+ u8 state;
+
+ u8 oamLoadDisabled:1;
+};
+
+#endif // GUARD_MAIN_H
diff --git a/include/sprite.h b/include/sprite.h
new file mode 100644
index 000000000..27b3222ee
--- /dev/null
+++ b/include/sprite.h
@@ -0,0 +1,242 @@
+#ifndef GUARD_SPRITE_H
+#define GUARD_SPRITE_H
+
+struct SpriteSheet
+{
+ u8 *data;
+ u16 size;
+ u16 tag;
+};
+
+struct SpriteFrameImage
+{
+ u8 *data;
+ u16 size;
+};
+
+struct SpritePalette
+{
+ u8 *data;
+ u16 tag;
+};
+
+struct AnimFrameCmd
+{
+ // If the sprite has an array of images, this is the array index.
+ // If the sprite has a sheet, this is the tile offset.
+ u32 imageValue:16;
+
+ u32 duration:6;
+ u32 hFlip:1;
+ u32 vFlip:1;
+};
+
+struct AnimLoopCmd
+{
+ u32 type:16;
+ u32 count:6;
+};
+
+struct AnimJumpCmd
+{
+ u32 type:16;
+ u32 target:6;
+};
+
+union AnimCmd
+{
+ s16 type;
+ struct AnimFrameCmd frame;
+ struct AnimLoopCmd loop;
+ struct AnimJumpCmd jump;
+};
+
+struct AffineAnimFrameCmd
+{
+ s16 xScale;
+ s16 yScale;
+ u8 rotation;
+ u8 duration;
+};
+
+struct AffineAnimLoopCmd
+{
+ s16 type;
+ u16 count;
+};
+
+struct AffineAnimJumpCmd
+{
+ s16 type;
+ u16 target;
+};
+
+union AffineAnimCmd
+{
+ s16 type;
+ struct AffineAnimFrameCmd frame;
+ struct AffineAnimLoopCmd loop;
+ struct AffineAnimJumpCmd jump;
+};
+
+struct AffineAnimState
+{
+ u8 animNum;
+ u8 animCmdIndex;
+ u8 delayCounter;
+ u8 loopCounter;
+ s16 xScale;
+ s16 yScale;
+ u16 rotation;
+};
+
+enum
+{
+ SUBSPRITES_OFF,
+ SUBSPRITES_ON,
+ SUBSPRITES_IGNORE_PRIORITY, // on but priority is ignored
+};
+
+struct Subsprite
+{
+ u16 x;
+ u16 y;
+ u16 shape:2;
+ u16 size:2;
+ u16 tileOffset:10;
+ u16 priority:2;
+};
+
+struct SubspriteTable
+{
+ u8 subspriteCount;
+ struct Subsprite *subsprites;
+};
+
+struct Sprite;
+
+struct SpriteTemplate
+{
+ u16 tileTag;
+ u16 paletteTag;
+ struct OamData *oam;
+ union AnimCmd **anims;
+ struct SpriteFrameImage *images;
+ union AffineAnimCmd **affineAnims;
+ void (*callback)(struct Sprite *);
+};
+
+struct Sprite
+{
+ struct OamData oam;
+ union AnimCmd **anims;
+ struct SpriteFrameImage *images;
+ union AffineAnimCmd **affineAnims;
+ struct SpriteTemplate *template;
+ struct SubspriteTable *subspriteTables;
+ void (*callback)(struct Sprite *);
+
+ struct Coords16 pos1;
+ struct Coords16 pos2;
+ s8 centerToCornerVecX;
+ s8 centerToCornerVecY;
+
+ u8 animNum;
+ u8 animCmdIndex;
+ u8 animDelayCounter:6;
+ u8 animPaused:1;
+ u8 affineAnimPaused:1;
+ u8 animLoopCounter;
+
+ // general purpose data fields
+ u16 data0;
+ u16 data1;
+ u16 data2;
+ u16 data3;
+ u16 data4;
+ u16 data5;
+ u16 data6;
+ u16 data7;
+
+ u16 inUse:1;
+ u16 coordOffsetEnabled:1;
+ u16 invisible:1;
+ u16 flags_3:1;
+ u16 flags_4:1;
+ u16 flags_5:1;
+ u16 flags_6:1;
+ u16 flags_7:1;
+ u16 hFlip:1;
+ u16 vFlip:1;
+ u16 animBeginning:1;
+ u16 affineAnimBeginning:1;
+ u16 animEnded:1;
+ u16 affineAnimEnded:1;
+ u16 usingSheet:1;
+ u16 flags_f:1;
+
+ u16 sheetTileStart;
+
+ u8 subspriteTableNum:6;
+ u8 subspriteMode:2;
+
+ u8 subpriority;
+};
+
+void ResetSpriteData(void);
+void AnimateSprites(void);
+void BuildOamBuffer(void);
+u8 CreateSprite(struct SpriteTemplate *template, u16 x, u16 y, u8 subpriority);
+u8 CreateSpriteAtEnd(struct SpriteTemplate *template, u16 x, u16 y, u8 subpriority);
+u8 CreateInvisibleSprite(void (*callback)(struct Sprite *));
+u8 CreateSpriteAndAnimate(struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority);
+void DestroySprite(struct Sprite *sprite);
+void ResetOamRange(u8 a, u8 b);
+void LoadOam(void);
+void SetOamMatrix(u8 matrixNum, u16 a, u16 b, u16 c, u16 d);
+void CalcCenterToCornerVec(struct Sprite *sprite, u8 shape, u8 size, u8 affineMode);
+void SpriteCallbackDummy(struct Sprite *sprite);
+void ProcessSpriteCopyRequests(void);
+void RequestSpriteCopy(u8 *src, u8 *dest, u16 size);
+void FreeSpriteTiles(struct Sprite *sprite);
+void FreeSpritePalette(struct Sprite *sprite);
+void FreeSpriteOamMatrix(struct Sprite *sprite);
+void DestroySpriteAndFreeResources(struct Sprite *sprite);
+void sub_800142C(u32 a1, u32 a2, u16 *a3, u16 a4, u32 a5);
+void AnimateSprite(struct Sprite *sprite);
+void StartSpriteAnim(struct Sprite *sprite, u8 animNum);
+void StartSpriteAnimIfDifferent(struct Sprite *sprite, u8 animNum);
+void SeekSpriteAnim(struct Sprite *sprite, u8 animCmdIndex);
+void StartSpriteAffineAnim(struct Sprite *sprite, u8 animNum);
+void StartSpriteAffineAnimIfDifferent(struct Sprite *sprite, u8 animNum);
+void ChangeSpriteAffineAnim(struct Sprite *sprite, u8 animNum);
+void ChangeSpriteAffineAnimIfDifferent(struct Sprite *sprite, u8 animNum);
+void SetSpriteSheetFrameTileNum(struct Sprite *sprite);
+u8 AllocOamMatrix(void);
+void FreeOamMatrix(u8 matrixNum);
+void InitSpriteAffineAnim(struct Sprite *sprite);
+void SetOamMatrixRotationScaling(u8 matrixNum, s16 xScale, s16 yScale, u16 rotation);
+u16 LoadSpriteSheet(struct SpriteSheet *sheet);
+void LoadSpriteSheets(struct SpriteSheet *sheets);
+u16 AllocTilesForSpriteSheet(struct SpriteSheet *sheet);
+void AllocTilesForSpriteSheets(struct SpriteSheet *sheets);
+void LoadTilesForSpriteSheet(struct SpriteSheet *sheet);
+void LoadTilesForSpriteSheets(struct SpriteSheet *sheets);
+void FreeSpriteTilesByTag(u16 tag);
+void FreeAllSpriteTiles(void);
+u16 GetSpriteTileStartByTag(u16 tag);
+u16 GetSpriteTileTagByTileStart(u16 start);
+void RequestSpriteSheetCopy(struct SpriteSheet *sheet);
+u16 LoadSpriteSheetDeferred(struct SpriteSheet *sheet);
+void FreeAllSpritePalettes(void);
+u8 LoadSpritePalette(struct SpritePalette *palette);
+void LoadSpritePalettes(struct SpritePalette *palettes);
+u8 AllocSpritePalette(u16 tag);
+u8 IndexOfSpritePaletteTag(u16 tag);
+u16 GetSpritePaletteTagByPaletteNum(u8 paletteNum);
+void FreeSpritePaletteByTag(u16 tag);
+void SetSubspriteTables(struct Sprite *sprite, struct SubspriteTable *subspriteTables);
+bool8 AddSpriteToOamBuffer(struct Sprite *object, u8 *oamIndex);
+bool8 AddSubspritesToOamBuffer(struct Sprite *sprite, struct OamData *destOam, u8 *oamIndex);
+
+#endif // GUARD_SPRITE_H