#ifndef GPU_H
#define GPU_H
#include "ARM9.h"
#include <stdio.h>
#include "mem.h"
#include "registers.h"
#include "FIFO.h"
#include "MMU.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WORDS_BIGENDIAN
struct _DISPCNT
{
u8 ForceBlank:1; u8 OBJ_BMP_mapping:1; u8 OBJ_BMP_2D_dim:1; u8 OBJ_Tile_1D:1; u8 BG0_3D:1; u8 BG_Mode:3; u8 WinOBJ_Enable:1; u8 Win1_Enable:1; u8 Win0_Enable:1; u8 OBJ_Enable:1; u8 BG3_Enable:1; u8 BG2_Enable:1; u8 BG1_Enable:1; u8 BG0_Enable:1; u8 OBJ_HBlank_process:1; u8 OBJ_BMP_1D_Bound:1; u8 OBJ_Tile_1D_Bound:2; u8 VRAM_Block:2;
u8 DisplayMode:2;
u8 ExOBJPalette_Enable:1; u8 ExBGxPalette_Enable:1; u8 ScreenBase_Block:3; u8 CharacBase_Block:3; };
#else
struct _DISPCNT
{
u8 BG_Mode:3; u8 BG0_3D:1; u8 OBJ_Tile_1D:1; u8 OBJ_BMP_2D_dim:1; u8 OBJ_BMP_mapping:1;
u8 ForceBlank:1; u8 BG0_Enable:1; u8 BG1_Enable:1; u8 BG2_Enable:1; u8 BG3_Enable:1; u8 OBJ_Enable:1; u8 Win0_Enable:1; u8 Win1_Enable:1; u8 WinOBJ_Enable:1;
u8 DisplayMode:2;
u8 VRAM_Block:2; u8 OBJ_Tile_1D_Bound:2; u8 OBJ_BMP_1D_Bound:1; u8 OBJ_HBlank_process:1; u8 CharacBase_Block:3; u8 ScreenBase_Block:3; u8 ExBGxPalette_Enable:1; u8 ExOBJPalette_Enable:1; };
#endif
typedef union
{
struct _DISPCNT bits;
u32 val;
} DISPCNT;
#define BGxENABLED(cnt,num) ((num<8)? ((cnt.val>>8) & num):0)
#ifdef WORDS_BIGENDIAN
struct _BGxCNT
{
u8 Palette_256:1; u8 Mosaic_Enable:1; u8 CharacBase_Block:4; u8 Priority:2; u8 ScreenSize:2; u8 PaletteSet_Wrap:1; u8 ScreenBase_Block:5; };
#else
struct _BGxCNT
{
u8 Priority:2; u8 CharacBase_Block:4; u8 Mosaic_Enable:1; u8 Palette_256:1; u8 ScreenBase_Block:5; u8 PaletteSet_Wrap:1; u8 ScreenSize:2; };
#endif
typedef union
{
struct _BGxCNT bits;
u16 val;
} BGxCNT;
typedef struct {
u16 BGxHOFS;
u16 BGxVOFS;
} BGxOFS;
typedef struct {
s16 BGxPA;
s16 BGxPB;
s16 BGxPC;
s16 BGxPD;
s32 BGxX;
s32 BGxY;
} BGxPARMS;
typedef union {
struct {
u8 end:8;
u8 start:8;
} bits ;
u16 val;
} WINxDIM;
#ifdef WORDS_BIGENDIAN
typedef struct {
u8 :2;
u8 WINx_Effect_Enable:1;
u8 WINx_OBJ_Enable:1;
u8 WINx_BG3_Enable:1;
u8 WINx_BG2_Enable:1;
u8 WINx_BG1_Enable:1;
u8 WINx_BG0_Enable:1;
} WINxBIT;
#else
typedef struct {
u8 WINx_BG0_Enable:1;
u8 WINx_BG1_Enable:1;
u8 WINx_BG2_Enable:1;
u8 WINx_BG3_Enable:1;
u8 WINx_OBJ_Enable:1;
u8 WINx_Effect_Enable:1;
u8 :2;
} WINxBIT;
#endif
#ifdef WORDS_BIGENDIAN
typedef union {
struct {
WINxBIT win0;
WINxBIT win1;
} bits;
struct {
u8 :3;
u8 win0_en:5;
u8 :3;
u8 win1_en:5;
} packed_bits;
struct {
u8 low;
u8 high;
} bytes;
u16 val ;
} WINxCNT ;
#else
typedef union {
struct {
WINxBIT win0;
WINxBIT win1;
} bits;
struct {
u8 win0_en:5;
u8 :3;
u8 win1_en:5;
u8 :3;
} packed_bits;
struct {
u8 low;
u8 high;
} bytes;
u16 val ;
} WINxCNT ;
#endif
typedef struct {
u16 MOSAIC;
u16 unused1;
u16 unused2; u16 unused3; u16 unused4; u16 unused5;
} MISCCNT;
struct _DISP3DCNT
{
u8 EnableTexMapping:1; u8 PolygonShading:1; u8 EnableAlphaTest:1; u8 EnableAlphaBlending:1; u8 EnableAntiAliasing:1; u8 EnableEdgeMarking:1; u8 FogOnlyAlpha:1; u8 EnableFog:1; u8 FogShiftSHR:4; u8 AckColorBufferUnderflow:1; u8 AckVertexRAMOverflow:1; u8 RearPlaneMode:1; u8 :1;
u16 :16;
};
typedef union
{
struct _DISP3DCNT bits;
u32 val;
} DISP3DCNT;
struct _DISPCAPCNT
{
u8 BlendFactor_A:5; u8 :3; u8 BlendFactor_B:5; u8 :3; u8 VRAM_Write_Block:2; u8 VRAM_Write_Offset:2; u8 Capture_Size:2; u8 :2; u8 Source_A:1; u8 Source_B:1; u8 VRAM_Read_Offset:2; u8 :1; u8 Capture_Source:2; u8 Capture_Enable:1; };
typedef union
{
struct _DISPCAPCNT bits;
u32 val;
} DISPCAPCNT;
typedef struct _reg_dispx {
DISPCNT dispx_DISPCNT; u16 dispA_DISPSTAT; u16 dispx_VCOUNT; BGxCNT dispx_BGxCNT[4]; BGxOFS dispx_BGxOFS[4]; BGxPARMS dispx_BG2PARMS; BGxPARMS dispx_BG3PARMS; u8 filler[12]; MISCCNT dispx_MISC; DISP3DCNT dispA_DISP3DCNT; DISPCAPCNT dispA_DISPCAPCNT; u32 dispA_DISPMMEMFIFO; } REG_DISPx ;
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef max
#define max(a,b) (((a)>(b))?(a):(b))
#endif
typedef BOOL (*fun_gl_Begin) (int screen);
typedef void (*fun_gl_End) (int screen);
void register_gl_fun(fun_gl_Begin beg,fun_gl_End end);
#define GPU_MAIN 0
#define GPU_SUB 1
#define ADDRESS_STEP_512B 0x00200
#define ADDRESS_STEP_1KB 0x00400
#define ADDRESS_STEP_2KB 0x00800
#define ADDRESS_STEP_4KB 0x01000
#define ADDRESS_STEP_8KB 0x02000
#define ADDRESS_STEP_16KB 0x04000
#define ADDRESS_STEP_32KB 0x08000
#define ADDRESS_STEP_64kB 0x10000
#ifdef WORDS_BIGENDIAN
struct _TILEENTRY
{
unsigned Palette:4;
unsigned VFlip:1; unsigned HFlip:1; unsigned TileNum:10;
};
#else
struct _TILEENTRY
{
unsigned TileNum:10;
unsigned HFlip:1; unsigned VFlip:1; unsigned Palette:4;
};
#endif
typedef union
{
struct _TILEENTRY bits;
u16 val;
} TILEENTRY;
struct _ROTOCOORD
{
unsigned Fraction:8;
signed Integer:24;
};
typedef union
{
struct _ROTOCOORD bits;
s32 val;
} ROTOCOORD;
struct _COLOR { #ifdef WORDS_BIGENDIAN
unsigned alpha:1; unsigned blue:5;
unsigned green:5;
unsigned red:5;
#else
unsigned red:5;
unsigned green:5;
unsigned blue:5;
unsigned alpha:1; #endif
};
struct _COLORx { unsigned bgr:15;
unsigned alpha:1; };
typedef union
{
struct _COLOR bits;
struct _COLORx bitx;
u16 val;
} COLOR;
struct _COLOR32 { unsigned :3;
unsigned blue:5;
unsigned :3;
unsigned green:5;
unsigned :3;
unsigned red:5;
unsigned :7;
unsigned alpha:1; };
typedef union
{
struct _COLOR32 bits;
u32 val;
} COLOR32;
#define COLOR_16_32(w,i) \
\
i.bits.red = w.bits.red; \
i.bits.green = w.bits.green; \
i.bits.blue = w.bits.blue; \
i.bits.alpha = w.bits.alpha;
typedef struct
{
#ifdef WORDS_BIGENDIAN
unsigned Y:8;
unsigned Shape:2; unsigned Depth:1; unsigned Mosaic:1; unsigned Mode:2; unsigned RotScale:2; signed X:9;
unsigned Size:2;
unsigned VFlip:1;
unsigned HFlip:1;
unsigned RotScalIndex:3; unsigned TileIndex:10;
unsigned PaletteIndex:4;
unsigned Priority:2;
unsigned attr3:16;
#else
unsigned Y:8;
unsigned RotScale:2; unsigned Mode:2; unsigned Mosaic:1; unsigned Depth:1; unsigned Shape:2; signed X:9;
unsigned RotScalIndex:3; unsigned HFlip:1;
unsigned VFlip:1;
unsigned Size:2;
unsigned TileIndex:10;
unsigned Priority:2;
unsigned PaletteIndex:4;
unsigned attr3:16;
#endif
} _OAM_;
typedef struct
{
u16 attr0;
u16 attr1;
u16 attr2;
u16 attr3;
} OAM;
typedef struct
{
s16 x;
s16 y;
} size;
#define NB_PRIORITIES 4
#define NB_BG 4
typedef struct
{
u8 BGs[NB_BG], nbBGs;
u8 PixelsX[256];
u16 nbPixelsX;
} itemsForPriority_t;
typedef struct _GPU GPU;
struct _GPU
{
REG_DISPx * dispx_st;
DISPCAPCNT dispCapCnt;
BOOL LayersEnable[5];
itemsForPriority_t itemsForPriority[NB_PRIORITIES];
u8 sprWin[256][256];
#define BGBmpBB BG_bmp_ram
#define BGChBB BG_tile_ram
u8 *(BG_bmp_ram[4]);
u8 *(BG_tile_ram[4]);
u8 *(BG_map_ram[4]);
u8 BGExtPalSlot[4];
u32 BGSize[4][2];
u8 lcd;
u8 core;
u8 dispMode;
u8 vramBlock;
BOOL dispBG[4];
BOOL dispOBJ;
OAM * oam;
u8 * sprMem;
u8 sprBoundary;
u8 sprBMPBoundary;
u8 sprBMPMode;
u32 sprEnable;
u8 WIN0H0;
u8 WIN0H1;
u8 WIN0V0;
u8 WIN0V1;
u8 WIN1H0;
u8 WIN1H1;
u8 WIN1V0;
u8 WIN1V1;
u8 WININ0;
u8 WININ0_SPECIAL;
u8 WININ1;
u8 WININ1_SPECIAL;
u8 WINOUT;
u8 WINOUT_SPECIAL;
u8 WINOBJ;
u8 WINOBJ_SPECIAL;
u8 WIN0_ENABLED;
u8 WIN1_ENABLED;
u8 WINOBJ_ENABLED;
u16 BLDCNT;
u8 BLDALPHA_EVA;
u8 BLDALPHA_EVB;
u8 BLDY_EVY;
u8 MasterBrightMode;
u32 MasterBrightFactor;
BOOL (*setFinalColorSpr)(const GPU *gpu, u32 passing, u8 bgnum, u8 *dst, u16 color, u16 x, u16 y);
BOOL (*setFinalColorBck)(const GPU *gpu, u32 passing, u8 bgnum, u8 *dst, u16 color, u16 x, u16 y);
void (*spriteRender) (GPU * gpu, u16 l, u8 * dst, u8 * prioTab);
};
extern u8 GPU_screen[4*256*192];
GPU * GPU_Init(u8 l);
void GPU_Reset(GPU *g, u8 l);
void GPU_DeInit(GPU *);
void textBG(const GPU * gpu, u8 num, u8 * DST); void rotBG(GPU * gpu, u8 num, u8 * DST);
void extRotBG(GPU * gpu, u8 num, u8 * DST);
void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab);
void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab);
extern short sizeTab[4][4][2];
extern size sprSizeTab[4][4];
extern s8 mode2type[8][4];
extern void (*modeRender[8][4])(GPU * gpu, u8 num, u16 l, u8 * DST);
typedef struct {
GPU * gpu;
u16 offset;
} NDS_Screen;
extern NDS_Screen MainScreen;
extern NDS_Screen SubScreen;
int Screen_Init(int coreid);
void Screen_Reset(void);
void Screen_DeInit(void);
extern MMU_struct MMU;
#define GFXCORE_DEFAULT -1
#define GFXCORE_DUMMY 0
#define GFXCORE_FULLSCREEN (1 << 0)
typedef struct
{
int id; const char *Name; int flags; int (*Init)(); void (*DeInit)(); void (*Resize)(int width, int height, BOOL fullscreen); void (*OnScreenText)(char *string, ...); } GraphicsInterface_struct;
extern GraphicsInterface_struct GFXDummy;
void GPU_setVideoProp(GPU *, u32 p);
void GPU_setBGProp(GPU *, u16 num, u16 p);
void GPU_setBLDCNT(GPU *gpu, u16 v) ;
void GPU_setBLDALPHA(GPU *gpu, u16 v) ;
void GPU_setBLDY(GPU *gpu, u16 v) ;
void GPU_setMOSAIC(GPU *gpu, u16 v) ;
void GPU_remove(GPU *, u8 num);
void GPU_addBack(GPU *, u8 num);
int GPU_ChangeGraphicsCore(int coreid);
void GPU_set_DISPCAPCNT(GPU * gpu, u32 val) ;
void GPU_ligne(NDS_Screen * screen, u16 l) ;
void GPU_setMasterBrightness (GPU *gpu, u16 val);
void GPU_setWIN0_H (GPU *gpu, u16 val);
void GPU_setWIN0_H0 (GPU *gpu, u8 val);
void GPU_setWIN0_H1 (GPU *gpu, u8 val);
void GPU_setWIN0_V (GPU *gpu, u16 val);
void GPU_setWIN0_V0 (GPU *gpu, u8 val);
void GPU_setWIN0_V1 (GPU *gpu, u8 val);
void GPU_setWIN1_H (GPU *gpu, u16 val);
void GPU_setWIN1_H0 (GPU *gpu, u8 val);
void GPU_setWIN1_H1 (GPU *gpu, u8 val);
void GPU_setWIN1_V (GPU *gpu, u16 val);
void GPU_setWIN1_V0 (GPU *gpu, u8 val);
void GPU_setWIN1_V1 (GPU *gpu, u8 val);
void GPU_setWININ (GPU *gpu, u16 val);
void GPU_setWININ0 (GPU *gpu, u8 val);
void GPU_setWININ1 (GPU *gpu, u8 val);
void GPU_setWINOUT16(GPU *gpu, u16 val);
void GPU_setWINOUT (GPU *gpu, u8 val);
void GPU_setWINOBJ (GPU *gpu, u8 val);
void GPU_setBLDCNT_LOW (GPU *gpu, u8 val);
void GPU_setBLDCNT_HIGH (GPU *gpu, u8 val);
void GPU_setBLDCNT (GPU *gpu, u16 val);
void GPU_setBLDALPHA (GPU *gpu, u16 val);
void GPU_setBLDALPHA_EVA(GPU *gpu, u8 val);
void GPU_setBLDALPHA_EVB(GPU *gpu, u8 val);
void GPU_setBLDY_EVY (GPU *gpu, u8 val);
#ifdef __cplusplus
}
#endif
#endif