mirror of
https://github.com/FireEmblemUniverse/fireemblem8u.git
synced 2024-11-23 13:19:53 +00:00
427 lines
13 KiB
C
427 lines
13 KiB
C
#ifndef GUARD_HARDWARE_H
|
|
#define GUARD_HARDWARE_H
|
|
|
|
#include "global.h"
|
|
|
|
enum {
|
|
FRAMES_PER_SECOND = 60,
|
|
FRAMES_PER_MINUTE = 60 * FRAMES_PER_SECOND,
|
|
FRAMES_PER_HOUR = 60 * FRAMES_PER_MINUTE,
|
|
};
|
|
|
|
struct DispCnt {
|
|
/* bit 0 */ u16 mode : 3;
|
|
/* bit 3 */ u16 cgbMode : 1; // reserved, do not use
|
|
/* bit 4 */ u16 bmpFrameNum : 1;
|
|
/* bit 5 */ u16 hblankIntervalFree : 1;
|
|
/* bit 6 */ u16 obj1dMap : 1;
|
|
/* bit 7 */ u16 forcedBlank : 1;
|
|
/* bit 8 */ u16 bg0_on : 1;
|
|
/* bit 9 */ u16 bg1_on : 1;
|
|
/* bit 10 */ u16 bg2_on : 1;
|
|
/* bit 11 */ u16 bg3_on : 1;
|
|
/* bit 12 */ u16 obj_on : 1;
|
|
/* bit 13 */ u16 win0_on : 1;
|
|
/* bit 14 */ u16 win1_on : 1;
|
|
/* bit 15 */ u16 objWin_on : 1;
|
|
STRUCT_PAD(0x02, 0x04);
|
|
} BITPACKED;
|
|
|
|
struct DispStat {
|
|
/* bit 0 */ u16 vblankFlag : 1;
|
|
/* bit 1 */ u16 hblankFlag : 1;
|
|
/* bit 2 */ u16 vcountFlag : 1;
|
|
/* bit 3 */ u16 vblankIrqEnable : 1;
|
|
/* bit 4 */ u16 hblankIrqEnable : 1;
|
|
/* bit 5 */ u16 vcountIrqEnable : 1;
|
|
/* bit 6 */ u16 dummy : 2;
|
|
/* bit 8 */ u16 vcountCompare : 8;
|
|
STRUCT_PAD(0x02, 0x04);
|
|
} BITPACKED;
|
|
|
|
struct BgCnt {
|
|
/* bit 0 */ u16 priority : 2;
|
|
/* bit 2 */ u16 charBaseBlock : 2;
|
|
/* bit 4 */ u16 dummy : 2;
|
|
/* bit 6 */ u16 mosaic : 1;
|
|
/* bit 7 */ u16 colorMode : 1;
|
|
/* bit 8 */ u16 screenBaseBlock : 5;
|
|
/* bit 13 */ u16 areaOverflowMode : 1;
|
|
/* bit 14 */ u16 screenSize : 2;
|
|
STRUCT_PAD(0x02, 0x04);
|
|
} BITPACKED;
|
|
|
|
struct WinCnt {
|
|
u8 win0_enableBg0 : 1;
|
|
u8 win0_enableBg1 : 1;
|
|
u8 win0_enableBg2 : 1;
|
|
u8 win0_enableBg3 : 1;
|
|
u8 win0_enableObj : 1;
|
|
u8 win0_enableBlend : 1;
|
|
u8 : 2;
|
|
|
|
u8 win1_enableBg0 : 1;
|
|
u8 win1_enableBg1 : 1;
|
|
u8 win1_enableBg2 : 1;
|
|
u8 win1_enableBg3 : 1;
|
|
u8 win1_enableObj : 1;
|
|
u8 win1_enableBlend : 1;
|
|
u8 : 2;
|
|
|
|
u8 wout_enableBg0 : 1;
|
|
u8 wout_enableBg1 : 1;
|
|
u8 wout_enableBg2 : 1;
|
|
u8 wout_enableBg3 : 1;
|
|
u8 wout_enableObj : 1;
|
|
u8 wout_enableBlend : 1;
|
|
u8 : 2;
|
|
|
|
u8 wobj_enableBg0 : 1;
|
|
u8 wobj_enableBg1 : 1;
|
|
u8 wobj_enableBg2 : 1;
|
|
u8 wobj_enableBg3 : 1;
|
|
u8 wobj_enableObj : 1;
|
|
u8 wobj_enableBlend : 1;
|
|
u8 : 2;
|
|
} BITPACKED;
|
|
|
|
struct BlendCnt {
|
|
u16 target1_bg0_on : 1;
|
|
u16 target1_bg1_on : 1;
|
|
u16 target1_bg2_on : 1;
|
|
u16 target1_bg3_on : 1;
|
|
u16 target1_obj_on : 1;
|
|
u16 target1_bd_on : 1;
|
|
u16 effect : 2;
|
|
u16 target2_bg0_on : 1;
|
|
u16 target2_bg1_on : 1;
|
|
u16 target2_bg2_on : 1;
|
|
u16 target2_bg3_on : 1;
|
|
u16 target2_obj_on : 1;
|
|
u16 target2_bd_on : 1;
|
|
u32 _unused;
|
|
} BITPACKED;
|
|
|
|
struct LCDControlBuffer {
|
|
/* 00 */ struct DispCnt dispcnt;
|
|
/* 04 */ struct DispStat dispstat;
|
|
/* 08 */ STRUCT_PAD(0x08, 0x0C);
|
|
/* 0C */ struct BgCnt bg0cnt;
|
|
/* 10 */ struct BgCnt bg1cnt;
|
|
/* 14 */ struct BgCnt bg2cnt;
|
|
/* 18 */ struct BgCnt bg3cnt;
|
|
/* 1C */ struct BgCoords bgoffset[4];
|
|
/* 2C */ u8 win0_right, win0_left;
|
|
/* 2C */ u8 win1_right, win1_left;
|
|
/* 30 */ u8 win0_bottom, win0_top;
|
|
/* 30 */ u8 win1_bottom, win1_top;
|
|
/* 34 */ struct WinCnt wincnt;
|
|
/* 38 */ u16 mosaic;
|
|
STRUCT_PAD(0x3A, 0x3C);
|
|
/* 3C */ struct BlendCnt bldcnt;
|
|
/* 44 */ u8 blendCoeffA;
|
|
/* 45 */ u8 blendCoeffB;
|
|
/* 46 */ u8 blendY;
|
|
/* 48 */ struct BgAffineDstData bg2affin;
|
|
/* 58 */ struct BgAffineDstData bg3affin;
|
|
/* 68 */ s8 colorAddition;
|
|
};
|
|
|
|
struct KeyStatusBuffer {
|
|
/* 00 */ u8 repeatDelay; // initial delay before generating auto-repeat presses
|
|
/* 01 */ u8 repeatInterval; // time between auto-repeat presses
|
|
/* 02 */ u8 repeatTimer; // (decreased by one each frame, reset to repeatDelay when Presses change and repeatInterval when reaches 0)
|
|
/* 04 */ u16 heldKeys; // keys that are currently held down
|
|
/* 06 */ u16 repeatedKeys; // auto-repeated keys
|
|
/* 08 */ u16 newKeys; // keys that went down this frame
|
|
/* 0A */ u16 prevKeys; // keys that were held down last frame
|
|
/* 0C */ u16 LastPressState;
|
|
/* 0E */ bool16 ABLRPressed; // 1 for Release (A B L R Only), 0 Otherwise
|
|
/* 10 */ u16 newKeys2;
|
|
/* 12 */ u16 TimeSinceStartSelect; // Time since last Non-Start Non-Select Button was pressed
|
|
};
|
|
|
|
struct Struct02024CD4 {
|
|
int count;
|
|
int size;
|
|
};
|
|
|
|
struct TileDataTransfer {
|
|
const void *src;
|
|
void *dest;
|
|
u16 size;
|
|
u16 mode;
|
|
};
|
|
|
|
struct OamSection {
|
|
u16 * buf;
|
|
void * oam;
|
|
u16 offset;
|
|
u16 count;
|
|
};
|
|
|
|
extern struct OamSection sOamHi;
|
|
extern struct OamSection sOamLo;
|
|
|
|
// extern ??? gKeyComboResetEN
|
|
extern u8 sModifiedBGs; // BGs that need copying
|
|
extern s8 sModifiedPalette;
|
|
extern u16 gKeyStatusIgnoredSt;
|
|
// extern ??? gUnknown_03000014
|
|
extern u8 gUnknown_03000018;
|
|
extern u8 gUnknown_03000019;
|
|
extern bool gSoftwareResetFlag;
|
|
|
|
extern s8 gFadeComponentStep[];
|
|
extern s8 gFadeComponents[];
|
|
extern u16 gPaletteBuffer[];
|
|
|
|
// In text mode, the tilemap entries are 16 bits,
|
|
// while in affine mode, they are 8 bits.
|
|
// they are defined as u16 for convenience
|
|
|
|
extern u16 gBG0TilemapBuffer[32 * 32];
|
|
extern u16 gBG1TilemapBuffer[32 * 32];
|
|
extern u16 gBG2TilemapBuffer[32 * 32];
|
|
extern u16 gBG3TilemapBuffer[32 * 32];
|
|
|
|
extern void * gBGVramTilemapPointers[4];
|
|
|
|
extern void (*gMainCallback)(void);
|
|
|
|
extern struct KeyStatusBuffer * CONST_DATA gKeyStatusPtr;
|
|
|
|
extern struct LCDControlBuffer gLCDControlBuffer;
|
|
|
|
extern struct Struct02024CD4 gFrameTmRegisterConfig;
|
|
extern struct TileDataTransfer gFrameTmRegister[32];
|
|
|
|
extern SHOULD_BE_CONST s16 gSinLookup[]; // needs to be non-const to match?
|
|
|
|
// Utility macros and constants
|
|
|
|
// Some functions only match with one of the macros.
|
|
// NOTE: TILEMAP_INDEX2 is TM_OFFSET in fe6
|
|
#define TILEMAP_INDEX(aX, aY) (0x20 * (aY) + (aX))
|
|
#define TILEMAP_INDEX2(aX, aY) (((aY) << 5) + (aX))
|
|
|
|
#define TILEMAP_LOCATED(aMap, aX, aY) (TILEMAP_INDEX((aX), (aY)) + (aMap))
|
|
|
|
#define TILEREF(aChar, aPal) ((aChar) + ((aPal) << 12))
|
|
#define TILE_HFLIP 0x0400
|
|
#define TILE_VFLIP 0x0800
|
|
|
|
#define CHR_SIZE 0x20
|
|
#define CHR_LINE 0x20
|
|
#define BG_CHR_ADDR(n) (void *)(BG_VRAM + (CHR_SIZE * (n)))
|
|
#define OBJ_CHR_ADDR(n) (void *)(OBJ_VRAM0 + (CHR_SIZE * (n)))
|
|
|
|
#define RED_MASK 0x1F
|
|
#define GREEN_MASK (0x1F << 5)
|
|
#define BLUE_MASK (0x1F << 10)
|
|
|
|
#define PAL_COLOR_OFFSET(palid, colornum) (palid) * 0x10 + (colornum)
|
|
#define PAL_OFFSET(palid) PAL_COLOR_OFFSET((palid), 0)
|
|
#define BGPAL_OFFSET(bgpal) PAL_OFFSET(0x00 + (bgpal))
|
|
#define OBPAL_OFFSET(obpal) PAL_OFFSET(0x10 + (obpal))
|
|
|
|
#define PAL_BACKDROP_OFFSET PAL_COLOR_OFFSET(0, 0)
|
|
|
|
#define PAL_BUF_COLOR(buf, palid, colornum) buf[PAL_COLOR_OFFSET((palid), (colornum))]
|
|
#define PAL_COLOR(palid, colornum) PAL_BUF_COLOR(gPaletteBuffer, palid, colornum)
|
|
#define PAL_BG_COLOR(palid, colornum) PAL_COLOR(palid, colornum)
|
|
#define PAL_OBJ_COLOR(palid, colornum) PAL_COLOR((palid) + 0x10, colornum)
|
|
#define PAL_BG(palid) (&PAL_BG_COLOR(palid, 0))
|
|
#define PAL_OBJ(palid) (&PAL_OBJ_COLOR(palid, 0))
|
|
|
|
#define SIN(aAngle) (gSinLookup[((aAngle) & 0xFF)])
|
|
#define COS(aAngle) (gSinLookup[0x40 + ((aAngle) & 0xFF)])
|
|
|
|
#define BG_SYNC_BIT(aBg) (1 << (aBg))
|
|
|
|
enum {
|
|
BG_0 = 0,
|
|
BG_1,
|
|
BG_2,
|
|
BG_3,
|
|
};
|
|
|
|
enum {
|
|
BG0_SYNC_BIT = BG_SYNC_BIT(0),
|
|
BG1_SYNC_BIT = BG_SYNC_BIT(1),
|
|
BG2_SYNC_BIT = BG_SYNC_BIT(2),
|
|
BG3_SYNC_BIT = BG_SYNC_BIT(3),
|
|
};
|
|
|
|
#define ApplyPalettes(aSrc, aPalId, aPalCount) CopyToPaletteBuffer((aSrc), 0x20 * (aPalId), 0x20 * (aPalCount))
|
|
#define ApplyPalette(aSrc, aPalId) ApplyPalettes((aSrc), (aPalId), 1)
|
|
|
|
#define SetDispEnable(bg0, bg1, bg2, bg3, obj) \
|
|
{ \
|
|
gLCDControlBuffer.dispcnt.bg0_on = (bg0); \
|
|
gLCDControlBuffer.dispcnt.bg1_on = (bg1); \
|
|
gLCDControlBuffer.dispcnt.bg2_on = (bg2); \
|
|
gLCDControlBuffer.dispcnt.bg3_on = (bg3); \
|
|
gLCDControlBuffer.dispcnt.obj_on = (obj); \
|
|
}
|
|
|
|
#define SetWinEnable(win0, win1, objwin) \
|
|
{ \
|
|
gLCDControlBuffer.dispcnt.win0_on = (win0); \
|
|
gLCDControlBuffer.dispcnt.win1_on = (win1); \
|
|
gLCDControlBuffer.dispcnt.objWin_on = (objwin); \
|
|
}
|
|
|
|
#define SetWin0Box(left, top, right, bottom) \
|
|
{ \
|
|
gLCDControlBuffer.win0_left = (left); \
|
|
gLCDControlBuffer.win0_top = (top); \
|
|
gLCDControlBuffer.win0_right = (right); \
|
|
gLCDControlBuffer.win0_bottom = (bottom); \
|
|
}
|
|
|
|
#define SetWin1Box(left, top, right, bottom) \
|
|
{ \
|
|
gLCDControlBuffer.win1_left = (left); \
|
|
gLCDControlBuffer.win1_top = (top); \
|
|
gLCDControlBuffer.win1_right = (right); \
|
|
gLCDControlBuffer.win1_bottom = (bottom); \
|
|
}
|
|
|
|
#define SetWin0Layers(bg0, bg1, bg2, bg3, obj) \
|
|
{ \
|
|
gLCDControlBuffer.wincnt.win0_enableBg0 = (bg0); \
|
|
gLCDControlBuffer.wincnt.win0_enableBg1 = (bg1); \
|
|
gLCDControlBuffer.wincnt.win0_enableBg2 = (bg2); \
|
|
gLCDControlBuffer.wincnt.win0_enableBg3 = (bg3); \
|
|
gLCDControlBuffer.wincnt.win0_enableObj = (obj); \
|
|
}
|
|
|
|
#define SetWin1Layers(bg0, bg1, bg2, bg3, obj) \
|
|
{ \
|
|
gLCDControlBuffer.wincnt.win1_enableBg0 = (bg0); \
|
|
gLCDControlBuffer.wincnt.win1_enableBg1 = (bg1); \
|
|
gLCDControlBuffer.wincnt.win1_enableBg2 = (bg2); \
|
|
gLCDControlBuffer.wincnt.win1_enableBg3 = (bg3); \
|
|
gLCDControlBuffer.wincnt.win1_enableObj = (obj); \
|
|
}
|
|
|
|
#define SetWObjLayers(bg0, bg1, bg2, bg3, obj) \
|
|
{ \
|
|
gLCDControlBuffer.wincnt.wobj_enableBg0 = (bg0); \
|
|
gLCDControlBuffer.wincnt.wobj_enableBg1 = (bg1); \
|
|
gLCDControlBuffer.wincnt.wobj_enableBg2 = (bg2); \
|
|
gLCDControlBuffer.wincnt.wobj_enableBg3 = (bg3); \
|
|
gLCDControlBuffer.wincnt.wobj_enableObj = (obj); \
|
|
}
|
|
|
|
#define SetWOutLayers(bg0, bg1, bg2, bg3, obj) \
|
|
{ \
|
|
gLCDControlBuffer.wincnt.wout_enableBg0 = (bg0); \
|
|
gLCDControlBuffer.wincnt.wout_enableBg1 = (bg1); \
|
|
gLCDControlBuffer.wincnt.wout_enableBg2 = (bg2); \
|
|
gLCDControlBuffer.wincnt.wout_enableBg3 = (bg3); \
|
|
gLCDControlBuffer.wincnt.wout_enableObj = (obj); \
|
|
}
|
|
|
|
#define SetBlendAlpha(ca, cb) \
|
|
SetBlendConfig(BLEND_EFFECT_ALPHA, (ca), (cb), 0)
|
|
|
|
#define SetBlendBrighten(cy) \
|
|
SetBlendConfig(BLEND_EFFECT_BRIGHTEN, 0, 0, (cy))
|
|
|
|
#define SetBlendDarken(cy) \
|
|
SetBlendConfig(BLEND_EFFECT_DARKEN, 0, 0, (cy))
|
|
|
|
#define SetBlendNone() \
|
|
SetBlendConfig(BLEND_EFFECT_NONE, 0x10, 0, 0)
|
|
|
|
#define SetBackdropColor(color) \
|
|
gPaletteBuffer[0] = (color); \
|
|
EnablePaletteSync()
|
|
|
|
// Functions
|
|
|
|
void CopyToPaletteBuffer(const void* src, int b, int size);
|
|
void sub_8000E14(u16 *a, int b, int size, int d);
|
|
void FlushLCDControl(void);
|
|
struct BgCnt *BG_GetControlBuffer(u16 bg);
|
|
int GetBackgroundTileDataOffset(int bg);
|
|
int GetTileIndex(int bg, int offset);
|
|
int BG_GetTileMapOffset(int bg);
|
|
void SetBackgroundTileDataOffset(int bg, int offset);
|
|
void SetBackgroundMapDataOffset(int bg, int offset);
|
|
void SetBackgroundScreenSize(int bg, int size);
|
|
void BG_SetColorBpp(int bg, int bitsPerPixel);
|
|
// ??? ApplyColorAddition_ClampMax(???);
|
|
// ??? ApplyColorAddition_ClampMin(???);
|
|
void FlushBackgrounds(void);
|
|
void BG_Fill(void *dest, int b);
|
|
void RegisterBlankTile(int a);
|
|
void SetInterrupt_LCDVBlank(InterruptHandler handler);
|
|
void SetInterrupt_LCDVCountMatch(InterruptHandler handler);
|
|
void SetNextVCount(int a);
|
|
void SetLCDVCountSetting(int set);
|
|
void SetMainUpdateRoutine(void(*)(void));
|
|
void ExecMainUpdate();
|
|
// ??? _UpdateKeyStatus(???);
|
|
void UpdateKeyStatus(struct KeyStatusBuffer *keyStatus);
|
|
void SnycKeyStatus(struct KeyStatusBuffer *keyStatus);
|
|
void ResetKeyStatus(struct KeyStatusBuffer *keyStatus);
|
|
void SetKeyStatus_IgnoreMask(int keys);
|
|
int GetKeyStatus_IgnoreMask(void);
|
|
// ??? AsnycKeyStatusExt(???);
|
|
void AsnycKeyStatus(int key);
|
|
void BG_SetPosition(u16 bg, u16 x, u16 y);
|
|
void sub_800151C(u8 a, u8 b);
|
|
void sub_800151C(u8 a, u8 b);
|
|
void sub_8001530(u16 *a, u16 *b);
|
|
void sub_800154C(void* outTm, void const* inData, u8 base, u8 linebits);
|
|
void AddAttr2dBitMap(u16 * _dst, u16 * _src, s16 ix, s16 iy, u16 chr);
|
|
// ??? sub_80016C4(???);
|
|
void MaybeResetSomePal(void);
|
|
void MaybeSmoothChangeSomePal(u16 *src, int b, int c, int d);
|
|
void sub_80017B4(int a, int b, int c, int d);
|
|
void sub_800183C(int a, int b, int c);
|
|
void ColorFadeSetupFromColorToBlack(u8);
|
|
void ColorFadeSetupFromBlack(u8);
|
|
void ColorFadeSetupFromColorToWhite(u8);
|
|
void ColorFadeSetupFromWhite(u8);
|
|
void sub_8001A6C(void);
|
|
void SetupBackgrounds(u16 *bgConfig);
|
|
u16* BG_GetMapBuffer(int bg);
|
|
void SetSoftwareResetFlag(u8);
|
|
int IsSoftwareReset(void);
|
|
void SoftResetIfKeyComboPressed();
|
|
void sub_8001CB0(int a);
|
|
void ExecBothHBlankHandlers(void);
|
|
void UpdateHBlankHandlerState(void);
|
|
void SetPrimaryHBlankHandler(void (*hblankHandler)(void));
|
|
void SetSecondaryHBlankHandler(void(*)(void));
|
|
int GetBackgroundFromBufferPointer(u16 *ptr);
|
|
void BG_SetPriority(int bg, int priority);
|
|
int BG_GetPriority(int bg);
|
|
void SetBlendConfig(u16 effect, u8 coeffA, u8 coeffB, u8 blendY);
|
|
void SetBlendTargetA(int, int, int, int, int);
|
|
void SetBlendTargetB(int, int, int, int, int);
|
|
void SetBlendBackdropA(int);
|
|
void SetBlendBackdropB(int a);
|
|
void SetDefaultColorEffects(void);
|
|
void EnablePaletteSync(void);
|
|
void DisablePaletteSync(void);
|
|
void BG_EnableSyncByMask(int bg);
|
|
void BG_EnableSync(int bg);
|
|
void sub_8001FD0(int a);
|
|
void ClearTileRigistry(void);
|
|
void RegisterDataMove(const void *a, void *b, int c);
|
|
void RegisterFillTile(const void *a, void *b, int c);
|
|
void FlushTiles(void);
|
|
void InitOam(int a);
|
|
void SyncHiOam(void);
|
|
void SyncLoOam(void);
|
|
void SetObjAffine(int index, s16 pa, s16 pb, s16 pc, s16 pd);
|
|
// ??? sub_80021E4(???);
|
|
int GetPrimaryOAMSize(void);
|
|
|
|
#endif // GUARD_HARDWARE_H
|