mirror of https://github.com/mgba-emu/mgba.git
DS Video: Implement extended character base
This commit is contained in:
parent
76885a1c17
commit
e5ae0209a6
|
@ -24,6 +24,7 @@ struct GBAVideoSoftwareBackground {
|
|||
int enabled;
|
||||
unsigned priority;
|
||||
uint32_t charBase;
|
||||
uint16_t control;
|
||||
int mosaic;
|
||||
int multipalette;
|
||||
uint32_t screenBase;
|
||||
|
|
|
@ -127,7 +127,7 @@ DECL_BITS(GBARegisterDISPSTAT, VcountSetting, 8, 8);
|
|||
|
||||
DECL_BITFIELD(GBARegisterBGCNT, uint16_t);
|
||||
DECL_BITS(GBARegisterBGCNT, Priority, 0, 2);
|
||||
DECL_BITS(GBARegisterBGCNT, CharBase, 2, 2);
|
||||
DECL_BITS(GBARegisterBGCNT, CharBase, 2, 4);
|
||||
DECL_BIT(GBARegisterBGCNT, Mosaic, 6);
|
||||
DECL_BIT(GBARegisterBGCNT, 256Color, 7);
|
||||
DECL_BITS(GBARegisterBGCNT, ScreenBase, 8, 5);
|
||||
|
|
|
@ -74,22 +74,23 @@ static void DSVideoSoftwareRendererUpdateDISPCNTA(struct DSVideoSoftwareRenderer
|
|||
softwareRenderer->engA.d.writeVideoRegister(&softwareRenderer->engA.d, DS9_REG_A_DISPCNT_LO, fakeDispcnt);
|
||||
uint32_t charBase = DSRegisterDISPCNTGetCharBase(softwareRenderer->dispcntA) << 16;
|
||||
uint32_t screenBase = DSRegisterDISPCNTGetScreenBase(softwareRenderer->dispcntA) << 16;
|
||||
softwareRenderer->engA.bg[0].charBase &= ~0x70000;
|
||||
softwareRenderer->engA.bg[0].charBase |= charBase;
|
||||
softwareRenderer->engA.d.writeVideoRegister(&softwareRenderer->engA.d, DS9_REG_A_BG0CNT, softwareRenderer->engA.bg[0].control);
|
||||
softwareRenderer->engA.bg[0].charBase += charBase;
|
||||
softwareRenderer->engA.bg[0].screenBase &= ~0x70000;
|
||||
softwareRenderer->engA.bg[0].screenBase |= screenBase;
|
||||
softwareRenderer->engA.bg[1].charBase &= ~0x70000;
|
||||
softwareRenderer->engA.bg[1].charBase |= charBase;
|
||||
softwareRenderer->engA.d.writeVideoRegister(&softwareRenderer->engA.d, DS9_REG_A_BG1CNT, softwareRenderer->engA.bg[1].control);
|
||||
softwareRenderer->engA.bg[1].charBase += charBase;
|
||||
softwareRenderer->engA.bg[1].screenBase &= ~0x70000;
|
||||
softwareRenderer->engA.bg[1].screenBase |= screenBase;
|
||||
softwareRenderer->engA.bg[2].charBase &= ~0x70000;
|
||||
softwareRenderer->engA.bg[2].charBase |= charBase;
|
||||
softwareRenderer->engA.d.writeVideoRegister(&softwareRenderer->engA.d, DS9_REG_A_BG2CNT, softwareRenderer->engA.bg[2].control);
|
||||
softwareRenderer->engA.bg[2].charBase += charBase;
|
||||
softwareRenderer->engA.bg[2].screenBase &= ~0x70000;
|
||||
softwareRenderer->engA.bg[2].screenBase |= screenBase;
|
||||
softwareRenderer->engA.bg[3].charBase &= ~0x70000;
|
||||
softwareRenderer->engA.bg[3].charBase |= charBase;
|
||||
softwareRenderer->engA.d.writeVideoRegister(&softwareRenderer->engA.d, DS9_REG_A_BG3CNT, softwareRenderer->engA.bg[3].control);
|
||||
softwareRenderer->engA.bg[3].charBase += charBase;
|
||||
softwareRenderer->engA.bg[3].screenBase &= ~0x70000;
|
||||
softwareRenderer->engA.bg[3].screenBase |= screenBase;}
|
||||
softwareRenderer->engA.bg[3].screenBase |= screenBase;
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererUpdateDISPCNTB(struct DSVideoSoftwareRenderer* softwareRenderer) {
|
||||
uint16_t fakeDispcnt = softwareRenderer->dispcntB & 0xFF87;
|
||||
|
|
|
@ -68,8 +68,11 @@
|
|||
#define SPRITE_YBASE_16(localY) unsigned yBase = (localY & ~0x7) * stride + (localY & 0x7) * 4;
|
||||
|
||||
#define SPRITE_DRAW_PIXEL_16_NORMAL(localX) \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x7FFE); \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x3FFFE); \
|
||||
uint16_t* vramBase = renderer->d.vramOBJ[spriteBase >> VRAM_BLOCK_OFFSET]; \
|
||||
if (UNLIKELY(!vramBase)) { \
|
||||
return 0; \
|
||||
} \
|
||||
LOAD_16(tileData, spriteBase & VRAM_BLOCK_MASK, vramBase); \
|
||||
tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \
|
||||
current = renderer->spriteLayer[outX]; \
|
||||
|
@ -82,8 +85,11 @@
|
|||
}
|
||||
|
||||
#define SPRITE_DRAW_PIXEL_16_NORMAL_OBJWIN(localX) \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x7FFE); \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x3FFFE); \
|
||||
uint16_t* vramBase = renderer->d.vramOBJ[spriteBase >> VRAM_BLOCK_OFFSET]; \
|
||||
if (UNLIKELY(!vramBase)) { \
|
||||
return 0; \
|
||||
} \
|
||||
LOAD_16(tileData, spriteBase & VRAM_BLOCK_MASK, vramBase); \
|
||||
tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \
|
||||
current = renderer->spriteLayer[outX]; \
|
||||
|
@ -97,8 +103,11 @@
|
|||
}
|
||||
|
||||
#define SPRITE_DRAW_PIXEL_16_OBJWIN(localX) \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x7FFE); \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x3FFFE); \
|
||||
uint16_t* vramBase = renderer->d.vramOBJ[spriteBase >> VRAM_BLOCK_OFFSET]; \
|
||||
if (UNLIKELY(!vramBase)) { \
|
||||
return 0; \
|
||||
} \
|
||||
LOAD_16(tileData, spriteBase & VRAM_BLOCK_MASK, vramBase); \
|
||||
tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \
|
||||
if (tileData) { \
|
||||
|
@ -109,8 +118,11 @@
|
|||
#define SPRITE_YBASE_256(localY) unsigned yBase = (localY & ~0x7) * stride + (localY & 0x7) * 8;
|
||||
|
||||
#define SPRITE_DRAW_PIXEL_256_NORMAL(localX) \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x7FFE); \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x3FFFE); \
|
||||
uint16_t* vramBase = renderer->d.vramOBJ[spriteBase >> VRAM_BLOCK_OFFSET]; \
|
||||
if (UNLIKELY(!vramBase)) { \
|
||||
return 0; \
|
||||
} \
|
||||
LOAD_16(tileData, spriteBase & VRAM_BLOCK_MASK, vramBase); \
|
||||
tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \
|
||||
current = renderer->spriteLayer[outX]; \
|
||||
|
@ -123,8 +135,11 @@
|
|||
}
|
||||
|
||||
#define SPRITE_DRAW_PIXEL_256_NORMAL_OBJWIN(localX) \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x7FFE); \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x3FFFE); \
|
||||
uint16_t* vramBase = renderer->d.vramOBJ[spriteBase >> VRAM_BLOCK_OFFSET]; \
|
||||
if (UNLIKELY(!vramBase)) { \
|
||||
return 0; \
|
||||
} \
|
||||
LOAD_16(tileData, spriteBase & VRAM_BLOCK_MASK, vramBase); \
|
||||
tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \
|
||||
current = renderer->spriteLayer[outX]; \
|
||||
|
@ -138,8 +153,11 @@
|
|||
}
|
||||
|
||||
#define SPRITE_DRAW_PIXEL_256_OBJWIN(localX) \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x7FFE); \
|
||||
uint32_t spriteBase = ((yBase + charBase + xBase) & 0x3FFFE); \
|
||||
uint16_t* vramBase = renderer->d.vramOBJ[spriteBase >> VRAM_BLOCK_OFFSET]; \
|
||||
if (UNLIKELY(!vramBase)) { \
|
||||
return 0; \
|
||||
} \
|
||||
LOAD_16(tileData, spriteBase & VRAM_BLOCK_MASK, vramBase); \
|
||||
tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \
|
||||
if (tileData) { \
|
||||
|
@ -160,7 +178,6 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
|
|||
int32_t x = (uint32_t) GBAObjAttributesBGetX(sprite->b) << 23;
|
||||
x >>= 23;
|
||||
unsigned charBase = GBAObjAttributesCGetTile(sprite->c) * renderer->tileStride;
|
||||
uint16_t* vramBase = NULL;
|
||||
if (GBARegisterDISPCNTGetMode(renderer->dispcnt) >= 3 && GBAObjAttributesCGetTile(sprite->c) < 512) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -637,14 +637,17 @@ static void GBAVideoSoftwareRendererUpdateDISPCNT(struct GBAVideoSoftwareRendere
|
|||
static void GBAVideoSoftwareRendererWriteBGCNT(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* bg, uint16_t value) {
|
||||
UNUSED(renderer);
|
||||
bg->priority = GBARegisterBGCNTGetPriority(value);
|
||||
bg->charBase &= ~0xC000;
|
||||
bg->charBase |= GBARegisterBGCNTGetCharBase(value) << 14;
|
||||
bg->charBase = GBARegisterBGCNTGetCharBase(value) << 14;
|
||||
if (!renderer->d.vramBG[4]) {
|
||||
bg->charBase &= 0xC000;
|
||||
}
|
||||
bg->mosaic = GBARegisterBGCNTGetMosaic(value);
|
||||
bg->multipalette = GBARegisterBGCNTGet256Color(value);
|
||||
bg->screenBase &= ~0xF800;
|
||||
bg->screenBase |= GBARegisterBGCNTGetScreenBase(value) << 11;
|
||||
bg->overflow = GBARegisterBGCNTGetOverflow(value);
|
||||
bg->size = GBARegisterBGCNTGetSize(value);
|
||||
bg->control = value;
|
||||
}
|
||||
|
||||
static void GBAVideoSoftwareRendererWriteBGPA(struct GBAVideoSoftwareBackground* bg, uint16_t value) {
|
||||
|
|
Loading…
Reference in New Issue