diff --git a/.gitignore b/.gitignore index cb6c1ea..75783d7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ *.EXE .ccls-cache/ *.LNK +*.o +*.exe diff --git a/bmpload.h b/bmpload.h index 123fb1b..8030a77 100644 --- a/bmpload.h +++ b/bmpload.h @@ -25,5 +25,6 @@ struct BMPImage { int readBMPIntoMemory(FILE *, struct BMPImage *); int readBMPIntoNewMemory(FILE *, struct BMPImage *); void bmp256ColorPaletteToVGAColorPalette(struct BMPImage*, struct VGAColor[]); +void freeBMP(struct BMPImage *); #endif diff --git a/game.c b/game.c index 65dad36..98f61dc 100644 --- a/game.c +++ b/game.c @@ -10,6 +10,171 @@ struct BMPImage spritesheetImage; struct VGAColor vgaColors[256]; struct SpriteRender arenaWallTop, arenaWallSide, arenaFloor; +struct SpriteRender rabbit; + +void setupWallSprites() { + buildSpriteFromSpritesheet( + &spritesheetImage, + &arenaWallTop, + 0, 0, 20, 20 + ); + + buildSpriteFromSpritesheet( + &spritesheetImage, + &arenaWallSide, + 20, 0, 20, 20 + ); + + buildSpriteFromSpritesheet( + &spritesheetImage, + &arenaFloor, + 40, 0, 20, 20 + ); +} + +void setupRabbitSprites() { + buildSpriteFromSpritesheet( + &spritesheetImage, + &rabbit, + 0, 20, 16, 16 + ); +} + +char arenaLayout[10][10] = { + { 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 }, + { 1, 2, 2, 2, 0, 0, 2, 2, 2, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 2, 0, 0, 0, 0, 0, 0, 0, 0, 2 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 } +}; + +void renderArenaTile(int x, int y) { + char tile; + struct SpriteRender *target; + + tile = arenaLayout[y][x]; + + switch (tile) { + case 0: + target = &arenaFloor; + break; + case 1: + target = &arenaWallTop; + break; + case 2: + target = &arenaWallSide; + break; + } + + target->x = x * 20; + target->y = y * 20; + + drawSprite(target); +} + +void buildArena() { + int x, y; + + for (y = 0; y < 10; ++y) { + for (x = 0; x < 10; ++x) { + renderArenaTile(x, y); + } + } +} + +int rabbitPosition[2] = { 60, 60 }; +int rabbitLimits[2][2] = { + { 20, 20 }, + { 180, 180 } +}; + +#define RABBIT_MOTION_DRAG (2) +#define RABBIT_MOTION_ACCELERATION (5) +#define RABBIT_MOTION_MAX_SPEED (12) + +signed char rabbitVelocity[2] = { 0, 0 }; + +void renderRabbit() { + rabbit.x = rabbitPosition[0]; + rabbit.y = rabbitPosition[1]; + + drawSprite(&rabbit); +} + +void handleRabbitMovement() { + int i; + + if (keyboardKeydownState.KEY_W) { + rabbitVelocity[1] -= RABBIT_MOTION_ACCELERATION; + if (rabbitVelocity[1] < -RABBIT_MOTION_MAX_SPEED) { + rabbitVelocity[1] = -RABBIT_MOTION_MAX_SPEED; + } + } + if (keyboardKeydownState.KEY_S) { + rabbitVelocity[1] += RABBIT_MOTION_ACCELERATION; + if (rabbitVelocity[1] > RABBIT_MOTION_MAX_SPEED) { + rabbitVelocity[1] = RABBIT_MOTION_MAX_SPEED; + } + } + if (keyboardKeydownState.KEY_A) { + rabbitVelocity[0] -= RABBIT_MOTION_ACCELERATION; + if (rabbitVelocity[0] < -RABBIT_MOTION_MAX_SPEED) { + rabbitVelocity[0] = -RABBIT_MOTION_MAX_SPEED; + } + } + if (keyboardKeydownState.KEY_D) { + rabbitVelocity[0] += RABBIT_MOTION_ACCELERATION; + if (rabbitVelocity[0] > RABBIT_MOTION_MAX_SPEED) { + rabbitVelocity[0] = RABBIT_MOTION_MAX_SPEED; + } + } + + for (i = 0; i < 2; ++i) { + rabbitPosition[i] += (rabbitVelocity[i] / 5); + + if (rabbitPosition[i] < rabbitLimits[0][i]) { + rabbitPosition[i] = rabbitLimits[0][i]; + } + if (rabbitPosition[i] >= rabbitLimits[1][i]) { + rabbitPosition[i] = rabbitLimits[1][i]; + } + + if (rabbitVelocity[i] < 0) { + rabbitVelocity[i] += RABBIT_MOTION_DRAG; + if (rabbitVelocity[i] > 0) rabbitVelocity[i] = 0; + } + if (rabbitVelocity[i] > 0) { + rabbitVelocity[i] -= RABBIT_MOTION_DRAG; + if (rabbitVelocity[i] < 0) rabbitVelocity[i] = 0; + } + } +} + +void drawOnlyRabbitArena() { + int rabbitLeftTileX, rabbitRightTileX, + rabbitTopTileY, rabbitBottomTileY; + + rabbitLeftTileX = rabbitPosition[0] / 20; + rabbitRightTileX = (rabbitPosition[0] + 16) / 20; + rabbitTopTileY = rabbitPosition[1] / 20; + rabbitBottomTileY = (rabbitPosition[1] + 16) / 20; + + renderArenaTile(rabbitLeftTileX, rabbitTopTileY); + if (rabbitLeftTileX != rabbitRightTileX) { + renderArenaTile(rabbitRightTileX, rabbitTopTileY); + if (rabbitTopTileY != rabbitBottomTileY) { + renderArenaTile(rabbitRightTileX, rabbitBottomTileY); + } + } + if (rabbitTopTileY != rabbitBottomTileY) { + renderArenaTile(rabbitLeftTileX, rabbitBottomTileY); + } +} int main(void) { FILE *fh; @@ -24,32 +189,33 @@ int main(void) { if (readBMPIntoNewMemory(fh, &spritesheetImage)) return 1; fclose(fh); - return 0; - spritesheetImage.transparentColor = 0; - buildSpriteFromSpritesheet( - &spritesheetImage, - &arenaWallTop, - 0, 0, 20, 20 - ); + setupWallSprites(); + setupRabbitSprites(); setVideoMode(VIDEO_MODE_VGA_256); bmp256ColorPaletteToVGAColorPalette(&spritesheetImage, vgaColors); setVGAColors(vgaColors, 256); - while (keepRunning) { - arenaWallTop.x = 0; - arenaWallTop.y = 0; + buildArena(); - drawSprite(&arenaWallTop); + while (keepRunning) { + readMouse(&mouseStatus); + populateKeyboardKeydownState(); + handleRabbitMovement(); waitStartVbl(); + drawOnlyRabbitArena(); + renderRabbit(); copyDrawBufferToDisplay(); waitEndVbl(); + + if (mouseStatus.leftButtonDown) { keepRunning = 0; } } + // states: // * main menu // * play @@ -70,6 +236,13 @@ int main(void) { // * check for bullets hitting the edges of the screen and remove // * // + + freeBMP(&spritesheetImage); + + setVideoMode(VIDEO_MODE_80x25_TEXT); + uninstallKeyboardHandler(); + + fprintf(stderr, "meow\n"); return 0; } diff --git a/game.lnk b/game.lnk new file mode 100644 index 0000000..02a2c7e --- /dev/null +++ b/game.lnk @@ -0,0 +1,2 @@ +NAME game.exe +FILE game.o diff --git a/makefile b/makefile index a32a827..4531711 100644 --- a/makefile +++ b/makefile @@ -1,13 +1,7 @@ -.c.obj - wcc386 -q $< +obj = game.o bmpload.o mouse_io.o pc_stuff.o vga.o keyboard.o -game.exe: bmpload.obj mouse_io.obj pc_stuff.obj vga.obj keyboard.obj game.obj - %write game.lnk NAME $@ - %write game.lnk SYSTEM DOS4G - %write game.lnk FILE bmpload.obj - %write game.lnk FILE mouse_io.obj - %write game.lnk FILE pc_stuff.obj - %write game.lnk FILE vga.obj - %write game.lnk FILE keyboard.obj - %write game.lnk FILE game.obj - wlink @game.lnk +.c.o: + wcc386 -q -bt=dos -q $< + +game.exe: $(obj) + wcl386 -q -bt=dos -l=dos4g $(obj) diff --git a/mouse_io.c b/mouse_io.c index 8bf4eb3..3114e66 100644 --- a/mouse_io.c +++ b/mouse_io.c @@ -1,8 +1,11 @@ #include #include +#include #include "mouse_io.h" +struct MouseStatus *_status; + int activateMouse(struct MouseStatus *status) { union REGS regs; int mouseActivated; @@ -28,10 +31,12 @@ int activateMouse(struct MouseStatus *status) { int386(MOUSE_DRIVER_INTERRUPT, ®s, ®s); } + _status = status; + return mouseActivated; } -void readMouse(struct MouseStatus *status) { +void readMouse() { union REGS regs; int buttonStatus; @@ -39,10 +44,10 @@ void readMouse(struct MouseStatus *status) { int386(MOUSE_DRIVER_INTERRUPT, ®s, ®s); buttonStatus = regs.w.bx; - status->xPosition = regs.w.cx; - status->yPosition = regs.w.dx; + _status->xPosition = regs.w.cx; + _status->yPosition = regs.w.dx; - status->leftButtonDown = buttonStatus & 1; - status->rightButtonDown = (buttonStatus >> 1) & 1; + _status->leftButtonDown = buttonStatus & 1; + _status->rightButtonDown = (buttonStatus >> 1) & 1; } diff --git a/setup.sh b/setup.sh new file mode 100644 index 0000000..60c78ad --- /dev/null +++ b/setup.sh @@ -0,0 +1,3 @@ +export WATCOM=~/Applications/open-watcom-v2/rel +export INCLUDE=$WATCOM/h +export PATH=$WATCOM/binl64:$WATCOM/binl:$PATH diff --git a/spritesheet.xcf b/spritesheet.xcf index 6618ef8..b1eb2d5 100644 Binary files a/spritesheet.xcf and b/spritesheet.xcf differ diff --git a/sprtsht.bmp b/sprtsht.bmp index eec24cd..064e850 100644 Binary files a/sprtsht.bmp and b/sprtsht.bmp differ