From 531ce04fa1dd9fb3c72d16614650ea2c6c8624d0 Mon Sep 17 00:00:00 2001 From: gerstrong Date: Wed, 22 Jul 2009 16:38:10 +0000 Subject: [PATCH] 22.Jul.2009 git-svn-id: https://clonekeenplus.svn.sourceforge.net/svnroot/clonekeenplus/cgenius/trunk@95 4df4b0f3-56ce-47cb-b001-ed939b7d65a6 --- src/CGame.cpp | 13 +- src/CGame.h | 7 +- src/CGraphics.cpp | 39 +- src/CGraphics.h | 13 +- src/CLatch.cpp | 73 +- src/eseq_ep1.cpp | 885 ++++++----- src/eseq_ep2.cpp | 1430 +++++++++-------- src/fileio.cpp | 1583 +++++++++---------- src/fileio.h | 12 +- src/fileio/CExeFile.cpp | 18 +- src/fileio/CExeFile.h | 8 +- src/fileio/CParser.cpp | 6 +- src/fileio/CParser.h | 3 +- src/fileio/CPatcher.cpp | 16 +- src/fileio/CPatcher.h | 12 +- src/fileio/story.cpp | 23 +- src/finale.cpp | 268 ++-- src/funcdefs.h | 325 ++-- src/gamedo.cpp | 1497 +++++++++--------- src/hqp/CHQBitmap.cpp | 4 +- src/hqp/CHQBitmap.h | 3 +- src/hqp/CMusic.cpp | 8 +- src/hqp/hq_sound.cpp | 25 +- src/hqp/hq_sound.h | 12 +- src/include/declarations.h | 17 +- src/include/eseq_ep2.h | 9 +- src/include/fileio.h | 11 +- src/include/fileio/story.h | 9 +- src/keen.h | 1728 ++++++++++----------- src/main.cpp | 3 +- src/menu.cpp | 1451 +++++++++++++++++ src/misc.cpp | 2739 +++++++++++++++++---------------- src/sdl/COpenGL.cpp | 5 +- src/sdl/CVideoDriver.cpp | 44 +- src/sdl/CVideoDriver.h | 16 +- src/sdl/sound/CSound.cpp | 44 +- src/sdl/sound/CSound.h | 8 +- src/sdl/sound/CSoundSlot.cpp | 12 +- src/sdl/sound/CSoundSlot.h | 2 +- src/vorbis/oggsupport.cpp | 9 +- src/vorticon/CCredits.cpp | 2 +- src/vorticon/CDialog.cpp | 58 +- src/vorticon/CDialog.h | 16 +- src/vorticon/CEGAGraphics.cpp | 37 +- src/vorticon/CEGAGraphics.h | 5 +- src/vorticon/CEGALatch.cpp | 5 +- src/vorticon/CEGALatch.h | 5 +- src/vorticon/CEGASprit.cpp | 5 +- src/vorticon/CEGASprit.h | 4 +- src/vorticon/CHighScores.cpp | 52 +- src/vorticon/CHighScores.h | 4 +- src/vorticon/CMessages.cpp | 4 +- src/vorticon/CMessages.h | 6 +- 53 files changed, 7040 insertions(+), 5553 deletions(-) diff --git a/src/CGame.cpp b/src/CGame.cpp index 78160b697..c622d5963 100644 --- a/src/CGame.cpp +++ b/src/CGame.cpp @@ -27,6 +27,7 @@ CGame::CGame() { m_Episode = 0; + memset(m_DataDirectory,0,256); TileLoader = NULL; EGAGraphics = NULL; @@ -217,13 +218,15 @@ short CGame::runCycle(stCloneKeenPlus *pCKP) return 0; } -int CGame::loadResources(unsigned short Episode, const std::string& DataDirectory) +int CGame::loadResources(unsigned short Episode, char *DataDirectory) { m_Episode = Episode; - m_DataDirectory = DataDirectory; + memcpy(m_DataDirectory, DataDirectory, 256); - if( m_DataDirectory.size() > 0 && m_DataDirectory[m_DataDirectory.size()-1] != '/' ) - m_DataDirectory += "/"; + int pos = strlen(DataDirectory)-1; + if(pos == -1) pos =0; + if( ( *(DataDirectory+pos) != '/' ) && strlen(DataDirectory) > 0) + strcat(DataDirectory,"/"); // Decode the entire graphics for the game (EGALATCH, EGASPRIT) EGAGraphics = new CEGAGraphics(Episode, DataDirectory); // Path is relative to the data dir @@ -276,6 +279,8 @@ void CGame::preallocateCKP(stCloneKeenPlus *pCKP) pCKP->GameData = NULL; pCKP->GameData = new stGameData[1]; + memset(pCKP->GameData, 0, sizeof(stGameData)); + framebyframe = 0; demomode = DEMO_NODEMO; diff --git a/src/CGame.h b/src/CGame.h index ab8afeeb2..6dd5ce2e0 100644 --- a/src/CGame.h +++ b/src/CGame.h @@ -8,7 +8,7 @@ #ifndef CGAME_H_ #define CGAME_H_ -#include +#include #include "vorticon/CEGAGraphics.h" #include "vorticon/CMessages.h" @@ -17,14 +17,15 @@ public: CGame(); virtual ~CGame(); - int loadResources(unsigned short Episode, const std::string& DataDirectory); + int loadResources(unsigned short Episode, char *DataDirectory); void freeResources(void); short runCycle(stCloneKeenPlus *pCKP); void preallocateCKP(stCloneKeenPlus *pCKP); private: + static const unsigned short MAX_TEXT_LENGTH = 256; unsigned short m_Episode; - std::string m_DataDirectory; + char m_DataDirectory[MAX_TEXT_LENGTH]; int current_demo; CEGAGraphics *EGAGraphics; diff --git a/src/CGraphics.cpp b/src/CGraphics.cpp index 31725397f..c9ad43746 100644 --- a/src/CGraphics.cpp +++ b/src/CGraphics.cpp @@ -10,14 +10,12 @@ * not platform-specific). */ -#include "keen.h" -#include "keenext.h" #include "CGraphics.h" +#include "keen.h" #include "sdl/CVideoDriver.h" #include "sdl/video/colourtable.h" #include "sdl/CVideoDriver.h" #include "CLogFile.h" -#include "StringUtils.h" CGraphics::CGraphics() { HQBitmap = NULL; @@ -593,13 +591,13 @@ int c; } // font drawing functions -void CGraphics::drawFont(const std::string& text, int xoff, int yoff, int highlight) +void CGraphics::drawFont(unsigned char *text, int xoff, int yoff, int highlight) { unsigned int i,x=xoff,y; int c; y = yoff; - for(i=0;i #include #include "hqp/CHQBitmap.h" @@ -45,18 +44,18 @@ public: void drawBitmap2FG(int xa, int ya, int b); int getBitmapNumberFromName(const char *bmname); void sb_drawCharacterinverse(int x, int y, int f); - void drawFont(const std::string& text, int xoff, int yoff, int highlight); - void sb_font_draw(const std::string& text, int xoff, int yoff); - void sb_mask_font_draw(const std::string& text, int xoff, int yoff, char mask); - void sb_color_font_draw(const std::string& text, int xoff, int yoff, unsigned int colour, unsigned short bgcolour); - void sb_font_draw_inverse(const std::string& text, int xoff, int yoff); + void drawFont(unsigned char *text, int xoff, int yoff, int highlight); + void sb_font_draw(const unsigned char *text, int xoff, int yoff); + 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); void drawTile_direct(int x, int y, unsigned int t); void setFadeBlack(bool value); Uint8 *getScrollbuffer(void); void renderHQBitmap(); - void loadHQGraphics(unsigned char episode, unsigned char level, const std::string& datadir); + void loadHQGraphics(unsigned char episode, unsigned char level, char *datadir); void unloadHQGraphics(); private: diff --git a/src/CLatch.cpp b/src/CLatch.cpp index bb6165230..6f762702f 100644 --- a/src/CLatch.cpp +++ b/src/CLatch.cpp @@ -13,7 +13,6 @@ #include "fileio.h" #include "keen.h" #include "keenext.h" -#include "StringUtils.h" #include "CLogFile.h" //#include "vorticon/CEGAGraphics.h" @@ -59,15 +58,19 @@ char CLatch::loadHeader(int episode, const char *path) FILE *headfile; unsigned long SpriteTableRAMSize; unsigned long BitmapTableRAMSize; - std::string buf; + char buf[12]; int i,j,k; - std::string fname; - std::string buffer; + char fname[80]; + char buffer[256]; - buffer = formatPathString(path); - buffer += "egahead.ck"; + memset(buffer,0,256); + memset(fname,0,80); - fname = buffer + itoa(episode); + formatPathString(buffer,path); + + strcat(buffer,"egahead.ck"); + + sprintf(fname, "%s%d", buffer,episode); /*CEGAGraphics *EGAGraphics; @@ -77,14 +80,14 @@ char CLatch::loadHeader(int episode, const char *path) delete EGAGraphics;*/ - headfile = fopen(fname.c_str(), "rb"); + headfile = fopen(fname, "rb"); if (!headfile) { - g_pLogFile->ftextOut("latch_loadheader(): unable to open '%s'.
", fname.c_str()); + g_pLogFile->ftextOut("latch_loadheader(): unable to open '%s'.
", fname); return 1; } - g_pLogFile->ftextOut("latch_loadheader(): reading main header from '%s'...
", fname.c_str()); + g_pLogFile->ftextOut("latch_loadheader(): reading main header from '%s'...
", fname); // read the main header data from EGAHEAD LatchHeader.LatchPlaneSize = fgetl(headfile); @@ -132,7 +135,7 @@ char CLatch::loadHeader(int episode, const char *path) return 1; } - g_pLogFile->ftextOut("latch_loadheader(): Reading sprite table from '%s'...
", fname.c_str()); + g_pLogFile->ftextOut("latch_loadheader(): Reading sprite table from '%s'...
", fname); fseek(headfile, LatchHeader.OffSpriteTable, SEEK_SET); for(i=0;iftextOut("latch_loadheader(): reading bitmap table from '%s'...
", fname.c_str()); + g_pLogFile->ftextOut("latch_loadheader(): reading bitmap table from '%s'...
", fname); fseek(headfile, LatchHeader.OffBitmapTable, SEEK_SET); @@ -188,7 +191,7 @@ char CLatch::loadHeader(int episode, const char *path) // print the bitmap info to the console for debug for(j=0;j<8;j++) buf[j] = BitmapTable[i].Name[j]; buf[j] = 0; - g_pLogFile->ftextOut(" Bitmap '%s': %dx%d at offset %04x. RAMAllocSize=0x%04x
", buf.c_str(),BitmapTable[i].Width,BitmapTable[i].Height,BitmapTable[i].Offset,BitmapBufferRAMSize); + g_pLogFile->ftextOut(" Bitmap '%s': %dx%d at offset %04x. RAMAllocSize=0x%04x
", buf,BitmapTable[i].Width,BitmapTable[i].Height,BitmapTable[i].Offset,BitmapBufferRAMSize); } BitmapBufferRAMSize++; @@ -203,24 +206,26 @@ char CLatch::load(int episode, const char *path) { FILE *latchfile; unsigned long plane1, plane2, plane3, plane4; - std::string fname; +char fname[80]; int x,y,t,b,c,p; char *bmdataptr; unsigned long RawDataSize; //unsigned char ch; - std::string buffer; +char buffer[256]; - buffer = formatPathString(path); - buffer += "egalatch.ck"; - fname = buffer + itoa(episode); + formatPathString(buffer,path); - g_pLogFile->ftextOut("latch_loadlatch(): Opening file '%s'.
", fname.c_str()); + strcat(buffer,"egalatch.ck"); - latchfile = fopen(fname.c_str(), "rb"); + sprintf(fname, "%s%c", buffer,episode + '0'); + + g_pLogFile->ftextOut("latch_loadlatch(): Opening file '%s'.
", fname); + + latchfile = fopen(fname, "rb"); if (!latchfile) { - g_pLogFile->ftextOut("latch_loadlatch(): Unable to open '%s'!
", fname.c_str()); + g_pLogFile->ftextOut("latch_loadlatch(): Unable to open '%s'!
", fname); return 1; } @@ -261,7 +266,7 @@ unsigned long RawDataSize; plane4 = (LatchHeader.LatchPlaneSize * 3); // ** read the 8x8 tiles ** - g_pLogFile->ftextOut("latch_loadlatch(): Decoding 8x8 tiles...
", fname.c_str()); + g_pLogFile->ftextOut("latch_loadlatch(): Decoding 8x8 tiles...
", fname); // set up the getbit() function @@ -304,7 +309,7 @@ unsigned long RawDataSize; delete Planes; // ** read the 16x16 tiles ** - g_pLogFile->ftextOut("latch_loadlatch(): Decoding 16x16 tiles...
", fname.c_str()); + g_pLogFile->ftextOut("latch_loadlatch(): Decoding 16x16 tiles...
", fname); // set up the getbit() function Planes = new CPlanes(plane1 + LatchHeader.Off16Tiles, \ @@ -349,7 +354,7 @@ unsigned long RawDataSize; return 1; } - g_pLogFile->ftextOut("latch_loadlatch(): Decoding bitmaps...
", fname.c_str()); + g_pLogFile->ftextOut("latch_loadlatch(): Decoding bitmaps...
", fname); // set up the getbit() function Planes = new CPlanes(plane1 + LatchHeader.OffBitmaps, \ @@ -414,22 +419,24 @@ char CLatch::loadSprites(int episode, const char *path) { FILE *spritfile; unsigned long plane1, plane2, plane3, plane4, plane5; - std::string fname; +char fname[80]; int x,y,s,c,p; unsigned long RawDataSize; - std::string buffer; +char buffer[256]; CPlanes *Planes; - buffer = formatPathString(path); - buffer += "egasprit.ck"; - fname = buffer + itoa(episode); + formatPathString(buffer,path); - g_pLogFile->ftextOut("latch_loadsprites(): Opening file '%s'.
", fname.c_str()); + strcat(buffer,"egasprit.ck"); - spritfile = fopen(fname.c_str(), "rb"); + sprintf(fname, "%s%c", buffer,episode + '0'); + + g_pLogFile->ftextOut("latch_loadsprites(): Opening file '%s'.
", fname); + + spritfile = fopen(fname, "rb"); if (!spritfile) { - g_pLogFile->ftextOut("latch_loadsprites(): Unable to open '%s'!
", fname.c_str()); + g_pLogFile->ftextOut("latch_loadsprites(): Unable to open '%s'!
", fname); return 1; } @@ -468,7 +475,7 @@ CPlanes *Planes; plane5 = (LatchHeader.SpritePlaneSize * 4); // ** read the sprites ** - g_pLogFile->ftextOut("latch_loadsprites(): Decoding sprites...
", fname.c_str()); + g_pLogFile->ftextOut("latch_loadsprites(): Decoding sprites...
", fname); // set up the getbit() function Planes = new CPlanes(plane1 + LatchHeader.OffSprites, \ diff --git a/src/eseq_ep1.cpp b/src/eseq_ep1.cpp index d7cf6ae0f..9648ca69b 100644 --- a/src/eseq_ep1.cpp +++ b/src/eseq_ep1.cpp @@ -1,443 +1,442 @@ -/* ESEQ_EP1.C - Ending sequence for Episode 1. -*/ - -#include "keen.h" -#include "include/game.h" -#include "include/gamedo.h" -#include "include/gamepdo.h" -#include "sdl/CInput.h" -#include "sdl/CTimer.h" -#include "include/eseq_ep1.h" -#include "include/eseq_ep2.h" -#include "include/menu.h" -#include "CGraphics.h" -#include "StringUtils.h" - -#define CMD_MOVE 0 -#define CMD_WAIT 1 -#define CMD_SPAWNSPR 2 -#define CMD_REMOVESPR 3 -#define CMD_FADEOUT 4 -#define CMD_ENDOFQUEUE 5 -#define CMD_ENABLESCROLLING 6 -#define CMD_DISABLESCROLLING 7 - - -// start x,y map scroll position for eseq1_ShipFlys() -#define SHIPFLY_X 32 -#define SHIPFLY_Y 0 - -// worldmap scroll position for eseq1_ReturnsToShip() -#define WM_X 40 -#define WM_Y 540 - -#define LETTER_SHOW_SPD 30 -#define RETURNTOSHIP_WAIT_TIME 600 - -#define SPR_SHIP_RIGHT 115 -#define SPR_SHIP_LEFT 116 -#define SPR_EXCLAMATION 117 -#define SPR_QUESTION 118 -#define SHIPSPD 4 - -#define BACKHOME_SHORT_WAIT_TIME 250 - -int eseq1_ReturnsToShip(stCloneKeenPlus *pCKP) -{ -int i; - - for(i=0;iControl.levelcontrol.levels_completed[i] = 0; - - showmapatpos(80, WM_X, WM_Y, 0, pCKP); - - // draw keen next to his ship - g_pGraphics->drawSprite(168, 85, PMAPLEFTFRAME, 0); - // do not show player when we render the screen - numplayers = 1; - player[0].x = 0; - player[0].y = 0; - player[0].playframe = BlankSprite; - // all objects -> nonexistant - for(i=0;ipollEvents(); - g_pTimer->SpeedThrottle(); - } while(fade.mode != FADE_COMPLETE && !g_pInput->getPressedKey(KQUIT)); - - return 0; -} - - -void addshipqueue(int cmd, int time, int flag1) -{ - shipqueue[ShipQueuePtr].cmd = cmd; - shipqueue[ShipQueuePtr].time = time; - shipqueue[ShipQueuePtr].flag1 = flag1; - ShipQueuePtr++; -} - -int eseq1_ShipFlys(stCloneKeenPlus *pCKP) -{ -char enter,lastenterstate; -int x, y; -int scrollingon; - - scrollingon = 1; - - #define MARK_SPR_NUM 5 - initgame(pCKP); - - // set up the ship's route - ShipQueuePtr = 0; - addshipqueue(CMD_MOVE, 230, DUP); - addshipqueue(CMD_WAIT, 50, 0); - addshipqueue(CMD_MOVE, 2690, DDOWNRIGHT); - addshipqueue(CMD_WAIT, 100, 0); - addshipqueue(CMD_MOVE, 480, DDOWN); - addshipqueue(CMD_WAIT, 150, 0); - addshipqueue(CMD_SPAWNSPR, 0, SPR_QUESTION); - addshipqueue(CMD_DISABLESCROLLING, 0, 0); - addshipqueue(CMD_WAIT, 350, 0); - addshipqueue(CMD_REMOVESPR, 0, 0); - addshipqueue(CMD_WAIT, 50, 0); - addshipqueue(CMD_MOVE, 700, DLEFT); - addshipqueue(CMD_WAIT, 150, 0); - addshipqueue(CMD_SPAWNSPR, 0, SPR_EXCLAMATION); - addshipqueue(CMD_WAIT, 500, 0); - addshipqueue(CMD_REMOVESPR, 0, 0); - addshipqueue(CMD_WAIT, 50, 0); - addshipqueue(CMD_MOVE, 700, DRIGHT); - addshipqueue(CMD_WAIT, 25, 0); - addshipqueue(CMD_ENABLESCROLLING, 0, 0); - addshipqueue(CMD_MOVE, 465, DDOWN); - addshipqueue(CMD_FADEOUT, 0, 0); - addshipqueue(CMD_MOVE, 100, DDOWN); - addshipqueue(CMD_ENDOFQUEUE, 0, 0); - - showmapatpos(81, SHIPFLY_X, SHIPFLY_Y, 0, pCKP); - - objects[MARK_SPR_NUM].type = OBJ_YORP; // doesn't matter - objects[MARK_SPR_NUM].exists = 0; - objects[MARK_SPR_NUM].sprite = SPR_QUESTION; - - numplayers = 1; - // place the player at the center of mars - if (map_findtile(593, &x, &y)) - { // found the tile at the center of mars - player[0].x = ((x<<4)+1)<>CSF)-scroll_x; - objects[MARK_SPR_NUM].scry = (objects[MARK_SPR_NUM].y>>CSF)-scroll_y; - - // execute the current command in the queue - if (fade.dir != FADE_OUT) - { - switch(shipqueue[ShipQueuePtr].cmd) - { - case CMD_MOVE: - switch(shipqueue[ShipQueuePtr].flag1) - { - case DUP: - player[0].y-=SHIPSPD; - player[0].playframe = SPR_SHIP_RIGHT; - break; - case DDOWN: - player[0].y+=SHIPSPD/2; - player[0].playframe = SPR_SHIP_RIGHT; - break; - case DLEFT: - player[0].x-=SHIPSPD; - player[0].playframe = SPR_SHIP_LEFT; - break; - case DRIGHT: - player[0].x+=SHIPSPD; - player[0].playframe = SPR_SHIP_RIGHT; - break; - case DDOWNRIGHT: - player[0].x+=SHIPSPD*2; - player[0].y+=SHIPSPD*0.8; - player[0].playframe = SPR_SHIP_RIGHT; - break; - } - break; - case CMD_SPAWNSPR: - objects[MARK_SPR_NUM].sprite = shipqueue[ShipQueuePtr].flag1; - objects[MARK_SPR_NUM].exists = 1; - break; - case CMD_REMOVESPR: - objects[MARK_SPR_NUM].sprite = shipqueue[ShipQueuePtr].flag1; - objects[MARK_SPR_NUM].exists = 0; - break; - case CMD_ENABLESCROLLING: - scrollingon = 1; - break; - case CMD_DISABLESCROLLING: - scrollingon = 0; - break; - case CMD_WAIT: - break; - case CMD_FADEOUT: - if (fade.dir!=FADE_OUT) - { - fade.dir = FADE_OUT; - fade.curamt = PAL_FADE_SHADES; - fade.fadetimer = 0; - fade.mode = FADE_GO; - fade.rate = FADE_NORM; - } - break; - default: break; - } - // decrease the time remaining - if (shipqueue[ShipQueuePtr].time) - { - shipqueue[ShipQueuePtr].time--; - } - else - { // no time left on this command, go to next cmd - ShipQueuePtr++; - } - } - - if (fade.dir==FADE_OUT && fade.mode==FADE_COMPLETE) - { // we're done - return 0; - } - - enter = ( g_pInput->getPressedKey(KENTER) || g_pInput->getPressedKey(KCTRL) || g_pInput->getPressedKey(KALT) ); - if (enter) - { - if (fade.dir!=FADE_OUT) - { - fade.dir = FADE_OUT; - fade.curamt = PAL_FADE_SHADES; - fade.fadetimer = 0; - fade.mode = FADE_GO; - fade.rate = FADE_NORM; - } - } - lastenterstate = enter; - - gamedo_fades(); - gamedo_AnimatedTiles(); - - gamedo_frameskipping(pCKP); - if (scrollingon) gamedo_ScrollTriggers(0); - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(!g_pInput->getPressedKey(KQUIT)); - return 1; -} - -int eseq1_BackAtHome(stCloneKeenPlus *pCKP) -{ -/*int draw;*/ -int i; - std::string text[10]; - std::string strname; - std::string tempbuf; -short textline, showtimer; -unsigned short amountshown; -signed int waittimer; -int state; -int enter, lastenterstate; -int dlgX, dlgY, dlgW, dlgH; - - #define STATE_TEXTAPPEARING 0 - #define STATE_WAITASEC 1 - #define STATE_FADING 2 - - // get pointers to all the strings we're going to be using - for(i=0;i<8;i++) - { - strname = "EP1_ESEQ_PART2_PAGE" + itoa(i+1); - text[i] = getstring(strname); - } - - textline = 0; - amountshown = 0; - showtimer = 0; - state = STATE_TEXTAPPEARING; - lastenterstate = 1; - waittimer = 0; - - finale_draw("finale.ck1", pCKP->GameData[pCKP->Resources.GameSelected-1].DataDirectory); - scrollx_buf = scroll_x = 0; - scrolly_buf = scroll_y = 0; - - numplayers = 1; - player[0].x = 16; - player[0].y = 16; - player[0].playframe = BlankSprite; - - dlgX = GetStringAttribute("EP1_ESEQ_PART2_PAGE1", "LEFT"); - dlgY = GetStringAttribute("EP1_ESEQ_PART2_PAGE1", "TOP"); - dlgW = GetStringAttribute("EP1_ESEQ_PART2_PAGE1", "WIDTH"); - dlgH = GetStringAttribute("EP1_ESEQ_PART2_PAGE1", "HEIGHT"); - - fade.mode = FADE_GO; - fade.rate = FADE_NORM; - fade.dir = FADE_IN; - fade.curamt = 0; - fade.fadetimer = 0; - do - { - enter = ( g_pInput->getPressedKey(KENTER) || g_pInput->getPressedKey(KCTRL) || g_pInput->getPressedKey(KALT) ); - - sb_dialogbox(dlgX, dlgY, dlgW, dlgH); - - // draw the current text line up to the amount currently shown - tempbuf = text[textline]; - tempbuf.erase(amountshown); - g_pGraphics->sb_font_draw( tempbuf, (dlgX+1)*8, (dlgY+1)*8); - - if (state==STATE_TEXTAPPEARING) - { - if (enter) goto fullshow; - if (showtimer > LETTER_SHOW_SPD) - { // it's time to show a new letter - amountshown++; - if (amountshown > text[textline].size()) - { // reached end of line - state = STATE_WAITASEC; -// if (textline==8) - // waittimer = -BACKHOME_SHORT_WAIT_TIME*3; - // else - waittimer = -BACKHOME_SHORT_WAIT_TIME*2; - } - // if the last letter shown is a dash/cr ('Billy...are you a-'), - // show the rest of the text immediately - // (for when the mom shouts "WHAT IS THIS ONE-EYED GREEN THING..." - if (text[textline][amountshown]==13 && \ - text[textline][amountshown-1]=='-') - { - fullshow: ; - amountshown = text[textline].size(); - state = STATE_WAITASEC; - waittimer = -BACKHOME_SHORT_WAIT_TIME*3; - } - showtimer = 0; - } else showtimer++; - - // user pressed enter - if (enter) - { // show all text immediately - - } - } - else if (state==STATE_WAITASEC) - { - if (enter) goto nextline; - if (waittimer7) - { // end of text - break; - } - } - } - } - - if (fade.dir==FADE_OUT && fade.mode==FADE_COMPLETE) - return 0; - - gamedo_fades(); - gamedo_frameskipping_blitonly(); - - lastenterstate = enter; - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - if (g_pInput->getPressedKey(KQUIT)) return 1; - } while(1); - - finale_draw("finale.ck1", pCKP->GameData[pCKP->Resources.GameSelected-1].DataDirectory); - eseq_ToBeContinued(pCKP); - return 1; -} - -void eseq_ToBeContinued(stCloneKeenPlus *pCKP) -{ -int i; - std::string text; -int dlgX, dlgY, dlgW, dlgH; - - // remove all objects because eseq_showmsg will call drawobjects - for(i=0;igetPressedKey(KQUIT)) return; - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(fade.mode == FADE_GO); -} +/* ESEQ_EP1.C + Ending sequence for Episode 1. +*/ + +#include "keen.h" +#include "include/game.h" +#include "include/gamedo.h" +#include "include/gamepdo.h" +#include "sdl/CInput.h" +#include "sdl/CTimer.h" +#include "include/eseq_ep1.h" +#include "include/eseq_ep2.h" +#include "include/menu.h" +#include "CGraphics.h" + +#define CMD_MOVE 0 +#define CMD_WAIT 1 +#define CMD_SPAWNSPR 2 +#define CMD_REMOVESPR 3 +#define CMD_FADEOUT 4 +#define CMD_ENDOFQUEUE 5 +#define CMD_ENABLESCROLLING 6 +#define CMD_DISABLESCROLLING 7 + + +// start x,y map scroll position for eseq1_ShipFlys() +#define SHIPFLY_X 32 +#define SHIPFLY_Y 0 + +// worldmap scroll position for eseq1_ReturnsToShip() +#define WM_X 40 +#define WM_Y 540 + +#define LETTER_SHOW_SPD 30 +#define RETURNTOSHIP_WAIT_TIME 600 + +#define SPR_SHIP_RIGHT 115 +#define SPR_SHIP_LEFT 116 +#define SPR_EXCLAMATION 117 +#define SPR_QUESTION 118 +#define SHIPSPD 4 + +#define BACKHOME_SHORT_WAIT_TIME 250 + +int eseq1_ReturnsToShip(stCloneKeenPlus *pCKP) +{ +int i; + + for(i=0;iControl.levelcontrol.levels_completed[i] = 0; + + showmapatpos(80, WM_X, WM_Y, 0, pCKP); + + // draw keen next to his ship + g_pGraphics->drawSprite(168, 85, PMAPLEFTFRAME, 0); + // do not show player when we render the screen + numplayers = 1; + player[0].x = 0; + player[0].y = 0; + player[0].playframe = BlankSprite; + // all objects -> nonexistant + for(i=0;ipollEvents(); + g_pTimer->SpeedThrottle(); + } while(fade.mode != FADE_COMPLETE && !g_pInput->getPressedKey(KQUIT)); + + return 0; +} + + +void addshipqueue(int cmd, int time, int flag1) +{ + shipqueue[ShipQueuePtr].cmd = cmd; + shipqueue[ShipQueuePtr].time = time; + shipqueue[ShipQueuePtr].flag1 = flag1; + ShipQueuePtr++; +} + +int eseq1_ShipFlys(stCloneKeenPlus *pCKP) +{ +char enter,lastenterstate; +int x, y; +int scrollingon; + + scrollingon = 1; + + #define MARK_SPR_NUM 5 + initgame(pCKP); + + // set up the ship's route + ShipQueuePtr = 0; + addshipqueue(CMD_MOVE, 230, DUP); + addshipqueue(CMD_WAIT, 50, 0); + addshipqueue(CMD_MOVE, 2690, DDOWNRIGHT); + addshipqueue(CMD_WAIT, 100, 0); + addshipqueue(CMD_MOVE, 480, DDOWN); + addshipqueue(CMD_WAIT, 150, 0); + addshipqueue(CMD_SPAWNSPR, 0, SPR_QUESTION); + addshipqueue(CMD_DISABLESCROLLING, 0, 0); + addshipqueue(CMD_WAIT, 350, 0); + addshipqueue(CMD_REMOVESPR, 0, 0); + addshipqueue(CMD_WAIT, 50, 0); + addshipqueue(CMD_MOVE, 700, DLEFT); + addshipqueue(CMD_WAIT, 150, 0); + addshipqueue(CMD_SPAWNSPR, 0, SPR_EXCLAMATION); + addshipqueue(CMD_WAIT, 500, 0); + addshipqueue(CMD_REMOVESPR, 0, 0); + addshipqueue(CMD_WAIT, 50, 0); + addshipqueue(CMD_MOVE, 700, DRIGHT); + addshipqueue(CMD_WAIT, 25, 0); + addshipqueue(CMD_ENABLESCROLLING, 0, 0); + addshipqueue(CMD_MOVE, 465, DDOWN); + addshipqueue(CMD_FADEOUT, 0, 0); + addshipqueue(CMD_MOVE, 100, DDOWN); + addshipqueue(CMD_ENDOFQUEUE, 0, 0); + + showmapatpos(81, SHIPFLY_X, SHIPFLY_Y, 0, pCKP); + + objects[MARK_SPR_NUM].type = OBJ_YORP; // doesn't matter + objects[MARK_SPR_NUM].exists = 0; + objects[MARK_SPR_NUM].sprite = SPR_QUESTION; + + numplayers = 1; + // place the player at the center of mars + if (map_findtile(593, &x, &y)) + { // found the tile at the center of mars + player[0].x = ((x<<4)+1)<>CSF)-scroll_x; + objects[MARK_SPR_NUM].scry = (objects[MARK_SPR_NUM].y>>CSF)-scroll_y; + + // execute the current command in the queue + if (fade.dir != FADE_OUT) + { + switch(shipqueue[ShipQueuePtr].cmd) + { + case CMD_MOVE: + switch(shipqueue[ShipQueuePtr].flag1) + { + case DUP: + player[0].y-=SHIPSPD; + player[0].playframe = SPR_SHIP_RIGHT; + break; + case DDOWN: + player[0].y+=SHIPSPD/2; + player[0].playframe = SPR_SHIP_RIGHT; + break; + case DLEFT: + player[0].x-=SHIPSPD; + player[0].playframe = SPR_SHIP_LEFT; + break; + case DRIGHT: + player[0].x+=SHIPSPD; + player[0].playframe = SPR_SHIP_RIGHT; + break; + case DDOWNRIGHT: + player[0].x+=SHIPSPD*2; + player[0].y+=SHIPSPD*0.8; + player[0].playframe = SPR_SHIP_RIGHT; + break; + } + break; + case CMD_SPAWNSPR: + objects[MARK_SPR_NUM].sprite = shipqueue[ShipQueuePtr].flag1; + objects[MARK_SPR_NUM].exists = 1; + break; + case CMD_REMOVESPR: + objects[MARK_SPR_NUM].sprite = shipqueue[ShipQueuePtr].flag1; + objects[MARK_SPR_NUM].exists = 0; + break; + case CMD_ENABLESCROLLING: + scrollingon = 1; + break; + case CMD_DISABLESCROLLING: + scrollingon = 0; + break; + case CMD_WAIT: + break; + case CMD_FADEOUT: + if (fade.dir!=FADE_OUT) + { + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + fade.mode = FADE_GO; + fade.rate = FADE_NORM; + } + break; + default: break; + } + // decrease the time remaining + if (shipqueue[ShipQueuePtr].time) + { + shipqueue[ShipQueuePtr].time--; + } + else + { // no time left on this command, go to next cmd + ShipQueuePtr++; + } + } + + if (fade.dir==FADE_OUT && fade.mode==FADE_COMPLETE) + { // we're done + return 0; + } + + enter = ( g_pInput->getPressedKey(KENTER) || g_pInput->getPressedKey(KCTRL) || g_pInput->getPressedKey(KALT) ); + if (enter) + { + if (fade.dir!=FADE_OUT) + { + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + fade.mode = FADE_GO; + fade.rate = FADE_NORM; + } + } + lastenterstate = enter; + + gamedo_fades(); + gamedo_AnimatedTiles(); + + gamedo_frameskipping(pCKP); + if (scrollingon) gamedo_ScrollTriggers(0); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!g_pInput->getPressedKey(KQUIT)); + return 1; +} + +int eseq1_BackAtHome(stCloneKeenPlus *pCKP) +{ +/*int draw;*/ +int i; +char *text[10]; +char strname[40]; +char tempbuf[200]; +short textline, showtimer; +unsigned short amountshown; +signed int waittimer; +int state; +int enter, lastenterstate; +int dlgX, dlgY, dlgW, dlgH; + + #define STATE_TEXTAPPEARING 0 + #define STATE_WAITASEC 1 + #define STATE_FADING 2 + + // get pointers to all the strings we're going to be using + for(i=0;i<8;i++) + { + sprintf(strname, "EP1_ESEQ_PART2_PAGE%d", i+1); + text[i] = getstring(strname); + } + + textline = 0; + amountshown = 0; + showtimer = 0; + state = STATE_TEXTAPPEARING; + lastenterstate = 1; + waittimer = 0; + + finale_draw("finale.ck1", pCKP->GameData[pCKP->Resources.GameSelected-1].DataDirectory); + scrollx_buf = scroll_x = 0; + scrolly_buf = scroll_y = 0; + + numplayers = 1; + player[0].x = 16; + player[0].y = 16; + player[0].playframe = BlankSprite; + + dlgX = GetStringAttribute("EP1_ESEQ_PART2_PAGE1", "LEFT"); + dlgY = GetStringAttribute("EP1_ESEQ_PART2_PAGE1", "TOP"); + dlgW = GetStringAttribute("EP1_ESEQ_PART2_PAGE1", "WIDTH"); + dlgH = GetStringAttribute("EP1_ESEQ_PART2_PAGE1", "HEIGHT"); + + fade.mode = FADE_GO; + fade.rate = FADE_NORM; + fade.dir = FADE_IN; + fade.curamt = 0; + fade.fadetimer = 0; + do + { + enter = ( g_pInput->getPressedKey(KENTER) || g_pInput->getPressedKey(KCTRL) || g_pInput->getPressedKey(KALT) ); + + sb_dialogbox(dlgX, dlgY, dlgW, dlgH); + + // draw the current text line up to the amount currently shown + strcpy(tempbuf, text[textline]); + tempbuf[amountshown] = 0; + g_pGraphics->sb_font_draw( (unsigned char*) tempbuf, (dlgX+1)*8, (dlgY+1)*8); + + if (state==STATE_TEXTAPPEARING) + { + if (enter) goto fullshow; + if (showtimer > LETTER_SHOW_SPD) + { // it's time to show a new letter + amountshown++; + if (amountshown > strlen(text[textline])) + { // reached end of line + state = STATE_WAITASEC; +// if (textline==8) + // waittimer = -BACKHOME_SHORT_WAIT_TIME*3; + // else + waittimer = -BACKHOME_SHORT_WAIT_TIME*2; + } + // if the last letter shown is a dash/cr ('Billy...are you a-'), + // show the rest of the text immediately + // (for when the mom shouts "WHAT IS THIS ONE-EYED GREEN THING..." + if (text[textline][amountshown]==13 && \ + text[textline][amountshown-1]=='-') + { + fullshow: ; + amountshown = strlen(text[textline]); + state = STATE_WAITASEC; + waittimer = -BACKHOME_SHORT_WAIT_TIME*3; + } + showtimer = 0; + } else showtimer++; + + // user pressed enter + if (enter) + { // show all text immediately + + } + } + else if (state==STATE_WAITASEC) + { + if (enter) goto nextline; + if (waittimer7) + { // end of text + break; + } + } + } + } + + if (fade.dir==FADE_OUT && fade.mode==FADE_COMPLETE) + return 0; + + gamedo_fades(); + gamedo_frameskipping_blitonly(); + + lastenterstate = enter; + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + if (g_pInput->getPressedKey(KQUIT)) return 1; + } while(1); + + finale_draw("finale.ck1", pCKP->GameData[pCKP->Resources.GameSelected-1].DataDirectory); + eseq_ToBeContinued(pCKP); + return 1; +} + +void eseq_ToBeContinued(stCloneKeenPlus *pCKP) +{ +int i; +char *text; +int dlgX, dlgY, dlgW, dlgH; + + // remove all objects because eseq_showmsg will call drawobjects + for(i=0;igetPressedKey(KQUIT)) return; + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(fade.mode == FADE_GO); +} diff --git a/src/eseq_ep2.cpp b/src/eseq_ep2.cpp index 167040c4d..71e4b0ffa 100644 --- a/src/eseq_ep2.cpp +++ b/src/eseq_ep2.cpp @@ -1,716 +1,714 @@ -/* ESEQ_EP2.C - Ending sequence for Episode 2. -*/ - -#include "keen.h" -#include "include/game.h" -#include "include/gamedo.h" -#include "include/gamepdo.h" -#include "sdl/CTimer.h" -#include "sdl/CInput.h" -#include "sdl/sound/CSound.h" -#include "include/eseq_ep2.h" -#include "include/eseq_ep1.h" -#include "include/menu.h" -#include "include/enemyai.h" -#include "CGraphics.h" -#include "StringUtils.h" - - -#define CMD_MOVE 0 -#define CMD_WAIT 1 -#define CMD_SPAWNSPR 2 -#define CMD_REMOVESPR 3 -#define CMD_FADEOUT 4 -#define CMD_ENDOFQUEUE 5 -#define CMD_ENABLESCROLLING 6 -#define CMD_DISABLESCROLLING 7 - -stShipQueue shipqueue[32]; -int ShipQueuePtr; - -#define LETTER_SHOW_SPD 30 - -// start x,y map scroll position for eseq2_TantalusRay() -#define TANTALUS_X 0 -#define TANTALUS_Y 0 - -#define TANTALUS_SPD_X 21 -#define TANTALUS_SPD_Y 9 - -#define TANTALUS_SPRITE 58 - -#define TAN_DELAY_BEFORE_FIRE 500 - -#define TAN_STATE_WAITBEFOREFIRE 0 -#define TAN_STATE_FIRING 1 -#define TAN_STATE_EARTH_EXPLODING 2 -#define TAN_STATE_CHUNKS_FLYING 3 -#define TAN_STATE_GAMEOVER 4 - -#define EARTHCHUNK_BIG_UP 64 -#define EARTHCHUNK_BIG_DN 66 -#define EARTHCHUNK_SMALL_UP 68 -#define EARTHCHUNK_SMALL_DN 70 - -int eseq2_TantalusRay(stCloneKeenPlus *pCKP) -{ -char enter,lastenterstate; -int x, y, t, o, i; -int tantalus_animframe, tantalus_animtimer; -int state, timer, spawnedcount; - - o=0; - - fade.mode = FADE_GO; - fade.rate = FADE_NORM; - fade.dir = FADE_OUT; - fade.curamt = PAL_FADE_SHADES; - fade.fadetimer = 0; - do - { - gamedo_fades(); - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); } while(fade.mode!=FADE_COMPLETE); - - pCKP->Control.levelcontrol.dark = 0; - g_pGraphics->initPalette(pCKP->Control.levelcontrol.dark); - - initgame(pCKP); - state = TAN_STATE_WAITBEFOREFIRE; - - showmapatpos(81,TANTALUS_X, TANTALUS_Y, 0, pCKP); - - AllPlayersInvisible(); - numplayers = 1; - player[0].hideplayer = 0; - objects[player[0].useObject].onscreen = 1; - - // place the player (which is actually the tantalus ray) at the mouth - // of the vorticon mothership - if (map_findtile(593, &x, &y)) - { // found the tile - player[0].x = ((x<<4)-1)< TAN_DELAY_BEFORE_FIRE) - { - g_pSound->playStereofromCoord(SOUND_KEEN_FIRE, PLAY_NOW, objects[o].scrx); - state = TAN_STATE_FIRING; - timer = 0; - } - else timer++; - break; - case TAN_STATE_FIRING: - - if (tantalus_animtimer>5) - { - tantalus_animframe ^= 1; - player[0].playframe = TANTALUS_SPRITE + tantalus_animframe; - } - else tantalus_animtimer++; - - player[0].x += TANTALUS_SPD_X; - player[0].y += TANTALUS_SPD_Y; - - t = getmaptileat((player[0].x>>CSF)+(sprites[TANTALUS_SPRITE].xsize/2), (player[0].y>>CSF)+(sprites[TANTALUS_SPRITE].ysize/2)); - if (t==586) - { // hit center of earth - state = TAN_STATE_EARTH_EXPLODING; - player[0].playframe = BlankSprite; - timer = 0; - spawnedcount = 0; - srand(300); - o = spawn_object(player[0].x+(24<playSound(SOUND_EARTHPOW, PLAY_NOW); - } - break; - case TAN_STATE_EARTH_EXPLODING: - if (!timer) - { - if (spawnedcount<16) o = spawn_object(player[0].x+((rand()%32)< 4) - { - objects[o].sprite = EARTHCHUNK_SMALL_DN; - } - else - { - objects[o].sprite = EARTHCHUNK_SMALL_UP; - } - } - - break; - case 6: - o = spawn_object(player[0].x+(16<playSound(SOUND_GAME_OVER, PLAY_NOW); - SetGameOver(pCKP); - break; - } - spawnedcount++; - timer = 60; - } - else timer--; - break; - case TAN_STATE_GAMEOVER: - break; - } - - if (fade.dir==FADE_OUT && fade.mode==FADE_COMPLETE) - { // we're done - return 0; - } - - enter = (g_pInput->getPressedCommand(KENTER) || g_pInput->getPressedCommand(KCTRL) || g_pInput->getPressedCommand(KALT) ); - if (enter && state==TAN_STATE_GAMEOVER) - { - if (fade.dir!=FADE_OUT) - { - fade.dir = FADE_OUT; - fade.curamt = PAL_FADE_SHADES; - fade.fadetimer = 0; - fade.rate = FADE_NORM; - fade.mode = FADE_GO; - } - } - lastenterstate = enter; - - gamedo_fades(); - if (state!=TAN_STATE_GAMEOVER) gamedo_AnimatedTiles(); - - gamedo_frameskipping(pCKP); - gamedo_enemyai(pCKP); - - if(((player[0].x>>CSF)-scroll_x) > 160-16) map_scroll_right(); - if (((player[0].y>>CSF)-scroll_y) > 100) - { - map_scroll_down(); - } - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(!g_pInput->getPressedCommand(KQUIT)); - return 1; -} - -void eseq2_vibrate(stCloneKeenPlus *pCKP) -{ -int xamt, yamt; -int xdir, ydir; -int vibratetimes; -//int enter,lastenterstate; -int i; -int x,y,w,h; - - vibratetimes = 0; - - #define VIBRATE_AMT 16 - #define VIBRATE_NUM_FRAMES 500 - - xamt = yamt = 0; - xdir = 0; ydir = 0; - do - { - - // undo the scroll from last time - if (!xdir) - { - for(i=0;i>CSF)-scroll_x; - objects[i].scry = (objects[i].y>>CSF)-scroll_y; - } - } - - // show the frame - gamedo_frameskipping(pCKP); - vibratetimes++; - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(!g_pInput->getPressedCommand(KQUIT) && vibratetimes < VIBRATE_NUM_FRAMES); - - // display the "uh-oh." - x = GetStringAttribute("EP2_AfterVibrateString", "LEFT"); - y = GetStringAttribute("EP2_AfterVibrateString", "TOP"); - w = GetStringAttribute("EP2_AfterVibrateString", "WIDTH"); - h = GetStringAttribute("EP2_AfterVibrateString", "HEIGHT"); - - eseq_showmsg(getstring("EP2_AfterVibrateString"),x,y,w,h,1, pCKP); -} - - -#define HEADFOREARTH_X 0 -#define HEADFOREARTH_Y 0 - -#define HEADFOREARTH_WAIT_TIME 600 - -#define SPR_SHIP_RIGHT_EP2 132 -#define SPR_SHIP_LEFT_EP2 133 -#define SPR_VORTICON_MOTHERSHIP 72 - -#define HEADSFOREARTH_X 3 -#define HEADSFOREARTH_Y 15 -#define HEADSFOREARTH_W 33 -#define HEADSFOREARTH_H 8 - -void eseq_showmsg(const std::string& text, int boxleft, int boxtop, int boxwidth, int boxheight, char autodismiss, stCloneKeenPlus *pCKP) -{ -//int draw; -//int i; - - std::string tempbuf; -char textline, showtimer; -unsigned int amountshown; -int waittimer; -int cancel, lastcancelstate; - - textline = 0; - amountshown = 0; - showtimer = 0; - lastcancelstate = 1; - waittimer = 0; - - do - { - gamedo_fades(); - gamedo_AnimatedTiles(); - gamedo_render_drawobjects(pCKP); - - cancel = (g_pInput->getPressedCommand(KENTER) || g_pInput->getPressedCommand(KCTRL) || g_pInput->getPressedCommand(KALT)); - - // draw the text up to the amount currently shown - tempbuf = text; - tempbuf.erase(amountshown); - sb_dialogbox(boxleft,boxtop,boxwidth,boxheight); - g_pGraphics->sb_font_draw( tempbuf, (boxleft+1)*8, (boxtop+1+textline)*8); - - gamedo_frameskipping_blitonly(); - gamedo_render_eraseobjects(); - - if (showtimer > LETTER_SHOW_SPD) - { // it's time to show a new letter - if (amountshown < text.size()) - { - amountshown++; - } - showtimer = 0; - } else showtimer++; - - // user pressed enter or some other key - if (cancel && !lastcancelstate) - { - if (amountshown < text.size()) - { - amountshown = text.size(); - } - else return; - } - - // when all text is shown wait a sec then return - if (autodismiss) - { - if (amountshown >= text.size()) - { - if (waittimer > HEADFOREARTH_WAIT_TIME) return; - waittimer++; - } - } - - - lastcancelstate = cancel; - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(!g_pInput->getPressedCommand(KQUIT)); - return; -} - -int eseq2_HeadsForEarth(stCloneKeenPlus *pCKP) -{ -char enter,lastenterstate; -int x, y; -int downtimer; -int afterfadewaittimer; - - initgame(pCKP); - - // set up the ship's route - ShipQueuePtr = 0; - addshipqueue(CMD_WAIT, 10, 0); - addshipqueue(CMD_MOVE, 2360, DDOWNRIGHT); - addshipqueue(CMD_FADEOUT, 0, 0); - - showmapatpos(81, HEADFOREARTH_X, HEADFOREARTH_Y, 0, pCKP); - - numplayers = 1; - // place the player near the vorticon mothership - if (map_findtile(593, &x, &y)) - { - player[0].x = ((x<<4)+2)< 6) - { - player[0].y++; - downtimer = 0; - } - else downtimer++; - break; - case CMD_WAIT: - break; - case CMD_FADEOUT: - if (fade.dir!=FADE_OUT) - { - fade.dir = FADE_OUT; - fade.curamt = PAL_FADE_SHADES; - fade.fadetimer = 0; - fade.rate = FADE_NORM; - fade.mode = FADE_GO; - } - break; - default: break; - } - // decrease the time remaining - if (shipqueue[ShipQueuePtr].time) - { - shipqueue[ShipQueuePtr].time--; - } - else - { // no time left on this command, go to next cmd - ShipQueuePtr++; - } - } - - if (fade.dir==FADE_OUT && fade.mode==FADE_COMPLETE) - { - if (afterfadewaittimer > 80) - { - return 0; - } - else afterfadewaittimer++; - } - - enter = (g_pInput->getPressedCommand(KENTER)||g_pInput->getPressedCommand(KCTRL)||g_pInput->getPressedCommand(KALT)); - if (enter && !lastenterstate) - { - if (fade.dir!=FADE_OUT) - { - fade.dir = FADE_OUT; - fade.curamt = PAL_FADE_SHADES; - fade.fadetimer = 0; - fade.rate = FADE_NORM; - fade.mode = FADE_GO; - } - } - lastenterstate = enter; - - gamedo_fades(); - gamedo_AnimatedTiles(); - - gamedo_frameskipping(pCKP); - gamedo_ScrollTriggers(0); - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(!g_pInput->getPressedCommand(KQUIT)); - return 1; -} - -#define LIMPSHOME_X 0 -#define LIMPSHOME_Y 344 - -int eseq2_LimpsHome(stCloneKeenPlus *pCKP) -{ -char enter,lastenterstate; -//int x, y; -int downtimer; -int afterfadewaittimer = 0; - - initgame(pCKP); - - // set up the ship's route - ShipQueuePtr = 0; - addshipqueue(CMD_WAIT, 10, 0); - addshipqueue(CMD_MOVE, 1600, DUPLEFT); - addshipqueue(CMD_FADEOUT, 0, 0); - - showmapatpos(81, LIMPSHOME_X, LIMPSHOME_Y, 0, pCKP); - - numplayers = 1; - player[0].x = (10 <<4< 80) - { - return 0; - } - else afterfadewaittimer++; - } - - enter = (g_pInput->getPressedCommand(KENTER)||g_pInput->getPressedCommand(KCTRL)||g_pInput->getPressedCommand(KALT)); - if (enter && !lastenterstate) - { - if (fade.dir!=FADE_OUT) - { - fade.dir = FADE_OUT; - fade.curamt = PAL_FADE_SHADES; - fade.fadetimer = 0; - fade.rate = FADE_NORM; - fade.mode = FADE_GO; - } - } - lastenterstate = enter; - - gamedo_fades(); - gamedo_AnimatedTiles(); - - gamedo_frameskipping(pCKP); - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(!g_pInput->getPressedCommand(KQUIT)); - return 1; -} - -int eseq2_SnowedOutside(stCloneKeenPlus *pCKP) -{ -int curpage; -int lastpage; - std::string tempstr; - std::string text; -//int enter, lastenterstate; -int dlgX, dlgY, dlgW, dlgH; - - scrollx_buf = scroll_x = 0; - scrolly_buf = scroll_y = 0; - finale_draw("finale.ck2", pCKP->GameData[pCKP->Resources.GameSelected-1].DataDirectory); - - curpage = 1; - fade.mode = FADE_GO; - fade.rate = FADE_NORM; - fade.dir = FADE_IN; - fade.curamt = 0; - fade.fadetimer = 0; - - numplayers = 1; - player[0].x = player[0].y = 0; - player[0].playframe = BlankSprite; - - do - { - tempstr = "EP2_ESEQ_PART3_PAGE" + itoa(curpage); - text = getstring(tempstr); - dlgX = GetStringAttribute(tempstr, "LEFT"); - dlgY = GetStringAttribute(tempstr, "TOP"); - dlgW = GetStringAttribute(tempstr, "WIDTH"); - dlgH = GetStringAttribute(tempstr, "HEIGHT"); - lastpage = GetStringAttribute(tempstr, "LASTPAGE"); - - eseq_showmsg(text, dlgX, dlgY, dlgW, dlgH, 1, pCKP); - if (lastpage==1) break; - - curpage++; - } while(!g_pInput->getPressedCommand(KQUIT)); - - finale_draw("finale.ck2", pCKP->GameData[pCKP->Resources.GameSelected-1].DataDirectory); - eseq_ToBeContinued(pCKP); - - return 0; -} +/* ESEQ_EP2.C + Ending sequence for Episode 2. +*/ + +#include "keen.h" +#include "include/game.h" +#include "include/gamedo.h" +#include "include/gamepdo.h" +#include "sdl/CTimer.h" +#include "sdl/CInput.h" +#include "sdl/sound/CSound.h" +#include "include/eseq_ep2.h" +#include "include/eseq_ep1.h" +#include "include/menu.h" +#include "include/enemyai.h" +#include "CGraphics.h" + +#define CMD_MOVE 0 +#define CMD_WAIT 1 +#define CMD_SPAWNSPR 2 +#define CMD_REMOVESPR 3 +#define CMD_FADEOUT 4 +#define CMD_ENDOFQUEUE 5 +#define CMD_ENABLESCROLLING 6 +#define CMD_DISABLESCROLLING 7 + +stShipQueue shipqueue[32]; +int ShipQueuePtr; + +#define LETTER_SHOW_SPD 30 + +// start x,y map scroll position for eseq2_TantalusRay() +#define TANTALUS_X 0 +#define TANTALUS_Y 0 + +#define TANTALUS_SPD_X 21 +#define TANTALUS_SPD_Y 9 + +#define TANTALUS_SPRITE 58 + +#define TAN_DELAY_BEFORE_FIRE 500 + +#define TAN_STATE_WAITBEFOREFIRE 0 +#define TAN_STATE_FIRING 1 +#define TAN_STATE_EARTH_EXPLODING 2 +#define TAN_STATE_CHUNKS_FLYING 3 +#define TAN_STATE_GAMEOVER 4 + +#define EARTHCHUNK_BIG_UP 64 +#define EARTHCHUNK_BIG_DN 66 +#define EARTHCHUNK_SMALL_UP 68 +#define EARTHCHUNK_SMALL_DN 70 + +int eseq2_TantalusRay(stCloneKeenPlus *pCKP) +{ +char enter,lastenterstate; +int x, y, t, o, i; +int tantalus_animframe, tantalus_animtimer; +int state, timer, spawnedcount; + + o=0; + + fade.mode = FADE_GO; + fade.rate = FADE_NORM; + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + do + { + gamedo_fades(); + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); } while(fade.mode!=FADE_COMPLETE); + + pCKP->Control.levelcontrol.dark = 0; + g_pGraphics->initPalette(pCKP->Control.levelcontrol.dark); + + initgame(pCKP); + state = TAN_STATE_WAITBEFOREFIRE; + + showmapatpos(81,TANTALUS_X, TANTALUS_Y, 0, pCKP); + + AllPlayersInvisible(); + numplayers = 1; + player[0].hideplayer = 0; + objects[player[0].useObject].onscreen = 1; + + // place the player (which is actually the tantalus ray) at the mouth + // of the vorticon mothership + if (map_findtile(593, &x, &y)) + { // found the tile + player[0].x = ((x<<4)-1)< TAN_DELAY_BEFORE_FIRE) + { + g_pSound->playStereofromCoord(SOUND_KEEN_FIRE, PLAY_NOW, objects[o].scrx); + state = TAN_STATE_FIRING; + timer = 0; + } + else timer++; + break; + case TAN_STATE_FIRING: + + if (tantalus_animtimer>5) + { + tantalus_animframe ^= 1; + player[0].playframe = TANTALUS_SPRITE + tantalus_animframe; + } + else tantalus_animtimer++; + + player[0].x += TANTALUS_SPD_X; + player[0].y += TANTALUS_SPD_Y; + + t = getmaptileat((player[0].x>>CSF)+(sprites[TANTALUS_SPRITE].xsize/2), (player[0].y>>CSF)+(sprites[TANTALUS_SPRITE].ysize/2)); + if (t==586) + { // hit center of earth + state = TAN_STATE_EARTH_EXPLODING; + player[0].playframe = BlankSprite; + timer = 0; + spawnedcount = 0; + srand(300); + o = spawn_object(player[0].x+(24<playSound(SOUND_EARTHPOW, PLAY_NOW); + } + break; + case TAN_STATE_EARTH_EXPLODING: + if (!timer) + { + if (spawnedcount<16) o = spawn_object(player[0].x+((rand()%32)< 4) + { + objects[o].sprite = EARTHCHUNK_SMALL_DN; + } + else + { + objects[o].sprite = EARTHCHUNK_SMALL_UP; + } + } + + break; + case 6: + o = spawn_object(player[0].x+(16<playSound(SOUND_GAME_OVER, PLAY_NOW); + SetGameOver(pCKP); + break; + } + spawnedcount++; + timer = 60; + } + else timer--; + break; + case TAN_STATE_GAMEOVER: + break; + } + + if (fade.dir==FADE_OUT && fade.mode==FADE_COMPLETE) + { // we're done + return 0; + } + + enter = (g_pInput->getPressedCommand(KENTER) || g_pInput->getPressedCommand(KCTRL) || g_pInput->getPressedCommand(KALT) ); + if (enter && state==TAN_STATE_GAMEOVER) + { + if (fade.dir!=FADE_OUT) + { + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + fade.rate = FADE_NORM; + fade.mode = FADE_GO; + } + } + lastenterstate = enter; + + gamedo_fades(); + if (state!=TAN_STATE_GAMEOVER) gamedo_AnimatedTiles(); + + gamedo_frameskipping(pCKP); + gamedo_enemyai(pCKP); + + if(((player[0].x>>CSF)-scroll_x) > 160-16) map_scroll_right(); + if (((player[0].y>>CSF)-scroll_y) > 100) + { + map_scroll_down(); + } + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!g_pInput->getPressedCommand(KQUIT)); + return 1; +} + +void eseq2_vibrate(stCloneKeenPlus *pCKP) +{ +int xamt, yamt; +int xdir, ydir; +int vibratetimes; +//int enter,lastenterstate; +int i; +int x,y,w,h; + + vibratetimes = 0; + + #define VIBRATE_AMT 16 + #define VIBRATE_NUM_FRAMES 500 + + xamt = yamt = 0; + xdir = 0; ydir = 0; + do + { + + // undo the scroll from last time + if (!xdir) + { + for(i=0;i>CSF)-scroll_x; + objects[i].scry = (objects[i].y>>CSF)-scroll_y; + } + } + + // show the frame + gamedo_frameskipping(pCKP); + vibratetimes++; + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!g_pInput->getPressedCommand(KQUIT) && vibratetimes < VIBRATE_NUM_FRAMES); + + // display the "uh-oh." + x = GetStringAttribute("EP2_AfterVibrateString", "LEFT"); + y = GetStringAttribute("EP2_AfterVibrateString", "TOP"); + w = GetStringAttribute("EP2_AfterVibrateString", "WIDTH"); + h = GetStringAttribute("EP2_AfterVibrateString", "HEIGHT"); + + eseq_showmsg(getstring("EP2_AfterVibrateString"),x,y,w,h,1, pCKP); +} + + +#define HEADFOREARTH_X 0 +#define HEADFOREARTH_Y 0 + +#define HEADFOREARTH_WAIT_TIME 600 + +#define SPR_SHIP_RIGHT_EP2 132 +#define SPR_SHIP_LEFT_EP2 133 +#define SPR_VORTICON_MOTHERSHIP 72 + +#define HEADSFOREARTH_X 3 +#define HEADSFOREARTH_Y 15 +#define HEADSFOREARTH_W 33 +#define HEADSFOREARTH_H 8 + +void eseq_showmsg(char *text, int boxleft, int boxtop, int boxwidth, int boxheight, char autodismiss, stCloneKeenPlus *pCKP) +{ +//int draw; +//int i; + +char tempbuf[1024]; +char textline, showtimer; +unsigned int amountshown; +int waittimer; +int cancel, lastcancelstate; + + textline = 0; + amountshown = 0; + showtimer = 0; + lastcancelstate = 1; + waittimer = 0; + + do + { + gamedo_fades(); + gamedo_AnimatedTiles(); + gamedo_render_drawobjects(pCKP); + + cancel = (g_pInput->getPressedCommand(KENTER) || g_pInput->getPressedCommand(KCTRL) || g_pInput->getPressedCommand(KALT)); + + // draw the text up to the amount currently shown + strcpy(tempbuf, text); + tempbuf[amountshown] = 0; + sb_dialogbox(boxleft,boxtop,boxwidth,boxheight); + g_pGraphics->sb_font_draw( (unsigned char*)tempbuf, (boxleft+1)*8, (boxtop+1+textline)*8); + + gamedo_frameskipping_blitonly(); + gamedo_render_eraseobjects(); + + if (showtimer > LETTER_SHOW_SPD) + { // it's time to show a new letter + if (amountshown < strlen(text)) + { + amountshown++; + } + showtimer = 0; + } else showtimer++; + + // user pressed enter or some other key + if (cancel && !lastcancelstate) + { + if (amountshown < strlen(text)) + { + amountshown = strlen(text); + } + else return; + } + + // when all text is shown wait a sec then return + if (autodismiss) + { + if (amountshown >= strlen(text)) + { + if (waittimer > HEADFOREARTH_WAIT_TIME) return; + waittimer++; + } + } + + + lastcancelstate = cancel; + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!g_pInput->getPressedCommand(KQUIT)); + return; +} + +int eseq2_HeadsForEarth(stCloneKeenPlus *pCKP) +{ +char enter,lastenterstate; +int x, y; +int downtimer; +int afterfadewaittimer; + + initgame(pCKP); + + // set up the ship's route + ShipQueuePtr = 0; + addshipqueue(CMD_WAIT, 10, 0); + addshipqueue(CMD_MOVE, 2360, DDOWNRIGHT); + addshipqueue(CMD_FADEOUT, 0, 0); + + showmapatpos(81, HEADFOREARTH_X, HEADFOREARTH_Y, 0, pCKP); + + numplayers = 1; + // place the player near the vorticon mothership + if (map_findtile(593, &x, &y)) + { + player[0].x = ((x<<4)+2)< 6) + { + player[0].y++; + downtimer = 0; + } + else downtimer++; + break; + case CMD_WAIT: + break; + case CMD_FADEOUT: + if (fade.dir!=FADE_OUT) + { + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + fade.rate = FADE_NORM; + fade.mode = FADE_GO; + } + break; + default: break; + } + // decrease the time remaining + if (shipqueue[ShipQueuePtr].time) + { + shipqueue[ShipQueuePtr].time--; + } + else + { // no time left on this command, go to next cmd + ShipQueuePtr++; + } + } + + if (fade.dir==FADE_OUT && fade.mode==FADE_COMPLETE) + { + if (afterfadewaittimer > 80) + { + return 0; + } + else afterfadewaittimer++; + } + + enter = (g_pInput->getPressedCommand(KENTER)||g_pInput->getPressedCommand(KCTRL)||g_pInput->getPressedCommand(KALT)); + if (enter && !lastenterstate) + { + if (fade.dir!=FADE_OUT) + { + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + fade.rate = FADE_NORM; + fade.mode = FADE_GO; + } + } + lastenterstate = enter; + + gamedo_fades(); + gamedo_AnimatedTiles(); + + gamedo_frameskipping(pCKP); + gamedo_ScrollTriggers(0); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!g_pInput->getPressedCommand(KQUIT)); + return 1; +} + +#define LIMPSHOME_X 0 +#define LIMPSHOME_Y 344 + +int eseq2_LimpsHome(stCloneKeenPlus *pCKP) +{ +char enter,lastenterstate; +//int x, y; +int downtimer; +int afterfadewaittimer = 0; + + initgame(pCKP); + + // set up the ship's route + ShipQueuePtr = 0; + addshipqueue(CMD_WAIT, 10, 0); + addshipqueue(CMD_MOVE, 1600, DUPLEFT); + addshipqueue(CMD_FADEOUT, 0, 0); + + showmapatpos(81, LIMPSHOME_X, LIMPSHOME_Y, 0, pCKP); + + numplayers = 1; + player[0].x = (10 <<4< 80) + { + return 0; + } + else afterfadewaittimer++; + } + + enter = (g_pInput->getPressedCommand(KENTER)||g_pInput->getPressedCommand(KCTRL)||g_pInput->getPressedCommand(KALT)); + if (enter && !lastenterstate) + { + if (fade.dir!=FADE_OUT) + { + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + fade.rate = FADE_NORM; + fade.mode = FADE_GO; + } + } + lastenterstate = enter; + + gamedo_fades(); + gamedo_AnimatedTiles(); + + gamedo_frameskipping(pCKP); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!g_pInput->getPressedCommand(KQUIT)); + return 1; +} + +int eseq2_SnowedOutside(stCloneKeenPlus *pCKP) +{ +int curpage; +int lastpage; +char tempstr[80]; +char *text; +//int enter, lastenterstate; +int dlgX, dlgY, dlgW, dlgH; + + scrollx_buf = scroll_x = 0; + scrolly_buf = scroll_y = 0; + finale_draw("finale.ck2", pCKP->GameData[pCKP->Resources.GameSelected-1].DataDirectory); + + curpage = 1; + fade.mode = FADE_GO; + fade.rate = FADE_NORM; + fade.dir = FADE_IN; + fade.curamt = 0; + fade.fadetimer = 0; + + numplayers = 1; + player[0].x = player[0].y = 0; + player[0].playframe = BlankSprite; + + do + { + sprintf(tempstr, "EP2_ESEQ_PART3_PAGE%d", curpage); + text = getstring(tempstr); + dlgX = GetStringAttribute(tempstr, "LEFT"); + dlgY = GetStringAttribute(tempstr, "TOP"); + dlgW = GetStringAttribute(tempstr, "WIDTH"); + dlgH = GetStringAttribute(tempstr, "HEIGHT"); + lastpage = GetStringAttribute(tempstr, "LASTPAGE"); + + eseq_showmsg(text, dlgX, dlgY, dlgW, dlgH, 1, pCKP); + if (lastpage==1) break; + + curpage++; + } while(!g_pInput->getPressedCommand(KQUIT)); + + finale_draw("finale.ck2", pCKP->GameData[pCKP->Resources.GameSelected-1].DataDirectory); + eseq_ToBeContinued(pCKP); + + return 0; +} diff --git a/src/fileio.cpp b/src/fileio.cpp index 2d84d3c8a..8f7cc704b 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -1,532 +1,536 @@ -/* FILEIO.C - Functions responsible for loading data from files, such as the one that - decodes the level map files (loadmap()) and the one that loads in the - tile attribute data contained in ep?attr.dat (loadtileattributes()). - The functions for loading the graphics (EGALATCH&EGASPRIT) are in latch.c. -*/ - -#include "keen.h" -#include "sdl/CVideoDriver.h" -#include "sdl/sound/CSound.h" -#include "hqp/CMusic.h" -#include "include/fileio.h" -#include "include/fileio/rle.h" -#include "vorticon/CPlayer.h" -#include "CLogFile.h" -#include "CGraphics.h" -#include -#include -#include -#include "StringUtils.h" - -extern CPlayer *Player; - -unsigned int curmapx, curmapy; -unsigned char mapdone; -void addmaptile(unsigned int t) -{ - map.mapdata[curmapx][curmapy] = t; - curmapx++; - if (curmapx >= map.xsize) - { - curmapx = 0; - curmapy++; - - if (curmapy >= map.ysize) mapdone = 1; - } -} - -bool renameFilenamesLowerCase(const std::string& dir_name) -{ -#ifdef TARGET_WIN32 - return true; -#else - DIR *p_Dir; - char newname[256]; - char buf[256]; - struct dirent *dp; - - memset(newname,0,256); - strcpy(buf,dir_name.c_str()); - - if(buf[0] == '\0') - strcpy(buf,"./"); - - chdir("data"); - - if((p_Dir = opendir(buf))==NULL) - return false; - - bool retval = true; - // This function checks if all the files in the directory are lower case. - // If they aren't rename them - while((dp = readdir(p_Dir)) != NULL) - { - if(dp->d_type == DT_REG) - { - strcpy(newname,dp->d_name); - - int len = strlen(newname); - for(int pos=0 ; pos < len ; pos++ ) - if(newname[pos] >= 'A' && newname[pos] <= 'Z') - newname[pos] += ('a'-'A'); - - if(strncmp(newname,dp->d_name,strlen(dp->d_name)) != 0) - if(rename(dp->d_name,newname) != -1) - retval &= true; - } - } - - closedir(p_Dir); - - chdir("../"); - - return retval; - -#endif -} - -short checkConsistencyofGameData(stGameData *p_GameData) -{ - short ok = 0; - - FILE *fp; - - // Let's define which files need to be read! - if(p_GameData->Episode >= 1 && p_GameData->Episode <= 3) - { - p_GameData->FileList[1] = "keen" + itoa(p_GameData->Episode) + ".exe"; - p_GameData->FileList[2] = "egahead.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[3] = "egasprit.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[4] = "egalatch.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[5] = "finale.ck" + itoa(p_GameData->Episode); - - // Levels! - p_GameData->FileList[6] = "level01.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[7] = "level02.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[8] = "level03.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[9] = "level04.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[10] = "level05.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[11] = "level06.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[12] = "level07.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[13] = "level08.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[14] = "level09.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[15] = "level10.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[16] = "level11.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[17] = "level12.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[18] = "level13.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[19] = "level14.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[20] = "level15.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[21] = "level16.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[22] = "level80.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[23] = "level81.ck" + itoa(p_GameData->Episode); - p_GameData->FileList[24] = "level90.ck" + itoa(p_GameData->Episode); - - // Other - if(p_GameData->Episode == 1) - p_GameData->FileList[24] = "sounds.ck" + itoa(p_GameData->Episode); - } - - // Rename all the the files in the directory to lower case - if(!renameFilenamesLowerCase(p_GameData->DataDirectory)) - { - g_pLogFile->ftextOut(PURPLE,"WARNING: There was an error while trying to format correctly the game data."); - g_pLogFile->ftextOut(PURPLE,"Please check, if you have write permissions on the game data directory and it is accessible
"); - } - - // Finally check if they really exist! - int c=0; - for(c = 0 ; c < MAX_NUMBER_OF_FILES ; c++) - { - if(p_GameData->FileList[c][0] == 0) // If there are no more files! - break; - - std::string buf = "data/" + p_GameData->DataDirectory; - if(p_GameData->DataDirectory != "") - buf += "/"; - buf += p_GameData->FileList[c]; - - if((fp = fopen(buf.c_str(),"r")) != NULL) - { - fclose(fp); - } - else - { - g_pLogFile->ftextOut("Error! File \"%s\" was not found! Please add it to the configured directory.
", p_GameData->FileList[c].c_str()); - p_GameData->Episode = -1; - ok++; - } - } - - if(ok==0) - g_pLogFile->ftextOut("Game data of Episode %d is complete.
", p_GameData->Episode); - - return ok; -} - -char NessieAlreadySpawned; -void addobjectlayertile(unsigned int t, stCloneKeenPlus *pCKP) -{ -int o; - switch(t) - { - case 0: break; // blank - case 255: // player start - - //Player[0].setCoord(curmapx << 4 << CSF, curmapy << 4 << CSF); - - player[0].x = curmapx << 4 << CSF; - player[0].y = curmapy << 4 << CSF; - map.objectlayer[curmapx][curmapy] = 0; - break; - case NESSIE_PATH: // spawn nessie at first occurance of her path - if (pCKP->Control.levelcontrol.episode==3) - { - if (!NessieAlreadySpawned) - { - o = spawn_object(curmapx<<4<Control.levelcontrol.levels_completed[t&0x00ff]) - { - if(!options[OPT_LVLREPLAYABILITY].value) - map.objectlayer[curmapx][curmapy] = 0; - else - map.objectlayer[curmapx][curmapy] = t; - - int newtile = tiles[map.mapdata[curmapx][curmapy]].chgtile; - - // Consistency check! Some Mods have issues with that. - if(pCKP->Control.levelcontrol.episode == 1 || pCKP->Control.levelcontrol.episode == 2) - { - if(newtile<77 || newtile>81) - // something went wrong. Use default tile - newtile = 77; - - // try to guess, if it is a 32x32 (4 16x16) Tile - if(map.mapdata[curmapx-1][curmapy-1] == (unsigned int) newtile && - map.mapdata[curmapx][curmapy-1] == (unsigned int) newtile && - map.mapdata[curmapx-1][curmapy] == (unsigned int) newtile) - { - map.mapdata[curmapx-1][curmapy-1] = 78; //ul - map.mapdata[curmapx][curmapy-1] = 79; //ur - map.mapdata[curmapx-1][curmapy] = 80; //bl - newtile = 81; // br. this one - } - } - else if(pCKP->Control.levelcontrol.episode == 3) - { - if(newtile<52 || newtile>56) - // something went wrong. Use default tile - newtile = 56; - // try to guess, if it is a 32x32 (4 16x16) Tile - if(map.mapdata[curmapx-1][curmapy-1] == (unsigned int) newtile && - map.mapdata[curmapx][curmapy-1] == (unsigned int) newtile && - map.mapdata[curmapx-1][curmapy] == (unsigned int) newtile) - { - map.mapdata[curmapx-1][curmapy-1] = 52; //bl - map.mapdata[curmapx][curmapy-1] = 53; //ur - map.mapdata[curmapx-1][curmapy] = 54; //ul - newtile = 55; // br. this one - } - } - - map.mapdata[curmapx][curmapy] = newtile; - - } - else - { - map.objectlayer[curmapx][curmapy] = t; - } - break; - } - - curmapx++; - if (curmapx >= map.xsize) - { - curmapx = 0; - curmapy++; - if (curmapy >= map.ysize) mapdone = 1; - } -} - -void addenemytile(unsigned int t, stCloneKeenPlus *pCKP) -{ -int o,x; - map.objectlayer[curmapx][curmapy] = t; - - if (t) - { - if (t==255) - { - if(curmapx >= map.xsize-2) // Edge bug. Keen would fall in some levels without this. - curmapx = 4; - - if(curmapy >= map.ysize-2) // Edge bug. Keen would fall in some levels without this. - curmapx = 4; - - //Player[0].setCoord(curmapx << 4 << CSF, ((curmapy << 4) + 8) << CSF); - - player[0].x = curmapx << 4 << CSF; - player[0].y = ((curmapy << 4) + 8) << CSF; - } - else - { - switch(t) - { - case 0: break; - case -1: break; - case 1: // yorp (ep1) vort (ep2&3) - if (pCKP->Control.levelcontrol.episode==1) - { - x = curmapx; - - if (TileProperty[map.mapdata[x][curmapy+1]][BLEFT]) x--; - spawn_object(x<<4< +#include +#include + +extern CPlayer *Player; + +unsigned int curmapx, curmapy; +unsigned char mapdone; +void addmaptile(unsigned int t) +{ + map.mapdata[curmapx][curmapy] = t; + curmapx++; + if (curmapx >= map.xsize) + { + curmapx = 0; + curmapy++; + + if (curmapy >= map.ysize) mapdone = 1; + } +} + +bool renameFilenamesLowerCase(const char *dir_name) +{ +#ifdef TARGET_WIN32 + return true; +#else + DIR *p_Dir; + char newname[256]; + char buf[256]; + struct dirent *dp; + + memset(newname,0,256); + strcpy(buf,dir_name); + + if(buf[0] == '\0') + strcpy(buf,"./"); + + chdir("data"); + + if((p_Dir = opendir(buf))==NULL) + return false; + + bool retval = true; + // This function checks if all the files in the directory are lower case. + // If they aren't rename them + while((dp = readdir(p_Dir)) != NULL) + { + if(dp->d_type == DT_REG) + { + strcpy(newname,dp->d_name); + + int len = strlen(newname); + for(int pos=0 ; pos < len ; pos++ ) + if(newname[pos] >= 'A' && newname[pos] <= 'Z') + newname[pos] += ('a'-'A'); + + if(strncmp(newname,dp->d_name,strlen(dp->d_name)) != 0) + if(rename(dp->d_name,newname) != -1) + retval &= true; + } + } + + closedir(p_Dir); + + chdir("../"); + + return retval; + +#endif +} + +short checkConsistencyofGameData(stGameData *p_GameData) +{ + short ok = 0; + + FILE *fp; + + // Let's define which files need to be read! + memset(p_GameData->FileList,0,MAX_NUMBER_OF_FILES*MAX_STRING_LENGTH); + if(p_GameData->Episode >= 1 && p_GameData->Episode <= 3) + { + sprintf(p_GameData->FileList[1],"keen%d.exe",p_GameData->Episode); + sprintf(p_GameData->FileList[2],"egahead.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[3],"egasprit.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[4],"egalatch.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[5],"finale.ck%d",p_GameData->Episode); + + // Levels! + sprintf(p_GameData->FileList[6],"level01.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[7],"level02.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[8],"level03.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[9],"level04.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[10],"level05.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[11],"level06.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[12],"level07.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[13],"level08.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[14],"level09.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[15],"level10.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[16],"level11.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[17],"level12.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[18],"level13.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[19],"level14.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[20],"level15.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[21],"level16.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[22],"level80.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[23],"level81.ck%d",p_GameData->Episode); + sprintf(p_GameData->FileList[24],"level90.ck%d",p_GameData->Episode); + + // Other + if(p_GameData->Episode == 1) + sprintf(p_GameData->FileList[24],"sounds.ck%d",p_GameData->Episode); + } + + // Rename all the the files in the directory to lower case + if(!renameFilenamesLowerCase(p_GameData->DataDirectory)) + { + g_pLogFile->ftextOut(PURPLE,"WARNING: There was an error while trying to format correctly the game data."); + g_pLogFile->ftextOut(PURPLE,"Please check, if you have write permissions on the game data directory and it is accessible
"); + } + + // Finally check if they really exist! + char buf[MAX_STRING_LENGTH]; + int c=0; + for(c = 0 ; c < MAX_NUMBER_OF_FILES ; c++) + { + if(p_GameData->FileList[c][0] == 0) // If there are no more files! + break; + + memset(buf,0,MAX_STRING_LENGTH*sizeof(char)); + strcat(buf,"data/"); + strcat(buf,p_GameData->DataDirectory); + if(*(p_GameData->DataDirectory) != 0) + strcat(buf,"/"); + strcat(buf,p_GameData->FileList[c]); + + if((fp = fopen(buf,"r")) != NULL) + { + fclose(fp); + } + else + { + g_pLogFile->ftextOut("Error! File \"%s\" was not found! Please add it to the configured directory.
", p_GameData->FileList[c]); + p_GameData->Episode = -1; + ok++; + } + } + + if(ok==0) + g_pLogFile->ftextOut("Game data of Episode %d is complete.
", p_GameData->Episode); + + return ok; +} + +char NessieAlreadySpawned; +void addobjectlayertile(unsigned int t, stCloneKeenPlus *pCKP) +{ +int o; + switch(t) + { + case 0: break; // blank + case 255: // player start + + //Player[0].setCoord(curmapx << 4 << CSF, curmapy << 4 << CSF); + + player[0].x = curmapx << 4 << CSF; + player[0].y = curmapy << 4 << CSF; + map.objectlayer[curmapx][curmapy] = 0; + break; + case NESSIE_PATH: // spawn nessie at first occurance of her path + if (pCKP->Control.levelcontrol.episode==3) + { + if (!NessieAlreadySpawned) + { + o = spawn_object(curmapx<<4<Control.levelcontrol.levels_completed[t&0x00ff]) + { + if(!options[OPT_LVLREPLAYABILITY].value) + map.objectlayer[curmapx][curmapy] = 0; + else + map.objectlayer[curmapx][curmapy] = t; + + int newtile = tiles[map.mapdata[curmapx][curmapy]].chgtile; + + // Consistency check! Some Mods have issues with that. + if(pCKP->Control.levelcontrol.episode == 1 || pCKP->Control.levelcontrol.episode == 2) + { + if(newtile<77 || newtile>81) + // something went wrong. Use default tile + newtile = 77; + + // try to guess, if it is a 32x32 (4 16x16) Tile + if(map.mapdata[curmapx-1][curmapy-1] == (unsigned int) newtile && + map.mapdata[curmapx][curmapy-1] == (unsigned int) newtile && + map.mapdata[curmapx-1][curmapy] == (unsigned int) newtile) + { + map.mapdata[curmapx-1][curmapy-1] = 78; //ul + map.mapdata[curmapx][curmapy-1] = 79; //ur + map.mapdata[curmapx-1][curmapy] = 80; //bl + newtile = 81; // br. this one + } + } + else if(pCKP->Control.levelcontrol.episode == 3) + { + if(newtile<52 || newtile>56) + // something went wrong. Use default tile + newtile = 56; + // try to guess, if it is a 32x32 (4 16x16) Tile + if(map.mapdata[curmapx-1][curmapy-1] == (unsigned int) newtile && + map.mapdata[curmapx][curmapy-1] == (unsigned int) newtile && + map.mapdata[curmapx-1][curmapy] == (unsigned int) newtile) + { + map.mapdata[curmapx-1][curmapy-1] = 52; //bl + map.mapdata[curmapx][curmapy-1] = 53; //ur + map.mapdata[curmapx-1][curmapy] = 54; //ul + newtile = 55; // br. this one + } + } + + map.mapdata[curmapx][curmapy] = newtile; + + } + else + { + map.objectlayer[curmapx][curmapy] = t; + } + break; + } + + curmapx++; + if (curmapx >= map.xsize) + { + curmapx = 0; + curmapy++; + if (curmapy >= map.ysize) mapdone = 1; + } +} + +void addenemytile(unsigned int t, stCloneKeenPlus *pCKP) +{ +int o,x; + map.objectlayer[curmapx][curmapy] = t; + + if (t) + { + if (t==255) + { + if(curmapx >= map.xsize-2) // Edge bug. Keen would fall in some levels without this. + curmapx = 4; + + if(curmapy >= map.ysize-2) // Edge bug. Keen would fall in some levels without this. + curmapx = 4; + + //Player[0].setCoord(curmapx << 4 << CSF, ((curmapy << 4) + 8) << CSF); + + player[0].x = curmapx << 4 << CSF; + player[0].y = ((curmapy << 4) + 8) << CSF; + } + else + { + switch(t) + { + case 0: break; + case -1: break; + case 1: // yorp (ep1) vort (ep2&3) + if (pCKP->Control.levelcontrol.episode==1) + { + x = curmapx; + + if (TileProperty[map.mapdata[x][curmapy+1]][BLEFT]) x--; + spawn_object(x<<4<Control.levelcontrol.episode==1) + { + // those bastards. sometimes embedding garg's in the floor in + // the original maps. + if(TileProperty[map.mapdata[curmapx+1][curmapy+1]][BLEFT]) + { + if (pCKP->Control.levelcontrol.chglevelto==7) + { + spawn_object(curmapx<<4<Control.levelcontrol.episode==1) + { + spawn_object(curmapx<<4<Control.levelcontrol.episode==2) + { + spawn_object(curmapx<<4<Control.levelcontrol.episode==3) + { + spawn_object(curmapx<<4<Control.levelcontrol.episode==1) + spawn_object(curmapx<<4<Control.levelcontrol.episode==2) + spawn_object(curmapx<<4<Control.levelcontrol.episode==3) + spawn_object(curmapx<<4<Control.levelcontrol.episode==1) + { + o = spawn_object(curmapx<<4<Control.levelcontrol.chglevelto==13) + { + objects[o].hasbeenonscreen = 1; + } + } + else if (pCKP->Control.levelcontrol.episode==2) + spawn_object(curmapx<<4<Control.levelcontrol.episode==3) + { + if(TileProperty[map.mapdata[curmapx][curmapy+1]][BLEFT]) + { + spawn_object(curmapx<<4<Control.levelcontrol.episode==1) + { + o = spawn_object((((curmapx+1)<<4)+4)<Control.levelcontrol.episode==2) + { + o = spawn_object(curmapx<<4<Control.levelcontrol.episode==3) + { + o = spawn_object(curmapx<<4<Control.levelcontrol.episode==1) + case 7: // spark (ep2) ball (ep3) + if (pCKP->Control.levelcontrol.episode==2) + { + o = spawn_object(curmapx<<4<Control.levelcontrol.canexit = 0; // can't exit till spark is shot + } + else + { + o = spawn_object(curmapx<<4<Control.levelcontrol.episode==3) + { + o = spawn_object(curmapx<<4<Control.levelcontrol.episode==1) + { + o = spawn_object(((curmapx<<4)-4)<Control.levelcontrol.episode==3) + { + o = spawn_object(curmapx<<4<Control.levelcontrol.episode==1) { - // those bastards. sometimes embedding garg's in the floor in - // the original maps. - if(TileProperty[map.mapdata[curmapx+1][curmapy+1]][BLEFT]) - { - if (pCKP->Control.levelcontrol.chglevelto==7) - { - spawn_object(curmapx<<4<Control.levelcontrol.episode==3) + { + spawn_object(curmapx<<4<Control.levelcontrol.episode==3) + { + spawn_object(curmapx<<4<Control.levelcontrol.episode==3) + { + o = spawn_object(curmapx<<4<Control.levelcontrol.episode==3) + { + o = spawn_object(curmapx<<4<Control.levelcontrol.episode==1) - { - spawn_object(curmapx<<4<Control.levelcontrol.episode==2) - { - spawn_object(curmapx<<4<Control.levelcontrol.episode==3) - { - spawn_object(curmapx<<4<Control.levelcontrol.episode==1) - spawn_object(curmapx<<4<Control.levelcontrol.episode==2) - spawn_object(curmapx<<4<Control.levelcontrol.episode==3) - spawn_object(curmapx<<4<Control.levelcontrol.episode==1) - { - o = spawn_object(curmapx<<4<Control.levelcontrol.chglevelto==13) - { - objects[o].hasbeenonscreen = 1; - } - } - else if (pCKP->Control.levelcontrol.episode==2) - spawn_object(curmapx<<4<Control.levelcontrol.episode==3) - { - if(TileProperty[map.mapdata[curmapx][curmapy+1]][BLEFT]) - { - spawn_object(curmapx<<4<Control.levelcontrol.episode==1) - { - o = spawn_object((((curmapx+1)<<4)+4)<Control.levelcontrol.episode==2) - { - o = spawn_object(curmapx<<4<Control.levelcontrol.episode==3) - { - o = spawn_object(curmapx<<4<Control.levelcontrol.episode==2) - { - o = spawn_object(curmapx<<4<Control.levelcontrol.canexit = 0; // can't exit till spark is shot - } - else - { - o = spawn_object(curmapx<<4<Control.levelcontrol.episode==3) - { - o = spawn_object(curmapx<<4<Control.levelcontrol.episode==1) - { - o = spawn_object(((curmapx<<4)-4)<Control.levelcontrol.episode==3) - { - o = spawn_object(curmapx<<4<Control.levelcontrol.episode==1) - { - spawn_object(curmapx<<4<Control.levelcontrol.episode==3) - { - spawn_object(curmapx<<4<Control.levelcontrol.episode==3) - { - spawn_object(curmapx<<4<Control.levelcontrol.episode==3) - { - o = spawn_object(curmapx<<4<Control.levelcontrol.episode==3) - { - o = spawn_object(curmapx<<4<fadePalette(20); - g_pLogFile->ftextOut(PURPLE,"unknown enemy type %d at (%d,%d)
", t, curmapx, curmapy); - //while(g_pInput->getPressedCommand(KENTER)); - - break; - } - } - } - curmapx++; - if (curmapx >= map.xsize) - { - curmapx = 0; - curmapy++; - if (curmapy >= map.ysize) mapdone = 1; - } -} - -unsigned int fgeti(FILE *fp) { -unsigned int temp1, temp2; - temp1 = fgetc(fp); + case 16: // mortimer's arms + o = spawn_object(curmapx<<4<fadePalette(20); + g_pLogFile->ftextOut(PURPLE,"unknown enemy type %d at (%d,%d)
", t, curmapx, curmapy); + //while(g_pInput->getPressedCommand(KENTER)); + + break; + } + } + } + curmapx++; + if (curmapx >= map.xsize) + { + curmapx = 0; + curmapy++; + if (curmapy >= map.ysize) mapdone = 1; + } +} + +unsigned int fgeti(FILE *fp) { +unsigned int temp1, temp2; + temp1 = fgetc(fp); temp2 = fgetc(fp); - return (temp2<<8) | temp1; -} - -unsigned long fgetl(FILE *fp) { -unsigned int temp1, temp2, temp3, temp4; - temp1 = fgetc(fp); - temp2 = fgetc(fp); - temp3 = fgetc(fp); - temp4 = fgetc(fp); - return (temp4<<24) | (temp3<<16) | (temp2<<8) | temp1; -} - -unsigned int loadmap(const std::string& filename, const std::string& path, int lvlnum, int isworldmap, stCloneKeenPlus *pCKP) -{ + return (temp2<<8) | temp1; +} + +unsigned long fgetl(FILE *fp) { +unsigned int temp1, temp2, temp3, temp4; + temp1 = fgetc(fp); + temp2 = fgetc(fp); + temp3 = fgetc(fp); + temp4 = fgetc(fp); + return (temp4<<24) | (temp3<<16) | (temp2<<8) | temp1; +} + +unsigned int loadmap(char filename[MAX_STRING_LENGTH], char *path, int lvlnum, int isworldmap, stCloneKeenPlus *pCKP) +{ FILE *fp; -int t; +char fname[256]; +int t; unsigned int c; int numruns = 0; int gottenazero; @@ -534,47 +538,50 @@ int resetcnt, resetpt; NessieAlreadySpawned = 0; map.isworldmap = isworldmap; + + char buffer[256]; + + formatPathString(buffer, path); - std::string buffer = formatPathString(path); - std::string fname = buffer + filename; - fp = fopen(fname.c_str(), "rb"); + sprintf(fname, "%s%s", buffer, filename); + fp = fopen(fname, "rb"); if (!fp) { // only record this error message on build platforms that log errors // to a file and not to the screen. - g_pLogFile->ftextOut("loadmap(): unable to open file %s
", fname.c_str()); + g_pLogFile->ftextOut("loadmap(): unable to open file %s
", fname); return 1; - } - g_pLogFile->ftextOut("loadmap(): file %s opened. Loading...
", fname.c_str()); - - // decompress map RLEW data - curmapx = curmapy = mapdone = 0; - - unsigned int *filebuf; // big File Buffer for the uncompression - filebuf = (unsigned int*) malloc(500000*sizeof(int)); - - if(filebuf == NULL) - { - g_pLogFile->ftextOut("loadmap(): unable to allocate memory for unpacking the level file
", fname.c_str()); - return 1; - } - - int finsize; // Final size - - finsize = unRLEW(fp, filebuf); - - c=0; - - if(finsize == -1) - { - rewind(fp); - while(!feof(fp)) - { - filebuf[c] = fgeti(fp); - c++; - } - } - + } + g_pLogFile->ftextOut("loadmap(): file %s opened. Loading...
", fname); + + // decompress map RLEW data + curmapx = curmapy = mapdone = 0; + + unsigned int *filebuf; // big File Buffer for the uncompression + filebuf = (unsigned int*) malloc(500000*sizeof(int)); + + if(filebuf == NULL) + { + g_pLogFile->ftextOut("loadmap(): unable to allocate memory for unpacking the level file
", fname); + return 1; + } + + int finsize; // Final size + + finsize = unRLEW(fp, filebuf); + + c=0; + + if(finsize == -1) + { + rewind(fp); + while(!feof(fp)) + { + filebuf[c] = fgeti(fp); + c++; + } + } + map.xsize = filebuf[2]; map.ysize = filebuf[3]; @@ -584,163 +591,162 @@ int resetcnt, resetpt; g_pLogFile->textOut(RED,"loadmap(): level is too big
"); return 1; } - - c=18; - - while(c < ((filebuf[9] / 2)+18)) // Check against Tilesize - { - t = filebuf[c]; - if(!mapdone) - addmaptile(t); - - if(t > 255) - { - t=0; // If there are some invalid values in the file - } - - c++; - } - + + c=18; + + while(c < ((filebuf[9] / 2)+18)) // Check against Tilesize + { + t = filebuf[c]; + if(!mapdone) + addmaptile(t); + + if(t > 255) + { + t=0; // If there are some invalid values in the file + } + + c++; + } + // now do the enemies gottenazero = 0; // get enemy/objectlayer data curmapx = curmapy = mapdone = numruns = 0; - resetcnt = resetpt = 0; - - while(!mapdone) - { - t = filebuf[c]; - - if (t==0 && !gottenazero) - { - curmapx = curmapy = 0; - gottenazero = 1; - } - if (map.isworldmap) addobjectlayertile(t, pCKP); else addenemytile(t, pCKP); - if (++resetcnt==resetpt) curmapx=curmapy=0; - - c++; - } - - free(filebuf); - - fclose(fp); - - // HQ Sounds. Load Music for a level if you have HQP - g_pMusicPlayer->stop(); - - if((fp=fopen("data/hqp/music/table.cfg","rt")) != NULL) - { - static const int MAX_STRING_LENGTH = 256; - char buf1[MAX_STRING_LENGTH]; - char buf2[MAX_STRING_LENGTH]; - - memset(buf1,0,sizeof(char)*MAX_STRING_LENGTH); - memset(buf2,0,sizeof(char)*MAX_STRING_LENGTH); - - while(!feof(fp)) - { - fscanf(fp,"%s",buf1); - - if(strcmp(buf1,filename.c_str()) == 0) - { - fscanf(fp,"%s",buf2); - break; - } - else - fgets(buf1,MAX_STRING_LENGTH,fp); - } - - - fclose(fp); - - if(*buf2 != 0) - { - strcpy(buf1,"data/hqp/music/"); - strcat(buf1,buf2); - g_pMusicPlayer->load(g_pSound->getAudioSpec(),buf1); - g_pMusicPlayer->play(); - } - } - - // Didn't it work? Don't matter. HQP is optional, so continue - - // install enemy stoppoints as needed - if (pCKP->Control.levelcontrol.episode==1 && lvlnum==13) + resetcnt = resetpt = 0; + + while(!mapdone) + { + t = filebuf[c]; + + if (t==0 && !gottenazero) + { + curmapx = curmapy = 0; + gottenazero = 1; + } + if (map.isworldmap) addobjectlayertile(t, pCKP); else addenemytile(t, pCKP); + if (++resetcnt==resetpt) curmapx=curmapy=0; + + c++; + } + + free(filebuf); + + fclose(fp); + + // HQ Sounds. Load Music for a level if you have HQP + g_pMusicPlayer->stop(); + + if((fp=fopen("data/hqp/music/table.cfg","rt")) != NULL) + { + char buf1[MAX_STRING_LENGTH]; + char buf2[MAX_STRING_LENGTH]; + + memset(buf1,0,sizeof(char)*MAX_STRING_LENGTH); + memset(buf2,0,sizeof(char)*MAX_STRING_LENGTH); + + while(!feof(fp)) + { + fscanf(fp,"%s",buf1); + + if(strcmp(buf1,filename) == 0) + { + fscanf(fp,"%s",buf2); + break; + } + else + fgets(buf1,MAX_STRING_LENGTH,fp); + } + + + fclose(fp); + + if(*buf2 != 0) + { + strcpy(buf1,"data/hqp/music/"); + strcat(buf1,buf2); + g_pMusicPlayer->load(g_pSound->getAudioSpec(),buf1); + g_pMusicPlayer->play(); + } + } + + // Didn't it work? Don't matter. HQP is optional, so continue + + // install enemy stoppoints as needed + if (pCKP->Control.levelcontrol.episode==1 && lvlnum==13) { map.objectlayer[94][13] = GARG_STOPPOINT; - map.objectlayer[113][13] = GARG_STOPPOINT; - map.objectlayer[48][6] = GARG_STOPPOINT; - map.objectlayer[80][5] = GARG_STOPPOINT; - map.objectlayer[87][5] = GARG_STOPPOINT; - map.objectlayer[39][18] = GARG_STOPPOINT; - } - else if (pCKP->Control.levelcontrol.episode==3 && lvlnum==6) - { - map.objectlayer[40][7] = BALL_NOPASSPOINT; + map.objectlayer[113][13] = GARG_STOPPOINT; + map.objectlayer[48][6] = GARG_STOPPOINT; + map.objectlayer[80][5] = GARG_STOPPOINT; + map.objectlayer[87][5] = GARG_STOPPOINT; + map.objectlayer[39][18] = GARG_STOPPOINT; + } + else if (pCKP->Control.levelcontrol.episode==3 && lvlnum==6) + { + map.objectlayer[40][7] = BALL_NOPASSPOINT; map.objectlayer[50][7] = BALL_NOPASSPOINT; } else if (pCKP->Control.levelcontrol.episode==3 && lvlnum==9) - { - map.objectlayer[45][106] = BALL_NOPASSPOINT; - - } - else if (pCKP->Control.levelcontrol.episode==3 && lvlnum==4) - { - map.objectlayer[94][17] = BALL_NOPASSPOINT; - } - - return 0; -} - -char loadstrings_AddAttr(char *attr, int stringIndex) -{ -char stAttrName[80]; -char stAttrValue[80]; -int attrvalue; -int RAMAllocSize; -char *copyPtr; + { + map.objectlayer[45][106] = BALL_NOPASSPOINT; + + } + else if (pCKP->Control.levelcontrol.episode==3 && lvlnum==4) + { + map.objectlayer[94][17] = BALL_NOPASSPOINT; + } + + return 0; +} + +char loadstrings_AddAttr(char *attr, int stringIndex) +{ +char stAttrName[80]; +char stAttrValue[80]; +int attrvalue; +int RAMAllocSize; +char *copyPtr; unsigned int i; - + // if the attribute does not have an equals sign bail - if (!strstr(attr, "=")) - { - g_pLogFile->ftextOut("loadstrings_AddAttr(): '%s' is not a valid attribute definition.
", attr); - return 1; - } - - // split the attribute up into it's name and it's value - copyPtr = stAttrName; - for(i=0;i", attr); + return 1; + } + + // split the attribute up into it's name and it's value + copyPtr = stAttrName; + for(i=0;itextOut(RED,"loadstrings_AddAttr(): Unable to allocate space for attribute name ('%s').
", stAttrName); - return 1; - } + + // malloc space for the attribute name + RAMAllocSize = strlen(stAttrName) + 1; + strings[stringIndex].attrnames[strings[stringIndex].numAttributes] = (unsigned char*) malloc(RAMAllocSize+1); + if (!strings[stringIndex].attrnames[strings[stringIndex].numAttributes]) + { + g_pLogFile->textOut(RED,"loadstrings_AddAttr(): Unable to allocate space for attribute name ('%s').
", stAttrName); + return 1; + } // copy the data into the strings structure memcpy(strings[stringIndex].attrnames[strings[stringIndex].numAttributes], stAttrName, RAMAllocSize); @@ -755,14 +761,16 @@ char loadstrings(const char *fname) { FILE *fp; char state; -char stName[80]; -char stString[1024]; -char stAttr[80]; +unsigned char stName[80]; +unsigned char stString[1024]; +unsigned char stAttr[80]; int i,c; -int nameIndex, stringIndex; +int nameIndex, stringIndex; int attrIndex=0; int waitChar, gotoState; char highlight; +int RAMSize; +char *RAMPtr; #define STSTATE_WAITCHAR 0 #define STSTATE_READNAME 1 @@ -781,8 +789,8 @@ g_pLogFile->ftextOut("loadstrings(): Opening string file '%s'.
", fname); // let us know which ones are in use (and need to be free()d at shutdown) for(i=0;iftextOut("loadstrings(): Opening string file '%s'.
", fname); /* save the string to the strings[] structure */ + // we're going to malloc() an area and copy the name, then the string, + // into it. We'll need room for both the name and the string, plus + // null-terminators for each. + RAMSize = strlen( (char*) stName) + strlen((char*)stString) + 2; + RAMPtr = (char*) malloc(RAMSize); + if (!RAMPtr) + { + g_pLogFile->ftextOut(RED,"loadstrings(): Could not allocate memory for string '%s'
", stName); + return 1; + } + + // assign our pointers + strings[numStrings].name = (unsigned char*) &RAMPtr[0]; + strings[numStrings].stringptr = (unsigned char*) &RAMPtr[strlen((char*)stName)+1]; + // copy the string info to the newly malloc()'d memory area - strings[numStrings].name = stName; - strings[numStrings].stringptr = stString; + memcpy(strings[numStrings].name, stName, strlen((char*)stName)+1); + memcpy(strings[numStrings].stringptr, stString, strlen((char*)stString)+1); numStrings++; // read the name of the next string @@ -923,77 +946,95 @@ g_pLogFile->ftextOut("loadstrings(): Opening string file '%s'.
", fname); g_pLogFile->ftextOut("loadstrings(): loaded %d strings from '%s'.
", numStrings, fname); fclose(fp); return 0; -} - -int freestrings(void) -{ +} + +int freestrings(void) +{ int i,j; int NumStringsFreed; NumStringsFreed = 0; for(i=0;i -#include +#include char loadstrings(const char *fname); unsigned int fgeti(FILE *fp); unsigned long fgetl(FILE *fp); - std::string formatPathString(const std::string& path); +void formatPathString(char *output, const char *path); +#ifdef __cplusplus +} #endif diff --git a/src/fileio/CExeFile.cpp b/src/fileio/CExeFile.cpp index 909e9f3e8..4aadb8a4b 100644 --- a/src/fileio/CExeFile.cpp +++ b/src/fileio/CExeFile.cpp @@ -6,31 +6,29 @@ */ #include "CExeFile.h" -#include +#include #include #include -#include "../StringUtils.h" - - using namespace std; -CExeFile::CExeFile(int episode, const std::string& datadirectory) { +CExeFile::CExeFile(int episode, char *datadirectory) { m_episode = episode; m_datadirectory = datadirectory; m_data = NULL; } CExeFile::~CExeFile() { - if(m_data) delete m_data; + if(m_data) delete [] m_data; } bool CExeFile::readData() { + char filename[256]; unsigned char *m_data_temp; - std::string filename = "data/" + m_datadirectory + "keen" + itoa(m_episode) + ".exe"; + sprintf(filename, "data/%skeen%d.exe", m_datadirectory, m_episode); - std::ifstream File(filename.c_str(),ios::binary); + ifstream File(filename,ios::binary); if(!File) return false; @@ -49,7 +47,7 @@ bool CExeFile::readData() { m_datasize = decdata.size(); m_data = new unsigned char[m_datasize]; - memcpy(m_data, &decdata[0], m_datasize); + memcpy(m_data, decdata->data(), m_datasize); } else { @@ -57,7 +55,7 @@ bool CExeFile::readData() m_data = new unsigned char[m_datasize]; memcpy(m_data, m_data_temp+512,m_datasize); } - delete m_data_temp; + delete [] m_data_temp; return true; } diff --git a/src/fileio/CExeFile.h b/src/fileio/CExeFile.h index 664f0af54..347c3074d 100644 --- a/src/fileio/CExeFile.h +++ b/src/fileio/CExeFile.h @@ -12,11 +12,11 @@ #define CEXEFILE_H_ #include -#include +using namespace std; class CExeFile { public: - CExeFile(int episode, const std::string& datadirectory); + CExeFile(int episode, char *datadirectory); virtual ~CExeFile(); bool readData(); @@ -27,10 +27,10 @@ private: int m_datasize; int m_episode; unsigned char *m_data; - std::string m_datadirectory; + char *m_datadirectory; int get_bit(int *p_bit_count, unsigned char *fin, int *posin); - int unlzexe(unsigned char *fin, std::vector *outbuffer); + int unlzexe(unsigned char *fin, vector *outbuffer); }; #endif /* CEXEFILE_H_ */ diff --git a/src/fileio/CParser.cpp b/src/fileio/CParser.cpp index c7511b46b..c717d8de8 100644 --- a/src/fileio/CParser.cpp +++ b/src/fileio/CParser.cpp @@ -83,7 +83,7 @@ bool CParser::saveParseFile(void) // open, write on the file and close if((fp=fopen(CONFIGFILENAME,"wt"))) { - std::list::iterator i; + list::iterator i; for(i=m_filebuffer.begin() ; i != m_filebuffer.end() ; ++i ) fprintf(fp,"%s",*i); @@ -104,7 +104,7 @@ bool CParser::saveParseFile(void) // open, write on the file and close int CParser::getIntValue(const char *keyword, const char *category) { // The getter will search for category and than for keyword. After that, read the value and return it! - std::list::iterator i; + list::iterator i; char *line; @@ -152,7 +152,7 @@ void CParser::saveIntValue(const char *keyword, const char *category,int value) // 2.- category exists, but keyword not // 3.- category and keyword exist, only the value must be changed - std::list::iterator i; + list::iterator i; char *line; diff --git a/src/fileio/CParser.h b/src/fileio/CParser.h index 2d157bf3b..3d460fcfd 100644 --- a/src/fileio/CParser.h +++ b/src/fileio/CParser.h @@ -10,6 +10,7 @@ #include #include +using namespace std; class CParser { @@ -42,7 +43,7 @@ public: private: bool m_isOpen; - std::list m_filebuffer; + list m_filebuffer; }; diff --git a/src/fileio/CPatcher.cpp b/src/fileio/CPatcher.cpp index 2c9091b4f..125082108 100644 --- a/src/fileio/CPatcher.cpp +++ b/src/fileio/CPatcher.cpp @@ -10,11 +10,11 @@ #include #include -CPatcher::CPatcher(int episode, int version,unsigned char *data, const std::string& datadir) { +CPatcher::CPatcher(int episode, int version,unsigned char *data, char *datadir) { m_episode = episode; m_version = version; m_data = data; - m_datadirectory = datadir; + strcpy(m_datadirectory, datadir); } CPatcher::~CPatcher() { @@ -35,7 +35,7 @@ void CPatcher::patchMemory() // change to the proper directory chdir("data"); - chdir(m_datadirectory.c_str()); + chdir(m_datadirectory); // TODO: Extend this part further with more commands while(!m_TextList.empty()) @@ -80,6 +80,7 @@ void CPatcher::patchMemory() } } } + } if(!m_TextList.empty()) @@ -108,7 +109,7 @@ bool CPatcher::loadPatchfile() { bool ret = false; chdir("data"); - chdir(m_datadirectory.c_str()); + chdir(m_datadirectory); // Detect the patchfile DIR *dir = opendir("."); struct dirent *dp; @@ -120,9 +121,8 @@ bool CPatcher::loadPatchfile() if(strstr(dp->d_name,".pat")) { // The file was found! now read it into the memory! - char* buf; - std::ifstream Patchfile(dp->d_name); + ifstream Patchfile(dp->d_name); while(!Patchfile.eof()) { @@ -157,12 +157,12 @@ bool CPatcher::loadPatchfile() return ret; } -void CPatcher::patchMemfromFile(const std::string& patch_file_name, int offset) +void CPatcher::patchMemfromFile(const char *patch_file_name, int offset) { unsigned char *buf_to_patch; unsigned char byte; - std::ifstream Patchfile(patch_file_name.c_str(), std::ios::binary); + ifstream Patchfile(patch_file_name, ios::binary); if(!Patchfile) return; diff --git a/src/fileio/CPatcher.h b/src/fileio/CPatcher.h index e4de4427c..b47565619 100644 --- a/src/fileio/CPatcher.h +++ b/src/fileio/CPatcher.h @@ -9,15 +9,15 @@ #define CPATCHER_H_ #include -#include +using namespace std; class CPatcher { public: - CPatcher(int episode, int version,unsigned char *data, const std::string& datadir); + CPatcher(int episode, int version,unsigned char *data, char *datadir); virtual ~CPatcher(); void patchMemory(); - void patchMemfromFile(const std::string& patch_file_name, int offset); + void patchMemfromFile(const char *patch_file_name, int offset); private: @@ -26,9 +26,9 @@ private: int m_episode; int m_version; unsigned char *m_data; - std::string m_datadirectory; - - std::list m_TextList; + char m_datadirectory[256]; + + list m_TextList; }; diff --git a/src/fileio/story.cpp b/src/fileio/story.cpp index 84e33f50b..dddb22231 100644 --- a/src/fileio/story.cpp +++ b/src/fileio/story.cpp @@ -12,19 +12,24 @@ #include "../include/fileio.h" #include "../fileio/CExeFile.h" #include "../CLogFile.h" -#include "../StringUtils.h" -int readStoryText(char **ptext, int episode, const std::string& path) +int readStoryText(char **ptext, int episode, char *path) { - std::string buf2 = formatPathString(path); - std::string buf = buf2 + "storytxt.ck" + itoa(episode); - FILE *fp; - if((fp=fopen(buf.c_str(),"rt"))==NULL) - { - buf = buf2 + "keen" + itoa(episode) + ".exe"; + char buf[256]; + char buf2[256]; - if((fp=fopen(buf.c_str(),"rb"))!=NULL) + memset(buf,0,256*sizeof(char)); + + formatPathString(buf2,path); + + sprintf(buf,"%sstorytxt.ck%d",buf2,episode); + + if((fp=fopen(buf,"rt"))==NULL) + { + sprintf(buf,"%skeen%d.exe",buf2,episode); + + if((fp=fopen(buf,"rb"))!=NULL) { unsigned char *filebuf; int startflag=0, endflag=0; // where story begins and ends! diff --git a/src/finale.cpp b/src/finale.cpp index b470884ad..bab9e885f 100644 --- a/src/finale.cpp +++ b/src/finale.cpp @@ -1,133 +1,135 @@ -/* FINALE.C - Code for displaying the FINALE.CK? files. - Thanks to Andrew Durdin for FIN2BMP, from which I got - the decompression algorithm. -*/ - -#include "keen.h" -#include "include/fileio.h" -#include "CGraphics.h" - -int finale_x; -int finale_y; -int finale_count; -int finale_planecol; -int finale_plane_length; -int finale_done; - -// used internally by finale_draw() -void finale_plot(int pix) -{ -int mask; - - mask = 128; - do - { - if (pix & mask) - { - if (finale_planecol==1) - { - g_pGraphics->sb_setpixel(finale_x, finale_y, finale_planecol); - } - else - { // merge with previous planes - g_pGraphics->sb_setpixel(finale_x, finale_y, g_pGraphics->sb_getpixel(finale_x, finale_y) | finale_planecol); - } - } - else if (finale_planecol==1) - { - g_pGraphics->sb_setpixel(finale_x, finale_y, 0); - } - - finale_x++; - if (finale_x > 319) - { - finale_x = 0; - finale_y++; - } - - finale_count++; - if (finale_count >= finale_plane_length) - { - finale_x = finale_y = 0; - finale_count = 0; - finale_planecol <<= 1; - if (finale_planecol > 8) finale_done = 1; - } - - if (mask==1) - { - return; - } - else - { - mask >>= 1; - } - - } while(1); - -} - -// draws a finale.ck? file into the upper-left corner of the scrollbuffer -void finale_draw(const std::string& filename, const std::string& path) -{ -FILE *fp; -int cmdbyte; -int bytecount; -int repeatbyte; -int i; - - - std::string buffer = formatPathString(path); - - - map_unregister_all_animtiles(); - - std::string fname = buffer + filename; - fp = fopen(fname.c_str(), "rb"); - if (!fp) - { - crashflag = 1; - why_term_ptr = "finale_draw(): cannot open finake.ck? file."; - return; - } - - finale_plane_length = fgetl(fp)*2; //length of a plane when decompressed - finale_planecol = 1; - finale_x = finale_y = 0; - finale_count = 0; - finale_done = 0; - - /* decompress/draw the image */ - do - { - cmdbyte = fgetc(fp); - if (cmdbyte<0) - { // EOF - return; - } - - if (cmdbyte & 0x80) - { - //N + 1 bytes of data follows - bytecount = (cmdbyte & 0x7F) + 1; - for(i=0;isb_setpixel(finale_x, finale_y, finale_planecol); + } + else + { // merge with previous planes + g_pGraphics->sb_setpixel(finale_x, finale_y, g_pGraphics->sb_getpixel(finale_x, finale_y) | finale_planecol); + } + } + else if (finale_planecol==1) + { + g_pGraphics->sb_setpixel(finale_x, finale_y, 0); + } + + finale_x++; + if (finale_x > 319) + { + finale_x = 0; + finale_y++; + } + + finale_count++; + if (finale_count >= finale_plane_length) + { + finale_x = finale_y = 0; + finale_count = 0; + finale_planecol <<= 1; + if (finale_planecol > 8) finale_done = 1; + } + + if (mask==1) + { + return; + } + else + { + mask >>= 1; + } + + } while(1); + +} + +// draws a finale.ck? file into the upper-left corner of the scrollbuffer +void finale_draw(const char *filename, const char *path) +{ +char fname[256]; +FILE *fp; +int cmdbyte; +int bytecount; +int repeatbyte; +int i; +char buffer[256]; + + + formatPathString(buffer,path); + + + map_unregister_all_animtiles(); + + sprintf(fname, "%s%s", buffer,filename); + fp = fopen(fname, "rb"); + if (!fp) + { + crashflag = 1; + why_term_ptr = "finale_draw(): cannot open finake.ck? file."; + return; + } + + finale_plane_length = fgetl(fp)*2; //length of a plane when decompressed + finale_planecol = 1; + finale_x = finale_y = 0; + finale_count = 0; + finale_done = 0; + + /* decompress/draw the image */ + do + { + cmdbyte = fgetc(fp); + if (cmdbyte<0) + { // EOF + return; + } + + if (cmdbyte & 0x80) + { + //N + 1 bytes of data follows + bytecount = (cmdbyte & 0x7F) + 1; + for(i=0;i - -// gamedo.c -int gamedo_ScrollTriggers(int theplayer); -void gamedo_AnimatedTiles(void); - -void gamedo_render_eraseobjects(void); -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 -void map_scroll_right(void); -void map_scroll_left(void); -void map_scroll_down(void); -void map_scroll_up(void); -void map_draw_vstripe(unsigned int x, unsigned int mpx); -void map_draw_hstripe(unsigned int y, unsigned int mpy); -void nosb_map_draw_vstripe(unsigned int x, unsigned int mapx); -unsigned int getmaptileat(unsigned int x, unsigned int y); -unsigned int getlevelat(unsigned int x, unsigned int y); -void drawmap(void); -void map_unregister_all_animtiles(void); -void map_deanimate(int x, int y); -int map_isanimated(int x, int y); -void map_animate(int x, int y); -char map_findobject(unsigned int obj, int *xout, int *yout); -char map_findtile(unsigned int tile, int *xout, int *yout); -void map_redraw(void); -void map_chgtile(unsigned int x,unsigned int y, int newtile); -// dos\snddrv.c -void SoundDrv_Stop(void); -void sound_do(void); -void sound_play_stereo(int snd, char mode, short balance); -void sound_play_stereo_from_coord(int snd, char mode, unsigned int xcoordinate); -void sound_play(int snd, char mode); -char sound_is_playing(int snd); -void sound_stop(int snd); -void sound_stop_all(void); -void sound_pause(void); -void sound_resume(void); -char sound_extraction_of_exe_files(char *inputpath, int episode); - -// graphics.c -void DrawBitmap(int xa, int ya, int b); -void freemem(void); -void Graphics_Stop(void); -void /*inline*/ sb_setpixel(int x, int y, unsigned char c); -unsigned char sb_getpixel(int x, int y); -void drawtile(int x, int y, unsigned int t); -void drawtile_direct(int x, int y, unsigned int t); -void drawtilewithmask(int x, int y, unsigned int til, unsigned int tmask); -void drawprioritytile(int x, int y, unsigned int til); -void drawsprite_direct(int x, int y, unsigned int t); -void drawsprite(int x, int y, unsigned int s, int objectnum); -void erasesprite(int x, int y, unsigned int s, int objectnum); -void drawcharacter(int x, int y, int f); -void sb_drawcharacter(int x, int y, int f); -void sb_drawcharacterwithmask(int x, int y, int f, char mask); -void sb_drawcolorcharacter(int x, int y, int f, unsigned short colour, unsigned short bgcolour); -void sb_drawcharacterinverse(int x, int y, int f); -void save_area(int x1, int y1, int x2, int y2); -void restore_area(int x1, int y1, int x2, int y2); -void setvideomode(unsigned char mode); -void addpal(int c, int r, int g, int b); -void pal_init(int dark); -void pal_fade(int fadeamt); -void pal_apply(void); -void font_draw(unsigned char *text, int xoff, int yoff, int highlight); -void sb_font_draw(const unsigned char *text, int xoff, int yoff); -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); -int freestrings(void); -std::string getstring(const std::string& name); -int GetStringAttribute(const std::string& stringName, const char *attrName); - -// keydrv.c -char KeyDrv_Start(void); -void KeyDrv_Stop(void); - -// misc.c -void banner(void); -void dialogbox(int x1, int y1, int w, int h); -void sb_dialogbox(int x1, int y1, int w, int h); -void statusbox(void); - -int savegameiswm(char *fname); -void usage(void); -void radar(void); -void SetAllCanSupportPlayer(int o, int state); -void AllPlayersInvisible(void); - -// menu.c -int GetBitmapNumberFromName(const char *bmname); - - -// eseq_ep1.c -void addshipqueue(int cmd, int time, int flag1); - -// latch.c -//char latch_loadgraphics(int episode, char *path); - -// sglre.c -void sgrle_reset(void); -void sgrle_compress(FILE *fp, unsigned char *ptr, unsigned long nbytes); -void sgrle_decompress(FILE *fp, unsigned char *ptr, unsigned long nbytes); -unsigned char sgrle_get_next_byte(FILE *fp); - -// lz.c -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 - +/*check if the compiler is of C++*/ +#ifdef __cplusplus +extern "C" { +#endif + +// gamedo.c +int gamedo_ScrollTriggers(int theplayer); +void gamedo_AnimatedTiles(void); + +void gamedo_render_eraseobjects(void); +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 +void map_scroll_right(void); +void map_scroll_left(void); +void map_scroll_down(void); +void map_scroll_up(void); +void map_draw_vstripe(unsigned int x, unsigned int mpx); +void map_draw_hstripe(unsigned int y, unsigned int mpy); +void nosb_map_draw_vstripe(unsigned int x, unsigned int mapx); +unsigned int getmaptileat(unsigned int x, unsigned int y); +unsigned int getlevelat(unsigned int x, unsigned int y); +void drawmap(void); +void map_unregister_all_animtiles(void); +void map_deanimate(int x, int y); +int map_isanimated(int x, int y); +void map_animate(int x, int y); +char map_findobject(unsigned int obj, int *xout, int *yout); +char map_findtile(unsigned int tile, int *xout, int *yout); +void map_redraw(void); +void map_chgtile(unsigned int x,unsigned int y, int newtile); +// dos\snddrv.c +void SoundDrv_Stop(void); +void sound_do(void); +void sound_play_stereo(int snd, char mode, short balance); +void sound_play_stereo_from_coord(int snd, char mode, unsigned int xcoordinate); +void sound_play(int snd, char mode); +char sound_is_playing(int snd); +void sound_stop(int snd); +void sound_stop_all(void); +void sound_pause(void); +void sound_resume(void); +char sound_extraction_of_exe_files(char *inputpath, int episode); + +// graphics.c +void DrawBitmap(int xa, int ya, int b); +void freemem(void); +void Graphics_Stop(void); +void /*inline*/ sb_setpixel(int x, int y, unsigned char c); +unsigned char sb_getpixel(int x, int y); +void drawtile(int x, int y, unsigned int t); +void drawtile_direct(int x, int y, unsigned int t); +void drawtilewithmask(int x, int y, unsigned int til, unsigned int tmask); +void drawprioritytile(int x, int y, unsigned int til); +void drawsprite_direct(int x, int y, unsigned int t); +void drawsprite(int x, int y, unsigned int s, int objectnum); +void erasesprite(int x, int y, unsigned int s, int objectnum); +void drawcharacter(int x, int y, int f); +void sb_drawcharacter(int x, int y, int f); +void sb_drawcharacterwithmask(int x, int y, int f, char mask); +void sb_drawcolorcharacter(int x, int y, int f, unsigned short colour, unsigned short bgcolour); +void sb_drawcharacterinverse(int x, int y, int f); +void save_area(int x1, int y1, int x2, int y2); +void restore_area(int x1, int y1, int x2, int y2); +void setvideomode(unsigned char mode); +void addpal(int c, int r, int g, int b); +void pal_init(int dark); +void pal_fade(int fadeamt); +void pal_apply(void); +void font_draw(unsigned char *text, int xoff, int yoff, int highlight); +void sb_font_draw(const unsigned char *text, int xoff, int yoff); +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); +int freestrings(void); +char* getstring(const char *name); +int GetStringAttribute(const char *stringName, const char *attrName); + +// keydrv.c +char KeyDrv_Start(void); +void KeyDrv_Stop(void); + +// misc.c +void banner(void); +void dialogbox(int x1, int y1, int w, int h); +void sb_dialogbox(int x1, int y1, int w, int h); +void statusbox(void); + +int savegameiswm(char *fname); +void usage(void); +void radar(void); +void SetAllCanSupportPlayer(int o, int state); +void AllPlayersInvisible(void); + +// menu.c +int GetBitmapNumberFromName(const char *bmname); + + +// eseq_ep1.c +void addshipqueue(int cmd, int time, int flag1); + +// latch.c +//char latch_loadgraphics(int episode, char *path); + +// sglre.c +void sgrle_reset(void); +void sgrle_compress(FILE *fp, unsigned char *ptr, unsigned long nbytes); +void sgrle_decompress(FILE *fp, unsigned char *ptr, unsigned long nbytes); +unsigned char sgrle_get_next_byte(FILE *fp); + +// lz.c +char lz_decompress(FILE *lzfile, unsigned char *outbuffer); + +// finale.c +void finale_draw(const char *filename, const char *path); + +// scalerx.c +//void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height); + +/*check if the compiler is of C++*/ +#ifdef __cplusplus +} +#endif diff --git a/src/gamedo.cpp b/src/gamedo.cpp index 9d354b2a1..e760b2a6e 100644 --- a/src/gamedo.cpp +++ b/src/gamedo.cpp @@ -1,750 +1,747 @@ -/* GAMEDO.C - Contains all of the gamedo_xxx functions...which are called from the - main game loop. These functions perform some task that is done each - time around the game loop, not directly related to the player. -*/ - -#include "keen.h" - -#include "include/game.h" -#include "include/gamedo.h" -#include "include/gamepdo.h" -#include "include/misc.h" -#include "sdl/CVideoDriver.h" -#include "sdl/CTimer.h" -#include "sdl/CInput.h" -#include "sdl/sound/CSound.h" -#include "CGraphics.h" -#include "vorticon/CPlayer.h" -#include "keenext.h" -#include "StringUtils.h" - -#include "include/enemyai.h" - -extern unsigned long gotPlayX; - -extern unsigned long CurrentTickCount; - -extern unsigned int unknownKey; - -extern CPlayer *Player; - -int animtiletimer, curanimtileframe; - -// gathers data from input controllers: keyboard, joystick, network, -// whatever to populate each player's keytable -unsigned char oldleftkey = 5; -unsigned char oldrightkey = 5; -unsigned char oldupkey = 5; -unsigned char olddownkey = 5; -unsigned char oldctrlkey = 5; -unsigned char oldaltkey = 5; -void gamedo_getInput(stCloneKeenPlus *pCKP) -{ -int i; -int byt; -unsigned int msb, lsb; - - if (demomode==DEMO_PLAYBACK) - { - // time to get a new key block? - if (!demo_RLERunLen) - { - /* get next RLE run length */ - lsb = demo_data[demo_data_index++]; - msb = demo_data[demo_data_index++]; - demo_RLERunLen = (msb<<8) | lsb; - byt = demo_data[demo_data_index++]; // get keys down - - player[0].playcontrol[PA_X] = 0; - player[0].playcontrol[PA_POGO] = 0; - player[0].playcontrol[PA_JUMP] = 0; - player[0].playcontrol[PA_FIRE] = 0; - player[0].playcontrol[PA_STATUS] = 0; - - if (byt & 1) player[0].playcontrol[PA_X] -= 100; - if (byt & 2) player[0].playcontrol[PA_X] += 100; - if (byt & 4) player[0].playcontrol[PA_POGO] = 1; - if (byt & 8) player[0].playcontrol[PA_JUMP] = 1; - if (byt & 16)player[0].playcontrol[PA_FIRE] = 1; - if (byt & 32)player[0].playcontrol[PA_STATUS] = 1; - if (byt & 64) - { // demo STOP command - if (fade.mode!=FADE_GO) endlevel(1, pCKP); - } - } - else - { - // we're still in the last RLE run, don't change any keys - demo_RLERunLen--; - } - - // user trying to cancel the demo? - for(i=0;igetPressedKey(i)) - { - if (fade.mode!=FADE_GO) endlevel(0, pCKP); - } - } - if (g_pInput->getPressedCommand(IC_STATUS)) - { - if (fade.mode!=FADE_GO) endlevel(0, pCKP); - } - - return; - } - - for(Uint8 p=0 ; pgetHoldedCommand(p, IC_LEFT)) - player[p].playcontrol[PA_X] -= 100; - if(g_pInput->getHoldedCommand(p, IC_RIGHT)) - player[p].playcontrol[PA_X] += 100; - - if(g_pInput->getHoldedCommand(p, IC_UP)) - player[p].playcontrol[PA_Y] -= 100; - if(g_pInput->getHoldedCommand(p, IC_DOWN)) - player[p].playcontrol[PA_Y] += 100; - - if(g_pInput->getHoldedCommand(p, IC_JUMP)) - player[p].playcontrol[PA_JUMP] = 1; - if(g_pInput->getHoldedCommand(p, IC_POGO)) - player[p].playcontrol[PA_POGO] = 1; - if(g_pInput->getHoldedCommand(p, IC_FIRE)) - player[p].playcontrol[PA_FIRE] = 1; - if(g_pInput->getHoldedCommand(p, IC_STATUS)) - player[p].playcontrol[PA_STATUS] = 1; - - if (demomode==DEMO_RECORD) - { - if(i) player[p].playcontrol[PA_X] += 100; - fputc(i, demofile); - if(i) player[p].playcontrol[PA_X] -= 100; - fputc(i, demofile); - if(i) player[p].playcontrol[PA_POGO] = 1; - fputc(i, demofile); - if(i) player[p].playcontrol[PA_JUMP] = 1; - fputc(i, demofile); - if(i) player[p].playcontrol[PA_FIRE] = 1; - fputc(i, demofile); - if(i) player[p].playcontrol[PA_STATUS] = 1; - fputc(i, demofile); - } - } -} - -// handles scrolling, for player cp -// returns nonzero if the scroll was changed -int gamedo_ScrollTriggers(int theplayer) -{ -signed int px, py; -int scrollchanged; - - if (player[theplayer].pdie) return 0; - - //px = (Player[theplayer].getCoordX()>>CSF)-scroll_x; - //py = (Player[theplayer].getCoordY()>>CSF)-scroll_y; - - px = (player[theplayer].x>>CSF)-scroll_x; - py = (player[theplayer].y>>CSF)-scroll_y; - - scrollchanged = 0; - - /* left-right scrolling */ - if(px > SCROLLTRIGGERRIGHT && scroll_x < max_scroll_x) - { - map_scroll_right(); - scrollchanged = 1; - } - else if(px < SCROLLTRIGGERLEFT && scroll_x > 32) - { - map_scroll_left(); - scrollchanged = 1; - } - - /* up-down scrolling */ - if (py > SCROLLTRIGGERDOWN && scroll_y < max_scroll_y) - { - map_scroll_down(); - scrollchanged = 1; - } - else if (py < SCROLLTRIGGERUP && scroll_y > 32) - { - map_scroll_up(); - scrollchanged = 1; - } - - return scrollchanged; -} - -// animates animated tiles -void gamedo_AnimatedTiles(void) -{ -int i; - /* animate animated tiles */ - if (animtiletimer>ANIM_TILE_TIME) - { - /* advance to next frame */ - curanimtileframe = (curanimtileframe+1)&7; - /* re-draw all animated tiles */ - for(i=1;idrawTile(animtiles[i].x, animtiles[i].y, animtiles[i].baseframe+((animtiles[i].offset+curanimtileframe)%TileProperty[animtiles[i].baseframe][ANIMATION])); - } - } - animtiletimer = 0; - } - else animtiletimer++; -} - -// do object and enemy AI -void gamedo_enemyai(stCloneKeenPlus *pCKP) -{ -int i; -// handle objects and do enemy AI - for(i=1;i (map.xsize << CSF << 4) || objects[i].y > (map.ysize << CSF << 4)) - continue; - - objects[i].scrx = (objects[i].x>>CSF)-scroll_x; - objects[i].scry = (objects[i].y>>CSF)-scroll_y; - if (objects[i].scrx < -(sprites[objects[i].sprite].xsize) || objects[i].scrx > 320 \ - || objects[i].scry < -(sprites[objects[i].sprite].ysize) || objects[i].scry > 200) - { - objects[i].onscreen = 0; - objects[i].wasoffscreen = 1; - if (objects[i].type==OBJ_ICEBIT) objects[i].exists = 0; - } - else - { - #ifdef TARGET_WIN32 -// if (numplayers>1) -// 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) - { - common_enemy_ai(i); - switch(objects[i].type) - { - //KEEN1 - case OBJ_YORP: yorp_ai(i, pCKP->Control.levelcontrol); break; - case OBJ_GARG: garg_ai(i, pCKP); break; - case OBJ_VORT: vort_ai(i, pCKP, pCKP->Control.levelcontrol); break; - case OBJ_BUTLER: butler_ai(i, pCKP->Control.levelcontrol.hardmode); break; - 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); break; - case OBJ_ICECHUNK: icechunk_ai(i); break; - case OBJ_ICEBIT: icebit_ai(i); break; - case OBJ_TELEPORTER: teleporter_ai(i, pCKP->Control.levelcontrol); break; - case OBJ_ROPE: rope_ai(i); break; - //KEEN2 - case OBJ_WALKER: walker_ai(i, pCKP->Control.levelcontrol); break; - case OBJ_TANKEP2: tankep2_ai(i, pCKP); break; - case OBJ_PLATFORM: platform_ai(i, pCKP->Control.levelcontrol); break; - case OBJ_BEAR: bear_ai(i, pCKP->Control.levelcontrol, pCKP); break; - case OBJ_SECTOREFFECTOR: se_ai(i, pCKP); break; - case OBJ_BABY: baby_ai(i, pCKP->Control.levelcontrol); break; - case OBJ_EXPLOSION: explosion_ai(i); break; - case OBJ_EARTHCHUNK: earthchunk_ai(i); break; - //KEEN3 - case OBJ_FOOB: foob_ai(i, pCKP); break; - case OBJ_NINJA: ninja_ai(i, pCKP); break; - case OBJ_MEEP: meep_ai(i, pCKP->Control.levelcontrol); break; - case OBJ_SNDWAVE: sndwave_ai(i, pCKP); break; - case OBJ_MOTHER: mother_ai(i, pCKP->Control.levelcontrol); break; - case OBJ_FIREBALL: fireball_ai(i, pCKP); break; - case OBJ_BALL: ballandjack_ai(i, pCKP); break; - case OBJ_JACK: ballandjack_ai(i, pCKP); break; - case OBJ_PLATVERT: platvert_ai(i); break; - case OBJ_NESSIE: nessie_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"; - break; - } - - objects[i].scrx = (objects[i].x>>CSF)-scroll_x; - objects[i].scry = (objects[i].y>>CSF)-scroll_y; - } - } -} - - -int savew, saveh; - -void gamedo_render_drawobjects(stCloneKeenPlus *pCKP) -{ -unsigned int i; -int x,y,o,tl,xsize,ysize; -int xa,ya; - - // copy player data to their associated objects show they can get drawn - // in the object-drawing loop with the rest of the objects - for( i=0 ;i < numplayers ; i++) - { - o = player[i].useObject; - - if (!player[i].hideplayer) - { - objects[o].sprite = player[i].playframe + playerbaseframes[i]; - } - - else - { - objects[o].sprite = BlankSprite; - } - objects[o].x = player[i].x; - objects[o].y = player[i].y; - objects[o].scrx = (player[i].x>>CSF)-scroll_x; - objects[o].scry = (player[i].y>>CSF)-scroll_y; - - } - - // if we're playing a demo keep the "DEMO" message on the screen - // as an object - if (demomode==DEMO_PLAYBACK) - { - #define DEMO_X_POS 137 - #define DEMO_Y_POS 6 - objects[DemoObjectHandle].exists = 1; - objects[DemoObjectHandle].onscreen = 1; - objects[DemoObjectHandle].type = OBJ_DEMOMSG; - objects[DemoObjectHandle].sprite = DemoSprite; - objects[DemoObjectHandle].x = (DEMO_X_POS+scroll_x)<>CSF)-scroll_x); - objects[i].scry = ((objects[i].y>>CSF)-scroll_y); - g_pGraphics->drawSprite(objects[i].scrx, objects[i].scry, objects[i].sprite, i); - - if (objects[i].honorPriority) - { - // handle priority tiles and tiles with masks - // get the upper-left coordinates to start checking for tiles - x = (((objects[i].x>>CSF)-1)>>4)<<4; - y = (((objects[i].y>>CSF)-1)>>4)<<4; - - // get the xsize/ysize of this sprite--round up to the nearest 16 - xsize = ((sprites[objects[i].sprite].xsize)>>4<<4); - if (xsize != sprites[objects[i].sprite].xsize) xsize+=16; - - ysize = ((sprites[objects[i].sprite].ysize)>>4<<4); - if (ysize != sprites[objects[i].sprite].ysize) ysize+=16; - - // now redraw any priority/masked tiles that we covered up - // with the sprite - for(ya=0;ya<=ysize;ya+=16) - { - for(xa=0;xa<=xsize;xa+=16) - { - tl = getmaptileat(x+xa,y+ya); - if(TileProperty[tl][BEHAVIOR] == 65534) - { - g_pGraphics->drawTilewithmask(x+xa-scroll_x,y+ya-scroll_y,tl,tl+1); - } - else if (TileProperty[tl][BEHAVIOR] == 65535) - { - if ( TileProperty[tl][ANIMATION] > 1 ) - { - tl = (tl-tiles[tl].animOffset)+((tiles[tl].animOffset+curanimtileframe)%TileProperty[tl][ANIMATION]); - } - g_pGraphics->drawPrioritytile(x+xa-scroll_x,y+ya-scroll_y,tl); - } - } - } - } - - } - if(i==0) break; - } - -} - -void gamedo_render_drawdebug(void) -{ -int tl,y; -/*int h;*/ - std::string debugmsg; - - if (debugmode) - { - if (debugmode==1) - { - savew = 190; - saveh = 80; - g_pGraphics->saveArea(4,4,savew,saveh); - y = 5-8; - debugmsg = "p1x/y: " + itoa(player[0].x) + "/" + itoa(player[0].y); - g_pGraphics->sb_font_draw( debugmsg, 5, y+=8); - debugmsg = "p2x/y: " + itoa(player[1].x) + "/" + itoa(player[1].y); - g_pGraphics->sb_font_draw( debugmsg, 5, y+=8); - debugmsg = "scroll_x/y = " + itoa(scroll_x) + "/" + itoa(scroll_y); - g_pGraphics->sb_font_draw( debugmsg, 5, y+=8); - debugmsg = "scrollbuf_x/y: " + itoa(scrollx_buf) + "/" + itoa(scrolly_buf); - g_pGraphics->sb_font_draw( debugmsg, 5, y+=8); - debugmsg = "iw,pw: " + itoa(player[0].inhibitwalking) + "/" + itoa(player[0].pwalking); - g_pGraphics->sb_font_draw( debugmsg, 5, y+=8); - debugmsg = "pinertia_x: " + itoa(player[0].pinertia_x); - g_pGraphics->sb_font_draw( debugmsg, 5, y+=8); - debugmsg = "psupt: (" + itoa(player[0].psupportingtile) + "," + itoa(player[0].psupportingobject) + ")"; - g_pGraphics->sb_font_draw( debugmsg, 5, y+=8); - - debugmsg = "lvl,tile = " + itoa(getlevelat((player[0].x>>CSF)+4, (player[0].y>>CSF)+9)) + "," + itoa(tl); - g_pGraphics->sb_font_draw( debugmsg, 5, y+=8); - -/* - sprintf(debugmsg, "NOH=%d", NessieObjectHandle); - sb_font_draw(debugmsg, 5, y+=8); - sprintf(debugmsg, "x,y=(%d,%d)", objects[NessieObjectHandle].x,objects[NessieObjectHandle].y); - sb_font_draw(debugmsg, 5, y+=8); - sprintf(debugmsg, " >>CSF=(%d,%d)", objects[NessieObjectHandle].x>>CSF,objects[NessieObjectHandle].y>>CSF); - sb_font_draw(debugmsg, 5, y+=8); - sprintf(debugmsg, " >>CSF>>4=(%d,%d)", objects[NessieObjectHandle].x>>CSF>>4,objects[NessieObjectHandle].y>>CSF>>4); - sb_font_draw(debugmsg, 5, y+=8); - - sprintf(debugmsg, "nessiestate = %d", objects[NessieObjectHandle].ai.nessie.state); - sb_font_draw(debugmsg, 5, y+=8); - sprintf(debugmsg, "pausetimer = %d", objects[NessieObjectHandle].ai.nessie.pausetimer); - sb_font_draw(debugmsg, 5, y+=8); - sprintf(debugmsg, "pausex/y = (%d,%d)", objects[NessieObjectHandle].ai.nessie.pausex,objects[NessieObjectHandle].ai.nessie.pausey); - sb_font_draw(debugmsg, 5, y+=8); - sprintf(debugmsg, "destx/y = %d/%d", objects[NessieObjectHandle].ai.nessie.destx,objects[NessieObjectHandle].ai.nessie.desty); - sb_font_draw(debugmsg, 5, y+=8); - sprintf(debugmsg, " >>CSF = %d/%d", objects[NessieObjectHandle].ai.nessie.destx>>CSF,objects[NessieObjectHandle].ai.nessie.desty>>CSF); - sb_font_draw(debugmsg, 5, y+=8); - sprintf(debugmsg, " >>CSF>>4 = %d/%d", objects[NessieObjectHandle].ai.nessie.destx>>CSF>>4,objects[NessieObjectHandle].ai.nessie.desty>>CSF>>4); - sb_font_draw(debugmsg, 5, y+=8); - sprintf(debugmsg, "mort_swim_amt = %d", objects[NessieObjectHandle].ai.nessie.mortimer_swim_amt); - sb_font_draw(debugmsg, 5, y+=8); - - h = objects[NessieObjectHandle].ai.nessie.tiletrailhead; - - sprintf(debugmsg, "tthead=%d", h); - sb_font_draw(debugmsg, 5, y+=8); - - sprintf(debugmsg, "ttX=%d,%d,%d,%d,%d", objects[NessieObjectHandle].ai.nessie.tiletrailX[0],objects[NessieObjectHandle].ai.nessie.tiletrailX[1],objects[NessieObjectHandle].ai.nessie.tiletrailX[2],objects[NessieObjectHandle].ai.nessie.tiletrailX[3],objects[NessieObjectHandle].ai.nessie.tiletrailX[4]); - sb_font_draw(debugmsg, 5, y+=8); - sprintf(debugmsg, "ttY=%d,%d,%d,%d,%d", objects[NessieObjectHandle].ai.nessie.tiletrailY[0],objects[NessieObjectHandle].ai.nessie.tiletrailY[1],objects[NessieObjectHandle].ai.nessie.tiletrailY[2],objects[NessieObjectHandle].ai.nessie.tiletrailY[3],objects[NessieObjectHandle].ai.nessie.tiletrailY[4]); - sb_font_draw(debugmsg, 5, y+=8); -*/ - } - else if (debugmode==2) - { - savew = map.xsize+4; - saveh = map.ysize+4; - g_pGraphics->saveArea(4,4,savew,saveh); - radar(); - } - } -} - -void gamedo_render_erasedebug(void) -{ - if (debugmode) g_pGraphics->restoreArea(4,4,savew,saveh); -} - -void gamedo_render_eraseobjects(void) -{ -int i; - - // erase all objects. - // note that this is done in the reverse order they are drawn. - // this is necessary or you will see corrupted pixels when - // two objects are occupying the same space. - for(i=0;ieraseSprite(objects[i].scrx, objects[i].scry, objects[i].sprite, i); - } - } -} - -extern int NumConsoleMessages; - -// draws sprites, players, and debug messages (if debug mode is on), -// performs frameskipping and blits the display as needed, -// at end of functions erases all drawn objects from the scrollbuf. -void gamedo_RenderScreen(stCloneKeenPlus *pCKP) -{ - int x,y,bmnum; - - g_pGraphics->renderHQBitmap(); - - gamedo_render_drawobjects(pCKP); - - if(pCKP != NULL) - { - if (pCKP->Control.levelcontrol.gameovermode) - { - // figure out where to center the gameover bitmap and draw it - bmnum = g_pGraphics->getBitmapNumberFromName("GAMEOVER"); - x = (320/2)-(bitmaps[bmnum].xsize/2); - y = (200/2)-(bitmaps[bmnum].ysize/2); - g_pGraphics->drawBitmap(x, y, bmnum); - } - } - - g_pVideoDriver->sb_blit(); // blit scrollbuffer to display - - gamedo_render_erasedebug(); - gamedo_render_eraseobjects(); - - curfps++; -} - -int ctspace=0, lastctspace=0; -void gamedo_HandleFKeys(stCloneKeenPlus *pCKP) -{ -int i; - - if (g_pInput->getHoldedKey(KC) && - g_pInput->getHoldedKey(KT) && - g_pInput->getHoldedKey(KSPACE)) - { - ctspace = 1; - } - else ctspace = 0; - - if (ctspace && !lastctspace) - { - for(i=0;iAddConsoleMsg("All items cheat"); - } - - lastctspace = ctspace; - - // GOD cheat -- toggle god mode - if (g_pInput->getHoldedKey(KG) && g_pInput->getHoldedKey(KO) && g_pInput->getHoldedKey(KD)) - { - for(i=0;iDeleteConsoleMsgs(); - if (player[0].godmode) - g_pVideoDriver->AddConsoleMsg("God mode ON"); - else - g_pVideoDriver->AddConsoleMsg("God mode OFF"); - - g_pSound->playSound(SOUND_GUN_CLICK, PLAY_FORCE); - - // Show a message like in the original game - char **text; - - text = (char**) malloc(sizeof(char*)); - - static const int MAX_STRING_LENGTH = 256; - text[0]= (char*) malloc(MAX_STRING_LENGTH*sizeof(char)); - - if (player[0].godmode) - strcpy(text[0], "Godmode enabled"); - else - strcpy(text[0], "Godmode disabled"); - - showTextMB(1,text,pCKP); - - free(text[0]); - free(text); - } - - - if (pCKP->Option[OPT_CHEATS].value) - { - if (g_pInput->getHoldedKey(KTAB)) // noclip/revive - { - // resurrect any dead players. the rest of the KTAB magic is - // scattered throughout the various functions. - for(i=0;igetPressedKey(KF8)) - { - framebyframe = 1; - #ifdef BUILD_SDL - g_pVideoDriver->AddConsoleMsg("Frame-by-frame mode F8:advance F7:stop"); - #endif - } - // F9 - exit level immediately - if(g_pInput->getPressedKey(KF9)) - { - endlevel(1, pCKP); - } - // F6 - onscreen debug--toggle through debug/radar/off - if(g_pInput->getPressedKey(KF6)) - { - debugmode++; - if (debugmode>2) debugmode=0; - } - // F7 - accelerate mode/frame by frame frame advance - if(g_pInput->getPressedKey(KF7)) - { - if (!framebyframe) acceleratemode=1-acceleratemode; - } - } - - // F10 - change primary player - if(g_pInput->getPressedKey(KF10)) - { - primaryplayer++; - if (primaryplayer>=numplayers) primaryplayer=0; - } - // F3 - save game - if (g_pInput->getPressedKey(KF3)) - game_save_interface(pCKP); - -} - -void gamedo_fades(void) -{ - if (fade.mode != FADE_GO) return; - - if (fade.fadetimer > fade.rate) - { - if (fade.dir==FADE_IN) - { - if (fade.curamt < PAL_FADE_SHADES) - { - fade.curamt++; // coming in from black - } - else - { - fade.curamt--; // coming in from white-out - } - if (fade.curamt==PAL_FADE_SHADES) - { - fade.mode = FADE_COMPLETE; - } - g_pGraphics->fadePalette(fade.curamt); - } - else if (fade.dir==FADE_OUT) - { - fade.curamt--; - if (fade.curamt==0) fade.mode = FADE_COMPLETE; - g_pGraphics->fadePalette(fade.curamt); - } - fade.fadetimer = 0; - } - else - { - fade.fadetimer++; - } -} - -void gamedo_frameskipping(stCloneKeenPlus *pCKP) -{ - if (framebyframe) - { - gamedo_RenderScreen(pCKP); - return; - } - - if (frameskiptimer >= g_pVideoDriver->getFrameskip()) - { - gamedo_RenderScreen(pCKP); - frameskiptimer = 0; - } else frameskiptimer++; - -} - -// same as above but only does a sb_blit, not the full RenderScreen. -// used for intros etc. -void gamedo_frameskipping_blitonly(void) -{ - if (framebyframe) - { - g_pVideoDriver->sb_blit(); - return; - } - - if (frameskiptimer >= g_pVideoDriver->getFrameskip()) - { - g_pVideoDriver->sb_blit(); - frameskiptimer = 0; - } else frameskiptimer++; -} - +/* GAMEDO.C + Contains all of the gamedo_xxx functions...which are called from the + main game loop. These functions perform some task that is done each + time around the game loop, not directly related to the player. +*/ + +#include "keen.h" + +#include "include/game.h" +#include "include/gamedo.h" +#include "include/gamepdo.h" +#include "include/misc.h" +#include "sdl/CVideoDriver.h" +#include "sdl/CTimer.h" +#include "sdl/CInput.h" +#include "sdl/sound/CSound.h" +#include "CGraphics.h" +#include "vorticon/CPlayer.h" +#include "keenext.h" + +#include "include/enemyai.h" + +extern unsigned long gotPlayX; + +extern unsigned long CurrentTickCount; + +extern unsigned int unknownKey; + +extern CPlayer *Player; + +int animtiletimer, curanimtileframe; + +// gathers data from input controllers: keyboard, joystick, network, +// whatever to populate each player's keytable +unsigned char oldleftkey = 5; +unsigned char oldrightkey = 5; +unsigned char oldupkey = 5; +unsigned char olddownkey = 5; +unsigned char oldctrlkey = 5; +unsigned char oldaltkey = 5; +void gamedo_getInput(stCloneKeenPlus *pCKP) +{ +int i; +int byt; +unsigned int msb, lsb; + + if (demomode==DEMO_PLAYBACK) + { + // time to get a new key block? + if (!demo_RLERunLen) + { + /* get next RLE run length */ + lsb = demo_data[demo_data_index++]; + msb = demo_data[demo_data_index++]; + demo_RLERunLen = (msb<<8) | lsb; + byt = demo_data[demo_data_index++]; // get keys down + + player[0].playcontrol[PA_X] = 0; + player[0].playcontrol[PA_POGO] = 0; + player[0].playcontrol[PA_JUMP] = 0; + player[0].playcontrol[PA_FIRE] = 0; + player[0].playcontrol[PA_STATUS] = 0; + + if (byt & 1) player[0].playcontrol[PA_X] -= 100; + if (byt & 2) player[0].playcontrol[PA_X] += 100; + if (byt & 4) player[0].playcontrol[PA_POGO] = 1; + if (byt & 8) player[0].playcontrol[PA_JUMP] = 1; + if (byt & 16)player[0].playcontrol[PA_FIRE] = 1; + if (byt & 32)player[0].playcontrol[PA_STATUS] = 1; + if (byt & 64) + { // demo STOP command + if (fade.mode!=FADE_GO) endlevel(1, pCKP); + } + } + else + { + // we're still in the last RLE run, don't change any keys + demo_RLERunLen--; + } + + // user trying to cancel the demo? + for(i=0;igetPressedKey(i)) + { + if (fade.mode!=FADE_GO) endlevel(0, pCKP); + } + } + if (g_pInput->getPressedCommand(IC_STATUS)) + { + if (fade.mode!=FADE_GO) endlevel(0, pCKP); + } + + return; + } + + for(Uint8 p=0 ; pgetHoldedCommand(p, IC_LEFT)) + player[p].playcontrol[PA_X] -= 100; + if(g_pInput->getHoldedCommand(p, IC_RIGHT)) + player[p].playcontrol[PA_X] += 100; + + if(g_pInput->getHoldedCommand(p, IC_UP)) + player[p].playcontrol[PA_Y] -= 100; + if(g_pInput->getHoldedCommand(p, IC_DOWN)) + player[p].playcontrol[PA_Y] += 100; + + if(g_pInput->getHoldedCommand(p, IC_JUMP)) + player[p].playcontrol[PA_JUMP] = 1; + if(g_pInput->getHoldedCommand(p, IC_POGO)) + player[p].playcontrol[PA_POGO] = 1; + if(g_pInput->getHoldedCommand(p, IC_FIRE)) + player[p].playcontrol[PA_FIRE] = 1; + if(g_pInput->getHoldedCommand(p, IC_STATUS)) + player[p].playcontrol[PA_STATUS] = 1; + + if (demomode==DEMO_RECORD) + { + if(i) player[p].playcontrol[PA_X] += 100; + fputc(i, demofile); + if(i) player[p].playcontrol[PA_X] -= 100; + fputc(i, demofile); + if(i) player[p].playcontrol[PA_POGO] = 1; + fputc(i, demofile); + if(i) player[p].playcontrol[PA_JUMP] = 1; + fputc(i, demofile); + if(i) player[p].playcontrol[PA_FIRE] = 1; + fputc(i, demofile); + if(i) player[p].playcontrol[PA_STATUS] = 1; + fputc(i, demofile); + } + } +} + +// handles scrolling, for player cp +// returns nonzero if the scroll was changed +int gamedo_ScrollTriggers(int theplayer) +{ +signed int px, py; +int scrollchanged; + + if (player[theplayer].pdie) return 0; + + //px = (Player[theplayer].getCoordX()>>CSF)-scroll_x; + //py = (Player[theplayer].getCoordY()>>CSF)-scroll_y; + + px = (player[theplayer].x>>CSF)-scroll_x; + py = (player[theplayer].y>>CSF)-scroll_y; + + scrollchanged = 0; + + /* left-right scrolling */ + if(px > SCROLLTRIGGERRIGHT && scroll_x < max_scroll_x) + { + map_scroll_right(); + scrollchanged = 1; + } + else if(px < SCROLLTRIGGERLEFT && scroll_x > 32) + { + map_scroll_left(); + scrollchanged = 1; + } + + /* up-down scrolling */ + if (py > SCROLLTRIGGERDOWN && scroll_y < max_scroll_y) + { + map_scroll_down(); + scrollchanged = 1; + } + else if (py < SCROLLTRIGGERUP && scroll_y > 32) + { + map_scroll_up(); + scrollchanged = 1; + } + + return scrollchanged; +} + +// animates animated tiles +void gamedo_AnimatedTiles(void) +{ +int i; + /* animate animated tiles */ + if (animtiletimer>ANIM_TILE_TIME) + { + /* advance to next frame */ + curanimtileframe = (curanimtileframe+1)&7; + /* re-draw all animated tiles */ + for(i=1;idrawTile(animtiles[i].x, animtiles[i].y, animtiles[i].baseframe+((animtiles[i].offset+curanimtileframe)%TileProperty[animtiles[i].baseframe][ANIMATION])); + } + } + animtiletimer = 0; + } + else animtiletimer++; +} + +// do object and enemy AI +void gamedo_enemyai(stCloneKeenPlus *pCKP) +{ +int i; +// handle objects and do enemy AI + for(i=1;i (map.xsize << CSF << 4) || objects[i].y > (map.ysize << CSF << 4)) + continue; + + objects[i].scrx = (objects[i].x>>CSF)-scroll_x; + objects[i].scry = (objects[i].y>>CSF)-scroll_y; + if (objects[i].scrx < -(sprites[objects[i].sprite].xsize) || objects[i].scrx > 320 \ + || objects[i].scry < -(sprites[objects[i].sprite].ysize) || objects[i].scry > 200) + { + objects[i].onscreen = 0; + objects[i].wasoffscreen = 1; + if (objects[i].type==OBJ_ICEBIT) objects[i].exists = 0; + } + else + { + #ifdef TARGET_WIN32 +// if (numplayers>1) +// 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) + { + common_enemy_ai(i); + switch(objects[i].type) + { + //KEEN1 + case OBJ_YORP: yorp_ai(i, pCKP->Control.levelcontrol); break; + case OBJ_GARG: garg_ai(i, pCKP); break; + case OBJ_VORT: vort_ai(i, pCKP, pCKP->Control.levelcontrol); break; + case OBJ_BUTLER: butler_ai(i, pCKP->Control.levelcontrol.hardmode); break; + 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); break; + case OBJ_ICECHUNK: icechunk_ai(i); break; + case OBJ_ICEBIT: icebit_ai(i); break; + case OBJ_TELEPORTER: teleporter_ai(i, pCKP->Control.levelcontrol); break; + case OBJ_ROPE: rope_ai(i); break; + //KEEN2 + case OBJ_WALKER: walker_ai(i, pCKP->Control.levelcontrol); break; + case OBJ_TANKEP2: tankep2_ai(i, pCKP); break; + case OBJ_PLATFORM: platform_ai(i, pCKP->Control.levelcontrol); break; + case OBJ_BEAR: bear_ai(i, pCKP->Control.levelcontrol, pCKP); break; + case OBJ_SECTOREFFECTOR: se_ai(i, pCKP); break; + case OBJ_BABY: baby_ai(i, pCKP->Control.levelcontrol); break; + case OBJ_EXPLOSION: explosion_ai(i); break; + case OBJ_EARTHCHUNK: earthchunk_ai(i); break; + //KEEN3 + case OBJ_FOOB: foob_ai(i, pCKP); break; + case OBJ_NINJA: ninja_ai(i, pCKP); break; + case OBJ_MEEP: meep_ai(i, pCKP->Control.levelcontrol); break; + case OBJ_SNDWAVE: sndwave_ai(i, pCKP); break; + case OBJ_MOTHER: mother_ai(i, pCKP->Control.levelcontrol); break; + case OBJ_FIREBALL: fireball_ai(i, pCKP); break; + case OBJ_BALL: ballandjack_ai(i, pCKP); break; + case OBJ_JACK: ballandjack_ai(i, pCKP); break; + case OBJ_PLATVERT: platvert_ai(i); break; + case OBJ_NESSIE: nessie_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"; + break; + } + + objects[i].scrx = (objects[i].x>>CSF)-scroll_x; + objects[i].scry = (objects[i].y>>CSF)-scroll_y; + } + } +} + + +int savew, saveh; + +void gamedo_render_drawobjects(stCloneKeenPlus *pCKP) +{ +unsigned int i; +int x,y,o,tl,xsize,ysize; +int xa,ya; + + // copy player data to their associated objects show they can get drawn + // in the object-drawing loop with the rest of the objects + for( i=0 ;i < numplayers ; i++) + { + o = player[i].useObject; + + if (!player[i].hideplayer) + { + objects[o].sprite = player[i].playframe + playerbaseframes[i]; + } + + else + { + objects[o].sprite = BlankSprite; + } + objects[o].x = player[i].x; + objects[o].y = player[i].y; + objects[o].scrx = (player[i].x>>CSF)-scroll_x; + objects[o].scry = (player[i].y>>CSF)-scroll_y; + + } + + // if we're playing a demo keep the "DEMO" message on the screen + // as an object + if (demomode==DEMO_PLAYBACK) + { + #define DEMO_X_POS 137 + #define DEMO_Y_POS 6 + objects[DemoObjectHandle].exists = 1; + objects[DemoObjectHandle].onscreen = 1; + objects[DemoObjectHandle].type = OBJ_DEMOMSG; + objects[DemoObjectHandle].sprite = DemoSprite; + objects[DemoObjectHandle].x = (DEMO_X_POS+scroll_x)<>CSF)-scroll_x); + objects[i].scry = ((objects[i].y>>CSF)-scroll_y); + g_pGraphics->drawSprite(objects[i].scrx, objects[i].scry, objects[i].sprite, i); + + if (objects[i].honorPriority) + { + // handle priority tiles and tiles with masks + // get the upper-left coordinates to start checking for tiles + x = (((objects[i].x>>CSF)-1)>>4)<<4; + y = (((objects[i].y>>CSF)-1)>>4)<<4; + + // get the xsize/ysize of this sprite--round up to the nearest 16 + xsize = ((sprites[objects[i].sprite].xsize)>>4<<4); + if (xsize != sprites[objects[i].sprite].xsize) xsize+=16; + + ysize = ((sprites[objects[i].sprite].ysize)>>4<<4); + if (ysize != sprites[objects[i].sprite].ysize) ysize+=16; + + // now redraw any priority/masked tiles that we covered up + // with the sprite + for(ya=0;ya<=ysize;ya+=16) + { + for(xa=0;xa<=xsize;xa+=16) + { + tl = getmaptileat(x+xa,y+ya); + if(TileProperty[tl][BEHAVIOR] == 65534) + { + g_pGraphics->drawTilewithmask(x+xa-scroll_x,y+ya-scroll_y,tl,tl+1); + } + else if (TileProperty[tl][BEHAVIOR] == 65535) + { + if ( TileProperty[tl][ANIMATION] > 1 ) + { + tl = (tl-tiles[tl].animOffset)+((tiles[tl].animOffset+curanimtileframe)%TileProperty[tl][ANIMATION]); + } + g_pGraphics->drawPrioritytile(x+xa-scroll_x,y+ya-scroll_y,tl); + } + } + } + } + + } + if(i==0) break; + } + +} + +void gamedo_render_drawdebug(void) +{ +int tl,y; +/*int h;*/ +char debugmsg[80]; + + if (debugmode) + { + if (debugmode==1) + { + savew = 190; + saveh = 80; + g_pGraphics->saveArea(4,4,savew,saveh); + y = 5-8; + sprintf(debugmsg, "p1x/y: %ld/%d", player[0].x, player[0].y); + g_pGraphics->sb_font_draw( (unsigned char*) debugmsg, 5, y+=8); + sprintf(debugmsg, "p2x/y: %ld/%d", player[1].x, player[1].y); + g_pGraphics->sb_font_draw( (unsigned char*) debugmsg, 5, y+=8); + sprintf(debugmsg, "scroll_x/y = %d/%d", (unsigned int)scroll_x, (unsigned int)scroll_y); + g_pGraphics->sb_font_draw( (unsigned char*) debugmsg, 5, y+=8); + sprintf(debugmsg, "scrollbuf_x/y: %d/%d", scrollx_buf, scrolly_buf); + g_pGraphics->sb_font_draw( (unsigned char*) debugmsg, 5, y+=8); + sprintf(debugmsg, "iw,pw: %d/%d", player[0].inhibitwalking, player[0].pwalking); + g_pGraphics->sb_font_draw( (unsigned char*) debugmsg, 5, y+=8); + sprintf(debugmsg, "pinertia_x: %d", player[0].pinertia_x); + g_pGraphics->sb_font_draw( (unsigned char*) debugmsg, 5, y+=8); + sprintf(debugmsg, "psupt: (%d,%d)", player[0].psupportingtile, player[0].psupportingobject); + g_pGraphics->sb_font_draw( (unsigned char*) debugmsg, 5, y+=8); + + sprintf(debugmsg, "lvl,tile = %d,%d", getlevelat((player[0].x>>CSF)+4, (player[0].y>>CSF)+9), tl); + g_pGraphics->sb_font_draw( (unsigned char*) debugmsg, 5, y+=8); + +/* + sprintf(debugmsg, "NOH=%d", NessieObjectHandle); + sb_font_draw(debugmsg, 5, y+=8); + sprintf(debugmsg, "x,y=(%d,%d)", objects[NessieObjectHandle].x,objects[NessieObjectHandle].y); + sb_font_draw(debugmsg, 5, y+=8); + sprintf(debugmsg, " >>CSF=(%d,%d)", objects[NessieObjectHandle].x>>CSF,objects[NessieObjectHandle].y>>CSF); + sb_font_draw(debugmsg, 5, y+=8); + sprintf(debugmsg, " >>CSF>>4=(%d,%d)", objects[NessieObjectHandle].x>>CSF>>4,objects[NessieObjectHandle].y>>CSF>>4); + sb_font_draw(debugmsg, 5, y+=8); + + sprintf(debugmsg, "nessiestate = %d", objects[NessieObjectHandle].ai.nessie.state); + sb_font_draw(debugmsg, 5, y+=8); + sprintf(debugmsg, "pausetimer = %d", objects[NessieObjectHandle].ai.nessie.pausetimer); + sb_font_draw(debugmsg, 5, y+=8); + sprintf(debugmsg, "pausex/y = (%d,%d)", objects[NessieObjectHandle].ai.nessie.pausex,objects[NessieObjectHandle].ai.nessie.pausey); + sb_font_draw(debugmsg, 5, y+=8); + sprintf(debugmsg, "destx/y = %d/%d", objects[NessieObjectHandle].ai.nessie.destx,objects[NessieObjectHandle].ai.nessie.desty); + sb_font_draw(debugmsg, 5, y+=8); + sprintf(debugmsg, " >>CSF = %d/%d", objects[NessieObjectHandle].ai.nessie.destx>>CSF,objects[NessieObjectHandle].ai.nessie.desty>>CSF); + sb_font_draw(debugmsg, 5, y+=8); + sprintf(debugmsg, " >>CSF>>4 = %d/%d", objects[NessieObjectHandle].ai.nessie.destx>>CSF>>4,objects[NessieObjectHandle].ai.nessie.desty>>CSF>>4); + sb_font_draw(debugmsg, 5, y+=8); + sprintf(debugmsg, "mort_swim_amt = %d", objects[NessieObjectHandle].ai.nessie.mortimer_swim_amt); + sb_font_draw(debugmsg, 5, y+=8); + + h = objects[NessieObjectHandle].ai.nessie.tiletrailhead; + + sprintf(debugmsg, "tthead=%d", h); + sb_font_draw(debugmsg, 5, y+=8); + + sprintf(debugmsg, "ttX=%d,%d,%d,%d,%d", objects[NessieObjectHandle].ai.nessie.tiletrailX[0],objects[NessieObjectHandle].ai.nessie.tiletrailX[1],objects[NessieObjectHandle].ai.nessie.tiletrailX[2],objects[NessieObjectHandle].ai.nessie.tiletrailX[3],objects[NessieObjectHandle].ai.nessie.tiletrailX[4]); + sb_font_draw(debugmsg, 5, y+=8); + sprintf(debugmsg, "ttY=%d,%d,%d,%d,%d", objects[NessieObjectHandle].ai.nessie.tiletrailY[0],objects[NessieObjectHandle].ai.nessie.tiletrailY[1],objects[NessieObjectHandle].ai.nessie.tiletrailY[2],objects[NessieObjectHandle].ai.nessie.tiletrailY[3],objects[NessieObjectHandle].ai.nessie.tiletrailY[4]); + sb_font_draw(debugmsg, 5, y+=8); +*/ + } + else if (debugmode==2) + { + savew = map.xsize+4; + saveh = map.ysize+4; + g_pGraphics->saveArea(4,4,savew,saveh); + radar(); + } + } +} + +void gamedo_render_erasedebug(void) +{ + if (debugmode) g_pGraphics->restoreArea(4,4,savew,saveh); +} + +void gamedo_render_eraseobjects(void) +{ +int i; + + // erase all objects. + // note that this is done in the reverse order they are drawn. + // this is necessary or you will see corrupted pixels when + // two objects are occupying the same space. + for(i=0;ieraseSprite(objects[i].scrx, objects[i].scry, objects[i].sprite, i); + } + } +} + +extern int NumConsoleMessages; + +// draws sprites, players, and debug messages (if debug mode is on), +// performs frameskipping and blits the display as needed, +// at end of functions erases all drawn objects from the scrollbuf. +void gamedo_RenderScreen(stCloneKeenPlus *pCKP) +{ + int x,y,bmnum; + + g_pGraphics->renderHQBitmap(); + + gamedo_render_drawobjects(pCKP); + + if(pCKP != NULL) + { + if (pCKP->Control.levelcontrol.gameovermode) + { + // figure out where to center the gameover bitmap and draw it + bmnum = g_pGraphics->getBitmapNumberFromName("GAMEOVER"); + x = (320/2)-(bitmaps[bmnum].xsize/2); + y = (200/2)-(bitmaps[bmnum].ysize/2); + g_pGraphics->drawBitmap(x, y, bmnum); + } + } + + g_pVideoDriver->sb_blit(); // blit scrollbuffer to display + + gamedo_render_erasedebug(); + gamedo_render_eraseobjects(); + + curfps++; +} + +int ctspace=0, lastctspace=0; +void gamedo_HandleFKeys(stCloneKeenPlus *pCKP) +{ +int i; + + if (g_pInput->getHoldedKey(KC) && + g_pInput->getHoldedKey(KT) && + g_pInput->getHoldedKey(KSPACE)) + { + ctspace = 1; + } + else ctspace = 0; + + if (ctspace && !lastctspace) + { + for(i=0;iAddConsoleMsg("All items cheat"); + } + + lastctspace = ctspace; + + // GOD cheat -- toggle god mode + if (g_pInput->getHoldedKey(KG) && g_pInput->getHoldedKey(KO) && g_pInput->getHoldedKey(KD)) + { + for(i=0;iDeleteConsoleMsgs(); + if (player[0].godmode) + g_pVideoDriver->AddConsoleMsg("God mode ON"); + else + g_pVideoDriver->AddConsoleMsg("God mode OFF"); + + g_pSound->playSound(SOUND_GUN_CLICK, PLAY_FORCE); + + // Show a message like in the original game + char **text; + + text = (char**) malloc(sizeof(char*)); + + text[0]= (char*) malloc(MAX_STRING_LENGTH*sizeof(char)); + + if (player[0].godmode) + strcpy(text[0], "Godmode enabled"); + else + strcpy(text[0], "Godmode disabled"); + + showTextMB(1,text,pCKP); + + free(text[0]); + free(text); + } + + + if (pCKP->Option[OPT_CHEATS].value) + { + if (g_pInput->getHoldedKey(KTAB)) // noclip/revive + { + // resurrect any dead players. the rest of the KTAB magic is + // scattered throughout the various functions. + for(i=0;igetPressedKey(KF8)) + { + framebyframe = 1; + #ifdef BUILD_SDL + g_pVideoDriver->AddConsoleMsg("Frame-by-frame mode F8:advance F7:stop"); + #endif + } + // F9 - exit level immediately + if(g_pInput->getPressedKey(KF9)) + { + endlevel(1, pCKP); + } + // F6 - onscreen debug--toggle through debug/radar/off + if(g_pInput->getPressedKey(KF6)) + { + debugmode++; + if (debugmode>2) debugmode=0; + } + // F7 - accelerate mode/frame by frame frame advance + if(g_pInput->getPressedKey(KF7)) + { + if (!framebyframe) acceleratemode=1-acceleratemode; + } + } + + // F10 - change primary player + if(g_pInput->getPressedKey(KF10)) + { + primaryplayer++; + if (primaryplayer>=numplayers) primaryplayer=0; + } + // F3 - save game + if (g_pInput->getPressedKey(KF3)) + game_save_interface(pCKP); + +} + +void gamedo_fades(void) +{ + if (fade.mode != FADE_GO) return; + + if (fade.fadetimer > fade.rate) + { + if (fade.dir==FADE_IN) + { + if (fade.curamt < PAL_FADE_SHADES) + { + fade.curamt++; // coming in from black + } + else + { + fade.curamt--; // coming in from white-out + } + if (fade.curamt==PAL_FADE_SHADES) + { + fade.mode = FADE_COMPLETE; + } + g_pGraphics->fadePalette(fade.curamt); + } + else if (fade.dir==FADE_OUT) + { + fade.curamt--; + if (fade.curamt==0) fade.mode = FADE_COMPLETE; + g_pGraphics->fadePalette(fade.curamt); + } + fade.fadetimer = 0; + } + else + { + fade.fadetimer++; + } +} + +void gamedo_frameskipping(stCloneKeenPlus *pCKP) +{ + if (framebyframe) + { + gamedo_RenderScreen(pCKP); + return; + } + + if (frameskiptimer >= g_pVideoDriver->getFrameskip()) + { + gamedo_RenderScreen(pCKP); + frameskiptimer = 0; + } else frameskiptimer++; + +} + +// same as above but only does a sb_blit, not the full RenderScreen. +// used for intros etc. +void gamedo_frameskipping_blitonly(void) +{ + if (framebyframe) + { + g_pVideoDriver->sb_blit(); + return; + } + + if (frameskiptimer >= g_pVideoDriver->getFrameskip()) + { + g_pVideoDriver->sb_blit(); + frameskiptimer = 0; + } else frameskiptimer++; +} + diff --git a/src/hqp/CHQBitmap.cpp b/src/hqp/CHQBitmap.cpp index bb86085b0..87b694076 100644 --- a/src/hqp/CHQBitmap.cpp +++ b/src/hqp/CHQBitmap.cpp @@ -22,9 +22,9 @@ CHQBitmap::~CHQBitmap() { if(m_blackscreen){ SDL_FreeSurface(m_blackscreen); m_blackscreen = NULL;} } -bool CHQBitmap::loadImage(const std::string& pFilename, int wsize, int hsize) +bool CHQBitmap::loadImage(const char *pFilename, int wsize, int hsize) { - SDL_Surface *BitmapSurface = SDL_LoadBMP(pFilename.c_str()); + SDL_Surface *BitmapSurface = SDL_LoadBMP(pFilename); m_active = false; diff --git a/src/hqp/CHQBitmap.h b/src/hqp/CHQBitmap.h index 9f7818ebe..2e80aecf9 100644 --- a/src/hqp/CHQBitmap.h +++ b/src/hqp/CHQBitmap.h @@ -9,7 +9,6 @@ #define CHQBITMAP_H_ #include -#include class CHQBitmap { public: @@ -18,7 +17,7 @@ public: void setScrollposition(unsigned int xpos, unsigned int ypos); void updateHQBitmap(SDL_Surface *m_surface, SDL_Rect *p_srcrect, SDL_Rect *p_dstrect); - bool loadImage(const std::string& pFilename, int wsize, int hsize); + bool loadImage(const char *pFilename, int wsize, int hsize); void setAlphaBlend(Uint8 alpha); void offsetAlphaBlend(Uint8 alpha); diff --git a/src/hqp/CMusic.cpp b/src/hqp/CMusic.cpp index 3ad9b513c..452ad56c7 100644 --- a/src/hqp/CMusic.cpp +++ b/src/hqp/CMusic.cpp @@ -12,6 +12,7 @@ CMusic::CMusic() { playmode = PLAY_MODE_STOP; + music_buffer = NULL; } CMusic::~CMusic() { @@ -20,6 +21,8 @@ CMusic::~CMusic() { int CMusic::load(SDL_AudioSpec AudioSpec, char *musicfile) { + FILE *fp; + if(AudioSpec.format != 0) { @@ -33,10 +36,10 @@ int CMusic::load(SDL_AudioSpec AudioSpec, char *musicfile) pOggAudio.sound_len=0; pOggAudio.sound_pos=0; - FILE *fp; if((fp = fopen(musicfile,"rb")) == NULL) { g_pLogFile->textOut(PURPLE,"Music Driver(): \"%s\". File does not exist!
", musicfile); + return -1; } @@ -101,7 +104,8 @@ void CMusic::unload(void) void CMusic::play(void) { - playmode = PLAY_MODE_PLAY; + if(music_buffer) + playmode = PLAY_MODE_PLAY; } void CMusic::stop(void) diff --git a/src/hqp/hq_sound.cpp b/src/hqp/hq_sound.cpp index 01d284820..6061b9c25 100644 --- a/src/hqp/hq_sound.cpp +++ b/src/hqp/hq_sound.cpp @@ -11,17 +11,17 @@ #include "../include/vorbis/oggsupport.h" #include "../CLogFile.h" -short HQSndDrv_Load(SDL_AudioSpec *AudioSpec, stHQSound *psound, const std::string& soundfile) +short HQSndDrv_Load(SDL_AudioSpec *AudioSpec, stHQSound *psound, const char *soundfile) { SDL_AudioSpec AudioFileSpec; SDL_AudioCVT Audio_cvt; psound->sound_buffer = NULL; - std::string buf; + char buf[80]; FILE *fp; - buf = "data/hqp/snd/" + soundfile + ".OGG"; // Start with OGG - if((fp = fopen(buf.c_str(),"rb")) != NULL) + sprintf(buf,"data/hqp/snd/%s.OGG",soundfile); // Start with OGG + if((fp = fopen(buf,"rb")) != NULL) { #ifdef BUILD_WITH_OGG if(openOGGSound(fp, &AudioFileSpec, AudioSpec->format, psound) != 0) @@ -29,37 +29,38 @@ short HQSndDrv_Load(SDL_AudioSpec *AudioSpec, stHQSound *psound, const std::stri g_pLogFile->textOut(PURPLE,"OGG file could not be opened: \"%s\". The file was detected, but appears to be damaged. Trying to load the classical sound
", soundfile); return 1; } - psound->enabled = true; #endif #ifndef BUILD_WITH_OGG g_pLogFile->textOut(PURPLE,"Sorry, OGG-Support is disabled!
"); - buf = "data/hqp/snd/"+ soundfile + ".WAV"; + sprintf(buf,"data/hqp/snd/%s.WAV",soundfile); // Check, if it is a wav file or go back to classic sounds - if (SDL_LoadWAV (buf.c_str(), &AudioFileSpec, &(psound->sound_buffer), &(psound->sound_len)) == NULL) + if (SDL_LoadWAV (buf, &AudioFileSpec, &(psound->sound_buffer), &(psound->sound_len)) == NULL) { - g_pLogFile->textOut(PURPLE,"Wave file could not be opened: \"%s\". Trying to load the classical sound
", buf.c_str()); + g_pLogFile->textOut(PURPLE,"Wave file could not be opened: \"%s\". Trying to load the classical sound
", buf); return 1; } #endif + + psound->enabled = true; } else { - buf = "data/hqp/snd/" + soundfile + ".WAV"; + sprintf(buf,"data/hqp/snd/%s.WAV",soundfile); // Check, if it is a wav file or go back to classic sounds - if (SDL_LoadWAV (buf.c_str(), &AudioFileSpec, &(psound->sound_buffer), &(psound->sound_len)) == NULL) + if (SDL_LoadWAV (buf, &AudioFileSpec, &(psound->sound_buffer), &(psound->sound_len)) == NULL) { - g_pLogFile->textOut(PURPLE,"Wave file could not be opened: \"%s\". Trying to load the classical sounds
", buf.c_str()); + g_pLogFile->textOut(PURPLE,"Wave file could not be opened: \"%s\". Trying to load the classical sounds
", buf); return 1; } } psound->sound_pos = 0; - g_pLogFile->textOut(PURPLE,"File \"%s\" opened successfully!
", buf.c_str()); + g_pLogFile->textOut(PURPLE,"File \"%s\" opened successfully!
", buf); int ret; /* Build AudioCVT (This is needed for the conversion from one format to the one used in the game)*/ diff --git a/src/hqp/hq_sound.h b/src/hqp/hq_sound.h index 8d8c905c9..a126063a5 100644 --- a/src/hqp/hq_sound.h +++ b/src/hqp/hq_sound.h @@ -5,21 +5,15 @@ * Author: gerstrong */ -#ifndef __CG_HQ_SOUND_H__ -#define __CG_HQ_SOUND_H__ - #include -#include -struct stHQSound +typedef struct stHQSound { Uint8 *sound_buffer; Uint32 sound_len; int sound_pos; bool enabled; -}; +} stHQSound; -short HQSndDrv_Load(SDL_AudioSpec *AudioSpec, stHQSound *psound, const std::string& soundfile); +short HQSndDrv_Load(SDL_AudioSpec *AudioSpec, stHQSound *psound, const char *soundfile); void HQSndDrv_Unload(stHQSound *psound); - -#endif diff --git a/src/include/declarations.h b/src/include/declarations.h index c05f12015..3cf912e15 100644 --- a/src/include/declarations.h +++ b/src/include/declarations.h @@ -1,12 +1,8 @@ -#ifndef __CG_DECLARATIONS_H__ -#define __CG_DECLARATIONS_H__ - -#include -#include #define MAX_COMMANDS 8 #define MAX_SOUND_LENGTH 1024 #define MAX_SOUNDS 50 +#define MAX_STRING_LENGTH 256 #define MAX_NUMBER_OF_FILES 100 @@ -72,11 +68,10 @@ typedef struct stControl typedef struct stGameData { - std::string DataDirectory; - short Episode; - std::string Name; - std::string FileList[MAX_NUMBER_OF_FILES]; - stGameData() : Episode(0) {} + char DataDirectory[MAX_STRING_LENGTH]; + short Episode; + char Name[MAX_STRING_LENGTH]; + char FileList[MAX_NUMBER_OF_FILES][MAX_STRING_LENGTH]; } stGameData; @@ -111,5 +106,3 @@ typedef struct stNewPlayer { stCommand Command; } stNewPlayer; - -#endif diff --git a/src/include/eseq_ep2.h b/src/include/eseq_ep2.h index b5188f3f7..00ded39a0 100644 --- a/src/include/eseq_ep2.h +++ b/src/include/eseq_ep2.h @@ -5,17 +5,10 @@ * Author: gerstrong */ -#ifndef __CG_ESEQ_EP2_H__ -#define __CG_ESEQ_EP2_H__ - -#include -struct stCloneKeenPlus; - int eseq2_LimpsHome(stCloneKeenPlus *pCKP); int eseq2_TantalusRay(stCloneKeenPlus *pCKP); void eseq2_vibrate(stCloneKeenPlus *pCKP); int eseq2_HeadsForEarth(stCloneKeenPlus *pCKP); int eseq2_SnowedOutside(stCloneKeenPlus *pCKP); -void eseq_showmsg(const std::string& text, int boxleft, int boxtop, int boxwidth, int boxheight, char autodismiss, stCloneKeenPlus *pCKP); +void eseq_showmsg(char *text, int boxleft, int boxtop, int boxwidth, int boxheight, char autodismiss, stCloneKeenPlus *pCKP); -#endif diff --git a/src/include/fileio.h b/src/include/fileio.h index 831d51e1b..6991c57f6 100644 --- a/src/include/fileio.h +++ b/src/include/fileio.h @@ -5,17 +5,10 @@ * Author: gerstrong */ -#ifndef __CG_FILEIO_H__ -#define __CG_FILEIO_H__ - -#include - -unsigned int loadmap(const std::string& filename, const std::string& path, int lvlnum, int isworldmap, stCloneKeenPlus *pCKP); +unsigned int loadmap(char filename[MAX_STRING_LENGTH], char *path, int lvlnum, int isworldmap, stCloneKeenPlus *pCKP); void addmaptile(unsigned int t); void addenemytile(unsigned int t, stCloneKeenPlus *pCKP); short checkConsistencyofGameData(stGameData *p_GameData); -std::string formatPathString(const std::string& path); +void formatPathString(char *output, const char *path); bool renameFilenamesLowerCase(const char *dir_name); void assignChangeTileAttribute(stTile *tile, int episode); - -#endif diff --git a/src/include/fileio/story.h b/src/include/fileio/story.h index 6c7ae39c0..6c051082f 100644 --- a/src/include/fileio/story.h +++ b/src/include/fileio/story.h @@ -5,11 +5,4 @@ * Author: gerstrong */ -#ifndef __CG_STORY_H__ -#define __CG_STORY_H__ - -#include - -int readStoryText(char **ptext, int episode, const std::string& path); - -#endif +int readStoryText(char **ptext, int episode, char *path); diff --git a/src/keen.h b/src/keen.h index 6c51fa217..77d06723b 100644 --- a/src/keen.h +++ b/src/keen.h @@ -1,864 +1,864 @@ -#include -#include -#include - -#ifdef TARGET_DOS - #include - #include - #include - #include - #include "dos\timer.h" -#endif - -#ifdef TARGET_WIN32 - #include -#endif - -#include "vorticon/sounds.h" -#include "funcdefs.h" -#include "fileio/CTileLoader.h" - -#include "include/playeraction.h" - -#define CSF 5 - -//#define OVSIZE 3000 - -// when crashflag is activated by setting it to QUIT_NONFATAL, -// the application will immediately shut down, however the -// "a Fatal Error Occurred" message box will not pop up and -// the sysbeep will not sound. -#define QUIT_NONFATAL 555 - -#define SAVEGAMEVERSION '4' -#define ATTRFILEVERSION 1 - -#define WM_MAP_NUM 80 - -#define MAX_SPRITES 300 -#define MAX_FONT 256 -#define MAX_BITMAPS 20 - -#define MAX_OBJECTS 100 -#define MAX_ANIMTILES 200 - -#define PAL_FADE_SHADES 20 -#define PAL_FADE_WHITEOUT 40 -typedef struct stFade -{ - int mode; - int dir; - int curamt; - int fadetimer; - int rate; -} stFade; -#define NO_FADE 0 -#define FADE_GO 1 -#define FADE_COMPLETE 2 - -#define FADE_IN 1 -#define FADE_OUT 2 -#define FADE_NORM 3 -#define FADE_FAST 1 -#define FADE_SLOW 30 - -#define NO_QUIT 0 -#define QUIT_PROGRAM 1 -#define QUIT_TO_TITLE 2 - -#define MAX_LEVELS 100 -#define SCROLLBUF_XSIZE 512 -#define SCROLLBUF_YSIZE 512 -#define SCROLLBUF_MEMSIZE ((SCROLLBUF_XSIZE)*(SCROLLBUF_YSIZE+300)) -#define SCROLLBUF_NUMTILESX (SCROLLBUF_XSIZE / 16) -#define SCROLLBUF_NUMTILESY (SCROLLBUF_YSIZE / 16) - -#define BLITBUF_XSIZE 320 -#define BLITBUF_YSIZE 200 -#define BLITBUF_MEMSIZE ((BLITBUF_XSIZE)*(BLITBUF_YSIZE+30)) - // for each entry in the animtileinuse array that is nonzero, that - // location on the display is an animated tile which is currently registered - // in animtiles[]. Used in map_draw_hstripe and map_draw_vstripe. - // When drawing a new stripe over one that previously contained an animated - // tile, this lets it know it needs to unregister the animated tile that - // used to be there. the nonzero value corresponds to the associated entry - // in animtiles[]. the x,y pixel position is the index in here * 16. - #define ATILEINUSE_SIZEX 33 - #define ATILEINUSE_SIZEY 33 - - #define MAX_PLAYERS 8 - - #define WORLD_MAP 80 - #define FINAL_MAP 16 - - #define LVLC_NOCOMMAND 0 - #define LVLC_CHANGE_LEVEL 1 - #define LVLC_END_SEQUENCE 2 - #define LVLC_GAME_OVER 3 - #define LVLC_TANTALUS_RAY 4 // switch on tantalus ray pressed - #define LVLC_START_LEVEL 5 - - -typedef struct stMap -{ - unsigned int xsize, ysize; // size of the map - unsigned char isworldmap; // if 1, this is the world map - unsigned int mapdata[256][256]; // the map data - // in-game, contains monsters and special object tags like for switches - // on world map contains level numbers and flags for things like teleporters - unsigned int objectlayer[256][256]; - char firsttime; // used when generating multiplayer positions on world map -} stMap; - - -// Tile information planes -#define ANIMATION 0 -#define BEHAVIOR 1 -#define BUP 2 -#define BRIGHT 3 -#define BDOWN 4 -#define BLEFT 5 - -typedef struct stBitmap -{ - int xsize; - int ysize; - unsigned char *bmptr; - char name[9]; -} stBitmap; - -typedef struct stSprite -{ - char xsize, ysize; - unsigned char imgdata[64][64]; - unsigned char maskdata[64][64]; - // bounding box for hit detection - unsigned int bboxX1, bboxY1; - unsigned int bboxX2, bboxY2; -} stSprite; - -typedef struct stInventory -{ - unsigned long score; - unsigned long extralifeat; - unsigned int charges; // ray gun ammo - signed int lives; - unsigned char HasPogo; - unsigned char HasCardYellow; - unsigned char HasCardRed; - unsigned char HasCardGreen; - unsigned char HasCardBlue; - // ep1 only - unsigned char HasJoystick; - unsigned char HasFuel; - unsigned char HasBattery; - unsigned char HasVacuum; -} stInventory; - -// for strings loaded from "strings.dat" -#define MAX_STRINGS 100 -#define MAX_ATTRIBUTES 16 -struct stString -{ - std::string name; // pointer to malloc'd area containing string name - std::string stringptr; // pointer to malloc'd area containing string - - int numAttributes; - unsigned char *attrnames[MAX_ATTRIBUTES+1]; - unsigned int attrvalues[MAX_ATTRIBUTES+1]; -}; - -/* Structs used for different enemies data, these are in a union */ -typedef struct stYorpData -{ - unsigned char state; - - unsigned char looktimes,lookposition; - unsigned char timer, dietimer; - unsigned char walkframe; - unsigned int dist_traveled; - signed int yorpdie_inertia_y; - - unsigned char movedir; -} stYorpData; -typedef struct stGargData -{ - unsigned char state; - - unsigned char looktimes,lookframe; - unsigned char timer, dietimer, keenonsameleveltimer; - unsigned char about_to_charge; - unsigned char walkframe; - unsigned int dist_traveled; - signed int gargdie_inertia_y; - - unsigned char movedir; - unsigned char detectedPlayer, detectedPlayerIndex; -} stGargData; -typedef struct stVortData -{ - unsigned char state; - - unsigned char timer,timer2; - unsigned int animtimer; - unsigned char palflashtimer, palflashamt; - unsigned char frame; - unsigned int dist_traveled; - signed int inertiay; - - char ep1style; // episode 1 style four-shots-to-kill - - unsigned char movedir; - // these hold the animation frames indexes since they're - // different for each episode - int WalkLeftFrame; - int WalkRightFrame; - int LookFrame; - int JumpRightFrame; - int JumpLeftFrame; - int DyingFrame; - int DeadFrame; -} stVortData; -typedef struct stBearData -{ - unsigned char state; - - unsigned char timer,timer2; - unsigned int animtimer; - unsigned char frame; - signed int inertiay; - unsigned char movedir; - unsigned int timesincefire; - unsigned int running; - - int dist_traveled; -} stBearData; -typedef struct stButlerData -{ - unsigned char state; - unsigned char timer,animtimer; - unsigned char frame; - unsigned int dist_traveled; - - unsigned char movedir; -} stButlerData; -typedef struct stTankData -{ - unsigned char state; - - unsigned char timer,animtimer; - unsigned char frame; - unsigned int dist_traveled; - - unsigned char movedir; - - int ponsameleveltime; - unsigned char alreadyfiredcauseonsamelevel; - unsigned char fireafterlook; - - unsigned char detectedPlayer; // 1 if player on same level - unsigned char detectedPlayerIndex; // index of player that was detected - - // for tank2 - unsigned int timetillnextshot; - unsigned int firetimes; - unsigned int timetillcanfire; - unsigned int timetillcanfirecauseonsamelevel; -} stTankData; -typedef struct stRayData -{ - char state; - char direction; - char zapzottimer; - - char dontHitEnable; - unsigned int dontHit; // index of an object type ray will not harm - - // for soundwave - int animframe, animtimer; - int offscreentime; - - // for earth chunks - int baseframe; -} stRayData; -typedef struct stDoorData -{ - char timer; - char distance_traveled; -} stDoorData; -typedef struct stIceChunk -{ - char movedir; - char state; - unsigned int originalX, originalY; - int timer; -} stIceChunk; -typedef struct stTeleportData -{ - char animtimer; - char animframe; - char numframechanges; - - char direction; - int whichplayer; - unsigned int destx; - signed int desty; - - int baseframe; - int idleframe; - - char NoExitingTeleporter; - char snap; - - char fadeamt; - char fadetimer; -} stTeleportData; -typedef struct stRopeData -{ - char state; - int droptimer; - int droptimes; - int stoneX, stoneY; - int vortboss; -} stRopeData; - -typedef struct stWalkerData -{ - unsigned char state; - - unsigned char animtimer, dietimer; - unsigned char walkframe; - signed int walkerdie_inertia_y; - int fallinctimer,fallspeed; - - unsigned char walkdir; - unsigned char kickedplayer[MAX_PLAYERS]; -} stWalkerData; - -typedef struct stPlatformData -{ - unsigned char state; - unsigned char animframe; - unsigned int animtimer; - unsigned int waittimer; - - unsigned char movedir; - unsigned char kickedplayer[MAX_PLAYERS]; -} stPlatformData; - -typedef struct stSEData -{ - unsigned int type; - - unsigned char state; - unsigned int timer; - unsigned int platx, platy; - unsigned int bgtile; - unsigned int dir; - - int counter,destroytiles; - unsigned int frame; - int mx,my; - int blowx,blowy; -} stSEData; - -typedef struct stBabyData -{ - char state; - char dir; - signed int inertia_x, inertia_y; - int jumpdectimer, xdectimer; - int jumpdecrate; - int dietimer; - - char walkframe; - int walktimer; -} stBabyData; - -typedef struct stFoobData -{ - char state; - char dir; - - int animframe, animtimer; - int OnSameLevelTime; - int OffOfSameLevelTime; - int spooktimer; - int SpookedByWho; -} stFoobData; - -typedef struct stNinjaData -{ - char state; - char dir; - - int animframe, animtimer; - unsigned int timetillkick; - - signed int XInertia, YInertia; - unsigned int XFrictionTimer, YFrictionTimer; - unsigned int XFrictionRate, YFrictionRate; - int KickMoveTimer; - int isdying; - int dietimer; -} stNinjaData; - -typedef struct stMotherData -{ - char state; - char dir; - char hittimes; - - int animframe, animtimer; - int timer; -} stMotherData; - -typedef struct stMeepData -{ - char state; - char dir; - - int animframe, animtimer; - int timer; -} stMeepData; - -typedef struct stBallJackData -{ - char dir; - int animframe, animtimer; - int speed; -} stBallJackData; - -#define NESSIETRAILLEN 5 -typedef struct stNessieData -{ - char state; - char leftrightdir, updowndir; - unsigned int baseframe; - - unsigned int tiletrailX[NESSIETRAILLEN+1]; - unsigned int tiletrailY[NESSIETRAILLEN+1]; - int tiletrailhead; - - char animframe, animtimer; - unsigned int destx, desty; - - unsigned int pausetimer; - unsigned int pausex, pausey; - - unsigned int mortimer_swim_amt; - unsigned int mounted[MAX_PLAYERS]; -} stNessieData; - -// and the object structure containing the union of the above structs -typedef struct stObject -{ - unsigned int type; // yorp, vorticon, etc. - unsigned int exists; - unsigned int onscreen; // 1=(scrx,scry) position is visible onscreen - unsigned int hasbeenonscreen; - unsigned int sprite; // which sprite should this object be drawn with - unsigned int x, y; // x,y location in map coords, CSFed - int scrx, scry; // x,y pixel position on screen - - // if type is OBJ_PLAYER, this contains the player number that this object - // is associated with - int AssociatedWithPlayer; - - // if zero, priority tiles will not be honored and object will always - // appear in front of the background - char honorPriority; - - char canbezapped; // if 0 ray will not stop on hitdetect - char zapped; // number of times got hit by keen's raygun - - char inhibitfall; // if 1 common_enemy_ai will not do falling - char cansupportplayer[MAX_PLAYERS]; - - unsigned int blockedl, blockedr, blockedu, blockedd; - signed int xinertia, yinertia; - unsigned char xinertiatimer, yinertiatimer; - - unsigned char touchPlayer; // 1=hit detection with player - unsigned char touchedBy; // which player was hit - // Y position on this object the hit was detected - // this is used for the yorps' bonk-on-the-head thing. - // objects are scanned bottom to top, and first pixel - // touching player is what goes in here. - unsigned char hity; - - unsigned int needinit; // 1=new object--requires initilization - unsigned char wasoffscreen; // set to 1 when object goes offscreen - // data for ai and such, used differently depending on - // what kind of object it is - union ai - { - // ep1 - stYorpData yorp; - stGargData garg; - stVortData vort; - stButlerData butler; - stTankData tank; - stRayData ray; - stDoorData door; - stIceChunk icechunk; - stTeleportData teleport; - stRopeData rope; - // ep2 - stWalkerData walker; - stPlatformData platform; - stBearData bear; - stSEData se; - stBabyData baby; - // ep3 - stFoobData foob; - stNinjaData ninja; - stMeepData meep; - stMotherData mother; - stBallJackData bj; - stNessieData nessie; - } ai; - unsigned char erasedata[64][64]; // backbuffer to erase this object -} stObject; - -// (map) stripe attribute structures, for animated tiles -// slot 0 is not used. data starts at slot 1. see description -// of AnimTileInUse in map structure to see why. -typedef struct stAnimTile -{ - int slotinuse; // if 0, this entry should not be drawn - int x; // x pixel position in scrollbuf[] where tile is - int y; // y pixel position in scrollbuf[] - int baseframe; // base frame, i.e. the first frame of animation - int offset; // offset from base frame -} stAnimTile; - -#define NUM_OBJ_TYPES 40 -// ** objects from KEEN1 -#define OBJ_YORP 1 -#define OBJ_GARG 2 -#define OBJ_VORT 3 -#define OBJ_BUTLER 4 -#define OBJ_TANK 5 -#define OBJ_RAY 6 // keen's raygun blast -#define OBJ_DOOR 7 // an opening door -#define OBJ_ICECHUNK 8 // ice chunk from ice cannon -#define OBJ_ICEBIT 9 // piece of shattered ice chunk -#define OBJ_PLAYER 10 -#define OBJ_TELEPORTER 11 // world map teleporter -#define OBJ_ROPE 12 - -// ** objects from KEEN2 (some of these are in ep3 as well) -#define OBJ_WALKER 13 -#define OBJ_TANKEP2 14 -#define OBJ_PLATFORM 15 -#define OBJ_BEAR 16 -#define OBJ_SECTOREFFECTOR 17 -#define OBJ_BABY 18 -#define OBJ_EXPLOSION 19 -#define OBJ_EARTHCHUNK 20 - -// ** objects from KEEN3 -#define OBJ_FOOB 21 -#define OBJ_NINJA 22 -#define OBJ_MEEP 23 -#define OBJ_SNDWAVE 24 -#define OBJ_MOTHER 25 -#define OBJ_FIREBALL 26 -#define OBJ_BALL 27 -#define OBJ_JACK 28 -#define OBJ_PLATVERT 29 -#define OBJ_NESSIE 30 - -#define OBJ_DEMOMSG 31 - -// default sprites...when an object is spawned it's sprite is set to this -// sprite. the object AI will immediately reset the sprite frame, so it -// wouldn't really matter what these are...except that it does because -// the width and height of the default sprite will determine exactly when -// the object because active the first time it scrolls onto the screen -// from the top or left. if the default sprite is wrong the object may -// suddenly appear on the screen instead of smoothly scrolling on. -#define OBJ_YORP_DEFSPRITE 50 -#define OBJ_GARG_DEFSPRITE 60 -#define OBJ_VORT_DEFSPRITE_EP1 78 -#define OBJ_VORT_DEFSPRITE_EP2 82 -#define OBJ_VORT_DEFSPRITE_EP3 71 -#define OBJ_BUTLER_DEFSPRITE 88 -#define OBJ_TANK_DEFSPRITE 98 -#define OBJ_RAY_DEFSPRITE_EP1 108 -#define OBJ_RAY_DEFSPRITE_EP2 122 -#define OBJ_RAY_DEFSPRITE_EP3 102 -#define OBJ_ICECHUNK_DEFSPRITE 112 -#define OBJ_ICEBIT_DEFSPRITE 113 -#define OBJ_TELEPORTER_DEFSPRITE 180 -#define OBJ_ROPE_DEFSPRITE 184 - -#define OBJ_PLATFORM_DEFSPRITE_EP2 126 -#define OBJ_PLATFORM_DEFSPRITE_EP3 107 -#define OBJ_WALKER_DEFSPRITE 102 -#define OBJ_TANKEP2_DEFSPRITE 112 -#define OBJ_BEAR_DEFSPRITE 88 - -#define OBJ_FOOB_DEFSPRITE 95 -#define OBJ_NINJA_DEFSPRITE 77 -#define OBJ_MOTHER_DEFSPRITE 87 -#define OBJ_BJ_DEFSPRITE 109 -#define OBJ_MEEP_DEFSPRITE 118 - -#define OBJ_BABY_DEFSPRITE_EP2 52 -#define OBJ_BABY_DEFSPRITE_EP3 51 - - -// some directions (mostly for OBJ_ICECHUNK and OBJ_ICEBIT) -#define DUPRIGHT 0 -#define DUPLEFT 1 -#define DUP 2 -#define DDOWN 3 -#define DDOWNRIGHT 4 -#define DDOWNLEFT 5 -#define DLEFT 6 -#define DRIGHT 7 - -// directions for OBJ_EARTHCHUNK -#define EC_UPLEFTLEFT 0 // 22 degrees CC of UP/LEFT -#define EC_UPUPLEFT 1 // 22 degrees C of UP/LEFT -#define EC_UP 2 // straight UP -#define EC_UPUPRIGHT 3 // 22 degrees CC of UP/RIGHT -#define EC_UPRIGHTRIGHT 4 // 22 degrees C of UP/RIGHT -#define EC_DOWNLEFTLEFT 5 // 22 degrees CC of DOWN/LEFT -#define EC_DOWNDOWNLEFT 6 // 22 degrees C of DOWN/LEFT -#define EC_DOWN 7 // straight DOWN -#define EC_DOWNDOWNRIGHT 8 // 22 degrees CC of DOWN/RIGHT -#define EC_DOWNRIGHTRIGHT 9 // 22 degrees C of DOWN/RIGHT - -#define EC_UPLEFT 10 -#define EC_UPRIGHT 11 -#define EC_DOWNLEFT 12 -#define EC_DOWNRIGHT 13 - -// scroll triggers -#define SCROLLTRIGGERRIGHT 194 -#define SCROLLTRIGGERLEFT 110 -#define SCROLLTRIGGERUP 80 -#define SCROLLTRIGGERDOWN 114 - -// this structure contains all the variables used by a player -typedef struct stPlayer -{ - // these coordinates are CSFed - unsigned long x; - unsigned int y; - - unsigned int w; - unsigned int h; - - char isPlaying; - int useObject; - - char godmode; - - // used on world map only - char hideplayer; - char mounted; - - short treshold; // This is used for analog devices like joysticks - signed int pinertia_y; - - unsigned long mapplayx; - signed int mapplayy; - - unsigned char playframe; - - unsigned char pfalling,plastfalling,pfallspeed,pfallspeed_increasetimer; - - unsigned char pwalking,playspeed; - unsigned char pslowingdown; - unsigned char pwalkframe,pwalkframea,pwalkanimtimer; - unsigned char pwalkincreasetimer, pfriction_timer_x, pfriction_timer_y; - signed int pinertia_x,pboost_x,playpushed_x; - int chargedjump; - unsigned char playpushed_decreasetimer; - bool widejump; - - unsigned char blockedl,blockedr,blockedu,blockedd; - unsigned int blockedby; - - unsigned char pjumping, pjumptime, pjumpupspeed_decreasetimer, pjumpdir; - unsigned char pjumpframe, pjumpanimtimer, pjumpupspeed; - unsigned char pjumpnormaltime, pjumpupdecreaserate, pjustjumped; - unsigned char pjustfell; - unsigned char pjumpfloattimer; - - unsigned char pdir,pshowdir,lastpdir; - - char pfiring,pfireframetimer; - char inhibitwalking, inhibitfall; - - int ctrltimer, alttimer; - char keyprocstate; - char wm_lastenterstate; - - char pdie, pdieframe, pdietimer; - int pdietillfly; - signed int pdie_xvect; - int psupportingtile, psupportingobject, lastsupportingobject; - char psliding; - char psemisliding; - bool ppogostick; - int pfrozentime,pfrozenframe,pfrozenanimtimer; - - unsigned char keytable[50]; - unsigned char lastkeytable[50]; - - - // New values - char playcontrol[PA_MAX_ACTIONS]; - char lastplaycontrol[PA_MAX_ACTIONS]; - - char x_friction; - char y_friction; - - // End new values - - unsigned char dpadcount, dpadlastcount; - - unsigned int ankhtime, ankhshieldobject; - - stInventory inventory; -} stPlayer; - -typedef struct stShipQueue -{ - int cmd; - int time; - int flag1; -} stShipQueue; - - -#define TILE_LITTLE_DONE 77 -#define TILE_BIG_DONE1 78 -#define TILE_BIG_DONE2 79 -#define TILE_BIG_DONE3 80 -#define TILE_BIG_DONE4 81 - -#define TILE_TELEPORTER_GREY_IDLE 99 -#define TILE_TELEPORTER_RED_INUSE 338 - -// special level codes on worldmap -#define LVLS_TELEPORTER_BONUS 46 // bonus teleporter in ep1 -#define LVLS_SHIP 20 - -#define TELEPORTING_OUT 0 -#define TELEPORTING_IN 1 - -#define TELEPORT_BONUS_DESTX ((((23085>>CSF>>4)+2)<<4<>CSF>>4)+2)<<4< -#include "include/declarations.h" -#include "keenext.h" -#include "sdl/CSettings.h" - -typedef struct stCloneKeenPlus -{ - stCommand Command[MAX_COMMANDS]; - SDL_Joystick *Joystick; - SDL_Event Event; - stResources Resources; - stGameData *GameData; - stDevice Device; - stControl Control; - stOption Option[NUM_OPTIONS]; - unsigned short numGames; - unsigned short shutdown; -}stCloneKeenPlus; - -// keen.c -void playgame_levelmanager(stCloneKeenPlus *pCKP); -char play_demo(int demonum, stCloneKeenPlus *pCKP, int s); +#include +#include +#include + +#ifdef TARGET_DOS + #include + #include + #include + #include + #include "dos\timer.h" +#endif + +#ifdef TARGET_WIN32 + #include +#endif + +#include "vorticon/sounds.h" +#include "funcdefs.h" +#include "fileio/CTileLoader.h" + +#include "include/playeraction.h" + +#define CSF 5 + +//#define OVSIZE 3000 + +// when crashflag is activated by setting it to QUIT_NONFATAL, +// the application will immediately shut down, however the +// "a Fatal Error Occurred" message box will not pop up and +// the sysbeep will not sound. +#define QUIT_NONFATAL 555 + +#define SAVEGAMEVERSION '4' +#define ATTRFILEVERSION 1 + +#define WM_MAP_NUM 80 + +#define MAX_SPRITES 300 +#define MAX_FONT 256 +#define MAX_BITMAPS 20 + +#define MAX_OBJECTS 100 +#define MAX_ANIMTILES 200 + +#define PAL_FADE_SHADES 20 +#define PAL_FADE_WHITEOUT 40 +typedef struct stFade +{ + int mode; + int dir; + int curamt; + int fadetimer; + int rate; +} stFade; +#define NO_FADE 0 +#define FADE_GO 1 +#define FADE_COMPLETE 2 + +#define FADE_IN 1 +#define FADE_OUT 2 +#define FADE_NORM 3 +#define FADE_FAST 1 +#define FADE_SLOW 30 + +#define NO_QUIT 0 +#define QUIT_PROGRAM 1 +#define QUIT_TO_TITLE 2 + +#define MAX_LEVELS 100 +#define SCROLLBUF_XSIZE 512 +#define SCROLLBUF_YSIZE 512 +#define SCROLLBUF_MEMSIZE ((SCROLLBUF_XSIZE)*(SCROLLBUF_YSIZE+300)) +#define SCROLLBUF_NUMTILESX (SCROLLBUF_XSIZE / 16) +#define SCROLLBUF_NUMTILESY (SCROLLBUF_YSIZE / 16) + +#define BLITBUF_XSIZE 320 +#define BLITBUF_YSIZE 200 +#define BLITBUF_MEMSIZE ((BLITBUF_XSIZE)*(BLITBUF_YSIZE+30)) + // for each entry in the animtileinuse array that is nonzero, that + // location on the display is an animated tile which is currently registered + // in animtiles[]. Used in map_draw_hstripe and map_draw_vstripe. + // When drawing a new stripe over one that previously contained an animated + // tile, this lets it know it needs to unregister the animated tile that + // used to be there. the nonzero value corresponds to the associated entry + // in animtiles[]. the x,y pixel position is the index in here * 16. + #define ATILEINUSE_SIZEX 33 + #define ATILEINUSE_SIZEY 33 + + #define MAX_PLAYERS 8 + + #define WORLD_MAP 80 + #define FINAL_MAP 16 + + #define LVLC_NOCOMMAND 0 + #define LVLC_CHANGE_LEVEL 1 + #define LVLC_END_SEQUENCE 2 + #define LVLC_GAME_OVER 3 + #define LVLC_TANTALUS_RAY 4 // switch on tantalus ray pressed + #define LVLC_START_LEVEL 5 + + +typedef struct stMap +{ + unsigned int xsize, ysize; // size of the map + unsigned char isworldmap; // if 1, this is the world map + unsigned int mapdata[256][256]; // the map data + // in-game, contains monsters and special object tags like for switches + // on world map contains level numbers and flags for things like teleporters + unsigned int objectlayer[256][256]; + char firsttime; // used when generating multiplayer positions on world map +} stMap; + + +// Tile information planes +#define ANIMATION 0 +#define BEHAVIOR 1 +#define BUP 2 +#define BRIGHT 3 +#define BDOWN 4 +#define BLEFT 5 + +typedef struct stBitmap +{ + int xsize; + int ysize; + unsigned char *bmptr; + char name[9]; +} stBitmap; + +typedef struct stSprite +{ + char xsize, ysize; + unsigned char imgdata[64][64]; + unsigned char maskdata[64][64]; + // bounding box for hit detection + unsigned int bboxX1, bboxY1; + unsigned int bboxX2, bboxY2; +} stSprite; + +typedef struct stInventory +{ + unsigned long score; + unsigned long extralifeat; + unsigned int charges; // ray gun ammo + signed int lives; + unsigned char HasPogo; + unsigned char HasCardYellow; + unsigned char HasCardRed; + unsigned char HasCardGreen; + unsigned char HasCardBlue; + // ep1 only + unsigned char HasJoystick; + unsigned char HasFuel; + unsigned char HasBattery; + unsigned char HasVacuum; +} stInventory; + +// for strings loaded from "strings.dat" +#define MAX_STRINGS 100 +#define MAX_ATTRIBUTES 16 +typedef struct stString +{ + unsigned char *name; // pointer to malloc'd area containing string name + unsigned char *stringptr; // pointer to malloc'd area containing string + + int numAttributes; + unsigned char *attrnames[MAX_ATTRIBUTES+1]; + unsigned int attrvalues[MAX_ATTRIBUTES+1]; +} stString; + +/* Structs used for different enemies data, these are in a union */ +typedef struct stYorpData +{ + unsigned char state; + + unsigned char looktimes,lookposition; + unsigned char timer, dietimer; + unsigned char walkframe; + unsigned int dist_traveled; + signed int yorpdie_inertia_y; + + unsigned char movedir; +} stYorpData; +typedef struct stGargData +{ + unsigned char state; + + unsigned char looktimes,lookframe; + unsigned char timer, dietimer, keenonsameleveltimer; + unsigned char about_to_charge; + unsigned char walkframe; + unsigned int dist_traveled; + signed int gargdie_inertia_y; + + unsigned char movedir; + unsigned char detectedPlayer, detectedPlayerIndex; +} stGargData; +typedef struct stVortData +{ + unsigned char state; + + unsigned char timer,timer2; + unsigned int animtimer; + unsigned char palflashtimer, palflashamt; + unsigned char frame; + unsigned int dist_traveled; + signed int inertiay; + + char ep1style; // episode 1 style four-shots-to-kill + + unsigned char movedir; + // these hold the animation frames indexes since they're + // different for each episode + int WalkLeftFrame; + int WalkRightFrame; + int LookFrame; + int JumpRightFrame; + int JumpLeftFrame; + int DyingFrame; + int DeadFrame; +} stVortData; +typedef struct stBearData +{ + unsigned char state; + + unsigned char timer,timer2; + unsigned int animtimer; + unsigned char frame; + signed int inertiay; + unsigned char movedir; + unsigned int timesincefire; + unsigned int running; + + int dist_traveled; +} stBearData; +typedef struct stButlerData +{ + unsigned char state; + unsigned char timer,animtimer; + unsigned char frame; + unsigned int dist_traveled; + + unsigned char movedir; +} stButlerData; +typedef struct stTankData +{ + unsigned char state; + + unsigned char timer,animtimer; + unsigned char frame; + unsigned int dist_traveled; + + unsigned char movedir; + + int ponsameleveltime; + unsigned char alreadyfiredcauseonsamelevel; + unsigned char fireafterlook; + + unsigned char detectedPlayer; // 1 if player on same level + unsigned char detectedPlayerIndex; // index of player that was detected + + // for tank2 + unsigned int timetillnextshot; + unsigned int firetimes; + unsigned int timetillcanfire; + unsigned int timetillcanfirecauseonsamelevel; +} stTankData; +typedef struct stRayData +{ + char state; + char direction; + char zapzottimer; + + char dontHitEnable; + unsigned int dontHit; // index of an object type ray will not harm + + // for soundwave + int animframe, animtimer; + int offscreentime; + + // for earth chunks + int baseframe; +} stRayData; +typedef struct stDoorData +{ + char timer; + char distance_traveled; +} stDoorData; +typedef struct stIceChunk +{ + char movedir; + char state; + unsigned int originalX, originalY; + int timer; +} stIceChunk; +typedef struct stTeleportData +{ + char animtimer; + char animframe; + char numframechanges; + + char direction; + int whichplayer; + unsigned int destx; + signed int desty; + + int baseframe; + int idleframe; + + char NoExitingTeleporter; + char snap; + + char fadeamt; + char fadetimer; +} stTeleportData; +typedef struct stRopeData +{ + char state; + int droptimer; + int droptimes; + int stoneX, stoneY; + int vortboss; +} stRopeData; + +typedef struct stWalkerData +{ + unsigned char state; + + unsigned char animtimer, dietimer; + unsigned char walkframe; + signed int walkerdie_inertia_y; + int fallinctimer,fallspeed; + + unsigned char walkdir; + unsigned char kickedplayer[MAX_PLAYERS]; +} stWalkerData; + +typedef struct stPlatformData +{ + unsigned char state; + unsigned char animframe; + unsigned int animtimer; + unsigned int waittimer; + + unsigned char movedir; + unsigned char kickedplayer[MAX_PLAYERS]; +} stPlatformData; + +typedef struct stSEData +{ + unsigned int type; + + unsigned char state; + unsigned int timer; + unsigned int platx, platy; + unsigned int bgtile; + unsigned int dir; + + int counter,destroytiles; + unsigned int frame; + int mx,my; + int blowx,blowy; +} stSEData; + +typedef struct stBabyData +{ + char state; + char dir; + signed int inertia_x, inertia_y; + int jumpdectimer, xdectimer; + int jumpdecrate; + int dietimer; + + char walkframe; + int walktimer; +} stBabyData; + +typedef struct stFoobData +{ + char state; + char dir; + + int animframe, animtimer; + int OnSameLevelTime; + int OffOfSameLevelTime; + int spooktimer; + int SpookedByWho; +} stFoobData; + +typedef struct stNinjaData +{ + char state; + char dir; + + int animframe, animtimer; + unsigned int timetillkick; + + signed int XInertia, YInertia; + unsigned int XFrictionTimer, YFrictionTimer; + unsigned int XFrictionRate, YFrictionRate; + int KickMoveTimer; + int isdying; + int dietimer; +} stNinjaData; + +typedef struct stMotherData +{ + char state; + char dir; + char hittimes; + + int animframe, animtimer; + int timer; +} stMotherData; + +typedef struct stMeepData +{ + char state; + char dir; + + int animframe, animtimer; + int timer; +} stMeepData; + +typedef struct stBallJackData +{ + char dir; + int animframe, animtimer; + int speed; +} stBallJackData; + +#define NESSIETRAILLEN 5 +typedef struct stNessieData +{ + char state; + char leftrightdir, updowndir; + unsigned int baseframe; + + unsigned int tiletrailX[NESSIETRAILLEN+1]; + unsigned int tiletrailY[NESSIETRAILLEN+1]; + int tiletrailhead; + + char animframe, animtimer; + unsigned int destx, desty; + + unsigned int pausetimer; + unsigned int pausex, pausey; + + unsigned int mortimer_swim_amt; + unsigned int mounted[MAX_PLAYERS]; +} stNessieData; + +// and the object structure containing the union of the above structs +typedef struct stObject +{ + unsigned int type; // yorp, vorticon, etc. + unsigned int exists; + unsigned int onscreen; // 1=(scrx,scry) position is visible onscreen + unsigned int hasbeenonscreen; + unsigned int sprite; // which sprite should this object be drawn with + unsigned int x, y; // x,y location in map coords, CSFed + int scrx, scry; // x,y pixel position on screen + + // if type is OBJ_PLAYER, this contains the player number that this object + // is associated with + int AssociatedWithPlayer; + + // if zero, priority tiles will not be honored and object will always + // appear in front of the background + char honorPriority; + + char canbezapped; // if 0 ray will not stop on hitdetect + char zapped; // number of times got hit by keen's raygun + + char inhibitfall; // if 1 common_enemy_ai will not do falling + char cansupportplayer[MAX_PLAYERS]; + + unsigned int blockedl, blockedr, blockedu, blockedd; + signed int xinertia, yinertia; + unsigned char xinertiatimer, yinertiatimer; + + unsigned char touchPlayer; // 1=hit detection with player + unsigned char touchedBy; // which player was hit + // Y position on this object the hit was detected + // this is used for the yorps' bonk-on-the-head thing. + // objects are scanned bottom to top, and first pixel + // touching player is what goes in here. + unsigned char hity; + + unsigned int needinit; // 1=new object--requires initilization + unsigned char wasoffscreen; // set to 1 when object goes offscreen + // data for ai and such, used differently depending on + // what kind of object it is + union ai + { + // ep1 + stYorpData yorp; + stGargData garg; + stVortData vort; + stButlerData butler; + stTankData tank; + stRayData ray; + stDoorData door; + stIceChunk icechunk; + stTeleportData teleport; + stRopeData rope; + // ep2 + stWalkerData walker; + stPlatformData platform; + stBearData bear; + stSEData se; + stBabyData baby; + // ep3 + stFoobData foob; + stNinjaData ninja; + stMeepData meep; + stMotherData mother; + stBallJackData bj; + stNessieData nessie; + } ai; + unsigned char erasedata[64][64]; // backbuffer to erase this object +} stObject; + +// (map) stripe attribute structures, for animated tiles +// slot 0 is not used. data starts at slot 1. see description +// of AnimTileInUse in map structure to see why. +typedef struct stAnimTile +{ + int slotinuse; // if 0, this entry should not be drawn + int x; // x pixel position in scrollbuf[] where tile is + int y; // y pixel position in scrollbuf[] + int baseframe; // base frame, i.e. the first frame of animation + int offset; // offset from base frame +} stAnimTile; + +#define NUM_OBJ_TYPES 40 +// ** objects from KEEN1 +#define OBJ_YORP 1 +#define OBJ_GARG 2 +#define OBJ_VORT 3 +#define OBJ_BUTLER 4 +#define OBJ_TANK 5 +#define OBJ_RAY 6 // keen's raygun blast +#define OBJ_DOOR 7 // an opening door +#define OBJ_ICECHUNK 8 // ice chunk from ice cannon +#define OBJ_ICEBIT 9 // piece of shattered ice chunk +#define OBJ_PLAYER 10 +#define OBJ_TELEPORTER 11 // world map teleporter +#define OBJ_ROPE 12 + +// ** objects from KEEN2 (some of these are in ep3 as well) +#define OBJ_WALKER 13 +#define OBJ_TANKEP2 14 +#define OBJ_PLATFORM 15 +#define OBJ_BEAR 16 +#define OBJ_SECTOREFFECTOR 17 +#define OBJ_BABY 18 +#define OBJ_EXPLOSION 19 +#define OBJ_EARTHCHUNK 20 + +// ** objects from KEEN3 +#define OBJ_FOOB 21 +#define OBJ_NINJA 22 +#define OBJ_MEEP 23 +#define OBJ_SNDWAVE 24 +#define OBJ_MOTHER 25 +#define OBJ_FIREBALL 26 +#define OBJ_BALL 27 +#define OBJ_JACK 28 +#define OBJ_PLATVERT 29 +#define OBJ_NESSIE 30 + +#define OBJ_DEMOMSG 31 + +// default sprites...when an object is spawned it's sprite is set to this +// sprite. the object AI will immediately reset the sprite frame, so it +// wouldn't really matter what these are...except that it does because +// the width and height of the default sprite will determine exactly when +// the object because active the first time it scrolls onto the screen +// from the top or left. if the default sprite is wrong the object may +// suddenly appear on the screen instead of smoothly scrolling on. +#define OBJ_YORP_DEFSPRITE 50 +#define OBJ_GARG_DEFSPRITE 60 +#define OBJ_VORT_DEFSPRITE_EP1 78 +#define OBJ_VORT_DEFSPRITE_EP2 82 +#define OBJ_VORT_DEFSPRITE_EP3 71 +#define OBJ_BUTLER_DEFSPRITE 88 +#define OBJ_TANK_DEFSPRITE 98 +#define OBJ_RAY_DEFSPRITE_EP1 108 +#define OBJ_RAY_DEFSPRITE_EP2 122 +#define OBJ_RAY_DEFSPRITE_EP3 102 +#define OBJ_ICECHUNK_DEFSPRITE 112 +#define OBJ_ICEBIT_DEFSPRITE 113 +#define OBJ_TELEPORTER_DEFSPRITE 180 +#define OBJ_ROPE_DEFSPRITE 184 + +#define OBJ_PLATFORM_DEFSPRITE_EP2 126 +#define OBJ_PLATFORM_DEFSPRITE_EP3 107 +#define OBJ_WALKER_DEFSPRITE 102 +#define OBJ_TANKEP2_DEFSPRITE 112 +#define OBJ_BEAR_DEFSPRITE 88 + +#define OBJ_FOOB_DEFSPRITE 95 +#define OBJ_NINJA_DEFSPRITE 77 +#define OBJ_MOTHER_DEFSPRITE 87 +#define OBJ_BJ_DEFSPRITE 109 +#define OBJ_MEEP_DEFSPRITE 118 + +#define OBJ_BABY_DEFSPRITE_EP2 52 +#define OBJ_BABY_DEFSPRITE_EP3 51 + + +// some directions (mostly for OBJ_ICECHUNK and OBJ_ICEBIT) +#define DUPRIGHT 0 +#define DUPLEFT 1 +#define DUP 2 +#define DDOWN 3 +#define DDOWNRIGHT 4 +#define DDOWNLEFT 5 +#define DLEFT 6 +#define DRIGHT 7 + +// directions for OBJ_EARTHCHUNK +#define EC_UPLEFTLEFT 0 // 22 degrees CC of UP/LEFT +#define EC_UPUPLEFT 1 // 22 degrees C of UP/LEFT +#define EC_UP 2 // straight UP +#define EC_UPUPRIGHT 3 // 22 degrees CC of UP/RIGHT +#define EC_UPRIGHTRIGHT 4 // 22 degrees C of UP/RIGHT +#define EC_DOWNLEFTLEFT 5 // 22 degrees CC of DOWN/LEFT +#define EC_DOWNDOWNLEFT 6 // 22 degrees C of DOWN/LEFT +#define EC_DOWN 7 // straight DOWN +#define EC_DOWNDOWNRIGHT 8 // 22 degrees CC of DOWN/RIGHT +#define EC_DOWNRIGHTRIGHT 9 // 22 degrees C of DOWN/RIGHT + +#define EC_UPLEFT 10 +#define EC_UPRIGHT 11 +#define EC_DOWNLEFT 12 +#define EC_DOWNRIGHT 13 + +// scroll triggers +#define SCROLLTRIGGERRIGHT 194 +#define SCROLLTRIGGERLEFT 110 +#define SCROLLTRIGGERUP 80 +#define SCROLLTRIGGERDOWN 114 + +// this structure contains all the variables used by a player +typedef struct stPlayer +{ + // these coordinates are CSFed + unsigned long x; + unsigned int y; + + unsigned int w; + unsigned int h; + + char isPlaying; + int useObject; + + char godmode; + + // used on world map only + char hideplayer; + char mounted; + + short treshold; // This is used for analog devices like joysticks + signed int pinertia_y; + + unsigned long mapplayx; + signed int mapplayy; + + unsigned char playframe; + + unsigned char pfalling,plastfalling,pfallspeed,pfallspeed_increasetimer; + + unsigned char pwalking,playspeed; + unsigned char pslowingdown; + unsigned char pwalkframe,pwalkframea,pwalkanimtimer; + unsigned char pwalkincreasetimer, pfriction_timer_x, pfriction_timer_y; + signed int pinertia_x,pboost_x,playpushed_x; + int chargedjump; + unsigned char playpushed_decreasetimer; + bool widejump; + + unsigned char blockedl,blockedr,blockedu,blockedd; + unsigned int blockedby; + + unsigned char pjumping, pjumptime, pjumpupspeed_decreasetimer, pjumpdir; + unsigned char pjumpframe, pjumpanimtimer, pjumpupspeed; + unsigned char pjumpnormaltime, pjumpupdecreaserate, pjustjumped; + unsigned char pjustfell; + unsigned char pjumpfloattimer; + + unsigned char pdir,pshowdir,lastpdir; + + char pfiring,pfireframetimer; + char inhibitwalking, inhibitfall; + + int ctrltimer, alttimer; + char keyprocstate; + char wm_lastenterstate; + + char pdie, pdieframe, pdietimer; + int pdietillfly; + signed int pdie_xvect; + int psupportingtile, psupportingobject, lastsupportingobject; + char psliding; + char psemisliding; + bool ppogostick; + int pfrozentime,pfrozenframe,pfrozenanimtimer; + + unsigned char keytable[50]; + unsigned char lastkeytable[50]; + + + // New values + char playcontrol[PA_MAX_ACTIONS]; + char lastplaycontrol[PA_MAX_ACTIONS]; + + char x_friction; + char y_friction; + + // End new values + + unsigned char dpadcount, dpadlastcount; + + unsigned int ankhtime, ankhshieldobject; + + stInventory inventory; +} stPlayer; + +typedef struct stShipQueue +{ + int cmd; + int time; + int flag1; +} stShipQueue; + + +#define TILE_LITTLE_DONE 77 +#define TILE_BIG_DONE1 78 +#define TILE_BIG_DONE2 79 +#define TILE_BIG_DONE3 80 +#define TILE_BIG_DONE4 81 + +#define TILE_TELEPORTER_GREY_IDLE 99 +#define TILE_TELEPORTER_RED_INUSE 338 + +// special level codes on worldmap +#define LVLS_TELEPORTER_BONUS 46 // bonus teleporter in ep1 +#define LVLS_SHIP 20 + +#define TELEPORTING_OUT 0 +#define TELEPORTING_IN 1 + +#define TELEPORT_BONUS_DESTX ((((23085>>CSF>>4)+2)<<4<>CSF>>4)+2)<<4< +#include "include/declarations.h" +#include "keenext.h" +#include "sdl/CSettings.h" + +typedef struct stCloneKeenPlus +{ + stCommand Command[MAX_COMMANDS]; + SDL_Joystick *Joystick; + SDL_Event Event; + stResources Resources; + stGameData *GameData; + stDevice Device; + stControl Control; + stOption Option[NUM_OPTIONS]; + unsigned short numGames; + unsigned short shutdown; +}stCloneKeenPlus; + +// keen.c +void playgame_levelmanager(stCloneKeenPlus *pCKP); +char play_demo(int demonum, stCloneKeenPlus *pCKP, int s); diff --git a/src/main.cpp b/src/main.cpp index aca842fed..28588de72 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,7 +24,7 @@ CloneKeen 2003-2005 Caitlin Shaw CloneKeenPlus 2008-2009 Gerstrong - Commander Genius 2009 Tulip, Pickle and DaVince + Commander Genius 2009 Tulip, Pickle, DaVince and Albert */ #include "keen.h" @@ -572,7 +572,6 @@ demoHeaderCorrupt: ; short readCommandLine(int argc, char *argv[], stCloneKeenPlus *pCKP) { int i; - static const int MAX_STRING_LENGTH = 256; char tempbuf[MAX_STRING_LENGTH]; diff --git a/src/menu.cpp b/src/menu.cpp index 5366c46ec..608f0586a 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -1,3 +1,1453 @@ +<<<<<<< .mine + /* MENU.C + The main menu, intro, and other such stuff. +*/ + +#include "keen.h" +#include "pressf10.h" +#include "include/menu.h" +#include "include/misc.h" +#include "sdl/CVideoDriver.h" +#include "include/game.h" +#include "include/gamedo.h" +#include "sdl/CTimer.h" +#include "sdl/sound/CSound.h" +#include "include/eseq_ep2.h" +#include "include/fileio.h" +#include "include/gm_pdowm.h" +#include "include/gamedo.h" +#include "include/main.h" +#include "CGraphics.h" +#include "sdl/video/colourtable.h" +#include "include/gui/dialog.h" +#include "sdl/CInput.h" +#include "vorticon/CDialog.h" +#include "CLogFile.h" +#include "sdl/CSettings.h" +#include +#include +#include +using namespace std; + +#define SELMOVE_SPD 3 + +short openDlgStruct(stDlgStruct *pDlgStruct, stCloneKeenPlus *pCKP); + +void showmapatpos(int level, int xoff, int yoff, int wm, stCloneKeenPlus *pCKP) +{ +int i; +char levelname[MAX_STRING_LENGTH]; +g_pLogFile->ftextOut("showmapatpos(%d, %d, %d, %d);
",level,xoff,yoff,wm); + pCKP->Control.levelcontrol.dark = 0; + g_pGraphics->initPalette(pCKP->Control.levelcontrol.dark); + + initgame(pCKP); // reset scroll + memset(levelname,0,MAX_STRING_LENGTH*sizeof(char)); + sprintf(levelname, "level%02d.ck%d", level, pCKP->Control.levelcontrol.episode); + + short numsel; + if(pCKP->Resources.GameSelected == 0 ) // First time startup. No game has been chosen + numsel = 0; + else + numsel = pCKP->Resources.GameSelected-1; + + loadmap(levelname, pCKP->GameData[numsel].DataDirectory, level, wm, pCKP); + + drawmap(); + for(i=0;isb_blit(); +} + +short loadResourcesforStartMenu(stCloneKeenPlus *pCKP, CGame *Game) +{ + string line; + + ifstream gamescfg("data/games.cfg"); + + if (gamescfg.is_open()) + { + while ( !gamescfg.eof() && pCKP->numGames < 20 ) + { + getline (gamescfg,line); + + if(strncmp(line.data(),"[",strlen("[")) == 0) + { + stGameData *NewGameData; + + pCKP->numGames++; + NewGameData = new stGameData[pCKP->numGames]; + memset(NewGameData,0,pCKP->numGames*sizeof(stGameData)); + memcpy(NewGameData,pCKP->GameData,(pCKP->numGames-1)*sizeof(stGameData)); + + delete[] pCKP->GameData; + + pCKP->GameData = NewGameData; + } + if(strncmp(line.data(),"Name=",strlen("Name=")) == 0) + { + line.copy(pCKP->GameData[pCKP->numGames-1].Name,line.length()-strlen("Name="),strlen("Name=")); + } + if(strncmp(line.data(),"Episode=",strlen("Episode=")) == 0) + { + sscanf(line.data(),"Episode=%hd", &(pCKP->GameData[pCKP->numGames-1].Episode)); + } + if(strncmp(line.data(),"Path=",strlen("Path=")) == 0) + { + unsigned short l = strlen("Path="); + line.copy(pCKP->GameData[pCKP->numGames-1].DataDirectory,line.length()-l,l); + } + } + gamescfg.close(); + } + else + { + g_pLogFile->ftextOut(RED,"loadResourcesforStartMenu(): \"data/games.cfg\" could not be read! Assure, that the directory can be accessed."); + return -1; + } + + if( pCKP->numGames >= 20 ) + g_pLogFile->ftextOut(PURPLE,"parseTheGames(): Warning! Number of games limit in \"data/games.cfg\" reached."); + + if(pCKP->numGames == 0) + { + g_pLogFile->ftextOut(PURPLE,"parseTheGames(): In the file \"data/games.cfg\" no games were found."); + return -1; + } + + unsigned short c=0; + for(c=0 ; c < pCKP->numGames ; c++) + { + checkConsistencyofGameData(&(pCKP->GameData[c])); + } + + // /* Load the graphics of the first game for displaying the menu */ /* Graphics of the first Episode are taken*/ + if(!pCKP->Control.skipstarting) + pCKP->Control.levelcontrol.episode = 1; + else + pCKP->Control.levelcontrol.episode = pCKP->GameData[pCKP->Resources.GameSelected-1].Episode; + + //if (latch_loadgraphics(pCKP->Control.levelcontrol.episode, pCKP->GameData[0].DataDirectory)) return abortCKP(pCKP); + //if (Game->getLatch()->loadGraphics(pCKP->Control.levelcontrol.episode, pCKP->GameData[0].DataDirectory)) return abortCKP(pCKP); + Game->loadResources(pCKP->Control.levelcontrol.episode, pCKP->GameData[0].DataDirectory); + + player[0].x = player[0].y = 0; + if(initgamefirsttime(pCKP, 0) != 0) + { + return 1; + } + initgame(pCKP); + + return 0; +} + + +#define MAINMENU_GOTO_DEMO_TIME 4000 + +extern char fade_black; +short loadStartMenu(stCloneKeenPlus *pCKP) +{ + CDialog *GamesMenu; + int i; + + fade.mode = FADE_GO; + fade.rate = FADE_NORM; + fade.dir = FADE_IN; + fade.curamt = 0; + fade.fadetimer = 0; + showmapatpos(90, (104 << 2)+256+256+80, 32-4, 0, pCKP); + + // Prepare the Games Menu + GamesMenu = new CDialog(); + + GamesMenu->setDimensions(2,2,36,15); + + // Show me the games you detected! + for( i=0 ; i < pCKP->numGames ; i++ ) + { + GamesMenu->addOptionText(pCKP->GameData[i].Name); + } + + GamesMenu->animateDialogBox(true); + + do + { + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + + // do fades + gamedo_fades(); + if(fade.mode == FADE_COMPLETE) + GamesMenu->setVisible(true); + + gamedo_AnimatedTiles(); + + // Check the Input + if(g_pInput->getPulsedCommand(IC_DOWN, 80)) + GamesMenu->setNextSelection(); + if(g_pInput->getPulsedCommand(IC_UP, 80)) + GamesMenu->setPrevSelection(); + + if(g_pInput->getPressedCommand(0, IC_STATUS)) + { + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + fade.rate = FADE_NORM; + fade.mode = FADE_GO; + pCKP->Resources.GameSelected = GamesMenu->getSelection()+1; + pCKP->Control.levelcontrol.episode = pCKP->GameData[pCKP->Resources.GameSelected-1].Episode; + break; + } + + // Render the Games-Menu + GamesMenu->renderDialog(); + + // blit the scrollbuffer to the display + gamedo_frameskipping_blitonly(); + } while(!g_pInput->getExitEvent()); + + delete GamesMenu; + + return 0; +} + +int mainmenu(stCloneKeenPlus *pCKP,int defaultopt) +{ + + CDialog *MainMenu; + int bmnum; + int x; + int selection; + + for(unsigned int cp=0 ; cpsetDimensions(11,8,18,12); + + // Load the Title Bitmap + bmnum = g_pGraphics->getBitmapNumberFromName("TITLE"); + + MainMenu->addOptionText("1-Player Game"); + MainMenu->addOptionText("2-Player Game"); + MainMenu->addOptionText("Load Game"); + MainMenu->addOptionText("Story"); + MainMenu->addOptionText("High Scores"); + MainMenu->addOptionText("Options"); + MainMenu->addOptionText("Demo"); + MainMenu->addOptionText("Change Game"); + MainMenu->addOptionText("About CG"); + MainMenu->addOptionText("Quit"); + + x = (320/2)-(bitmaps[bmnum].xsize/2); + + g_pGraphics->drawBitmap(x, 0, bmnum); + + MainMenu->animateDialogBox(true); + + do + { + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + + // do fades + gamedo_fades(); + if(fade.mode == FADE_COMPLETE) + MainMenu->setVisible(true); + + gamedo_AnimatedTiles(); + + // Check the Input + if(g_pInput->getPulsedCommand(IC_DOWN, 80)) + MainMenu->setNextSelection(); + if(g_pInput->getPulsedCommand(IC_UP, 80)) + MainMenu->setPrevSelection(); + + if(g_pInput->getPressedCommand(IC_STATUS)) + { + selection = MainMenu->getSelection(); + break; + } + + + // Render the Games-Menu + MainMenu->renderDialog(); + + // blit the scrollbuffer to the display + gamedo_frameskipping_blitonly(); + + if(g_pInput->getExitEvent()) + { + delete MainMenu; + return MAINMNU_QUIT; + } + + } while(1); + + if (selection==MAINMNU_LOADGAME) + { + int diff; + diff = getDifficulty(pCKP); + if(diff>2) + { + return BACK2MAINMENU; + } + + pCKP->Control.levelcontrol.hardmode = (diff == 1) ? true : false; + + loadslot = save_slot_box(0, pCKP); + if (loadslot) + { + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + fade.rate = FADE_NORM; + fade.mode = FADE_GO; + } + bmnum = g_pGraphics->getBitmapNumberFromName("TITLE"); + x = (320/2)-(bitmaps[bmnum].xsize/2); + g_pGraphics->drawBitmap(x, 0, bmnum); + } + else if (selection==MAINMNU_OPTIONS) + { + if (configmenu(pCKP)) + { // need to restart game + return RESTART_GAME; + } + } + else + { + if(selection==MAINMNU_1PLAYER || selection==MAINMNU_2PLAYER) + { + + int diff; + diff = getDifficulty(pCKP); + + if(diff>2) + { + delete MainMenu; + return BACK2MAINMENU; + } + pCKP->Control.levelcontrol.hardmode = (diff == 1) ? true : false; + } + + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + fade.rate = FADE_NORM; + fade.mode = FADE_GO; + } + + delete MainMenu; + + return selection; +} + +void initialiazeDlgStruct(stDlgStruct *pDlgStruct) +{ + pDlgStruct->OptionSwitch = (stOptionSwitch*) malloc(pDlgStruct->num_OptionSwitches*sizeof(stOptionSwitch)); + pDlgStruct->Separator = (stSeparator*) malloc(pDlgStruct->num_Separators*sizeof(stSeparator)); + pDlgStruct->StarterSwitch = (stStarterSwitch*) malloc(pDlgStruct->num_StarterSwitch*sizeof(stStarterSwitch)); + pDlgStruct->TextLine = (stTextLine*) malloc(pDlgStruct->num_TextLines*sizeof(stTextLine)); +} + +int getDifficulty(stCloneKeenPlus *pCKP) +{ + CDialog *DifficultyMenu; + int bmnum; + int selection; + int x; + + fade.mode = FADE_GO; + fade.rate = FADE_NORM; + fade.dir = FADE_IN; + fade.curamt = 0; + fade.fadetimer = 0; + + showmapatpos(90, MAINMENU_X, MENUS_Y, 0, pCKP); + + // Load the Title Bitmap + bmnum = g_pGraphics->getBitmapNumberFromName("TITLE"); + + x = (320/2)-(bitmaps[bmnum].xsize/2); + + g_pGraphics->drawBitmap(x, 0, bmnum); + + // Prepare the Games Menu + DifficultyMenu = new CDialog(); + + DifficultyMenu->setDimensions(15,4,14,6); + + DifficultyMenu->addOptionText("Normal"); + DifficultyMenu->addOptionText("Hard"); + DifficultyMenu->addSeparator(); + DifficultyMenu->addOptionText("Cancel"); + + DifficultyMenu->animateDialogBox(true); + + do + { + // do fades + gamedo_fades(); + if(fade.mode == FADE_COMPLETE) + DifficultyMenu->setVisible(true); + + gamedo_AnimatedTiles(); + + // Check the Input + if(g_pInput->getPulsedCommand(IC_DOWN, 80)) + DifficultyMenu->setNextSelection(); + if(g_pInput->getPulsedCommand(IC_UP, 80)) + DifficultyMenu->setPrevSelection(); + + if(g_pInput->getPressedCommand(IC_STATUS)) + { + selection = DifficultyMenu->getSelection(); + break; + } + // Render the Games-Menu + DifficultyMenu->renderDialog(); + + // blit the scrollbuffer to the display + gamedo_frameskipping_blitonly(); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + + } while(1); + + delete DifficultyMenu; + + return selection; +} + +int AudioDlg(stCloneKeenPlus *pCKP) +{ + CDialog *AudioMenu; + int bmnum; + int selection; + int x; + int ok=0; + + int rate=0; + short mode=0; + + showmapatpos(90, MAINMENU_X, MENUS_Y, 0, pCKP); + + // Load the Title Bitmap + bmnum = g_pGraphics->getBitmapNumberFromName("TITLE"); + x = (320/2)-(bitmaps[bmnum].xsize/2); + g_pGraphics->drawBitmap(x, 0, bmnum); + + // Prepare the Games Menu + AudioMenu = new CDialog(); + AudioMenu->setDimensions(4,4,32,7); + + char buf[256]; + rate = g_pSound->getAudioSpec().freq; + sprintf(buf,"Rate: %d kHz",rate); + AudioMenu->addOptionText(buf); + mode = g_pSound->getAudioSpec().channels - 1; + if(mode == 1) + AudioMenu->addOptionText("Mode: Stereo"); + else + AudioMenu->addOptionText("Mode: Mono"); + AudioMenu->addSeparator(); + AudioMenu->addOptionText("Save and go back"); + AudioMenu->addOptionText("Cancel"); + + AudioMenu->animateDialogBox(true); + + do + { + // do fades + gamedo_fades(); + if(fade.mode == FADE_COMPLETE) + AudioMenu->setVisible(true); + gamedo_AnimatedTiles(); + + // Check the Input + if(g_pInput->getPulsedCommand(IC_DOWN, 80)) + AudioMenu->setNextSelection(); + if(g_pInput->getPulsedCommand(IC_UP, 80)) + AudioMenu->setPrevSelection(); + + if(g_pInput->getPressedCommand(IC_STATUS)) + { + selection = AudioMenu->getSelection(); + + if(selection == 0) + { + switch(rate) + { + case 44100: rate = 48000; break; + case 22050: rate = 44100; break; + case 11000: rate = 22050; break; + default: rate = 11000; break; + } + + sprintf(buf,"Rate: %d kHz",rate); + AudioMenu->setOptionText(0,buf); + } + + if(selection == 1) + { + mode = !mode; + if(!mode) + AudioMenu->setOptionText(1,"Mode: Mono"); + else + AudioMenu->setOptionText(1,"Mode: Stereo"); + } + + if(selection == 3) + { + g_pSound->destroy(); + g_pSound->setSoundmode(rate, mode ? true : false); + CSettings *Settings; + Settings = new CSettings(); + Settings->saveDrvCfg(); + delete Settings; Settings = NULL; + g_pSound->init(); + ok = g_pSound->loadSoundData(pCKP->Control.levelcontrol.episode, + pCKP->GameData[pCKP->Resources.GameSelected-1].DataDirectory); + + break; + } + if(selection == 4) + break; + + } + // Render the Games-Menu + AudioMenu->renderDialog(); + + // blit the scrollbuffer to the display + gamedo_frameskipping_blitonly(); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + + } while(1); + + delete AudioMenu; + return ok; +} + +void OptionsDlg(stCloneKeenPlus *pCKP) +{ + CDialog *OptionsMenu; + int bmnum; + int selection; + int x,i; + + char buf[256]; + + showmapatpos(90, MAINMENU_X, MENUS_Y, 0, pCKP); + + // Load the Title Bitmap + bmnum = g_pGraphics->getBitmapNumberFromName("TITLE"); + x = (320/2)-(bitmaps[bmnum].xsize/2); + g_pGraphics->drawBitmap(x, 0, bmnum); + + // Prepare the Games Menu + OptionsMenu = new CDialog(); + OptionsMenu->setDimensions(3,3,34,12); + + for( i = 0 ; i < NUM_OPTIONS ; i++ ) + { + sprintf(buf,"%s: ",options[i].name); + if(options[i].value) + strcat(buf,"Enabled"); + else + strcat(buf,"Disabled"); + + OptionsMenu->addOptionText(buf); + } + + OptionsMenu->addSeparator(); + OptionsMenu->addOptionText("Return"); + + OptionsMenu->animateDialogBox(true); + + do + { + // do fades + gamedo_fades(); + if(fade.mode == FADE_COMPLETE) + OptionsMenu->setVisible(true); + gamedo_AnimatedTiles(); + + // Check the Input + if(g_pInput->getPulsedCommand(IC_DOWN, 80)) + OptionsMenu->setNextSelection(); + if(g_pInput->getPulsedCommand(IC_UP, 80)) + OptionsMenu->setPrevSelection(); + + if(g_pInput->getPressedCommand(IC_STATUS)) + { + selection = OptionsMenu->getSelection(); + + if(selection < NUM_OPTIONS) + { + sprintf(buf,"%s: ",options[selection].name); + + if(options[selection].value) + { + options[selection].value = 0; + strcat(buf,"Disabled"); + } + else + { + options[selection].value = 1; + strcat(buf,"Enabled"); + } + + OptionsMenu->setOptionText(selection,buf); + } + else + { + CSettings Settings; + Settings.saveGameCfg(pCKP->Option); + break; + } + } + // Render the Games-Menu + OptionsMenu->renderDialog(); + + // blit the scrollbuffer to the display + gamedo_frameskipping_blitonly(); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + + } while(1); + + delete OptionsMenu; +} + +short GraphicsDlg(stCloneKeenPlus *pCKP) +{ + CDialog *DisplayMenu; + int bmnum; + int selection; + int x; + unsigned int width; + unsigned int height; + unsigned short depth; + unsigned short zoom = 1; + unsigned short filter = 0; + unsigned short frameskip = 0; + bool opengl = false; + unsigned char gl_filter = 0; + bool fsmode; + char buf[256]; + short retval = 0; + unsigned char autoframeskip = 0; + bool aspect; + + showmapatpos(90, MAINMENU_X, MENUS_Y, 0, pCKP); + + // Load the Title Bitmap + bmnum = g_pGraphics->getBitmapNumberFromName("TITLE"); + x = (320/2)-(bitmaps[bmnum].xsize/2); + g_pGraphics->drawBitmap(x, 0, bmnum); + + // Prepare the Games Menu + DisplayMenu = new CDialog(); + DisplayMenu->setDimensions(4,3,32,13); + + width = g_pVideoDriver->getWidth(); + height = g_pVideoDriver->getHeight(); + depth = g_pVideoDriver->getDepth(); + sprintf(buf,"Resolution: %dx%dx%d",width,height,depth); + + zoom = g_pVideoDriver->getZoomValue(); + filter = g_pVideoDriver->getFiltermode(); + frameskip = g_pVideoDriver->getFrameskip(); + + DisplayMenu->addOptionText(buf); + if(g_pVideoDriver->getFullscreen()) + { + DisplayMenu->addOptionText("Fullscreen mode"); + fsmode = true; + } + else + { + DisplayMenu->addOptionText("Windowed mode"); + fsmode = false; + } + + opengl = g_pVideoDriver->isOpenGL(); + if(!opengl) + { + zoom = g_pVideoDriver->getZoomValue(); + + if(zoom == 1) + sprintf(buf,"No scale"); + else + sprintf(buf,"Scale: %d", zoom); + DisplayMenu->addOptionText(buf); + } + else + { + gl_filter = g_pVideoDriver->getOGLFilter(); + + if(gl_filter == 1) + sprintf(buf,"OGL Filter: Linear"); + else + sprintf(buf,"OGL Filter: Nearest"); + DisplayMenu->addOptionText(buf); + } + + filter = g_pVideoDriver->getFiltermode(); + if(filter == 0) + DisplayMenu->addOptionText("No Filter"); + else if(filter == 1) + DisplayMenu->addOptionText("Scale2x Filter"); + else if(filter == 2) + DisplayMenu->addOptionText("Scale3x Filter"); + else if(filter == 3) + DisplayMenu->addOptionText("Scale4x Filter"); + else + DisplayMenu->addOptionText("Unknown Filter"); + + sprintf(buf,"Frameskip: %d", frameskip); + DisplayMenu->addOptionText(buf); + + if(opengl) + DisplayMenu->addOptionText("OpenGL Acceleration"); + else + DisplayMenu->addOptionText("Software Rendering"); + + autoframeskip = g_pVideoDriver->getTargetFPS(); + + if(autoframeskip) + sprintf(buf,"Auto-Frameskip : %d fps",autoframeskip); + else + sprintf(buf,"Auto-Frameskip disabled"); + + DisplayMenu->addOptionText(buf); + + aspect = g_pVideoDriver->getAspectCorrection(); + + if(aspect) + DisplayMenu->addOptionText("OGL Aspect Ratio Enabled"); + else + DisplayMenu->addOptionText("OGL Aspect Ratio Disabled"); + + DisplayMenu->addSeparator(); + DisplayMenu->addOptionText("Save and return"); + DisplayMenu->addOptionText("Cancel"); + DisplayMenu->animateDialogBox(true); + + do + { + // do fades + gamedo_fades(); + if(fade.mode == FADE_COMPLETE) + DisplayMenu->setVisible(true); + gamedo_AnimatedTiles(); + + // Check the Input + if(g_pInput->getPulsedCommand(IC_DOWN, 80)) + DisplayMenu->setNextSelection(); + if(g_pInput->getPulsedCommand(IC_UP, 80)) + DisplayMenu->setPrevSelection(); + + if(g_pInput->getPressedCommand(IC_STATUS)) + { + selection = DisplayMenu->getSelection(); + + if(selection == 0) + { + // Now the part of the resolution list + st_resolution Resolution; + Resolution = g_pVideoDriver->setNextResolution(); + + sprintf(buf,"Resolution: %dx%dx%d", Resolution.width, Resolution.height, Resolution.depth); + DisplayMenu->setOptionText(selection,buf); + } + else if(selection == 1) + { + if(!fsmode) + DisplayMenu->setOptionText(1,"Fullscreen mode"); + else + DisplayMenu->setOptionText(1,"Windowed mode"); + fsmode = !fsmode; + } + else if(selection == 2) + { + if(opengl) + { + gl_filter = (gl_filter==1) ? 0 : 1; + + if(gl_filter == 1) + sprintf(buf,"OGL Filter: Linear"); + else + sprintf(buf,"OGL Filter: Nearest"); + + DisplayMenu->setOptionText(2,buf); + } + else + { + if(zoom >= 4) + zoom = 1; + else + zoom++; + + if(zoom == 1) + sprintf(buf,"No scale"); + else + sprintf(buf,"Scale: %d", zoom); + } + + DisplayMenu->setOptionText(2,buf); + } + + else if(selection == 3) + { + if(filter >= 3) + filter = 0; + else + filter++; + + if(filter == 0) + DisplayMenu->setOptionText(3,"No Filter"); + else if(filter == 1) + DisplayMenu->setOptionText(3,"Scale2x Filter"); + else if(filter == 2) + DisplayMenu->setOptionText(3,"Scale3x Filter"); + else if(filter == 3) + DisplayMenu->setOptionText(3,"Scale4x Filter"); + } + else if(selection == 4) + { + frameskip++; + + if(frameskip > 20) + frameskip = 0; + + sprintf(buf,"Frameskip: %d",frameskip); + DisplayMenu->setOptionText(4,buf); + } + else if(selection == 5) + { + opengl = opengl ? false : true; // switch the mode!! + + if(opengl) + DisplayMenu->setOptionText(5,"OpenGL Acceleration"); + else + DisplayMenu->setOptionText(5,"Software Rendering"); + } + else if(selection == 6) + { + if(autoframeskip < 70) + { + autoframeskip += 10; + sprintf(buf,"Auto-Frameskip : %d fps", autoframeskip); + } + else + { + autoframeskip = 0; + sprintf(buf,"Auto-Frameskip disabled"); + } + + DisplayMenu->setOptionText(6, buf); + } + else if(selection == 7) + { + aspect = !aspect; + + if(aspect) + DisplayMenu->setOptionText(7,"OGL Aspect Ratio Enabled"); + else + DisplayMenu->setOptionText(7,"OGL Aspect Ratio Disabled"); + + } + else if(selection == 9) + { + g_pVideoDriver->stop(); + + if(fsmode) + g_pVideoDriver->isFullscreen(true); + else + g_pVideoDriver->isFullscreen(false); + + g_pVideoDriver->enableOpenGL(opengl); + g_pVideoDriver->setOGLFilter(gl_filter); + g_pVideoDriver->setZoom(zoom); + g_pVideoDriver->setFilter(filter); + g_pVideoDriver->setFrameskip(frameskip); + g_pVideoDriver->setTargetFPS(autoframeskip); + g_pVideoDriver->setAspectCorrection(aspect); + + // initialize/activate all drivers + g_pLogFile->ftextOut("Restarting graphics driver... (Menu)
"); + if (g_pVideoDriver->start()) + retval = 1; + + CSettings *Settings; + Settings = new CSettings(); + + Settings->saveDrvCfg(); + delete Settings; Settings = NULL; + + showmapatpos(90, MAINMENU_X, MENUS_Y, 0, pCKP); + + fade.mode = FADE_GO; + fade.dir = FADE_IN; + fade.curamt = 0; + fade.rate = FADE_NORM; + fade.fadetimer = 0; + gamedo_fades(); + break; + } + else + break; + } + // Render the Games-Menu + DisplayMenu->renderDialog(); + + // blit the scrollbuffer to the display + gamedo_frameskipping_blitonly(); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + + } while(1); + + delete DisplayMenu; + + return retval; +} + + +// This function shows the Story of Commander Keen! +void showPage(char *text, stCloneKeenPlus *pCKP, int textsize) +{ + unsigned int i, j, k; + int exit=0; + int textpos; + bool enter; + unsigned int dlgX,dlgY,dlgW,dlgH; + unsigned int scroll, maxscroll; + char buffer[200][40]; + + showmapatpos(90, STORYBOARD_X, STORYBOARD_Y, 0, pCKP); + + fade.mode = FADE_GO; + fade.rate = FADE_NORM; + fade.dir = FADE_IN; + fade.curamt = 0; + fade.fadetimer = 0; + + scroll=0; + maxscroll=0; + + j=0; + k=0; + + AllPlayersInvisible(); + + dlgX = 0; + dlgY = 0; + dlgW = 39; + dlgH = 15; + + textpos=0; + memset(buffer,0,200*40*sizeof(char)); + // Prepare the buffer + + char sbuf[256]; + unsigned int totnumline=0; + + for(i=0;i<200;i++) + { + for(j=0;j dlgW-2)) + { + if(text[textpos] == ' ') + { + textpos++; + break; + } + } + + if(text[textpos]=='\n' ) + { + textpos++; + break; + } + + if(text[textpos]==31 ) // I don't know, what they do, + //but original version seems to ignore them! + { + text[textpos]=' '; + } + + + buffer[i][j]=text[textpos]; + textpos++; + if(textpos >= textsize) + break; + } + if(textpos >= textsize) + { + totnumline+=3; + break; + } + + totnumline++; + } + buffer[i][j] = ' '; // Last character is empty! + + char coverline[39]; + memset(coverline,2,38*sizeof(char)); // for the upper and lower edges + coverline[38]=0; + + do + { + gamedo_fades(); + + gamedo_AnimatedTiles(); + + sb_dialogbox(dlgX, dlgY, dlgW, dlgH); + + k=0; + + // Draw the text + for(i=0;i>3)][0]=='~') // Special Background Colour + { + char temp[39]; + memset(temp,' ',38*sizeof(char)); + temp[38]=0; + g_pGraphics->sb_color_font_draw((unsigned char*) temp, (dlgX+1)<<3, (((dlgY+i+1)<<3) -(scroll%8)),COLOUR_DARKRED,COLOUR_GREY); + g_pGraphics->sb_color_font_draw((unsigned char*) buffer[i+(scroll>>3)]+1, (dlgX+1)<<3, (((dlgY+i+1)<<3) -(scroll%8)),COLOUR_DARKRED,COLOUR_GREY); + } + else + { + g_pGraphics->sb_font_draw((unsigned char*) buffer[i+(scroll>>3)], (dlgX+1)<<3, (((dlgY+i+1)<<3) -(scroll%8))); + } + } + g_pGraphics->sb_font_draw((unsigned char*) coverline, (dlgX+1)<<3, dlgY); // Upper and lower edge Update + g_pGraphics->sb_font_draw((unsigned char*) coverline, (dlgX+1)<<3, (dlgY+dlgH-1)<<3); + + // If user presses up or down + if (g_pInput->getHoldedCommand(0,IC_DOWN) || g_pInput->getHoldedCommand(1,IC_DOWN)) + { + if(scroll < (totnumline-dlgH)<<3) + scroll++; + SDL_Delay(2); + } + else if (g_pInput->getHoldedCommand(0,IC_UP) || g_pInput->getHoldedCommand(1,IC_UP)) + { + if(scroll > 0) + scroll--; + SDL_Delay(2); + } + + enter = (g_pInput->getPressedCommand(0,IC_STATUS) || g_pInput->getPressedCommand(1,IC_STATUS)); + if (enter) + { + exit=1; + fade.dir = FADE_OUT; + fade.curamt = PAL_FADE_SHADES; + fade.fadetimer = 0; + fade.rate = FADE_NORM; + fade.mode = FADE_GO; + } + + gamedo_frameskipping(pCKP); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + + + if(exit==1 && fade.mode==FADE_COMPLETE) + break; + + if (g_pInput->getPressedCommand(KQUIT)) break; + } while(!crashflag); + return; +} + +char configmenu(stCloneKeenPlus *pCKP) +{ + CDialog *OptionsMenu; + int bmnum; + int selection; + int x; + + showmapatpos(90, MAINMENU_X, MENUS_Y, 0, pCKP); + + // Load the Title Bitmap + bmnum = g_pGraphics->getBitmapNumberFromName("TITLE"); + + x = (320/2)-(bitmaps[bmnum].xsize/2); + + g_pGraphics->drawBitmap(x, 0, bmnum); + + // Prepare the Games Menu + OptionsMenu = new CDialog(); + + OptionsMenu->setDimensions(15,4,14,8); + + OptionsMenu->addOptionText("Graphics"); + OptionsMenu->addOptionText("Audio"); + OptionsMenu->addOptionText("Game"); + OptionsMenu->addOptionText("Controls"); + OptionsMenu->addSeparator(); + OptionsMenu->addOptionText("Back"); + + OptionsMenu->animateDialogBox(true); + + do + { + // do fades + gamedo_fades(); + if(fade.mode == FADE_COMPLETE) + OptionsMenu->setVisible(true); + + gamedo_AnimatedTiles(); + + // Check the Input + if(g_pInput->getPulsedCommand(IC_DOWN, 80)) + OptionsMenu->setNextSelection(); + if(g_pInput->getPulsedCommand(IC_UP, 80)) + OptionsMenu->setPrevSelection(); + + if(g_pInput->getPressedCommand(IC_STATUS)) + { + selection = OptionsMenu->getSelection(); + break; + } + // Render the Games-Menu + OptionsMenu->renderDialog(); + + // blit the scrollbuffer to the display + gamedo_frameskipping_blitonly(); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + + } while(1); + + switch(selection) + { + case 0: + GraphicsDlg(pCKP); + break; + + case 1: + AudioDlg(pCKP); + break; + + case 2: + OptionsDlg(pCKP); + break; + + case 3: + controlsmenu(pCKP); + break; + + default: + break; + } + + delete OptionsMenu; + + return 0; +} + +char controlsmenu(stCloneKeenPlus *pCKP) +{ + CDialog *ControlsMenu; + int bmnum; + int selection; + int x; + char buf[256]; + char buf2[256]; + + showmapatpos(90, MAINMENU_X, MENUS_Y, 0, pCKP); + + // Load the Title Bitmap + bmnum = g_pGraphics->getBitmapNumberFromName("TITLE"); + + x = (320/2)-(bitmaps[bmnum].xsize/2); + + g_pGraphics->drawBitmap(x, 0, bmnum); + + // Prepare the Games Menu + ControlsMenu = new CDialog(); + + ControlsMenu->setDimensions(1,3,38,20); + + g_pInput->getEventName(IC_LEFT, 0, buf2); + sprintf(buf,"P1 Left: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_UP, 0, buf2); + sprintf(buf,"P1 Up: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_RIGHT, 0, buf2); + sprintf(buf,"P1 Right: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_DOWN, 0, buf2); + sprintf(buf,"P1 Down: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_JUMP, 0, buf2); + sprintf(buf,"P1 Jump: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_POGO, 0, buf2); + sprintf(buf,"P1 Pogo: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_FIRE, 0, buf2); + sprintf(buf,"P1 Fire: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_STATUS, 0, buf2); + sprintf(buf,"P1 Status: %s",buf2); + ControlsMenu->addOptionText(buf); + + g_pInput->getEventName(IC_LEFT, 1, buf2); + sprintf(buf,"P2 Left: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_UP, 1, buf2); + sprintf(buf,"P2 Up: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_RIGHT, 1, buf2); + sprintf(buf,"P2 Right: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_DOWN, 1, buf2); + sprintf(buf,"P2 Down: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_JUMP, 1, buf2); + sprintf(buf,"P2 Jump: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_POGO, 1, buf2); + sprintf(buf,"P2 Pogo: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_FIRE, 1, buf2); + sprintf(buf,"P2 Fire: %s",buf2); + ControlsMenu->addOptionText(buf); + g_pInput->getEventName(IC_STATUS, 1, buf2); + sprintf(buf,"P2 Status: %s",buf2); + ControlsMenu->addOptionText(buf); + ControlsMenu->addSeparator(); + ControlsMenu->addOptionText("Return"); + + ControlsMenu->animateDialogBox(true); + + do + { + // do fades + gamedo_fades(); + if(fade.mode == FADE_COMPLETE) + ControlsMenu->setVisible(true); + gamedo_AnimatedTiles(); + + // Check the Input + if(g_pInput->getPulsedCommand(IC_DOWN, 80)) + ControlsMenu->setNextSelection(); + if(g_pInput->getPulsedCommand(IC_UP, 80)) + ControlsMenu->setPrevSelection(); + + if(g_pInput->getPressedCommand(IC_STATUS)) + { + selection = ControlsMenu->getSelection(); + + if(selection < MAX_COMMANDS) + { + int item=0; + if(selection < 4) + item = selection + 4; + else + item = selection - 4; + + switch(selection) + { + case 0: sprintf(buf,"P1 Left: "); break; + case 1: sprintf(buf,"P1 Up: "); break; + case 2: sprintf(buf,"P1 Right: "); break; + case 3: sprintf(buf,"P1 Down: "); break; + case 4: sprintf(buf,"P1 Jump: "); break; + case 5: sprintf(buf,"P1 Pogo: "); break; + case 6: sprintf(buf,"P1 Fire: "); break; + case 7: sprintf(buf,"P1 Status: "); break; + } + + strcpy(buf2,buf); + strcat(buf2,"*Waiting for Input*"); + ControlsMenu->setOptionText(selection,buf2); + + while(!g_pInput->readNewEvent(0,item)) + { + ControlsMenu->renderDialog(); + gamedo_frameskipping_blitonly(); + } + + g_pInput->getEventName(item, 0, buf2); + strcat(buf,buf2); + ControlsMenu->setOptionText(selection,buf); + } + else if(selection >= MAX_COMMANDS && selection < MAX_COMMANDS*2) + { + int item=0; + if(selection < (4 + MAX_COMMANDS)) + item = selection + 4 - MAX_COMMANDS; + else + item = selection - 4 - MAX_COMMANDS; + + switch(selection) + { + case 0+ MAX_COMMANDS: sprintf(buf,"P2 Left: "); break; + case 1+ MAX_COMMANDS: sprintf(buf,"P2 Up: "); break; + case 2+ MAX_COMMANDS: sprintf(buf,"P2 Right: "); break; + case 3+ MAX_COMMANDS: sprintf(buf,"P2 Down: "); break; + case 4+ MAX_COMMANDS: sprintf(buf,"P2 Jump: "); break; + case 5+ MAX_COMMANDS: sprintf(buf,"P2 Pogo: "); break; + case 6+ MAX_COMMANDS: sprintf(buf,"P2 Fire: "); break; + case 7+ MAX_COMMANDS: sprintf(buf,"P2 Status: "); break; + } + + strcpy(buf2,buf); + strcat(buf2,"*Waiting for Input*"); + ControlsMenu->setOptionText(selection,buf2); + + while(!g_pInput->readNewEvent(1,item)) + { + ControlsMenu->renderDialog(); + gamedo_frameskipping_blitonly(); + } + + g_pInput->getEventName(item, 1, buf2); + strcat(buf,buf2); + ControlsMenu->setOptionText(selection,buf); + } + else + { + g_pInput->saveControlconfig(); + break; + } + } + // Render the Menu + ControlsMenu->renderDialog(); + + // blit the scrollbuffer to the display + gamedo_frameskipping_blitonly(); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + + } while(1); + + delete ControlsMenu; + return 0; +} + +void keensleft(stCloneKeenPlus *pCKP) +{ +int enter, lastenterstate; +unsigned int p; +int x,y,i; +int boxY, boxH; +int boxtimer; +int ep3; + +stLevelControl *p_levelcontrol; + + p_levelcontrol = &(pCKP->Control.levelcontrol); + + // on episode 3 we have to subtract one from the map tiles + // because the tiles start at 31, not 32 like on the other eps + ep3 = 0; + if (p_levelcontrol->episode==3) ep3 = 1; + + #define KEENSLEFT_TIME 400 + + for(i=0;idrawFont( (unsigned char*) getstring("LIVES_LEFT_BACKGROUND"),(KEENSLEFT_X+1)*8,(boxY+1)*8,0); + g_pGraphics->drawFont( (unsigned char*) getstring("LIVES_LEFT"),((KEENSLEFT_X+7)*8)+4,(boxY+1)*8,0); + y = ((boxY+2)*8)+4; + if (numplayers>1) y--; + for(p=0;pdrawSprite_direct(x, y, PMAPDOWNFRAME+playerbaseframes[p]-ep3); + x+=16; + } + y+=18; + } + g_pVideoDriver->update_screen(); + + g_pSound->playSound(SOUND_KEENSLEFT, PLAY_NOW); + + boxtimer = 0; + do + { + + gamedo_fades(); + + if (boxtimer > KEENSLEFT_TIME) + { + break; + } else boxtimer++; + + enter = g_pInput->getPressedCommand(IC_STATUS)||g_pInput->getPressedCommand(IC_FIRE)|| + g_pInput->getPressedCommand(IC_JUMP)||g_pInput->getPressedCommand(IC_POGO); + if (enter) + { + break; + } + if (g_pInput->getPressedCommand(KQUIT)) + { + return; + } + + lastenterstate = enter; + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!crashflag); + +} +======= /* MENU.C The main menu, intro, and other such stuff. */ @@ -1443,3 +2893,4 @@ stLevelControl *p_levelcontrol = &pCKP->Control.levelcontrol; } while(!crashflag); } +>>>>>>> .r93 diff --git a/src/misc.cpp b/src/misc.cpp index 60bbde906..7106f8872 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -1,1366 +1,1373 @@ -/* MISC.C - All KINDS of assorted crap :) Has most of the in-game dialog boxes - such as the status box etc. - - Also like I said there's all kinds of assorted crap in here. - That's why it's called "misc.c" (get it? :)) -*/ - -#include "keen.h" -#ifdef BUILD_SDL -#include -#include "sdl/joydrv.h" -#include "sdl/CInput.h" -#include "sdl/CTimer.h" -#include "sdl/CVideoDriver.h" -#include "sdl/sound/CSound.h" -#endif - -#include "include/misc.h" -#include "include/game.h" -#include "include/eseq_ep1.h" -#include "include/eseq_ep2.h" -#include "include/eseq_ep3.h" -#include "include/gamedo.h" -#include "CLogFile.h" -#include "CGraphics.h" -#include "StringUtils.h" - -void banner(void) -{ -char buf[80]; - - sprintf(buf, "%s *Unknown* build check banner()", REVISION); - #ifdef TARGET_WIN32 - sprintf(buf, "%s Windows build", REVISION); - #endif - #ifdef TARGET_LNX - sprintf(buf, "%s Linux build", REVISION); - #endif - printf("%s", buf); - printf(" (%d bit)", static_cast (sizeof(int*)*8)); - - printf("\nby The CloneKeenPlus Team 2009\n"); - printf("\n"); - printf("BY A FAN, FOR FANS. ALL \"COMMANDER KEEN\" GRAPHICS,\n"); - printf("SOUND, AND LEVEL FILES ARE THE PROPERTY OF ID SOFTWARE.\n"); - printf("\n"); -} - -void cleanup(stCloneKeenPlus *CKP) -{ - if(CKP->GameData){ delete[] CKP->GameData; CKP->GameData = NULL; } - - g_pLogFile->ftextOut(BLACK,true," Freed %d strings.
", freestrings()); - - JoyDrv_Stop(&(CKP->Joystick)); - g_pLogFile->textOut(BLACK,true," Joystick driver shut down.
"); - g_pSound->stopAllSounds(); - g_pSound->destroy(); - g_pLogFile->textOut(BLACK,true," Sound driver shut down.
"); - - #ifdef NETWORK_PLAY - if (is_server) - { - NetDrv_Server_Stop(); - g_pLogFile->ftextOut(" * Network (server) shut down.
"); - } - if (is_client) - { - NetDrv_Client_Stop(); - g_pLogFile->ftextOut(" * Network (client) shut down.
"); - } - #endif - - if (demofile) - { - fclose(demofile); - g_pLogFile->ftextOut(BLACK,true," Demo file closed.
"); - } - - g_pGraphics->stopGraphics(); - g_pLogFile->ftextOut(BLACK,true," Graphics driver shut down.
"); - - g_pGraphics->freemem(); - - g_pLogFile->ftextOut("
"); -} - -// draw an empty dialog box, for youseeinyourmind(), etc. -void dialogbox(int x1, int y1, int w, int h) -{ -int x,y,i,j; - - g_pGraphics->drawCharacter(x1*8, y1*8, 1); - g_pGraphics->drawCharacter((x1+w)*8, y1*8, 3); - for(x=(x1*8)+8,i=0;idrawCharacter(x, y1*8, 2); - x+=8; - } - y=(y1+1)*8; - for(j=0;jdrawCharacter(x, y, 4); - else if (i==w) g_pGraphics->drawCharacter(x, y, 5); - else g_pGraphics->drawCharacter(x, y, ' '); - x+=8; - } - y+=8; - } - for(x=(x1*8),i=0;i<=w;i++) - { - if (i==0) g_pGraphics->drawCharacter(x, y, 6); - else if (i==w) g_pGraphics->drawCharacter(x, y, 8); - else g_pGraphics->drawCharacter(x, y, 7); - x+=8; - } -} -// draw an empty dialog box, for youseeinyourmind(), etc. -void sb_dialogbox(int x1, int y1, int w, int h) -{ - int x,y,i,j; - - g_pGraphics->sb_drawCharacter(x1*8, y1*8, 1); - g_pGraphics->sb_drawCharacter((x1+w)*8, y1*8, 3); - for(x=(x1*8)+8,i=0;isb_drawCharacter(x, y1*8, 2); - x+=8; - } - y=(y1+1)*8; - for(j=0;jsb_drawCharacter(x, y, 4); - else if (i==w) g_pGraphics->sb_drawCharacter(x, y, 5); - else g_pGraphics->sb_drawCharacter(x, y, ' '); - x+=8; - } - y+=8; - } - for(x=(x1*8),i=0;i<=w;i++) - { - if (i==0) g_pGraphics->sb_drawCharacter(x, y, 6); - else if (i==w) g_pGraphics->sb_drawCharacter(x, y, 8); - else g_pGraphics->sb_drawCharacter(x, y, 7); - x+=8; - } -} - -#define YORPSTATUEHEADUSED 485 -void youseeinyourmind(int mpx, int mpy, stCloneKeenPlus *pCKP) -{ -int twirlframe, twirltimer; -char strname[80]; -int dlgX,dlgY,dlgW,dlgH,twirlX,twirlY; - -bool isgarg; - -int i; - - isgarg = false; - if(map.mapdata[mpx][mpy] >= 435 && map.mapdata[mpx][mpy] <= 438) - isgarg = true; - - if (!isgarg) - { - if(!map_isanimated(mpx, mpy)) - return; - } - else - { // it's a garg statue - if(!map_isanimated(mpx, mpy)) - return; - } - - for(i=0; i < 4 ; i++) - { - player[0].playcontrol[PA_JUMP+i] = 0; - } - - const int twirl_speed = 100; - - // get the name of the string we need to display - sprintf(strname, "EP1_YSIYM_LVL%d", pCKP->Control.levelcontrol.curlevel); - - dlgX = GetStringAttribute(strname, "LEFT"); - dlgY = GetStringAttribute(strname, "TOP"); - dlgW = GetStringAttribute(strname, "WIDTH"); - dlgH = GetStringAttribute(strname, "HEIGHT"); - twirlX = GetStringAttribute(strname, "TWIRLX"); - twirlY = GetStringAttribute(strname, "TWIRLY"); - - dialogbox(dlgX,dlgY,dlgW,dlgH); - g_pGraphics->drawFont(getstring(strname), (dlgX+1)<<3, (dlgY+1)<<3,0); - - twirlframe = 0; - twirltimer = twirl_speed+1; - // wait for enter - do - { - if (twirltimer>twirl_speed) - { - g_pGraphics->drawCharacter((dlgX+twirlX)<<3, (dlgY+twirlY)<<3, 9+twirlframe); - g_pVideoDriver->update_screen(); - twirlframe++; - if (twirlframe>5) twirlframe=0; - twirltimer=0; - } else twirltimer++; - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - g_pVideoDriver->update_screen(); - } while(!g_pInput->getPressedKey(KENTER) /*&& !immediate_keytable[KQUIT] && !getanyevent(pCKP)*/); - - // make the statue head stop glowing - if (!isgarg) - { - map_chgtile(mpx, mpy, YORPSTATUEHEADUSED); - map_deanimate(mpx, mpy); - } - else - { // it's a garg statue - - map_chgtile(mpx, mpy, 434); - map_deanimate(mpx, mpy); - } -} - -void VorticonElder(int mpx, int mpy, stCloneKeenPlus *pCKP) -{ - int twirlframe, twirltimer; - int dlgX,dlgY,dlgW,dlgH,twirlX,twirlY; - const char *strName; - const int twirl_speed = 100; - - for(int i=0; i < 4 ; i++) - { - player[0].playcontrol[PA_JUMP+i] = 0; - } - - g_pSound->pauseSound(); - - switch(pCKP->Control.levelcontrol.curlevel) - { - case 8: - strName = "EP2_VE_NOJUMPINDARK"; - break; - case 10: - strName = "EP2_VE_EVILBELTS"; - break; - - default: - crashflag = 1; - why_term_ptr = "VE box: Illegal level #."; - break; - } - - dlgX = GetStringAttribute(strName, "LEFT"); - dlgY = GetStringAttribute(strName, "TOP"); - dlgW = GetStringAttribute(strName, "WIDTH"); - dlgH = GetStringAttribute(strName, "HEIGHT"); - twirlX = GetStringAttribute(strName, "TWIRLX"); - twirlY = GetStringAttribute(strName, "TWIRLY"); - - dialogbox(dlgX, dlgY, dlgW, dlgH); - g_pGraphics->drawFont( getstring(strName), (dlgX+1)<<3, (dlgY+1)<<3,0); - - twirlframe = 0; - twirltimer = twirl_speed+1; - // wait for enter - do - { - if (twirltimer>twirl_speed) - { - g_pGraphics->drawCharacter((dlgX+twirlX)<<3, (dlgY+twirlY)<<3, 9+twirlframe); - g_pVideoDriver->update_screen(); - twirlframe++; - if (twirlframe>5) twirlframe=0; - twirltimer=0; - } else twirltimer++; - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - g_pVideoDriver->update_screen(); - } while(!g_pInput->getPressedKey(KENTER) ); - - // make the switch stop glowing - map_chgtile(mpx, mpy+1, 432); - - map_deanimate(mpx, mpy+1); - - g_pSound->resumeSounds(); -} - - -void inventory_draw_ep1(int p) -{ -int x,t,i,j; - std::string tempbuf; -int dlgX,dlgY,dlgW,dlgH; - - dlgX = GetStringAttribute("EP1_StatusBox", "LEFT"); - dlgY = GetStringAttribute("EP1_StatusBox", "TOP"); - dlgW = GetStringAttribute("EP1_StatusBox", "WIDTH"); - dlgH = GetStringAttribute("EP1_StatusBox", "HEIGHT"); - - dialogbox(dlgX,dlgY,dlgW,dlgH); - g_pGraphics->drawFont( getstring("EP1_StatusBox"), (dlgX+1)<<3, (dlgY+1)<<3, 0); - -// fill in what we have - // 321: joystick/battery/vacuum/fuel not gotten - // 414: raygun, 415, pogo - // 424: yellow/red/green/blue cards - // 448: ship parts, gotten - // raygun icon - g_pGraphics->drawTile_direct((dlgX+4)<<3, ((dlgY+8)<<3)+3, 414); - // pogo - if (player[p].inventory.HasPogo) g_pGraphics->drawTile_direct(((dlgX+12)<<3)+4, ((dlgY+9)<<3)+3, 415); - // cards - if (player[p].inventory.HasCardYellow) - { - g_pGraphics->drawTile_direct((dlgX+21)<<3, ((dlgY+8)<<3)+3, 424); - if(player[p].inventory.HasCardYellow > 1) - { - std::string buf = itoa(player[p].inventory.HasCardYellow); - g_pGraphics->drawFont(buf,(dlgX+20)<<3,((dlgY+8)<<3)+3,0); - } - } - if (player[p].inventory.HasCardRed) - { - g_pGraphics->drawTile_direct((dlgX+25)<<3, ((dlgY+8)<<3)+3, 425); - if(player[p].inventory.HasCardRed > 1) - { - std::string buf = itoa(player[p].inventory.HasCardRed); - g_pGraphics->drawFont(buf,(dlgX+24)<<3,((dlgY+8)<<3)+3,0); - } - } - if (player[p].inventory.HasCardGreen) - { - g_pGraphics->drawTile_direct((dlgX+21)<<3, ((dlgY+10)<<3)+4, 426); - - if (player[p].inventory.HasCardGreen > 1) - { - std::string buf = itoa(player[p].inventory.HasCardGreen); - g_pGraphics->drawFont(buf,(dlgX+20)<<3,((dlgY+10)<<3)+3,0); - } - } - if (player[p].inventory.HasCardBlue) - { - g_pGraphics->drawTile_direct((dlgX+25)<<3, ((dlgY+10)<<3)+4, 427); - if(player[p].inventory.HasCardBlue > 1) - { - std::string buf = itoa(player[p].inventory.HasCardBlue); - g_pGraphics->drawFont(buf,(dlgX+24)<<3,((dlgY+10)<<3)+3,0); - } - } - // ship parts - if (player[p].inventory.HasJoystick) t=448; else t=321; - g_pGraphics->drawTile_direct((dlgX+18)<<3, ((dlgY+4)<<3)+3, t); - if (player[p].inventory.HasBattery) t=449; else t=322; - g_pGraphics->drawTile_direct((dlgX+21)<<3, ((dlgY+4)<<3)+3, t); - if (player[p].inventory.HasVacuum) t=450; else t=323; - g_pGraphics->drawTile_direct((dlgX+24)<<3, ((dlgY+4)<<3)+3, t); - if (player[p].inventory.HasFuel) t=451; else t=324; - g_pGraphics->drawTile_direct((dlgX+27)<<3, ((dlgY+4)<<3)+3, t); - // ray gun charges - i = player[p].inventory.charges; - if (i>999) i=999; - tempbuf = itoa(i); - g_pGraphics->drawFont( tempbuf, (dlgX+4)<<3, (dlgY+12)<<3, 0); - - // score - i = player[p].inventory.score; - tempbuf = itoa(i); - g_pGraphics->drawFont( tempbuf, (dlgX+12-tempbuf.size())<<3, (dlgY+2)<<3, 0); - // extra life at - i = player[p].inventory.extralifeat; - tempbuf = itoa(i); - g_pGraphics->drawFont( tempbuf, (dlgX+28-tempbuf.size())<<3, (dlgY+2)<<3, 0); - // lives - i = player[p].inventory.lives; - x = ((dlgX+1)<<3)+4; - if (i>7) i=7; - for(j=0;jdrawSprite_direct(x, (dlgY+4)<<3, playerbaseframes[p]); - x += sprites[0].xsize; - } -} - -void inventory_draw_ep2(int p, stCloneKeenPlus *pCKP) -{ -int x,/*y,t,*/i,j; - std::string tempbuf; -int dlgX,dlgY,dlgW,dlgH; - - stLevelControl *p_levelcontrol; - - p_levelcontrol = &(pCKP->Control.levelcontrol); - - dlgX = GetStringAttribute("EP2_StatusBox", "LEFT"); - dlgY = GetStringAttribute("EP2_StatusBox", "TOP"); - dlgW = GetStringAttribute("EP2_StatusBox", "WIDTH"); - dlgH = GetStringAttribute("EP2_StatusBox", "HEIGHT"); - - dialogbox(dlgX,dlgY,dlgW,dlgH); - g_pGraphics->drawFont( getstring("EP2_StatusBox"), (dlgX+1)<<3, (dlgY+1)<<3, 0); - - // cards - if (player[p].inventory.HasCardYellow) - { - g_pGraphics->drawTile_direct(((dlgX+21)<<3)-4, ((dlgY+8)<<3)+3, 424); - if(player[p].inventory.HasCardYellow > 1) - { - std::string buf = itoa(player[p].inventory.HasCardYellow); - g_pGraphics->drawFont(buf,(dlgX+20)<<3,((dlgY+8)<<3)+3,0); - } - } - if (player[p].inventory.HasCardRed) - { - g_pGraphics->drawTile_direct(((dlgX+25)<<3)-4, ((dlgY+8)<<3)+3, 425); - if(player[p].inventory.HasCardRed > 1) - { - std::string buf = itoa(player[p].inventory.HasCardRed); - g_pGraphics->drawFont(buf,(dlgX+24)<<3,((dlgY+8)<<3)+3,0); - } - } - if (player[p].inventory.HasCardGreen) - { - g_pGraphics->drawTile_direct(((dlgX+21)<<3)-4, ((dlgY+10)<<3)+4, 426); - if(player[p].inventory.HasCardGreen > 1) - { - std::string buf = itoa(player[p].inventory.HasCardGreen); - g_pGraphics->drawFont(buf,(dlgX+20)<<3,((dlgY+10)<<3)+3,0); - } - } - if (player[p].inventory.HasCardBlue) - { - g_pGraphics->drawTile_direct(((dlgX+25)<<3)-4, ((dlgY+10)<<3)+4, 427); - if(player[p].inventory.HasCardBlue > 1) - { - std::string buf = itoa(player[p].inventory.HasCardBlue); - g_pGraphics->drawFont(buf,(dlgX+24)<<3,((dlgY+10)<<3)+3,0); - } - } - // cities saved - if (p_levelcontrol->levels_completed[4]) g_pGraphics->drawFont( getstring("EP2_LVL4_TargetName"), (dlgX+1)<<3, (dlgY+8)<<3, 0); - if (p_levelcontrol->levels_completed[6]) g_pGraphics->drawFont( getstring("EP2_LVL6_TargetName"), (dlgX+8)<<3, (dlgY+8)<<3, 0); - if (p_levelcontrol->levels_completed[7]) g_pGraphics->drawFont( getstring("EP2_LVL7_TargetName"), (dlgX+1)<<3, (dlgY+9)<<3, 0); - if (p_levelcontrol->levels_completed[13]) g_pGraphics->drawFont( getstring("EP2_LVL13_TargetName"), (dlgX+8)<<3, (dlgY+9)<<3, 0); - if (p_levelcontrol->levels_completed[11]) g_pGraphics->drawFont( getstring("EP2_LVL11_TargetName"), (dlgX+1)<<3, (dlgY+10)<<3, 0); - if (p_levelcontrol->levels_completed[9]) g_pGraphics->drawFont( getstring("EP2_LVL9_TargetName"), (dlgX+8)<<3, (dlgY+10)<<3, 0); - if (p_levelcontrol->levels_completed[15]) g_pGraphics->drawFont( getstring("EP2_LVL15_TargetName"), (dlgX+1)<<3, (dlgY+11)<<3, 0); - if (p_levelcontrol->levels_completed[16]) g_pGraphics->drawFont( getstring("EP2_LVL16_TargetName"), (dlgX+8)<<3, (dlgY+11)<<3, 0); - - // raygun icon - g_pGraphics->drawTile_direct((dlgX+20)<<3, ((dlgY+5)<<3)-5, 414); - - // ray gun charges text - i = player[p].inventory.charges; - if (i>999) i=999; - tempbuf = itoa(i); - g_pGraphics->drawFont( tempbuf, (dlgX+27-tempbuf.size())<<3, ((dlgY+5)<<3)-1, 0); - - // score - i = player[p].inventory.score; - tempbuf = itoa(i); - g_pGraphics->drawFont( tempbuf, (dlgX+12-tempbuf.size())<<3, (dlgY+2)<<3, 0); - // extra life at - i = player[p].inventory.extralifeat; - tempbuf = itoa(i); - g_pGraphics->drawFont( tempbuf, (dlgX+28-tempbuf.size())<<3, (dlgY+2)<<3, 0); - // lives - i = player[p].inventory.lives; - x = ((dlgX + 1)<<3)+4; - if (i>7) i=7; - for(j=0;jdrawSprite_direct(x, (dlgY+4)<<3, playerbaseframes[p]); - x += sprites[0].xsize; - } - -} - -void inventory_draw_ep3(int p) -{ -//int x,y,t,i,j; -int i,j,x; -int ankhtimepercent; - std::string tempbuf; -int dlgX,dlgY,dlgW,dlgH; - - dlgX = GetStringAttribute("EP3_StatusBox", "LEFT"); - dlgY = GetStringAttribute("EP3_StatusBox", "TOP"); - dlgW = GetStringAttribute("EP3_StatusBox", "WIDTH"); - dlgH = GetStringAttribute("EP3_StatusBox", "HEIGHT"); - - dialogbox(dlgX,dlgY,dlgW,dlgH); - g_pGraphics->drawFont( getstring("EP3_StatusBox"), (dlgX+1)<<3, (dlgY+1)<<3, 0); - - // calculate % ankh time left - ankhtimepercent = (int)((float)player[p].ankhtime / (PLAY_ANKH_TIME/100)); - // ankh time - g_pGraphics->drawTile_direct((dlgX+4)<<3, ((dlgY+8)<<3)+3, 214); - tempbuf = itoa(ankhtimepercent); - g_pGraphics->drawFont( tempbuf, (dlgX+8)<<3, ((dlgY+8)<<3)+7, 0); - - // raygun icon - g_pGraphics->drawTile_direct((dlgX+23)<<3, ((dlgY+5)<<3)-5, 216); - - // ray gun charges text - i = player[p].inventory.charges; - if (i>999) i=999; - tempbuf = itoa(i); - g_pGraphics->drawFont( tempbuf, (dlgX+26)<<3, ((dlgY+5)<<3)-1, 0); - - // cards - if (player[p].inventory.HasCardYellow) - { - g_pGraphics->drawTile_direct(((dlgX+14)<<3)+4, ((dlgY+8)<<3)+4, 217); - if(player[p].inventory.HasCardYellow > 1) - { - std::string buf = itoa(player[p].inventory.HasCardYellow); - g_pGraphics->drawFont(buf,(dlgX+13)<<3,((dlgY+8)<<3)+3,0); - } - } - if (player[p].inventory.HasCardRed) - { - g_pGraphics->drawTile_direct(((dlgX+18)<<3)+4, ((dlgY+8)<<3)+4, 218); - if(player[p].inventory.HasCardRed > 1) - { - std::string buf = itoa(player[p].inventory.HasCardRed); - g_pGraphics->drawFont(buf,(dlgX+17)<<3,((dlgY+8)<<3)+3,0); - } - } - if (player[p].inventory.HasCardGreen) - { - g_pGraphics->drawTile_direct(((dlgX+22)<<3)+4, ((dlgY+8)<<3)+4, 219); - if(player[p].inventory.HasCardGreen > 1) - { - std::string buf = itoa(player[p].inventory.HasCardGreen); - g_pGraphics->drawFont(buf,(dlgX+21)<<3,((dlgY+8)<<3)+3,0); - } - } - if (player[p].inventory.HasCardBlue) - { - g_pGraphics->drawTile_direct(((dlgX+26)<<3)+4, ((dlgY+8)<<3)+4, 220); - if(player[p].inventory.HasCardBlue > 1) - { - std::string buf = itoa(player[p].inventory.HasCardBlue); - g_pGraphics->drawFont(buf,(dlgX+25)<<3,((dlgY+8)<<3)+3,0); - } - } - - // score - i = player[p].inventory.score; - tempbuf = itoa(i); - g_pGraphics->drawFont( tempbuf, (dlgX+12-tempbuf.size())<<3, (dlgY+2)<<3, 0); - // extra life at - i = player[p].inventory.extralifeat; - tempbuf = itoa(i); - g_pGraphics->drawFont( tempbuf, (dlgX+28-tempbuf.size())<<3, (dlgY+2)<<3, 0); - // lives - i = player[p].inventory.lives; - x = ((dlgX+1)<<3)+4; - if (i>9) i=9; - for(j=0;jdrawSprite_direct(x, (dlgY+4)<<3, playerbaseframes[p]); - x += sprites[0].xsize; - } -} - -void showinventory(int p, stCloneKeenPlus *pCKP) -{ -//int x,y,t,i,j; -//char tempbuf[40]; - unsigned short i; - - stLevelControl *p_levelcontrol; - p_levelcontrol = &(pCKP->Control.levelcontrol); - - // draw the episode-specific stuff - if (p_levelcontrol->episode==1) - { - inventory_draw_ep1(p); - } - else if (p_levelcontrol->episode==2) - { - inventory_draw_ep2(p, pCKP); - } - else if (p_levelcontrol->episode==3) - { - inventory_draw_ep3(p); - } - - - g_pVideoDriver->update_screen(); - - // wait for any button pressed or any action triggered - bool close=false; - - while(!close) - { - g_pInput->pollEvents(); - - for(i=0 ; igetPressedCommand(i)) - close=true; - } - - for(i=0 ; igetPressedKey(i)) - close=true; - } - } -} - -/*void sshot(char *visiblefile, char *scrollfile) -{ -FILE *fp; -int x,y; - - fp = fopen(visiblefile, "wb"); - if (!fp) return;< - - for(y=0;y<200;y++) - for(x=0;x<320;x++) - fputc(getpixel(x,y), fp); - - fclose(fp); - - fp = fopen(scrollfile, "wb"); - if (!fp) return; - - for(y=0;y<512;y++) - for(x=0;x<512;x++) - fputc(sb_getpixel(x,y), fp); - - fclose(fp); -}*/ - -void YourShipNeedsTheseParts(stCloneKeenPlus *pCKP) -{ -int cp = 0; -int dlgX,dlgY,dlgW,dlgH; - - dlgX = GetStringAttribute("EP1_SHIP", "LEFT"); - dlgY = GetStringAttribute("EP1_SHIP", "TOP"); - dlgW = GetStringAttribute("EP1_SHIP", "WIDTH"); - dlgH = GetStringAttribute("EP1_SHIP", "HEIGHT"); - - dialogbox(dlgX,dlgY,dlgW,dlgH); - - g_pGraphics->drawFont( getstring("EP1_SHIP"), (dlgX+1)<<3, (dlgY+1)<<3,0); - - // draw needed parts - if (!player[cp].inventory.HasJoystick) - g_pGraphics->drawTile_direct((dlgX+9)<<3, (dlgY+3)<<3, 448); - - if (!player[cp].inventory.HasBattery) - g_pGraphics->drawTile_direct((dlgX+12)<<3, (dlgY+3)<<3, 449); - - if (!player[cp].inventory.HasVacuum) - g_pGraphics->drawTile_direct((dlgX+15)<<3, (dlgY+3)<<3, 450); - - if (!player[cp].inventory.HasFuel) - g_pGraphics->drawTile_direct((dlgX+18)<<3, (dlgY+3)<<3, 451); - - g_pVideoDriver->update_screen(); - - // wait for any key! - g_pInput->flushKeys(); - while(!g_pInput->getPressedAnyKey()) - { - g_pInput->pollEvents(); - - if(g_pInput->getPressedAnyCommand()) - break; - } -} - -void ShipEp3(stCloneKeenPlus *pCKP) -{ -char strname[80]; -int twirlframe, twirltimer; -int dlgX,dlgY,dlgW,dlgH,twirlX,twirlY; -const int twirlspeed = 100; - - // display one of four random strings - sprintf(strname, "EP3_SHIP%d", (rand()%4)+1); - - dlgX = GetStringAttribute(strname, "LEFT"); - dlgY = GetStringAttribute(strname, "TOP"); - dlgW = GetStringAttribute(strname, "WIDTH"); - dlgH = GetStringAttribute(strname, "HEIGHT"); - twirlX = GetStringAttribute(strname, "TWIRLX"); - twirlY = GetStringAttribute(strname, "TWIRLY"); - - dialogbox(dlgX,dlgY,dlgW,dlgH); - g_pGraphics->drawFont( getstring(strname), (dlgX+1)<<3, (dlgY+1)<<3,0); - - g_pVideoDriver->update_screen(); - - g_pInput->flushAll(); - - twirlframe = 0; - twirltimer = twirlspeed+1; - g_pInput->flushKeys(); - // wait for any command or key - do - { - if (twirltimer>twirlspeed) - { - g_pGraphics->drawCharacter((dlgX+twirlX)<<3, (dlgY+twirlY)<<3, twirlframe+9); - g_pVideoDriver->update_screen(); - twirlframe++; - if (twirlframe>5) twirlframe=0; - twirltimer=0; - } else twirltimer++; - if(g_pInput->getPressedAnyCommand()) break; - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(!g_pInput->getPressedAnyKey()); -} - -void game_save(char *fname, stCloneKeenPlus *pCKP) -{ - unsigned int i; - FILE *fp; - - fp = fopen(fname, "wb"); - - // save the header/version check - fputc('S', fp); - fputc(SAVEGAMEVERSION, fp); - - // save all necessary structures to the file - if (map.isworldmap) fputc('W', fp); else fputc('L', fp); - - sgrle_compress(fp, (unsigned char *)&numplayers, sizeof(numplayers)); - sgrle_compress(fp, (unsigned char *)&(pCKP->Control.levelcontrol), sizeof(pCKP->Control.levelcontrol)); - sgrle_compress(fp, (unsigned char *)&scroll_x, sizeof(scroll_x)); - sgrle_compress(fp, (unsigned char *)&scroll_y, sizeof(scroll_y)); - sgrle_compress(fp, (unsigned char *)&max_scroll_x, sizeof(max_scroll_x)); - sgrle_compress(fp, (unsigned char *)&max_scroll_y, sizeof(max_scroll_y)); - sgrle_compress(fp, (unsigned char *)&map, sizeof(map)); - for(i=0;iControl.levelcontrol); - - fp = fopen(fname, "rb"); - if (!fp) return 1; - - // do the header and version check - if (fgetc(fp) != 'S') { fclose(fp); return 1; } - if (fgetc(fp) != SAVEGAMEVERSION) { fclose(fp); return 1; } - fgetc(fp); // iswm flag--not needed here - - // load all structures from the file - sgrle_reset(); - sgrle_decompress(fp, (unsigned char *)&numplayers, sizeof(numplayers)); - sgrle_decompress(fp, (unsigned char *) p_levelcontrol , sizeof(*p_levelcontrol)); - sgrle_decompress(fp, (unsigned char *)&scrx, sizeof(scrx)); - sgrle_decompress(fp, (unsigned char *)&scry, sizeof(scry)); - sgrle_decompress(fp, (unsigned char *)&max_scroll_x, sizeof(max_scroll_x)); - sgrle_decompress(fp, (unsigned char *)&max_scroll_y, sizeof(max_scroll_y)); - sgrle_decompress(fp, (unsigned char *)&map, sizeof(map)); - - initgame(pCKP); // reset scroll - drawmap(); - for(i=0;iControl.levelcontrol); - -top: ; - if (issave) - { - dlgX = GetStringAttribute("WhichSlotSave", "LEFT"); - dlgY = GetStringAttribute("WhichSlotSave", "TOP"); - dlgW = GetStringAttribute("WhichSlotSave", "WIDTH"); - dlgH = GetStringAttribute("WhichSlotSave", "HEIGHT"); - } - else - { - dlgX = GetStringAttribute("WhichSlotLoad", "LEFT"); - dlgY = GetStringAttribute("WhichSlotLoad", "TOP"); - dlgW = GetStringAttribute("WhichSlotLoad", "WIDTH"); - dlgH = GetStringAttribute("WhichSlotLoad", "HEIGHT"); - map_redraw(); - bmnum = g_pGraphics->getBitmapNumberFromName("TITLE"); - x = (320/2)-(bitmaps[bmnum].xsize/2); - g_pGraphics->drawBitmap(x, 0, bmnum); - } - - saveslot = 0; - do - { - - gamedo_render_drawobjects(pCKP); - - sb_dialogbox(dlgX,dlgY,dlgW,dlgH); - if (issave) - { - g_pGraphics->sb_font_draw( getstring("WhichSlotSave"),(dlgX+1)<<3,(dlgY+1)<<3); - } - else - { - g_pGraphics->sb_font_draw( getstring("WhichSlotLoad"),(dlgX+1)<<3,(dlgY+1)<<3); - gamedo_AnimatedTiles(); - } - - for (int i=0 ; i<9 ; i++) - { - if (g_pInput->getPressedKey(KNUM1+i)) saveslot = 1+i; - } - - g_pVideoDriver->sb_blit(); - gamedo_render_eraseobjects(); - - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(!g_pInput->getPressedKey(KQUIT) && !saveslot); - - /* check if the selected save file exists */ - fname = "ep"; - fname += p_levelcontrol->episode+'0'; - fname += "save"; - fname += saveslot+'0'; - fname += ".dat"; - slotexists = 0; - fp = fopen(fname.c_str(), "rb"); - if (fp) - { - fclose(fp); - slotexists = 1; - } - - if ((issave && !slotexists) || (!issave && slotexists)) - { - map_redraw(); - return saveslot; - } - - if (issave) - { - dlgX = GetStringAttribute("SaveSlotOverwrite", "LEFT"); - dlgY = GetStringAttribute("SaveSlotOverwrite", "TOP"); - dlgW = GetStringAttribute("SaveSlotOverwrite", "WIDTH"); - dlgH = GetStringAttribute("SaveSlotOverwrite", "HEIGHT"); - } - else - { - dlgX = GetStringAttribute("LoadNoSuchSlot", "LEFT"); - dlgY = GetStringAttribute("LoadNoSuchSlot", "TOP"); - dlgW = GetStringAttribute("LoadNoSuchSlot", "WIDTH"); - dlgH = GetStringAttribute("LoadNoSuchSlot", "HEIGHT"); - } - - // either we're trying to save over an existing game, or we're - // loading a game that doesn't exist. - do - { - - gamedo_render_drawobjects(pCKP); - - sb_dialogbox(dlgX,dlgY,dlgW,dlgH); - if (issave) - { - g_pGraphics->sb_font_draw( getstring("SaveSlotOverwrite"),(dlgX+1)<<3,(dlgY+1)<<3); - if (g_pInput->getPressedKey(KN)) - { - map_redraw(); - goto top; - } - else if (g_pInput->getPressedKey(KY)) - { - map_redraw(); - return saveslot; - } - } - else - { - g_pGraphics->sb_font_draw( getstring("LoadNoSuchSlot"),(dlgX+1)<<3,(dlgY+1)<<3); - - if (g_pInput->getPressedAnyKey()) - { - map_redraw(); - goto top; - } - - gamedo_AnimatedTiles(); - } - - g_pVideoDriver->sb_blit(); - gamedo_render_eraseobjects(); - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(!g_pInput->getPressedKey(KQUIT)); - - map_redraw(); - return 0; -} - -void game_save_interface(stCloneKeenPlus *pCKP) -{ -int waittimer; -char fname[40]; -char saveslot; -int dlgX,dlgY,dlgW,dlgH; - - dlgX = GetStringAttribute("GameSaveSuccess", "LEFT"); - dlgY = GetStringAttribute("GameSaveSuccess", "TOP"); - dlgW = GetStringAttribute("GameSaveSuccess", "WIDTH"); - dlgH = GetStringAttribute("GameSaveSuccess", "HEIGHT"); - - saveslot = save_slot_box(1, pCKP); - if (!saveslot) return; // canceled - - /* save the game */ - sprintf(fname, "ep%csave%c.dat", pCKP->Control.levelcontrol.episode+'0', saveslot+'0'); - game_save(fname,pCKP); - - /* display the "your game has been saved" box */ - waittimer = 0; - do - { - waittimer++; - if (waittimer > 5000) break; - - gamedo_render_drawobjects(pCKP); - - sb_dialogbox(dlgX,dlgY,dlgW,dlgH); - g_pGraphics->sb_font_draw( getstring("GameSaveSuccess"),(dlgX+1)<<3,(dlgY+1)<<3); - - g_pVideoDriver->sb_blit(); - gamedo_render_eraseobjects(); - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(!g_pInput->getPressedAnyKey()); - - map_redraw(); -} - -int VerifyQuit(stCloneKeenPlus *pCKP) -{ -int dlgX,dlgY,dlgW,dlgH; - std::string text; - - if (fade.mode==FADE_GO) return NO_QUIT; - - text = getstring("VerifyQuit"); - dlgX = GetStringAttribute("VerifyQuit", "LEFT"); - dlgY = GetStringAttribute("VerifyQuit", "TOP"); - dlgW = GetStringAttribute("VerifyQuit", "WIDTH"); - dlgH = GetStringAttribute("VerifyQuit", "HEIGHT"); - - // either we're trying to save over an existing game, or we're - // loading a game that doesn't exist. - do - { - gamedo_render_drawobjects(pCKP); - gamedo_AnimatedTiles(); - - sb_dialogbox(dlgX, dlgY, dlgW, dlgH); - g_pGraphics->sb_font_draw( text, (dlgX+1)<<3, (dlgY+1)<<3); - if (g_pInput->getPressedKey(KQ)) - { - map_redraw(); - QuitState = QUIT_PROGRAM; - return 0; - } - else if (g_pInput->getPressedKey(KT)) - { - map_redraw(); - QuitState = QUIT_TO_TITLE; - return QuitState; - } - else if (g_pInput->getPressedKey(KQUIT)) - { - map_redraw(); - QuitState = NO_QUIT; - return QuitState; - } - - g_pVideoDriver->sb_blit(); - gamedo_render_eraseobjects(); - - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - } while(1); -} - -int endsequence(stCloneKeenPlus *pCKP) -{ - - if (pCKP->Control.levelcontrol.episode==1) - { - if (eseq1_ReturnsToShip(pCKP)) return 0; - if (eseq1_ShipFlys(pCKP)) return 0; - eseq1_BackAtHome(pCKP); - } - else if (pCKP->Control.levelcontrol.episode==2) - { - if (eseq2_HeadsForEarth(pCKP)) return 0; - if (eseq2_LimpsHome(pCKP)) return 0; - if (eseq2_SnowedOutside(pCKP)) return 0; - } - else if (pCKP->Control.levelcontrol.episode==3) - { - if (eseq3_AwardBigV(pCKP)) return 0; - } - - return 0; -} - -void AllPlayersInvisible(void) -{ -int i; - - for(i=0;iControl.levelcontrol); - - if (p_levelcontrol->episode==1) - { - /* episode 1: game is won when all parts are collected */ - - // count the number of parts the players have acquired - partcount = 0; - for(i=0;i= 4) - { - return 1; - } - else return 0; - } - else if (p_levelcontrol->episode==2) - { - /* episode 2: game is won when all cities are saved */ - if (!p_levelcontrol->levels_completed[4]) return 0; - if (!p_levelcontrol->levels_completed[6]) return 0; - if (!p_levelcontrol->levels_completed[7]) return 0; - if (!p_levelcontrol->levels_completed[13]) return 0; - if (!p_levelcontrol->levels_completed[11]) return 0; - if (!p_levelcontrol->levels_completed[9]) return 0; - if (!p_levelcontrol->levels_completed[15]) return 0; - if (!p_levelcontrol->levels_completed[16]) return 0; - return 1; - } - else if (p_levelcontrol->episode==3) - { - /* episode 3: game is won when mortimer is defeated */ - if (p_levelcontrol->levels_completed[16]) - { - return 1; - } - else - { - return 0; - } - } - -return 0; -} - -void usage(void) -{ - printf("Usage: keen [lvlnum] [-*player] [-nopk] [-ep*] [-dtm] [-nocheat] [-rec] -[eseq]
\n"); - printf("lvlnum specify a level number (such as 2) to go directly to that level
"); - printf("-*player select number of players (1-4); defaults to 1
"); - printf("-nopk do not allow players to kill each other in multiplayer games
"); - printf("-game* select game of data base; if not given, start menu is opened
"); - printf("-dtm go directly to the world map, bypassing intro and title screen
"); - printf("-mean increase game difficulty
"); - printf("-cheat enable function key cheat/debug codes
"); - printf("-rec record player actions to demo.dat for making a demo
"); - printf("-eseq for the impatient--cut directly to the ending sequence
"); -#ifdef BUILD_SDL - printf("-fs use fullscreen mode
"); - printf("-dbl zoom image 2x
"); - printf("-ogl hardware acceleration
"); - printf("-showfps show FPS in upper-right of screen
"); -#endif -#ifdef TARGET_WIN32 - printf("
-host & -join for the experimental network play mode. These DON'T work yet.\n"); -#endif - - printf("
"); - printf("Examples:
"); - printf(" keen 3 -ep2 play ep 2, level 3 in 1-player mode
"); - printf(" keen -ep3 -dtm -2player play ep3, skip title&intro, 2-player mode
"); - printf(" keen -ep3 play a normal game of ep3
"); -} - -void radar(void) -{ -unsigned int x,y,o; -unsigned int x1,y1,x2,y2; -unsigned int yoff; - // draw the map - for(y=0;ygetScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = map.mapdata[x][y]&15; - } - } - - // draw objects - for(o=0;o> CSF >> 4; - y = objects[o].y >> CSF >> 4; - - yoff = ((y+4+scrolly_buf)&511)<<9; - g_pGraphics->getScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = objects[o].type&15; - } - } - - // draw the area that is visible in the scrollbuffer - x1 = mapx; y1 = mapy; - x2 = x1+32; y2 = y1+32; - for(y=y1;ygetScrollbuffer()[yoff+((4+x1+scrollx_buf)&511)] = 10; - if (x2getScrollbuffer()[yoff+((4+x2+scrollx_buf)&511)] = 10; - } - } - for(x=x1;x<=x2;x++) - { - if (y1 < map.ysize && x < map.xsize) - { - yoff = ((y1+4+scrolly_buf)&511)<<9; - g_pGraphics->getScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = 10; - } - if (y2 < map.ysize && x < map.xsize) - { - yoff = ((y2+4+scrolly_buf)&511)<<9; - g_pGraphics->getScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = 10; - } - } - - // draw the area that is visible on the screen - // 320x200 = 20x12.5 tiles - x1 = scroll_x>>4; y1 = scroll_y>>4; - x2 = x1+20; y2 = y1+12; - for(y=y1;ygetScrollbuffer()[yoff+((4+x1+scrollx_buf)&511)] = 12; - if (x2getScrollbuffer()[yoff+((4+x2+scrollx_buf)&511)] = 12; - } - } - for(x=x1;x<=x2;x++) - { - if (x < map.xsize) - { - if (y1 < map.ysize) - { - yoff = ((y1+4+scrolly_buf)&511)<<9; - g_pGraphics->getScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = 12; - } - if (y2 < map.ysize) - { - yoff = ((y2+4+scrolly_buf)&511)<<9; - g_pGraphics->getScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = 12; - } - } - } -} - -void SetAllCanSupportPlayer(int o, int state) -{ - unsigned int i; - for(i=0;idrawFont(text[i], (dlgX+1)<<3, (dlgY+1+i)<<3,0); - } - - twirlframe = 0; - twirltimer = TWIRL_SPEED+1; - - g_pInput->flushAll(); - - // wait for enter - do - { - if (twirltimer>TWIRL_SPEED) - { - g_pGraphics->drawCharacter((dlgX+twirlX)<<3, (dlgY+twirlY)<<3, 9+twirlframe); - g_pVideoDriver->update_screen(); - twirlframe++; - if (twirlframe>5) twirlframe=0; - twirltimer=0; - } else twirltimer++; - g_pInput->pollEvents(); - g_pTimer->SpeedThrottle(); - g_pVideoDriver->update_screen(); - } while(!g_pInput->getPressedKey(KENTER)); -} +/* MISC.C + All KINDS of assorted crap :) Has most of the in-game dialog boxes + such as the status box etc. + + Also like I said there's all kinds of assorted crap in here. + That's why it's called "misc.c" (get it? :)) +*/ + +#include "keen.h" +#ifdef BUILD_SDL +#include +#include "sdl/joydrv.h" +#include "sdl/CInput.h" +#include "sdl/CTimer.h" +#include "sdl/CVideoDriver.h" +#include "sdl/sound/CSound.h" +#endif + +#include "include/misc.h" +#include "include/game.h" +#include "include/eseq_ep1.h" +#include "include/eseq_ep2.h" +#include "include/eseq_ep3.h" +#include "include/gamedo.h" +#include "CLogFile.h" +#include "CGraphics.h" + +void banner(void) +{ +char buf[80]; + + sprintf(buf, "%s *Unknown* build check banner()", REVISION); + #ifdef TARGET_WIN32 + sprintf(buf, "%s Windows build", REVISION); + #endif + #ifdef TARGET_LNX + sprintf(buf, "%s Linux build", REVISION); + #endif + printf("%s", buf); + printf(" (%d bit)", static_cast (sizeof(int*)*8)); + + printf("\nby The CloneKeenPlus Team 2009\n"); + printf("\n"); + printf("BY A FAN, FOR FANS. ALL \"COMMANDER KEEN\" GRAPHICS,\n"); + printf("SOUND, AND LEVEL FILES ARE THE PROPERTY OF ID SOFTWARE.\n"); + printf("\n"); +} + +void cleanup(stCloneKeenPlus *CKP) +{ + if(CKP->GameData){ delete[] CKP->GameData; CKP->GameData = NULL; } + + g_pLogFile->ftextOut(BLACK,true," Freed %d strings.
", freestrings()); + + JoyDrv_Stop(&(CKP->Joystick)); + g_pLogFile->textOut(BLACK,true," Joystick driver shut down.
"); + g_pSound->stopAllSounds(); + g_pSound->destroy(); + g_pLogFile->textOut(BLACK,true," Sound driver shut down.
"); + + #ifdef NETWORK_PLAY + if (is_server) + { + NetDrv_Server_Stop(); + g_pLogFile->ftextOut(" * Network (server) shut down.
"); + } + if (is_client) + { + NetDrv_Client_Stop(); + g_pLogFile->ftextOut(" * Network (client) shut down.
"); + } + #endif + + if (demofile) + { + fclose(demofile); + g_pLogFile->ftextOut(BLACK,true," Demo file closed.
"); + } + + g_pGraphics->stopGraphics(); + g_pLogFile->ftextOut(BLACK,true," Graphics driver shut down.
"); + + g_pGraphics->freemem(); + + g_pLogFile->ftextOut("
"); +} + +// draw an empty dialog box, for youseeinyourmind(), etc. +void dialogbox(int x1, int y1, int w, int h) +{ +int x,y,i,j; + + g_pGraphics->drawCharacter(x1*8, y1*8, 1); + g_pGraphics->drawCharacter((x1+w)*8, y1*8, 3); + for(x=(x1*8)+8,i=0;idrawCharacter(x, y1*8, 2); + x+=8; + } + y=(y1+1)*8; + for(j=0;jdrawCharacter(x, y, 4); + else if (i==w) g_pGraphics->drawCharacter(x, y, 5); + else g_pGraphics->drawCharacter(x, y, ' '); + x+=8; + } + y+=8; + } + for(x=(x1*8),i=0;i<=w;i++) + { + if (i==0) g_pGraphics->drawCharacter(x, y, 6); + else if (i==w) g_pGraphics->drawCharacter(x, y, 8); + else g_pGraphics->drawCharacter(x, y, 7); + x+=8; + } +} +// draw an empty dialog box, for youseeinyourmind(), etc. +void sb_dialogbox(int x1, int y1, int w, int h) +{ + int x,y,i,j; + + g_pGraphics->sb_drawCharacter(x1*8, y1*8, 1); + g_pGraphics->sb_drawCharacter((x1+w)*8, y1*8, 3); + for(x=(x1*8)+8,i=0;isb_drawCharacter(x, y1*8, 2); + x+=8; + } + y=(y1+1)*8; + for(j=0;jsb_drawCharacter(x, y, 4); + else if (i==w) g_pGraphics->sb_drawCharacter(x, y, 5); + else g_pGraphics->sb_drawCharacter(x, y, ' '); + x+=8; + } + y+=8; + } + for(x=(x1*8),i=0;i<=w;i++) + { + if (i==0) g_pGraphics->sb_drawCharacter(x, y, 6); + else if (i==w) g_pGraphics->sb_drawCharacter(x, y, 8); + else g_pGraphics->sb_drawCharacter(x, y, 7); + x+=8; + } +} + +#define YORPSTATUEHEADUSED 485 +void youseeinyourmind(int mpx, int mpy, stCloneKeenPlus *pCKP) +{ +int twirlframe, twirltimer; +char strname[80]; +int dlgX,dlgY,dlgW,dlgH,twirlX,twirlY; + +bool isgarg; + +int i; + + isgarg = false; + if(map.mapdata[mpx][mpy] >= 435 && map.mapdata[mpx][mpy] <= 438) + isgarg = true; + + if (!isgarg) + { + if(!map_isanimated(mpx, mpy)) + return; + } + else + { // it's a garg statue + if(!map_isanimated(mpx, mpy)) + return; + } + + for(i=0; i < 4 ; i++) + { + player[0].playcontrol[PA_JUMP+i] = 0; + } + + const int twirl_speed = 100; + + // get the name of the string we need to display + sprintf(strname, "EP1_YSIYM_LVL%d", pCKP->Control.levelcontrol.curlevel); + + dlgX = GetStringAttribute(strname, "LEFT"); + dlgY = GetStringAttribute(strname, "TOP"); + dlgW = GetStringAttribute(strname, "WIDTH"); + dlgH = GetStringAttribute(strname, "HEIGHT"); + twirlX = GetStringAttribute(strname, "TWIRLX"); + twirlY = GetStringAttribute(strname, "TWIRLY"); + + dialogbox(dlgX,dlgY,dlgW,dlgH); + g_pGraphics->drawFont((unsigned char*) getstring(strname), (dlgX+1)<<3, (dlgY+1)<<3,0); + + twirlframe = 0; + twirltimer = twirl_speed+1; + // wait for enter + do + { + if (twirltimer>twirl_speed) + { + g_pGraphics->drawCharacter((dlgX+twirlX)<<3, (dlgY+twirlY)<<3, 9+twirlframe); + g_pVideoDriver->update_screen(); + twirlframe++; + if (twirlframe>5) twirlframe=0; + twirltimer=0; + } else twirltimer++; + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + g_pVideoDriver->update_screen(); + } while(!g_pInput->getPressedKey(KENTER) /*&& !immediate_keytable[KQUIT] && !getanyevent(pCKP)*/); + + // make the statue head stop glowing + if (!isgarg) + { + map_chgtile(mpx, mpy, YORPSTATUEHEADUSED); + map_deanimate(mpx, mpy); + } + else + { // it's a garg statue + + map_chgtile(mpx, mpy, 434); + map_deanimate(mpx, mpy); + } +} + +void VorticonElder(int mpx, int mpy, stCloneKeenPlus *pCKP) +{ + int twirlframe, twirltimer; + int dlgX,dlgY,dlgW,dlgH,twirlX,twirlY; + const char *strName; + const int twirl_speed = 100; + + for(int i=0; i < 4 ; i++) + { + player[0].playcontrol[PA_JUMP+i] = 0; + } + + g_pSound->pauseSound(); + + switch(pCKP->Control.levelcontrol.curlevel) + { + case 8: + strName = "EP2_VE_NOJUMPINDARK"; + break; + case 10: + strName = "EP2_VE_EVILBELTS"; + break; + + default: + crashflag = 1; + why_term_ptr = "VE box: Illegal level #."; + break; + } + + dlgX = GetStringAttribute(strName, "LEFT"); + dlgY = GetStringAttribute(strName, "TOP"); + dlgW = GetStringAttribute(strName, "WIDTH"); + dlgH = GetStringAttribute(strName, "HEIGHT"); + twirlX = GetStringAttribute(strName, "TWIRLX"); + twirlY = GetStringAttribute(strName, "TWIRLY"); + + dialogbox(dlgX, dlgY, dlgW, dlgH); + g_pGraphics->drawFont( (unsigned char*) getstring(strName), (dlgX+1)<<3, (dlgY+1)<<3,0); + + twirlframe = 0; + twirltimer = twirl_speed+1; + // wait for enter + do + { + if (twirltimer>twirl_speed) + { + g_pGraphics->drawCharacter((dlgX+twirlX)<<3, (dlgY+twirlY)<<3, 9+twirlframe); + g_pVideoDriver->update_screen(); + twirlframe++; + if (twirlframe>5) twirlframe=0; + twirltimer=0; + } else twirltimer++; + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + g_pVideoDriver->update_screen(); + } while(!g_pInput->getPressedKey(KENTER) ); + + // make the switch stop glowing + map_chgtile(mpx, mpy+1, 432); + + map_deanimate(mpx, mpy+1); + + g_pSound->resumeSounds(); +} + + +void inventory_draw_ep1(int p) +{ +int x,t,i,j; +char tempbuf[40]; +int dlgX,dlgY,dlgW,dlgH; + + dlgX = GetStringAttribute("EP1_StatusBox", "LEFT"); + dlgY = GetStringAttribute("EP1_StatusBox", "TOP"); + dlgW = GetStringAttribute("EP1_StatusBox", "WIDTH"); + dlgH = GetStringAttribute("EP1_StatusBox", "HEIGHT"); + + dialogbox(dlgX,dlgY,dlgW,dlgH); + g_pGraphics->drawFont( (unsigned char*) getstring("EP1_StatusBox"), (dlgX+1)<<3, (dlgY+1)<<3, 0); + +// fill in what we have + // 321: joystick/battery/vacuum/fuel not gotten + // 414: raygun, 415, pogo + // 424: yellow/red/green/blue cards + // 448: ship parts, gotten + // raygun icon + g_pGraphics->drawTile_direct((dlgX+4)<<3, ((dlgY+8)<<3)+3, 414); + // pogo + if (player[p].inventory.HasPogo) g_pGraphics->drawTile_direct(((dlgX+12)<<3)+4, ((dlgY+9)<<3)+3, 415); + // cards + if (player[p].inventory.HasCardYellow) + { + g_pGraphics->drawTile_direct((dlgX+21)<<3, ((dlgY+8)<<3)+3, 424); + if(player[p].inventory.HasCardYellow > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardYellow); + g_pGraphics->drawFont((unsigned char*)buf,(dlgX+20)<<3,((dlgY+8)<<3)+3,0); + } + } + if (player[p].inventory.HasCardRed) + { + g_pGraphics->drawTile_direct((dlgX+25)<<3, ((dlgY+8)<<3)+3, 425); + if(player[p].inventory.HasCardRed > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardRed); + g_pGraphics->drawFont((unsigned char*) buf,(dlgX+24)<<3,((dlgY+8)<<3)+3,0); + } + } + if (player[p].inventory.HasCardGreen) + { + g_pGraphics->drawTile_direct((dlgX+21)<<3, ((dlgY+10)<<3)+4, 426); + + if (player[p].inventory.HasCardGreen > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardGreen); + g_pGraphics->drawFont((unsigned char*) buf,(dlgX+20)<<3,((dlgY+10)<<3)+3,0); + } + } + if (player[p].inventory.HasCardBlue) + { + g_pGraphics->drawTile_direct((dlgX+25)<<3, ((dlgY+10)<<3)+4, 427); + if(player[p].inventory.HasCardBlue > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardBlue); + g_pGraphics->drawFont((unsigned char*) buf,(dlgX+24)<<3,((dlgY+10)<<3)+3,0); + } + } + // ship parts + if (player[p].inventory.HasJoystick) t=448; else t=321; + g_pGraphics->drawTile_direct((dlgX+18)<<3, ((dlgY+4)<<3)+3, t); + if (player[p].inventory.HasBattery) t=449; else t=322; + g_pGraphics->drawTile_direct((dlgX+21)<<3, ((dlgY+4)<<3)+3, t); + if (player[p].inventory.HasVacuum) t=450; else t=323; + g_pGraphics->drawTile_direct((dlgX+24)<<3, ((dlgY+4)<<3)+3, t); + if (player[p].inventory.HasFuel) t=451; else t=324; + g_pGraphics->drawTile_direct((dlgX+27)<<3, ((dlgY+4)<<3)+3, t); + // ray gun charges + i = player[p].inventory.charges; + if (i>999) i=999; + sprintf(tempbuf, "%d", i); + g_pGraphics->drawFont( (unsigned char*) tempbuf, (dlgX+4)<<3, (dlgY+12)<<3, 0); + + // score + i = player[p].inventory.score; + sprintf(tempbuf, "%d", i); + g_pGraphics->drawFont( (unsigned char*) tempbuf, (dlgX+12-strlen(tempbuf))<<3, (dlgY+2)<<3, 0); + // extra life at + i = player[p].inventory.extralifeat; + sprintf(tempbuf, "%d", i); + g_pGraphics->drawFont( (unsigned char*) tempbuf, (dlgX+28-strlen(tempbuf))<<3, (dlgY+2)<<3, 0); + // lives + i = player[p].inventory.lives; + x = ((dlgX+1)<<3)+4; + if (i>7) i=7; + for(j=0;jdrawSprite_direct(x, (dlgY+4)<<3, playerbaseframes[p]); + x += sprites[0].xsize; + } +} + +void inventory_draw_ep2(int p, stCloneKeenPlus *pCKP) +{ +int x,/*y,t,*/i,j; +char tempbuf[40]; +int dlgX,dlgY,dlgW,dlgH; + + stLevelControl *p_levelcontrol; + + p_levelcontrol = &(pCKP->Control.levelcontrol); + + dlgX = GetStringAttribute("EP2_StatusBox", "LEFT"); + dlgY = GetStringAttribute("EP2_StatusBox", "TOP"); + dlgW = GetStringAttribute("EP2_StatusBox", "WIDTH"); + dlgH = GetStringAttribute("EP2_StatusBox", "HEIGHT"); + + dialogbox(dlgX,dlgY,dlgW,dlgH); + g_pGraphics->drawFont( (unsigned char*) getstring("EP2_StatusBox"), (dlgX+1)<<3, (dlgY+1)<<3, 0); + + // cards + if (player[p].inventory.HasCardYellow) + { + g_pGraphics->drawTile_direct(((dlgX+21)<<3)-4, ((dlgY+8)<<3)+3, 424); + if(player[p].inventory.HasCardYellow > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardYellow); + g_pGraphics->drawFont((unsigned char*)buf,(dlgX+20)<<3,((dlgY+8)<<3)+3,0); + } + } + if (player[p].inventory.HasCardRed) + { + g_pGraphics->drawTile_direct(((dlgX+25)<<3)-4, ((dlgY+8)<<3)+3, 425); + if(player[p].inventory.HasCardRed > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardRed); + g_pGraphics->drawFont((unsigned char*)buf,(dlgX+24)<<3,((dlgY+8)<<3)+3,0); + } + } + if (player[p].inventory.HasCardGreen) + { + g_pGraphics->drawTile_direct(((dlgX+21)<<3)-4, ((dlgY+10)<<3)+4, 426); + if(player[p].inventory.HasCardGreen > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardGreen); + g_pGraphics->drawFont((unsigned char*)buf,(dlgX+20)<<3,((dlgY+10)<<3)+3,0); + } + } + if (player[p].inventory.HasCardBlue) + { + g_pGraphics->drawTile_direct(((dlgX+25)<<3)-4, ((dlgY+10)<<3)+4, 427); + if(player[p].inventory.HasCardBlue > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardBlue); + g_pGraphics->drawFont((unsigned char*)buf,(dlgX+24)<<3,((dlgY+10)<<3)+3,0); + } + } + // cities saved + if (p_levelcontrol->levels_completed[4]) g_pGraphics->drawFont( (unsigned char*) getstring("EP2_LVL4_TargetName"), (dlgX+1)<<3, (dlgY+8)<<3, 0); + if (p_levelcontrol->levels_completed[6]) g_pGraphics->drawFont( (unsigned char*) getstring("EP2_LVL6_TargetName"), (dlgX+8)<<3, (dlgY+8)<<3, 0); + if (p_levelcontrol->levels_completed[7]) g_pGraphics->drawFont( (unsigned char*) getstring("EP2_LVL7_TargetName"), (dlgX+1)<<3, (dlgY+9)<<3, 0); + if (p_levelcontrol->levels_completed[13]) g_pGraphics->drawFont( (unsigned char*) getstring("EP2_LVL13_TargetName"), (dlgX+8)<<3, (dlgY+9)<<3, 0); + if (p_levelcontrol->levels_completed[11]) g_pGraphics->drawFont( (unsigned char*) getstring("EP2_LVL11_TargetName"), (dlgX+1)<<3, (dlgY+10)<<3, 0); + if (p_levelcontrol->levels_completed[9]) g_pGraphics->drawFont( (unsigned char*) getstring("EP2_LVL9_TargetName"), (dlgX+8)<<3, (dlgY+10)<<3, 0); + if (p_levelcontrol->levels_completed[15]) g_pGraphics->drawFont( (unsigned char*) getstring("EP2_LVL15_TargetName"), (dlgX+1)<<3, (dlgY+11)<<3, 0); + if (p_levelcontrol->levels_completed[16]) g_pGraphics->drawFont( (unsigned char*) getstring("EP2_LVL16_TargetName"), (dlgX+8)<<3, (dlgY+11)<<3, 0); + + // raygun icon + g_pGraphics->drawTile_direct((dlgX+20)<<3, ((dlgY+5)<<3)-5, 414); + + // ray gun charges text + i = player[p].inventory.charges; + if (i>999) i=999; + sprintf(tempbuf, "%d", i); + g_pGraphics->drawFont( (unsigned char*) tempbuf, (dlgX+27-strlen( (char*) tempbuf))<<3, ((dlgY+5)<<3)-1, 0); + + // score + i = player[p].inventory.score; + sprintf(tempbuf, "%d", i); + g_pGraphics->drawFont( (unsigned char*) tempbuf, (dlgX+12-strlen( (char*) tempbuf))<<3, (dlgY+2)<<3, 0); + // extra life at + i = player[p].inventory.extralifeat; + sprintf(tempbuf, "%d", i); + g_pGraphics->drawFont( (unsigned char*) tempbuf, (dlgX+28-strlen( (char*) tempbuf))<<3, (dlgY+2)<<3, 0); + // lives + i = player[p].inventory.lives; + x = ((dlgX + 1)<<3)+4; + if (i>7) i=7; + for(j=0;jdrawSprite_direct(x, (dlgY+4)<<3, playerbaseframes[p]); + x += sprites[0].xsize; + } + +} + +void inventory_draw_ep3(int p) +{ +//int x,y,t,i,j; +int i,j,x; +int ankhtimepercent; +char tempbuf[40]; +int dlgX,dlgY,dlgW,dlgH; + + dlgX = GetStringAttribute("EP3_StatusBox", "LEFT"); + dlgY = GetStringAttribute("EP3_StatusBox", "TOP"); + dlgW = GetStringAttribute("EP3_StatusBox", "WIDTH"); + dlgH = GetStringAttribute("EP3_StatusBox", "HEIGHT"); + + dialogbox(dlgX,dlgY,dlgW,dlgH); + g_pGraphics->drawFont( (unsigned char*) getstring("EP3_StatusBox"), (dlgX+1)<<3, (dlgY+1)<<3, 0); + + // calculate % ankh time left + ankhtimepercent = (int)((float)player[p].ankhtime / (PLAY_ANKH_TIME/100)); + // ankh time + g_pGraphics->drawTile_direct((dlgX+4)<<3, ((dlgY+8)<<3)+3, 214); + sprintf(tempbuf, "%d", ankhtimepercent); + g_pGraphics->drawFont( (unsigned char*) tempbuf, (dlgX+8)<<3, ((dlgY+8)<<3)+7, 0); + + // raygun icon + g_pGraphics->drawTile_direct((dlgX+23)<<3, ((dlgY+5)<<3)-5, 216); + + // ray gun charges text + i = player[p].inventory.charges; + if (i>999) i=999; + sprintf(tempbuf, "%d", i); + g_pGraphics->drawFont( (unsigned char*) tempbuf, (dlgX+26)<<3, ((dlgY+5)<<3)-1, 0); + + // cards + if (player[p].inventory.HasCardYellow) + { + g_pGraphics->drawTile_direct(((dlgX+14)<<3)+4, ((dlgY+8)<<3)+4, 217); + if(player[p].inventory.HasCardYellow > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardYellow); + g_pGraphics->drawFont((unsigned char*)buf,(dlgX+13)<<3,((dlgY+8)<<3)+3,0); + } + } + if (player[p].inventory.HasCardRed) + { + g_pGraphics->drawTile_direct(((dlgX+18)<<3)+4, ((dlgY+8)<<3)+4, 218); + if(player[p].inventory.HasCardRed > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardRed); + g_pGraphics->drawFont((unsigned char*)buf,(dlgX+17)<<3,((dlgY+8)<<3)+3,0); + } + } + if (player[p].inventory.HasCardGreen) + { + g_pGraphics->drawTile_direct(((dlgX+22)<<3)+4, ((dlgY+8)<<3)+4, 219); + if(player[p].inventory.HasCardGreen > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardGreen); + g_pGraphics->drawFont((unsigned char*)buf,(dlgX+21)<<3,((dlgY+8)<<3)+3,0); + } + } + if (player[p].inventory.HasCardBlue) + { + g_pGraphics->drawTile_direct(((dlgX+26)<<3)+4, ((dlgY+8)<<3)+4, 220); + if(player[p].inventory.HasCardBlue > 1) + { + char buf[10]; + sprintf(buf,"%d",player[p].inventory.HasCardBlue); + g_pGraphics->drawFont((unsigned char*)buf,(dlgX+25)<<3,((dlgY+8)<<3)+3,0); + } + } + + // score + i = player[p].inventory.score; + sprintf(tempbuf, "%d", i); + g_pGraphics->drawFont( (unsigned char*) tempbuf, (dlgX+12-strlen(tempbuf))<<3, (dlgY+2)<<3, 0); + // extra life at + i = player[p].inventory.extralifeat; + sprintf(tempbuf, "%d", i); + g_pGraphics->drawFont( (unsigned char*) tempbuf, (dlgX+28-strlen(tempbuf))<<3, (dlgY+2)<<3, 0); + // lives + i = player[p].inventory.lives; + x = ((dlgX+1)<<3)+4; + if (i>9) i=9; + for(j=0;jdrawSprite_direct(x, (dlgY+4)<<3, playerbaseframes[p]); + x += sprites[0].xsize; + } +} + +void showinventory(int p, stCloneKeenPlus *pCKP) +{ +//int x,y,t,i,j; +//char tempbuf[40]; + unsigned short i; + + stLevelControl *p_levelcontrol; + p_levelcontrol = &(pCKP->Control.levelcontrol); + + // draw the episode-specific stuff + if (p_levelcontrol->episode==1) + { + inventory_draw_ep1(p); + } + else if (p_levelcontrol->episode==2) + { + inventory_draw_ep2(p, pCKP); + } + else if (p_levelcontrol->episode==3) + { + inventory_draw_ep3(p); + } + + + g_pVideoDriver->update_screen(); + + // wait for any button pressed or any action triggered + bool close=false; + + while(!close) + { + g_pInput->pollEvents(); + + for(i=0 ; igetPressedCommand(i)) + close=true; + } + + for(i=0 ; igetPressedKey(i)) + close=true; + } + } +} + +/*void sshot(char *visiblefile, char *scrollfile) +{ +FILE *fp; +int x,y; + + fp = fopen(visiblefile, "wb"); + if (!fp) return;< + + for(y=0;y<200;y++) + for(x=0;x<320;x++) + fputc(getpixel(x,y), fp); + + fclose(fp); + + fp = fopen(scrollfile, "wb"); + if (!fp) return; + + for(y=0;y<512;y++) + for(x=0;x<512;x++) + fputc(sb_getpixel(x,y), fp); + + fclose(fp); +}*/ + +void YourShipNeedsTheseParts(stCloneKeenPlus *pCKP) +{ +int cp = 0; +int dlgX,dlgY,dlgW,dlgH; + + dlgX = GetStringAttribute("EP1_SHIP", "LEFT"); + dlgY = GetStringAttribute("EP1_SHIP", "TOP"); + dlgW = GetStringAttribute("EP1_SHIP", "WIDTH"); + dlgH = GetStringAttribute("EP1_SHIP", "HEIGHT"); + + dialogbox(dlgX,dlgY,dlgW,dlgH); + + g_pGraphics->drawFont( (unsigned char*) getstring("EP1_SHIP"), (dlgX+1)<<3, (dlgY+1)<<3,0); + + // draw needed parts + if (!player[cp].inventory.HasJoystick) + g_pGraphics->drawTile_direct((dlgX+9)<<3, (dlgY+3)<<3, 448); + + if (!player[cp].inventory.HasBattery) + g_pGraphics->drawTile_direct((dlgX+12)<<3, (dlgY+3)<<3, 449); + + if (!player[cp].inventory.HasVacuum) + g_pGraphics->drawTile_direct((dlgX+15)<<3, (dlgY+3)<<3, 450); + + if (!player[cp].inventory.HasFuel) + g_pGraphics->drawTile_direct((dlgX+18)<<3, (dlgY+3)<<3, 451); + + g_pVideoDriver->update_screen(); + + // wait for any key! + g_pInput->flushKeys(); + while(!g_pInput->getPressedAnyKey()) + { + g_pInput->pollEvents(); + + if(g_pInput->getPressedAnyCommand()) + break; + } +} + +void ShipEp3(stCloneKeenPlus *pCKP) +{ +char strname[80]; +int twirlframe, twirltimer; +int dlgX,dlgY,dlgW,dlgH,twirlX,twirlY; +const int twirlspeed = 100; + + // display one of four random strings + sprintf(strname, "EP3_SHIP%d", (rand()%4)+1); + + dlgX = GetStringAttribute(strname, "LEFT"); + dlgY = GetStringAttribute(strname, "TOP"); + dlgW = GetStringAttribute(strname, "WIDTH"); + dlgH = GetStringAttribute(strname, "HEIGHT"); + twirlX = GetStringAttribute(strname, "TWIRLX"); + twirlY = GetStringAttribute(strname, "TWIRLY"); + + dialogbox(dlgX,dlgY,dlgW,dlgH); + g_pGraphics->drawFont( (unsigned char*) getstring(strname), (dlgX+1)<<3, (dlgY+1)<<3,0); + + g_pVideoDriver->update_screen(); + + g_pInput->flushAll(); + + twirlframe = 0; + twirltimer = twirlspeed+1; + g_pInput->flushKeys(); + // wait for any command or key + do + { + if (twirltimer>twirlspeed) + { + g_pGraphics->drawCharacter((dlgX+twirlX)<<3, (dlgY+twirlY)<<3, twirlframe+9); + g_pVideoDriver->update_screen(); + twirlframe++; + if (twirlframe>5) twirlframe=0; + twirltimer=0; + } else twirltimer++; + if(g_pInput->getPressedAnyCommand()) break; + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!g_pInput->getPressedAnyKey()); +} + +void game_save(char *fname, stCloneKeenPlus *pCKP) +{ + unsigned int i; + FILE *fp; + + fp = fopen(fname, "wb"); + + // save the header/version check + fputc('S', fp); + fputc(SAVEGAMEVERSION, fp); + + // save all necessary structures to the file + if (map.isworldmap) fputc('W', fp); else fputc('L', fp); + + sgrle_compress(fp, (unsigned char *)&numplayers, sizeof(numplayers)); + sgrle_compress(fp, (unsigned char *)&(pCKP->Control.levelcontrol), sizeof(pCKP->Control.levelcontrol)); + sgrle_compress(fp, (unsigned char *)&scroll_x, sizeof(scroll_x)); + sgrle_compress(fp, (unsigned char *)&scroll_y, sizeof(scroll_y)); + sgrle_compress(fp, (unsigned char *)&max_scroll_x, sizeof(max_scroll_x)); + sgrle_compress(fp, (unsigned char *)&max_scroll_y, sizeof(max_scroll_y)); + sgrle_compress(fp, (unsigned char *)&map, sizeof(map)); + for(i=0;iControl.levelcontrol); + + fp = fopen(fname, "rb"); + if (!fp) return 1; + + // do the header and version check + if (fgetc(fp) != 'S') { fclose(fp); return 1; } + if (fgetc(fp) != SAVEGAMEVERSION) { fclose(fp); return 1; } + fgetc(fp); // iswm flag--not needed here + + // load all structures from the file + sgrle_reset(); + sgrle_decompress(fp, (unsigned char *)&numplayers, sizeof(numplayers)); + sgrle_decompress(fp, (unsigned char *) p_levelcontrol , sizeof(*p_levelcontrol)); + sgrle_decompress(fp, (unsigned char *)&scrx, sizeof(scrx)); + sgrle_decompress(fp, (unsigned char *)&scry, sizeof(scry)); + sgrle_decompress(fp, (unsigned char *)&max_scroll_x, sizeof(max_scroll_x)); + sgrle_decompress(fp, (unsigned char *)&max_scroll_y, sizeof(max_scroll_y)); + sgrle_decompress(fp, (unsigned char *)&map, sizeof(map)); + + initgame(pCKP); // reset scroll + drawmap(); + for(i=0;iControl.levelcontrol); + +top: ; + if (issave) + { + dlgX = GetStringAttribute("WhichSlotSave", "LEFT"); + dlgY = GetStringAttribute("WhichSlotSave", "TOP"); + dlgW = GetStringAttribute("WhichSlotSave", "WIDTH"); + dlgH = GetStringAttribute("WhichSlotSave", "HEIGHT"); + } + else + { + dlgX = GetStringAttribute("WhichSlotLoad", "LEFT"); + dlgY = GetStringAttribute("WhichSlotLoad", "TOP"); + dlgW = GetStringAttribute("WhichSlotLoad", "WIDTH"); + dlgH = GetStringAttribute("WhichSlotLoad", "HEIGHT"); + map_redraw(); + bmnum = g_pGraphics->getBitmapNumberFromName("TITLE"); + x = (320/2)-(bitmaps[bmnum].xsize/2); + g_pGraphics->drawBitmap(x, 0, bmnum); + } + + saveslot = 0; + do + { + + gamedo_render_drawobjects(pCKP); + + sb_dialogbox(dlgX,dlgY,dlgW,dlgH); + if (issave) + { + g_pGraphics->sb_font_draw( (unsigned char*) getstring("WhichSlotSave"),(dlgX+1)<<3,(dlgY+1)<<3); + } + else + { + g_pGraphics->sb_font_draw( (unsigned char*) getstring("WhichSlotLoad"),(dlgX+1)<<3,(dlgY+1)<<3); + gamedo_AnimatedTiles(); + } + + for (int i=0 ; i<9 ; i++) + { + if (g_pInput->getPressedKey(KNUM1+i)) saveslot = 1+i; + } + + g_pVideoDriver->sb_blit(); + gamedo_render_eraseobjects(); + + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!g_pInput->getPressedKey(KQUIT) && !saveslot); + + /* check if the selected save file exists */ + sprintf(fname, "ep%csave%c.dat", p_levelcontrol->episode+'0', saveslot+'0'); + slotexists = 0; + fp = fopen(fname, "rb"); + if (fp) + { + fclose(fp); + slotexists = 1; + } + + if ((issave && !slotexists) || (!issave && slotexists)) + { + map_redraw(); + return saveslot; + } + + if (issave) + { + dlgX = GetStringAttribute("SaveSlotOverwrite", "LEFT"); + dlgY = GetStringAttribute("SaveSlotOverwrite", "TOP"); + dlgW = GetStringAttribute("SaveSlotOverwrite", "WIDTH"); + dlgH = GetStringAttribute("SaveSlotOverwrite", "HEIGHT"); + } + else + { + dlgX = GetStringAttribute("LoadNoSuchSlot", "LEFT"); + dlgY = GetStringAttribute("LoadNoSuchSlot", "TOP"); + dlgW = GetStringAttribute("LoadNoSuchSlot", "WIDTH"); + dlgH = GetStringAttribute("LoadNoSuchSlot", "HEIGHT"); + } + + // either we're trying to save over an existing game, or we're + // loading a game that doesn't exist. + do + { + + gamedo_render_drawobjects(pCKP); + + sb_dialogbox(dlgX,dlgY,dlgW,dlgH); + if (issave) + { + g_pGraphics->sb_font_draw( (unsigned char*) getstring("SaveSlotOverwrite"),(dlgX+1)<<3,(dlgY+1)<<3); + if (g_pInput->getPressedKey(KN)) + { + map_redraw(); + goto top; + } + else if (g_pInput->getPressedKey(KY)) + { + map_redraw(); + return saveslot; + } + } + else + { + g_pGraphics->sb_font_draw( (unsigned char*) getstring("LoadNoSuchSlot"),(dlgX+1)<<3,(dlgY+1)<<3); + + if (g_pInput->getPressedAnyKey()) + { + map_redraw(); + goto top; + } + + gamedo_AnimatedTiles(); + } + + g_pVideoDriver->sb_blit(); + gamedo_render_eraseobjects(); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!g_pInput->getPressedKey(KQUIT)); + + map_redraw(); + return 0; +} + +void game_save_interface(stCloneKeenPlus *pCKP) +{ +int waittimer; +char fname[40]; +char saveslot; +int dlgX,dlgY,dlgW,dlgH; + + dlgX = GetStringAttribute("GameSaveSuccess", "LEFT"); + dlgY = GetStringAttribute("GameSaveSuccess", "TOP"); + dlgW = GetStringAttribute("GameSaveSuccess", "WIDTH"); + dlgH = GetStringAttribute("GameSaveSuccess", "HEIGHT"); + + saveslot = save_slot_box(1, pCKP); + if (!saveslot) return; // canceled + + /* save the game */ + sprintf(fname, "ep%csave%c.dat", pCKP->Control.levelcontrol.episode+'0', saveslot+'0'); + game_save(fname,pCKP); + + /* display the "your game has been saved" box */ + waittimer = 0; + do + { + waittimer++; + if (waittimer > 5000) break; + + gamedo_render_drawobjects(pCKP); + + sb_dialogbox(dlgX,dlgY,dlgW,dlgH); + g_pGraphics->sb_font_draw( (unsigned char*) getstring("GameSaveSuccess"),(dlgX+1)<<3,(dlgY+1)<<3); + + g_pVideoDriver->sb_blit(); + gamedo_render_eraseobjects(); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(!g_pInput->getPressedAnyKey()); + + map_redraw(); +} + +int VerifyQuit(stCloneKeenPlus *pCKP) +{ +int dlgX,dlgY,dlgW,dlgH; +char *text; + + if (fade.mode==FADE_GO) return NO_QUIT; + + text = getstring("VerifyQuit"); + dlgX = GetStringAttribute("VerifyQuit", "LEFT"); + dlgY = GetStringAttribute("VerifyQuit", "TOP"); + dlgW = GetStringAttribute("VerifyQuit", "WIDTH"); + dlgH = GetStringAttribute("VerifyQuit", "HEIGHT"); + + // either we're trying to save over an existing game, or we're + // loading a game that doesn't exist. + do + { + gamedo_render_drawobjects(pCKP); + gamedo_AnimatedTiles(); + + sb_dialogbox(dlgX, dlgY, dlgW, dlgH); + g_pGraphics->sb_font_draw( (unsigned char*) text, (dlgX+1)<<3, (dlgY+1)<<3); + if (g_pInput->getPressedKey(KQ)) + { + map_redraw(); + QuitState = QUIT_PROGRAM; + return 0; + } + else if (g_pInput->getPressedKey(KT)) + { + map_redraw(); + QuitState = QUIT_TO_TITLE; + return QuitState; + } + else if (g_pInput->getPressedKey(KQUIT)) + { + map_redraw(); + QuitState = NO_QUIT; + return QuitState; + } + + g_pVideoDriver->sb_blit(); + gamedo_render_eraseobjects(); + + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + } while(1); +} + +int endsequence(stCloneKeenPlus *pCKP) +{ + + if (pCKP->Control.levelcontrol.episode==1) + { + if (eseq1_ReturnsToShip(pCKP)) return 0; + if (eseq1_ShipFlys(pCKP)) return 0; + eseq1_BackAtHome(pCKP); + } + else if (pCKP->Control.levelcontrol.episode==2) + { + if (eseq2_HeadsForEarth(pCKP)) return 0; + if (eseq2_LimpsHome(pCKP)) return 0; + if (eseq2_SnowedOutside(pCKP)) return 0; + } + else if (pCKP->Control.levelcontrol.episode==3) + { + if (eseq3_AwardBigV(pCKP)) return 0; + } + + return 0; +} + +void AllPlayersInvisible(void) +{ +int i; + + for(i=0;iControl.levelcontrol); + + if (p_levelcontrol->episode==1) + { + /* episode 1: game is won when all parts are collected */ + + // count the number of parts the players have acquired + partcount = 0; + for(i=0;i= 4) + { + return 1; + } + else return 0; + } + else if (p_levelcontrol->episode==2) + { + /* episode 2: game is won when all cities are saved */ + if (!p_levelcontrol->levels_completed[4]) return 0; + if (!p_levelcontrol->levels_completed[6]) return 0; + if (!p_levelcontrol->levels_completed[7]) return 0; + if (!p_levelcontrol->levels_completed[13]) return 0; + if (!p_levelcontrol->levels_completed[11]) return 0; + if (!p_levelcontrol->levels_completed[9]) return 0; + if (!p_levelcontrol->levels_completed[15]) return 0; + if (!p_levelcontrol->levels_completed[16]) return 0; + return 1; + } + else if (p_levelcontrol->episode==3) + { + /* episode 3: game is won when mortimer is defeated */ + if (p_levelcontrol->levels_completed[16]) + { + return 1; + } + else + { + return 0; + } + } + +return 0; +} + +void usage(void) +{ + printf("Usage: keen [lvlnum] [-*player] [-nopk] [-ep*] [-dtm] [-nocheat] [-rec] -[eseq]
\n"); + printf("lvlnum specify a level number (such as 2) to go directly to that level
"); + printf("-*player select number of players (1-4); defaults to 1
"); + printf("-nopk do not allow players to kill each other in multiplayer games
"); + printf("-game* select game of data base; if not given, start menu is opened
"); + printf("-dtm go directly to the world map, bypassing intro and title screen
"); + printf("-mean increase game difficulty
"); + printf("-cheat enable function key cheat/debug codes
"); + printf("-rec record player actions to demo.dat for making a demo
"); + printf("-eseq for the impatient--cut directly to the ending sequence
"); +#ifdef BUILD_SDL + printf("-fs use fullscreen mode
"); + printf("-dbl zoom image 2x
"); + printf("-ogl hardware acceleration
"); + printf("-showfps show FPS in upper-right of screen
"); +#endif +#ifdef TARGET_WIN32 + printf("
-host & -join for the experimental network play mode. These DON'T work yet.\n"); +#endif + + printf("
"); + printf("Examples:
"); + printf(" keen 3 -ep2 play ep 2, level 3 in 1-player mode
"); + printf(" keen -ep3 -dtm -2player play ep3, skip title&intro, 2-player mode
"); + printf(" keen -ep3 play a normal game of ep3
"); +} + +void radar(void) +{ +unsigned int x,y,o; +unsigned int x1,y1,x2,y2; +unsigned int yoff; + // draw the map + for(y=0;ygetScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = map.mapdata[x][y]&15; + } + } + + // draw objects + for(o=0;o> CSF >> 4; + y = objects[o].y >> CSF >> 4; + + yoff = ((y+4+scrolly_buf)&511)<<9; + g_pGraphics->getScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = objects[o].type&15; + } + } + + // draw the area that is visible in the scrollbuffer + x1 = mapx; y1 = mapy; + x2 = x1+32; y2 = y1+32; + for(y=y1;ygetScrollbuffer()[yoff+((4+x1+scrollx_buf)&511)] = 10; + if (x2getScrollbuffer()[yoff+((4+x2+scrollx_buf)&511)] = 10; + } + } + for(x=x1;x<=x2;x++) + { + if (y1 < map.ysize && x < map.xsize) + { + yoff = ((y1+4+scrolly_buf)&511)<<9; + g_pGraphics->getScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = 10; + } + if (y2 < map.ysize && x < map.xsize) + { + yoff = ((y2+4+scrolly_buf)&511)<<9; + g_pGraphics->getScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = 10; + } + } + + // draw the area that is visible on the screen + // 320x200 = 20x12.5 tiles + x1 = scroll_x>>4; y1 = scroll_y>>4; + x2 = x1+20; y2 = y1+12; + for(y=y1;ygetScrollbuffer()[yoff+((4+x1+scrollx_buf)&511)] = 12; + if (x2getScrollbuffer()[yoff+((4+x2+scrollx_buf)&511)] = 12; + } + } + for(x=x1;x<=x2;x++) + { + if (x < map.xsize) + { + if (y1 < map.ysize) + { + yoff = ((y1+4+scrolly_buf)&511)<<9; + g_pGraphics->getScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = 12; + } + if (y2 < map.ysize) + { + yoff = ((y2+4+scrolly_buf)&511)<<9; + g_pGraphics->getScrollbuffer()[yoff+((4+x+scrollx_buf)&511)] = 12; + } + } + } +} + +void SetAllCanSupportPlayer(int o, int state) +{ + unsigned int i; + for(i=0;idrawFont((unsigned char*) text[i], (dlgX+1)<<3, (dlgY+1+i)<<3,0); + } + + twirlframe = 0; + twirltimer = TWIRL_SPEED+1; + + g_pInput->flushAll(); + + // wait for enter + do + { + if (twirltimer>TWIRL_SPEED) + { + g_pGraphics->drawCharacter((dlgX+twirlX)<<3, (dlgY+twirlY)<<3, 9+twirlframe); + g_pVideoDriver->update_screen(); + twirlframe++; + if (twirlframe>5) twirlframe=0; + twirltimer=0; + } else twirltimer++; + g_pInput->pollEvents(); + g_pTimer->SpeedThrottle(); + g_pVideoDriver->update_screen(); + } while(!g_pInput->getPressedKey(KENTER)); +} diff --git a/src/sdl/COpenGL.cpp b/src/sdl/COpenGL.cpp index 7af509788..fec20cb5e 100644 --- a/src/sdl/COpenGL.cpp +++ b/src/sdl/COpenGL.cpp @@ -5,7 +5,6 @@ * Author: gerstrong */ #include "COpenGL.h" -#include "CVideoDriver.h" #include "../CLogFile.h" #define GAME_STD_WIDTH 320 @@ -116,7 +115,7 @@ void COpenGL::render(void) //Clear the screen glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen - LockSurface(m_blitsurface); + SDL_LockSurface(m_blitsurface); if(m_ScaleX == 2) //Scale 2x { @@ -158,7 +157,7 @@ void COpenGL::render(void) glVertex3f (0.0, 1.0, 0.0); glEnd(); - UnlockSurface(m_blitsurface); + SDL_UnlockSurface(m_blitsurface); // Reset (Position?) glLoadIdentity(); diff --git a/src/sdl/CVideoDriver.cpp b/src/sdl/CVideoDriver.cpp index e6e3dde96..5812aa23a 100644 --- a/src/sdl/CVideoDriver.cpp +++ b/src/sdl/CVideoDriver.cpp @@ -480,7 +480,7 @@ char tempbuf[80]; #else sprintf(tempbuf, "FPS: %03d", fps); #endif - g_pGraphics->drawFont( tempbuf, 320-3-(strlen( (char *) tempbuf)<<3), 3, 1); + g_pGraphics->drawFont( (unsigned char *) tempbuf, 320-3-(strlen( (char *) tempbuf)<<3), 3, 1); } update_screen(); @@ -499,11 +499,11 @@ void CVideoDriver::update_screen(void) mp_OpenGL->render(); - LockSurface(FGLayerSurface); + SDL_LockSurface(FGLayerSurface); // Flush the layers memset(FGLayerSurface->pixels,SDL_MapRGB(FGLayerSurface->format, 0, 0, 0), GAME_STD_WIDTH*GAME_STD_HEIGHT*FGLayerSurface->format->BytesPerPixel); - UnlockSurface(FGLayerSurface); + SDL_UnlockSurface(FGLayerSurface); } else // No OpenGL but Software Rendering { @@ -514,8 +514,8 @@ void CVideoDriver::update_screen(void) // another offscreen buffer, and must now stretchblit it to the screen if (Zoom == 1 && m_Resolution.width != 320 ) { - LockSurface(BlitSurface); - LockSurface(screen); + SDL_LockSurface(BlitSurface); + SDL_LockSurface(screen); if(Filtermode == 0) { @@ -527,13 +527,13 @@ void CVideoDriver::update_screen(void) g_pLogFile->textOut(PURPLE,"Try to use a higher zoom factor. Switching to no-filter
"); Filtermode = 0; } - UnlockSurface(screen); - UnlockSurface(BlitSurface); + SDL_UnlockSurface(screen); + SDL_UnlockSurface(BlitSurface); } if (Zoom == 2) { - LockSurface(BlitSurface); - LockSurface(screen); + SDL_LockSurface(BlitSurface); + SDL_LockSurface(screen); if(Filtermode == 0) { @@ -551,13 +551,13 @@ void CVideoDriver::update_screen(void) Filtermode = 0; } - UnlockSurface(screen); - UnlockSurface(BlitSurface); + SDL_UnlockSurface(screen); + SDL_UnlockSurface(BlitSurface); } else if (Zoom == 3) { - LockSurface(BlitSurface); - LockSurface(screen); + SDL_LockSurface(BlitSurface); + SDL_LockSurface(screen); if(Filtermode == 0) { @@ -579,13 +579,13 @@ void CVideoDriver::update_screen(void) g_pLogFile->textOut(PURPLE,"Try to use a higher zoom factor. Switching to no-filter
"); Filtermode = 0; } - UnlockSurface(screen); - UnlockSurface(BlitSurface); + SDL_UnlockSurface(screen); + SDL_UnlockSurface(BlitSurface); } else if (Zoom == 4) { - LockSurface(BlitSurface); - LockSurface(screen); + SDL_LockSurface(BlitSurface); + SDL_LockSurface(screen); if(Filtermode == 0) { @@ -612,18 +612,18 @@ void CVideoDriver::update_screen(void) g_pLogFile->textOut(PURPLE,"Try to use a higher zoom factor. Switching to no-filter
"); Filtermode = 0; } - UnlockSurface(screen); - UnlockSurface(BlitSurface); + SDL_UnlockSurface(screen); + SDL_UnlockSurface(BlitSurface); } SDL_Flip(screen); //SDL_UpdateRect(screen, screenrect.x, screenrect.y, screenrect.w, screenrect.h); - LockSurface(FGLayerSurface); + SDL_LockSurface(FGLayerSurface); // Flush the layers memset(FGLayerSurface->pixels,SDL_MapRGB(FGLayerSurface->format, 0, 0, 0), GAME_STD_WIDTH*GAME_STD_HEIGHT*FGLayerSurface->format->BytesPerPixel); - UnlockSurface(FGLayerSurface); + SDL_UnlockSurface(FGLayerSurface); #ifdef USE_OPENGL } #endif @@ -765,7 +765,7 @@ int y; y = CONSOLE_MESSAGE_Y; for(i=0;idrawFont( cmsg[i].msg, CONSOLE_MESSAGE_X, y, 1); + g_pGraphics->drawFont( (unsigned char *) cmsg[i].msg, CONSOLE_MESSAGE_X, y, 1); y += CONSOLE_MESSAGE_SPACING; } } diff --git a/src/sdl/CVideoDriver.h b/src/sdl/CVideoDriver.h index 0dace2d9b..69e1d4096 100644 --- a/src/sdl/CVideoDriver.h +++ b/src/sdl/CVideoDriver.h @@ -21,17 +21,7 @@ struct st_resolution #include #include #include - -inline bool LockSurface(SDL_Surface * bmp) { - if (SDL_MUSTLOCK(bmp)) - return SDL_LockSurface(bmp) != -1; - return true; -} - -inline void UnlockSurface(SDL_Surface * bmp) { - if (SDL_MUSTLOCK(bmp)) - SDL_UnlockSurface(bmp); -} +using namespace std; class CVideoDriver : public CSingleton { @@ -109,8 +99,8 @@ private: st_resolution m_Resolution; - std::list m_Resolutionlist; - std::list :: iterator m_Resolution_pos; + list m_Resolutionlist; + list :: iterator m_Resolution_pos; unsigned int Mode; bool Fullscreen; diff --git a/src/sdl/sound/CSound.cpp b/src/sdl/sound/CSound.cpp index bde61eabd..3c24087e7 100644 --- a/src/sdl/sound/CSound.cpp +++ b/src/sdl/sound/CSound.cpp @@ -12,7 +12,6 @@ #include "../../hqp/CMusic.h" #include "../../vorticon/sounds.h" #include "../../fileio/CExeFile.h" -#include "../../StringUtils.h" #define SAFE_DELETE_ARRAY(x) if(x) delete[] x; x=NULL @@ -45,7 +44,7 @@ CSound::~CSound() { bool CSound::init(void) { - char name[256]; + char name[MAX_STRING_LENGTH]; SDL_AudioSpec *desired, *obtained; desired = &AudioSpec; @@ -298,14 +297,14 @@ playsound: ; m_soundchannel[chnl].setupSound((unsigned short)snd, 0, true, WAVE_IN, 0, (mode==PLAY_FORCE) ? true : false ); } -char CSound::loadSoundData(unsigned short Episode, const std::string& DataDirectory) +char CSound::loadSoundData(unsigned short Episode, char *DataDirectory) { if(!m_active) return false; - std::string path; + char *path; int ok; - std::string soundfile; - std::string buf; + char soundfile[80]; + char buf[256]; if(m_soundslot) delete[] m_soundslot; m_soundslot = new CSoundSlot[MAX_SOUNDS]; @@ -319,16 +318,21 @@ char CSound::loadSoundData(unsigned short Episode, const std::string& DataDirect g_pLogFile->ftextOut("sound_load_all(): loading all sounds...
"); - soundfile = formatPathString(path) + "sounds.ck" + itoa(Episode); + char buffer[256]; + + formatPathString(buffer,path); + + sprintf(soundfile, "%ssounds.ck%d", buffer,Episode); FILE *p_file; - if( ( p_file = fopen(soundfile.c_str(),"rb") ) == NULL ) + if( ( p_file = fopen(soundfile,"rb") ) == NULL ) { - - buf = "keen" + itoa(Episode) + ".exe"; - g_pLogFile->ftextOut("sound_load_all(): \"%s\" was not found in the data directory. Looking for \"%s\" in \"%s\" and trying to extract this file
", soundfile.c_str(), buf.c_str(), formatPathString(path).c_str()); - extractOfExeFile(formatPathString(path), Episode); + formatPathString(buffer,path); + + sprintf(buf,"keen%d.exe",Episode); + g_pLogFile->ftextOut("sound_load_all(): \"%s\" was not found in the data directory. Looking for \"%s\" in \"%s\" and trying to extract this file
", soundfile, buf, buffer); + extractOfExeFile(buffer, Episode); } else fclose(p_file); @@ -372,7 +376,7 @@ char CSound::loadSoundData(unsigned short Episode, const std::string& DataDirect if (Episode == 2) { - ok |= m_soundslot[33].loadSound(soundfile, "EARTHPOW", SOUND_EARTHPOW); + ok |= m_soundslot[SOUND_KEEN_BLOK].loadSound(soundfile, "EARTHPOW", SOUND_EARTHPOW); } else if (Episode == 3) { @@ -405,16 +409,18 @@ char CSound::loadSoundData(unsigned short Episode, const std::string& DataDirect the sound data. */ -char CSound::extractOfExeFile(const std::string& inputpath, int episode) +char CSound::extractOfExeFile(char *inputpath, int episode) { - std::string outputfname; + const char *outputfname; int bit_count; int pos, sounds_start, sounds_end, ret = 0; - std::string buffer; - std::string inputfname; + char buffer[MAX_STRING_LENGTH]; + char inputfname[MAX_STRING_LENGTH]; pos = 0; bit_count = 0; + memset(buffer,0, MAX_STRING_LENGTH*sizeof(char)); + memset(inputfname,0, MAX_STRING_LENGTH*sizeof(char)); // Set Offsets. Episode 1 already provides this if (episode == 2) @@ -431,7 +437,7 @@ char CSound::extractOfExeFile(const std::string& inputpath, int episode) } else { - g_pLogFile->ftextOut("Error: Unknown keen executable name: %s
", inputfname.c_str()); + g_pLogFile->ftextOut("Error: Unknown keen executable name: %s
", inputfname); return 1; } @@ -440,7 +446,7 @@ char CSound::extractOfExeFile(const std::string& inputpath, int episode) else { FILE *fout; - if(!(fout = fopen(outputfname.c_str(),"wb"))) ret = 1; + if(!(fout = fopen(outputfname,"wb"))) ret = 1; else { fwrite( ExeFile->getData()+sounds_start, 1, (sounds_end-sounds_start), fout); diff --git a/src/sdl/sound/CSound.h b/src/sdl/sound/CSound.h index 456d474bb..8ab64171d 100644 --- a/src/sdl/sound/CSound.h +++ b/src/sdl/sound/CSound.h @@ -11,12 +11,10 @@ #include "../../CSingleton.h" #define g_pSound CSound::Get() -#include #include #include "CSoundChannel.h" #include "CSoundSlot.h" - class CSound : public CSingleton { public: @@ -25,11 +23,11 @@ public: bool init(void); void stop(void); - char loadSoundData(unsigned short Episode, const std::string& DataDirectory); + char loadSoundData(unsigned short Episode, char *DataDirectory); void stopAllSounds(void); bool forcedisPlaying(void); - char sound_load_all(const std::string& path); + char sound_load_all(const char *path); void transform_into_logaritmic_sound(int *pcmstream, int len); void callback(void *unused, Uint8 *stream, int len); void pauseSound(void); @@ -46,7 +44,7 @@ public: void setSoundmode(int freq, bool stereo); - char extractOfExeFile(const std::string& inputpath, int episode); // This is a special funktion. It doesn't belong here! + char extractOfExeFile(char *inputpath, int episode); // This is a special funktion. It doesn't belong here! private: CSoundChannel *m_soundchannel; diff --git a/src/sdl/sound/CSoundSlot.cpp b/src/sdl/sound/CSoundSlot.cpp index 097347b89..243a44516 100644 --- a/src/sdl/sound/CSoundSlot.cpp +++ b/src/sdl/sound/CSoundSlot.cpp @@ -34,7 +34,7 @@ CSoundSlot::~CSoundSlot() { // loads sound searchname from file fname, into sounds[] entry loadnum // return value is nonzero on failure -bool CSoundSlot::loadSound(const std::string& fname, const std::string& searchname, unsigned int loadnum) +bool CSoundSlot::loadSound(const char *fname, const char *searchname, unsigned int loadnum) { // Unload the sound if any was previously loaded if(m_sounddata){ delete[] m_sounddata; m_sounddata = NULL; } @@ -57,10 +57,10 @@ bool CSoundSlot::loadSound(const std::string& fname, const std::string& searchna for(i=0;i<12;i++) name[i] = 0; - fp = fopen(fname.c_str(), "rb"); + fp = fopen(fname, "rb"); if (!fp) { - g_pLogFile->ftextOut("loadSound : Sounds file '%s' unopenable attempting load of '%s'
", fname.c_str(), searchname.c_str()); + g_pLogFile->ftextOut("loadSound : Sounds file '%s' unopenable attempting load of '%s'
", fname, searchname); return false; } @@ -75,12 +75,12 @@ bool CSoundSlot::loadSound(const std::string& fname, const std::string& searchna priority = fgetc(fp); garbage = fgetc(fp); for(i=0;i<12;i++) name[i] = fgetc(fp); - if (name == searchname) goto sound_found; + if (!strcmp(name, searchname)) goto sound_found; curheader += 0x10; } // sound could not be found - g_pLogFile->ftextOut("loadSound : sound %s could not be found in %s.
", searchname.c_str(), fname.c_str()); + g_pLogFile->ftextOut("loadSound : sound %s could not be found in %s.
", searchname, fname); fclose(fp); return false; @@ -115,7 +115,7 @@ bool CSoundSlot::loadSound(const std::string& fname, const std::string& searchna memcpy(m_sounddata, tempstack, m_soundlength*sizeof(unsigned int)); - g_pLogFile->ftextOut("loadSound : loaded sound %s of %d bytes.
", searchname.c_str(), m_soundlength); + g_pLogFile->ftextOut("loadSound : loaded sound %s of %d bytes.
", searchname, m_soundlength); m_hqsound.enabled = false; fclose(fp); diff --git a/src/sdl/sound/CSoundSlot.h b/src/sdl/sound/CSoundSlot.h index 408c61310..f0c131f20 100644 --- a/src/sdl/sound/CSoundSlot.h +++ b/src/sdl/sound/CSoundSlot.h @@ -15,7 +15,7 @@ public: CSoundSlot(); virtual ~CSoundSlot(); - bool loadSound(const std::string& fname, const std::string& searchname, unsigned int loadnum); + bool loadSound(const char *fname, const char *searchname, unsigned int loadnum); void setpAudioSpec(SDL_AudioSpec *pAudioSpec){ m_pAudioSpec = pAudioSpec; } diff --git a/src/vorbis/oggsupport.cpp b/src/vorbis/oggsupport.cpp index 7c8174db3..3290eb2b0 100644 --- a/src/vorbis/oggsupport.cpp +++ b/src/vorbis/oggsupport.cpp @@ -64,11 +64,14 @@ short openOGGSound(FILE *fp, SDL_AudioSpec *pspec, Uint16 format, stHQSound *pso psound->sound_len = buffer.size(); - psound->sound_buffer = new Uint8[psound->sound_len]; - for(Uint32 i=0; isound_len ; i++ ) + //psound->sound_buffer = new Uint8[psound->sound_len]; + psound->sound_buffer = (Uint8*) malloc(psound->sound_len); + /*for(Uint32 i=0; isound_len ; i++ ) { memcpy( &(psound->sound_buffer[i]), &(buffer[i]), 1); - } + }*/ + memcpy( psound->sound_buffer, buffer.data(), psound->sound_len ); + buffer.clear(); return 0; } diff --git a/src/vorticon/CCredits.cpp b/src/vorticon/CCredits.cpp index 037694dd6..76ea1be58 100644 --- a/src/vorticon/CCredits.cpp +++ b/src/vorticon/CCredits.cpp @@ -128,7 +128,7 @@ void CCredits::Render(stCloneKeenPlus *pCKP) for(int j=0 ; j<51 ; j++) if(scrolly+(j<<3) > -8 && scrolly+(j<<3) < 200) - g_pGraphics->sb_font_draw_inverse( scrolltext[j], mid[j], scrolly+(j<<3)); + g_pGraphics->sb_font_draw_inverse( (unsigned char*) scrolltext[j], mid[j], scrolly+(j<<3)); if( g_pInput->getPressedAnyCommand() ) { diff --git a/src/vorticon/CDialog.cpp b/src/vorticon/CDialog.cpp index 27c67685a..e99685a88 100644 --- a/src/vorticon/CDialog.cpp +++ b/src/vorticon/CDialog.cpp @@ -77,9 +77,10 @@ void CDialog::addSeparator(void) addOptionText(""); } -void CDialog::addOptionText(const std::string& text) +void CDialog::addOptionText(const char *text) { - std::string buf; + char buf[TEXT_LENGTH]; + memset(buf,0,TEXT_LENGTH); // This algorithm is similar to one pointer session and // list implementation. TextList is the head. if(OptionTextList == NULL) @@ -87,21 +88,22 @@ void CDialog::addOptionText(const std::string& text) OptionTextList = new stTextList; OptionTextList->nextElement = NULL; - OptionTextList->text = ""; + memset(OptionTextList->text,0,TEXT_LENGTH); - buf = text; + strcpy(buf,text); - size_t length = buf.length(); + unsigned int length; + length = strlen(buf); // before the text is copied, check if that string is too long. if(length > w-4) { - OptionTextList->text = text.substr(0, w-7); - OptionTextList->text += "..."; + copy(text,text+w-7,OptionTextList->text); + strcat(OptionTextList->text,"..."); } else { - OptionTextList->text = text; + strcpy(OptionTextList->text,text); } number_of_options = 1; @@ -122,41 +124,41 @@ void CDialog::addOptionText(const std::string& text) curTextList = (stTextList*) curTextList->nextElement; - curTextList->text = ""; + memset(curTextList->text,0, TEXT_LENGTH); number_of_options++; - buf = text; + strcpy(buf,text); - size_t length = buf.length(); + unsigned int length; + length = strlen(buf); // before the text is copied, check if that string is too long. if(length > w-4) { - curTextList->text = text.substr(0, w-7); - curTextList->text += "..."; + copy(text,text+w-7,curTextList->text); + strcat(curTextList->text,"..."); } else { - curTextList->text = text; + strcpy(curTextList->text,text); } curTextList->nextElement = NULL; } } -void CDialog::setOptionText(unsigned int pos, const std::string& text) +void CDialog::setOptionText(unsigned int pos, const char *text) { unsigned int i; - stTextList *curTextList = OptionTextList; + stTextList *curTextList; - for(i=0 ; inextElement; - } - - curTextList->text = text; + curTextList = OptionTextList; + + for(i=0 ; inextElement; + + memset(curTextList->text,0,TEXT_LENGTH); + strcpy(curTextList->text,text); } void CDialog::setDimensions(int rectx, int recty, int rectw, int recth) @@ -195,7 +197,7 @@ void CDialog::renderDialog() while(curTextList != NULL) { - g_pGraphics->sb_font_draw(curTextList->text, (x+3)<<3, (y+i+1)<<3); + g_pGraphics->sb_font_draw((unsigned char*)(curTextList->text), (x+3)<<3, (y+i+1)<<3); curTextList = (stTextList*) curTextList->nextElement; i++; if(i >= h-2) @@ -285,7 +287,7 @@ void CDialog::renderOpenDialogAnimation(int x,int y, int w, int h) isanimated = false; } -std::string CDialog::getOptionString(unsigned int pos) +char *CDialog::getOptionString(unsigned int pos) { unsigned int i; stTextList *curTextList; @@ -325,7 +327,7 @@ bool CDialog::setNextSelection() int i=0; if(selection+1 < number_of_options) { - while(getOptionString(selection+i+1) == "") + while(strcmp(getOptionString(selection+i+1),"") == 0) i++; selection += i; @@ -341,7 +343,7 @@ bool CDialog::setPrevSelection() int i=0; if(selection-1 > 0) { - while(getOptionString(selection-i-1) == "") + while(strcmp(getOptionString(selection-i-1),"") == 0) i++; selection -= i; diff --git a/src/vorticon/CDialog.h b/src/vorticon/CDialog.h index 632f81b24..f81cd2299 100644 --- a/src/vorticon/CDialog.h +++ b/src/vorticon/CDialog.h @@ -8,13 +8,13 @@ #ifndef CDIALOG_H_ #define CDIALOG_H_ -#include +#define TEXT_LENGTH 256 -struct stTextList +typedef struct stTextList { - std::string text; - stTextList *nextElement; -}; + char text[TEXT_LENGTH]; + void *nextElement; +}stTextList; class CDialog { public: @@ -25,8 +25,8 @@ public: void drawDialogbox(int x1, int y1, int w, int h); void setDimensions(int rectx, int recty, int rectw, int recth); - void addOptionText(const std::string& text); - void setOptionText(unsigned int pos, const std::string& text); + void addOptionText(const char *text); + void setOptionText(unsigned int pos, const char *text); void addSeparator(void); bool setSelection(int value); @@ -34,7 +34,7 @@ public: bool setPrevSelection(); int getSelection(void); - std::string getOptionString(unsigned int pos); + char *getOptionString(unsigned int pos); void renderOpenDialogAnimation(int x,int y, int w, int h); void animateDialogBox(bool value); diff --git a/src/vorticon/CEGAGraphics.cpp b/src/vorticon/CEGAGraphics.cpp index 51df16a25..82bbf1bc5 100644 --- a/src/vorticon/CEGAGraphics.cpp +++ b/src/vorticon/CEGAGraphics.cpp @@ -12,14 +12,11 @@ #endif #include #include -#include "../StringUtils.h" - - using namespace std; -CEGAGraphics::CEGAGraphics(short episode, const std::string& path) { +CEGAGraphics::CEGAGraphics(short episode, const char *path) { m_episode = episode; - m_path = path; + strcpy(m_path, path); // EGAHEAD Structure LatchPlaneSize = 0; @@ -54,15 +51,15 @@ CEGAGraphics::~CEGAGraphics() { bool CEGAGraphics::loadData() { - std::string buf; + char buf[256]; vector databuf; chdir("data"); // TODO: You must be able to use another directory - if(m_path == "") - buf = "egahead.ck" + itoa(m_episode); + if(m_path[0] == 0) + sprintf(buf,"egahead.ck%hd",m_episode); else - buf = m_path + "/egahead.ck" + itoa(m_episode); - std::ifstream HeadFile(buf.c_str(),ios::binary); + sprintf(buf,"%s/egahead.ck%hd",m_path,m_episode); + ifstream HeadFile(buf,ios::binary); if(!HeadFile) return false; @@ -75,8 +72,10 @@ bool CEGAGraphics::loadData() } HeadFile.close(); - char *data = new char[databuf.size()]; - memcpy(data, &databuf[0], databuf.size()); + char *data; + data = new char[databuf.size()]; + + memcpy(data, databuf.data(), databuf.size()); // Now copy the data to the EGAHEAD Structure memcpy(&LatchPlaneSize,data,4); @@ -109,10 +108,10 @@ bool CEGAGraphics::loadData() m_Latch->loadHead(data); - if(m_path == "") - buf = "egalatch.ck" + itoa(m_episode); + if(m_path[0] == 0) + sprintf(buf,"egalatch.ck%hd",m_episode); else - buf = m_path + "/egalatch.ck" + itoa(m_episode); + sprintf(buf,"%s/egalatch.ck%hd",m_path,m_episode); m_Latch->loadData(buf,(compressed>>1)); // The second bit tells, if latch is compressed. @@ -122,14 +121,16 @@ bool CEGAGraphics::loadData() SpriteLocation); m_Sprit->loadHead(data); - if(m_path == "") - buf = "egasprit.ck" + itoa(m_episode); + if(m_path[0] == 0) + sprintf(buf,"egasprit.ck%hd",m_episode); else - buf = m_path + "/egasprit.ck" + itoa(m_episode); + sprintf(buf,"%s/egasprit.ck%hd",m_path,m_episode); m_Sprit->loadData(buf,(compressed>>1)); chdir("../"); + delete [] data; + return true; } diff --git a/src/vorticon/CEGAGraphics.h b/src/vorticon/CEGAGraphics.h index 99605342d..7c8287c4e 100644 --- a/src/vorticon/CEGAGraphics.h +++ b/src/vorticon/CEGAGraphics.h @@ -14,13 +14,12 @@ #ifndef CEGAGRAPHICS_H_ #define CEGAGRAPHICS_H_ -#include #include "CEGALatch.h" #include "CEGASprit.h" class CEGAGraphics { public: - CEGAGraphics(short episode, const std::string& path); + CEGAGraphics(short episode, const char *path); virtual ~CEGAGraphics(); bool loadData(); @@ -29,7 +28,7 @@ public: private: short m_episode; - std::string m_path; + char m_path[256]; // Part of the EGAHEAD Data Structure // Section 1: diff --git a/src/vorticon/CEGALatch.cpp b/src/vorticon/CEGALatch.cpp index 1ea63f2d5..930a15179 100644 --- a/src/vorticon/CEGALatch.cpp +++ b/src/vorticon/CEGALatch.cpp @@ -65,11 +65,12 @@ bool CEGALatch::loadHead( char *data ) return true; } -bool CEGALatch::loadData(const std::string& filename, bool compresseddata) +bool CEGALatch::loadData(const char *filename, bool compresseddata) { + FILE* latchfile; char *RawData; - FILE* latchfile = fopen(filename.c_str(),"rb"); + latchfile = fopen(filename,"rb"); if(!latchfile) return false; diff --git a/src/vorticon/CEGALatch.h b/src/vorticon/CEGALatch.h index d72589fd3..6dac2b5be 100644 --- a/src/vorticon/CEGALatch.h +++ b/src/vorticon/CEGALatch.h @@ -8,8 +8,7 @@ #ifndef CEGALATCH_H_ #define CEGALATCH_H_ -#include -#include +#include class CEGALatch { public: @@ -26,7 +25,7 @@ public: virtual ~CEGALatch(); bool loadHead(char *data ); - bool loadData(const std::string& filename, bool compresseddata); + bool loadData(const char *filename, bool compresseddata); char *RawData; diff --git a/src/vorticon/CEGASprit.cpp b/src/vorticon/CEGASprit.cpp index cb4b96dde..f5d29a8e9 100644 --- a/src/vorticon/CEGASprit.cpp +++ b/src/vorticon/CEGASprit.cpp @@ -71,11 +71,12 @@ bool CEGASprit::loadHead(char *data) return true; } -bool CEGASprit::loadData(const std::string& filename, bool compresseddata) +bool CEGASprit::loadData(const char *filename, bool compresseddata) { + FILE* latchfile; char *RawData; - FILE* latchfile = fopen(filename.c_str(),"rb"); + latchfile = fopen(filename,"rb"); if(!latchfile) return false; diff --git a/src/vorticon/CEGASprit.h b/src/vorticon/CEGASprit.h index 1f46dda2a..2cabe9ad9 100644 --- a/src/vorticon/CEGASprit.h +++ b/src/vorticon/CEGASprit.h @@ -8,8 +8,6 @@ #ifndef CEGASPRIT_H_ #define CEGASPRIT_H_ -#include - class CEGASprit { public: CEGASprit(int planesize, @@ -19,7 +17,7 @@ public: virtual ~CEGASprit(); bool loadHead(char *data); - bool loadData(const std::string& filename, bool compresseddata); + bool loadData(const char *filename, bool compresseddata); private: int m_numsprites; diff --git a/src/vorticon/CHighScores.cpp b/src/vorticon/CHighScores.cpp index c398b7a8f..d166e01fa 100644 --- a/src/vorticon/CHighScores.cpp +++ b/src/vorticon/CHighScores.cpp @@ -9,7 +9,9 @@ #include #include -#include +using namespace std; + +#include #include "../keen.h" #include "../include/menu.h" @@ -18,14 +20,10 @@ #include "../sdl/CInput.h" #include "../sdl/CTimer.h" #include "../CGraphics.h" -#include "../StringUtils.h" #define HIGHSCORETABLE_X 1344 #define HIGHSCORETABLE_Y 32 -using namespace std; - - CHighScores::CHighScores(stCloneKeenPlus *poutsideCKP) { // Set default Scores strcpy(Name[0],"Gerstrong"); @@ -126,8 +124,8 @@ char CHighScores::showHighScore(void) for( i=0 ; i<7 ; i++ ) { - g_pGraphics->sb_color_font_draw(Name[i],40,64+(i<<4),4,7); - g_pGraphics->sb_color_font_draw(Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) Name[i],40,64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); if(Extra[i][0] == true) g_pGraphics->drawTile(32,90+(i<<4),ItemTiles[0]); if(Extra[i][1] == true) @@ -142,19 +140,19 @@ char CHighScores::showHighScore(void) { for( i=0 ; i<7 ; i++ ) { - std::string buf; - g_pGraphics->sb_color_font_draw(Name[i],40,64+(i<<4),4,7); - g_pGraphics->sb_color_font_draw(Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); - buf = itoa(Cities[i]); - g_pGraphics->sb_color_font_draw(buf,250,64+(i<<4),4,7); + char buf[2]; + g_pGraphics->sb_color_font_draw((unsigned char*) Name[i],40,64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); + sprintf(buf,"%d",Cities[i]); + g_pGraphics->sb_color_font_draw((unsigned char*) buf,250,64+(i<<4),4,7); } } else { for( i=0 ; i<7 ; i++ ) { - g_pGraphics->sb_color_font_draw(Name[i],40,64+(i<<4),4,7); - g_pGraphics->sb_color_font_draw(Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) Name[i],40,64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); } } @@ -247,19 +245,19 @@ char CHighScores::writeHighScore(int points, bool *extras, int cities) { for( i=0 ; i<7 ; i++ ) { - std::string buf; - g_pGraphics->sb_color_font_draw(Name[i],40,64+(i<<4),4,7); - g_pGraphics->sb_color_font_draw(Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); - buf = itoa(Cities[i]); - g_pGraphics->sb_color_font_draw(buf,250,64+(i<<4),4,7); + char buf[2]; + g_pGraphics->sb_color_font_draw((unsigned char*) Name[i],40,64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); + sprintf(buf,"%d",Cities[i]); + g_pGraphics->sb_color_font_draw((unsigned char*) buf,250,64+(i<<4),4,7); } } else { for( i=0 ; i<7 ; i++ ) { - g_pGraphics->sb_color_font_draw(Name[i],40,64+(i<<4),4,7); - g_pGraphics->sb_color_font_draw(Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) Name[i],40,64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); } } @@ -313,7 +311,7 @@ char CHighScores::writeHighScore(int points, bool *extras, int cities) if(g_pInput->getPressedKey(KBCKSPCE) && (WrittenName.length() > 0)) { memset(buf,0,256); - g_pGraphics->sb_color_font_draw(" ",40,64+(place<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) " ",40,64+(place<<4),4,7); WrittenName.erase(WrittenName.length()-1); WrittenName.copy(buf,WrittenName.length(),0); memset(Name[place],0,16); @@ -331,10 +329,10 @@ char CHighScores::writeHighScore(int points, bool *extras, int cities) for( i=0 ; i<7 ; i++ ) { if(i != place) - g_pGraphics->sb_color_font_draw(Name[i],40,64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) Name[i],40,64+(i<<4),4,7); else - g_pGraphics->sb_color_font_draw(buf,40,64+(i<<4),4,7); - g_pGraphics->sb_color_font_draw(Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) buf,40,64+(i<<4),4,7); + g_pGraphics->sb_color_font_draw((unsigned char*) Score[i],200-(strlen(Score[i])<<3),64+(i<<4),4,7); if(pCKP->Control.levelcontrol.episode == 1) { @@ -366,7 +364,9 @@ char CHighScores::writeHighScore(int points, bool *extras, int cities) char CHighScores::loadHighScoreTable(void) { string sBuf; - std::string chBuf = itoa(Episode); + char chBuf[256]; + + sprintf(chBuf,"%d",Episode); sBuf.append("data/"); sBuf.append(DataDirectory); diff --git a/src/vorticon/CHighScores.h b/src/vorticon/CHighScores.h index 4797a19d5..7b822a657 100644 --- a/src/vorticon/CHighScores.h +++ b/src/vorticon/CHighScores.h @@ -8,8 +8,6 @@ #ifndef CHIGHSCORES_H_ #define CHIGHSCORES_H_ -#include - class CHighScores { public: CHighScores(stCloneKeenPlus *poutsideCKP); @@ -27,7 +25,7 @@ private: int ItemTiles[4]; char Episode; - std::string DataDirectory; + char *DataDirectory; stCloneKeenPlus *pCKP; diff --git a/src/vorticon/CMessages.cpp b/src/vorticon/CMessages.cpp index ef5dd5c9a..e479b9d31 100644 --- a/src/vorticon/CMessages.cpp +++ b/src/vorticon/CMessages.cpp @@ -55,7 +55,7 @@ bool CMessages::readData(char *buf, int episode, int version) // Now read the stuff and store it to a list for(int pos=offset_start ; pos :: iterator i; + list :: iterator i; #include for(i=StringList.begin() ; i!=StringList.end() ; i++) diff --git a/src/vorticon/CMessages.h b/src/vorticon/CMessages.h index 00d6be2fb..a76f35568 100644 --- a/src/vorticon/CMessages.h +++ b/src/vorticon/CMessages.h @@ -12,6 +12,8 @@ #include #include +using namespace std; + // TODO: Make the strings a class, but it must read from the exe-files basing on uncompressed buffer class CMessages { @@ -23,8 +25,8 @@ public: char *getString(const char *IDtext); private: - std::list StringList; - std::list StringIDList; + list StringList; + list StringIDList; }; #endif /* CMESSAGES_H_ */