implementing sprites drawn overtop of tilemap
This commit is contained in:
parent
28f98c20b2
commit
aeb1f47f51
186
testbed.c
186
testbed.c
|
@ -21,6 +21,7 @@
|
|||
#define setAllPlanes() outport(REG_TS, 0x0f02)
|
||||
|
||||
#define VID ((volatile char far *)MK_FP(0xa000, 0))
|
||||
#define WVID ((volatile int far *)MK_FP(0xa000, 0))
|
||||
|
||||
void vid_cleanup() {
|
||||
setTextMode();
|
||||
|
@ -377,7 +378,7 @@ int tifLoadEGA(FILE *f, TifImageMeta_t meta, unsigned int vidOffset, int maxY, u
|
|||
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 irow;
|
||||
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 *r = g + 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;
|
||||
}
|
||||
|
||||
|
@ -413,11 +415,17 @@ int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int
|
|||
*++g = gpair;
|
||||
*++r = rpair;
|
||||
*++i = ipair;
|
||||
if (planes == 5) {
|
||||
*++m = bpair & gpair & rpair & ipair;
|
||||
}
|
||||
} else {
|
||||
*b |= bpair << shift;
|
||||
*g |= gpair << shift;
|
||||
*r |= rpair << shift;
|
||||
*i |= ipair << shift;
|
||||
if (planes == 5) {
|
||||
*m |= (bpair & gpair & rpair & ipair) << shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
y++;
|
||||
|
@ -425,10 +433,10 @@ int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int
|
|||
return y;
|
||||
}
|
||||
if (y % yRepeat == 0) {
|
||||
b += planeStride * 3;
|
||||
g += planeStride * 3;
|
||||
r += planeStride * 3;
|
||||
i += planeStride * 3;
|
||||
b += planeStride * (planes - 1);
|
||||
g += planeStride * (planes - 1);
|
||||
r += planeStride * (planes - 1);
|
||||
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 ***/
|
||||
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() {
|
||||
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 {
|
||||
unsigned int w;
|
||||
unsigned int h;
|
||||
int scrollX;
|
||||
int scrollY;
|
||||
unsigned int pageOffset[2];
|
||||
unsigned char currentPage;
|
||||
unsigned char dirty[2][PAGE_TILES_COUNT];
|
||||
unsigned int tilesOffset;
|
||||
unsigned int *memTiles;
|
||||
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 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) {
|
||||
screen.tilesOffset = tilesOffset;
|
||||
|
@ -481,11 +502,85 @@ void loadMap(unsigned char *map, unsigned int w, unsigned int 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) {
|
||||
unsigned int startX = screen.scrollX >> 4;
|
||||
unsigned int startY = screen.scrollY >> 4;
|
||||
x = min(max(x, 0), (screen.w << 4) - 320);
|
||||
y = min(max(y, 0), (screen.h << 4) - 176);
|
||||
screen.scrollX = x;
|
||||
screen.scrollY = y;
|
||||
if (startX != (x >> 4) || startY != (y >> 4)) {
|
||||
memset(screen.dirty, D_BGTILE, 2 * PAGE_TILES_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
void drawScreen() {
|
||||
|
@ -495,27 +590,51 @@ void drawScreen() {
|
|||
unsigned int offsetY = screen.scrollY - (startY << 4);
|
||||
unsigned int drawOffset = screen.pageOffset[screen.currentPage];
|
||||
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 ++) {
|
||||
for (x = startX; x < startX + 21; x ++) {
|
||||
di = 0;
|
||||
for (y = startY; y < startY + PAGE_TILES_H; y ++) {
|
||||
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 += 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);
|
||||
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 ***/
|
||||
|
||||
unsigned int tiles[2*16 * 128];
|
||||
#define NUM_TILES 128
|
||||
#define NUM_SPRITES 64
|
||||
#define OFF_TILES 0x4840
|
||||
|
||||
unsigned int tiles[NUM_TILES][4*16];
|
||||
unsigned int sprites[NUM_SPRITES][5*16];
|
||||
|
||||
|
||||
unsigned char map[10000];
|
||||
|
||||
void fillMap() {
|
||||
|
@ -546,8 +665,13 @@ void game_init() {
|
|||
|
||||
f = fopen("TILES.TIF", "rb");
|
||||
meta = tifLoadMeta(f);
|
||||
tifLoadEGA(f, meta, OFF_TILES, 256, 16);
|
||||
tifLoad(f, meta, tiles, 128 * 16, 16);
|
||||
tifLoadEGA(f, meta, OFF_TILES, NUM_TILES * 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);
|
||||
|
||||
setSplitScreen(351);
|
||||
|
@ -558,8 +682,8 @@ void game_init() {
|
|||
}
|
||||
|
||||
int main() {
|
||||
int x;
|
||||
int y;
|
||||
int x = 100;
|
||||
int y = 100;
|
||||
int z = 0;
|
||||
|
||||
game_init();
|
||||
|
@ -567,13 +691,13 @@ int main() {
|
|||
|
||||
while (!keyPressed(K_ESC)) {
|
||||
|
||||
x = screen.scrollX;
|
||||
y = screen.scrollY;
|
||||
if (keyPressed(K_LEFT)) x -= 8;
|
||||
if (keyPressed(K_RIGHT)) x += 8;
|
||||
if (keyPressed(K_UP)) y -= 8;
|
||||
if (keyPressed(K_DOWN)) y += 8;
|
||||
scroll(x, y);
|
||||
if (keyPressed(K_LEFT)) x -= 1;
|
||||
if (keyPressed(K_RIGHT)) x += 1;
|
||||
if (keyPressed(K_UP)) y -= 1;
|
||||
if (keyPressed(K_DOWN)) y += 1;
|
||||
scroll(x + 152, y + 90);
|
||||
drawSprite(sprites[0], 50, 50);
|
||||
drawSprite(sprites[1], x, y);
|
||||
drawScreen();
|
||||
|
||||
z++;
|
||||
|
|
BIN
testbed.exe
BIN
testbed.exe
Binary file not shown.
Loading…
Reference in a new issue