#include #include "swis.h" #include #include #include "Sound.h" #include "Graphics.h" /********************************************\ Slightly hacked up 'Mission2' as a map editor \********************************************/ extern int tick; extern int lasttick; extern int screen; #define TILESX 10 #define TILESY 10 #define SMARTTILES 200 #define AREAS 20 // SWI Registers _kernel_swi_regs inreg; _kernel_swi_regs outreg; // Sprite buffer unsigned char *buffer; unsigned char *fontbuffer; unsigned char *tilebuffer; int tick = 0; int lasttick = 0; extern int screen; int clipboard = 0; int clipboard_tileid = 0; extern void screen_nobuffer(); unsigned int editsmart = 0; int selectedsmart = -1; // 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; }; int readmodkey = 0; struct TilePlayer_s { struct EntityLocation_s location; struct EntityLocation_s hitbox_bl; struct EntityLocation_s hitbox_tr; struct EntityLocation_s mapoffset; 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]; struct Area_s { unsigned char name[16]; }; struct Area_s Areas[AREAS]; #define ACTION_SIZE 16 char actionnames[][ACTION_SIZE] = { "TileSet", "AreaChange" }; 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_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]); //exit(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_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); } int game2_getnewsmarttile() { int i; for(i = 0; i < SMARTTILES; i++) { if(SmartTiles[i].Tile == -1) { SmartTiles[i].Tile = TilePlayer.rawtile; SmartTiles[i].Action = 0; SmartTiles[i].ActionValue = 0; return i; } } screen_nobuffer(); printf("Couldn't allocate new spart tile."); exit(0); return -1; } void game2_loadmap(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(fullmap)) { screen_nobuffer(); printf("Map exceeds %d bytes (%d bytes) object type is %d",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); } void game2_savemap(char* filename) { // Attempt to get file info inreg.r[0] = 10; inreg.r[1] = (int) filename; inreg.r[2] = 0xffd; inreg.r[4] = (int) fullmap; inreg.r[5] = (int) fullmap + sizeof(fullmap); _kernel_swi(OS_File,&inreg,&outreg); } 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 = 50; TilePlayer.location.Y = 50; TilePlayer.hitbox_bl.X = 0; TilePlayer.hitbox_bl.Y = 0; TilePlayer.hitbox_tr.X = 60; TilePlayer.hitbox_tr.Y = 50; 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_fillmap(TilePlayer.mapoffset.X,TilePlayer.mapoffset.Y); } void game2_tick_input() { int x,y; int oldselectedsmart; int i,tmptileid; oldselectedsmart = selectedsmart; if(editsmart == 1) { // Right arrow if(input_readkey(121)) { if(tick > readmodkey) { SmartTiles[selectedsmart].Action++; if(SmartTiles[selectedsmart].Action > 1) SmartTiles[selectedsmart].Action = 1; readmodkey = tick + 20; } } // Left arrow if(input_readkey(25)) { if(tick > readmodkey) { SmartTiles[selectedsmart].Action--; // Looks weird, but unsigned so -1 is 255 if(SmartTiles[selectedsmart].Action > 1) SmartTiles[selectedsmart].Action = 0; readmodkey = tick + 20; } } // Up arrow if(input_readkey(57)) { if(tick > readmodkey) { selectedsmart--; while(SmartTiles[selectedsmart].Tile != SmartTiles[oldselectedsmart].Tile) { if(selectedsmart > 0) selectedsmart--; else selectedsmart = oldselectedsmart; } readmodkey = tick + 20; } } // Down arrow if(input_readkey(41)) { if(tick > readmodkey) { selectedsmart++; while(SmartTiles[selectedsmart].Tile != SmartTiles[oldselectedsmart].Tile) { if(selectedsmart < SMARTTILES) selectedsmart++; else selectedsmart = oldselectedsmart; } readmodkey = tick + 20; } } // > - next tile if(input_readkey(103)) { if(tick > readmodkey) { if(SmartTiles[selectedsmart].Action == 0) SmartTiles[selectedsmart].ActionValue++; if(SmartTiles[selectedsmart].Action == 1) SmartTiles[selectedsmart].ActionValue++; readmodkey = tick + 10; } } // < - previous tile if(input_readkey(102)) { if(tick > readmodkey) { if(SmartTiles[selectedsmart].Action == 0) SmartTiles[selectedsmart].ActionValue--; if(SmartTiles[selectedsmart].Action == 1) SmartTiles[selectedsmart].ActionValue--; readmodkey = tick + 10; } } // D - Delete SmartTile if(input_readkey(50)) { if(tick > readmodkey) { SmartTiles[selectedsmart].Tile = -1; readmodkey = tick + 50; } } // C - Create smart tile if(input_readkey(82)) { if(tick > readmodkey) { game2_getnewsmarttile(); readmodkey = tick + 10; } } // P - Set Target if(input_readkey(55)) { if(tick > readmodkey) { if(SmartTiles[selectedsmart].Action == 0) SmartTiles[selectedsmart].ActionTarget = clipboard_tileid; readmodkey = tick + 10; } } }else{ // Right arrow if(input_readkey(121)) { if(tick > readmodkey) { TilePlayer.location.X += 100; if(TilePlayer.location.X > (950)) { TilePlayer.location.X = 50; TilePlayer.mapoffset.X += 10; } readmodkey = tick + 10; } } // Left arrow if(input_readkey(25)) { if(tick > readmodkey) { TilePlayer.location.X -= 100; if(TilePlayer.location.X < (10)) { if(TilePlayer.mapoffset.X > 0) { TilePlayer.location.X = 950; TilePlayer.mapoffset.X -= 10; }else{ TilePlayer.location.X += 100; } } readmodkey = tick + 10; } } // Up arrow if(input_readkey(57)) { if(tick > readmodkey) { TilePlayer.location.Y += 100; if(TilePlayer.location.Y > (950)) { TilePlayer.location.Y = 50; TilePlayer.mapoffset.Y += 10; } readmodkey = tick + 10; } } // Down arrow if(input_readkey(41)) { if(tick > readmodkey) { TilePlayer.location.Y -= 100; if(TilePlayer.location.Y < (10)) { if(TilePlayer.mapoffset.Y > 0) { TilePlayer.location.Y = 950; TilePlayer.mapoffset.Y -= 10; }else{ TilePlayer.location.Y += 100; } } readmodkey = tick + 10; } } // > - next tile if(input_readkey(103)) { if(tick > readmodkey) { fullmap[TilePlayer.rawtile] = fullmap[TilePlayer.rawtile] + 1; readmodkey = tick + 10; } } // < - previous tile if(input_readkey(102)) { if(tick > readmodkey) { fullmap[TilePlayer.rawtile] = fullmap[TilePlayer.rawtile] - 1; readmodkey = tick + 10; } } // C - Copy tile if(input_readkey(82)) { if(tick > readmodkey) { clipboard = fullmap[TilePlayer.rawtile]; clipboard_tileid = TilePlayer.rawtile; readmodkey = tick + 10; } } // P - Paste tile if(input_readkey(55)) { if(tick > readmodkey) { fullmap[TilePlayer.rawtile] = clipboard; for(i = 0; i < SMARTTILES; i++) { if(SmartTiles[i].Tile == clipboard_tileid) { tmptileid = game2_getnewsmarttile(); if(tmptileid > -1) { SmartTiles[tmptileid].ActionTarget = SmartTiles[i].ActionTarget; SmartTiles[tmptileid].Action = SmartTiles[i].Action; SmartTiles[tmptileid].ActionValue = SmartTiles[i].ActionValue; } } } readmodkey = tick + 10; } } } // S - Save if(input_readkey(81)) { game2_savemap("m2_map"); game2_savesmarttiles("m2_smart"); } // H - Toggle 'hard' on a tile if(input_readkey(84)) { if(tick > readmodkey) { fullmap[TilePlayer.rawtile] = fullmap[TilePlayer.rawtile] ^ 128; readmodkey = tick + 10; } } // T - Toggle Smart Tile (trigger) editor if(input_readkey(35)) { if(tick > readmodkey) { editsmart = !editsmart; readmodkey = tick + 50; } } } int game2_tick() { int x; int y; int i; int udt = 0; int smarty = 0; lasttick = tick; tick = clock(); screen_flipbuffer(); if(1) { screen_clear(); game2_fillmap(TilePlayer.mapoffset.X,TilePlayer.mapoffset.Y); for(x = 0; x < TILESX; x++) { for(y = 0; y < TILESY; y++) { if(1/*map[0][x][y] ^ map[screen+1][x][y]*/) { map[screen+1][x][y] = map[0][x][y]; sprintf(tilenamebuffer,"%i",map[screen+1][x][y] & 127); draw_tile(tilenamebuffer,x*100,y*100); if(((map[screen+1][x][y] >> 7) & 0x01)) { draw_sprite("solid",x*100,y*100); } udt++; } if(game_hitbox_collide( (TilePlayer.location.X),(TilePlayer.location.Y), 1,1, x*100,y*100, 100,100 )) { map[1][x][y] = 255; map[2][x][y] = 255; TilePlayer.localtile.X = x; TilePlayer.localtile.Y = y; draw_sprite("select1",x*100,y*100); } } } draw_sprite("commspanel",1000,DISPLAY_Y-164); TilePlayer.rawtile = (TilePlayer.mapoffset.Y) + TilePlayer.localtile.Y + (TilePlayer.mapoffset.X * 100) + (TilePlayer.localtile.X * 100); if(editsmart == 1) { // If our selected smart tile isn't one we're stood on then reset if(SmartTiles[selectedsmart].Tile != TilePlayer.rawtile) selectedsmart = -1; for(i = 0; i < SMARTTILES; i++) { if(SmartTiles[i].Tile == TilePlayer.rawtile) { // If we dont have a selected one, then use the first one we hit if(selectedsmart == -1) selectedsmart = i; draw_sprite("smart",TilePlayer.localtile.X*100,TilePlayer.localtile.Y*100); smarty++; if(selectedsmart == i) { sprintf(textbuffer,"} %i",SmartTiles[i].ActionTarget); draw_spritetext(textbuffer, 150, 1000 - (smarty*120)); } else { sprintf(textbuffer,"] %i",SmartTiles[i].ActionTarget); draw_spritetext(textbuffer, 150, 1000 - (smarty*120)); } sprintf(textbuffer,"%s",actionnames[SmartTiles[i].Action]); draw_spritetext(textbuffer, 300, 1000 - (smarty*120)); if(SmartTiles[i].Action == 0) { sprintf(tilenamebuffer,"%i",SmartTiles[i].ActionValue); draw_tile(tilenamebuffer,600,1000 - (smarty*120) - 25); }else if(SmartTiles[i].Action == 1) { sprintf(textbuffer,"%s",Areas[SmartTiles[i].ActionValue].name); draw_spritetext(textbuffer,600,1000 - (smarty*120)); } } } // If no smart tiles then say if(smarty == 0) { smarty++; sprintf(textbuffer,"No Smart Tiles"); draw_spritetext(textbuffer, 150, 1000 - (smarty*120)); } }else{ // Just a simple highlight if we've not got the smart edit being shown for(i = 0; i < SMARTTILES; i++) { if(SmartTiles[i].Tile == TilePlayer.rawtile) draw_sprite("smart",TilePlayer.localtile.X*100,TilePlayer.localtile.Y*100); } } sprintf(textbuffer,"Tile:%i\nSprite:%i\nSolid: %i", TilePlayer.rawtile, fullmap[TilePlayer.rawtile], ((fullmap[TilePlayer.rawtile] >> 7) & 0x01) ); draw_spritetext(textbuffer, 1070, 950); game2_tick_input(); x = 1100; y = 600; for(i = (fullmap[TilePlayer.rawtile] - 3); i <= (fullmap[TilePlayer.rawtile] + 3); i++) { if((i >=0) && (i <= 255)) { sprintf(tilenamebuffer,"%i",i); draw_tile(tilenamebuffer,x,y); sprintf(textbuffer,"%d",i); draw_spritetext(textbuffer, x-60, y+30); if(i == fullmap[TilePlayer.rawtile]) draw_sprite("select1",x,y); } y = y - 100; } x = 1180; y = 750; sprintf(tilenamebuffer,"%i",clipboard); draw_tile(tilenamebuffer,x,y); draw_sprite("select1",x,y); sprintf(tilenamebuffer,"%i",clipboard_tileid); draw_spritetext(tilenamebuffer, x+10, y+30); draw_spritetext("Clipboard", x-174, y+30); return 0; }else{ /* screen_flipbuffer(); screen_clear(); game2_death(); return 1;*/ } } int game_hitbox_collide(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) { if((x1 + w1) >= x2) if(x1 <= (x2 + w2)) if((y1 + h1) >= y2) if(y1 <= (y2 + h2)) return 1; return 0; } void exitfunc () { screen_flipbuffer(); screen_clear(); screen_flipbuffer(); screen_clear(); screen_nobuffer(); free(buffer); free(fontbuffer); free(tilebuffer); } int main(int argc, char *argv[]) { int lastoutcome = 1; int outcome = 0; atexit(exitfunc); // Set initial display mode display_mode(DISPLAY_MODE); screen_clear(); // Load sprite library load_sprites("Spr",&buffer); load_sprites("Font",&fontbuffer); // Clear both buffers or we get gibberish screen_flipbuffer(); screen_clear(); screen_flipbuffer(); screen_clear(); lastoutcome = 1; load_sprites("Tiles",&tilebuffer); // Mission 2 while(lastoutcome == 1) { outcome = 0; screen_clear(); game2_setup(); while(!outcome) { outcome = game2_tick(); } lastoutcome = outcome; } free(buffer); return 0; }