DS Video: Implement extended character base

This commit is contained in:
Vicki Pfau 2017-02-23 00:09:02 -08:00
parent 76885a1c17
commit e5ae0209a6
5 changed files with 41 additions and 19 deletions

View File

@ -24,6 +24,7 @@ struct GBAVideoSoftwareBackground {
int enabled;
unsigned priority;
uint32_t charBase;
uint16_t control;
int mosaic;
int multipalette;
uint32_t screenBase;

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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) {