Move gfxDrawTextScreen() into GBAGfx.cpp

This commit is contained in:
retro-wertz 2018-06-08 20:56:39 +08:00
parent 27aeb6dc67
commit 57dc0c25ff
3 changed files with 230 additions and 228 deletions

View File

@ -4190,233 +4190,6 @@ void CPULoop(int ticks)
#endif
}
#ifdef TILED_RENDERING
union uint8_th {
struct
{
/* 0*/ unsigned lo : 4;
/* 4*/ unsigned hi : 4;
} __attribute__((packed));
uint8_t val;
};
union TileEntry {
struct
{
/* 0*/ unsigned tileNum : 10;
/*12*/ unsigned hFlip : 1;
/*13*/ unsigned vFlip : 1;
/*14*/ unsigned palette : 4;
};
uint16_t val;
};
struct TileLine {
uint32_t pixels[8];
};
typedef const TileLine (*TileReader)(const uint16_t*, const int, const uint8_t*, uint16_t*, const uint32_t);
static inline void gfxDrawPixel(uint32_t* dest, const uint8_t color, const uint16_t* palette, const uint32_t prio)
{
*dest = color ? (READ16LE(&palette[color]) | prio) : 0x80000000;
}
inline const TileLine gfxReadTile(const uint16_t* screenSource, const int yyy, const uint8_t* charBase, uint16_t* palette, const uint32_t prio)
{
TileEntry tile;
tile.val = READ16LE(screenSource);
int tileY = yyy & 7;
if (tile.vFlip)
tileY = 7 - tileY;
TileLine tileLine;
const uint8_t* tileBase = &charBase[tile.tileNum * 64 + tileY * 8];
if (!tile.hFlip) {
gfxDrawPixel(&tileLine.pixels[0], tileBase[0], palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[1], palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[2], palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[3], palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[4], palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[5], palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[6], palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[7], palette, prio);
} else {
gfxDrawPixel(&tileLine.pixels[0], tileBase[7], palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[6], palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[5], palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[4], palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[3], palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[2], palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[1], palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[0], palette, prio);
}
return tileLine;
}
inline const TileLine gfxReadTilePal(const uint16_t* screenSource, const int yyy, const uint8_t* charBase, uint16_t* palette, const uint32_t prio)
{
TileEntry tile;
tile.val = READ16LE(screenSource);
int tileY = yyy & 7;
if (tile.vFlip)
tileY = 7 - tileY;
palette += tile.palette * 16;
TileLine tileLine;
const uint8_th* tileBase = (uint8_th*)&charBase[tile.tileNum * 32 + tileY * 4];
if (!tile.hFlip) {
gfxDrawPixel(&tileLine.pixels[0], tileBase[0].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[0].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[1].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[1].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[2].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[2].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[3].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[3].hi, palette, prio);
} else {
gfxDrawPixel(&tileLine.pixels[0], tileBase[3].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[3].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[2].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[2].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[1].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[1].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[0].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[0].lo, palette, prio);
}
return tileLine;
}
static inline void gfxDrawTile(const TileLine& tileLine, uint32_t* line)
{
memcpy(line, tileLine.pixels, sizeof(tileLine.pixels));
}
static inline void gfxDrawTileClipped(const TileLine& tileLine, uint32_t* line, const int start, int w)
{
memcpy(line, tileLine.pixels + start, w * sizeof(uint32_t));
}
template <TileReader readTile>
static void gfxDrawTextScreen(uint16_t control, uint16_t hofs, uint16_t vofs,
uint32_t* line)
{
uint16_t* palette = (uint16_t*)paletteRAM;
uint8_t* charBase = &vram[((control >> 2) & 0x03) * 0x4000];
uint16_t* screenBase = (uint16_t*)&vram[((control >> 8) & 0x1f) * 0x800];
uint32_t prio = ((control & 3) << 25) + 0x1000000;
int sizeX = 256;
int sizeY = 256;
switch ((control >> 14) & 3) {
case 0:
break;
case 1:
sizeX = 512;
break;
case 2:
sizeY = 512;
break;
case 3:
sizeX = 512;
sizeY = 512;
break;
}
int maskX = sizeX - 1;
int maskY = sizeY - 1;
bool mosaicOn = (control & 0x40) ? true : false;
int xxx = hofs & maskX;
int yyy = (vofs + VCOUNT) & maskY;
int mosaicX = (MOSAIC & 0x000F) + 1;
int mosaicY = ((MOSAIC & 0x00F0) >> 4) + 1;
if (mosaicOn) {
if ((VCOUNT % mosaicY) != 0) {
mosaicY = VCOUNT - (VCOUNT % mosaicY);
yyy = (vofs + mosaicY) & maskY;
}
}
if (yyy > 255 && sizeY > 256) {
yyy &= 255;
screenBase += 0x400;
if (sizeX > 256)
screenBase += 0x400;
}
int yshift = ((yyy >> 3) << 5);
uint16_t* screenSource = screenBase + 0x400 * (xxx >> 8) + ((xxx & 255) >> 3) + yshift;
int x = 0;
const int firstTileX = xxx & 7;
// First tile, if clipped
if (firstTileX) {
gfxDrawTileClipped(readTile(screenSource, yyy, charBase, palette, prio), &line[x], firstTileX, 8 - firstTileX);
screenSource++;
x += 8 - firstTileX;
xxx += 8 - firstTileX;
if (xxx == 256 && sizeX > 256) {
screenSource = screenBase + 0x400 + yshift;
} else if (xxx >= sizeX) {
xxx = 0;
screenSource = screenBase + yshift;
}
}
// Middle tiles, full
while (x < 240 - firstTileX) {
gfxDrawTile(readTile(screenSource, yyy, charBase, palette, prio), &line[x]);
screenSource++;
xxx += 8;
x += 8;
if (xxx == 256 && sizeX > 256) {
screenSource = screenBase + 0x400 + yshift;
} else if (xxx >= sizeX) {
xxx = 0;
screenSource = screenBase + yshift;
}
}
// Last tile, if clipped
if (firstTileX) {
gfxDrawTileClipped(readTile(screenSource, yyy, charBase, palette, prio), &line[x], 0, firstTileX);
}
if (mosaicOn) {
if (mosaicX > 1) {
int m = 1;
for (int i = 0; i < 239; i++) {
line[i + 1] = line[i];
m++;
if (m == mosaicX) {
m = 1;
i++;
}
}
}
}
}
void gfxDrawTextScreen(uint16_t control, uint16_t hofs, uint16_t vofs, uint32_t* line)
{
if (control & 0x80) // 1 pal / 256 col
gfxDrawTextScreen<gfxReadTile>(control, hofs, vofs, line);
else // 16 pal / 16 col
gfxDrawTextScreen<gfxReadTilePal>(control, hofs, vofs, line);
}
#endif
struct EmulatedSystem GBASystem = {
// emuMain
CPULoop,

View File

@ -1,3 +1,5 @@
#include <string.h>
#include "GBAGfx.h"
#include "../System.h"
int coeff[32] = {
@ -24,3 +26,230 @@ int gfxBG2Y = 0;
int gfxBG3X = 0;
int gfxBG3Y = 0;
int gfxLastVCOUNT = 0;
#ifdef TILED_RENDERING
union uint8_th {
struct
{
/* 0*/ unsigned lo : 4;
/* 4*/ unsigned hi : 4;
} __attribute__((packed));
uint8_t val;
};
union TileEntry {
struct
{
/* 0*/ unsigned tileNum : 10;
/*12*/ unsigned hFlip : 1;
/*13*/ unsigned vFlip : 1;
/*14*/ unsigned palette : 4;
};
uint16_t val;
};
struct TileLine {
uint32_t pixels[8];
};
typedef const TileLine (*TileReader)(const uint16_t*, const int, const uint8_t*, uint16_t*, const uint32_t);
static inline void gfxDrawPixel(uint32_t* dest, const uint8_t color, const uint16_t* palette, const uint32_t prio)
{
*dest = color ? (READ16LE(&palette[color]) | prio) : 0x80000000;
}
inline const TileLine gfxReadTile(const uint16_t* screenSource, const int yyy, const uint8_t* charBase, uint16_t* palette, const uint32_t prio)
{
TileEntry tile;
tile.val = READ16LE(screenSource);
int tileY = yyy & 7;
if (tile.vFlip)
tileY = 7 - tileY;
TileLine tileLine;
const uint8_t* tileBase = &charBase[tile.tileNum * 64 + tileY * 8];
if (!tile.hFlip) {
gfxDrawPixel(&tileLine.pixels[0], tileBase[0], palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[1], palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[2], palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[3], palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[4], palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[5], palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[6], palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[7], palette, prio);
} else {
gfxDrawPixel(&tileLine.pixels[0], tileBase[7], palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[6], palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[5], palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[4], palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[3], palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[2], palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[1], palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[0], palette, prio);
}
return tileLine;
}
inline const TileLine gfxReadTilePal(const uint16_t* screenSource, const int yyy, const uint8_t* charBase, uint16_t* palette, const uint32_t prio)
{
TileEntry tile;
tile.val = READ16LE(screenSource);
int tileY = yyy & 7;
if (tile.vFlip)
tileY = 7 - tileY;
palette += tile.palette * 16;
TileLine tileLine;
const uint8_th* tileBase = (uint8_th*)&charBase[tile.tileNum * 32 + tileY * 4];
if (!tile.hFlip) {
gfxDrawPixel(&tileLine.pixels[0], tileBase[0].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[0].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[1].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[1].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[2].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[2].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[3].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[3].hi, palette, prio);
} else {
gfxDrawPixel(&tileLine.pixels[0], tileBase[3].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[1], tileBase[3].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[2], tileBase[2].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[3], tileBase[2].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[4], tileBase[1].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[5], tileBase[1].lo, palette, prio);
gfxDrawPixel(&tileLine.pixels[6], tileBase[0].hi, palette, prio);
gfxDrawPixel(&tileLine.pixels[7], tileBase[0].lo, palette, prio);
}
return tileLine;
}
static inline void gfxDrawTile(const TileLine& tileLine, uint32_t* line)
{
memcpy(line, tileLine.pixels, sizeof(tileLine.pixels));
}
static inline void gfxDrawTileClipped(const TileLine& tileLine, uint32_t* line, const int start, int w)
{
memcpy(line, tileLine.pixels + start, w * sizeof(uint32_t));
}
template <TileReader readTile>
static void gfxDrawTextScreen(uint16_t control, uint16_t hofs, uint16_t vofs,
uint32_t* line)
{
uint16_t* palette = (uint16_t*)paletteRAM;
uint8_t* charBase = &vram[((control >> 2) & 0x03) * 0x4000];
uint16_t* screenBase = (uint16_t*)&vram[((control >> 8) & 0x1f) * 0x800];
uint32_t prio = ((control & 3) << 25) + 0x1000000;
int sizeX = 256;
int sizeY = 256;
switch ((control >> 14) & 3) {
case 0:
break;
case 1:
sizeX = 512;
break;
case 2:
sizeY = 512;
break;
case 3:
sizeX = 512;
sizeY = 512;
break;
}
int maskX = sizeX - 1;
int maskY = sizeY - 1;
bool mosaicOn = (control & 0x40) ? true : false;
int xxx = hofs & maskX;
int yyy = (vofs + VCOUNT) & maskY;
int mosaicX = (MOSAIC & 0x000F) + 1;
int mosaicY = ((MOSAIC & 0x00F0) >> 4) + 1;
if (mosaicOn) {
if ((VCOUNT % mosaicY) != 0) {
mosaicY = VCOUNT - (VCOUNT % mosaicY);
yyy = (vofs + mosaicY) & maskY;
}
}
if (yyy > 255 && sizeY > 256) {
yyy &= 255;
screenBase += 0x400;
if (sizeX > 256)
screenBase += 0x400;
}
int yshift = ((yyy >> 3) << 5);
uint16_t* screenSource = screenBase + 0x400 * (xxx >> 8) + ((xxx & 255) >> 3) + yshift;
int x = 0;
const int firstTileX = xxx & 7;
// First tile, if clipped
if (firstTileX) {
gfxDrawTileClipped(readTile(screenSource, yyy, charBase, palette, prio), &line[x], firstTileX, 8 - firstTileX);
screenSource++;
x += 8 - firstTileX;
xxx += 8 - firstTileX;
if (xxx == 256 && sizeX > 256) {
screenSource = screenBase + 0x400 + yshift;
} else if (xxx >= sizeX) {
xxx = 0;
screenSource = screenBase + yshift;
}
}
// Middle tiles, full
while (x < 240 - firstTileX) {
gfxDrawTile(readTile(screenSource, yyy, charBase, palette, prio), &line[x]);
screenSource++;
xxx += 8;
x += 8;
if (xxx == 256 && sizeX > 256) {
screenSource = screenBase + 0x400 + yshift;
} else if (xxx >= sizeX) {
xxx = 0;
screenSource = screenBase + yshift;
}
}
// Last tile, if clipped
if (firstTileX) {
gfxDrawTileClipped(readTile(screenSource, yyy, charBase, palette, prio), &line[x], 0, firstTileX);
}
if (mosaicOn) {
if (mosaicX > 1) {
int m = 1;
for (int i = 0; i < 239; i++) {
line[i + 1] = line[i];
m++;
if (m == mosaicX) {
m = 1;
i++;
}
}
}
}
}
void gfxDrawTextScreen(uint16_t control, uint16_t hofs, uint16_t vofs, uint32_t* line)
{
if (control & 0x80) // 1 pal / 256 col
gfxDrawTextScreen<gfxReadTile>(control, hofs, vofs, line);
else // 16 pal / 16 col
gfxDrawTextScreen<gfxReadTilePal>(control, hofs, vofs, line);
}
#endif // TILED_RENDERING

View File

@ -216,7 +216,7 @@ static inline void gfxDrawTextScreen(uint16_t control, uint16_t hofs, uint16_t v
}
}
}
#endif
#endif // !__TILED_RENDERING
static inline void gfxDrawRotScreen(uint16_t control, uint16_t x_l, uint16_t x_h, uint16_t y_l, uint16_t y_h, uint16_t pa, uint16_t pb,
uint16_t pc, uint16_t pd, int& currentX, int& currentY, int changed,