--- /dev/null
+/* Reconstructed Commander Keen 4-6 Source Code\r
+ * Copyright (C) 2021 K1n9_Duk3\r
+ *\r
+ * This file is primarily based on:\r
+ * Wolfenstein 3-D Source Code\r
+ * Copyright (C) 1992 id Software\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along\r
+ * with this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+ */\r
+\r
+#include "CK_DEF.H"\r
+\r
+/*\r
+=============================================================================\r
+\r
+TEXT FORMATTING COMMANDS\r
+------------------------\r
+^C<hex digit> Change text color\r
+^E[enter] End of layout (all pages)\r
+^G<y>,<x>,<pic>[enter] Draw a graphic and push margins\r
+^P[enter] start new page, must be the first chars in a layout\r
+^L<x>,<y>[ENTER] Locate to a specific spot, x in pixels, y in lines\r
+\r
+=============================================================================\r
+*/\r
+\r
+/*\r
+=============================================================================\r
+\r
+ LOCAL CONSTANTS\r
+\r
+=============================================================================\r
+*/\r
+\r
+#if GRMODE == CGAGR\r
+#ifdef KEEN5\r
+#define BACKCOLOR 2 // CGA magenta\r
+#else\r
+#define BACKCOLOR WHITE\r
+#endif\r
+#else\r
+#define BACKCOLOR RED\r
+#endif\r
+\r
+#define WORDLIMIT 80\r
+#define FONTHEIGHT 10\r
+#define TOPMARGIN 10\r
+#define BOTTOMMARGIN 10\r
+#define LEFTMARGIN 10\r
+#define RIGHTMARGIN 10\r
+#define PICMARGIN 8\r
+#define SPACEWIDTH 7\r
+#define TEXTROWS ((200-TOPMARGIN-BOTTOMMARGIN)/FONTHEIGHT)\r
+#define SCREENPIXWIDTH 320\r
+#define SCREENMID (SCREENPIXWIDTH/2)\r
+\r
+/*\r
+=============================================================================\r
+\r
+ LOCAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+Sint16 pagenum,numpages;\r
+Uint16 leftmargin[TEXTROWS],rightmargin[TEXTROWS];\r
+char far *text;\r
+Uint16 rowon;\r
+Sint16 picx,picy,picnum,picdelay;\r
+boolean layoutdone;\r
+\r
+Sint16 helpmenupos;\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= RipToEOL\r
+=\r
+=====================\r
+*/\r
+\r
+void RipToEOL(void)\r
+{\r
+ while (*text++ != '\n');\r
+}\r
+\r
+\r
+/*\r
+=====================\r
+=\r
+= ParseNumber\r
+=\r
+=====================\r
+*/\r
+\r
+Sint16 ParseNumber(void)\r
+{\r
+ char c, buffer[80];\r
+ char *bufptr;\r
+\r
+//\r
+// scan until a number is found\r
+//\r
+ c = *text;\r
+ while (c < '0' || c > '9')\r
+ c = *++text;\r
+\r
+//\r
+// copy the number out\r
+//\r
+ bufptr = buffer;\r
+ do\r
+ {\r
+ *bufptr = c;\r
+ bufptr++;\r
+ text++;\r
+ c = *text;\r
+ } while (c >= '0' && c <= '9');\r
+ *bufptr = 0;\r
+\r
+ return atoi(buffer);\r
+}\r
+\r
+\r
+/*\r
+=====================\r
+=\r
+= ParsePicCommand\r
+=\r
+= Call with text pointing just after a ^P\r
+= Upon exit text points to the start of next line\r
+=\r
+=====================\r
+*/\r
+\r
+void ParsePicCommand(void)\r
+{\r
+ picy = ParseNumber();\r
+ picx = ParseNumber();\r
+ picnum = ParseNumber();\r
+ RipToEOL();\r
+}\r
+\r
+void ParseTimedCommand(void)\r
+{\r
+ picy = ParseNumber();\r
+ picx = ParseNumber();\r
+ picnum = ParseNumber();\r
+ picdelay = ParseNumber();\r
+ RipToEOL();\r
+}\r
+\r
+/*\r
+=====================\r
+=\r
+= TimedPicCommand\r
+=\r
+= Call with text pointing just after a ^P\r
+= Upon exit text points to the start of next line\r
+=\r
+=====================\r
+*/\r
+\r
+void TimedPicCommand(void)\r
+{\r
+ ParseTimedCommand();\r
+\r
+//\r
+// update the screen, and wait for time delay\r
+//\r
+#if GRMODE == CGAGR\r
+ VW_UpdateScreen();\r
+#else\r
+ VW_WaitVBL(1);\r
+ VW_ScreenToScreen(bufferofs, displayofs, 40, 200);\r
+#endif\r
+\r
+//\r
+// wait for time\r
+//\r
+ TimeCount = 0;\r
+ while (picdelay > TimeCount)\r
+ ;\r
+\r
+//\r
+// draw pic\r
+//\r
+ VWB_DrawPic(picx & ~7, picy, picnum);\r
+}\r
+\r
+\r
+/*\r
+=====================\r
+=\r
+= HandleCommand\r
+=\r
+=====================\r
+*/\r
+\r
+void HandleCommand(void)\r
+{\r
+ Sint16 i,margin,top,bottom;\r
+ Sint16 picwidth,picheight,picmid;\r
+\r
+ switch (toupper(*(++text)))\r
+ {\r
+ case 'B':\r
+ picy = ParseNumber();\r
+ picx = ParseNumber();\r
+ picwidth = ParseNumber();\r
+ picheight = ParseNumber();\r
+ VWB_Bar(picx, picy, picwidth, picheight, BACKCOLOR);\r
+ RipToEOL();\r
+ break;\r
+\r
+ case 'P': // ^P is start of next page, ^E is end of file\r
+ case 'E':\r
+ layoutdone = true;\r
+ text--;\r
+ break;\r
+\r
+ case 'C': // ^c<hex digit> changes text color\r
+ i = toupper(*(++text));\r
+ if (i >= '0' && i <= '9')\r
+ {\r
+ fontcolor = i + 0 - '0';\r
+ }\r
+ else if (i >= 'A' && i <= 'F')\r
+ {\r
+ fontcolor = i + 10 - 'A';\r
+ }\r
+#if GRMODE == CGAGR\r
+ {\r
+ static Sint16 colormap[16] = {2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0};\r
+ // Note: This mapping is a bit problematic for Keen 5 CGA,\r
+ // since some colors get mapped to CGA magenta, which is\r
+ // used as the background color in that version. Luckily\r
+ // those colors aren't used in the Keen 5 texts anyway.\r
+\r
+ fontcolor = colormap[fontcolor];\r
+ }\r
+#endif\r
+ fontcolor ^= BACKCOLOR;\r
+ text++;\r
+ break;\r
+\r
+ case 'L':\r
+ py = ParseNumber();\r
+ rowon = (py - 10)/10;\r
+ py = rowon * 10 + 10;\r
+ px = ParseNumber();\r
+ while (*(text++) != '\n') // scan to end of line\r
+ ;\r
+ break;\r
+\r
+ case 'T': // ^Tyyy,xxx,ppp,ttt waits ttt tics, then draws pic\r
+ TimedPicCommand();\r
+ break;\r
+\r
+ case 'G': // ^Gyyy,xxx,ppp draws graphic\r
+ ParsePicCommand();\r
+ VWB_DrawPic(picx & ~7, picy, picnum);\r
+ picwidth = pictable[picnum-STARTPICS].width * BYTEPIXELS;\r
+ picheight = pictable[picnum-STARTPICS].height;\r
+ picmid = picx + picwidth/2;\r
+ //\r
+ // adjust margins\r
+ //\r
+ if (picmid > SCREENMID)\r
+ {\r
+ margin = picx-PICMARGIN; // new right margin\r
+ }\r
+ else\r
+ {\r
+ margin = picx+picwidth+PICMARGIN; // new left margin\r
+ }\r
+ top = (picy-TOPMARGIN)/FONTHEIGHT;\r
+ if (top < 0)\r
+ {\r
+ top = 0;\r
+ }\r
+ bottom = (picy+picheight-TOPMARGIN)/FONTHEIGHT;\r
+ if (bottom >= TEXTROWS)\r
+ {\r
+ bottom = TEXTROWS-1;\r
+ }\r
+\r
+ for (i=top; i<=bottom; i++)\r
+ {\r
+ if (picmid > SCREENMID)\r
+ {\r
+ rightmargin[i] = margin;\r
+ }\r
+ else\r
+ {\r
+ leftmargin[i] = margin;\r
+ }\r
+ }\r
+\r
+ //\r
+ // adjust this line if needed\r
+ //\r
+ if (leftmargin[rowon] > px)\r
+ {\r
+ px = leftmargin[rowon];\r
+ }\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+/*\r
+=====================\r
+=\r
+= NewLine\r
+=\r
+=====================\r
+*/\r
+\r
+void NewLine(void)\r
+{\r
+ char c;\r
+\r
+ if (++rowon == TEXTROWS)\r
+ {\r
+ //\r
+ // overflowed the page, so skip until next page break\r
+ //\r
+ layoutdone = true;\r
+ do\r
+ {\r
+ if (*text == '^')\r
+ {\r
+ c = toupper(text[1]);\r
+ if (c == 'E' || c == 'P')\r
+ {\r
+ layoutdone = true;\r
+ return;\r
+ }\r
+ }\r
+ text++;\r
+ } while (1);\r
+ }\r
+ px = leftmargin[rowon];\r
+ py += FONTHEIGHT;\r
+}\r
+\r
+\r
+/*\r
+=====================\r
+=\r
+= HandleCtrls\r
+=\r
+=====================\r
+*/\r
+\r
+void HandleCtrls(void)\r
+{\r
+ char c;\r
+\r
+ c = *(text++); // get the character and advance\r
+\r
+ if (c == '\n')\r
+ {\r
+ NewLine();\r
+ return;\r
+ }\r
+}\r
+\r
+/*\r
+=====================\r
+=\r
+= HandleWord\r
+=\r
+=====================\r
+*/\r
+\r
+void HandleWord(void)\r
+{\r
+ Uint16 wwidth, wheight, newpos, wordindex;\r
+ char word[WORDLIMIT];\r
+\r
+ //\r
+ // copy the next word into [word]\r
+ //\r
+ word[0] = *(text++);\r
+ wordindex = 1;\r
+ while (*text > ' ')\r
+ {\r
+ word[wordindex] = *(text++);\r
+ if (++wordindex == WORDLIMIT)\r
+ {\r
+ Quit("PageLayout: Word limit exceeded");\r
+ }\r
+ }\r
+ word[wordindex] = 0; // stick a null at end for C\r
+\r
+ //\r
+ // see if it fits on this line\r
+ //\r
+ VW_MeasurePropString(word, &wwidth, &wheight);\r
+ \r
+ while (rightmargin[rowon] < px+wwidth)\r
+ {\r
+ NewLine();\r
+ if (layoutdone)\r
+ {\r
+ return; // overflowed page\r
+ }\r
+ }\r
+\r
+ //\r
+ // print it\r
+ //\r
+ newpos = px+wwidth;\r
+ VWB_DrawPropString(word);\r
+ px = newpos;\r
+\r
+ //\r
+ // suck up any extra spaces\r
+ //\r
+ while (*text == ' ')\r
+ {\r
+ px += SPACEWIDTH;\r
+ text++;\r
+ }\r
+}\r
+\r
+/*\r
+=====================\r
+=\r
+= PageLayout\r
+=\r
+= Clears the screen, draws the pics on the page, and word wraps the text.\r
+= Returns a pointer to the terminating command\r
+=\r
+=====================\r
+*/\r
+\r
+void PageLayout(boolean shownumber)\r
+{\r
+ Sint16 oldcolor, i;\r
+ char c;\r
+\r
+ oldcolor = fontcolor;\r
+\r
+#if GRMODE == CGAGR\r
+ fontcolor = BLACK^BACKCOLOR;\r
+#else\r
+ fontcolor = YELLOW^BACKCOLOR;\r
+#endif\r
+\r
+//\r
+// clear the screen\r
+//\r
+ VWB_Bar(0, 0, 320, 200, BACKCOLOR);\r
+#ifndef KEEN6\r
+ VWB_DrawPic( 0, 0, H_TOPWINDOWPIC);\r
+ VWB_DrawPic( 0, 8, H_LEFTWINDOWPIC);\r
+ VWB_DrawPic(312, 8, H_RIGHTWINDOWPIC);\r
+ if (shownumber)\r
+ {\r
+ VWB_DrawPic(8, 176, H_BOTTOMINFOPIC);\r
+ }\r
+ else\r
+ {\r
+ VWB_DrawPic(8, 192, H_BOTTOMWINDOWPIC);\r
+ }\r
+#endif\r
+\r
+ for (i=0; i<TEXTROWS; i++)\r
+ {\r
+ leftmargin[i] = LEFTMARGIN;\r
+ rightmargin[i] = SCREENPIXWIDTH-RIGHTMARGIN;\r
+ }\r
+\r
+ px = LEFTMARGIN;\r
+ py = TOPMARGIN;\r
+ rowon = 0;\r
+ layoutdone = false;\r
+\r
+//\r
+// make sure we are starting layout text (^P first command)\r
+//\r
+ while (*text <= ' ')\r
+ {\r
+ text++;\r
+ }\r
+ if (*text != '^' || toupper(*(++text)) != 'P')\r
+ {\r
+ Quit("PageLayout: Text not headed with ^P");\r
+ }\r
+ while (*(text++) != '\n')\r
+ ;\r
+\r
+//\r
+// process text stream\r
+//\r
+ do\r
+ {\r
+ c = *text;\r
+ if (c == '^')\r
+ {\r
+ HandleCommand();\r
+ }\r
+ else if (c <= ' ')\r
+ {\r
+ HandleCtrls();\r
+ }\r
+ else\r
+ {\r
+ HandleWord();\r
+ }\r
+ } while (!layoutdone);\r
+\r
+ pagenum++;\r
+\r
+ if (shownumber)\r
+ {\r
+ strcpy(str, "pg ");\r
+ itoa(pagenum, str2, 10);\r
+ strcat(str, str2);\r
+ strcat(str, " of ");\r
+ itoa(numpages, str2, 10);\r
+ strcat(str, str2);\r
+#if GRMODE == CGAGR\r
+ fontcolor = BLACK^BACKCOLOR;\r
+#else\r
+ fontcolor = LIGHTRED^BACKCOLOR;\r
+#endif\r
+ py = 186;\r
+ px = 218;\r
+ VWB_DrawPropString(str);\r
+ }\r
+\r
+ fontcolor = oldcolor;\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= BackPage\r
+=\r
+= Scans for a previous ^P\r
+=\r
+=====================\r
+*/\r
+\r
+void BackPage(void)\r
+{\r
+ pagenum--;\r
+ do\r
+ {\r
+ text--;\r
+ if (text[0] == '^' && toupper(text[1]) == 'P')\r
+ {\r
+ return;\r
+ }\r
+ } while (1);\r
+}\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=====================\r
+=\r
+= CacheLayoutGraphics\r
+=\r
+= Scans an entire layout file (until a ^E) marking all graphics used, and\r
+= counting pages, then caches the graphics in\r
+=\r
+=====================\r
+*/\r
+void CacheLayoutGraphics(void)\r
+{\r
+ char far *bombpoint, far *textstart;\r
+ char ch;\r
+\r
+ textstart = text;\r
+ bombpoint = text+30000;\r
+ numpages = pagenum = 0;\r
+\r
+#ifndef KEEN6\r
+ CA_MarkGrChunk(H_TOPWINDOWPIC);\r
+ CA_MarkGrChunk(H_LEFTWINDOWPIC);\r
+ CA_MarkGrChunk(H_RIGHTWINDOWPIC);\r
+ CA_MarkGrChunk(H_BOTTOMINFOPIC);\r
+ CA_MarkGrChunk(H_BOTTOMWINDOWPIC);\r
+#endif\r
+\r
+ do\r
+ {\r
+ if (*text == '^')\r
+ {\r
+ ch = toupper(*(++text));\r
+ if (ch == 'P') // start of a page\r
+ {\r
+ numpages++;\r
+ }\r
+ if (ch == 'E') // end of file, so load graphics and return\r
+ {\r
+ CA_CacheMarks(NULL);\r
+ text = textstart;\r
+ return;\r
+ }\r
+ if (ch == 'G') // draw graphic command, so mark graphics\r
+ {\r
+ ParsePicCommand();\r
+ CA_MarkGrChunk(picnum);\r
+ }\r
+ if (ch == 'T') // timed draw graphic command, so mark graphics\r
+ {\r
+ ParseTimedCommand();\r
+ CA_MarkGrChunk(picnum);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ text++;\r
+ }\r
+\r
+ } while (text < bombpoint);\r
+\r
+ Quit("CacheLayoutGraphics: No ^E to terminate file!");\r
+}\r
+\r
+//===========================================================================\r
+\r
+#ifndef KEEN6\r
+/*\r
+=================\r
+=\r
+= HelpMenu\r
+=\r
+=================\r
+*/\r
+Sint16 HelpMenu(void)\r
+{\r
+ CursorInfo cursor;\r
+ ControlInfo control;\r
+ Sint16 ydelta;\r
+ Uint16 key;\r
+\r
+ VWB_Bar(0, 0, 320, 200, BACKCOLOR);\r
+\r
+ CA_CacheGrChunk(H_HELPPIC);\r
+ CA_CacheGrChunk(H_HANDPIC);\r
+ CA_CacheGrChunk(H_TOPWINDOWPIC);\r
+ CA_CacheGrChunk(H_LEFTWINDOWPIC);\r
+ CA_CacheGrChunk(H_RIGHTWINDOWPIC);\r
+ CA_CacheGrChunk(H_BOTTOMWINDOWPIC);\r
+\r
+ VWB_DrawPic( 0, 0, H_TOPWINDOWPIC);\r
+ VWB_DrawPic( 0, 8, H_LEFTWINDOWPIC);\r
+ VWB_DrawPic(312, 8, H_RIGHTWINDOWPIC);\r
+ VWB_DrawPic( 8, 192, H_BOTTOMWINDOWPIC);\r
+ VWB_DrawPic( 96, 8, H_HELPPIC);\r
+\r
+ ydelta = 0;\r
+ IN_ClearKeysDown();\r
+ do\r
+ {\r
+ if (helpmenupos < 0)\r
+ {\r
+ helpmenupos = 0;\r
+ }\r
+#ifdef GOODTIMES\r
+ else if (helpmenupos > 3)\r
+ {\r
+ helpmenupos = 3;\r
+ }\r
+#else\r
+ else if (helpmenupos > 4)\r
+ {\r
+ helpmenupos = 4;\r
+ }\r
+#endif\r
+ VWB_DrawPic(48, 24*helpmenupos+48, H_HANDPIC);\r
+ VW_UpdateScreen();\r
+ VWB_Bar(48, 24*helpmenupos+48, 39, 24, BACKCOLOR);\r
+ IN_ReadControl(0, &control);\r
+ IN_ReadCursor(&cursor);\r
+ if (LastScan)\r
+ {\r
+ key = LastScan;\r
+ IN_ClearKeysDown();\r
+ switch (key)\r
+ {\r
+ case sc_UpArrow:\r
+ helpmenupos--;\r
+ break;\r
+ case sc_DownArrow:\r
+ helpmenupos++;\r
+ break;\r
+ case sc_Enter:\r
+ VW_ClearVideo(BACKCOLOR);\r
+ return helpmenupos;\r
+ case sc_Escape:\r
+ VW_ClearVideo(BACKCOLOR);\r
+ return -1;\r
+ }\r
+ }\r
+ ydelta += cursor.y;\r
+ if (cursor.button0 || cursor.button1 || control.button0 || control.button1)\r
+ {\r
+ VW_ClearVideo(BACKCOLOR);\r
+ return helpmenupos;\r
+ }\r
+ if (ydelta < -40)\r
+ {\r
+ ydelta += 40;\r
+ helpmenupos--;\r
+ }\r
+ else if (ydelta > 40)\r
+ {\r
+ ydelta -= 40;\r
+ helpmenupos++;\r
+ }\r
+ } while (1);\r
+}\r
+\r
+/*\r
+=================\r
+=\r
+= HelpScreens\r
+=\r
+=================\r
+*/\r
+void HelpScreens(void)\r
+{\r
+ static Uint16 layouttable[5] =\r
+ {\r
+ T_HELPART,\r
+ T_CONTRART,\r
+ T_STORYART,\r
+#ifndef GOODTIMES\r
+ T_ORDERART,\r
+#endif\r
+ T_IDART\r
+ };\r
+\r
+ Uint16 olddisplayofs, oldbufferofs, oldfontnumber, temp;\r
+ Sint16 pos;\r
+ boolean newpage;\r
+\r
+ oldfontnumber = fontnumber;\r
+ olddisplayofs = displayofs;\r
+ oldbufferofs = bufferofs;\r
+ fontnumber = 0;\r
+\r
+#if GRMODE == EGAGR\r
+ EGAMAPMASK(15);\r
+#endif\r
+\r
+ CA_UpLevel();\r
+ CA_SetGrPurge();\r
+ VW_ClearVideo(BACKCOLOR);\r
+\r
+#if GRMODE == EGAGR\r
+ RF_FixOfs();\r
+ bufferofs = 0;\r
+ displayofs = 0x8000;\r
+ VW_SetScreen(displayofs, 0);\r
+#endif\r
+\r
+#ifdef KEEN5\r
+ StartMusic(19);\r
+#endif\r
+\r
+ do\r
+ {\r
+ pos = HelpMenu();\r
+\r
+ VW_ClearVideo(BACKCOLOR);\r
+\r
+ if (pos == -1)\r
+ {\r
+ CA_DownLevel();\r
+ IN_ClearKeysDown();\r
+ bufferofs = oldbufferofs;\r
+ displayofs = olddisplayofs;\r
+ fontnumber = oldfontnumber;\r
+ VW_ClearVideo(BACKCOLOR);\r
+ RF_FixOfs();\r
+#ifdef KEEN5\r
+ StopMusic(); // Note: it's safer to call StopMusic BEFORE CA_DownLevel\r
+#endif\r
+ return;\r
+ }\r
+\r
+ pos = layouttable[pos];\r
+ CA_CacheGrChunk(pos);\r
+ text = grsegs[pos];\r
+ CacheLayoutGraphics();\r
+\r
+ newpage = true;\r
+ do\r
+ {\r
+ if (newpage)\r
+ {\r
+ newpage = false;\r
+ PageLayout(true);\r
+#if GRMODE == CGAGR\r
+ VW_UpdateScreen();\r
+#else\r
+ VW_SetScreen(bufferofs, 0);\r
+ temp = displayofs;\r
+ displayofs = bufferofs;\r
+ bufferofs = temp;\r
+#endif\r
+ }\r
+\r
+ LastScan = 0;\r
+ while (!LastScan);\r
+\r
+ switch (LastScan)\r
+ {\r
+ case sc_UpArrow:\r
+ case sc_LeftArrow:\r
+ case sc_PgUp:\r
+ if (pagenum > 1)\r
+ {\r
+ BackPage();\r
+ BackPage();\r
+ newpage = true;\r
+ }\r
+ break;\r
+ case sc_DownArrow:\r
+ case sc_RightArrow:\r
+ case sc_PgDn:\r
+ if (pagenum < numpages)\r
+ {\r
+ newpage = true;\r
+ }\r
+ break;\r
+ }\r
+ } while (LastScan != sc_Escape);\r
+\r
+ MM_FreePtr(&grsegs[pos]);\r
+ IN_ClearKeysDown();\r
+ } while (true);\r
+}\r
+\r
+#endif\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=================\r
+=\r
+= FinaleLayout\r
+=\r
+=================\r
+*/\r
+void FinaleLayout(void)\r
+{\r
+ char _seg *textseg;\r
+ Sint16 i;\r
+\r
+ VW_ClearVideo(BACKCOLOR);\r
+ RF_FixOfs();\r
+ CA_UpLevel();\r
+ CA_SetGrPurge();\r
+ CA_CacheGrChunk(H_FLASHARROW2PIC);\r
+ CA_CacheGrChunk(H_FLASHARROW1PIC);\r
+\r
+#ifdef KEEN5\r
+ if (gamestate.leveldone[13] == ex_fusebroke)\r
+ {\r
+ CA_CacheGrChunk(T_ENDART2);\r
+ textseg = grsegs[T_ENDART2];\r
+ }\r
+ else\r
+ {\r
+ CA_CacheGrChunk(T_ENDART);\r
+ textseg = grsegs[T_ENDART];\r
+ }\r
+#else\r
+ CA_CacheGrChunk(T_ENDART);\r
+ textseg = grsegs[T_ENDART];\r
+#endif\r
+\r
+ text = textseg;\r
+ CacheLayoutGraphics();\r
+\r
+ StartMusic(ENDINGMUSIC);\r
+\r
+ while (pagenum < numpages)\r
+ {\r
+ PageLayout(false);\r
+ IN_ClearKeysDown();\r
+#if GRMODE == CGAGR\r
+ VW_UpdateScreen();\r
+#else\r
+ VW_SetScreen(bufferofs, 0);\r
+#endif\r
+\r
+ do\r
+ {\r
+ VWB_DrawPic(298, 184, H_FLASHARROW1PIC);\r
+#if GRMODE == CGAGR\r
+ VW_UpdateScreen();\r
+#endif\r
+ for (i=0; i<TickBase; i++)\r
+ {\r
+ if (IN_IsUserInput())\r
+ {\r
+ goto nextpage;\r
+ }\r
+ VW_WaitVBL(1);\r
+ }\r
+\r
+ VWB_DrawPic(298, 184, H_FLASHARROW2PIC);\r
+#if GRMODE == CGAGR\r
+ VW_UpdateScreen();\r
+#endif\r
+ for (i=0; i<TickBase; i++)\r
+ {\r
+ if (IN_IsUserInput())\r
+ {\r
+ goto nextpage;\r
+ }\r
+ VW_WaitVBL(1);\r
+ }\r
+ } while (1);\r
+\r
+nextpage:\r
+ ; // Borland C++ 2.0 needs a semicolon here...\r
+ }\r
+\r
+ StopMusic();\r
+\r
+#ifdef KEEN5\r
+ if (gamestate.leveldone[13] == ex_fusebroke)\r
+ {\r
+ MM_FreePtr(&grsegs[T_ENDART2]);\r
+ }\r
+ else\r
+ {\r
+ MM_FreePtr(&grsegs[H_FLASHARROW1PIC]); // BUG! this should free T_ENDART, the arrow should be freed after the else branch!\r
+ }\r
+#else\r
+ MM_FreePtr(&grsegs[T_ENDART]);\r
+ MM_FreePtr(&grsegs[H_FLASHARROW1PIC]);\r
+#endif\r
+ MM_FreePtr(&grsegs[H_FLASHARROW2PIC]);\r
+ CA_DownLevel();\r
+ IN_ClearKeysDown();\r
+#if GRMODE != CGAGR\r
+ VW_ClearVideo(BACKCOLOR);\r
+ RF_FixOfs();\r
+#endif\r
+ CA_FreeGraphics();\r
+}
\ No newline at end of file