working gfx are better then speed.
git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@926 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
parent
c1607a0df5
commit
f30577f406
356
src/gba/GBAGfx.h
356
src/gba/GBAGfx.h
|
@ -5,10 +5,10 @@
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
#include "../common/Port.h"
|
#include "../common/Port.h"
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
//#define SPRITE_DEBUG
|
//#define SPRITE_DEBUG
|
||||||
|
|
||||||
|
static void gfxDrawTextScreen(u16, u16, u16, u32 *);
|
||||||
static void gfxDrawRotScreen(u16,
|
static void gfxDrawRotScreen(u16,
|
||||||
u16, u16,
|
u16, u16,
|
||||||
u16, u16,
|
u16, u16,
|
||||||
|
@ -98,261 +98,145 @@ static inline void gfxClearArray(u32 *array)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __GNUC__
|
static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
|
||||||
union u8h
|
u32 *line)
|
||||||
{
|
{
|
||||||
struct
|
u16 *palette = (u16 *)paletteRAM;
|
||||||
{
|
u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000];
|
||||||
/* 0*/ unsigned lo:4;
|
u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800];
|
||||||
/* 4*/ unsigned hi:4;
|
u32 prio = ((control & 3)<<25) + 0x1000000;
|
||||||
} __attribute__ ((packed));
|
int sizeX = 256;
|
||||||
u8 val;
|
int sizeY = 256;
|
||||||
};
|
switch((control >> 14) & 3) {
|
||||||
#else
|
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;
|
||||||
|
|
||||||
union u8h
|
bool mosaicOn = (control & 0x40) ? true : false;
|
||||||
{
|
|
||||||
__declspec(align(8)) struct
|
|
||||||
{
|
|
||||||
unsigned lo:2;
|
|
||||||
unsigned hi:2;
|
|
||||||
};
|
|
||||||
u8 val;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
int xxx = hofs & maskX;
|
||||||
|
int yyy = (vofs + VCOUNT) & maskY;
|
||||||
|
int mosaicX = (MOSAIC & 0x000F)+1;
|
||||||
|
int mosaicY = ((MOSAIC & 0x00F0)>>4)+1;
|
||||||
|
|
||||||
union TileEntry
|
if(mosaicOn) {
|
||||||
{
|
if((VCOUNT % mosaicY) != 0) {
|
||||||
struct
|
mosaicY = VCOUNT - (VCOUNT % mosaicY);
|
||||||
{
|
yyy = (vofs + mosaicY) & maskY;
|
||||||
/* 0*/ unsigned tileNum:10;
|
}
|
||||||
/*12*/ unsigned hFlip:1;
|
}
|
||||||
/*13*/ unsigned vFlip:1;
|
|
||||||
/*14*/ unsigned palette:4;
|
|
||||||
};
|
|
||||||
u16 val;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TileLine
|
if(yyy > 255 && sizeY > 256) {
|
||||||
{
|
yyy &= 255;
|
||||||
u32 pixels[8];
|
screenBase += 0x400;
|
||||||
};
|
if(sizeX > 256)
|
||||||
|
screenBase += 0x400;
|
||||||
|
}
|
||||||
|
|
||||||
typedef const TileLine (*TileReader) (const u16 *, const int, const u8 *, u16 *, const u32);
|
int yshift = ((yyy>>3)<<5);
|
||||||
|
if((control) & 0x80) {
|
||||||
|
u16 *screenSource = screenBase + 0x400 * (xxx>>8) + ((xxx & 255)>>3) + yshift;
|
||||||
|
for(int x = 0; x < 240; x++) {
|
||||||
|
u16 data = READ16LE(screenSource);
|
||||||
|
|
||||||
static inline void gfxDrawPixel(u32 *dest, const u8 color, const u16 *palette, const u32 prio)
|
int tile = data & 0x3FF;
|
||||||
{
|
int tileX = (xxx & 7);
|
||||||
*dest = color ? (READ16LE(&palette[color]) | prio): 0x80000000;
|
int tileY = yyy & 7;
|
||||||
}
|
|
||||||
|
|
||||||
inline const TileLine gfxReadTile(const u16 *screenSource, const int yyy, const u8 *charBase, u16 *palette, const u32 prio)
|
if(tileX == 7)
|
||||||
{
|
screenSource++;
|
||||||
TileEntry tile;
|
|
||||||
tile.val = READ16LE(screenSource);
|
|
||||||
|
|
||||||
int tileY = yyy & 7;
|
if(data & 0x0400)
|
||||||
if (tile.vFlip) tileY = 7 - tileY;
|
tileX = 7 - tileX;
|
||||||
TileLine tileLine;
|
if(data & 0x0800)
|
||||||
|
tileY = 7 - tileY;
|
||||||
|
|
||||||
const u8 *tileBase = &charBase[tile.tileNum * 64 + tileY * 8];
|
u8 color = charBase[tile * 64 + tileY * 8 + tileX];
|
||||||
|
|
||||||
if (!tile.hFlip)
|
line[x] = color ? (READ16LE(&palette[color]) | prio): 0x80000000;
|
||||||
{
|
|
||||||
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;
|
xxx++;
|
||||||
}
|
if(xxx == 256) {
|
||||||
|
if(sizeX > 256)
|
||||||
|
screenSource = screenBase + 0x400 + yshift;
|
||||||
|
else {
|
||||||
|
screenSource = screenBase + yshift;
|
||||||
|
xxx = 0;
|
||||||
|
}
|
||||||
|
} else if(xxx >= sizeX) {
|
||||||
|
xxx = 0;
|
||||||
|
screenSource = screenBase + yshift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
u16 *screenSource = screenBase + 0x400*(xxx>>8)+((xxx&255)>>3) +
|
||||||
|
yshift;
|
||||||
|
for(int x = 0; x < 240; x++) {
|
||||||
|
u16 data = READ16LE(screenSource);
|
||||||
|
|
||||||
inline const TileLine gfxReadTilePal(const u16 *screenSource, const int yyy, const u8 *charBase, u16 *palette, const u32 prio)
|
int tile = data & 0x3FF;
|
||||||
{
|
int tileX = (xxx & 7);
|
||||||
TileEntry tile;
|
int tileY = yyy & 7;
|
||||||
tile.val = READ16LE(screenSource);
|
|
||||||
|
|
||||||
int tileY = yyy & 7;
|
if(tileX == 7)
|
||||||
if (tile.vFlip) tileY = 7 - tileY;
|
screenSource++;
|
||||||
palette += tile.palette * 16;
|
|
||||||
TileLine tileLine;
|
|
||||||
|
|
||||||
const u8h *tileBase = (u8h*) &charBase[tile.tileNum * 32 + tileY * 4];
|
if(data & 0x0400)
|
||||||
|
tileX = 7 - tileX;
|
||||||
|
if(data & 0x0800)
|
||||||
|
tileY = 7 - tileY;
|
||||||
|
|
||||||
if (!tile.hFlip)
|
u8 color = charBase[(tile<<5) + (tileY<<2) + (tileX>>1)];
|
||||||
{
|
|
||||||
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;
|
if(tileX & 1) {
|
||||||
}
|
color = (color >> 4);
|
||||||
|
} else {
|
||||||
|
color &= 0x0F;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void gfxDrawTile(const TileLine &tileLine, u32 *line)
|
int pal = (data>>8) & 0xF0;
|
||||||
{
|
line[x] = color ? (READ16LE(&palette[pal + color])|prio): 0x80000000;
|
||||||
memcpy(line, tileLine.pixels, sizeof(tileLine.pixels));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gfxDrawTileClipped(const TileLine &tileLine, u32 *line, const int start, int w)
|
xxx++;
|
||||||
{
|
if(xxx == 256) {
|
||||||
memcpy(line, tileLine.pixels + start, w * sizeof(u32));
|
if(sizeX > 256)
|
||||||
}
|
screenSource = screenBase + 0x400 + yshift;
|
||||||
|
else {
|
||||||
template<TileReader readTile>
|
screenSource = screenBase + yshift;
|
||||||
void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
|
xxx = 0;
|
||||||
u32 *line)
|
}
|
||||||
{
|
} else if(xxx >= sizeX) {
|
||||||
u16 *palette = (u16 *)paletteRAM;
|
xxx = 0;
|
||||||
u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000];
|
screenSource = screenBase + yshift;
|
||||||
u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800];
|
}
|
||||||
u32 prio = ((control & 3)<<25) + 0x1000000;
|
}
|
||||||
int sizeX = 256;
|
}
|
||||||
int sizeY = 256;
|
if(mosaicOn) {
|
||||||
switch ((control >> 14) & 3)
|
if(mosaicX > 1) {
|
||||||
{
|
int m = 1;
|
||||||
case 0:
|
for(int i = 0; i < 239; i++) {
|
||||||
break;
|
line[i+1] = line[i];
|
||||||
case 1:
|
m++;
|
||||||
sizeX = 512;
|
if(m == mosaicX) {
|
||||||
break;
|
m = 1;
|
||||||
case 2:
|
i++;
|
||||||
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);
|
|
||||||
|
|
||||||
u16 *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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
screenSource++;
|
|
||||||
x += firstTileX;
|
|
||||||
xxx += 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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs, u32 *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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gfxDrawRotScreen(u16 control,
|
static inline void gfxDrawRotScreen(u16 control,
|
||||||
|
|
Loading…
Reference in New Issue