implementing sprites drawn overtop of tilemap
This commit is contained in:
parent
28f98c20b2
commit
aeb1f47f51
188
testbed.c
188
testbed.c
|
@ -21,6 +21,7 @@
|
||||||
#define setAllPlanes() outport(REG_TS, 0x0f02)
|
#define setAllPlanes() outport(REG_TS, 0x0f02)
|
||||||
|
|
||||||
#define VID ((volatile char far *)MK_FP(0xa000, 0))
|
#define VID ((volatile char far *)MK_FP(0xa000, 0))
|
||||||
|
#define WVID ((volatile int far *)MK_FP(0xa000, 0))
|
||||||
|
|
||||||
void vid_cleanup() {
|
void vid_cleanup() {
|
||||||
setTextMode();
|
setTextMode();
|
||||||
|
@ -377,7 +378,7 @@ int tifLoadEGA(FILE *f, TifImageMeta_t meta, unsigned int vidOffset, int maxY, u
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int yRepeat) {
|
int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int yRepeat, int planes) {
|
||||||
int istrip;
|
int istrip;
|
||||||
int irow;
|
int irow;
|
||||||
int ipixelpair;
|
int ipixelpair;
|
||||||
|
@ -389,8 +390,9 @@ int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int
|
||||||
unsigned int *g = b + planeStride;
|
unsigned int *g = b + planeStride;
|
||||||
unsigned int *r = g + planeStride;
|
unsigned int *r = g + planeStride;
|
||||||
unsigned int *i = r + planeStride;
|
unsigned int *i = r + planeStride;
|
||||||
|
unsigned int *m = i + planeStride;
|
||||||
|
|
||||||
if (meta.width > MAX_WIDTH || (meta.width % 16) != 0) {
|
if (meta.width > MAX_WIDTH || (meta.width % 16) != 0 || planes < 4 || planes > 5) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,11 +415,17 @@ int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int
|
||||||
*++g = gpair;
|
*++g = gpair;
|
||||||
*++r = rpair;
|
*++r = rpair;
|
||||||
*++i = ipair;
|
*++i = ipair;
|
||||||
|
if (planes == 5) {
|
||||||
|
*++m = bpair & gpair & rpair & ipair;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
*b |= bpair << shift;
|
*b |= bpair << shift;
|
||||||
*g |= gpair << shift;
|
*g |= gpair << shift;
|
||||||
*r |= rpair << shift;
|
*r |= rpair << shift;
|
||||||
*i |= ipair << shift;
|
*i |= ipair << shift;
|
||||||
|
if (planes == 5) {
|
||||||
|
*m |= (bpair & gpair & rpair & ipair) << shift;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
y++;
|
y++;
|
||||||
|
@ -425,10 +433,10 @@ int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
if (y % yRepeat == 0) {
|
if (y % yRepeat == 0) {
|
||||||
b += planeStride * 3;
|
b += planeStride * (planes - 1);
|
||||||
g += planeStride * 3;
|
g += planeStride * (planes - 1);
|
||||||
r += planeStride * 3;
|
r += planeStride * (planes - 1);
|
||||||
i += planeStride * 3;
|
i += planeStride * (planes - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -436,12 +444,11 @@ int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** T I L E S ***/
|
/*** T I L E S ***/
|
||||||
void prepareEgaMemCopy() {
|
|
||||||
setAllPlanes();
|
|
||||||
setWriteMode(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PAGE_STRIDE 42
|
#define PAGE_TILES_W 21
|
||||||
|
#define PAGE_TILES_H 13
|
||||||
|
#define PAGE_TILES_COUNT (PAGE_TILES_H * PAGE_TILES_W)
|
||||||
|
#define PAGE_STRIDE (PAGE_TILES_W << 1)
|
||||||
|
|
||||||
void tile_init() {
|
void tile_init() {
|
||||||
setLogicalWidth(PAGE_STRIDE >> 1);
|
setLogicalWidth(PAGE_STRIDE >> 1);
|
||||||
|
@ -456,19 +463,33 @@ void blitTile(unsigned int offsetFrom, unsigned int offsetTo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define D_NOTHING 0x80
|
||||||
|
#define D_BGTILE 0x81
|
||||||
|
#define isBufIndex(d) (!((d) & 0x80))
|
||||||
|
|
||||||
|
#define NUM_BUFFERS 32
|
||||||
|
#define nextBufferIndex(i) ((i + 1) % 32)
|
||||||
|
#define BUF_WSTRIDE 16
|
||||||
|
#define BUF_WSIZE (BUF_WSTRIDE * 4)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int w;
|
unsigned int w;
|
||||||
unsigned int h;
|
unsigned int h;
|
||||||
int scrollX;
|
int scrollX;
|
||||||
int scrollY;
|
int scrollY;
|
||||||
unsigned int pageOffset[2];
|
unsigned int pageOffset[2];
|
||||||
unsigned char currentPage;
|
unsigned char dirty[2][PAGE_TILES_COUNT];
|
||||||
unsigned int tilesOffset;
|
unsigned int tilesOffset;
|
||||||
unsigned int *memTiles;
|
unsigned int *memTiles;
|
||||||
unsigned char *map;
|
unsigned char *map;
|
||||||
|
unsigned int buffer[NUM_BUFFERS][BUF_WSIZE];
|
||||||
|
unsigned int bufferOffset[NUM_BUFFERS];
|
||||||
|
unsigned char currentPage;
|
||||||
|
unsigned char nextBuffer;
|
||||||
|
unsigned char firstBuffer;
|
||||||
} TiledScreen_t;
|
} TiledScreen_t;
|
||||||
|
|
||||||
TiledScreen_t screen = { 0, 0, 0, 0, { 0x0400, 0x2620 }, 0, 0, NULL, NULL };
|
TiledScreen_t screen = { 0, 0, 0, 0, { 0x0400, 0x2620 }, 0, 0, NULL, NULL,
|
||||||
|
0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
void loadTiles(unsigned int tilesOffset, unsigned int *memTiles) {
|
void loadTiles(unsigned int tilesOffset, unsigned int *memTiles) {
|
||||||
screen.tilesOffset = tilesOffset;
|
screen.tilesOffset = tilesOffset;
|
||||||
|
@ -481,11 +502,85 @@ void loadMap(unsigned char *map, unsigned int w, unsigned int h) {
|
||||||
screen.h = h;
|
screen.h = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int prepareBuffer(int pageX, int pageY) {
|
||||||
|
unsigned char *dirty = &screen.dirty[screen.currentPage][pageX + (pageY * PAGE_TILES_W)];
|
||||||
|
if (!isBufIndex(*dirty)) {
|
||||||
|
unsigned int startX = screen.scrollX >> 4;
|
||||||
|
unsigned int startY = screen.scrollY >> 4;
|
||||||
|
unsigned char tile = screen.map[startX + pageX + ((startY + pageY) * screen.w)];
|
||||||
|
unsigned char ibuffer = screen.nextBuffer;
|
||||||
|
screen.nextBuffer = nextBufferIndex(screen.nextBuffer);
|
||||||
|
*dirty = ibuffer;
|
||||||
|
memcpy(screen.buffer[ibuffer], &screen.memTiles[tile * BUF_WSIZE], BUF_WSIZE);
|
||||||
|
screen.bufferOffset[ibuffer] = screen.pageOffset[screen.currentPage]
|
||||||
|
+ (pageX << 1) + (pageY * PAGE_STRIDE);
|
||||||
|
}
|
||||||
|
return *dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawSpriteToBuf(unsigned int *sprite, int pageX, int pageY, int shift, int yStart) {
|
||||||
|
unsigned int *buf, *mask;
|
||||||
|
int y, h, plane;
|
||||||
|
if (pageX < 0 || pageY < 0 ||
|
||||||
|
pageX >= PAGE_TILES_W || pageY >= PAGE_TILES_H ||
|
||||||
|
shift >= 16 || shift <= -16 ||
|
||||||
|
yStart <= -16 || yStart >= 16) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = screen.buffer[prepareBuffer(pageX, pageY)];
|
||||||
|
/* if (yStart < 0) {
|
||||||
|
sprite = &sprite[-yStart];
|
||||||
|
h = yStart + 16;
|
||||||
|
} else {
|
||||||
|
buf = &buf[yStart];
|
||||||
|
h = 16 - yStart;
|
||||||
|
}
|
||||||
|
mask = &sprite[16 * 4];
|
||||||
|
if (shift < 0) {
|
||||||
|
shift = -shift;
|
||||||
|
for (plane = 0; plane < 4; plane ++) {
|
||||||
|
for (y = 0; y < h; y ++) {
|
||||||
|
buf[y] = (buf[y] & ~(mask[y] << shift)) | (sprite[y] << shift);
|
||||||
|
}
|
||||||
|
sprite += BUF_WSTRIDE;
|
||||||
|
buf += BUF_WSTRIDE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (plane = 0; plane < 4; plane ++) {
|
||||||
|
for (y = 0; y < h; y ++) {
|
||||||
|
buf[y] = (buf[y] & ~(mask[y] >> shift)) | (sprite[y] >> shift);
|
||||||
|
}
|
||||||
|
sprite += BUF_WSTRIDE;
|
||||||
|
buf += BUF_WSTRIDE;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawSprite(unsigned int *sprite, int x, int y) {
|
||||||
|
unsigned int startX = screen.scrollX >> 4;
|
||||||
|
unsigned int startY = screen.scrollY >> 4;
|
||||||
|
int pageX = (x - startX) >> 4;
|
||||||
|
int pageY = (y - startY) >> 4;
|
||||||
|
int pageOffsetX = x - (pageX << 4);
|
||||||
|
int pageOffsetY = y - (pageY << 4);
|
||||||
|
|
||||||
|
drawSpriteToBuf(sprite, pageX, pageY, pageOffsetX, pageOffsetY);
|
||||||
|
drawSpriteToBuf(sprite, pageX + 1, pageY, pageOffsetX - 16, pageOffsetY);
|
||||||
|
drawSpriteToBuf(sprite, pageX, pageY + 1, pageOffsetX, pageOffsetY - 16);
|
||||||
|
drawSpriteToBuf(sprite, pageX + 1, pageY + 1, pageOffsetX - 16, pageOffsetY - 16);
|
||||||
|
}
|
||||||
|
|
||||||
void scroll(int x, int y) {
|
void scroll(int x, int y) {
|
||||||
|
unsigned int startX = screen.scrollX >> 4;
|
||||||
|
unsigned int startY = screen.scrollY >> 4;
|
||||||
x = min(max(x, 0), (screen.w << 4) - 320);
|
x = min(max(x, 0), (screen.w << 4) - 320);
|
||||||
y = min(max(y, 0), (screen.h << 4) - 176);
|
y = min(max(y, 0), (screen.h << 4) - 176);
|
||||||
screen.scrollX = x;
|
screen.scrollX = x;
|
||||||
screen.scrollY = y;
|
screen.scrollY = y;
|
||||||
|
if (startX != (x >> 4) || startY != (y >> 4)) {
|
||||||
|
memset(screen.dirty, D_BGTILE, 2 * PAGE_TILES_COUNT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawScreen() {
|
void drawScreen() {
|
||||||
|
@ -495,27 +590,51 @@ void drawScreen() {
|
||||||
unsigned int offsetY = screen.scrollY - (startY << 4);
|
unsigned int offsetY = screen.scrollY - (startY << 4);
|
||||||
unsigned int drawOffset = screen.pageOffset[screen.currentPage];
|
unsigned int drawOffset = screen.pageOffset[screen.currentPage];
|
||||||
unsigned int scrollOffset = drawOffset + (offsetX >> 3) + (offsetY * PAGE_STRIDE);
|
unsigned int scrollOffset = drawOffset + (offsetX >> 3) + (offsetY * PAGE_STRIDE);
|
||||||
unsigned int x, y;
|
unsigned char *dirty = screen.dirty[screen.currentPage];
|
||||||
|
unsigned int x, y, di, plane;
|
||||||
|
|
||||||
prepareEgaMemCopy();
|
setAllPlanes();
|
||||||
|
setWriteMode(1);
|
||||||
|
|
||||||
for (y = startY; y < startY + 13; y ++) {
|
di = 0;
|
||||||
for (x = startX; x < startX + 21; x ++) {
|
for (y = startY; y < startY + PAGE_TILES_H; y ++) {
|
||||||
blitTile(screen.tilesOffset + screen.map[x + (y * screen.w)], drawOffset);
|
for (x = startX; x < startX + PAGE_TILES_W; x ++) {
|
||||||
|
if (dirty[di++] == D_BGTILE) {
|
||||||
|
blitTile(screen.tilesOffset + screen.map[x + (y * screen.w)], drawOffset);
|
||||||
|
}
|
||||||
drawOffset += 2;
|
drawOffset += 2;
|
||||||
}
|
}
|
||||||
drawOffset += PAGE_STRIDE * 15;
|
drawOffset += PAGE_STRIDE * 15;
|
||||||
}
|
}
|
||||||
|
setWriteMode(0);
|
||||||
|
for(plane = 0; plane < 4; plane ++) {
|
||||||
|
setPlane(plane);
|
||||||
|
for (di = screen.firstBuffer; di != screen.nextBuffer; di = nextBufferIndex(di)) {
|
||||||
|
drawOffset = screen.bufferOffset[di] >> 1;
|
||||||
|
for (y = 0; y < 16; y ++) {
|
||||||
|
WVID[drawOffset] = screen.buffer[di][y + (BUF_WSTRIDE * plane)];
|
||||||
|
drawOffset += PAGE_STRIDE >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setAllPlanes();
|
||||||
setDisplayOffset(scrollOffset);
|
setDisplayOffset(scrollOffset);
|
||||||
screen.currentPage ^= 1;
|
screen.currentPage ^= 1;
|
||||||
|
screen.firstBuffer = screen.nextBuffer;
|
||||||
|
for (di = 0; di < PAGE_TILES_COUNT; di ++) {
|
||||||
|
dirty[di] = isBufIndex(dirty[di]) ? D_BGTILE : D_NOTHING;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** S C R A T C H ***/
|
/*** S C R A T C H ***/
|
||||||
|
#define NUM_TILES 128
|
||||||
unsigned int tiles[2*16 * 128];
|
#define NUM_SPRITES 64
|
||||||
#define OFF_TILES 0x4840
|
#define OFF_TILES 0x4840
|
||||||
|
|
||||||
|
unsigned int tiles[NUM_TILES][4*16];
|
||||||
|
unsigned int sprites[NUM_SPRITES][5*16];
|
||||||
|
|
||||||
|
|
||||||
unsigned char map[10000];
|
unsigned char map[10000];
|
||||||
|
|
||||||
void fillMap() {
|
void fillMap() {
|
||||||
|
@ -546,8 +665,13 @@ void game_init() {
|
||||||
|
|
||||||
f = fopen("TILES.TIF", "rb");
|
f = fopen("TILES.TIF", "rb");
|
||||||
meta = tifLoadMeta(f);
|
meta = tifLoadMeta(f);
|
||||||
tifLoadEGA(f, meta, OFF_TILES, 256, 16);
|
tifLoadEGA(f, meta, OFF_TILES, NUM_TILES * 16, 16);
|
||||||
tifLoad(f, meta, tiles, 128 * 16, 16);
|
tifLoad(f, meta, tiles, NUM_TILES * 16, 16, 4);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
f = fopen("SPRITE.TIF", "rb");
|
||||||
|
meta = tifLoadMeta(f);
|
||||||
|
tifLoad(f, meta, sprites, NUM_SPRITES * 16, 16, 5);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
setSplitScreen(351);
|
setSplitScreen(351);
|
||||||
|
@ -558,8 +682,8 @@ void game_init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int x;
|
int x = 100;
|
||||||
int y;
|
int y = 100;
|
||||||
int z = 0;
|
int z = 0;
|
||||||
|
|
||||||
game_init();
|
game_init();
|
||||||
|
@ -567,13 +691,13 @@ int main() {
|
||||||
|
|
||||||
while (!keyPressed(K_ESC)) {
|
while (!keyPressed(K_ESC)) {
|
||||||
|
|
||||||
x = screen.scrollX;
|
if (keyPressed(K_LEFT)) x -= 1;
|
||||||
y = screen.scrollY;
|
if (keyPressed(K_RIGHT)) x += 1;
|
||||||
if (keyPressed(K_LEFT)) x -= 8;
|
if (keyPressed(K_UP)) y -= 1;
|
||||||
if (keyPressed(K_RIGHT)) x += 8;
|
if (keyPressed(K_DOWN)) y += 1;
|
||||||
if (keyPressed(K_UP)) y -= 8;
|
scroll(x + 152, y + 90);
|
||||||
if (keyPressed(K_DOWN)) y += 8;
|
drawSprite(sprites[0], 50, 50);
|
||||||
scroll(x, y);
|
drawSprite(sprites[1], x, y);
|
||||||
drawScreen();
|
drawScreen();
|
||||||
|
|
||||||
z++;
|
z++;
|
||||||
|
|
BIN
testbed.exe
BIN
testbed.exe
Binary file not shown.
Loading…
Reference in a new issue