1 /* Reconstructed Commander Keen 4-6 Source Code
\r
2 * Copyright (C) 2021 K1n9_Duk3
\r
4 * This file is loosely based on:
\r
5 * Keen Dreams Source Code
\r
6 * Copyright (C) 2014 Javier M. Chavez
\r
8 * This program is free software; you can redistribute it and/or modify
\r
9 * it under the terms of the GNU General Public License as published by
\r
10 * the Free Software Foundation; either version 2 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU General Public License along
\r
19 * with this program; if not, write to the Free Software Foundation, Inc.,
\r
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
25 =============================================================================
\r
29 An Id Software production
\r
31 =============================================================================
\r
37 =============================================================================
\r
41 =============================================================================
\r
47 char str[80], str2[20];
\r
48 boolean storedemo, jerk;
\r
51 =============================================================================
\r
55 =============================================================================
\r
58 //===========================================================================
\r
61 =====================
\r
65 = Calculates width and height of a string that contains line breaks
\r
66 = (Note: only the height is ever used, width is NOT calculated correctly)
\r
68 =====================
\r
71 void SizeText(char *text, Uint16 *width, Uint16 *height)
\r
78 *width = *height = 0;
\r
80 while ((c=*(text++)) != '\0')
\r
83 if (c == '\n' || !*text)
\r
85 USL_MeasureString(strbuf, &w, &h); // BUG: strbuf may not have a terminating '\0' at the end!
\r
96 //===========================================================================
\r
99 ==========================
\r
103 = Shuts down all ID_?? managers
\r
105 ==========================
\r
108 void ShutdownId(void)
\r
120 //===========================================================================
\r
123 ==========================
\r
127 = Load a few things right away
\r
129 ==========================
\r
132 void InitGame(void)
\r
134 static char *ParmStrings[] = {"JERK", ""};
\r
135 void MML_UseSpace (Uint16 segstart, Uint16 seglength);
\r
137 Uint16 segstart,seglength;
\r
140 // Note: The value of the jerk variable is replaced with the value
\r
141 // read from the config file during US_Startup, which means the
\r
142 // JERK parameter has absolutely no effect if a valid config file
\r
143 // exists. The parameter check should be moved to some place after
\r
144 // US_Startup to make it work reliably.
\r
146 for (i=1; i < _argc; i++)
\r
148 if (US_CheckParm(_argv[i], ParmStrings) == 0)
\r
163 US_UpdateTextScreen();
\r
168 US_SetLoadSaveHooks(&LoadTheGame, &SaveTheGame, &ResetGame);
\r
169 drawcachebox = DialogDraw;
\r
170 updatecachebox = DialogUpdate;
\r
171 finishcachebox = DialogFinish;
\r
174 // load in and lock down some basic chunks
\r
179 CA_MarkGrChunk(STARTFONT);
\r
180 CA_MarkGrChunk(STARTTILE8);
\r
181 CA_MarkGrChunk(STARTTILE8M);
\r
182 #if GRMODE == EGAGR
\r
183 CA_MarkGrChunk(CORDPICM);
\r
184 CA_MarkGrChunk(METALPOLEPICM);
\r
187 CA_CacheMarks(NULL);
\r
189 MM_SetLock(&grsegs[STARTFONT], true);
\r
190 MM_SetLock(&grsegs[STARTTILE8], true);
\r
191 MM_SetLock(&grsegs[STARTTILE8M], true);
\r
192 #if GRMODE == EGAGR
\r
193 MM_SetLock(&grsegs[CORDPICM], true);
\r
194 MM_SetLock(&grsegs[METALPOLEPICM], true);
\r
199 US_FinishTextScreen();
\r
202 // reclaim the memory from the linked in text screen
\r
204 segstart = FP_SEG(&introscn);
\r
205 seglength = 4000/16;
\r
206 if (FP_OFF(&introscn))
\r
211 MML_UseSpace (segstart,seglength);
\r
213 VW_SetScreenMode(GRMODE);
\r
214 #if GRMODE == CGAGR
\r
215 VW_ColorBorder(BROWN);
\r
217 VW_ColorBorder(CYAN);
\r
219 VW_ClearVideo(BLACK);
\r
222 //===========================================================================
\r
225 ==========================
\r
229 ==========================
\r
232 void Quit(char *error)
\r
239 CA_CacheGrChunk(ORDERSCREEN);
\r
240 finscreen = (Uint16)grsegs[ORDERSCREEN];
\r
243 // BUG: VW_ClearVideo may brick the system if screenseg is 0
\r
244 // (i.e. VW_SetScreenMode has not been executed) - this may
\r
245 // happen if the code runs into an error during InitGame
\r
246 // (EMS/XMS errors, files not found etc.)
\r
247 VW_ClearVideo(BLACK);
\r
248 VW_SetLineWidth(40);
\r
251 if (error && *error)
\r
257 execlp("TED5.EXE", "TED5.EXE", "/LAUNCH", NULL);
\r
259 else if (US_ParmPresent("windows"))
\r
268 movedata(finscreen, 7, 0xB800, 0, 4000);
\r
270 if (US_ParmPresent("windows"))
\r
279 //===========================================================================
\r
289 void TEDDeath(void)
\r
292 execlp("TED5.EXE", "TED5.EXE", "/LAUNCH", NULL);
\r
293 // BUG: should call exit(1); here in case starting TED5 fails
\r
296 //===========================================================================
\r
306 void CheckMemory(void)
\r
310 if (mminfo.nearheap+mminfo.farheap+mminfo.EMSmem+mminfo.XMSmem >= MINMEMORY)
\r
313 CA_CacheGrChunk (OUTOFMEM);
\r
314 finscreen = (Uint16)grsegs[OUTOFMEM];
\r
316 movedata (finscreen,7,0xb800,0,4000);
\r
321 //===========================================================================
\r
324 =====================
\r
328 =====================
\r
331 void DemoLoop(void)
\r
333 static char *ParmStrings[] = {"easy", "normal", "hard", ""};
\r
335 register Sint16 i, state;
\r
339 // check for launch from ted
\r
344 CA_LoadAllSounds();
\r
345 gamestate.mapon = tedlevelnum;
\r
346 restartgame = gd_Normal;
\r
347 for (i = 1;i < _argc;i++)
\r
349 if ( (level = US_CheckParm(_argv[i],ParmStrings)) == -1)
\r
352 restartgame = level+gd_Easy;
\r
363 playstate = ex_stillplaying;
\r
369 #if GRMODE == CGAGR
\r
388 #if GRMODE == CGAGR
\r
413 while (playstate == ex_resetgame || playstate == ex_loadedgame)
\r
417 if (playstate == ex_resetgame || playstate == ex_loadedgame)
\r
419 continue; // don't show title screen, go directly to GameLoop();
\r
423 // this is completely useless:
\r
424 if (playstate == ex_resetgame || playstate == ex_loadedgame)
\r
433 //===========================================================================
\r
435 #if (GRMODE == EGAGR) && !(defined KEEN6)
\r
437 =====================
\r
441 =====================
\r
444 #define FILE_GR1 GREXT"1."EXTENSION
\r
445 #define FILE_GR2 GREXT"2."EXTENSION
\r
446 #define FILE_GRAPH GREXT"GRAPH."EXTENSION
\r
448 static void CheckCutFile(void)
\r
450 register Sint16 ohandle, ihandle;
\r
455 if ( (handle = open(FILE_GRAPH, O_BINARY|O_RDONLY)) != -1)
\r
460 puts("Combining "FILE_GR1" and "FILE_GR2" into "FILE_GRAPH"...");
\r
461 if (rename(FILE_GR1, FILE_GRAPH) == -1)
\r
463 puts("Can't rename "FILE_GR1"!");
\r
466 if ( (ohandle = open(FILE_GRAPH, O_BINARY|O_APPEND|O_WRONLY)) == -1)
\r
468 puts("Can't open "FILE_GRAPH"!");
\r
471 lseek(ohandle, 0, SEEK_END);
\r
472 if ( (ihandle = open(FILE_GR2, O_BINARY|O_RDONLY)) == -1)
\r
474 puts("Can't find "FILE_GR2"!");
\r
477 size = filelength(ihandle);
\r
478 buffer = farmalloc(32000);
\r
483 CA_FarRead(ihandle, buffer, 32000);
\r
484 CA_FarWrite(ohandle, buffer, 32000);
\r
489 CA_FarRead(ihandle, buffer, size);
\r
490 CA_FarWrite(ohandle, buffer, size);
\r
501 //===========================================================================
\r
505 ==========================
\r
509 ==========================
\r
514 #if (GRMODE == EGAGR) && !(defined KEEN6)
\r
518 if (US_ParmPresent("DEMO"))
\r
521 if (US_ParmPresent("JOYPAD"))
\r
522 joypad = true; // Note: the joypad variable is never used
\r
526 if (NoWait || tedlevel)
\r
530 Quit("Demo loop exited???");
\r