#include #include #include #include "system/vga.h" #include "system/keyboard.h" #include "system/mouse_io.h" #include "system/pc_stuff.h" #include "bmpload.h" struct BMPImage spritesheetImage; struct VGAColor vgaColors[256]; struct SpriteRender arenaWallTop, arenaWallSide, arenaFloor; struct SpriteRender rabbit, mouse; 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 ); rabbit.offsetX = 8; rabbit.offsetY = 15; buildSpriteFromSpritesheet( &spritesheetImage, &mouse, 16, 20, 8, 8 ); mouse.offsetX = 4; mouse.offsetY = 4; } 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); } } } #define RABBIT_MOTION_DRAG (2) #define RABBIT_MOTION_ACCELERATION (5) #define RABBIT_MOTION_MAX_SPEED (12) int rabbitPosition[2] = { 60, 60 }; int oldRabbitPosition[2] = { 60, 60 }; int rabbitLimits[2][2] = { { 20, 20 }, { 180, 180 } }; signed char rabbitVelocity[2] = { 0, 0 }; struct MouseStatus mouseStatus; char mousePosition[2] = { 0, 0 }; char oldMousePosition[2] = { 0, 0 }; char mouseDotPosition[2] = { 0, 0 }; char oldMouseDotPosition[2] = { 0, 0 }; void renderMouse() { mouse.x = mousePosition[0]; mouse.y = mousePosition[1]; drawSprite(&mouse); drawPixel(mouseDotPosition[0], mouseDotPosition[1], 2); } 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) { oldRabbitPosition[i] = rabbitPosition[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; } } } #define TILE_SIZE (20) struct SpriteBounds bounds; char tileRenderQueue[400]; void drawOnlyArena() { int leftTileX, rightTileX, topTileY, bottomTileY; leftTileX = bounds.left / TILE_SIZE; rightTileX = bounds.right / TILE_SIZE; topTileY = bounds.top / TILE_SIZE; bottomTileY = bounds.bottom / TILE_SIZE; renderArenaTile(leftTileX, topTileY); renderArenaTile(rightTileX, topTileY); renderArenaTile(rightTileX, bottomTileY); renderArenaTile(leftTileX, bottomTileY); } void drawOnlyMouseArena() { mouse.x = oldMousePosition[0]; mouse.y = oldMousePosition[1]; getSpriteBounds(&mouse, &bounds); drawOnlyArena(); bounds.top = oldMouseDotPosition[1]; bounds.bottom = oldMouseDotPosition[1]; bounds.left = oldMouseDotPosition[0]; bounds.right = oldMouseDotPosition[0]; drawOnlyArena(); } void drawOnlyRabbitArena() { rabbit.x = oldRabbitPosition[0]; rabbit.y = oldRabbitPosition[1]; getSpriteBounds(&rabbit, &bounds); drawOnlyArena(); } #define RAD2DEG (180/3.14159) #define DEG2RAD (3.14159/180) #define MOUSE_DISTANCE (32) void calculateTargetAngle() { float distanceX, distanceY; float angle; oldMouseDotPosition[0] = mouseDotPosition[0]; oldMouseDotPosition[1] = mouseDotPosition[1]; mouseDotPosition[0] = mouseStatus.xPosition; mouseDotPosition[1] = mouseStatus.yPosition; distanceX = mouseStatus.xPosition - rabbitPosition[0]; distanceY = mouseStatus.yPosition - rabbitPosition[1]; angle = atan2(distanceY, distanceX) * 180 / 3.14159 + 90; if (angle < 0) angle += 360; distanceX = sin(angle * DEG2RAD) * MOUSE_DISTANCE; distanceY = -cos(angle * DEG2RAD) * MOUSE_DISTANCE; oldMousePosition[0] = mousePosition[0]; oldMousePosition[1] = mousePosition[1]; mousePosition[0] = rabbitPosition[0] + distanceX; mousePosition[1] = rabbitPosition[1] + distanceY; } int main(void) { FILE *fh; int keepRunning = 1; installKeyboardHandler(); initializeDrawBuffer(); fh = fopen("sprtsht.bmp", "rb"); if (readBMPIntoNewMemory(fh, &spritesheetImage)) return 1; fclose(fh); spritesheetImage.transparentColor = 0; setupWallSprites(); setupRabbitSprites(); setVideoMode(VIDEO_MODE_VGA_256); bmp256ColorPaletteToVGAColorPalette(&spritesheetImage, vgaColors); setVGAColors(vgaColors, 256); activateMouse(&mouseStatus); limitMouseArea(0, 0, 199, 199); buildArena(); while (keepRunning) { readMouse(&mouseStatus); populateKeyboardKeydownState(); handleRabbitMovement(); calculateTargetAngle(); drawOnlyRabbitArena(); drawOnlyMouseArena(); renderRabbit(); renderMouse(); waitStartVbl(); copyDrawBufferToDisplay(); waitEndVbl(); if (keyboardKeydownState.KEY_ESC) { keepRunning = 0; } } // states: // * main menu // * play // * quit // * play // * draw base map // * draw sidebar // * Game loop // * get mouse // * get keyboard // * set character position // * check for enemy spawn and spawn enemy if needed // * check for character firing and able to fire, spawn bullet if allowed // * check for each enemy firing and able to fire, spawn enemy bullet if allowed // * check for bullet collisions // * enemies are destroyed // * character is damaged // * 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; }