/* 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" #include "FindFile.h" #include "dialog/CWindow.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->fltextOut(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->fltextOut(BLACK,true," Demo file closed.
"); } g_pGraphics->stopGraphics(); g_pLogFile->fltextOut(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; } } void showGameHint(int mpx, int mpy, int episode, int level) { std::string strname; if(episode == 1) { if(map.mapdata[mpx][mpy] >= 435 && map.mapdata[mpx][mpy] <= 438) // it's a garg statue map_chgtile(mpx, mpy, 434); else map_chgtile(mpx, mpy, 485); strname = "EP1_YSIYM_LVL" + itoa(level); } else if(episode == 2) { // make the switch stop glowing // There may be a bug. Be careful map_chgtile(mpx, mpy+1, 432); switch(level) { case 8: strname = "EP2_VE_NOJUMPINDARK"; break; case 10: strname = "EP2_VE_EVILBELTS"; break; } } CWindow *InfoTextWindow = new CWindow(0.2, 0.2, 0.6, 0.6); InfoTextWindow->addTextBox(0.0f, 0.0f, 1.0f, 0.8f, getstring(strname), true); InfoTextWindow->addTextBox(0.2f, 0.8f, 1.0f, 0.2f, "Okay!", true); g_pInput->flushAll(); do { g_pInput->pollEvents(); g_pTimer->SpeedThrottle(); InfoTextWindow->render(); g_pVideoDriver->update_screen(); } while(!g_pInput->getPressedAnyCommand()); delete InfoTextWindow; } 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 = OpenGameFile(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 = OpenGameFile(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 = OpenGameFile(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 = OpenGameFile(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 = OpenGameFile(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
"); } unsigned int rnd(void) { //random_seed = random_seed * 1103515245 + 12345; //return (uint)(random_seed / 65536) % 32768; return rand(); } 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)); }