276 lines
7.1 KiB
C
276 lines
7.1 KiB
C
#include <stdio.h>
|
|
#include <math.h>
|
|
#include <conio.h>
|
|
|
|
#include "system/vga.h"
|
|
#include "system/keyboard.h"
|
|
#include "system/mouse_io.h"
|
|
#include "system/pc_stuff.h"
|
|
|
|
#include "bmpload.h"
|
|
#include "const.h"
|
|
#include "arena.h"
|
|
#include "movement.h"
|
|
|
|
struct BMPImage spritesheetImage;
|
|
struct VGAColor vgaColors[256];
|
|
|
|
struct SpriteRender rabbit, mouse, bullet;
|
|
struct RabbitPosition rabbitPosition = {
|
|
.rabbitPosition = { 60, 60 },
|
|
.rabbitLimits = { { 20, 20 }, { 180, 180 } },
|
|
.mousePosition = { 0, 0 },
|
|
.rabbitVelocity = { 0, 0 },
|
|
.mouseDotPosition = { 0, 0 }
|
|
};
|
|
|
|
struct BulletPosition rabbitBulletPosition[RABBIT_BULLET_LIMIT];
|
|
struct RabbitWeaponry rabbitWeaponry;
|
|
|
|
void setupRabbitBullets() {
|
|
char i;
|
|
|
|
for (i = 0; i < RABBIT_BULLET_LIMIT; ++i) {
|
|
rabbitBulletPosition[i].isActive = 0;
|
|
rabbitBulletPosition[i].willBeInactive = 0;
|
|
}
|
|
|
|
rabbitWeaponry.cooldown = 0;
|
|
}
|
|
|
|
void attemptToFireRabbitBullet() {
|
|
char okToFire = 0, availableBullet, i;
|
|
signed char doubleVelocityX, doubleVelocityY;
|
|
|
|
if (rabbitWeaponry.cooldown > 0) return;
|
|
|
|
for (i = 0; i < RABBIT_BULLET_LIMIT; ++i) {
|
|
if (rabbitBulletPosition[i].isActive == 0) {
|
|
okToFire = 1;
|
|
availableBullet = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!okToFire) return;
|
|
|
|
rabbitWeaponry.cooldown = RABBIT_BULLET_COOLDOWN;
|
|
|
|
doubleVelocityX = sin(rabbitPosition.mouseAngle * DEG2RAD) * (RABBIT_BULLET_VELOCITY * 2);
|
|
doubleVelocityY = -cos(rabbitPosition.mouseAngle * DEG2RAD) * (RABBIT_BULLET_VELOCITY * 2);
|
|
|
|
rabbitBulletPosition[availableBullet].isActive = 1;
|
|
rabbitBulletPosition[availableBullet].willBeInactive = 0;
|
|
rabbitBulletPosition[availableBullet].x = rabbitPosition.rabbitPosition[0];
|
|
rabbitBulletPosition[availableBullet].y = rabbitPosition.rabbitPosition[1] - RABBIT_BULLET_HEIGHT_START;
|
|
rabbitBulletPosition[availableBullet].oldX = rabbitBulletPosition[availableBullet].x;
|
|
rabbitBulletPosition[availableBullet].oldY = rabbitBulletPosition[availableBullet].y;
|
|
|
|
rabbitBulletPosition[availableBullet].velocityXSteps[0] = doubleVelocityX / RABBIT_BULLET_VELOCITY;
|
|
rabbitBulletPosition[availableBullet].velocityXSteps[1] = doubleVelocityX % RABBIT_BULLET_VELOCITY;
|
|
|
|
rabbitBulletPosition[availableBullet].velocityYSteps[0] = doubleVelocityY / RABBIT_BULLET_VELOCITY;
|
|
rabbitBulletPosition[availableBullet].velocityYSteps[1] = doubleVelocityY % RABBIT_BULLET_VELOCITY;
|
|
|
|
rabbitBulletPosition[availableBullet].velocityStep = 0;
|
|
}
|
|
|
|
void advanceRabbitBullets() {
|
|
char i;
|
|
signed char velocityX, velocityY;
|
|
|
|
for (i = 0; i < RABBIT_BULLET_LIMIT; ++i) {
|
|
if (!rabbitBulletPosition[i].isActive) continue;
|
|
|
|
rabbitBulletPosition[i].oldX = rabbitBulletPosition[i].x;
|
|
rabbitBulletPosition[i].oldY = rabbitBulletPosition[i].y;
|
|
|
|
rabbitBulletPosition[i].x += rabbitBulletPosition[i].velocityXSteps[rabbitBulletPosition[i].velocityStep];
|
|
rabbitBulletPosition[i].y += rabbitBulletPosition[i].velocityYSteps[rabbitBulletPosition[i].velocityStep];
|
|
|
|
if (rabbitBulletPosition[i].x < MOUSE_LIMIT_LEFT) rabbitBulletPosition[i].willBeInactive = 1;
|
|
if (rabbitBulletPosition[i].x >= MOUSE_LIMIT_RIGHT) rabbitBulletPosition[i].willBeInactive = 1;
|
|
if (rabbitBulletPosition[i].y < MOUSE_LIMIT_TOP) rabbitBulletPosition[i].willBeInactive = 1;
|
|
if (rabbitBulletPosition[i].y >= MOUSE_LIMIT_BOTTOM) rabbitBulletPosition[i].willBeInactive = 1;
|
|
|
|
rabbitBulletPosition[i].velocityStep = 1 - rabbitBulletPosition[i].velocityStep;
|
|
}
|
|
|
|
if (rabbitWeaponry.cooldown > 0) rabbitWeaponry.cooldown--;
|
|
}
|
|
|
|
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;
|
|
|
|
buildSpriteFromSpritesheet(
|
|
&spritesheetImage,
|
|
&bullet,
|
|
16, 28, 4, 4
|
|
);
|
|
|
|
bullet.offsetX = 1;
|
|
bullet.offsetY = 1;
|
|
}
|
|
|
|
struct MouseStatus mouseStatus;
|
|
|
|
void renderMouse() {
|
|
mouse.x = rabbitPosition.mousePosition[0];
|
|
mouse.y = rabbitPosition.mousePosition[1];
|
|
|
|
drawSprite(&mouse);
|
|
drawPixel(rabbitPosition.mouseDotPosition[0], rabbitPosition.mouseDotPosition[1], 2);
|
|
}
|
|
|
|
void renderRabbit() {
|
|
rabbit.x = rabbitPosition.rabbitPosition[0];
|
|
rabbit.y = rabbitPosition.rabbitPosition[1];
|
|
|
|
drawSprite(&rabbit);
|
|
}
|
|
|
|
void renderRabbitBullets() {
|
|
char i;
|
|
|
|
char buffer[20];
|
|
|
|
for (i = 0; i < RABBIT_BULLET_LIMIT; ++i) {
|
|
if (!rabbitBulletPosition[i].isActive) continue;
|
|
|
|
bullet.x = rabbitBulletPosition[i].x;
|
|
bullet.y = rabbitBulletPosition[i].y;
|
|
|
|
sprintf(buffer, "%d %d", bullet.x, bullet.y);
|
|
writeString(buffer, 0, 10);
|
|
|
|
drawSprite(&bullet);
|
|
}
|
|
}
|
|
|
|
struct SpriteBounds bounds;
|
|
|
|
void drawOnlyMouseArena() {
|
|
mouse.x = rabbitPosition.oldMousePosition[0];
|
|
mouse.y = rabbitPosition.oldMousePosition[1];
|
|
getSpriteBounds(&mouse, &bounds);
|
|
drawOnlyArena(&bounds);
|
|
|
|
bounds.top = rabbitPosition.oldMouseDotPosition[1];
|
|
bounds.bottom = rabbitPosition.oldMouseDotPosition[1];
|
|
bounds.left = rabbitPosition.oldMouseDotPosition[0];
|
|
bounds.right = rabbitPosition.oldMouseDotPosition[0];
|
|
drawOnlyArena(&bounds);
|
|
}
|
|
|
|
void drawOnlyRabbitArena() {
|
|
rabbit.x = rabbitPosition.oldRabbitPosition[0];
|
|
rabbit.y = rabbitPosition.oldRabbitPosition[1];
|
|
getSpriteBounds(&rabbit, &bounds);
|
|
drawOnlyArena(&bounds);
|
|
}
|
|
|
|
void drawOnlyRabbitBulletArena() {
|
|
int i;
|
|
for (i = 0; i < RABBIT_BULLET_LIMIT; ++i) {
|
|
if (!rabbitBulletPosition[i].isActive) continue;
|
|
|
|
bullet.x = rabbitBulletPosition[i].oldX;
|
|
bullet.y = rabbitBulletPosition[i].oldY;
|
|
getSpriteBounds(&bullet, &bounds);
|
|
drawOnlyArena(&bounds);
|
|
|
|
if (rabbitBulletPosition[i].willBeInactive) {
|
|
rabbitBulletPosition[i].isActive = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
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(&spritesheetImage);
|
|
setupRabbitSprites();
|
|
setupRabbitBullets();
|
|
|
|
setVideoMode(VIDEO_MODE_VGA_256);
|
|
bmp256ColorPaletteToVGAColorPalette(&spritesheetImage, vgaColors);
|
|
setVGAColors(vgaColors, 256);
|
|
|
|
activateMouse(&mouseStatus);
|
|
|
|
buildArena();
|
|
clearArenaRedrawRequests();
|
|
|
|
while (keepRunning) {
|
|
readMouse(&mouseStatus);
|
|
populateKeyboardKeydownState();
|
|
handleRabbitMovement(
|
|
&rabbitPosition,
|
|
&keyboardKeydownState
|
|
);
|
|
captureAndLimitMousePosition(
|
|
&rabbitPosition,
|
|
&mouseStatus
|
|
);
|
|
calculateTargetAngle(
|
|
&rabbitPosition,
|
|
&mouseStatus
|
|
);
|
|
|
|
if (mouseStatus.leftButtonDown) attemptToFireRabbitBullet();
|
|
|
|
advanceRabbitBullets();
|
|
|
|
drawOnlyRabbitArena();
|
|
drawOnlyMouseArena();
|
|
drawOnlyRabbitBulletArena();
|
|
redrawArena();
|
|
renderRabbit();
|
|
renderMouse();
|
|
renderRabbitBullets();
|
|
|
|
waitStartVbl();
|
|
|
|
copyDrawBufferToDisplay();
|
|
|
|
waitEndVbl();
|
|
|
|
if (keyboardKeydownState.KEY_ESC) { keepRunning = 0; }
|
|
}
|
|
|
|
freeBMP(&spritesheetImage);
|
|
|
|
setVideoMode(VIDEO_MODE_80x25_TEXT);
|
|
uninstallKeyboardHandler();
|
|
|
|
fprintf(stderr, "meow\n");
|
|
|
|
return 0;
|
|
}
|