X-Git-Url: http://4ch.mooo.com/gitweb/?p=16.git;a=blobdiff_plain;f=16%2Fkeen456%2FKEEN4-6%2FCK_GAME.C;fp=16%2Fkeen456%2FKEEN4-6%2FCK_GAME.C;h=0000000000000000000000000000000000000000;hp=157bd3f8871ad0dadde1b34e907f68a402b39a6c;hb=a387b1ff6f02e2da93e870a330af886d1c8233da;hpb=7d1948e210bb7b58af0a0412e71f2a0a0a2010af diff --git a/16/keen456/KEEN4-6/CK_GAME.C b/16/keen456/KEEN4-6/CK_GAME.C deleted file mode 100755 index 157bd3f8..00000000 --- a/16/keen456/KEEN4-6/CK_GAME.C +++ /dev/null @@ -1,1009 +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 - -============================================================================= -*/ - -Uint16 fadecount; -Sint16 levelcompleted; -Sint32 chunkcount, chunkmax, handpic; - -/* -============================================================================= - - LOCAL VARIABLES - -============================================================================= -*/ - -void FadeAndUnhook(void); - -//=========================================================================== - -/* -============================ -= -= FreeGraphics -= -============================ -*/ - -void FreeGraphics(void) -{ - Sint16 i; - for (i=STARTSPRITES; inext) - { - if (!CA_FarWrite(handle, (byte far *)ob, sizeof(objtype))) - { - MM_FreePtr(&bigbuffer); - return false; - } - } - MM_FreePtr(&bigbuffer); - return true; -} - -//=========================================================================== - -/* -============================ -= -= LoadTheGame -= -============================ -*/ - -boolean LoadTheGame(Sint16 handle) -{ - Uint16 i; - objtype *prev,*next,*followed; - Uint16 compressed,expanded; - memptr bigbuffer; -#ifdef KEEN5 - Sint16 numfuses; -#endif - - if (!CA_FarRead(handle, (byte far *)&gamestate, sizeof(gamestate))) - return false; - -#ifdef KEEN5 - // - // remember the fuses value for later - SetupGameLevel calls - // ScanInfoPlane, which resets this part of the gamestate - // - numfuses = gamestate.numfuses; -#endif - - ca_levelbit >>= 1; - ca_levelnum--; - SetupGameLevel(false); - if (mmerror) - { - mmerror = false; - US_CenterWindow(20, 8); - PrintY += 20; - US_CPrint("Not enough memory\nto load game!"); - VW_UpdateScreen(); - IN_Ack(); - return false; - } - ca_levelbit <<= 1; - ca_levelnum++; - - expanded = mapwidth * mapheight * 2; - MM_BombOnError(true); //BUG: this should use false to avoid an instant crash - MM_GetPtr(&bigbuffer, expanded); - MM_BombOnError(false); //BUG: this should use true to force an instant crash - if (mmerror) - { - mmerror = false; - US_CenterWindow(20, 8); - PrintY += 20; - US_CPrint("Not enough memory\nto load game!"); - VW_UpdateScreen(); - IN_Ack(); - return false; - } - for (i = 0; i < 3; i++) - { - if (!CA_FarRead(handle, (byte far *)&compressed, sizeof(compressed))) - { - MM_FreePtr(&bigbuffer); - return false; - } - if (!CA_FarRead(handle, (byte far *)bigbuffer, compressed)) - { - MM_FreePtr(&bigbuffer); - return false; - } - CA_RLEWexpand(bigbuffer, mapsegs[i], expanded, RLETAG); - } - MM_FreePtr(&bigbuffer); - - InitObjArray(); - new = player; - prev = new->prev; - next = new->next; - if (!CA_FarRead(handle, (byte far *)new, sizeof(objtype))) - { - return false; - } - new->prev = prev; - new->next = next; - new->needtoreact = true; - new->sprite = NULL; - new = scoreobj; - while (true) - { - prev = new->prev; - next = new->next; - if (!CA_FarRead(handle, (byte far *)new, sizeof(objtype))) - { - return false; - } - followed = new->next; - new->prev = prev; - new->next = next; - new->needtoreact = true; - new->sprite = NULL; - if (new->obclass == stunnedobj) - { - new->temp3 = 0; //clear sprite ptr for the stars - } -#if defined KEEN4 - else if (new->obclass == platformobj) - { - new->temp2 = new->temp3 = 0; //clear sprite ptrs - } -#elif defined KEEN5 - else if (new->obclass == mineobj) - { - new->temp4 = 0; //clear sprite ptr - } - else if (new->obclass == spherefulobj) - { - new->temp1 = new->temp2 = new->temp3 = new->temp4 = 0; //clear sprite ptrs - } -#elif defined KEEN6 - else if (new->obclass == platformobj) - { - new->temp3 = 0; //clear sprite ptr - } -#endif - if (followed) - { - GetNewObj(false); - } - else - { - break; - } - } - scoreobj->temp2 = -1; - scoreobj->temp1 = -1; - scoreobj->temp3 = -1; - scoreobj->temp4 = -1; -#ifdef KEEN5 - gamestate.numfuses = numfuses; // put value from saved game back in place -#endif - return true; -} - -//=========================================================================== - -/* -============================ -= -= ResetGame -= -============================ -*/ - -void ResetGame(void) -{ - NewGame(); - ca_levelnum--; - ca_levelbit >>= 1; - CA_ClearMarks(); - ca_levelbit <<= 1; - ca_levelnum++; -} - -//=========================================================================== - - -/* -========================== -= -= PatchWorldMap -= -= Takes out blocking squares and spawns flags -= -========================== -*/ - -void PatchWorldMap(void) -{ - Uint16 x, y, planeoff, info, level, tag; - Uint16 far *infoptr; - - planeoff = 0; - infoptr = mapsegs[2]; - for (y = 0; y < mapheight; y++) - { - for (x = 0; x < mapwidth; x++, infoptr++, planeoff++) - { - info = *infoptr; - level = info & 0xFF; - if (level >= MINDONELEVEL && level <= MAXDONELEVEL && gamestate.leveldone[level]) - { - tag = info >> 8; - *infoptr = 0; // BUG: infoplane value should only be set to 0 if tag == 0xC0 - if (tag == 0xD0) - { - mapsegs[1][planeoff] = 0; - } - else if (tag == 0xF0) - { -#ifdef KEEN5 - SpawnFlag(x, y); -#else - if (levelcompleted == level) - { - SpawnThrowFlag(x, y); - } - else - { - SpawnFlag(x, y); - } -#endif - } - } - } - } -} - -//=========================================================================== - -/* -========================== -= -= DelayedFade -= -= Fades out and latches FadeAndUnhook onto the refresh -= -========================== -*/ - -void DelayedFade(void) -{ - VW_FadeOut(); - fadecount = 0; - RF_SetRefreshHook(&FadeAndUnhook); -} - -/* -========================== -= -= FadeAndUnhook -= -= Latch this onto the refresh so the screen only gets faded in after two -= refreshes. This lets all actors draw themselves to both pages before -= fading the screen in. -= -========================== -*/ - -void FadeAndUnhook(void) -{ - if (++fadecount == 2) - { - VW_FadeIn(); - RF_SetRefreshHook(NULL); - TimeCount = lasttimecount; // don't adaptively time the fade - } -} - -//=========================================================================== - - -/* -========================== -= -= SetupGameLevel -= -= Load in map mapon and cache everything needed for it -= -========================== -*/ - -void SetupGameLevel(boolean loadnow) -{ -// -// randomize if not a demo -// - if (DemoMode) - { - US_InitRndT(false); - gamestate.difficulty = gd_Normal; - } - else - { - US_InitRndT(true); - } - -// -// load the level header and three map planes -// - CA_CacheMap(gamestate.mapon); - -// -// let the refresh manager set up some variables -// - RF_NewMap(); - -// -// decide which graphics are needed and spawn actors -// - CA_ClearMarks(); - ScanInfoPlane(); - if (mapon == 0) - { - PatchWorldMap(); - } - RF_MarkTileGraphics(); - -// -// have the caching manager load and purge stuff to make sure all marks -// are in memory -// - MM_BombOnError(false); - CA_LoadAllSounds(); - if (loadnow) - { - if (scorescreenkludge) - { - CA_CacheMarks(NULL); - } - else if (DemoMode) - { - CA_CacheMarks("DEMO"); - } -#ifdef KEEN5 - else if (mapon == 0 && player->tiletop > 100) - { - CA_CacheMarks("Keen steps out\nonto Korath III"); - } -#endif - else - { - _fstrcpy(str, levelenter[mapon]); - CA_CacheMarks(str); - } - } - MM_BombOnError(true); - - if (!mmerror && loadnow) - { - DelayedFade(); - } -} - -//=========================================================================== - - -/* -========================== -= -= DialogDraw -= -========================== -*/ - -void DialogDraw(char *title, Uint16 numcache) -{ - Sint16 i; - Uint16 width, height; - Sint32 totalfree; - - totalfree = MM_TotalFree(); - if (totalfree < 2048) - { - handpic = 5; - } - else - { - handpic = 0; - for (i = 0; i < 6; i++) - { - CA_CacheGrChunk(i+KEENCOUNT1PIC); - CA_UnmarkGrChunk(i+KEENCOUNT1PIC); - if (grsegs[i+KEENCOUNT1PIC]) - { - MM_SetPurge(&grsegs[i+KEENCOUNT1PIC], PURGE_FIRST); - } - else - { - mmerror = false; - handpic = 5; - break; - } - } - } - US_CenterWindow(26, 8); - if (grsegs[KEENCOUNT1PIC]) - { - VWB_DrawPic(WindowX, WindowY, KEENCOUNT1PIC); - } - else - { - handpic = 5; - } - CA_UnmarkGrChunk(KEENCOUNT1PIC); //redundant - WindowW -= 48; - WindowX += 48; - SizeText(title, &width, &height); - PrintY += (WindowH-height)/2 - 4; - US_CPrint(title); - VW_UpdateScreen(); - chunkmax = chunkcount = numcache / 6; - if (!chunkmax && !handpic) - { - handpic = 5; - if (grsegs[KEENCOUNT6PIC]) - VWB_DrawPic(WindowX-24, WindowY+40, KEENCOUNT6PIC); - VW_UpdateScreen(); - } -} - -/* -========================== -= -= DialogUpdate -= -========================== -*/ - -void DialogUpdate(void) -{ - if (--chunkcount || handpic > 4) - return; - - chunkcount = chunkmax; - if (grsegs[handpic+KEENCOUNT2PIC]) - { - VWB_DrawPic(WindowX-24, WindowY+40, handpic+KEENCOUNT2PIC); - } - VW_UpdateScreen(); - handpic++; -} - -/* -========================== -= -= DialogFinish -= -========================== -*/ - -void DialogFinish(void) -{ - //this is empty -} - -//========================================================================== - -/* -================== -= -= StartDemoRecord -= -================== -*/ - -void StartDemoRecord(void) -{ - Sint16 level; - boolean esc; - - VW_FixRefreshBuffer(); - US_CenterWindow(30, 3); - PrintY += 6; - US_Print(" Record a demo from level(0-21):"); - VW_UpdateScreen(); - esc = !US_LineInput(px, py, str, NULL, true, 2, 0); - if (!esc) - { - level = atoi(str); - if (level >= 0 && level <= 21) - { - gamestate.mapon = level; - playstate = ex_warped; - IN_StartDemoRecord(0x1000); - } - } -} - -/* -================== -= -= EndDemoRecord -= -================== -*/ - -void EndDemoRecord(void) -{ - Sint16 handle; - boolean esc; - char filename[] = "DEMO?."EXTENSION; - - IN_StopDemo(); - VW_FixRefreshBuffer(); - US_CenterWindow(22, 3); - PrintY += 6; - US_Print(" Save as demo #(0-9):"); - VW_UpdateScreen(); - esc = !US_LineInput(px, py, str, NULL, true, 2, 0); - if (!esc && str[0] >= '0' && str[0] <= '9') - { - filename[4] = str[0]; - handle = open(filename, O_BINARY|O_WRONLY|O_CREAT, S_IFREG|S_IREAD|S_IWRITE); - if (handle == -1) - { - Quit("EndDemoRecord: Cannot write demo file!"); - } - write(handle, &mapon, sizeof(mapon)); - write(handle, &DemoOffset, sizeof(DemoOffset)); - CA_FarWrite(handle, DemoBuffer, DemoOffset); - close(handle); - } - IN_FreeDemoBuffer(); -} - -//========================================================================== - -/* -========================== -= -= HandleDeath -= -========================== -*/ - -void HandleDeath(void) -{ - Uint16 y, color, top, bottom, selection, w, h; - - _fstrcpy(str, levelnames[mapon]); - SizeText(str, &w, &h); - - memset(gamestate.keys, 0, sizeof(gamestate.keys)); - gamestate.lives--; - if (gamestate.lives >= 0) - { - VW_FixRefreshBuffer(); - US_CenterWindow(20, 8); - PrintY += 3; - US_CPrint("You didn't make it past"); - top = PrintY+22; - if (h < 15) - PrintY += 4; - US_CPrint(str); - PrintY = top+2; - US_CPrint("Try Again"); - PrintY += 4; - bottom = PrintY-2; - US_CPrint("Exit to "WORLDMAPNAME); - - IN_ClearKeysDown(); - selection = 0; - while (true) - { - if (selection) - { - y = bottom; - } - else - { - y = top; - } - -// draw select bar - if ((TimeCount / 16) & 1) - { - color = SECONDCOLOR; - } - else - { - color = FIRSTCOLOR; - } - VWB_Hlin(WindowX+4, WindowX+WindowW-4, y, color); - VWB_Hlin(WindowX+4, WindowX+WindowW-4, y+1, color); - VWB_Hlin(WindowX+4, WindowX+WindowW-4, y+12, color); - VWB_Hlin(WindowX+4, WindowX+WindowW-4, y+13, color); - VWB_Vlin(y+1, y+11, WindowX+4, color); - VWB_Vlin(y+1, y+11, WindowX+5, color); - VWB_Vlin(y+1, y+11, WindowX+WindowW-4, color); - VWB_Vlin(y+1, y+11, WindowX+WindowW-5, color); - - VW_UpdateScreen(); - -// erase select bar - VWB_Hlin(WindowX+4, WindowX+WindowW-4, y, WHITE); - VWB_Hlin(WindowX+4, WindowX+WindowW-4, y+1, WHITE); - VWB_Hlin(WindowX+4, WindowX+WindowW-4, y+12, WHITE); - VWB_Hlin(WindowX+4, WindowX+WindowW-4, y+13, WHITE); - VWB_Vlin(y+1, y+11, WindowX+4, WHITE); - VWB_Vlin(y+1, y+11, WindowX+5, WHITE); - VWB_Vlin(y+1, y+11, WindowX+WindowW-4, WHITE); - VWB_Vlin(y+1, y+11, WindowX+WindowW-5, WHITE); - - if (LastScan == sc_Escape) - { - gamestate.mapon = 0; // exit to world map - IN_ClearKeysDown(); - return; - } - - IN_ReadControl(0, &c); - if (c.button0 || c.button1 || LastScan == sc_Return || LastScan == sc_Space) - { - if (selection) - gamestate.mapon = 0; // exit to world map - return; - } - if (c.yaxis == -1 || LastScan == sc_UpArrow) - { - selection = 0; - } - else if (c.yaxis == 1 || LastScan == sc_DownArrow) - { - selection = 1; - } - } - } -} - -//========================================================================== - -/* -============================ -= -= GameLoop -= -= A game has just started (after the cinematic or load game) -= -============================ -*/ - -void GameLoop(void) -{ - Uint16 temp; -#ifdef KEEN6 - Uint16 i; -#endif - -#ifdef KEEN6 - if (!storedemo) - { - if (!US_ManualCheck()) - { - loadedgame = false; - restartgame = gd_Continue; - return; - } - } -#endif - - if (playstate == ex_loadedgame) - { - goto loaded; - } -reset: - gamestate.difficulty = restartgame; - restartgame = gd_Continue; - do - { -startlevel: - SetupGameLevel(true); - if (mmerror) - { - if (gamestate.mapon != 0) - { - mmerror = false; - US_CenterWindow(20, 8); - PrintY += 20; - US_CPrint("Insufficient memory\nto load level!"); - VW_UpdateScreen(); - IN_Ack(); - gamestate.mapon = 0; // exit to world map - SetupGameLevel(true); - } - if (mmerror) - { - Quit("GameLoop: Insufficient memory to load world map!"); - } - } -loaded: - keenkilled = false; - SD_WaitSoundDone(); - - PlayLoop(); - - if (playstate != ex_loadedgame) - { - memset(gamestate.keys, 0, sizeof(gamestate.keys)); -#ifdef KEEN5 - gamestate.keycard = false; -#endif - } - VW_FixRefreshBuffer(); - - if (tedlevel) - { - if (playstate == ex_loadedgame) - { - goto loaded; - } - else if (playstate == ex_died) - { - goto startlevel; - } - else - { - TEDDeath(); - } - } - - levelcompleted = -1; - switch (playstate) - { - case ex_resetgame: - goto reset; - - case ex_loadedgame: - goto loaded; - - case ex_died: - HandleDeath(); - break; - -#if defined KEEN4 - case ex_rescued: - if (mapon != 0) - { - SD_PlaySound(SND_LEVELDONE); - } - levelcompleted = mapon; - gamestate.leveldone[mapon] = true; - RescuedMember(); - if (gamestate.rescued != 8) - { - gamestate.mapon = 0; - } - else - { - FreeGraphics(); - RF_FixOfs(); - VW_FixRefreshBuffer(); - FinaleLayout(); - CheckHighScore(gamestate.score, gamestate.rescued); - return; - } - break; - -#elif defined KEEN5 - case ex_fusebroke: - SD_PlaySound(SND_LEVELDONE); - levelcompleted = mapon; - gamestate.leveldone[mapon] = ex_fusebroke; - FinishedFuse(); - gamestate.mapon = 0; - break; - - case ex_qedbroke: - FreeGraphics(); - RF_FixOfs(); - VW_FixRefreshBuffer(); - FinaleLayout(); - CheckHighScore(gamestate.score, 0); - return; - -#elif defined KEEN6 - case ex_hook: - GotHook(); - goto completed; - - case ex_sandwich: - GotSandwich(); - goto completed; - - case ex_card: - GotPasscard(); - goto completed; - - case ex_molly: - FreeGraphics(); - RF_FixOfs(); - VW_FixRefreshBuffer(); - FinaleLayout(); - goto check_score; - -#endif - case ex_completed: - case ex_foot: - case ex_portout: -completed: - if (mapon != 0) - { - SD_PlaySound(SND_LEVELDONE); - gamestate.mapon = 0; - levelcompleted = mapon; - gamestate.leveldone[mapon] = true; - if (storedemo && mapon == 2) - { - IN_ClearKeysDown(); - return; - } - } - else - { -#if GRMODE != CGAGR - temp = bufferofs; - bufferofs = displayofs; -#endif - US_CenterWindow(26, 8); - PrintY += 25; - US_CPrint("One moment"); -#if GRMODE == CGAGR - VW_UpdateScreen(); -#else - bufferofs = temp; -#endif - } - break; - - case ex_abortgame: - IN_ClearKeysDown(); - return; - } - } while (gamestate.lives >= 0); - - GameOver(); - -check_score: -#if defined KEEN4 - CheckHighScore(gamestate.score, gamestate.rescued); -#else - temp = 0; -#if defined KEEN6 - for (i = 0; i < GAMELEVELS; i++) - { - if (gamestate.leveldone[i]) - temp++; - } -#endif - CheckHighScore(gamestate.score, temp); -#endif -} \ No newline at end of file