mirror of
https://github.com/stevenhowes/CTheEscape.git
synced 2026-05-27 00:03:27 +01:00
442 lines
11 KiB
C
442 lines
11 KiB
C
#include "Graphics.h"
|
|
#include "swis.h"
|
|
#include <kernel.h>
|
|
|
|
extern int tick;
|
|
extern int lasttick;
|
|
extern int screen;
|
|
|
|
extern _kernel_swi_regs inreg;
|
|
extern _kernel_swi_regs outreg;
|
|
|
|
|
|
#define TILESX 10
|
|
#define TILESY 10
|
|
#define SMARTTILES 100
|
|
|
|
// map[0] is the 'master', [1] and [2] represents what is currently
|
|
// believed to be displayed in the corresponding (+1) screen buffer
|
|
// and we run a compare to see if re-drawing is needed. 0xFF is used
|
|
// for a re-draw being required (so it's set on the tile under the player
|
|
unsigned char map[3][TILESX][TILESY];
|
|
unsigned char fullmap[10000];
|
|
|
|
char tilenamebuffer[4];
|
|
char textbuffer[63];
|
|
|
|
struct EntityLocation_s {
|
|
short signed int X,Y;
|
|
};
|
|
|
|
struct TilePlayer_s {
|
|
struct EntityLocation_s location;
|
|
struct EntityLocation_s lastlocation;
|
|
struct EntityLocation_s hitbox_bl;
|
|
struct EntityLocation_s hitbox_tr;
|
|
struct EntityLocation_s drawbox_bl;
|
|
struct EntityLocation_s drawbox_tr;
|
|
struct EntityLocation_s mapoffset;
|
|
struct EntityLocation_s lastmapoffset;
|
|
struct EntityLocation_s localtile;
|
|
int rawtile;
|
|
};
|
|
|
|
struct TilePlayer_s TilePlayer;
|
|
|
|
struct SmartTile_s {
|
|
int Tile;
|
|
int ActionTarget;
|
|
unsigned char Action;
|
|
unsigned char ActionValue;
|
|
};
|
|
|
|
struct SmartTile_s SmartTiles[SMARTTILES];
|
|
|
|
void game2_savesmarttiles(char* filename)
|
|
{
|
|
// Attempt to get file info
|
|
inreg.r[0] = 10;
|
|
inreg.r[1] = (int) filename;
|
|
inreg.r[2] = 0xffd;
|
|
inreg.r[4] = (int) SmartTiles;
|
|
inreg.r[5] = (int) SmartTiles + (sizeof(SmartTiles));
|
|
|
|
_kernel_swi(OS_File,&inreg,&outreg);
|
|
|
|
}
|
|
|
|
void game2_loadsmarttiles(char* filename)
|
|
{
|
|
int length;
|
|
|
|
// Attempt to get file info
|
|
inreg.r[0] = 5;
|
|
inreg.r[1] = (int) filename;
|
|
_kernel_swi(OS_File,&inreg,&outreg);
|
|
|
|
// Length will be in R4 if it exists
|
|
length = outreg.r[4];
|
|
|
|
if(length > sizeof(SmartTiles))
|
|
{
|
|
screen_nobuffer();
|
|
while (1)
|
|
printf("Smarttiles exceeds %d bytes (%d bytes) object type is %d\n",sizeof(SmartTiles),length,outreg.r[0]);
|
|
//exit(0);
|
|
}
|
|
|
|
// Attempt to get file info
|
|
inreg.r[0] = 16;
|
|
inreg.r[1] = (int) filename;
|
|
inreg.r[2] = (int) SmartTiles;
|
|
inreg.r[3] = 0;
|
|
|
|
_kernel_swi(OS_File,&inreg,&outreg);
|
|
|
|
}
|
|
|
|
void game2_loadmap(char* filename)
|
|
{
|
|
int length,i;
|
|
|
|
// Attempt to get file info
|
|
inreg.r[0] = 5;
|
|
inreg.r[1] = (int) filename;
|
|
_kernel_swi(OS_File,&inreg,&outreg);
|
|
|
|
// Length will be in R4 if it exists
|
|
length = outreg.r[4];
|
|
|
|
if(length > sizeof(fullmap))
|
|
{
|
|
screen_nobuffer();
|
|
printf("Map exceeds %d bytes (%d bytes) object type is %d\n",sizeof(fullmap),length,outreg.r[0]);
|
|
exit(0);
|
|
}
|
|
|
|
// Attempt to get file info
|
|
inreg.r[0] = 16;
|
|
inreg.r[1] = (int) filename;
|
|
inreg.r[2] = (int) fullmap;
|
|
inreg.r[3] = 0;
|
|
|
|
_kernel_swi(OS_File,&inreg,&outreg);
|
|
|
|
for(i = 0; i < SMARTTILES; i++)
|
|
SmartTiles[i].Tile = -1;
|
|
}
|
|
|
|
void game2_death()
|
|
{
|
|
int currentstart = 0;
|
|
int introframe = 0;
|
|
sound_voices(4);
|
|
|
|
sound_set_voice(1,"WaveSynth-Beep");
|
|
sound_set_voice(2,"WaveSynth-Beep");
|
|
sound_set_voice(3,"WaveSynth-Beep");
|
|
sound_set_voice(4,"WaveSynth-Beep");
|
|
sound_composition_init();
|
|
|
|
sound_composition_load("music.cmpagrac");
|
|
|
|
tick = clock();
|
|
|
|
sound_composition_start(clock());
|
|
|
|
draw_sprite("spacebar",(DISPLAY_X/2)-106,50);
|
|
draw_sprite("kia",(DISPLAY_X/2)-300,500);
|
|
|
|
screen_flipbuffer();
|
|
|
|
while(sound_composition_incomplete())
|
|
{
|
|
sound_composition_tick(clock());
|
|
|
|
if(clock() > (tick + 100))
|
|
{
|
|
if(input_readkey(98))
|
|
sound_composition_stop();
|
|
}
|
|
}
|
|
}
|
|
|
|
void game2_briefing()
|
|
{
|
|
screen_clear();
|
|
|
|
draw_spritetext(
|
|
"~~~~~~~~{ chief engineers log - uss archimedes - stardate 1234567890 ==}\n\n\ndo stuff on the ship. not sure what yet. go for a wander. \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n~~~~~~~~{======================~~~~~~~~===========================}"
|
|
, 50, 950);
|
|
|
|
draw_sprite("spacebar",(DISPLAY_X/2)-106,50);
|
|
|
|
screen_flipbuffer();
|
|
|
|
tick = clock();
|
|
while(1)
|
|
{
|
|
if(clock() > (tick + 100))
|
|
{
|
|
if(input_readkey(98))
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void game2_fillmap(int xoffset, int yoffset)
|
|
{
|
|
memcpy(map[0][0],fullmap+yoffset+(xoffset*100),10);
|
|
memcpy(map[0][1],fullmap+yoffset+(xoffset*100)+100,10);
|
|
memcpy(map[0][2],fullmap+yoffset+(xoffset*100)+200,10);
|
|
memcpy(map[0][3],fullmap+yoffset+(xoffset*100)+300,10);
|
|
memcpy(map[0][4],fullmap+yoffset+(xoffset*100)+400,10);
|
|
memcpy(map[0][5],fullmap+yoffset+(xoffset*100)+500,10);
|
|
memcpy(map[0][6],fullmap+yoffset+(xoffset*100)+600,10);
|
|
memcpy(map[0][7],fullmap+yoffset+(xoffset*100)+700,10);
|
|
memcpy(map[0][8],fullmap+yoffset+(xoffset*100)+800,10);
|
|
memcpy(map[0][9],fullmap+yoffset+(xoffset*100)+900,10);
|
|
}
|
|
|
|
void game2_setup()
|
|
{
|
|
screen_flipbuffer();
|
|
screen_clear();
|
|
screen_flipbuffer();
|
|
screen_clear();
|
|
|
|
TilePlayer.location.X = 125;
|
|
TilePlayer.location.Y = 125;
|
|
|
|
TilePlayer.hitbox_bl.X = 30;
|
|
TilePlayer.hitbox_bl.Y = 0;
|
|
TilePlayer.hitbox_tr.X = 60;
|
|
TilePlayer.hitbox_tr.Y = 30;
|
|
|
|
TilePlayer.drawbox_bl.X = 5;
|
|
TilePlayer.drawbox_bl.Y = 0;
|
|
TilePlayer.drawbox_tr.X = 60;
|
|
TilePlayer.drawbox_tr.Y = 75;
|
|
|
|
memset(map[0],0xFF,100);
|
|
memset(map[1],0xFF,100);
|
|
memset(map[2],0xFF,100);
|
|
|
|
game2_loadmap("m2_map");
|
|
game2_loadsmarttiles("m2_smart");
|
|
game2_fillmap(TilePlayer.mapoffset.X,TilePlayer.mapoffset.Y);
|
|
}
|
|
|
|
int game2_check_collide()
|
|
{
|
|
int x,y,hit;
|
|
|
|
hit = 0;
|
|
|
|
for(x = 0; x < TILESX; x++)
|
|
{
|
|
for(y = 0; y < TILESY; y++)
|
|
{
|
|
// Finds any tile we collide with
|
|
if(game_hitbox_collide(
|
|
(TilePlayer.location.X + TilePlayer.hitbox_bl.X),(TilePlayer.location.Y + TilePlayer.hitbox_bl.Y),
|
|
(TilePlayer.hitbox_tr.X - TilePlayer.hitbox_bl.X),(TilePlayer.hitbox_tr.Y - TilePlayer.hitbox_bl.Y),
|
|
x*100,y*100,
|
|
100,100
|
|
))
|
|
{
|
|
if(((map[0][x][y] >> 7) & 0x01))
|
|
{
|
|
hit = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hit;
|
|
}
|
|
|
|
void game2_tick_input()
|
|
{
|
|
// Store in case we have a vertical collide
|
|
TilePlayer.lastlocation.X = TilePlayer.location.X;
|
|
TilePlayer.lastlocation.Y = TilePlayer.location.Y;
|
|
TilePlayer.lastmapoffset.X = TilePlayer.mapoffset.X;
|
|
TilePlayer.lastmapoffset.Y = TilePlayer.mapoffset.Y;
|
|
|
|
// Up arrow
|
|
if(input_readkey(57))
|
|
{
|
|
TilePlayer.location.Y += 3 * (tick - lasttick);
|
|
if(TilePlayer.location.Y > (950))
|
|
{
|
|
TilePlayer.location.Y = 100;
|
|
TilePlayer.mapoffset.Y += 10;
|
|
game2_fillmap(TilePlayer.mapoffset.X,TilePlayer.mapoffset.Y);
|
|
}
|
|
}
|
|
|
|
// Down arrow
|
|
if(input_readkey(41))
|
|
{
|
|
TilePlayer.location.Y -= 3 * (tick - lasttick);
|
|
if(TilePlayer.location.Y < (10))
|
|
{
|
|
if(TilePlayer.mapoffset.Y > 0)
|
|
{
|
|
TilePlayer.location.Y = 900;
|
|
TilePlayer.mapoffset.Y -= 10;
|
|
game2_fillmap(TilePlayer.mapoffset.X,TilePlayer.mapoffset.Y);
|
|
}else{
|
|
TilePlayer.location.Y = TilePlayer.lastlocation.Y;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if(game2_check_collide())
|
|
{
|
|
TilePlayer.location.X = TilePlayer.lastlocation.X;
|
|
TilePlayer.location.Y = TilePlayer.lastlocation.Y;
|
|
TilePlayer.mapoffset.X = TilePlayer.lastmapoffset.X;
|
|
TilePlayer.mapoffset.Y = TilePlayer.lastmapoffset.Y;
|
|
}
|
|
|
|
// Store in case we have a horizontal collide
|
|
TilePlayer.lastlocation.X = TilePlayer.location.X;
|
|
TilePlayer.lastlocation.Y = TilePlayer.location.Y;
|
|
|
|
// Right arrow
|
|
if(input_readkey(121))
|
|
{
|
|
TilePlayer.location.X += 3 * (tick - lasttick);
|
|
if(TilePlayer.location.X > (930))
|
|
{
|
|
TilePlayer.location.X = 100;
|
|
TilePlayer.mapoffset.X += 10;
|
|
game2_fillmap(TilePlayer.mapoffset.X,TilePlayer.mapoffset.Y);
|
|
}
|
|
}
|
|
|
|
// Left arrow
|
|
if(input_readkey(25))
|
|
{
|
|
TilePlayer.location.X -= 3 * (tick - lasttick);
|
|
if(TilePlayer.location.X < (10))
|
|
{
|
|
if(TilePlayer.mapoffset.X > 0)
|
|
{
|
|
TilePlayer.location.X = 900;
|
|
TilePlayer.mapoffset.X -= 10;
|
|
game2_fillmap(TilePlayer.mapoffset.X,TilePlayer.mapoffset.Y);
|
|
}else{
|
|
TilePlayer.location.X = TilePlayer.lastlocation.X;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(game2_check_collide())
|
|
{
|
|
TilePlayer.location.X = TilePlayer.lastlocation.X;
|
|
TilePlayer.location.Y = TilePlayer.lastlocation.Y;
|
|
}
|
|
}
|
|
|
|
int game2_tick()
|
|
{
|
|
int x;
|
|
int y;
|
|
int i;
|
|
|
|
lasttick = tick;
|
|
tick = clock();
|
|
|
|
screen_flipbuffer();
|
|
|
|
if(1)
|
|
{
|
|
// Fill the map0 with our chunk of the full map
|
|
game2_fillmap(TilePlayer.mapoffset.X,TilePlayer.mapoffset.Y);
|
|
|
|
for(x = 0; x < TILESX; x++)
|
|
{
|
|
for(y = 0; y < TILESY; y++)
|
|
{
|
|
// Finds any tile we collide with
|
|
if(game_hitbox_collide(
|
|
(TilePlayer.location.X + TilePlayer.drawbox_bl.X),(TilePlayer.location.Y + TilePlayer.drawbox_bl.Y),
|
|
(TilePlayer.hitbox_tr.X - TilePlayer.drawbox_bl.X),(TilePlayer.drawbox_tr.Y - TilePlayer.drawbox_bl.Y),
|
|
x*100,y*100,
|
|
100,100
|
|
))
|
|
{
|
|
map[1][x][y] = 255;
|
|
map[2][x][y] = 255;
|
|
}
|
|
|
|
// Find the tile under our centre of mass
|
|
if(game_hitbox_collide(
|
|
(TilePlayer.location.X + TilePlayer.hitbox_bl.X + (TilePlayer.hitbox_tr.X/2)),(TilePlayer.location.Y + TilePlayer.hitbox_bl.Y + (TilePlayer.hitbox_tr.Y/2)),
|
|
(1),(1),
|
|
x*100,y*100,
|
|
100,100
|
|
))
|
|
{
|
|
TilePlayer.localtile.X = x;
|
|
TilePlayer.localtile.Y = y;
|
|
}
|
|
|
|
// Redraw any tiles we're overlapping
|
|
if(map[0][x][y] ^ map[screen+1][x][y])
|
|
{
|
|
map[screen+1][x][y] = map[0][x][y];
|
|
if(map[screen+1][x][y] < 128)
|
|
sprintf(tilenamebuffer,"%i",map[screen+1][x][y]);
|
|
else
|
|
sprintf(tilenamebuffer,"%i",(map[screen+1][x][y]-128));
|
|
|
|
draw_tile(tilenamebuffer,x*100,y*100);
|
|
}
|
|
}
|
|
}
|
|
|
|
TilePlayer.rawtile = (TilePlayer.mapoffset.Y) + TilePlayer.localtile.Y + (TilePlayer.mapoffset.X * 100) + (TilePlayer.localtile.X * 100);
|
|
|
|
// Trigger any smart tiles for our centre of mass
|
|
for(i = 0; i < SMARTTILES; i++)
|
|
{
|
|
if(SmartTiles[i].Tile == TilePlayer.rawtile)
|
|
{
|
|
// Change tile sprite
|
|
if(SmartTiles[i].Action == 0)
|
|
fullmap[SmartTiles[i].ActionTarget] = SmartTiles[i].ActionValue;
|
|
}
|
|
}
|
|
|
|
game2_tick_input();
|
|
|
|
draw_sprite("man",TilePlayer.location.X,TilePlayer.location.Y);
|
|
|
|
#ifdef M2_DEBUG_HITBOXES
|
|
draw_rectangle(
|
|
(TilePlayer.location.X + TilePlayer.hitbox_bl.X),
|
|
(TilePlayer.location.Y + TilePlayer.hitbox_bl.Y),
|
|
(TilePlayer.location.X + TilePlayer.hitbox_tr.X),
|
|
(TilePlayer.location.Y + TilePlayer.hitbox_tr.Y)
|
|
);
|
|
draw_rectangle(
|
|
(TilePlayer.location.X + TilePlayer.drawbox_bl.X),
|
|
(TilePlayer.location.Y + TilePlayer.drawbox_bl.Y),
|
|
(TilePlayer.location.X + TilePlayer.drawbox_tr.X),
|
|
(TilePlayer.location.Y + TilePlayer.drawbox_tr.Y)
|
|
);
|
|
#endif
|
|
return 0;
|
|
}else{
|
|
/* screen_flipbuffer();
|
|
screen_clear();
|
|
game2_death();
|
|
return 1;*/
|
|
}
|
|
}
|