Implement map scrolling
This commit is contained in:
parent
7abb774dfb
commit
4688bdccb0
171
testbed.c
171
testbed.c
|
@ -26,42 +26,37 @@ void vid_cleanup() {
|
||||||
setTextMode();
|
setTextMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned int b[16];
|
|
||||||
unsigned int g[16];
|
|
||||||
unsigned int r[16];
|
|
||||||
unsigned int i[16];
|
|
||||||
} Tile_t;
|
|
||||||
|
|
||||||
unsigned int PAGE[] = { 0x04, 0x24 };
|
|
||||||
|
|
||||||
#define setWriteMode(m) outport(REG_GDC, 0x05 | m << 8)
|
#define setWriteMode(m) outport(REG_GDC, 0x05 | m << 8)
|
||||||
void setSplitScreen(unsigned int y) {
|
void setSplitScreen(unsigned int y) {
|
||||||
// TODO: VGA registers??
|
int val;
|
||||||
outport(REG_CRTC, 0x1018);// | y << 8);
|
outport(REG_CRTC, 0x18 | (y << 8));
|
||||||
outport(REG_CRTC, 0x0107);
|
outp(REG_CRTC, 7);
|
||||||
|
val = inp(REG_CRTC + 1);
|
||||||
|
val &= ~0x10;
|
||||||
|
val |= (y & 0x100) >> 4;
|
||||||
|
outp(REG_CRTC + 1, val);
|
||||||
|
outp(REG_CRTC, 9);
|
||||||
|
val = inp(REG_CRTC + 1);
|
||||||
|
val &= ~0x40;
|
||||||
|
outp(REG_CRTC + 1, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsetSplitScreen() {
|
void unsetSplitScreen() {
|
||||||
outport(REG_CRTC, 0xff18);
|
outport(REG_CRTC, 0xff18);
|
||||||
outport(REG_CRTC, 0x1107);
|
outport(REG_CRTC, 0x1107);
|
||||||
|
outport(REG_CRTC, 0x0f09);
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareEgaMemCopy() {
|
|
||||||
setAllPlanes();
|
|
||||||
setWriteMode(1);
|
|
||||||
}
|
|
||||||
#define PAGE_STRIDE 40
|
|
||||||
void blitTile(unsigned int offsetFrom, unsigned int offsetTo) {
|
|
||||||
int y;
|
|
||||||
for (y = 0; y < 16; y ++) {
|
|
||||||
VID[offsetTo] = VID[offsetFrom ++];
|
|
||||||
VID[offsetTo + 1] = VID[offsetFrom ++];
|
|
||||||
offsetTo += PAGE_STRIDE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define flipPage(p) outport(REG_CRTC, 0x0c | (p << 8))
|
#define flipPage(p) outport(REG_CRTC, 0x0c | (p << 8))
|
||||||
|
|
||||||
|
void setDisplayOffset(unsigned int offset) {
|
||||||
|
outport(REG_CRTC, 0x0c | (offset & 0xff00));
|
||||||
|
outport(REG_CRTC, 0x0d | (offset << 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define setLogicalWidth(w) outport(REG_CRTC, 0x13 | (w << 8))
|
||||||
|
|
||||||
/*** K E Y B O A R D ***/
|
/*** K E Y B O A R D ***/
|
||||||
#define KBD_INT 0x09
|
#define KBD_INT 0x09
|
||||||
void interrupt (*oldKbdISR)() = NULL;
|
void interrupt (*oldKbdISR)() = NULL;
|
||||||
|
@ -325,7 +320,7 @@ fail:
|
||||||
|
|
||||||
#define MAX_WIDTH 320
|
#define MAX_WIDTH 320
|
||||||
|
|
||||||
int tifLoadEGA(FILE *f, TifImageMeta_t meta, unsigned int vidOffset, int maxY) {
|
int tifLoadEGA(FILE *f, TifImageMeta_t meta, unsigned int vidOffset, int maxY, unsigned int w) {
|
||||||
int istrip;
|
int istrip;
|
||||||
int irow;
|
int irow;
|
||||||
int ipixelpair;
|
int ipixelpair;
|
||||||
|
@ -376,6 +371,7 @@ int tifLoadEGA(FILE *f, TifImageMeta_t meta, unsigned int vidOffset, int maxY) {
|
||||||
if (y == maxY) {
|
if (y == maxY) {
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
out += (w - meta.width) >> 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return y;
|
return y;
|
||||||
|
@ -439,30 +435,87 @@ int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** S C R A T C H ***/
|
/*** T I L E S ***/
|
||||||
void paintPattern(int r, int g, int b, int t) {
|
void prepareEgaMemCopy() {
|
||||||
int i;
|
setAllPlanes();
|
||||||
|
setWriteMode(1);
|
||||||
|
}
|
||||||
|
|
||||||
setPlane(PLANE_R);
|
#define PAGE_STRIDE 42
|
||||||
for (i = 0; i < 8000; i ++) {
|
|
||||||
VID[i] = r;
|
void tile_init() {
|
||||||
|
setLogicalWidth(PAGE_STRIDE >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void blitTile(unsigned int offsetFrom, unsigned int offsetTo) {
|
||||||
|
int y;
|
||||||
|
for (y = 0; y < 16; y ++) {
|
||||||
|
VID[offsetTo] = VID[offsetFrom ++];
|
||||||
|
VID[offsetTo + 1] = VID[offsetFrom ++];
|
||||||
|
offsetTo += PAGE_STRIDE;
|
||||||
}
|
}
|
||||||
setPlane(PLANE_G);
|
}
|
||||||
for (i = 0; i < 8000; i ++) {
|
|
||||||
VID[i] = g;
|
typedef struct {
|
||||||
|
unsigned int w;
|
||||||
|
unsigned int h;
|
||||||
|
int scrollX;
|
||||||
|
int scrollY;
|
||||||
|
unsigned int pageOffset;
|
||||||
|
unsigned char *tiles;
|
||||||
|
} TilePage_t;
|
||||||
|
|
||||||
|
#define OFF_TILES 0x4840
|
||||||
|
|
||||||
|
void scrollPage(TilePage_t *page, int x, int y) {
|
||||||
|
x = min(max(x, 0), (page->w << 4) - 320);
|
||||||
|
y = min(max(y, 0), (page->h << 4) - 176);
|
||||||
|
page->scrollX = x;
|
||||||
|
page->scrollY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawPage(TilePage_t *page) {
|
||||||
|
unsigned int startX = page->scrollX >> 4;
|
||||||
|
unsigned int startY = page->scrollY >> 4;
|
||||||
|
unsigned int offsetX = page->scrollX - (startX << 4);
|
||||||
|
unsigned int offsetY = page->scrollY - (startY << 4);
|
||||||
|
unsigned int drawOffset = page->pageOffset;
|
||||||
|
unsigned int scrollOffset = drawOffset + (offsetX >> 3) + (offsetY * PAGE_STRIDE);
|
||||||
|
unsigned int x, y;
|
||||||
|
|
||||||
|
prepareEgaMemCopy();
|
||||||
|
|
||||||
|
for (y = startY; y < startY + 13; y ++) {
|
||||||
|
for (x = startX; x < startX + 21; x ++) {
|
||||||
|
blitTile(OFF_TILES + page->tiles[x + (y * page->w)], drawOffset);
|
||||||
|
drawOffset += 2;
|
||||||
}
|
}
|
||||||
setPlane(PLANE_B);
|
drawOffset += PAGE_STRIDE * 15;
|
||||||
for (i = 0; i < 8000; i ++) {
|
}
|
||||||
VID[i] = b;
|
|
||||||
|
setDisplayOffset(scrollOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** S C R A T C H ***/
|
||||||
|
|
||||||
|
unsigned char tiles[10000];
|
||||||
|
TilePage_t pages[2] = {
|
||||||
|
{ 100, 100, 0, 0, 0x0400, tiles },
|
||||||
|
{ 100, 100, 0, 0, 0x2620, tiles }
|
||||||
|
};
|
||||||
|
|
||||||
|
void fillTiles() {
|
||||||
|
unsigned int x, y, z;
|
||||||
|
z = 0;
|
||||||
|
|
||||||
|
for (y = 0; y < 100; y ++) {
|
||||||
|
for (x = 0; x < 100; x ++) {
|
||||||
|
tiles[x + (y * 100)] = (((x + y + z) >> 2) % 3) << 5;
|
||||||
}
|
}
|
||||||
setPlane(PLANE_I);
|
|
||||||
for (i = 0; i < 8000; i ++) {
|
|
||||||
VID[i] = t;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Tile_t tiles[16];
|
|
||||||
FILE *f;
|
FILE *f;
|
||||||
TifImageMeta_t meta;
|
TifImageMeta_t meta;
|
||||||
int plane;
|
int plane;
|
||||||
|
@ -472,41 +525,39 @@ int main() {
|
||||||
unsigned int drawOffset;
|
unsigned int drawOffset;
|
||||||
unsigned int page = 0;
|
unsigned int page = 0;
|
||||||
|
|
||||||
#define OFF_TILES 0x4200
|
|
||||||
|
|
||||||
setEGAMode();
|
setEGAMode();
|
||||||
atexit(vid_cleanup);
|
atexit(vid_cleanup);
|
||||||
|
|
||||||
f = fopen("FOOTER.TIF", "rb");
|
f = fopen("FOOTER.TIF", "rb");
|
||||||
meta = tifLoadMeta(f);
|
meta = tifLoadMeta(f);
|
||||||
tifLoadEGA(f, meta, 0, 24);
|
tifLoadEGA(f, meta, 0, 24, 336);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
f = fopen("TILES.TIF", "rb");
|
f = fopen("TILES.TIF", "rb");
|
||||||
meta = tifLoadMeta(f);
|
meta = tifLoadMeta(f);
|
||||||
tifLoadEGA(f, meta, OFF_TILES, 256);
|
tifLoadEGA(f, meta, OFF_TILES, 256, 16);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
mouse_init();
|
|
||||||
kbd_init();
|
kbd_init();
|
||||||
|
tile_init();
|
||||||
|
setSplitScreen(351);
|
||||||
|
|
||||||
|
fillTiles();
|
||||||
|
|
||||||
while (!keyPressed(K_ESC)) {
|
while (!keyPressed(K_ESC)) {
|
||||||
page ^= 1;
|
page ^= 1;
|
||||||
|
|
||||||
prepareEgaMemCopy();
|
x = pages[page].scrollX;
|
||||||
drawOffset = PAGE[page] << 8;
|
y = pages[page].scrollY;
|
||||||
for (y = 0; y < 11; y ++) {
|
if (keyPressed(K_LEFT)) x -= 4;
|
||||||
for (x = 0; x < 20; x ++) {
|
if (keyPressed(K_RIGHT)) x += 4;
|
||||||
blitTile(OFF_TILES + ((((x + y + z) >> 2) % 3) << 5), drawOffset);
|
if (keyPressed(K_UP)) y -= 4;
|
||||||
drawOffset += 2;
|
if (keyPressed(K_DOWN)) y += 4;
|
||||||
}
|
scrollPage(&pages[0], x, y);
|
||||||
drawOffset += 600; // 40 bytes per line * 15 more lines
|
scrollPage(&pages[1], x, y);
|
||||||
}
|
drawPage(&pages[page]);
|
||||||
|
|
||||||
flipPage(PAGE[page]);
|
// kbd_wait();
|
||||||
setSplitScreen(16);
|
|
||||||
|
|
||||||
kbd_wait();
|
|
||||||
z++;
|
z++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
BIN
testbed.exe
BIN
testbed.exe
Binary file not shown.
Loading…
Reference in a new issue