diff --git a/readme.txt b/readme.txt index d4973b365..3bbe8c964 100644 --- a/readme.txt +++ b/readme.txt @@ -215,6 +215,7 @@ suggestions: Sciz CT DaVince Commander Spleen +Napalm Malvineous Tulip Hans de Goede diff --git a/src/CGame.cpp b/src/CGame.cpp index c741a4609..aa19fbad3 100644 --- a/src/CGame.cpp +++ b/src/CGame.cpp @@ -288,7 +288,7 @@ void CGame::preallocateCKP(stCloneKeenPlus *pCKP) framebyframe = 0; - demomode = DEMO_NODEMO; + pCKP->Control.levelcontrol.demomode = DEMO_NODEMO; current_demo = 1; pCKP->Joystick = NULL; diff --git a/src/CGraphics.cpp b/src/CGraphics.cpp index b9d08da82..4d2ae62b5 100644 --- a/src/CGraphics.cpp +++ b/src/CGraphics.cpp @@ -11,7 +11,7 @@ */ #include "keen.h" -#include "keenext.h" +//#include "externals.h" #include "CGraphics.h" #include "sdl/CVideoDriver.h" #include "sdl/video/colourtable.h" diff --git a/src/ai/fireball.cpp b/src/ai/fireball.cpp index 94bc1ef25..89cfc9935 100644 --- a/src/ai/fireball.cpp +++ b/src/ai/fireball.cpp @@ -45,8 +45,7 @@ int speed; } // test if it hit a baddie - //for(i=1;i @@ -21,8 +20,6 @@ #include "Debug.h" #include "FindFile.h" -extern CPlayer *Player; - unsigned int curmapx, curmapy; unsigned char mapdone; void addmaptile(unsigned int t) diff --git a/src/funcdefs.h b/src/funcdefs.h index 99b1c7e4f..dd259705d 100644 --- a/src/funcdefs.h +++ b/src/funcdefs.h @@ -13,32 +13,21 @@ void gamedo_render_drawdebug(void); void gamedo_render_erasedebug(void); void gamedo_fades(void); -// gamepdo.c - - // gamepdowm.c -//void gamepdo_wm_HandlePlayer(int cp); -//void gamepdo_InertiaAndFriction_Y(int cp); -//void gamepdo_wm_AllowEnterLevel(int cp); char wm_issolid(int xb, int yb, int *levels_completed); // game.c -//void SetGameOver(void); void overrun_detect(void); void scrolltest(void); -//void gameloop_initialize(void); void give_keycard(int doortile, int p); void take_keycard(int doortile, int p); -//void open_door(int doortile, int doorsprite, int mpx, int mpy, int cp, stCloneKeenPlus *pCKP) void extralifeat(int p); char spawn_object(int x, int y, int otype); void common_enemy_ai(int o); char hitdetect(int object1, int object2); void freezeplayer(int theplayer); void unregister_animtiles(int tile); -//void endlevel(int success, stCloneKeenPlus *pCKP) char checkobjsolid(unsigned int x, unsigned int y, unsigned int cp); -//void initsprites(stCloneKeenPlus *pCKP) void CopyTileToSprite(int t, int s, int ntilestocopy, int transparent); void GiveAnkh(int cp); // map.c @@ -104,12 +93,6 @@ void sb_mask_font_draw(unsigned char *text, int xoff, int yoff, char mask); void sb_color_font_draw(unsigned char *text, int xoff, int yoff, unsigned int colour, unsigned short bgcolour); void sb_font_draw_inverse(unsigned char *text, int xoff, int yoff); // viddrv.c -// fileio.c -//void addmaptile(unsigned int t, stCloneKeenPlus *pCKP); -//void addenemytile(unsigned int t, stCloneKeenPlus *pCKP); -//unsigned int fgeti(FILE *fp); -//unsigned long fgetl(FILE *fp); -//unsigned int loadmap(char *filename, char *path, int lvlnum, int isworldmap); #include "fileio.h" bool loadtileattributes(int episode, int version, unsigned char *filebuf); @@ -155,8 +138,5 @@ char lz_decompress(FILE *lzfile, unsigned char *outbuffer); // finale.c void finale_draw(const std::string& filename, const std::string& path); -// scalerx.c -//void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height); - #endif diff --git a/src/game.cpp b/src/game.cpp index 540ca6ec7..4f32fd079 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -18,7 +18,6 @@ #include "sdl/sound/CSound.h" #include "include/enemyai.h" #include "hqp/CMusic.h" -#include "vorticon/CPlayer.h" #include "vorticon/CHighScores.h" #include "hqp/CHQBitmap.h" #include "CLogFile.h" @@ -94,18 +93,6 @@ void gameloop(stCloneKeenPlus *pCKP) { if (primaryplayer==1) otherplayer = 0; else otherplayer = 1; - #ifdef NETWORK_PLAY -// if (numplayers>1) net_getdata(); - if (is_server) - { - Net_Server_Run(); - } - else if (is_client) - { - Net_Client_Run(); - } - #endif - gamedo_fades(); // periodically make all enemy gun fixtures fire (in ep3) @@ -159,7 +146,7 @@ void gameloop(stCloneKeenPlus *pCKP) { if (fade.dir==FADE_OUT) { - demomode = DEMO_NODEMO; + pCKP->Control.levelcontrol.demomode = DEMO_NODEMO; pCKP->Control.levelcontrol.level_done = LEVEL_COMPLETE; pCKP->Control.levelcontrol.command = LVLC_CHANGE_LEVEL; if (pCKP->Control.levelcontrol.curlevel != WM_MAP_NUM) @@ -378,15 +365,6 @@ short tilefix=0; objects[o].sprite = doorsprite; } -void delete_object(int o) -{ - if (objects[o].exists) - { - objects[o].exists = 0; - //if (o+1==highest_objslot) highest_objslot--; - } -} - // checks if score is > than "extra life at" and award 1-UPs when appropriate void extralifeat(int cp) { @@ -557,19 +535,19 @@ unsigned int i; } // each player is tied to a "puppet" object. // initialize objects used by players. - int o; for(i=0;iControl.levelcontrol.demomode) player[i].inventory.charges = 100; // start with pogo stick in all episodes but 1 - if (pCKP->Control.levelcontrol.episode!=1 || demomode) + if (pCKP->Control.levelcontrol.episode!=1 || pCKP->Control.levelcontrol.demomode) { player[i].inventory.HasPogo = 1; } else { player[i].inventory.HasPogo = 0; } @@ -627,7 +605,7 @@ int initgamefirsttime(stCloneKeenPlus *pCKP, int s) initsprites(pCKP, s); - if (demomode) srand(375); + if (pCKP->Control.levelcontrol.demomode) srand(375); primaryplayer = 0; @@ -638,7 +616,7 @@ char spawn_object(int x, int y, int otype) { int i; // find an unused object slot - for(i=1;i= highest_objslot ) + highest_objslot = i+1; + return i; } } - // object could not be created - - g_pLogFile->textOut(PURPLE, "Warning : Object could not be created."); - return 0; + // object could not be created + //crash("Object of type %d could not be created at %d,%d (out of object slots)",otype,x,y); + g_pLogFile->ftextOut("Object of type %d could not be created at %d,%d (out of object slots)
",otype,x,y); + return 0; } -// common enemy/object ai, such as falling, setting blocked variables, -// detecting player contact, etc. -void common_enemy_ai(int o) +void delete_object(int o) { -int x,y,xa,ya,xsize,ysize; -int temp; -int cplayer; + if (objects[o].exists) + { + objects[o].exists = 0; + if (o+1==highest_objslot) highest_objslot--; + } +} - if (objects[o].type==OBJ_DEMOMSG) return; +void delete_all_objects(void) +{ +int i; + for(i=0;i=0;i--) + { + if (objects[i].exists) + { + highest_objslot = i+1; + break; + } + } +} - xsize = sprites[objects[o].sprite].xsize; - ysize = sprites[objects[o].sprite].ysize; +// anything (players/enemies) occupying the map tile at [mpx,mpy] is killed +/*void kill_all_intersecting_tile(int mpx, int mpy) +{ +int xpix,ypix; +int i; + xpix = mpx<= objects[i].x) + { + if (ypix <= objects[i].y && ypix+(16<= objects[i].y) + { + killobject(i); + } + } + } + } +}*/ - // set value of blockedd--should object fall? - temp = (objects[o].y>>CSF)+ysize; - if ((temp>>4)<<4 != temp) - { - objects[o].blockedd = 0; - } - else - { // on a tile boundary, test if tile under object is solid - objects[o].blockedd = 0; - x = (objects[o].x>>CSF); - y = (objects[o].y>>CSF)+ysize+1; - for(xa=0;xa 1 && - TileProperty[getmaptileat(x+xa,y)][BEHAVIOR] < 6) ) - { - objects[o].blockedd = 1; - goto setblockedd; - } - } - if(TileProperty[getmaptileat(x+xsize-2, y)][BUP] || (TileProperty[getmaptileat(x+xa,y)][BEHAVIOR] > 1 && - TileProperty[getmaptileat(x+xa,y)][BEHAVIOR] < 6) ) - { - objects[o].blockedd = 1; - } - setblockedd: ; - } +// returns whether pix position x,y is a stop point for object o. +// stop points are invisible blockers that act solid only to certain +// kinds of enemies. They're used to help make the enemies seem smarter +// and keep them from falling off certain platforms. Stoppoints are manually +// placed from fileio.c. +char IsStopPoint(int x, int y, int o) +{ + switch(objects[o].type) + { + case OBJ_YORP: + case OBJ_GARG: + case OBJ_MOTHER: + case OBJ_VORT: + case OBJ_VORTELITE: + case OBJ_TANK: + case OBJ_TANKEP2: + //if (getlevelat(x,y)==ENEMY_STOPPOINT) return 1; + case OBJ_WALKER: + case OBJ_PLATFORM: + case OBJ_PLATVERT: + case OBJ_BABY: + //if (IsDoor(getmaptileat(x,y))) return 1; + break; - // set blockedu - objects[o].blockedu = 0; - x = (objects[o].x>>CSF); - y = (objects[o].y>>CSF)-1; - for(xa=0;xa>CSF)-1; - y = (objects[o].y>>CSF)+1; - for(ya=0;ya>CSF)+ysize-1))][BRIGHT]) - //if (tiles[getmaptileat(x, ((objects[o].y>>CSF)+ysize-1))].solidr) - { - objects[o].blockedl = 1; - } - setblockedl: ; + case OBJ_BALL: + if (getlevelat(x,y)==BALL_NOPASSPOINT) return 1; + //if (IsDoor(getmaptileat(x,y))) return 1; + break; + } - // set blockedr - objects[o].blockedr = 0; - x = (objects[o].x>>CSF)+xsize; - y = (objects[o].y>>CSF)+1; - for(ya=0;ya>CSF)+ysize-1))][BLEFT]) - //if (tiles[getmaptileat(x, ((objects[o].y>>CSF)+ysize-1))].solidl) - { - objects[o].blockedr = 1; - } - setblockedr: ; - - // hit detection with players - objects[o].touchPlayer = 0; - for(cplayer=0;cplayerOBJ_YINERTIA_RATE) - { - if (objects[o].yinertia < OBJFALLSPEED) objects[o].yinertia++; - objects[o].yinertiatimer = 0; - } else objects[o].yinertiatimer++; - } - objects[o].y += objects[o].yinertia; - } + return 0; } // returns nonzero if object1 overlaps object2 @@ -943,7 +879,7 @@ char checkobjsolid(unsigned int x, unsigned int y, unsigned int cp) { int o; - for(o=1;oControl.levelcontrol.demomode==DEMO_PLAYBACK) { // time to get a new key block? if (!demo_RLERunLen) @@ -123,7 +121,7 @@ unsigned int msb, lsb; if(g_pInput->getHoldedCommand(p, IC_STATUS)) player[p].playcontrol[PA_STATUS] = 1; - if (demomode==DEMO_RECORD) + if (pCKP->Control.levelcontrol.demomode==DEMO_RECORD) { if(i) player[p].playcontrol[PA_X] += 100; fputc(i, demofile); @@ -214,12 +212,16 @@ int i; // do object and enemy AI void gamedo_enemyai(stCloneKeenPlus *pCKP) { -int i; -// handle objects and do enemy AI - for(i=1;i1) -// if (!objects[i].hasbeenonscreen) -// net_sendobjectonscreen(i); - #endif - objects[i].onscreen = 1; objects[i].hasbeenonscreen = 1; } - if (objects[i].hasbeenonscreen || objects[i].type==OBJ_RAY || \ - objects[i].type==OBJ_ICECHUNK || objects[i].type==OBJ_PLATFORM ||\ - objects[i].type==OBJ_PLATVERT) + if (objects[i].hasbeenonscreen || objects[i].zapped || + objects[i].type==OBJ_RAY || \ + objects[i].type==OBJ_ICECHUNK || objects[i].type==OBJ_PLATFORM ||\ + objects[i].type==OBJ_PLATVERT || objects[i].type==OBJ_YORP || + objects[i].type==OBJ_FOOB || objects[i].type==OBJ_WALKER) + { common_enemy_ai(i); switch(objects[i].type) @@ -263,6 +262,7 @@ int i; case OBJ_TANK: tank_ai(i, pCKP->Control.levelcontrol.hardmode); break; case OBJ_RAY: ray_ai(i, pCKP, pCKP->Control.levelcontrol); break; case OBJ_DOOR: door_ai(i, pCKP->Control.levelcontrol.cepvars.DoorOpenDir); break; + //case OBJ_ICECANNON: icecannon_ai(i); break; TODO: Add this AI case OBJ_ICECHUNK: icechunk_ai(i); break; case OBJ_ICEBIT: icebit_ai(i); break; case OBJ_TELEPORTER: teleporter_ai(i, pCKP->Control.levelcontrol); break; @@ -277,6 +277,7 @@ int i; pCKP->Control.levelcontrol.hardmode); break; case OBJ_EXPLOSION: explosion_ai(i); break; case OBJ_EARTHCHUNK: earthchunk_ai(i); break; + //case OBJ_SPARK: spark_ai(i); break; TODO: Add this AI //KEEN3 case OBJ_FOOB: foob_ai(i, pCKP); break; case OBJ_NINJA: ninja_ai(i, pCKP); break; @@ -288,13 +289,13 @@ int i; case OBJ_JACK: ballandjack_ai(i); break; case OBJ_PLATVERT: platvert_ai(i); break; case OBJ_NESSIE: nessie_ai(i); break; + //Specials + //case OBJ_AUTORAY: case OBJ_AUTORAY_V: autoray_ai(i); break; + //case OBJ_GOTPOINTS: gotpoints_ai(i); break; case OBJ_DEMOMSG: break; default: - crashflag = 1; - crashflag2 = i; - crashflag3 = objects[i].type; - why_term_ptr = "Invalid object flag2 of type flag3"; + //crash("gamedo_enemy_ai: Object %d is of invalid type %d\n", i, objects[i].type); break; } @@ -304,6 +305,162 @@ int i; } } +// common enemy/object ai, such as falling, setting blocked variables, +// detecting player contact, etc. +void common_enemy_ai(int o) +{ +int x,y,xa,ya,xsize,ysize; +int temp; +int cplayer; + + //if (objects[o].type==OBJ_GOTPOINTS) return; + + xsize = sprites[objects[o].sprite].xsize; + ysize = sprites[objects[o].sprite].ysize; + + // set value of blockedd--should object fall? + temp = (objects[o].y>>CSF)+ysize; + if ((temp>>TILE_S)<>CSF); + y = (objects[o].y>>CSF)+ysize+1; + for(xa=0;xa>CSF); + y = (objects[o].y>>CSF)-1; + for(xa=1;xa>CSF)-1; + y = (objects[o].y>>CSF)+1; + for(ya=0;ya>CSF)+ysize-1))][BRIGHT] || + IsStopPoint(x, (objects[o].y>>CSF)+ysize-1, o)) + { + objects[o].blockedl = 1; + } + blockedl_set: ; + + // set blockedr + objects[o].blockedr = 0; + x = (objects[o].x>>CSF)+xsize; + y = (objects[o].y>>CSF)+1; + for(ya=0;ya>CSF)+ysize-1))][BLEFT] || + IsStopPoint(x, (objects[o].y>>CSF)+ysize-1, o)) + { + objects[o].blockedr = 1; + } + blockedr_set: ; + + // hit detection with players + objects[o].touchPlayer = 0; + for(cplayer=0;cplayerOBJ_YINERTIA_RATE) + { + if (objects[o].yinertia < OBJFALLSPEED) objects[o].yinertia++; + objects[o].yinertiatimer = 0; + } else objects[o].yinertiatimer++; + } + objects[o].y += objects[o].yinertia; + } +} int savew, saveh; @@ -337,7 +494,7 @@ int xa,ya; // if we're playing a demo keep the "DEMO" message on the screen // as an object - if (demomode==DEMO_PLAYBACK) + if (pCKP->Control.levelcontrol.demomode==DEMO_PLAYBACK) { #define DEMO_X_POS 137 #define DEMO_Y_POS 6 @@ -353,7 +510,7 @@ int xa,ya; // draw all objects. drawn in reverse order because the player sprites // are in the first few indexes and we want them to come out on top. - for(i=MAX_OBJECTS-1;;i--) + for(i=highest_objslot;;i--) { if (objects[i].exists && objects[i].onscreen) { @@ -515,10 +672,10 @@ void gamedo_RenderScreen(stCloneKeenPlus *pCKP) g_pGraphics->renderHQBitmap(); - gamedo_render_drawobjects(pCKP); - if(pCKP != NULL) { + gamedo_render_drawobjects(pCKP); + if (pCKP->Control.levelcontrol.gameovermode) { // figure out where to center the gameover bitmap and draw it diff --git a/src/gamepdo.cpp b/src/gamepdo.cpp index 97f218267..80feaed10 100644 --- a/src/gamepdo.cpp +++ b/src/gamepdo.cpp @@ -66,7 +66,7 @@ char doFall; } - if (fade.mode==NO_FADE || fade.dir==FADE_IN || demomode) + if (fade.mode==NO_FADE || fade.dir==FADE_IN || pCKP->Control.levelcontrol.demomode) { gamepdo_playpushed(cp, pCKP); gamepdo_InertiaAndFriction_X(cp, pCKP); diff --git a/src/include/declarations.h b/src/include/declarations.h index 210c430c3..3e5e97d3c 100644 --- a/src/include/declarations.h +++ b/src/include/declarations.h @@ -51,6 +51,7 @@ struct stLevelControl int episode; // which episode we're playing (1-3) bool hardmode; bool usedhintmb; // Has the message box been used? + int demomode; // array of which levels have been completed (have "Done" tiles over them // on the world map) diff --git a/src/include/game.h b/src/include/game.h index 6b134eadf..3ed7257b1 100644 --- a/src/include/game.h +++ b/src/include/game.h @@ -214,6 +214,9 @@ void initsprites(stCloneKeenPlus *pCKP, int s); void keen_get_goodie(int px, int py, int theplayer, stCloneKeenPlus *pCKP); void procgoodie(int t, int mpx, int mpy, int theplayer, stCloneKeenPlus *pCKP); +void recalc_highest_objslot(void); +char IsStopPoint(int x, int y, int o); + void initgame(stCloneKeenPlus *pCKP); int initgamefirsttime(stCloneKeenPlus *pCKP, int s); diff --git a/src/keen.h b/src/keen.h index f74441bf9..4b344ae89 100644 --- a/src/keen.h +++ b/src/keen.h @@ -65,6 +65,9 @@ typedef struct stFade #define SCROLLBUF_XSIZE 512 #define SCROLLBUF_YSIZE 512 #define SCROLLBUF_MEMSIZE ((SCROLLBUF_XSIZE)*(SCROLLBUF_YSIZE+300)) +#define TILE_W 16 +#define TILE_H 16 +#define TILE_S 4 #define SCROLLBUF_NUMTILESX (SCROLLBUF_XSIZE / 16) #define SCROLLBUF_NUMTILESY (SCROLLBUF_YSIZE / 16) @@ -497,6 +500,7 @@ typedef struct stObject unsigned int needinit; // 1=new object--requires initilization unsigned char wasoffscreen; // set to 1 when object goes offscreen + bool dead; // data for ai and such, used differently depending on // what kind of object it is union ai @@ -855,7 +859,7 @@ typedef struct stShipQueue #include #include "include/declarations.h" -#include "keenext.h" +#include "externals.h" #include "sdl/CSettings.h" struct stCloneKeenPlus diff --git a/src/main.cpp b/src/main.cpp index f15bd68ef..75a1c07ee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,7 +41,6 @@ #include "include/fileio/story.h" #include "include/main.h" #include "fileio/CParser.h" -#include "vorticon/CPlayer.h" #include "vorticon/CHighScores.h" #include "CLogFile.h" #include "CGame.h" @@ -70,7 +69,6 @@ char QuitState = NO_QUIT; stString strings[MAX_STRINGS+1]; int numStrings = 0; -int demomode; FILE *demofile = NULL; char ScreenIsScrolling; @@ -87,8 +85,6 @@ extern unsigned char scrollpixy; extern unsigned int mapy; extern unsigned int mapystripepos; -extern CPlayer *Player; - char loadinggame, loadslot; stFade fade; @@ -548,7 +544,7 @@ gotEOF: ; // initilize some variables demo_RLERunLen = 0; demo_data_index = 0; - demomode = DEMO_PLAYBACK; + pCKP->Control.levelcontrol.demomode = DEMO_PLAYBACK; loadinggame = 0; p_levelcontrol->curlevel = lvl; p_levelcontrol->command = LVLC_NOCOMMAND; @@ -650,7 +646,7 @@ short readCommandLine(int argc, char *argv[], stCloneKeenPlus *pCKP) } else if (strcmp(tempbuf, "-rec")==0) // record a demo { - demomode = DEMO_RECORD; + pCKP->Control.levelcontrol.demomode = DEMO_RECORD; } else if (strcmp(tempbuf, "-eseq")==0) // play end sequence { diff --git a/src/sdl/CTimer.cpp b/src/sdl/CTimer.cpp index 8e854a753..a1e816028 100644 --- a/src/sdl/CTimer.cpp +++ b/src/sdl/CTimer.cpp @@ -7,7 +7,7 @@ #include "../keen.h" -#include "../keenext.h" +//#include "../externals.h" #include "../MathLib.h" #include "CTimer.h" diff --git a/src/sdl/joydrv.cpp b/src/sdl/joydrv.cpp index ce771e4f2..10c44c171 100644 --- a/src/sdl/joydrv.cpp +++ b/src/sdl/joydrv.cpp @@ -3,7 +3,7 @@ */ #include "../keen.h" -#include "../keenext.h" +//#include "../externals.h" #include "CVideoDriver.h" #include "../CLogFile.h" diff --git a/src/vorticon/CEGALatch.cpp b/src/vorticon/CEGALatch.cpp index f55c7d6e8..eba77f3f2 100644 --- a/src/vorticon/CEGALatch.cpp +++ b/src/vorticon/CEGALatch.cpp @@ -10,7 +10,7 @@ #include "CPlanes.h" #include "../funcdefs.h" #include "../keen.h" -#include "../keenext.h" +//#include "../externals.h" #include "../FindFile.h" #include #include