mirror of
https://github.com/stevenhowes/CTheEscape.git
synced 2026-05-27 00:03:27 +01:00
879 lines
23 KiB
C
879 lines
23 KiB
C
#include "Graphics.h"
|
|
#include "swis.h"
|
|
#include <kernel.h>
|
|
#include "Sound.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 200
|
|
#define AREAS 20
|
|
|
|
#define MAXEVENTS 200
|
|
#define MAXEVENTACTIONS 1000
|
|
|
|
// 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)
|
|
// _overlay is used for the second layer on of tiles (optional)
|
|
unsigned char map[3][TILESX][TILESY];
|
|
unsigned char map_overlay[3][TILESX][TILESY];
|
|
|
|
unsigned char fullmap[10000*2];
|
|
|
|
unsigned char areaname[13];
|
|
|
|
char textbuffer[63];
|
|
|
|
struct EntityLocation_s {
|
|
short signed int X,Y;
|
|
};
|
|
|
|
struct Area_s {
|
|
unsigned char name[16];
|
|
};
|
|
|
|
struct Area_s Areas[AREAS];
|
|
|
|
#define DIRECTION_NONE 0
|
|
#define DIRECTION_N 0
|
|
#define DIRECTION_E 1
|
|
#define DIRECTION_S 2
|
|
#define DIRECTION_W 3
|
|
|
|
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;
|
|
int lastrawtile;
|
|
|
|
unsigned char direction;
|
|
unsigned char facedirection;
|
|
unsigned char sprite[13];
|
|
unsigned char basesprite[13];
|
|
unsigned char animframe;
|
|
int nextanimframe;
|
|
int nextanimidle;
|
|
};
|
|
|
|
struct TilePlayer_s TilePlayer;
|
|
|
|
/* VVV deprecated VVV */
|
|
struct SmartTile_s {
|
|
int Tile;
|
|
int ActionTarget;
|
|
unsigned char Action;
|
|
unsigned char ActionValue;
|
|
};
|
|
struct SmartTile_s SmartTiles[SMARTTILES];
|
|
/* ^^^ deprecated ^^^ */
|
|
|
|
|
|
struct EventAction_s {
|
|
int Event;
|
|
unsigned char Action; //0=change tile / 1=change area / 2=sound / 3=rearm / 4=schedule
|
|
unsigned char ActionValue; //tile sprite no. / area ID / sound ID / na / eventid
|
|
int ActionTarget; //tile ID / n/a / channel ID / eventid / ticks
|
|
};
|
|
struct EventAction_s EventActions[MAXEVENTACTIONS];
|
|
|
|
struct Event_s {
|
|
unsigned char Name[16];
|
|
unsigned char Triggered;
|
|
int RearmDelay;
|
|
int NextRearm;
|
|
};
|
|
struct Event_s Events[MAXEVENTS];
|
|
|
|
struct ScheduledEvent_s {
|
|
int Event;
|
|
int Ticks;
|
|
};
|
|
struct ScheduledEvent_s ScheduledEvents[MAXEVENTS];
|
|
|
|
|
|
void game2_saveevents(char* filename)
|
|
{
|
|
// Attempt to get file info
|
|
inreg.r[0] = 10;
|
|
inreg.r[1] = (int) filename;
|
|
inreg.r[2] = 0xffd;
|
|
inreg.r[4] = (int) Events;
|
|
inreg.r[5] = (int) Events + (sizeof(Events));
|
|
|
|
_kernel_swi(OS_File,&inreg,&outreg);
|
|
}
|
|
void game2_saveeventactions(char* filename)
|
|
{
|
|
// Attempt to get file info
|
|
inreg.r[0] = 10;
|
|
inreg.r[1] = (int) filename;
|
|
inreg.r[2] = 0xffd;
|
|
inreg.r[4] = (int) EventActions;
|
|
inreg.r[5] = (int) EventActions + (sizeof(EventActions));
|
|
|
|
_kernel_swi(OS_File,&inreg,&outreg);
|
|
}
|
|
|
|
void game2_loadevents(char* filename)
|
|
{
|
|
int length;
|
|
int i;
|
|
|
|
// Populate with inactive entries
|
|
for(i = 0; i<MAXEVENTS; i++)
|
|
{
|
|
// Default to Triggered with no re-arm so event never fires
|
|
sprintf(Events[i].Name,"INVALID");
|
|
Events[i].Triggered = 1;
|
|
Events[i].RearmDelay = -1;
|
|
Events[i].NextRearm = -1;
|
|
|
|
// We can populate these here as we use MAXEVENTS for both
|
|
ScheduledEvents[i].Event = -1;
|
|
ScheduledEvents[i].Ticks = -1;
|
|
}
|
|
|
|
// 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(Events))
|
|
{
|
|
screen_nobuffer();
|
|
while (1)
|
|
printf("Events exceeds %d bytes (%d bytes) object type is %d\n",sizeof(Events),length,outreg.r[0]);
|
|
}
|
|
|
|
// Attempt to get file info
|
|
inreg.r[0] = 16;
|
|
inreg.r[1] = (int) filename;
|
|
inreg.r[2] = (int) Events;
|
|
inreg.r[3] = 0;
|
|
|
|
_kernel_swi(OS_File,&inreg,&outreg);
|
|
}
|
|
|
|
void game2_loadeventactionss(char* filename)
|
|
{
|
|
int length;
|
|
int i;
|
|
|
|
// Populate with inactive entries
|
|
for(i = 0; i<MAXEVENTACTIONS; i++)
|
|
{
|
|
EventActions[i].Event = -1;
|
|
EventActions[i].Action = -1;
|
|
EventActions[i].ActionValue = -1;
|
|
EventActions[i].ActionTarget = -1;
|
|
}
|
|
|
|
// 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(EventActions))
|
|
{
|
|
screen_nobuffer();
|
|
while (1)
|
|
printf("EventActions exceeds %d bytes (%d bytes) object type is %d\n",sizeof(EventActions),length,outreg.r[0]);
|
|
}
|
|
|
|
// Attempt to get file info
|
|
inreg.r[0] = 16;
|
|
inreg.r[1] = (int) filename;
|
|
inreg.r[2] = (int) EventActions;
|
|
inreg.r[3] = 0;
|
|
|
|
_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]);
|
|
}
|
|
|
|
// 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_loadareanames(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(Areas))
|
|
{
|
|
screen_nobuffer();
|
|
while (1)
|
|
printf("Areas exceeds %d bytes (%d bytes) object type is %d\n",sizeof(Areas),length,outreg.r[0]);
|
|
}
|
|
|
|
// Attempt to get file info
|
|
inreg.r[0] = 16;
|
|
inreg.r[1] = (int) filename;
|
|
inreg.r[2] = (int) Areas;
|
|
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();
|
|
while(1)
|
|
printf("Map exceeds %d bytes (%d bytes) object type is %d\n",sizeof(fullmap),length,outreg.r[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_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);
|
|
|
|
memcpy(map_overlay[0][0],fullmap+yoffset+(xoffset*100)+10000,10);
|
|
memcpy(map_overlay[0][1],fullmap+yoffset+(xoffset*100)+100+10000,10);
|
|
memcpy(map_overlay[0][2],fullmap+yoffset+(xoffset*100)+200+10000,10);
|
|
memcpy(map_overlay[0][3],fullmap+yoffset+(xoffset*100)+300+10000,10);
|
|
memcpy(map_overlay[0][4],fullmap+yoffset+(xoffset*100)+400+10000,10);
|
|
memcpy(map_overlay[0][5],fullmap+yoffset+(xoffset*100)+500+10000,10);
|
|
memcpy(map_overlay[0][6],fullmap+yoffset+(xoffset*100)+600+10000,10);
|
|
memcpy(map_overlay[0][7],fullmap+yoffset+(xoffset*100)+700+10000,10);
|
|
memcpy(map_overlay[0][8],fullmap+yoffset+(xoffset*100)+800+10000,10);
|
|
memcpy(map_overlay[0][9],fullmap+yoffset+(xoffset*100)+900+10000,10);
|
|
}
|
|
|
|
void game2_setup_audio()
|
|
{
|
|
sound_pcm_loadsample(PCMSAMPLE_HAIL,"sounds.commbdg");
|
|
sound_pcm_loadsample(PCMSAMPLE_DOOR,"sounds.door");
|
|
sound_pcm_loadsample(PCMSAMPLE_ALERT,"sounds.alert");
|
|
sound_pcm_loadsample(PCMSAMPLE_TRACTOREND,"sounds.tracend");
|
|
sound_pcm_loadsample(PCMSAMPLE_TRANSPORTER,"sounds.transp");
|
|
}
|
|
|
|
void game2_setup()
|
|
{
|
|
screen_flipbuffer();
|
|
screen_clear();
|
|
screen_flipbuffer();
|
|
screen_clear();
|
|
|
|
TilePlayer.location.X = 102;
|
|
TilePlayer.location.Y = 102;
|
|
|
|
TilePlayer.hitbox_bl.X = 10;
|
|
TilePlayer.hitbox_bl.Y = 10;
|
|
TilePlayer.hitbox_tr.X = 70;
|
|
TilePlayer.hitbox_tr.Y = 70;
|
|
|
|
TilePlayer.drawbox_bl.X = 0;
|
|
TilePlayer.drawbox_bl.Y = 0;
|
|
TilePlayer.drawbox_tr.X = 80;
|
|
TilePlayer.drawbox_tr.Y = 80;
|
|
|
|
TilePlayer.direction = DIRECTION_NONE;
|
|
TilePlayer.facedirection = 1;
|
|
TilePlayer.animframe = 0;
|
|
TilePlayer.nextanimframe = 0;
|
|
TilePlayer.nextanimidle = 0;
|
|
TilePlayer.lastrawtile = -1;
|
|
memset(map[0],0xFF,100);
|
|
memset(map[1],0xFF,100);
|
|
memset(map[2],0xFF,100);
|
|
|
|
game2_loadmap("m2_map");
|
|
game2_loadsmarttiles("m2_smart");
|
|
game2_loadareanames("m2_areas");
|
|
game2_setup_audio();
|
|
game2_loadevents("m2_evt");
|
|
game2_loadeventactionss("m2_evact");
|
|
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()
|
|
{
|
|
int movex = 0;
|
|
int movey = 0;
|
|
|
|
TilePlayer.direction = 0;
|
|
|
|
if(input_readkey(57)) // UP
|
|
TilePlayer.direction |= 1 << DIRECTION_N;
|
|
if(input_readkey(41)) // DOWN
|
|
TilePlayer.direction |= 1 << DIRECTION_S;
|
|
if(input_readkey(121)) // RIGHT
|
|
TilePlayer.direction |= 1 << DIRECTION_E;
|
|
if(input_readkey(25)) // LEFT
|
|
TilePlayer.direction |= 1 << DIRECTION_W;
|
|
|
|
// If Up & Down then cancel both
|
|
if((TilePlayer.direction & (1 << DIRECTION_N)) && (TilePlayer.direction & (1 << DIRECTION_S)))
|
|
TilePlayer.direction -= 5;
|
|
// If Left & Right then cancel both
|
|
if((TilePlayer.direction & (1 << DIRECTION_E)) && (TilePlayer.direction & (1 << DIRECTION_W)))
|
|
TilePlayer.direction -= 10;
|
|
|
|
// If N
|
|
if(TilePlayer.direction & (1 << DIRECTION_N))
|
|
movey += 3;
|
|
// If S
|
|
if(TilePlayer.direction & (1 << DIRECTION_S))
|
|
movey -= 3;
|
|
// If W
|
|
if(TilePlayer.direction & (1 << DIRECTION_W))
|
|
movex -= 3;
|
|
// If E
|
|
if(TilePlayer.direction & (1 << DIRECTION_E))
|
|
movex += 3;
|
|
|
|
// Handle diagonals by reducing to sin(45) * 3 (conveniently about 2)
|
|
if((movex == 3) && (movey == 3)) // NE
|
|
{
|
|
movex = 2;
|
|
movey = 2;
|
|
}else if((movex == 3) && (movey == -3)) // SW
|
|
{
|
|
movex = 2;
|
|
movey = -2;
|
|
}else if((movex == -3) && (movey == 3)) // NW
|
|
{
|
|
movex = -2;
|
|
movey = 3;
|
|
}else if((movex == -3) && (movey == -3)) // SE
|
|
{
|
|
movex = -2;
|
|
movey = -2;
|
|
}
|
|
|
|
// Store the last movement so we know where to face an idle player
|
|
if(TilePlayer.direction > 0)
|
|
{
|
|
TilePlayer.facedirection = TilePlayer.direction;
|
|
if(tick > TilePlayer.nextanimframe)
|
|
{
|
|
TilePlayer.animframe++;
|
|
TilePlayer.nextanimframe = tick + 10;
|
|
TilePlayer.nextanimidle = tick + 20;
|
|
}
|
|
if(TilePlayer.animframe > 3)
|
|
TilePlayer.animframe = 0;
|
|
}else{
|
|
if(tick > TilePlayer.nextanimidle)
|
|
TilePlayer.animframe = 0;
|
|
}
|
|
|
|
// 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;
|
|
|
|
if(movey > 0)
|
|
{
|
|
TilePlayer.location.Y += movey * (tick - lasttick);
|
|
if(TilePlayer.location.Y > (910))
|
|
{
|
|
TilePlayer.location.Y = 100;
|
|
TilePlayer.mapoffset.Y += 10;
|
|
game2_fillmap(TilePlayer.mapoffset.X,TilePlayer.mapoffset.Y);
|
|
}
|
|
}
|
|
else if(movey < 0)
|
|
{
|
|
TilePlayer.location.Y += movey * (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;
|
|
|
|
if(movex > 0)
|
|
{
|
|
TilePlayer.location.X += movex * (tick - lasttick);
|
|
if(TilePlayer.location.X > (910))
|
|
{
|
|
TilePlayer.location.X = 100;
|
|
TilePlayer.mapoffset.X += 10;
|
|
game2_fillmap(TilePlayer.mapoffset.X,TilePlayer.mapoffset.Y);
|
|
}
|
|
}
|
|
else if(movex < 0)
|
|
{
|
|
TilePlayer.location.X += movex * (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_newevent()
|
|
{
|
|
int i;
|
|
int freeid = -1;
|
|
|
|
for(i = 0; i<MAXEVENTS; i++)
|
|
{
|
|
if(ScheduledEvents[i].Event < 0)
|
|
{
|
|
freeid = i;
|
|
i = MAXEVENTS;
|
|
}
|
|
}
|
|
|
|
if(freeid < 0)
|
|
{
|
|
while(1)
|
|
printf("No free slots in event scheduler!\n");
|
|
}
|
|
|
|
return freeid;
|
|
}
|
|
|
|
void game2_triggerevent(int id)
|
|
{
|
|
int i;
|
|
|
|
// Re-arm if appropriate
|
|
if(Events[id].NextRearm > 0)
|
|
{
|
|
if(tick > Events[id].NextRearm)
|
|
{
|
|
Events[id].Triggered = 0;
|
|
Events[id].NextRearm = -1;
|
|
}
|
|
}
|
|
|
|
// Don't trigger if we've been fired and not reset
|
|
if(Events[id].Triggered == 1)
|
|
return;
|
|
|
|
// Record firing
|
|
Events[id].Triggered = 1;
|
|
|
|
// Schedule re-arm if required
|
|
if(Events[id].RearmDelay >= 0)
|
|
Events[id].NextRearm = tick + Events[id].RearmDelay;
|
|
|
|
// Go through our actions
|
|
for(i = 0; i<MAXEVENTACTIONS; i++)
|
|
{
|
|
if(EventActions[i].Event == id)
|
|
{
|
|
if(EventActions[i].Action == 0) // Change tile sprite
|
|
fullmap[EventActions[i].ActionTarget] = EventActions[i].ActionValue;
|
|
else if(EventActions[i].Action == 1) // Change area name
|
|
sprintf(areaname,"%s",Areas[EventActions[i].ActionValue].name);
|
|
else if(EventActions[i].Action == 2) // Play sound
|
|
if(EventActions[i].ActionTarget == PCMCHANNEL_PLAYER)
|
|
sound_pcm_playsample(EventActions[i].ActionTarget,EventActions[i].ActionValue);
|
|
else
|
|
sound_pcm_playsample_ifidle(EventActions[i].ActionTarget,EventActions[i].ActionValue);
|
|
else if(EventActions[i].Action == 3) // Re-arm
|
|
Events[EventActions[i].ActionTarget].Triggered = 0;
|
|
else if(EventActions[i].Action == 4) // Schedule Event
|
|
{
|
|
int scheduleid = game2_newevent();
|
|
ScheduledEvents[scheduleid].Event = EventActions[i].ActionValue;
|
|
ScheduledEvents[scheduleid].Ticks = tick + EventActions[i].ActionTarget;
|
|
}
|
|
else if(EventActions[i].Action == 5) // Change overlay tile sprite
|
|
fullmap[EventActions[i].ActionTarget + 10000] = EventActions[i].ActionValue;
|
|
else if(EventActions[i].Action == 6) // Dis-arm
|
|
Events[EventActions[i].ActionTarget].Triggered = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void game2_triggerscheduledevents()
|
|
{
|
|
int i;
|
|
for(i = 0; i<MAXEVENTS; i++)
|
|
{
|
|
if(ScheduledEvents[i].Event > 0)
|
|
{
|
|
if(tick > ScheduledEvents[i].Ticks)
|
|
{
|
|
// Trigger the event
|
|
game2_triggerevent(ScheduledEvents[i].Event);
|
|
|
|
// Clear it
|
|
ScheduledEvents[i].Event = -1;
|
|
ScheduledEvents[i].Ticks = -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int game2_tick()
|
|
{
|
|
int x;
|
|
int y;
|
|
int i;
|
|
char flipv = 0;
|
|
char fliph = 0;
|
|
|
|
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);
|
|
|
|
draw_spritetext("#############", 1020, 950);
|
|
draw_spritetext(areaname, 1020, 950);
|
|
|
|
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_overlay[0][x][y] ^ map_overlay[screen+1][x][y]))
|
|
{
|
|
map[screen+1][x][y] = map[0][x][y];
|
|
if(map[screen+1][x][y] < 128)
|
|
draw_tile(map[screen+1][x][y],x*100,y*100);
|
|
else
|
|
draw_tile((map[screen+1][x][y]-128),x*100,y*100);
|
|
|
|
map_overlay[screen+1][x][y] = map_overlay[0][x][y];
|
|
if(map_overlay[screen+1][x][y] > 0)
|
|
{
|
|
draw_tile_trans(map_overlay[screen+1][x][y],x*100,y*100);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TilePlayer.lastrawtile = TilePlayer.rawtile;
|
|
TilePlayer.rawtile = (TilePlayer.mapoffset.Y) + TilePlayer.localtile.Y + (TilePlayer.mapoffset.X * 100) + (TilePlayer.localtile.X * 100);
|
|
|
|
if(TilePlayer.rawtile != TilePlayer.lastrawtile)
|
|
{
|
|
// Trigger any smart tiles for our centre of mass
|
|
for(i = 0; i < SMARTTILES; i++)
|
|
{
|
|
if(SmartTiles[i].Tile == TilePlayer.rawtile)
|
|
{
|
|
if(SmartTiles[i].Action == 2) // Trigger event
|
|
game2_triggerevent(SmartTiles[i].ActionValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
game2_triggerscheduledevents();
|
|
|
|
game2_tick_input();
|
|
|
|
if((TilePlayer.facedirection & (1 << DIRECTION_N)) && (TilePlayer.facedirection & (1 << DIRECTION_E))) //NE
|
|
{
|
|
fliph = 1;
|
|
sprintf(TilePlayer.basesprite, "man_se");
|
|
}else if((TilePlayer.facedirection & (1 << DIRECTION_S)) && (TilePlayer.facedirection & (1 << DIRECTION_E))) // SE
|
|
{
|
|
sprintf(TilePlayer.basesprite, "man_se");
|
|
}else if((TilePlayer.facedirection & (1 << DIRECTION_S)) && (TilePlayer.facedirection & (1 << DIRECTION_W))) // SW
|
|
{
|
|
flipv = 1;
|
|
sprintf(TilePlayer.basesprite, "man_se");
|
|
}else if((TilePlayer.facedirection & (1 << DIRECTION_N)) && (TilePlayer.facedirection & (1 << DIRECTION_W))) // NW
|
|
{
|
|
flipv = 1;
|
|
fliph = 1;
|
|
sprintf(TilePlayer.basesprite, "man_se");
|
|
}else if(TilePlayer.facedirection & (1 << DIRECTION_N)) // N
|
|
{
|
|
fliph = 1;
|
|
sprintf(TilePlayer.basesprite, "man_s");
|
|
}else if(TilePlayer.facedirection & (1 << DIRECTION_S)) // S
|
|
{
|
|
sprintf(TilePlayer.basesprite, "man_s");
|
|
}else if(TilePlayer.facedirection & (1 << DIRECTION_E)) // E
|
|
{
|
|
sprintf(TilePlayer.basesprite, "man_e");
|
|
}else if(TilePlayer.facedirection & (1 << DIRECTION_W)) // W
|
|
{
|
|
flipv = 1;
|
|
sprintf(TilePlayer.basesprite, "man_e");
|
|
}
|
|
|
|
if(TilePlayer.animframe == 0)
|
|
sprintf(TilePlayer.sprite, "%s",TilePlayer.basesprite);
|
|
if(TilePlayer.animframe == 1)
|
|
sprintf(TilePlayer.sprite, "%s_l",TilePlayer.basesprite);
|
|
if(TilePlayer.animframe == 2)
|
|
sprintf(TilePlayer.sprite, "%s",TilePlayer.basesprite);
|
|
if(TilePlayer.animframe == 3)
|
|
{
|
|
// Use 'right' for diagonals, otherwise we flip
|
|
if(strlen(TilePlayer.basesprite) > 5)
|
|
{
|
|
sprintf(TilePlayer.sprite, "%s_r",TilePlayer.basesprite);
|
|
}
|
|
else
|
|
{
|
|
if((TilePlayer.facedirection & (1 << DIRECTION_N)) || (TilePlayer.facedirection & (1 << DIRECTION_S)))
|
|
flipv = 1;
|
|
if((TilePlayer.facedirection & (1 << DIRECTION_E)) || (TilePlayer.facedirection & (1 << DIRECTION_W)))
|
|
fliph = 1;
|
|
sprintf(TilePlayer.sprite, "%s_l",TilePlayer.basesprite);
|
|
}
|
|
}
|
|
|
|
if(fliph && flipv)
|
|
draw_sprite_flippedhv(TilePlayer.sprite,TilePlayer.location.X,TilePlayer.location.Y);
|
|
else if(fliph)
|
|
draw_sprite_flippedh(TilePlayer.sprite,TilePlayer.location.X,TilePlayer.location.Y);
|
|
else if(flipv)
|
|
draw_sprite_flippedv(TilePlayer.sprite,TilePlayer.location.X,TilePlayer.location.Y);
|
|
else
|
|
draw_sprite(TilePlayer.sprite,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;*/
|
|
}
|
|
}
|