X-Git-Url: http://4ch.mooo.com/gitweb/?p=16.git;a=blobdiff_plain;f=16%2Fkeen456%2FKEEN4-6%2FCK_PLAY.C;fp=16%2Fkeen456%2FKEEN4-6%2FCK_PLAY.C;h=0000000000000000000000000000000000000000;hp=0e0814056c3076c1fd918c546f9f38c8e909f906;hb=a387b1ff6f02e2da93e870a330af886d1c8233da;hpb=7d1948e210bb7b58af0a0412e71f2a0a0a2010af diff --git a/16/keen456/KEEN4-6/CK_PLAY.C b/16/keen456/KEEN4-6/CK_PLAY.C deleted file mode 100755 index 0e081405..00000000 --- a/16/keen456/KEEN4-6/CK_PLAY.C +++ /dev/null @@ -1,2422 +0,0 @@ -/* Reconstructed Commander Keen 4-6 Source Code - * Copyright (C) 2021 K1n9_Duk3 - * - * This file is loosely based on: - * Keen Dreams Source Code - * Copyright (C) 2014 Javier M. Chavez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "CK_DEF.H" - -/* -============================================================================= - - GLOBAL VARIABLES - -============================================================================= -*/ - -ScanCode firescan = sc_Space; - -boolean singlestep, jumpcheat, godmode, keenkilled; - -exittype playstate; -gametype gamestate; - -objtype *new, *check, *player, *scoreobj; - -Uint16 originxtilemax; -Uint16 originytilemax; - -ControlInfo c; -boolean button2, button3; // never used - -objtype dummyobj; - -Sint16 invincible; - -boolean oldshooting, showscorebox, joypad; - -Sint16 groundslam; - -boolean debugok; -boolean jumpbutton, jumpheld, pogobutton, pogoheld, firebutton, fireheld, upheld; - - -/* -============================================================================= - - LOCAL VARIABLES - -============================================================================= -*/ - -objtype *obj; - -Uint16 centerlevel; - -Uint16 objectcount; -objtype objarray[MAXACTORS]; -objtype *lastobj; -objtype *objfreelist; - -Sint16 inactivateleft; -Sint16 inactivateright; -Sint16 inactivatetop; -Sint16 inactivatebottom; - -#ifdef KEEN6Ev15 -Uint16 __dummy__; // never used, but must be present to recreate the original EXE -#endif - -Uint16 extravbls; - -Uint16 windowofs; -Sint16 vislines; -boolean scrollup; - -Sint16 oldfirecount; - -//=========================================================================== - -/* -================== -= -= CountObjects -= -================== -*/ - -void CountObjects(void) -{ - Uint16 activeobjects, inactiveobjects; - objtype *ob; - - activeobjects = inactiveobjects = 0; - for (ob=player; ob; ob=ob->next) - { - if (ob->active) - { - activeobjects++; - } - else - { - inactiveobjects++; - } - } - VW_FixRefreshBuffer(); - US_CenterWindow(18, 4); - PrintY += 7; - US_Print("Active Objects :"); - US_PrintUnsigned(activeobjects); - US_Print("\nInactive Objects:"); - US_PrintUnsigned(inactiveobjects); - VW_UpdateScreen(); - IN_Ack(); -} - -/* -================== -= -= DebugMemory -= -================== -*/ - -void DebugMemory(void) -{ - VW_FixRefreshBuffer(); - US_CenterWindow(16, 7); - US_CPrint("Memory Usage"); - US_CPrint("------------"); - US_Print("Total :"); - US_PrintUnsigned((mminfo.mainmem+mminfo.EMSmem+mminfo.XMSmem)/1024); - US_Print("k\nFree :"); - US_PrintUnsigned(MM_UnusedMemory()/1024); - US_Print("k\nWith purge:"); - US_PrintUnsigned(MM_TotalFree()/1024); - US_Print("k\n"); - VW_UpdateScreen(); - IN_Ack(); -#if GRMODE != CGAGR - MM_ShowMemory(); -#endif -} - -/* -=================== -= -= TestSprites -= -=================== -*/ - -void TestSprites(void) -{ - Uint16 infox, infoy; - Sint16 chunk, oldchunk; - Sint16 shift; - Uint16 infobottom, drawx; - spritetabletype far *info; - Uint8 _seg *block; - Uint16 size; - Uint16 scan; - Uint32 totalsize; - - VW_FixRefreshBuffer(); - US_CenterWindow(30, 17); - totalsize = 0; - US_CPrint("Sprite Test"); - US_CPrint("-----------"); - infoy = PrintY; - infox = (PrintX + 56) & ~7; - drawx = infox + 40; - US_Print("Chunk:\nWidth:\nHeight:\nOrgx:\nOrgy:\nXl:\nYl:\nXh:\nYh:\nShifts:\nMem:\n"); - infobottom = PrintY; - chunk = STARTSPRITES; - shift = 0; - while (1) - { - if (chunk >= STARTSPRITES+NUMSPRITES) - { - chunk = STARTSPRITES+NUMSPRITES-1; - } - else if (chunk < STARTSPRITES) - { - chunk = STARTSPRITES; - } - info = &spritetable[chunk-STARTSPRITES]; - block = grsegs[chunk]; - VWB_Bar(infox, infoy, 40, infobottom-infoy, WHITE); - PrintX = infox; - PrintY = infoy; - US_PrintUnsigned(chunk); - US_Print("\n"); - PrintX = infox; - US_PrintUnsigned(info->width); - US_Print("\n"); - PrintX = infox; - US_PrintUnsigned(info->height); - US_Print("\n"); - PrintX = infox; - US_PrintSigned(info->orgx); - US_Print("\n"); - PrintX = infox; - US_PrintSigned(info->orgy); - US_Print("\n"); - PrintX = infox; - US_PrintSigned(info->xl); - US_Print("\n"); - PrintX = infox; - US_PrintSigned(info->yl); - US_Print("\n"); - PrintX = infox; - US_PrintSigned(info->xh); - US_Print("\n"); - PrintX = infox; - US_PrintSigned(info->yh); - US_Print("\n"); - PrintX = infox; - US_PrintSigned(info->shifts); - US_Print("\n"); - PrintX = infox; - if (!block) - { - US_Print("-----"); - } - else - { - size = ((spritetype far *)block)->sourceoffset[3] + ((spritetype far *)block)->planesize[3]*5; - size = (size + 15) & ~15; //round up to multiples of 16 - totalsize += size; //useless: the value stored in 'totalsize' is never used - US_PrintUnsigned(size); - US_Print("="); - } - oldchunk = chunk; - do - { - VWB_Bar(drawx, infoy, 110, infobottom-infoy, WHITE); - if (block) - { - PrintX = drawx; - PrintY = infoy; - US_Print("Shift:"); - US_PrintUnsigned(shift); - US_Print("\n"); - VWB_DrawSprite(drawx + 2*shift + 16, PrintY, chunk); - } - VW_UpdateScreen(); - scan = IN_WaitForKey(); - switch (scan) - { - case sc_UpArrow: - chunk++; - break; - case sc_DownArrow: - chunk--; - break; - case sc_PgUp: - chunk += 10; - if (chunk >= STARTSPRITES+NUMSPRITES) - { - chunk = STARTSPRITES+NUMSPRITES-1; - } - break; - case sc_PgDn: - chunk -= 10; - if (chunk < STARTSPRITES) - { - chunk = STARTSPRITES; - } - break; - case sc_LeftArrow: - if (--shift == -1) - { - shift = 3; - } - break; - case sc_RightArrow: - if (++shift == 4) - { - shift = 0; - } - break; - case sc_Escape: - return; - } - - } while (chunk == oldchunk); - - } -} - -/* -=================== -= -= PicturePause -= -=================== -*/ - -void PicturePause(void) -{ - Uint16 source; - Sint16 y; - -// -// wait for a key press, abort if it's not Enter -// - IN_ClearKeysDown(); - while (!LastScan); - if (LastScan != sc_Enter) - { - IN_ClearKeysDown(); - return; - } - - SD_PlaySound(SND_JUMP); - SD_WaitSoundDone(); - -// -// rearrange onscreen image into base EGA layout, so that it -// can be grabbed correctly by an external screenshot tool -// - source = displayofs + panadjust; - - VW_ColorBorder(15); // white (can't use WHITE as parameter, since that's defined as 3 for CGA and this must use 15) - VW_SetLineWidth(40); - VW_SetScreen(0, 0); - - if (source < 0x10000l-200*64) - { - // - // copy top line first - // - for (y=0; y<200; y++) - { - VW_ScreenToScreen(source+y*64, y*40, 40, 1); - } - } - else - { - // - // copy bottom line first - // - for (y=199; y>=0; y--) - { - VW_ScreenToScreen(source+y*64, y*40, 40, 1); - } - } - -// -// shut down input manager so that screenshot tool can see input again -// - IN_Shutdown(); - - SD_PlaySound(SND_EXTRAKEEN); - SD_WaitSoundDone(); - -// -// shut down the remaining ID managers, except VW (stay in graphics mode!) -// - US_Shutdown(); - SD_Shutdown(); - IN_Shutdown(); - RF_Shutdown(); - CA_Shutdown(); - MM_Shutdown(); - -// -// wait until user hits Escape -// - while (((bioskey(0) >> 8) & 0xFF) != sc_Escape); - -// -// back to text mode and exit to DOS -// - VW_Shutdown(); - exit(0); -} - -/* -=================== -= -= MaskOnTile -= -=================== -*/ - -void MaskOnTile(Uint16 dest, Uint16 source) -{ - Sint16 i; - Uint16 _seg *sourceseg; - Uint16 _seg *destseg; - Uint16 sourceval, maskindex, sourcemask; - - sourceseg = (grsegs+STARTTILE16M)[source]; - destseg = (grsegs+STARTTILE16M)[dest]; - for (i=0; i<64; i++) - { - maskindex = i & 15; -#ifdef KEEN6Ev15 - sourceval = sourceseg[16+i]; -#else - sourceval = (sourceseg+16)[i]; -#endif - sourcemask = sourceseg[maskindex]; - destseg[maskindex] &= sourcemask; - destseg[16+i] &= sourcemask; - destseg[16+i] |= sourceval; - } -} - -/* -=================== -= -= WallDebug -= -=================== -*/ - -void WallDebug(void) -{ - Sint16 i, val; - - VW_FixRefreshBuffer(); - US_CenterWindow(24, 3); - US_PrintCentered("WORKING"); - VW_UpdateScreen(); - for (i=STARTTILE16M+108; i 1) - { - strcpy(str, "WallDebug: East wall other than 1:"); - itoa(i, str2, 10); - strcat(str, str2); - Quit(str); - } - if (val) - { - MaskOnTile(i, val+114); //Note: val is always 1 here, so you could use 115 as 2nd arg - } - val = tinf[i+WESTWALL] & 7; - if (val > 1) - { - strcpy(str, "WallDebug: West wall other than 1:"); - itoa(i, str2, 10); - strcat(str, str2); - Quit(str); - } - if (val) - { - MaskOnTile(i, val+122); //Note: val is always 1 here, so you could use 123 as 2nd arg - } - } -} - - -//=========================================================================== - -/* -================ -= -= DebugKeys -= -================ -*/ - -boolean DebugKeys(void) -{ - Sint16 level, i, esc; - - if (Keyboard[sc_B] && ingame) // B = border color - { - VW_FixRefreshBuffer(); - US_CenterWindow(24, 3); - PrintY += 6; - US_Print(" Border color (0-15):"); - VW_UpdateScreen(); - esc = !US_LineInput(px, py, str, NULL, true, 2, 0); - if (!esc) - { - level = atoi(str); - if (level >= 0 && level <= 15) - { - VW_ColorBorder(level); - } - } - return true; - } - - if (Keyboard[sc_C] && ingame) // C = count objects - { - CountObjects(); - return true; - } - - if (Keyboard[sc_D] && ingame) // D = start / end demo record - { - if (DemoMode == demo_Off) - { - StartDemoRecord(); - } - else if (DemoMode == demo_Record) - { - EndDemoRecord(); - playstate = ex_completed; - } - return true; - } - - if (Keyboard[sc_E] && ingame) // E = quit level - { - if (tedlevel) - { - TEDDeath(); - } - playstate = ex_completed; - //BUG? there is no return in this branch (should return false) - } - - if (Keyboard[sc_G] && ingame) // G = god mode - { - VW_FixRefreshBuffer(); - US_CenterWindow(12, 2); - if (godmode) - { - US_PrintCentered("God mode OFF"); - } - else - { - US_PrintCentered("God mode ON"); - } - VW_UpdateScreen(); - IN_Ack(); - godmode ^= true; - return true; - } - else if (Keyboard[sc_I]) // I = item cheat - { - VW_FixRefreshBuffer(); - US_CenterWindow(12, 3); - US_PrintCentered("Free items!"); - for (i=0; i<4; i++) - { - gamestate.keys[i] = 99; - } - gamestate.ammo = 99; -#if defined KEEN4 - gamestate.wetsuit = true; -#elif defined KEEN5 - gamestate.keycard = true; -#elif defined KEEN6 - gamestate.passcardstate=gamestate.hookstate=gamestate.sandwichstate = 1; -#endif - VW_UpdateScreen(); - IN_Ack(); - GivePoints(3000); - return true; - } - else if (Keyboard[sc_J]) // J = jump cheat - { - jumpcheat ^= true; - VW_FixRefreshBuffer(); - US_CenterWindow(18, 3); - if (jumpcheat) - { - US_PrintCentered("Jump cheat ON"); - } - else - { - US_PrintCentered("Jump cheat OFF"); - } - VW_UpdateScreen(); - IN_Ack(); - return true; - } - else if (Keyboard[sc_M]) // M = memory info - { - DebugMemory(); - return true; - } - else if (Keyboard[sc_N]) // N = no clip - { - VW_FixRefreshBuffer(); - US_CenterWindow(18, 3); - if (player->needtoclip) - { - US_PrintCentered("No clipping ON"); - player->needtoclip = cl_noclip; - } - else - { - US_PrintCentered("No clipping OFF"); - player->needtoclip = cl_midclip; - } - VW_UpdateScreen(); - IN_Ack(); - return true; - } - else if (Keyboard[sc_P]) // P = pause with no screen disruptioon - { - IN_ClearKeysDown(); - PicturePause(); - return true; - } - else if (Keyboard[sc_S] && ingame) // S = slow motion - { - singlestep ^= true; - VW_FixRefreshBuffer(); - US_CenterWindow(18, 3); - if (singlestep) - { - US_PrintCentered("Slow motion ON"); - } - else - { - US_PrintCentered("Slow motion OFF"); - } - VW_UpdateScreen(); - IN_Ack(); - return true; - } - else if (Keyboard[sc_T]) // T = sprite test - { - TestSprites(); - return true; - } - else if (Keyboard[sc_V]) // V = extra VBLs - { - VW_FixRefreshBuffer(); - US_CenterWindow(30, 3); - PrintY += 6; - US_Print(" Add how many extra VBLs(0-8):"); - VW_UpdateScreen(); - esc = !US_LineInput(px, py, str, NULL, true, 2, 0); - if (!esc) - { - level = atoi(str); - if (level >= 0 && level <= 8) - { - extravbls = level; - } - } - return true; - } - else if (Keyboard[sc_W] && ingame) // W = warp to level - { - VW_FixRefreshBuffer(); - US_CenterWindow(26, 3); - PrintY += 6; - US_Print(" Warp to which level(1-18):"); - VW_UpdateScreen(); - esc = !US_LineInput(px, py, str, NULL, true, 2, 0); - if (!esc) - { - level = atoi(str); - if (level > 0 && level <= 18) - { - gamestate.mapon = level; - playstate = ex_warped; - } - } - return true; - } - else if (Keyboard[sc_Y]) // Y = wall debug - { - WallDebug(); - return true; - } - else if (Keyboard[sc_Z]) // Z = game over - { - gamestate.lives = 0; - KillKeen(); - return false; - } - return false; -} - -//=========================================================================== - -/* -================ -= -= UserCheat -= -================ -*/ - -void UserCheat(void) -{ - Sint16 i; - - for (i=sc_A; i<=sc_Z; i++) //Note: this does NOT check the keys in alphabetical order! - { - if (i != sc_B && i != sc_A && i != sc_T && Keyboard[i]) - { - return; - } - } - US_CenterWindow(20, 7); - PrintY += 2; - US_CPrint( - "Cheat Option!\n" - "\n" - "You just got all\n" - "the keys, 99 shots,\n" - "and an extra keen!"); - VW_UpdateScreen(); - IN_Ack(); - RF_ForceRefresh(); - gamestate.ammo = 99; - gamestate.lives++; -#ifdef KEEN5 - gamestate.keycard = true; -#endif - gamestate.keys[0] = gamestate.keys[1] = gamestate.keys[2] = gamestate.keys[3] = 1; -} - -//=========================================================================== - -/* -===================== -= -= CheckKeys -= -===================== -*/ - -void CheckKeys(void) -{ - if (screenfaded) // don't do anything with a faded screen - { - return; - } - -// -// Enter for status screen -// - if (Keyboard[sc_Enter] || (GravisGamepad && GravisAction[ga_Status])) - { - StatusWindow(); - IN_ClearKeysDown(); - RF_ForceRefresh(); - lasttimecount = TimeCount; // BUG: should be the other way around - } - -// -// pause key wierdness can't be checked as a scan code -// - if (Paused) - { - SD_MusicOff(); - VW_FixRefreshBuffer(); - US_CenterWindow(8, 3); - US_PrintCentered("PAUSED"); - VW_UpdateScreen(); - IN_Ack(); - RF_ForceRefresh(); - Paused = false; - SD_MusicOn(); - } - -#ifndef KEEN6 -// -// F1 to enter help screens -// - if (LastScan == sc_F1) - { - StopMusic(); - HelpScreens(); - StartMusic(gamestate.mapon); - if (showscorebox) - { - scoreobj->temp2 = -1; - scoreobj->temp1 = -1; - scoreobj->temp3 = -1; - scoreobj->temp4 = -1; - } - RF_ForceRefresh(); - } -#endif - - if (!storedemo) - { -// -// F2-F7/ESC to enter control panel -// - if (LastScan >= sc_F2 && LastScan <= sc_F7 || LastScan == sc_Escape) - { - VW_FixRefreshBuffer(); - StopMusic(); - US_ControlPanel(); - RF_FixOfs(); - StartMusic(gamestate.mapon); - if (!showscorebox && scoreobj->sprite) - { - RF_RemoveSprite(&scoreobj->sprite); - } - if (showscorebox) - { - scoreobj->temp2 = -1; - scoreobj->temp1 = -1; - scoreobj->temp3 = -1; - scoreobj->temp4 = -1; - } - IN_ClearKeysDown(); - if (restartgame) - { - playstate = ex_resetgame; - } - else if (!loadedgame) - { - RF_ForceRefresh(); - } - if (abortgame) - { - abortgame = false; - playstate = ex_abortgame; - } - if (loadedgame) - { - playstate = ex_loadedgame; - } - lasttimecount = TimeCount; // BUG: should be the other way around - } - -// -// F9 boss key -// - if (LastScan == sc_F9) - { - VW_Shutdown(); - SD_MusicOff(); - cputs("C:>"); - IN_ClearKeysDown(); - while (LastScan != sc_Escape); - VW_SetScreenMode(GRMODE); - VW_ColorBorder(bordercolor); - RF_ForceRefresh(); - IN_ClearKeysDown(); - lasttimecount = TimeCount; // BUG: should be the other way around - SD_MusicOn(); - } - } - -// -// B-A-T cheat code -// - if (Keyboard[sc_B] && Keyboard[sc_A] && Keyboard[sc_T]) - { - UserCheat(); - } - -// -// F10-? debug keys -// - if (debugok && Keyboard[sc_F10]) - { - if (DebugKeys()) - { - RF_ForceRefresh(); - lasttimecount = TimeCount; // BUG: should be the other way around - } - } - -// -// Ctrl-S toggles sound (only in storedemo mode) -// - if (storedemo && Keyboard[sc_Control] && LastScan == sc_S) - { - if (SoundMode != sdm_Off) - { - SD_SetSoundMode(sdm_Off); - SD_SetMusicMode(smm_Off); - } - else - { - if (AdLibPresent) - { - SD_SetSoundMode(sdm_AdLib); - QuietFX = false; - SD_SetMusicMode(smm_AdLib); - } - else - { - SD_SetSoundMode(sdm_PC); - SD_SetMusicMode(smm_Off); - } - CA_LoadAllSounds(); - } - } - -// -// Ctrl-Q quick quit -// - if (Keyboard[sc_Control] && LastScan == sc_Q) - { - IN_ClearKeysDown(); - Quit(NULL); - } -} - -//=========================================================================== - -/* -================== -= -= PrintNumbers -= -================== -*/ - -void PrintNumbers(Sint16 x, Sint16 y, Sint16 maxlen, Sint16 basetile, Sint32 number) -{ - register Sint16 i; - Sint16 len; - char buffer[20]; - - ltoa(number, buffer, 10); - len = strlen(buffer); - i = maxlen; - while (i>len) - { - VWB_DrawTile8(x, y, basetile); - i--; - x += 8; - } - while (i>0) - { - VWB_DrawTile8(x, y, basetile+buffer[len-i]+(1-'0')); - i--; - x += 8; - } -} - -/* -================== -= -= DrawStatusWindow -= -================== -*/ - -#if GRMODE == CGAGR - -#define BACKCOLOR WHITE -#define TEXTBACK BLACK -#define NUMBERBACK BLACK - -#else - -#define BACKCOLOR LIGHTGRAY -#define TEXTBACK WHITE -#define NUMBERBACK BLACK - -#endif - -void DrawStatusWindow(void) -{ - Sint16 off, x, y, w, h, i; - Uint16 width, height; - - x = 64; - y = 16; - w = 184; - h = 144; - VWB_DrawTile8(x, y, 54); - VWB_DrawTile8(x, y+h, 60); - for (i=x+8; i<=x+w-8; i+=8) - { - VWB_DrawTile8(i, y, 55); - VWB_DrawTile8(i, y+h, 61); - } - VWB_DrawTile8(i, y, 56); - VWB_DrawTile8(i, y+h, 62); - for (i=y+8; i<=y+h-8; i+=8) - { - VWB_DrawTile8(x, i, 57); - VWB_DrawTile8(x+w, i, 59); - } - VWB_Bar(72, 24, 176, 136, BACKCOLOR); - - PrintY = 28; - WindowX = 80; - WindowW = 160; - US_CPrint("LOCATION"); - VWB_Bar(79, 38, 162, 20, TEXTBACK); -#ifdef KEEN5 - if (mapon == 0 && player->y > 100*TILEGLOBAL) - _fstrcpy(str, levelnames[13]); - else - _fstrcpy(str, levelnames[gamestate.mapon]); -#else - _fstrcpy(str, levelnames[gamestate.mapon]); -#endif - SizeText(str, &width, &height); - PrintY = (20-height)/2+40-2; - US_CPrint(str); - - PrintY = 61; - WindowX = 80; - WindowW = 64; - US_CPrint("SCORE"); - VWB_Bar(79, 71, 66, 10, NUMBERBACK); - PrintNumbers(80, 72, 8, 41, gamestate.score); - - PrintY = 61; - WindowX = 176; - WindowW = 64; - US_CPrint("EXTRA"); - VWB_Bar(175, 71, 66, 10, NUMBERBACK); - PrintNumbers(176, 72, 8, 41, gamestate.nextextra); - -#if defined KEEN4 - PrintY = 85; - WindowX = 80; - WindowW = 64; - US_CPrint("RESCUED"); - VWB_Bar(79, 95, 66, 10, NUMBERBACK); - for (i = 0; i < gamestate.rescued; i++, off+=8) - { - VWB_DrawTile8(i*8 + 80, 96, 40); - } -#elif defined KEEN5 - PrintY = 92; - PrintX = 80; - US_Print("KEYCARD"); - VWB_Bar(135, 91, 10, 10, NUMBERBACK); - if (gamestate.keycard) - { - VWB_DrawTile8(136, 92, 40); - } -#endif - - PrintY = 85; - WindowX = 176; - WindowW = 64; - US_CPrint("LEVEL"); - VWB_Bar(175, 95, 66, 10, TEXTBACK); - PrintY = 96; - WindowX = 176; - WindowW = 64; - switch (gamestate.difficulty) - { - case gd_Easy: - US_CPrint("Easy"); - break; - case gd_Normal: - US_CPrint("Normal"); - break; - case gd_Hard: - US_CPrint("Hard"); - break; - } - -#ifdef KEEN6 - PrintX = 80; - PrintY = 96; - US_Print("ITEMS"); - VWB_Bar(127, 95, 26, 10, NUMBERBACK); - if (gamestate.sandwichstate == 1) - { - VWB_DrawTile8(128, 96, 2); - } - else - { - VWB_DrawTile8(128, 96, 1); - } - if (gamestate.hookstate == 1) - { - VWB_DrawTile8(136, 96, 4); - } - else - { - VWB_DrawTile8(136, 96, 3); - } - if (gamestate.passcardstate == 1) - { - VWB_DrawTile8(144, 96, 6); - } - else - { - VWB_DrawTile8(144, 96, 5); - } -#endif - - PrintX = 80; - PrintY = 112; - US_Print("KEYS"); - VWB_Bar(119, 111, 34, 10, NUMBERBACK); - for (i = 0; i < 4; i++) - { - if (gamestate.keys[i]) - { - VWB_DrawTile8(i*8+120, 112, 36+i); - } - } - - PrintX = 176; - PrintY = 112; - US_Print("AMMO"); - VWB_Bar(215, 111, 26, 10, NUMBERBACK); - PrintNumbers(216, 112, 3, 41, gamestate.ammo); - - PrintX = 80; - PrintY = 128; - US_Print("KEENS"); - VWB_Bar(127, 127, 18, 10, NUMBERBACK); - PrintNumbers(128, 128, 2, 41, gamestate.lives); - - PrintX = 176; - PrintY = 128; - US_Print(DROPSNAME); - VWB_Bar(224, 127, 16, 10, NUMBERBACK); - PrintNumbers(224, 128, 2, 41, gamestate.drops); - -#ifdef KEEN4 - VWB_Bar(79, 143, 66, 10, TEXTBACK); - PrintY = 144; - WindowX = 80; - WindowW = 64; - if (gamestate.wetsuit) - { - US_CPrint("Wetsuit"); - } - else - { - US_CPrint("???"); - } -#endif - - // draw the tiles for "PRESS A KEY": - for (i = 0; i < 10; i++) - { - VWB_DrawTile8(i*8+STATUS_PRESSKEY_X, 140, i+72); - VWB_DrawTile8(i*8+STATUS_PRESSKEY_X, 148, i+82); - } -} - -/* -================== -= -= ScrollStatusWindow -= -================== -*/ - -void ScrollStatusWindow(void) -{ - Uint16 source, dest; - Sint16 height; - - if (vislines > 152) - { - height = vislines - 152; - source = windowofs + panadjust + 8; - dest = bufferofs + panadjust + 8; - VW_ScreenToScreen(source, dest, 192/BYTEPIXELS, height); - VW_ClipDrawMPic((pansx+136)/BYTEPIXELS, -(16-height)+pansy, METALPOLEPICM); - source = windowofs + panadjust + 16*SCREENWIDTH + 8*CHARWIDTH; - dest = bufferofs + panadjust + height*SCREENWIDTH + 8; - height = 152; - } - else - { - source = windowofs + panadjust + (152-vislines)*SCREENWIDTH + 16*SCREENWIDTH + 8*CHARWIDTH; - dest = bufferofs + panadjust + 8; - height = vislines; - } - if (height > 0) - { - VW_ScreenToScreen(source, dest, 192/BYTEPIXELS, height); - } - if (scrollup) - { - height = 168-vislines; - source = masterofs + panadjust + vislines*SCREENWIDTH + 8; - dest = bufferofs + panadjust + vislines*SCREENWIDTH + 8; - VW_ScreenToScreen(source, dest, 192/BYTEPIXELS, height); - height = vislines; - source = windowofs + panadjust + 8 - 24/BYTEPIXELS; - dest = bufferofs + panadjust + 8 - 24/BYTEPIXELS; - if (height > 0) - VW_ScreenToScreen(source, dest, 24/BYTEPIXELS, height); - } - else - { - height = vislines + -72; - if (height > 0) - { - source = windowofs + panadjust + 8 - 24/BYTEPIXELS; - dest = bufferofs + panadjust + 8 - 24/BYTEPIXELS; - if (height > 0) - VW_ScreenToScreen(source, dest, 24/BYTEPIXELS, height); - } - } - if (vislines >= 72) - { - VW_ClipDrawMPic((pansx+40)/BYTEPIXELS, vislines-168+pansy, CORDPICM); - } - VW_UpdateScreen(); -} - -/* -================== -= -= StatusWindow -= -================== -*/ - -void StatusWindow(void) -{ -#if GRMODE == CGAGR - - if (Keyboard[sc_A] && Keyboard[sc_2]) - { - US_CenterWindow(20, 2); - PrintY += 2; - US_Print("Debug keys active"); - VW_UpdateScreen(); - IN_Ack(); - debugok = true; - } - - WindowX = 0; - WindowW = 320; - WindowY = 0; - WindowH = 200; - DrawStatusWindow(); - VW_UpdateScreen(); - IN_ClearKeysDown(); - IN_Ack(); - -#else - - Uint16 oldbufferofs; - - WindowX = 0; - WindowW = 320; - WindowY = 0; - WindowH = 200; - - if (Keyboard[sc_A] && Keyboard[sc_2]) - { - US_CenterWindow(20, 2); - PrintY += 2; - US_Print("Debug keys active"); - VW_UpdateScreen(); - IN_Ack(); - debugok = true; - } - - RF_Refresh(); - RFL_InitAnimList(); - oldbufferofs = bufferofs; - bufferofs = windowofs = RF_FindFreeBuffer(); - VW_ScreenToScreen(displayofs, displayofs, 44, 224); // useless (source and dest offsets are identical) - VW_ScreenToScreen(displayofs, masterofs, 44, 224); - VW_ScreenToScreen(displayofs, bufferofs, 44, 168); - DrawStatusWindow(); - bufferofs = oldbufferofs; - RF_Refresh(); - - SD_PlaySound(SND_SHOWSTATUS); - vislines = 16; - scrollup = false; - RF_SetRefreshHook(ScrollStatusWindow); - - while (true) - { - RF_Refresh(); - if (vislines == 168) - break; - vislines = vislines + tics*8; - if (vislines > 168) - vislines = 168; - } - - RF_Refresh(); - RF_SetRefreshHook(NULL); - IN_ClearKeysDown(); - IN_Ack(); - - SD_PlaySound(SND_HIDESTATUS); - vislines -= 16; - scrollup = true; - RF_SetRefreshHook(ScrollStatusWindow); - - while (true) - { - RF_Refresh(); - if (vislines == 0) - break; - vislines = vislines - tics*8; - if (vislines < 0) - vislines = 0; - } - - RF_SetRefreshHook(NULL); - - scoreobj->x = 0; //force scorebox to redraw? - -#endif -} - -//=========================================================================== - -/* -================== -= -= CenterActor -= -================== -*/ - -void CenterActor(objtype *ob) -{ - Uint16 orgx, orgy; - - centerlevel = 140; - if (ob->x < 152*PIXGLOBAL) - { - orgx = 0; - } - else - { - orgx = ob->x - 152*PIXGLOBAL; - } - if (mapon == 0) - { - if (ob->y < 80*PIXGLOBAL) - { - orgy = 0; - } - else - { - orgy = ob->y - 80*PIXGLOBAL; - } - } - else - { - if (ob->bottom < 140*PIXGLOBAL) - { - orgy = 0; - } - else - { - orgy = ob->bottom - 140*PIXGLOBAL; - } - } - if (!scorescreenkludge) - { - RF_NewPosition(orgx, orgy); - } - -// -// update limits for onscreen and inactivate checks -// - originxtilemax = (originxtile + PORTTILESWIDE) - 1; - originytilemax = (originytile + PORTTILESHIGH) - 1; - inactivateleft = originxtile - INACTIVATEDIST; - if (inactivateleft < 0) - { - inactivateleft = 0; - } - inactivateright = originxtilemax + INACTIVATEDIST; - if (inactivateright < 0) - { - inactivateright = 0; - } - inactivatetop = originytile - INACTIVATEDIST; - if (inactivatetop < 0) - { - inactivatetop = 0; - } - inactivatebottom = originytilemax + INACTIVATEDIST; - if (inactivatebottom < 0) - { - inactivatebottom = 0; - } -} - -//=========================================================================== - -/* -================== -= -= WorldScrollScreen -= -= Scroll if Keen is nearing an edge -= -================== -*/ - -void WorldScrollScreen(objtype *ob) -{ - Sint16 xscroll, yscroll; - - if (keenkilled) - return; - - if (ob->left < originxglobal + 9*TILEGLOBAL) - { - xscroll = ob->left - (originxglobal + 9*TILEGLOBAL); - } - else if (ob->right > originxglobal + 12*TILEGLOBAL) - { - xscroll = ob->right + 16 - (originxglobal + 12*TILEGLOBAL); - } - else - { - xscroll = 0; - } - - if (ob->top < originyglobal + 5*TILEGLOBAL) - { - yscroll = ob->top - (originyglobal + 5*TILEGLOBAL); - } - else if (ob->bottom > originyglobal + 7*TILEGLOBAL) - { - yscroll = ob->bottom - (originyglobal + 7*TILEGLOBAL); - } - else - { - yscroll = 0; - } - - if (!xscroll && !yscroll) - return; - -// -// don't scroll more than one tile per frame -// - if (xscroll >= 0x100) - { - xscroll = 0xFF; - } - else if (xscroll <= -0x100) - { - xscroll = -0xFF; - } - if (yscroll >= 0x100) - { - yscroll = 0xFF; - } - else if (yscroll <= -0x100) - { - yscroll = -0xFF; - } - - RF_Scroll(xscroll, yscroll); - -// -// update limits for onscreen and inactivate checks -// - originxtilemax = (originxtile + PORTTILESWIDE) - 1; - originytilemax = (originytile + PORTTILESHIGH) - 1; - inactivateleft = originxtile - INACTIVATEDIST; - if (inactivateleft < 0) - { - inactivateleft = 0; - } - inactivateright = originxtilemax + INACTIVATEDIST; - if (inactivateright < 0) - { - inactivateright = 0; - } - inactivatetop = originytile - INACTIVATEDIST; - if (inactivatetop < 0) - { - inactivatetop = 0; - } - inactivatebottom = originytilemax + INACTIVATEDIST; - if (inactivatebottom < 0) - { - inactivatebottom = 0; - } -} - -//=========================================================================== - -/* -================== -= -= ScrollScreen -= -= Scroll if Keen is nearing an edge -= Set playstate to ex_completes -= -================== -*/ - -void ScrollScreen(objtype *ob) -{ - Sint16 xscroll, yscroll, pix, speed; - Uint16 bottom; - - if (keenkilled) - return; - -// -// walked off edge of map? -// - if (ob->left < originxmin || ob->right > originxmax + 320*PIXGLOBAL) - { - playstate = ex_completed; - return; - } - -// -// fallen off bottom of world? -// - if (ob->bottom > originymax + 13*TILEGLOBAL) - { - ob->y -= ob->bottom - (originymax + 13*TILEGLOBAL); - SD_PlaySound(SND_PLUMMET); - godmode = false; - KillKeen(); - return; - } - - xscroll=yscroll=0; - - if (ob->x < originxglobal + 9*TILEGLOBAL) - { - xscroll = ob->x - (originxglobal + 9*TILEGLOBAL); - } - else if (ob->x > originxglobal + 12*TILEGLOBAL) - { - xscroll = ob->x - (originxglobal + 12*TILEGLOBAL); - } - - if (ob->state == &s_keenlookup2) - { - if (centerlevel+tics > 167) - { - pix = 167-centerlevel; - } - else - { - pix = tics; - } - centerlevel += pix; - yscroll = CONVERT_PIXEL_TO_GLOBAL(-pix); - } - else if (ob->state == &s_keenlookdown3) - { - if (centerlevel-tics < 33) - { - pix = centerlevel + -33; - } - else - { - pix = tics; - } - centerlevel -= pix; - yscroll = CONVERT_PIXEL_TO_GLOBAL(pix); - } - -#ifdef KEEN6 - if (groundslam) - { - static Sint16 shaketable[] = {0, - -64, -64, -64, 64, 64, 64, - -200, -200, -200, 200, 200, 200, - -250, -250, -250, 250, 250, 250, - -250, -250, -250, 250, 250, 250 - }; - yscroll = yscroll + (bottom - (ob->bottom + shaketable[groundslam])); // BUG: 'bottom' has not been initialized yet! - } - else -#endif - if ( (ob->hitnorth || !ob->needtoclip || ob->state == &s_keenholdon)) - { - if ( ob->state != &s_keenclimbup - && ob->state != &s_keenclimbup2 - && ob->state != &s_keenclimbup3 - && ob->state != &s_keenclimbup4) - { - yscroll += ob->ymove; - bottom = originyglobal + yscroll + CONVERT_PIXEL_TO_GLOBAL(centerlevel); - if (ob->bottom == bottom) - { - // player didn't move, no additional scrolling - } - else - { - if (ob->bottom < bottom) - { - pix = bottom - ob->bottom; - } - else - { - pix = ob->bottom - bottom; - } - speed = CONVERT_PIXEL_TO_GLOBAL(pix) >> 7; - if (speed > 0x30) - { - speed = 0x30; - } - speed *= tics; - if (speed < 0x10) - { - if (pix < 0x10) - { - speed = pix; - } - else - { - speed = 0x10; - } - } - if (ob->bottom < bottom) - { - yscroll -= speed; - } - else - { - yscroll += speed; - } - } - } - } - else - { - centerlevel = 140; - } - - pix = (ob->bottom-32*PIXGLOBAL)-(originyglobal+yscroll); - if (pix < 0) - { - yscroll += pix; - } - pix = (ob->bottom+32*PIXGLOBAL)-(originyglobal+yscroll+200*PIXGLOBAL); - if (pix > 0) - { - yscroll += pix; - } - - if (xscroll == 0 && yscroll == 0) - return; - -// -// don't scroll more than one tile per frame -// - if (xscroll >= 0x100) - { - xscroll = 0xFF; - } - else if (xscroll <= -0x100) - { - xscroll = -0xFF; - } - if (yscroll >= 0x100) - { - yscroll = 0xFF; - } - else if (yscroll <= -0x100) - { - yscroll = -0xFF; - } - RF_Scroll(xscroll, yscroll); - -// -// update limits for onscreen and inactivate checks -// - originxtilemax = (originxtile + PORTTILESWIDE) - 1; - originytilemax = (originytile + PORTTILESHIGH) - 1; - inactivateleft = originxtile - INACTIVATEDIST; - if (inactivateleft < 0) - { - inactivateleft = 0; - } - inactivateright = originxtilemax + INACTIVATEDIST; - if (inactivateright < 0) - { - inactivateright = 0; - } - inactivatetop = originytile - INACTIVATEDIST; - if (inactivatetop < 0) - { - inactivatetop = 0; - } - inactivatebottom = originytilemax + INACTIVATEDIST; - if (inactivatebottom < 0) - { - inactivatebottom = 0; - } -} - -//=========================================================================== - - -/* -############################################################################# - - The objarray data structure - -############################################################################# - -Objarray contains structures for every actor currently playing. The structure -is accessed as a linked list starting at *player, ending when ob->next == -NULL. GetNewObj inserts a new object at the end of the list, meaning that -if an actor spawns another actor, the new one WILL get to think and react the -same frame. RemoveObj unlinks the given object and returns it to the free -list, but does not damage the objects ->next pointer, so if the current object -removes itself, a linked list following loop can still safely get to the -next element. - - - -############################################################################# -*/ - - -/* -========================= -= -= InitObjArray -= -= Call to clear out the entire object list, returning them all to the free -= list. Allocates a special spot for the player. -= -========================= -*/ - -void InitObjArray(void) -{ - Sint16 i; - - for (i=0; iprev; - memset(new, 0, sizeof(*new)); - if (lastobj) - { - lastobj->next = new; - } - new->prev = lastobj; // new->next is allready NULL from memset - - new->active = ac_yes; - new->needtoclip = cl_midclip; - lastobj = new; - - objectcount++; - return 0; -} - -//=========================================================================== - -/* -========================= -= -= RemoveObj -= -= Add the given object back into the free list, and unlink it from it's -= neighbors -= -========================= -*/ - -void RemoveObj(objtype *ob) -{ - if (ob == player) - Quit("RemoveObj: Tried to remove the player!"); - -// -// erase it from the refresh manager -// - RF_RemoveSprite(&ob->sprite); - if (ob->obclass == stunnedobj) - { - RF_RemoveSprite((void **)&ob->temp3); - } - -// -// fix the next object's back link -// - if (ob == lastobj) - { - lastobj = ob->prev; - } - else - { - ob->next->prev = ob->prev; - } - -// -// fix the previous object's forward link -// - ob->prev->next = ob->next; - -// -// add it back in to the free list -// - ob->prev = objfreelist; - objfreelist = ob; -} - -//========================================================================== - -/* -==================== -= -= GivePoints -= -= Grants extra men at 20k,40k,80k,160k,320k -= -==================== -*/ - -void GivePoints(Uint16 points) -{ - gamestate.score += points; - if (!DemoMode && gamestate.score >= gamestate.nextextra) - { - SD_PlaySound(SND_EXTRAKEEN); - gamestate.lives++; - gamestate.nextextra *= 2; - } -} - -//========================================================================== - -/* -=================== -= -= PollControls -= -=================== -*/ - -void PollControls(void) -{ - IN_ReadControl(0, &c); - if (c.yaxis != -1) - upheld = false; - - if (GravisGamepad && !DemoMode) - { - jumpbutton = GravisAction[ga_Jump]; - pogobutton = GravisAction[ga_Pogo]; - firebutton = GravisAction[ga_Fire]; - if (!jumpbutton) - jumpheld = false; - if (!pogobutton) - pogoheld = false; - if (!firebutton) - fireheld = false; - } - else if (oldshooting || DemoMode) - { - if (c.button0 && c.button1) - { - firebutton = true; - jumpbutton = pogobutton = jumpheld = pogoheld = false; - } - else - { - firebutton = fireheld = false; - if (c.button0) - { - jumpbutton = true; - } - else - { - jumpbutton = jumpheld = false; - } - if (c.button1) - { - if (oldfirecount <= 8) - { - oldfirecount = oldfirecount + tics; - } - else - { - pogobutton = true; - } - } - else - { - if (oldfirecount != 0) - { - pogobutton = true; - } - else - { - pogobutton = pogoheld = false; - } - oldfirecount = 0; - } - } - } - else - { - jumpbutton = c.button0; - pogobutton = c.button1; - firebutton = Keyboard[firescan]; - if (!jumpbutton) - jumpheld = false; - if (!pogobutton) - pogoheld = false; - if (!firebutton) - fireheld = false; - } -} - -//========================================================================== - - -/* -================= -= -= StopMusic -= -================= -*/ - -void StopMusic(void) -{ - Sint16 i; - - SD_MusicOff(); - for (i=0; i= ARRAYLENGTH(songs) && num != 0xFFFF) - { - Quit("StartMusic() - bad level number"); - } - -#ifdef FIX_MUSIC_MEMORY_ISSUES - StopMusic(); -#else - SD_MusicOff(); -#endif - -#ifdef KEEN4 - if (num == 0xFFFF) - { - song = WONDER_MUS; - } - else - { - song = songs[num]; - } -#else - song = songs[num]; -#endif - - if (song == -1 || MusicMode != smm_AdLib) - { - return; - } - - MM_BombOnError(false); - CA_CacheAudioChunk(STARTMUSIC+song); - MM_BombOnError(true); - if (mmerror) - { - mmerror = false; - if (!DemoMode) - { - US_CenterWindow(20, 8); - PrintY += 20; - US_CPrint("Insufficient memory\nfor background music!"); - VW_UpdateScreen(); - wasfaded = screenfaded; - if (wasfaded) - { - VW_SetDefaultColors(); - } - IN_ClearKeysDown(); - IN_UserInput(3*TickBase, false); - if (wasfaded) - { - VW_FadeOut(); - } - } - } - else - { -#ifdef FIX_MUSIC_MEMORY_ISSUES - //The current music should be locked, so the memory manager will not - //mess with it when compressing memory blocks in MM_SortMem(). - MM_SetLock(&(memptr)audiosegs[STARTMUSIC+song], true); -#endif - SD_StartMusic((MusicGroup far *)audiosegs[STARTMUSIC+song]); - } -} - -//========================================================================== - - -/* -=================== -= -= PlayLoop -= -=================== -*/ - -void PlayLoop(void) -{ - objtype *check; - - StartMusic(gamestate.mapon); - fireheld = pogoheld = upheld = jumpheld = false; - ingame = true; - playstate = ex_stillplaying; - invincible = keenkilled = oldfirecount = 0; - - CenterActor(player); - - if (DemoMode) - { - US_InitRndT(false); - } - else - { - US_InitRndT(true); - } - TimeCount = lasttimecount = tics = 3; - - do - { - PollControls(); - -// -// go through state changes and propose movements -// - for (obj=player; obj; obj=obj->next) - { - if (!obj->active && obj->tileright >= originxtile-1 - && obj->tileleft <= originxtilemax+1 && obj->tiletop <= originytilemax+1 - && obj->tilebottom >= originytile-1) - { - obj->needtoreact = true; - obj->active = ac_yes; - } - if (obj->active) - { - if (obj->tileright < inactivateleft - || obj->tileleft > inactivateright - || obj->tiletop > inactivatebottom - || obj->tilebottom < inactivatetop) - { - if (obj->active == ac_removable) - { - RemoveObj(obj); - continue; - } - else if (obj->active != ac_allways) - { - if (US_RndT() < tics*2 || screenfaded || loadedgame) - { - RF_RemoveSprite(&obj->sprite); - if (obj->obclass == stunnedobj) - RF_RemoveSprite((void **)&obj->temp3); - obj->active = ac_no; - continue; - } - } - } - StateMachine(obj); - } - } - - if (gamestate.riding) - { - HandleRiding(player); - } - -// -// check for and handle collisions between objects -// - for (obj=player; obj; obj=obj->next) - { - if (obj->active) - { - for (check=obj->next; check; check=check->next) - { - if (!check->active) - { - continue; - } - if (obj->right > check->left && obj->left < check->right - && obj->top < check->bottom && obj->bottom > check->top) - { - if (obj->state->contact) - { - obj->state->contact(obj, check); - } - if (check->state->contact) - { - check->state->contact(check, obj); - } - if (obj->obclass == nothing) //useless -- obclass is NOT set to nothing by RemoveObj - { - break; - } - } - } - } - } - -// -// check intiles -// - if (mapon != 0) - { - CheckInTiles(player); - } - else - { - CheckWorldInTiles(player); - } - -// -// react to whatever happened, and post sprites to the refresh manager -// - for (obj=player; obj; obj=obj->next) - { - if (!obj->active) - { - continue; - } - if (obj->tilebottom >= mapheight-1) - { - if (obj->obclass == keenobj) - { - playstate = ex_died; - } - else - { - RemoveObj(obj); - } - continue; - } - if (obj->needtoreact && obj->state->react) - { - obj->needtoreact = false; - obj->state->react(obj); - } - } - -// -// scroll the screen and update the score box -// -#ifdef KEEN4 - if (mapon != 0 && mapon != 17) -#else - if (mapon != 0) -#endif - { - ScrollScreen(player); - } - else - { - WorldScrollScreen(player); - } - UpdateScore(scoreobj); - if (loadedgame) - { - loadedgame = false; - } - -// -// update the screen and calculate the number of tics it took to execute -// this cycle of events (for adaptive timing of next cycle) -// - RF_Refresh(); - - if (invincible) - { - if ((invincible = invincible - tics) < 0) - invincible = 0; - } - -#ifdef KEEN6 - if (groundslam) - { - if ((groundslam = groundslam - tics) < 0) - groundslam = 0; - } -#endif -// -// single step debug mode -// - if (singlestep) - { - VW_WaitVBL(14); //reduces framerate to 5 fps on VGA or 4.3 fps on EGA cards - lasttimecount = TimeCount; - } -// -// extra VBLs debug mode -// - if (extravbls) - { - VW_WaitVBL(extravbls); - } - -// -// handle user inputs -// - if (DemoMode == demo_Playback) - { - if (!screenfaded && IN_IsUserInput()) - { - playstate = ex_completed; - if (LastScan != sc_F1) - { - LastScan = sc_Space; - } - } - } - else if (DemoMode == demo_PlayDone) - { - playstate = ex_completed; - } - else - { - CheckKeys(); - } - -// -// E-N-D cheat -// - if (Keyboard[sc_E] && Keyboard[sc_N] && Keyboard[sc_D]) - { -#if defined KEEN4 - gamestate.rescued = 7; - playstate = ex_rescued; -#elif defined KEEN5 - playstate = ex_qedbroke; -#elif defined KEEN6 - playstate = ex_molly; -#endif - } - - } while (playstate == ex_stillplaying); - - ingame = false; - StopMusic(); -} \ No newline at end of file