summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschneefux <schneefux+commit@schneefux.xyz>2013-11-15 19:59:19 +0100
committerschneefux <schneefux+commit@schneefux.xyz>2013-11-15 19:59:19 +0100
commit5d4a70f81d1896ede119e0dfe42392c4506a2a34 (patch)
tree3107dfb277c97421d91b5b94f397c93f1a2f359e
parent677385ffdd1e330cfba4dd712ca58595feeea41d (diff)
downloadfx-maze-5d4a70f81d1896ede119e0dfe42392c4506a2a34.tar.gz
fx-maze-5d4a70f81d1896ede119e0dfe42392c4506a2a34.zip
added comments
-rw-r--r--Wolf3D.c47
-rw-r--r--calc.c4
-rw-r--r--draw.c134
-rw-r--r--engine.c86
-rw-r--r--global.c13
-rw-r--r--hardware.c12
-rw-r--r--key.c6
-rw-r--r--ki.c15
-rw-r--r--mapgen.c28
-rw-r--r--menu.c2
-rw-r--r--sprites.c4
11 files changed, 273 insertions, 78 deletions
diff --git a/Wolf3D.c b/Wolf3D.c
index 22f790f..cf2b00f 100644
--- a/Wolf3D.c
+++ b/Wolf3D.c
@@ -15,17 +15,22 @@
void main(void)
{
+ // strings for display
char FPS[9];
char LIVE[13];
+ // fps counter
static int oldtime;
static int maintimer = 0;
+ // every 100 ms, change contrast
if(RTC_Elapsed_ms(maintimer, 100))
{
+ // this is a workaround, so that no extra timer is needed
maintimer = RTC_GetTicks();
if(player.health <= 50)
{
+ // health is low, warn player
if(contrast > 10 || contrast < -10)
{
contradd *= -1;
@@ -34,32 +39,37 @@ void main(void)
set_contrast(168 + contrast);
}
+ // remove status every 100 * 100 ms = 10 sec, IIRC
if(statustimer++ == 100)
{
statustimer = 0;
status = NULL;
}
+ // a hit is shown with a backlight flash
if(BacklightIsOn() && statustimer % 5 == 0)
{
+ // turn backlight off after 100 ms * 5 = 500 ms
BacklightOff();
}
}
+ // check keyboard input
move();
- if(output != 0)
+ if(output != 0) // output of move()
{
unsigned int time;
- oldtime = RTC_GetTicks();
- clear_vram();
- cast();
+ oldtime = RTC_GetTicks(); // init FPS counter
+ clear_vram(); // clear display
+ cast(); // render image
- drawgun();
+ drawgun(); // show gun
- if(output == 2)
+ if(output == 2) // if the player moved fw/bw, the gun has to move
{
if(player.gunpos > 3 || player.gunpos < -3)
{
+ // move gun from top to bottom and vice-versa
if(player.gunpos > 3)
player.gunpos = 3;
@@ -68,21 +78,28 @@ void main(void)
player.gunpos += gundir;
}
+ // print FPS
sprintf(&FPS, "fps:%2.2f", 1 / fps);
PrintMini(0, 0, &FPS, MINI_OR);
+ // print health
sprintf(&LIVE, "health:%4d", player.health);
PrintMini(80, 0, &LIVE, MINI_OR);
+ // and a status message, if available
if(status != NULL)PrintMini(0, 58, status, MINI_OR);
+ // update screen
display_vram();
if(player.health <= 0)
{
+ // game over
exit = TRUE;
}
+ // set kind of move (output from move()) to 0 again
output = 0;
+ // re-calculate FPS
fps = (((RTC_GetTicks() * 15.625 - oldtime * 15.625)) / 1000);
}
}
@@ -90,8 +107,10 @@ void main(void)
int AddIn_main(int isAppli, unsigned short OptionNum)
{
int c;
+ // get the pointer to vram
vram = Disp_GetVRAMPtr();
+ // if we ever got a new calc model, this would save us (hopefully)
if(getCalc() == UNKNOWN)
{
clear_vram();
@@ -112,19 +131,26 @@ int AddIn_main(int isAppli, unsigned short OptionNum)
GetKey(&c);
}
+ // make it possible to start the game again after [Menu]
APP_EnableRestart();
+ // generate some tables for speed
table();
+ // seed rand()
seedrandom();
+ // if we want to have enemies, allocate and create them
if(ENEMYCNT)
{
sprites = (struct st_sprite *) malloc(ENEMYCNT * sizeof(struct st_sprite));
+ // these are debug checks; there should be enough memory
if(sprites == NULL)error();
}
+ // spritecnt holds the number of all sprites; enemies, items and whatever else will come
spritecnt = ENEMYCNT;
+ // set every enemy into the map
for(c = 0; c < spritecnt; c++)
{
kisetpos(&sprites[c].x, &sprites[c].y);
@@ -135,8 +161,10 @@ int AddIn_main(int isAppli, unsigned short OptionNum)
sprites[c].effect = 50;
}
+ // create a random maze
maze();
+ // init the player's values
player.x = 1.5;
player.y = 1.5;
player.dirX = -1;
@@ -148,20 +176,25 @@ int AddIn_main(int isAppli, unsigned short OptionNum)
player.health = 500;
contrast = 0;
+ // this timer handles the enemie's movement. KI is AI in German, I didn't want to rewrite everything :)
Timer_Install(8, &timer, KISPEED);
Timer_Start(8);
exit = FALSE;
+ // main loop
while(exit == FALSE)
{
main();
+ // if player won
if((int)player.x == MAPSIZE - 1 && (int)player.y == MAPSIZE - 1)break;
}
+ // kill all timers, set contrast to default
Timer_Uninstall(8);
set_contrast(168);
+ // did he/she loose
if(player.health > 0 && exit == FALSE)
{
clear_vram();
@@ -172,8 +205,10 @@ int AddIn_main(int isAppli, unsigned short OptionNum)
display_vram();
Sleep(1000);
}
+ // free memory to avoid system errors
free(sprites);
+ // clear keyboard buffer, otherwise you could see the cursor move after exit
Keyboard_ClrBuffer();
}
diff --git a/calc.c b/calc.c
index 51ef6e2..4b5be28 100644
--- a/calc.c
+++ b/calc.c
@@ -2,8 +2,10 @@
#include "calc.h"
#include "syscalls.h"
+// table that holds precalculated values for the floor and ceiling
int TDist[64];
+// random number generator; could be improved
static uint lastrandom = 0x123456;
void seedrandom(void)
@@ -17,6 +19,7 @@ unsigned int random()
return (lastrandom >> 16);
}
+// inits constants for floor etc
void table()
{
int x;
@@ -26,6 +29,7 @@ void table()
}
}
+// fills an array
void fill(uint *ptr, uint element, uint arraysize)
{
for(;arraysize > 0; arraysize--, ptr++)
diff --git a/draw.c b/draw.c
index 0235165..0a0802b 100644
--- a/draw.c
+++ b/draw.c
@@ -1,3 +1,5 @@
+// Thanks to PierrotLL for MonochromeLib! I took some functions and modified them a bit.
+
#include "global.h"
#include "draw.h"
#include "sprites.h"
@@ -5,8 +7,10 @@
#include "key.h"
#include "syscalls.h"
+// options, this can speed up the rendering
int drawfloor = FALSE, drawheight = TRUE, drawtex = TRUE;
+// fast drawing function for horizontal lines
void horizontal(int y, int x1, int x2)
{
int checker, i;
@@ -23,6 +27,7 @@ void horizontal(int y, int x1, int x2)
else vram[(y<<4)+(x1>>3)] |= (255>>(x1%8 + 7-x2%8))<<(7-(x2&7));
}
+// fills a box using horizontal
void fillbox(int x1, int y1, int x2, int y2)
{
int i;
@@ -42,11 +47,13 @@ void fillbox(int x1, int y1, int x2, int y2)
horizontal(i, x1, x2);
}
+// a printmini in locate-like lines (1 to 7, but small chars)
void locatePrintMini(int x, int y, const uchar *text)
{
PrintMini((x - 2) * 6, (y - 2) * 8, text, 0);
}
+// draws a generated map, only used in generation before the main game
void drawgenmap()
{
int x, y;
@@ -57,35 +64,42 @@ void drawgenmap()
{
if(map[x][y] == WALL || map[x][y] == CHECKED)
{
+ // draws a filled box wherever a wall is or could be
fillbox(x * sizex, y * sizey, (x + 1) * sizex, (y + 1) * sizey);
}
}
}
}
+// draws the map in the main game, including items
void showmap()
{
int x, y, exit = FALSE;
- int windowx = player.x, windowy = player.x, zoom = 8;
- const char plsprite = 0xA9;
- int lastkey, thiskey = 0;
+ int windowx = player.x, windowy = player.x, zoom = 8; // variables for scrolling
+ const char plsprite = 0xA9; // player's icon
+ int lastkey, thiskey = 0; // hold the pressed keys for a better movement
+
do
{
- int skew = 64 / zoom;
+ int skew = 64 / zoom; // factor for zooming
while(windowx + zoom * 2 >= MAPSIZE)
{
- windowx--;
+ windowx--; // if the window is outside of the map
}
+ // clear display
clear_vram();
+ // draw all static blocks
for(x = windowx; x < windowx + zoom * 2; x++)
{
for(y = windowy; y < windowy + zoom; y++)
{
+ // draw every square that is in the bounds of the viewer
if(map[x][y] != SPACE)
{
+ // if there is something, draw it
fillbox((x - windowx) * skew, (y - windowy) * skew, (x + 1 - windowx) * skew, (y + 1 - windowy) * skew);
switch(map[x][y])
{
@@ -97,11 +111,13 @@ void showmap()
}
else if(x == (int)player.x && y == (int)player.y)
{
+ // the player gets a nice icon
PrintMini((player.x - windowx) * skew + 1, (player.y - windowy) * skew, &plsprite, MINI_OVER);
}
}
}
+ // draw sprites
for(x = 0; x < spritecnt; x++)
{
if(sprites[x].x >= windowx && sprites[x].x < windowx + zoom * 2 && sprites[x].y >= windowy && sprites[x].y < windowy + zoom)
@@ -109,17 +125,21 @@ void showmap()
switch(sprites[x].type)
{
case TYPE_ENEMY:
+ // it's an enemy
PrintMini((sprites[x].x - windowx) * skew, (sprites[x].y - windowy) * skew, "!", MINI_OVER);
break;
case TYPE_PACK:
+ // health pack
PrintMini((sprites[x].x - windowx) * skew, (sprites[x].y - windowy) * skew, "+", MINI_OVER);
break;
}
}
}
+ // refresh
display_vram();
+ // emulate a GetKey-like speeding up on hold
keyupdate();
if(lastkey != thiskey)
@@ -133,7 +153,9 @@ void showmap()
lastkey = thiskey;
- if(keydown(KEY_CTRL_EXIT))exit = TRUE;
+ if(keydown(KEY_CTRL_EXIT)) exit = TRUE; // back to the game
+
+ // move the window
if(keydown(KEY_CTRL_UP) && windowy > 0)
{
windowy--;
@@ -154,6 +176,8 @@ void showmap()
windowx++;
thiskey = KEY_CTRL_RIGHT;
}
+
+ // zoom in and out
if(keydown(KEY_CHAR_PLUS) && zoom > 1)
{
zoom--;
@@ -167,18 +191,22 @@ void showmap()
}while(exit == FALSE);
}
+// draws the gun on the bottom of the screen
void drawgun()
{
int i,u;
const int y = 47 + player.gunpos;
+ // depending on the weapon, but both are 21 x 22
+ // this could be improved, but it is ok like this
for(i = 0; i < 21; i++)
{
for(u = 0; u < 22; u++)
{
if(y + u <= 64)
{
+ // 0 = transparent, 1 = black, 2 = white
switch(player.weapon)
{
case GUN:
@@ -214,15 +242,20 @@ void drawgun()
}
}
+// draw a vertical stripe using textures if wanted
+// args: x coord, x in texture, lower side's y, upper side's y, type of sprite, color (inversed or not)
+// if steps are given, use them; otherwise we get problems with the floor or ceiling
void vertical(int x, int tex, int start, int end, int type, int color, float steps)
{
int y = start;
int pos = 1 << 7, step;
-
+
+ // this fastens the progress
uchar xbyte = x & 7;
uchar shiftbyte = (128 >> xbyte);
uchar *buffpos = (unsigned char*)(vram + (x >> 3));
-
+
+ // do we need to draw textures?
if(drawtex == FALSE && type == 1)
{
if(start > end)
@@ -238,6 +271,7 @@ void vertical(int x, int tex, int start, int end, int type, int color, float ste
pixel(x,start);
}
+ // swap the end and start to draw from top down
if(start > end)
{
int tmp = start;
@@ -245,55 +279,59 @@ void vertical(int x, int tex, int start, int end, int type, int color, float ste
end = tmp;
}
+ // for every type of sprite use different textures
switch(type)
{
- case 1 :
- if(steps == 0)
- step = (16 << 8) / (end - start);
- else
- step = (16.0 / steps) * 128.0;
-
- for(; y < end;pos += step, y++)
- {
- if(wall[color][pos >> 8][(int)(tex >> 2)] == 1)
- (*(buffpos + (y << 4))) |= ((1 << 7) >> xbyte);
- /*else
- (*(buffpos + (y << 4))) &= ~((1 << 7) >> xbyte);*/
- }
- break;
+ case WALL:
+ // bitshifts are _lots_ faster than floats!
+ if(steps == 0)
+ step = (16 << 8) / (end - start);
+ else
+ step = (16.0 / steps) * 128.0;
- case 2 :
- if(steps == 0)
- step = (16 << 8) / (end - start);
- else
- step = (16.0 / steps) * 128.0;
-
- for(; y < end;pos += step, y ++)
- {
- (*(buffpos + (y << 4))) |= ((door[pos >> 8][(int)(tex >> 2)] << 7) >> xbyte);
- }
- break;
+ for(; y < end;pos += step, y++)
+ {
+ if(wall[color][pos >> 8][(int)(tex >> 2)] == 1)
+ (*(buffpos + (y << 4))) |= ((1 << 7) >> xbyte);
+
+ /*else
+ (*(buffpos + (y << 4))) &= ~((1 << 7) >> xbyte);*/
+ }
+ break;
- case 3 :
- if(steps == 0)
- step = (8 << 8) / (end - start);
- else
- step = (8.0 / steps) * 128.0;
-
- for(; y < end;pos += step, y ++)
- {
- if(pack[pos >> 8][(int)(tex >> 3)] == 1)
+ case DOOR:
+ if(steps == 0)
+ step = (16 << 8) / (end - start);
+ else
+ step = (16.0 / steps) * 128.0;
+
+ for(; y < end;pos += step, y ++)
{
- (*(buffpos + (y << 4))) |= shiftbyte;
+ (*(buffpos + (y << 4))) |= ((door[pos >> 8][(int)(tex >> 2)] << 7) >> xbyte);
}
+ break;
+
+ case 3 :
+ // this is a health packet
+ if(steps == 0)
+ step = (8 << 8) / (end - start);
else
+ step = (8.0 / steps) * 128.0;
+
+ for(; y < end;pos += step, y ++)
{
- if(pack[pos >> 8][(int)(tex >> 3)] == 2)
+ if(pack[pos >> 8][(int)(tex >> 3)] == 1)
+ {
+ (*(buffpos + (y << 4))) |= shiftbyte;
+ }
+ else
{
- (*(buffpos + (y << 4))) &= ( ~shiftbyte);
- }
+ if(pack[pos >> 8][(int)(tex >> 3)] == 2)
+ {
+ (*(buffpos + (y << 4))) &= ( ~shiftbyte);
+ }
+ }
}
- }
- break;
+ break;
}
}
diff --git a/engine.c b/engine.c
index 19a7cf9..8acd11a 100644
--- a/engine.c
+++ b/engine.c
@@ -11,6 +11,7 @@
float fps;
+// swap two floats
void swap(float *a, float *b)
{
float tmp = *a;
@@ -18,6 +19,7 @@ void swap(float *a, float *b)
*b = tmp;
}
+// sort algorithm for sprites
void combSort(int* order, float* dist, int amount)
{
int gap = amount, i;
@@ -43,17 +45,21 @@ void combSort(int* order, float* dist, int amount)
#define PI 3.141592653589793238464
+// perform a shoot
static void pshoot()
{
float xadd, yadd, x, y;
int c;
+ // check for every sprite whether it is hit
for(c = 0; c < spritecnt; c++)
{
+ // but just enemies, packs shouldn't die
if(sprites[c].type == TYPE_ENEMY)
{
- x = player.x;
- y = player.y;
+ x = player.x;
+ y = player.y;
+
if(Abs(x - sprites[c].x) > Abs(y - sprites[c].y))
{
xadd = sgn(sprites[c].x - x);
@@ -65,8 +71,9 @@ static void pshoot()
yadd = sgn(sprites[c].y - y);
}
- if(1/*TODOTODOTODOTODO*/)
+ if(1/*TODOTODOTODOTODO*/) // todo: implement something to check whether the player shoots in the right direction
{
+ // very simple raycasting
while(x < MAPSIZE && y < MAPSIZE && x >= 0 && y >= 0)
{
x += xadd;
@@ -74,6 +81,7 @@ static void pshoot()
if((int)y == (int)sprites[c].y && (int)x == (int)sprites[c].x)
{
+ // if hit, reduce enemie's health or let it die
sprites[c].effect -= 5;
if(sprites[c].effect <= 0)
{
@@ -81,9 +89,11 @@ static void pshoot()
sprites = (struct st_sprite *) realloc(sprites, spritecnt-- * sizeof(struct st_sprite));
if(sprites == NULL)error();
}
+ // we hit an enemy, go back to the game
return;
}
+ // if there is a wall, no chance, try again
if(solids[(int)(x + 0.5)][(int)(y + 0.5)] == SOLID)
{
break;
@@ -94,17 +104,22 @@ static void pshoot()
}
}
+// this moves the player in the world
void move()
{
float oldDirX, oldPlaneX, moveSpeed = fps * 1.25, rotSpeed = fps / 1.25;
float newx = 0, newy = 0;
+ // update the key buffer
keyupdate();
+
+ // I hope this is self-explaining
if(keydown(KEY_CTRL_DOWN) || keydown(KEY_CTRL_UP) || keydown(KEY_CTRL_LEFT) || keydown(KEY_CTRL_RIGHT))
{
if(keydown(KEY_CTRL_DOWN))
{
newy = player.y - (player.dirY * moveSpeed);
newx = player.x - (player.dirX * moveSpeed);
+
if(newx >= 0 && newx < MAPSIZE)
if(solids[(int)newx][(int)player.y] != SOLID)
{
@@ -116,7 +131,7 @@ void move()
{
player.y = newy;
}
- output = 2;
+ output = 2; // 2 means the player moved, so the gun has to move
}
if(keydown(KEY_CTRL_UP))
{
@@ -136,12 +151,15 @@ void move()
}
if(keydown(KEY_CTRL_RIGHT))
{
+ // rotate the plane
oldDirX = player.dirX;
player.dirX = player.dirX * cosf(-rotSpeed) - player.dirY * sinf(-rotSpeed);
player.dirY = oldDirX * sinf(-rotSpeed) + player.dirY * cosf(-rotSpeed);
oldPlaneX = player.planeX;
player.planeX = player.planeX * cosf(-rotSpeed) - player.planeY * sinf(-rotSpeed);
player.planeY = oldPlaneX * sinf(-rotSpeed) + player.planeY * cosf(-rotSpeed);
+
+ // if the output is 2 (move gun), let it; ortherwise set to 1 (just update)
output = (output < 2)?1:2;
}
if(keydown(KEY_CTRL_LEFT))
@@ -152,8 +170,11 @@ void move()
oldPlaneX = player.planeX;
player.planeX = player.planeX * cosf(rotSpeed) - player.planeY * sinf(rotSpeed);
player.planeY = oldPlaneX * sinf(rotSpeed) + player.planeY * cosf(rotSpeed);
+
output = (output < 2)?1:2;
}
+
+ // if we hit a sprite
if(solids[(int)newx][(int)newy] == SPRITE)
{
int c;
@@ -161,14 +182,17 @@ void move()
{
if(sprites[c].type == TYPE_PACK && (int)sprites[c].x == (int)newx && (int)sprites[c].y == (int)newy)
{
+ // cool, it is a pack
solids[(int)newx][(int)newy] = UNSOLID;
player.health += sprites[c].effect;
+ // delete it
sprites[c] = sprites[spritecnt];
sprites = (struct st_sprite *) realloc(sprites, spritecnt-- * sizeof(struct st_sprite));
if(sprites == NULL)error();
output = 2;
+ // got it
status = packmsg;
statustimer = 0;
break;
@@ -180,6 +204,7 @@ void move()
{
if(keydown(KEY_CTRL_MENU))
{
+ // open game menu
openmenu();
output = (output < 2)?1:2;
return;
@@ -188,24 +213,27 @@ void move()
if(keydown(KEY_CTRL_SHIFT))
{
- switch(player.weapon)
- {
- case GUN:
- pshoot();
- break;
- /*case KNIFE:
- newy = player.y + player.dirY;
- newx = player.x + player.dirX;
- if(newx >= 0 && newx < MAPSIZE)
- if(map[(int)(newx)][(int)(newy)] >= 10)
- {enemies[map[(int)(newx)][(int)(newy)] - 10].health -= 15;}
- break;*/
- }
-
- output = 2;
+ // fire!
+ switch(player.weapon)
+ {
+ case GUN:
+ // perhaps an enemy was hit?
+ pshoot();
+ break;
+ /*case KNIFE: // todo: fix this for dynamical enemies
+ newy = player.y + player.dirY;
+ newx = player.x + player.dirX;
+ if(newx >= 0 && newx < MAPSIZE)
+ if(map[(int)(newx)][(int)(newy)] >= 10)
+ {enemies[map[(int)(newx)][(int)(newy)] - 10].health -= 15;}
+ break;*/
+ }
+
+ output = 2;
}
if(keydown(KEY_CTRL_ALPHA))
{
+ // alpha opens a door
newy = player.y + player.dirY;
newx = player.x + player.dirX;
if(newx >= 0 && newx < MAPSIZE)
@@ -213,6 +241,7 @@ void move()
if(map[(int)(newx)][(int)(newy)] == DOOR)
{
map[(int)(newx)][(int)(newy)] = SPACE;
+ // now there is no wall any more, we can walk through
solids[(int)newx][(int)newy] = UNSOLID;
}
}
@@ -220,14 +249,18 @@ void move()
}
if(keydown(KEY_CTRL_OPTN))
{
+ // optn, change weapon
player.weapon += 1;
if(player.weapon == WEAPON_OVERFLOW)
player.weapon = GUN;
}
}
+// this is the "core", most important part
+// rendering is done here
void cast()
{
+ // see Lode Vandevenne's tutorial for details
float cameraX,rayDirX, rayDirY, sideDistX, sideDistY, deltaDistX, deltaDistY, perpWallDist, wallX, floorXWall, floorYWall, distWall;
int mapX, mapY, lineHeight, hit, side, x, tex, y, black, floorTexX, floorTexY, actualheight, heightdiff;
int stepX, drawStart, drawEnd, stepY;
@@ -254,6 +287,7 @@ void cast()
for(x = 0; x < 128; x++)
{
+ // create a ray from player
mapX = player.x;
mapY = player.y;
@@ -315,10 +349,12 @@ void cast()
{
if(heights[mapX][mapY] == 0 || drawheight == FALSE)
{
+ // it is a normal wall or something
hit = TRUE;
}
else
{
+ // now it's going to be complicated, let's draw a wall with a different height than the others \o/
if (side == 0)
perpWallDist = Abs((mapX - player.x + (1 - stepX) / 2) / rayDirX);
else
@@ -336,9 +372,11 @@ void cast()
if(drawStart < 0) drawStart = 0;
drawEnd = (actualheight == 0)?32 + (Abs((int)(64 / perpWallDist)) >> 1):actualheight;
if(drawEnd >= 64) drawEnd = 63;
-
+
+ // draw the wall
vertical(x, tex , drawStart, drawEnd, map[mapX][mapY], side, Abs((32 + (Abs((int)(64 / perpWallDist)) >> 1)) - (32 - (Abs((int)(64 / perpWallDist)) >> 1))));
+ // now, the floor and the ceiling
if(side == 0 && rayDirX > 0)
{
floorXWall = mapX;
@@ -380,6 +418,7 @@ void cast()
(*(vram + (y << 4) + (x >> 3))) |= (128 >> (x & 7));
}
}
+ // continue casting, but draw it 'behind' the current wall
actualheight = drawStart;
}
}
@@ -387,6 +426,7 @@ void cast()
if(hit == TRUE)
{
+ // if we hit a wall or something, draw it
if (side == 0)
perpWallDist = Abs((mapX - player.x + (1 - stepX) / 2) / rayDirX);
else
@@ -407,8 +447,10 @@ void cast()
drawEnd = (actualheight == 0)?(lineHeight >> 1) + 32:actualheight;
if(drawEnd >= 64) drawEnd = 63;
+ // draw it to the display
vertical(x, tex , drawStart, drawEnd, map[mapX][mapY], side, (actualheight > 0)?((lineHeight >> 1) + 32) - (32 - (lineHeight >> 1)):0);
+ // draw floor & ceiling
if(drawfloor == TRUE)
{
if(side == 0 && rayDirX > 0)
@@ -468,6 +510,7 @@ void cast()
}
}
+ // here something wants to be fixed... The sprites appear strange when there is a wall lower than the others
#define uDiv 1
#define vDiv 1
#define vMove 0.0
@@ -524,6 +567,9 @@ void cast()
free(spriteOrder);
}
+
+// old casting algo, this is just a backup
+// there is nothing else below, you can skip this
/*void cast()
{
float cameraX,rayDirX, rayDirY, sideDistX, sideDistY, deltaDistX, deltaDistY, perpWallDist, wallX, floorXWall, floorYWall, distWall;
diff --git a/global.c b/global.c
index 4f9e618..ae06c9e 100644
--- a/global.c
+++ b/global.c
@@ -1,7 +1,9 @@
#include "global.h"
#include "hardware.h"
+// constants for the map overview
const uint sizex = 128 / MAPSIZE, sizey = 64 / MAPSIZE;
+// output by move()
int output = 1;
int contrast = 0;
@@ -10,16 +12,19 @@ int contradd = 5;
int gundir = 1;
int exit = FALSE;
+// demo mode for future use
int demo = FALSE;
+// holds the sprites
struct st_sprite *sprites = NULL;
+// the player's values
struct st_player player;
uint spritecnt = 0;
const char *status = NULL;
unsigned int statustimer = 0;
-uint map[MAPSIZE][MAPSIZE] = {0};/*
+uint map[MAPSIZE][MAPSIZE] = {0}; // this is now generated automatically/*
{
{ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 },
{ 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 0 , 1 },
@@ -43,7 +48,7 @@ uint map[MAPSIZE][MAPSIZE] = {0};/*
{ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 },
};*/
-int heights[MAPSIZE][MAPSIZE] = {0};/*
+int heights[MAPSIZE][MAPSIZE] = {0}; // this, too. 0 means normal height, 32 is about half of the normal/*
{
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 32 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
@@ -67,8 +72,10 @@ int heights[MAPSIZE][MAPSIZE] = {0};/*
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
};*/
-uint solids[MAPSIZE][MAPSIZE] = {0};
+uint solids[MAPSIZE][MAPSIZE] = {0}; // here you can check whether you can walk through something
+// nice idea would be a hidden wall you can walk through to access a secret room... hmmm
+// something happened that should not happen
void error(void)
{
clear_vram();
diff --git a/hardware.c b/hardware.c
index 846a390..9f56847 100644
--- a/hardware.c
+++ b/hardware.c
@@ -1,8 +1,15 @@
+// Thanks to SimonLothar, cfxm and all the other hackers!
+
#include "global.h"
#include "hardware.h"
+// here are some functions for direct hardware access
+// they are splitted to support different calculators
+
char *vram, *vram2;
+// backlight funcions: on, off, switch, check
+// if it's unknown hardware we should do nothing
void BacklightOn()
{
if(!IsEmulator)
@@ -59,6 +66,7 @@ int BacklightIsOn()
}
}
+// change contrast only for known calcs
void set_contrast(int contrast)
{
if(!getCalc() == UNKNOWN && !IsEmulator)
@@ -69,6 +77,7 @@ void set_contrast(int contrast)
}
}
+// update the display, if secure; otherwise use syscalls (sloooow!)
void display_vram()
{
if(getCalc() == UNKNOWN && !IsEmulator)
@@ -92,6 +101,7 @@ void display_vram()
}
}
+// clear video ram
void clear_vram()
{
int i, end;
@@ -108,6 +118,7 @@ void clear_vram()
for(i=0 ; i<end ; i++) pointer_byte[i] = 0;
}
+// if possible, let it restart after going to the main menu
short*APP_EnableRestart()
{
if(getCalc() != UNKNOWN && !IsEmulator)
@@ -135,6 +146,7 @@ short*APP_EnableRestart()
return NULL;
}
+// return the model
int getCalc(void)
{
static int hardware = UNKNOWN;
diff --git a/key.c b/key.c
index 20ea4f2..fc37bde 100644
--- a/key.c
+++ b/key.c
@@ -2,9 +2,11 @@
#include "key.h"
#include "hardware.h"
+// SHA4 only
static const unsigned short* keyboard_register = (unsigned short*)0xA44B0000;
static unsigned short lastkey[8];
+// syscall getkey (non-blocking)
int PRGM_GetKey()
{
unsigned char buffer[12];
@@ -12,12 +14,14 @@ int PRGM_GetKey()
return (buffer[1] & 0x0F) * 10 + ((buffer[2] & 0xF0) >> 4);
}
+// do I have to explain this?
static void delay()
{
unsigned int i;
for(i=0 ; i<5 ; i++);
}
+// fast function for SH3
static unsigned char CheckKeyRow(int code)
{
unsigned int result=0;
@@ -64,6 +68,7 @@ static unsigned char CheckKeyRow(int code)
return result;
}
+// update key buffer
void keyupdate()
{
if(getCalc() == fx9860GII_2)
@@ -72,6 +77,7 @@ void keyupdate()
}
}
+// check for keypress, depending on the calculator
int keydown(int code)
{
if(getCalc() != UNKNOWN)
diff --git a/ki.c b/ki.c
index 717ce98..fb89bf4 100644
--- a/ki.c
+++ b/ki.c
@@ -5,6 +5,10 @@
#include "mathf.h"
+// here are the ai's functions
+// todo: change the function's names
+
+// check if the player can be seen by the enemy
static int kshoot(float x, float y)
{
float xadd, yadd;
@@ -20,6 +24,7 @@ static int kshoot(float x, float y)
yadd =sgn(player.y - y);
}
+ // this is raycasting again
while(x < MAPSIZE && y < MAPSIZE && x >= 0 && y >= 0)
{
if((int)y == (int)player.y && (int)x == (int)player.x)
@@ -36,6 +41,7 @@ static int kshoot(float x, float y)
return FALSE;
}
+// move them in a random direction
static void kimove()
{
int c;
@@ -45,14 +51,17 @@ static void kimove()
{
int fail[4] = {0}, success = FALSE;
+ // it _will_ move
if(sprites[c].type == TYPE_ENEMY)
{
+ // try until there is no possible direction left
while(!(fail[0] == TRUE && fail[1] == TRUE && fail[2] == TRUE && fail[3] == TRUE) && success == FALSE)
{
float newx, newy;
if(kshoot(sprites[c].x, sprites[c].y) == TRUE)
{
+ // if the player is in sight (< 3 fields), go to him/her
if(Abs((player.x) - sprites[c].x) > 3)
{
dirx = (player.x > sprites[c].x)?1:(player.x == sprites[c].x)?0:-1;
@@ -74,6 +83,7 @@ static void kimove()
}
else
{
+ // there is no player, move randomly
uint num;
do
@@ -107,6 +117,7 @@ static void kimove()
newx = sprites[c].x + dirx;
newy = sprites[c].y + diry;
+ // move that stupid sprite
if(newx < MAPSIZE && newx >= 0 && newy < MAPSIZE && newy >= 0)
{
if(solids[(int)newx][(int)newy] == UNSOLID)
@@ -123,6 +134,8 @@ static void kimove()
}
}
+// this is a kind of high-level kshoot
+// it subtracts the health
static void kishoot(void)
{
int c;
@@ -143,6 +156,7 @@ static void kishoot(void)
}
}
+// this is the timer that moves the ai
void timer(void)
{
static int ki = 0;
@@ -155,6 +169,7 @@ void timer(void)
kishoot();
}
+// set the new position in the map
void kisetpos(float *x, float *y)
{
do
diff --git a/mapgen.c b/mapgen.c
index f18df4d..6b169c4 100644
--- a/mapgen.c
+++ b/mapgen.c
@@ -4,6 +4,9 @@
#include "hardware.h"
#include "sprites.h"
+// this code is a random map generator based on the kill and hunt algorithm
+
+// this counts unempty neighbours
static int cntunvisit(union st_field cnt)
{
int c = 0;
@@ -15,6 +18,7 @@ static int cntunvisit(union st_field cnt)
return (c > 1)?c:0;
}
+// count empty ones, including ones that are outside which are counted as wall
static int cntempty(int x, int y)
{
union st_field c;
@@ -35,6 +39,7 @@ static int cntempty(int x, int y)
return cnt;
}
+// count walls
static int cntwall(int x, int y)
{
union st_field c;
@@ -55,6 +60,7 @@ static int cntwall(int x, int y)
return cnt;
}
+// return as st_field from map point
static union st_field get(int x, int y)
{
union st_field c;
@@ -69,6 +75,7 @@ static union st_field get(int x, int y)
return c;
}
+// try to find a wall with unvisited neighbours
static int hunt(int *x, int *y)
{
for(*x = 1; *x < MAPSIZE - 1; *x+=2)
@@ -84,6 +91,7 @@ static int hunt(int *x, int *y)
}
}
}
+ // if there is none, we can start the main game
return FALSE;
}
@@ -94,6 +102,7 @@ static int kill(int *x, int *y, union st_field this)
{
if(cntunvisit(this) == 0)fail1 = fail2 = fail3 = fail4 = TRUE;
+ // try to 'digg' in random directions
switch(random() % 4)
{
case 0:
@@ -179,12 +188,15 @@ static int kill(int *x, int *y, union st_field this)
if(fail1 == TRUE && fail2 == TRUE && fail3 == TRUE && fail4 == TRUE)
{
+ // dead end, try to find a new starting point
return hunt(x, y);
}
}
+ // no possible move left, let's go and kill some robots
return FALSE;
}
+// see if we can walk through that maze
static int solve()
{
int priotable[4];
@@ -193,6 +205,7 @@ static int solve()
int deltax = 1, deltay = 0;
int dir, dirx, diry;
start:
+ // that's dirty, I know, but it works
for(curx = 0; curx < MAPSIZE; curx++)
{
for(cury = 0; cury < MAPSIZE; cury++)
@@ -236,6 +249,7 @@ start:
dir = WEST;
}
+ // this is called the right-hand method, I think
switch(dir)
{
case NORTH:
@@ -263,6 +277,7 @@ start:
priotable[3] = EAST;
}
+ // try again with left-hand :D
for(dir = 0; dir < 4; dir++)
{
switch(priotable[dir])
@@ -294,12 +309,15 @@ start:
}
}
+ // we are at the start again?
if(curx == 1 && cury == 1)
{
+ // this maze has no exit, make another one
return FALSE;
}
- if(IsEmulator())
+ // debug only
+ if(IsEmulator)
{
clear_vram();
drawgenmap();
@@ -308,6 +326,7 @@ start:
}
}
+ // make changes permanent
for(curx = 0; curx < MAPSIZE; curx++)
{
for(cury = 0; cury < MAPSIZE; cury++)
@@ -325,6 +344,7 @@ start:
}
}
+ // create packs in dead-ends
for(curx = 0; curx < MAPSIZE; curx++)
{
for(cury = 0; cury < MAPSIZE; cury++)
@@ -348,6 +368,7 @@ start:
}
else if(map[curx][cury] == WALL)
{
+ // reduce the height of low walls, this gives a nice effect
if(cntwall(curx, cury) == 2)
{
heights[curx][cury] = 32;
@@ -362,6 +383,7 @@ start:
{
if(map[curx][cury] == SPACE && cntwall(curx, cury) < 2)
{
+ // it is easier with some doors that connect two floors
int dx, dy, fail1, fail2, fail3, fail4;
fail1 = fail2 = fail3 = fail4 = FALSE;
@@ -395,13 +417,17 @@ start:
return TRUE;
}
+// main loop
void maze()
{
do
{
int x = 1, y = 1, exit = TRUE;
+ // create an empty map
fill(&map, WALL, MAPSIZE * MAPSIZE);
+
+ // render it until it is solvable
while(exit == TRUE)
{
map[x][y] = SPACE;
diff --git a/menu.c b/menu.c
index a86fbdd..072ecb5 100644
--- a/menu.c
+++ b/menu.c
@@ -7,6 +7,8 @@
#include "stdio.h"
+// in-game menu
+
void openmenu()
{
uchar text[30];
diff --git a/sprites.c b/sprites.c
index 7baca5b..4b283b2 100644
--- a/sprites.c
+++ b/sprites.c
@@ -1,6 +1,10 @@
#include "global.h"
#include "sprites.h"
+// these are sprite constants
+// 0 = white, 1 = black
+// and for sprites, 0 is transparent and 2 white
+
const int wall[2][16][16] = {
{
{ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 },