From b1366fe3b2feac47efe541ae1bd9d4d3912332b1 Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Sat, 19 Jan 2019 16:29:32 -0500 Subject: [PATCH] smooth horizontal scrolling --- testbed.c | 36 +++++++++++++++++++++--------------- testbed.exe | Bin 65012 -> 65109 bytes 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/testbed.c b/testbed.c index 1059b1a..2279012 100755 --- a/testbed.c +++ b/testbed.c @@ -9,6 +9,7 @@ #define setEGAMode() setMode(000Dh) #define setTextMode() setMode(0003h) +#define REG_AC 0x03c0 #define REG_TS 0x03c4 #define REG_GDC 0x03ce #define REG_CRTC 0x03d4 @@ -56,6 +57,12 @@ void setDisplayOffset(unsigned int offset) { outport(REG_CRTC, 0x0d | (offset << 8)); } +void setHorizontalPan(int offset) { + inp(0x3da); // INPUT_STATUS_1? + outp(REG_AC, 0x13 | 0x20); + outp(REG_AC, offset); +} + #define setLogicalWidth(w) outport(REG_CRTC, 0x13 | (w << 8)) /*** K E Y B O A R D ***/ @@ -462,7 +469,7 @@ int tifLoad(FILE *f, TifImageMeta_t meta, unsigned int *planeBuf, int maxY, int // 89ABCDEF 01234567 << 3 => BCDEFXXX 3456789A byteswap => 3456789A BCDEFXXX #define PAGE_TILES_W 21 -#define PAGE_TILES_H 13 +#define PAGE_TILES_H 12 #define PAGE_TILES_COUNT (PAGE_TILES_H * PAGE_TILES_W) #define PAGE_STRIDE (PAGE_TILES_W << 1) @@ -504,7 +511,7 @@ typedef struct { 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, 0x2400 }, 0, 0, NULL, NULL, 0, 0, 0, 0, 0 }; void loadTiles(unsigned int tilesOffset, unsigned int *memTiles) { @@ -578,8 +585,8 @@ void drawSpriteToBuf(unsigned int *sprite, int pageX, int pageY, int shift, int } void drawSprite(unsigned int *sprite, int x, int y) { - int pageX = (x - (screen.scrollX & 0xfff0)) >> 4; - int pageY = (y - (screen.scrollY & 0xfff0)) >> 4; + int pageX = (int)(x - (screen.scrollX & 0xfff0)) >> 4; + int pageY = (int)(y - (screen.scrollY & 0xfff0)) >> 4; int pageOffsetX = x & 0x0f; int pageOffsetY = y & 0x0f; @@ -656,6 +663,8 @@ void drawScreen() { } setAllPlanes(); setDisplayOffset(scrollOffset); + setHorizontalPan(screen.scrollX & 0x07); + screen.currentPage ^= 1; screen.firstBuffer = screen.nextBuffer; for (di = 0; di < PAGE_TILES_COUNT; di ++) { @@ -720,25 +729,22 @@ void game_init() { } int main() { - int x = 100; - int y = 100; - int z = 0; + int x = -1; + int y = -1; + int dir = 0; game_init(); kbd_init(); while (!keyPressed(K_ESC)) { - if (keyPressed(K_LEFT)) x -= 3; - if (keyPressed(K_RIGHT)) x += 3; - if (keyPressed(K_UP)) y -= 3; - if (keyPressed(K_DOWN)) y += 3; + if (keyPressed(K_LEFT)) { x -= 3; dir = 2; } + if (keyPressed(K_RIGHT)) { x += 3; dir = 0; } + if (keyPressed(K_UP)) { y -= 3; dir = 1; } + if (keyPressed(K_DOWN)) { y += 3; dir = 3; } scroll(x - 152, y - 90); - drawSprite(&sprites[0 * SPRITE_STRIDE], 50, 50); - drawSprite(&sprites[1 * SPRITE_STRIDE], x, y); + drawSprite(&sprites[dir * SPRITE_STRIDE], x, y); drawScreen(); - - z++; } return 0; diff --git a/testbed.exe b/testbed.exe index 78bdec18acd310fb44215ef6d939dc1c693745d8..c3131ce54e6f18a42ce222a3d2fba8ac204334d5 100755 GIT binary patch delta 8678 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 YgO4~KoLzn6GE)oFX3nj?apOAsH=fYPU;qFB delta 8596 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