X-Git-Url: http://4ch.mooo.com/gitweb/?p=16.git;a=blobdiff_plain;f=16%2Fkeen456%2FKEEN4-6%2FCK_MAIN.C;fp=16%2Fkeen456%2FKEEN4-6%2FCK_MAIN.C;h=b8e71538541d3410534f2e93563a1c10ce4c8cba;hp=0000000000000000000000000000000000000000;hb=7d1948e210bb7b58af0a0412e71f2a0a0a2010af;hpb=ebc247a0a67daa69a027f31d9d7d9572db765e56 diff --git a/16/keen456/KEEN4-6/CK_MAIN.C b/16/keen456/KEEN4-6/CK_MAIN.C new file mode 100755 index 00000000..b8e71538 --- /dev/null +++ b/16/keen456/KEEN4-6/CK_MAIN.C @@ -0,0 +1,531 @@ +/* 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. + */ + +// CK_MAIN.C +/* +============================================================================= + + COMMANDER KEEN + + An Id Software production + +============================================================================= +*/ + +#include "CK_DEF.H" + +/* +============================================================================= + + GLOBAL VARIABLES + +============================================================================= +*/ + +boolean tedlevel; +Uint16 tedlevelnum; + +char str[80], str2[20]; +boolean storedemo, jerk; + +/* +============================================================================= + + LOCAL VARIABLES + +============================================================================= +*/ + +//=========================================================================== + +/* +===================== += += SizeText += += Calculates width and height of a string that contains line breaks += (Note: only the height is ever used, width is NOT calculated correctly) += +===================== +*/ + +void SizeText(char *text, Uint16 *width, Uint16 *height) +{ + register char *ptr; + char c; + Uint16 w, h; + char strbuf[80]; + + *width = *height = 0; + ptr = &strbuf[0]; + while ((c=*(text++)) != '\0') + { + *(ptr++) = c; + if (c == '\n' || !*text) + { + USL_MeasureString(strbuf, &w, &h); // BUG: strbuf may not have a terminating '\0' at the end! + *height += h; + if (*width < w) + { + *width = w; + } + ptr = &strbuf[0]; + } + } +} + +//=========================================================================== + +/* +========================== += += ShutdownId += += Shuts down all ID_?? managers += +========================== +*/ + +void ShutdownId(void) +{ + US_Shutdown(); + SD_Shutdown(); + IN_Shutdown(); + RF_Shutdown(); + VW_Shutdown(); + CA_Shutdown(); + MM_Shutdown(); +} + + +//=========================================================================== + +/* +========================== += += InitGame += += Load a few things right away += +========================== +*/ + +void InitGame(void) +{ + static char *ParmStrings[] = {"JERK", ""}; + void MML_UseSpace (Uint16 segstart, Uint16 seglength); + + Uint16 segstart,seglength; + Sint16 i; + + // Note: The value of the jerk variable is replaced with the value + // read from the config file during US_Startup, which means the + // JERK parameter has absolutely no effect if a valid config file + // exists. The parameter check should be moved to some place after + // US_Startup to make it work reliably. + + for (i=1; i < _argc; i++) + { + if (US_CheckParm(_argv[i], ParmStrings) == 0) + { + jerk = true; + } + } + + US_TextScreen(); + + MM_Startup(); + VW_Startup(); + RF_Startup(); + IN_Startup(); + SD_Startup(); + US_Startup(); + + US_UpdateTextScreen(); + + CA_Startup(); + US_Setup(); + + US_SetLoadSaveHooks(&LoadTheGame, &SaveTheGame, &ResetGame); + drawcachebox = DialogDraw; + updatecachebox = DialogUpdate; + finishcachebox = DialogFinish; + +// +// load in and lock down some basic chunks +// + + CA_ClearMarks(); + + CA_MarkGrChunk(STARTFONT); + CA_MarkGrChunk(STARTTILE8); + CA_MarkGrChunk(STARTTILE8M); +#if GRMODE == EGAGR + CA_MarkGrChunk(CORDPICM); + CA_MarkGrChunk(METALPOLEPICM); +#endif + + CA_CacheMarks(NULL); + + MM_SetLock(&grsegs[STARTFONT], true); + MM_SetLock(&grsegs[STARTTILE8], true); + MM_SetLock(&grsegs[STARTTILE8M], true); +#if GRMODE == EGAGR + MM_SetLock(&grsegs[CORDPICM], true); + MM_SetLock(&grsegs[METALPOLEPICM], true); +#endif + + fontcolor = WHITE; + + US_FinishTextScreen(); + +// +// reclaim the memory from the linked in text screen +// + segstart = FP_SEG(&introscn); + seglength = 4000/16; + if (FP_OFF(&introscn)) + { + segstart++; + seglength--; + } + MML_UseSpace (segstart,seglength); + + VW_SetScreenMode(GRMODE); +#if GRMODE == CGAGR + VW_ColorBorder(BROWN); +#else + VW_ColorBorder(CYAN); +#endif + VW_ClearVideo(BLACK); +} + +//=========================================================================== + +/* +========================== += += Quit += +========================== +*/ + +void Quit(char *error) +{ + Uint16 finscreen; + + if (!error) + { + CA_SetAllPurge(); + CA_CacheGrChunk(ORDERSCREEN); + finscreen = (Uint16)grsegs[ORDERSCREEN]; + } + + // BUG: VW_ClearVideo may brick the system if screenseg is 0 + // (i.e. VW_SetScreenMode has not been executed) - this may + // happen if the code runs into an error during InitGame + // (EMS/XMS errors, files not found etc.) + VW_ClearVideo(BLACK); + VW_SetLineWidth(40); + + ShutdownId(); + if (error && *error) + { + puts(error); + if (tedlevel) + { + getch(); + execlp("TED5.EXE", "TED5.EXE", "/LAUNCH", NULL); + } + else if (US_ParmPresent("windows")) + { + bioskey(0); + } + exit(1); + } + + if (!NoWait) + { + movedata(finscreen, 7, 0xB800, 0, 4000); + gotoxy(1, 24); + if (US_ParmPresent("windows")) + { + bioskey(0); + } + } + + exit(0); +} + +//=========================================================================== + +/* +================== += += TEDDeath += +================== +*/ + +void TEDDeath(void) +{ + ShutdownId(); + execlp("TED5.EXE", "TED5.EXE", "/LAUNCH", NULL); + // BUG: should call exit(1); here in case starting TED5 fails +} + +//=========================================================================== + +/* +================== += += CheckMemory += +================== +*/ + +void CheckMemory(void) +{ + Uint16 finscreen; + + if (mminfo.nearheap+mminfo.farheap+mminfo.EMSmem+mminfo.XMSmem >= MINMEMORY) + return; + + CA_CacheGrChunk (OUTOFMEM); + finscreen = (Uint16)grsegs[OUTOFMEM]; + ShutdownId(); + movedata (finscreen,7,0xb800,0,4000); + gotoxy (1,24); + exit(1); +} + +//=========================================================================== + +/* +===================== += += DemoLoop += +===================== +*/ + +void DemoLoop(void) +{ + static char *ParmStrings[] = {"easy", "normal", "hard", ""}; + + register Sint16 i, state; + Sint16 level; + +// +// check for launch from ted +// + if (tedlevel) + { + NewGame(); + CA_LoadAllSounds(); + gamestate.mapon = tedlevelnum; + restartgame = gd_Normal; + for (i = 1;i < _argc;i++) + { + if ( (level = US_CheckParm(_argv[i],ParmStrings)) == -1) + continue; + + restartgame = level+gd_Easy; + break; + } + GameLoop(); + TEDDeath(); + } + +// +// demo loop +// + state = 0; + playstate = ex_stillplaying; + while (1) + { + switch (state++) + { + case 0: +#if GRMODE == CGAGR + ShowTitle(); +#else + if (nopan) + { + ShowTitle(); + } + else + { + Terminator(); + } +#endif + break; + + case 1: + RunDemo(0); + break; + + case 2: +#if GRMODE == CGAGR + ShowCredits(); +#else + StarWars(); +#endif + break; + + case 3: + RunDemo(1); + break; + + case 4: + ShowHighScores(); + break; + + case 5: + RunDemo(2); + break; + + case 6: + state = 0; + RunDemo(3); + break; + } + + while (playstate == ex_resetgame || playstate == ex_loadedgame) + { + GameLoop(); + ShowHighScores(); + if (playstate == ex_resetgame || playstate == ex_loadedgame) + { + continue; // don't show title screen, go directly to GameLoop(); + } + ShowTitle(); + /////////////// + // this is completely useless: + if (playstate == ex_resetgame || playstate == ex_loadedgame) + { + continue; + } + /////////////// + } + } +} + +//=========================================================================== + +#if (GRMODE == EGAGR) && !(defined KEEN6) +/* +===================== += += CheckCutFile += +===================== +*/ + +#define FILE_GR1 GREXT"1."EXTENSION +#define FILE_GR2 GREXT"2."EXTENSION +#define FILE_GRAPH GREXT"GRAPH."EXTENSION + +static void CheckCutFile(void) +{ + register Sint16 ohandle, ihandle; + Sint16 handle; + Sint32 size; + void far *buffer; + + if ( (handle = open(FILE_GRAPH, O_BINARY|O_RDONLY)) != -1) + { + close(handle); + return; + } + puts("Combining "FILE_GR1" and "FILE_GR2" into "FILE_GRAPH"..."); + if (rename(FILE_GR1, FILE_GRAPH) == -1) + { + puts("Can't rename "FILE_GR1"!"); + exit(1); + } + if ( (ohandle = open(FILE_GRAPH, O_BINARY|O_APPEND|O_WRONLY)) == -1) + { + puts("Can't open "FILE_GRAPH"!"); + exit(1); + } + lseek(ohandle, 0, SEEK_END); + if ( (ihandle = open(FILE_GR2, O_BINARY|O_RDONLY)) == -1) + { + puts("Can't find "FILE_GR2"!"); + exit(1); + } + size = filelength(ihandle); + buffer = farmalloc(32000); + while (size) + { + if (size > 32000) + { + CA_FarRead(ihandle, buffer, 32000); + CA_FarWrite(ohandle, buffer, 32000); + size -= 32000; + } + else + { + CA_FarRead(ihandle, buffer, size); + CA_FarWrite(ohandle, buffer, size); + size = 0; + } + } + farfree(buffer); + close(ohandle); + close(ihandle); + unlink(FILE_GR2); +} +#endif + +//=========================================================================== + + +/* +========================== += += main += +========================== +*/ + +void main(void) +{ +#if (GRMODE == EGAGR) && !(defined KEEN6) + CheckCutFile(); +#endif + + if (US_ParmPresent("DEMO")) + storedemo = true; + + if (US_ParmPresent("JOYPAD")) + joypad = true; // Note: the joypad variable is never used + + InitGame(); + CheckMemory(); + if (NoWait || tedlevel) + debugok = true; + + DemoLoop(); + Quit("Demo loop exited???"); +} \ No newline at end of file