Subversion Repositories Kolibri OS

Rev

Rev 8557 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. // WL_INTER.C
  2.  
  3. #include "wl_def.h"
  4. #pragma hdrstop
  5. #define itoa ltoa
  6. LRstruct LevelRatios[LRpack];
  7. int32_t lastBreathTime = 0;
  8.  
  9. void Write (int x, int y, const char *string);
  10.  
  11. //==========================================================================
  12.  
  13. /*
  14. ==================
  15. =
  16. = CLearSplitVWB
  17. =
  18. ==================
  19. */
  20.  
  21. void
  22. ClearSplitVWB (void)
  23. {
  24.     WindowX = 0;
  25.     WindowY = 0;
  26.     WindowW = 320;
  27.     WindowH = 160;
  28. }
  29.  
  30.  
  31. //==========================================================================
  32.  
  33. #ifdef SPEAR
  34. #ifndef SPEARDEMO
  35. ////////////////////////////////////////////////////////
  36. //
  37. // End of Spear of Destiny
  38. //
  39. ////////////////////////////////////////////////////////
  40.  
  41. void
  42. EndScreen (int palette, int screen)
  43. {
  44.     SDL_Color pal[256];
  45.     CA_CacheScreen (screen);
  46.     VW_UpdateScreen ();
  47.     CA_CacheGrChunk (palette);
  48.     VL_ConvertPalette(grsegs[palette], pal, 256);
  49.     VL_FadeIn (0, 255, pal, 30);
  50.     UNCACHEGRCHUNK (palette);
  51.     IN_ClearKeysDown ();
  52.     IN_Ack ();
  53.     VW_FadeOut ();
  54. }
  55.  
  56.  
  57. void
  58. EndSpear (void)
  59. {
  60.     SDL_Color pal[256];
  61.  
  62.     EndScreen (END1PALETTE, ENDSCREEN11PIC);
  63.  
  64.     CA_CacheScreen (ENDSCREEN3PIC);
  65.     VW_UpdateScreen ();
  66.     CA_CacheGrChunk (END3PALETTE);
  67.     VL_ConvertPalette(grsegs[END3PALETTE], pal, 256);
  68.     VL_FadeIn (0, 255, pal, 30);
  69.     UNCACHEGRCHUNK (END3PALETTE);
  70.     fontnumber = 0;
  71.     fontcolor = 0xd0;
  72.     WindowX = 0;
  73.     WindowW = 320;
  74.     PrintX = 0;
  75.     PrintY = 180;
  76.     US_CPrint (STR_ENDGAME1 "\n");
  77.     US_CPrint (STR_ENDGAME2);
  78.     VW_UpdateScreen ();
  79.     IN_UserInput(700);
  80.  
  81.     PrintX = 0;
  82.     PrintY = 180;
  83.     VWB_Bar (0, 180, 320, 20, 0);
  84.     US_CPrint (STR_ENDGAME3 "\n");
  85.     US_CPrint (STR_ENDGAME4);
  86.     VW_UpdateScreen ();
  87.     IN_UserInput(700);
  88.  
  89.     VW_FadeOut ();
  90.  
  91.     EndScreen (END4PALETTE, ENDSCREEN4PIC);
  92.     EndScreen (END5PALETTE, ENDSCREEN5PIC);
  93.     EndScreen (END6PALETTE, ENDSCREEN6PIC);
  94.     EndScreen (END7PALETTE, ENDSCREEN7PIC);
  95.     EndScreen (END8PALETTE, ENDSCREEN8PIC);
  96.     EndScreen (END9PALETTE, ENDSCREEN9PIC);
  97.  
  98.     EndScreen (END2PALETTE, ENDSCREEN12PIC);
  99.  
  100.     MainMenu[savegame].active = 0;
  101. }
  102. #endif
  103. #endif
  104.  
  105. //==========================================================================
  106.  
  107. /*
  108. ==================
  109. =
  110. = Victory
  111. =
  112. ==================
  113. */
  114.  
  115. void
  116. Victory (void)
  117. {
  118. #ifndef SPEARDEMO
  119.     int32_t sec;
  120.     int i, min, kr, sr, tr, x;
  121.     char tempstr[8];
  122.  
  123. #define RATIOX  6
  124. #define RATIOY  14
  125. #define TIMEX   14
  126. #define TIMEY   8
  127.  
  128.  
  129. #ifdef SPEAR
  130.     StartCPMusic (XTHEEND_MUS);
  131.  
  132.     CA_CacheGrChunk (BJCOLLAPSE1PIC);
  133.     CA_CacheGrChunk (BJCOLLAPSE2PIC);
  134.     CA_CacheGrChunk (BJCOLLAPSE3PIC);
  135.     CA_CacheGrChunk (BJCOLLAPSE4PIC);
  136.  
  137.     VWB_Bar (0, 0, 320, 200, VIEWCOLOR);
  138.     VWB_DrawPic (124, 44, BJCOLLAPSE1PIC);
  139.     VW_UpdateScreen ();
  140.     VW_FadeIn ();
  141.     VW_WaitVBL (2 * 70);
  142.     VWB_DrawPic (124, 44, BJCOLLAPSE2PIC);
  143.     VW_UpdateScreen ();
  144.     VW_WaitVBL (105);
  145.     VWB_DrawPic (124, 44, BJCOLLAPSE3PIC);
  146.     VW_UpdateScreen ();
  147.     VW_WaitVBL (105);
  148.     VWB_DrawPic (124, 44, BJCOLLAPSE4PIC);
  149.     VW_UpdateScreen ();
  150.     VW_WaitVBL (3 * 70);
  151.  
  152.     UNCACHEGRCHUNK (BJCOLLAPSE1PIC);
  153.     UNCACHEGRCHUNK (BJCOLLAPSE2PIC);
  154.     UNCACHEGRCHUNK (BJCOLLAPSE3PIC);
  155.     UNCACHEGRCHUNK (BJCOLLAPSE4PIC);
  156.     VL_FadeOut (0, 255, 0, 17, 17, 5);
  157. #endif
  158.  
  159.     StartCPMusic (URAHERO_MUS);
  160.     ClearSplitVWB ();
  161.     CacheLump (LEVELEND_LUMP_START, LEVELEND_LUMP_END);
  162.     CA_CacheGrChunk (STARTFONT);
  163.  
  164. #ifndef SPEAR
  165.     CA_CacheGrChunk (C_TIMECODEPIC);
  166. #endif
  167.  
  168.     VWB_Bar (0, 0, 320, screenHeight / scaleFactor - STATUSLINES + 1, VIEWCOLOR);
  169.     if (bordercol != VIEWCOLOR)
  170.         DrawStatusBorder (VIEWCOLOR);
  171.  
  172. #ifdef JAPAN
  173. #ifndef JAPDEMO
  174.     CA_CacheGrChunk (C_ENDRATIOSPIC);
  175.     VWB_DrawPic (0, 0, C_ENDRATIOSPIC);
  176.     UNCACHEGRCHUNK (C_ENDRATIOSPIC);
  177. #endif
  178. #else
  179.     Write (18, 2, STR_YOUWIN);
  180.  
  181.     Write (TIMEX, TIMEY - 2, STR_TOTALTIME);
  182.  
  183.     Write (12, RATIOY - 2, "averages");
  184.  
  185. #ifdef SPANISH
  186.     Write (RATIOX + 2, RATIOY, STR_RATKILL);
  187.     Write (RATIOX + 2, RATIOY + 2, STR_RATSECRET);
  188.     Write (RATIOX + 2, RATIOY + 4, STR_RATTREASURE);
  189. #else
  190.     Write (RATIOX + 8, RATIOY, STR_RATKILL);
  191.     Write (RATIOX + 4, RATIOY + 2, STR_RATSECRET);
  192.     Write (RATIOX, RATIOY + 4, STR_RATTREASURE);
  193. #endif
  194.  
  195. #endif
  196.  
  197. #ifndef JAPDEMO
  198.     VWB_DrawPic (8, 4, L_BJWINSPIC);
  199. #endif
  200.  
  201.  
  202.     for (kr = sr = tr = sec = i = 0; i < LRpack; i++)
  203.     {
  204.         sec += LevelRatios[i].time;
  205.         kr += LevelRatios[i].kill;
  206.         sr += LevelRatios[i].secret;
  207.         tr += LevelRatios[i].treasure;
  208.     }
  209.  
  210. #ifndef SPEAR
  211.     kr /= LRpack;
  212.     sr /= LRpack;
  213.     tr /= LRpack;
  214. #else
  215.     kr /= 14;
  216.     sr /= 14;
  217.     tr /= 14;
  218. #endif
  219.  
  220.     min = sec / 60;
  221.     sec %= 60;
  222.  
  223.     if (min > 99)
  224.         min = sec = 99;
  225.  
  226.     i = TIMEX * 8 + 1;
  227.     VWB_DrawPic (i, TIMEY * 8, L_NUM0PIC + (min / 10));
  228.     i += 2 * 8;
  229.     VWB_DrawPic (i, TIMEY * 8, L_NUM0PIC + (min % 10));
  230.     i += 2 * 8;
  231.     Write (i / 8, TIMEY, ":");
  232.     i += 1 * 8;
  233.     VWB_DrawPic (i, TIMEY * 8, L_NUM0PIC + (sec / 10));
  234.     i += 2 * 8;
  235.     VWB_DrawPic (i, TIMEY * 8, L_NUM0PIC + (sec % 10));
  236.     VW_UpdateScreen ();
  237.  
  238.     itoa (kr, tempstr, 10);
  239.     x = RATIOX + 24 - (int) strlen(tempstr) * 2;
  240.     Write (x, RATIOY, tempstr);
  241.  
  242.     itoa (sr, tempstr, 10);
  243.     x = RATIOX + 24 - (int) strlen(tempstr) * 2;
  244.     Write (x, RATIOY + 2, tempstr);
  245.  
  246.     itoa (tr, tempstr, 10);
  247.     x = RATIOX + 24 - (int) strlen(tempstr) * 2;
  248.     Write (x, RATIOY + 4, tempstr);
  249.  
  250. #ifndef SPANISH
  251. #ifndef UPLOAD
  252. #ifndef SPEAR
  253.     //
  254.     // TOTAL TIME VERIFICATION CODE
  255.     //
  256.     if (gamestate.difficulty >= gd_medium)
  257.     {
  258.         VWB_DrawPic (30 * 8, TIMEY * 8, C_TIMECODEPIC);
  259.         fontnumber = 0;
  260.         fontcolor = READHCOLOR;
  261.         PrintX = 30 * 8 - 3;
  262.         PrintY = TIMEY * 8 + 8;
  263.         PrintX += 4;
  264.         tempstr[0] = (((min / 10) ^ (min % 10)) ^ 0xa) + 'A';
  265.         tempstr[1] = (int) ((((sec / 10) ^ (sec % 10)) ^ 0xa) + 'A');
  266.         tempstr[2] = (tempstr[0] ^ tempstr[1]) + 'A';
  267.         tempstr[3] = 0;
  268.         US_Print (tempstr);
  269.     }
  270. #endif
  271. #endif
  272. #endif
  273.  
  274.     fontnumber = 1;
  275.  
  276.     VW_UpdateScreen ();
  277.     VW_FadeIn ();
  278.  
  279.     IN_Ack ();
  280.  
  281.     VW_FadeOut ();
  282.     if(screenHeight % 200 != 0)
  283.         VL_ClearScreen(0);
  284.  
  285. #ifndef SPEAR
  286.     UNCACHEGRCHUNK (C_TIMECODEPIC);
  287. #endif
  288.     UnCacheLump (LEVELEND_LUMP_START, LEVELEND_LUMP_END);
  289.  
  290. #ifndef SPEAR
  291.     EndText ();
  292. #else
  293.     EndSpear ();
  294. #endif
  295.  
  296. #endif // SPEARDEMO
  297. }
  298.  
  299.  
  300. //==========================================================================
  301.  
  302. #ifndef JAPAN
  303. /*
  304. ==================
  305. =
  306. = PG13
  307. =
  308. ==================
  309. */
  310.  
  311. void
  312. PG13 (void)
  313. {
  314.     VW_FadeOut ();
  315.     VWB_Bar (0, 0, 320, 200, 0x82);     // background
  316.  
  317.     CA_CacheGrChunk (PG13PIC);
  318.     VWB_DrawPic (216, 110, PG13PIC);
  319.     VW_UpdateScreen ();
  320.  
  321.     UNCACHEGRCHUNK (PG13PIC);
  322.  
  323.     VW_FadeIn ();
  324.     IN_UserInput (TickBase * 7);
  325.  
  326.     VW_FadeOut ();
  327. }
  328. #endif
  329.  
  330.  
  331. //==========================================================================
  332.  
  333. void
  334. Write (int x, int y, const char *string)
  335. {
  336.     static const int alpha[] = { L_NUM0PIC, L_NUM1PIC, L_NUM2PIC, L_NUM3PIC, L_NUM4PIC, L_NUM5PIC,
  337.         L_NUM6PIC, L_NUM7PIC, L_NUM8PIC, L_NUM9PIC, L_COLONPIC, 0, 0, 0, 0, 0, 0, L_APIC, L_BPIC,
  338.         L_CPIC, L_DPIC, L_EPIC, L_FPIC, L_GPIC, L_HPIC, L_IPIC, L_JPIC, L_KPIC,
  339.         L_LPIC, L_MPIC, L_NPIC, L_OPIC, L_PPIC, L_QPIC, L_RPIC, L_SPIC, L_TPIC,
  340.         L_UPIC, L_VPIC, L_WPIC, L_XPIC, L_YPIC, L_ZPIC
  341.     };
  342.  
  343.     int i, ox, nx, ny, len = (int) strlen(string);
  344.     char ch;
  345.  
  346.     ox = nx = x * 8;
  347.     ny = y * 8;
  348.     for (i = 0; i < len; i++)
  349.     {
  350.         if (string[i] == '\n')
  351.         {
  352.             nx = ox;
  353.             ny += 16;
  354.         }
  355.         else
  356.         {
  357.             ch = string[i];
  358.             if (ch >= 'a')
  359.                 ch -= ('a' - 'A');
  360.             ch -= '0';
  361.  
  362.             switch (string[i])
  363.             {
  364.                 case '!':
  365.                     VWB_DrawPic (nx, ny, L_EXPOINTPIC);
  366.                     nx += 8;
  367.                     continue;
  368.  
  369. #ifndef APOGEE_1_0
  370.                 case '\'':
  371.                     VWB_DrawPic (nx, ny, L_APOSTROPHEPIC);
  372.                     nx += 8;
  373.                     continue;
  374. #endif
  375.  
  376.                 case ' ':
  377.                     break;
  378.  
  379.                 case 0x3a:     // ':'
  380.                     VWB_DrawPic (nx, ny, L_COLONPIC);
  381.                     nx += 8;
  382.                     continue;
  383.  
  384.                 case '%':
  385.                     VWB_DrawPic (nx, ny, L_PERCENTPIC);
  386.                     break;
  387.  
  388.                 default:
  389.                     VWB_DrawPic (nx, ny, alpha[ch]);
  390.             }
  391.             nx += 16;
  392.         }
  393.     }
  394. }
  395.  
  396.  
  397. //
  398. // Breathe Mr. BJ!!!
  399. //
  400. void
  401. BJ_Breathe (void)
  402. {
  403.     static int which = 0, max = 10;
  404.     int pics[2] = { L_GUYPIC, L_GUY2PIC };
  405.  
  406.     SDL_Delay(5);
  407.  
  408.     if ((int32_t) GetTimeCount () - lastBreathTime > max)
  409.     {
  410.         which ^= 1;
  411.         VWB_DrawPic (0, 16, pics[which]);
  412.         VW_UpdateScreen ();
  413.         lastBreathTime = GetTimeCount();
  414.         max = 35;
  415.     }
  416. }
  417.  
  418.  
  419.  
  420. /*
  421. ==================
  422. =
  423. = LevelCompleted
  424. =
  425. = Entered with the screen faded out
  426. = Still in split screen mode with the status bar
  427. =
  428. = Exit with the screen faded out
  429. =
  430. ==================
  431. */
  432.  
  433. void
  434. LevelCompleted (void)
  435. {
  436. #define VBLWAIT 30
  437. #define PAR_AMOUNT      500
  438. #define PERCENT100AMT   10000
  439.     typedef struct
  440.     {
  441.         float time;
  442.         char timestr[6];
  443.     } times;
  444.  
  445.     int x, i, min, sec, ratio, kr, sr, tr;
  446.     char tempstr[10];
  447.     int32_t bonus, timeleft = 0;
  448.     times parTimes[] = {
  449. #ifndef SPEAR
  450.         //
  451.         // Episode One Par Times
  452.         //
  453.         {1.5, "01:30"},
  454.         {2, "02:00"},
  455.         {2, "02:00"},
  456.         {3.5, "03:30"},
  457.         {3, "03:00"},
  458.         {3, "03:00"},
  459.         {2.5, "02:30"},
  460.         {2.5, "02:30"},
  461.         {0, "??:??"},           // Boss level
  462.         {0, "??:??"},           // Secret level
  463.  
  464.         //
  465.         // Episode Two Par Times
  466.         //
  467.         {1.5, "01:30"},
  468.         {3.5, "03:30"},
  469.         {3, "03:00"},
  470.         {2, "02:00"},
  471.         {4, "04:00"},
  472.         {6, "06:00"},
  473.         {1, "01:00"},
  474.         {3, "03:00"},
  475.         {0, "??:??"},
  476.         {0, "??:??"},
  477.  
  478.         //
  479.         // Episode Three Par Times
  480.         //
  481.         {1.5, "01:30"},
  482.         {1.5, "01:30"},
  483.         {2.5, "02:30"},
  484.         {2.5, "02:30"},
  485.         {3.5, "03:30"},
  486.         {2.5, "02:30"},
  487.         {2, "02:00"},
  488.         {6, "06:00"},
  489.         {0, "??:??"},
  490.         {0, "??:??"},
  491.  
  492.         //
  493.         // Episode Four Par Times
  494.         //
  495.         {2, "02:00"},
  496.         {2, "02:00"},
  497.         {1.5, "01:30"},
  498.         {1, "01:00"},
  499.         {4.5, "04:30"},
  500.         {3.5, "03:30"},
  501.         {2, "02:00"},
  502.         {4.5, "04:30"},
  503.         {0, "??:??"},
  504.         {0, "??:??"},
  505.  
  506.         //
  507.         // Episode Five Par Times
  508.         //
  509.         {2.5, "02:30"},
  510.         {1.5, "01:30"},
  511.         {2.5, "02:30"},
  512.         {2.5, "02:30"},
  513.         {4, "04:00"},
  514.         {3, "03:00"},
  515.         {4.5, "04:30"},
  516.         {3.5, "03:30"},
  517.         {0, "??:??"},
  518.         {0, "??:??"},
  519.  
  520.         //
  521.         // Episode Six Par Times
  522.         //
  523.         {6.5, "06:30"},
  524.         {4, "04:00"},
  525.         {4.5, "04:30"},
  526.         {6, "06:00"},
  527.         {5, "05:00"},
  528.         {5.5, "05:30"},
  529.         {5.5, "05:30"},
  530.         {8.5, "08:30"},
  531.         {0, "??:??"},
  532.         {0, "??:??"}
  533. #else
  534.         //
  535.         // SPEAR OF DESTINY TIMES
  536.         //
  537.         {1.5, "01:30"},
  538.         {3.5, "03:30"},
  539.         {2.75, "02:45"},
  540.         {3.5, "03:30"},
  541.         {0, "??:??"},           // Boss 1
  542.         {4.5, "04:30"},
  543.         {3.25, "03:15"},
  544.         {2.75, "02:45"},
  545.         {4.75, "04:45"},
  546.         {0, "??:??"},           // Boss 2
  547.         {6.5, "06:30"},
  548.         {4.5, "04:30"},
  549.         {2.75, "02:45"},
  550.         {4.5, "04:30"},
  551.         {6, "06:00"},
  552.         {0, "??:??"},           // Boss 3
  553.         {6, "06:00"},
  554.         {0, "??:??"},           // Boss 4
  555.         {0, "??:??"},           // Secret level 1
  556.         {0, "??:??"},           // Secret level 2
  557. #endif
  558.     };
  559.  
  560.     CacheLump (LEVELEND_LUMP_START, LEVELEND_LUMP_END);
  561.     ClearSplitVWB ();           // set up for double buffering in split screen
  562.     VWB_Bar (0, 0, 320, screenHeight / scaleFactor - STATUSLINES + 1, VIEWCOLOR);
  563.  
  564.     if (bordercol != VIEWCOLOR)
  565.         DrawStatusBorder (VIEWCOLOR);
  566.  
  567.     StartCPMusic (ENDLEVEL_MUS);
  568.  
  569. //
  570. // do the intermission
  571. //
  572.     IN_ClearKeysDown ();
  573.     IN_StartAck ();
  574.  
  575. #ifdef JAPAN
  576.     CA_CacheGrChunk (C_INTERMISSIONPIC);
  577.     VWB_DrawPic (0, 0, C_INTERMISSIONPIC);
  578.     UNCACHEGRCHUNK (C_INTERMISSIONPIC);
  579. #endif
  580.     VWB_DrawPic (0, 16, L_GUYPIC);
  581.  
  582. #ifndef SPEAR
  583.     if (mapon < 8)
  584. #else
  585.     if (mapon != 4 && mapon != 9 && mapon != 15 && mapon < 17)
  586. #endif
  587.     {
  588. #ifndef JAPAN
  589. #ifdef SPANISH
  590.         Write (14, 2, "piso\ncompletado");
  591. #else
  592.         Write (14, 2, "floor\ncompleted");
  593. #endif
  594.  
  595.         Write (14, 7, STR_BONUS "     0");
  596.         Write (16, 10, STR_TIME);
  597.         Write (16, 12, STR_PAR);
  598.  
  599. #ifdef SPANISH
  600.         Write (11, 14, STR_RAT2KILL);
  601.         Write (11, 16, STR_RAT2SECRET);
  602.         Write (11, 18, STR_RAT2TREASURE);
  603. #else
  604.         Write (9, 14, STR_RAT2KILL);
  605.         Write (5, 16, STR_RAT2SECRET);
  606.         Write (1, 18, STR_RAT2TREASURE);
  607. #endif
  608.  
  609.         Write (26, 2, itoa (gamestate.mapon + 1, tempstr, 10));
  610. #endif
  611.  
  612. #ifdef SPANISH
  613.         Write (30, 12, parTimes[gamestate.episode * 10 + mapon].timestr);
  614. #else
  615.         Write (26, 12, parTimes[gamestate.episode * 10 + mapon].timestr);
  616. #endif
  617.  
  618.         //
  619.         // PRINT TIME
  620.         //
  621.         sec = gamestate.TimeCount / 70;
  622.  
  623.         if (sec > 99 * 60)      // 99 minutes max
  624.             sec = 99 * 60;
  625.  
  626.         if (gamestate.TimeCount < parTimes[gamestate.episode * 10 + mapon].time * 4200)
  627.             timeleft = (int32_t) ((parTimes[gamestate.episode * 10 + mapon].time * 4200) / 70 - sec);
  628.  
  629.         min = sec / 60;
  630.         sec %= 60;
  631.  
  632. #ifdef SPANISH
  633.         i = 30 * 8;
  634. #else
  635.         i = 26 * 8;
  636. #endif
  637.         VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (min / 10));
  638.         i += 2 * 8;
  639.         VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (min % 10));
  640.         i += 2 * 8;
  641.         Write (i / 8, 10, ":");
  642.         i += 1 * 8;
  643.         VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (sec / 10));
  644.         i += 2 * 8;
  645.         VWB_DrawPic (i, 10 * 8, L_NUM0PIC + (sec % 10));
  646.  
  647.         VW_UpdateScreen ();
  648.         VW_FadeIn ();
  649.  
  650.  
  651.         //
  652.         // FIGURE RATIOS OUT BEFOREHAND
  653.         //
  654.         kr = sr = tr = 0;
  655.         if (gamestate.killtotal)
  656.             kr = (gamestate.killcount * 100) / gamestate.killtotal;
  657.         if (gamestate.secrettotal)
  658.             sr = (gamestate.secretcount * 100) / gamestate.secrettotal;
  659.         if (gamestate.treasuretotal)
  660.             tr = (gamestate.treasurecount * 100) / gamestate.treasuretotal;
  661.  
  662.  
  663.         //
  664.         // PRINT TIME BONUS
  665.         //
  666.         bonus = timeleft * PAR_AMOUNT;
  667.         if (bonus)
  668.         {
  669.             for (i = 0; i <= timeleft; i++)
  670.             {
  671.                 ltoa ((int32_t) i * PAR_AMOUNT, tempstr, 10);
  672.                 x = 36 - (int) strlen(tempstr) * 2;
  673.                 Write (x, 7, tempstr);
  674.                 if (!(i % (PAR_AMOUNT / 10)))
  675.                     SD_PlaySound (ENDBONUS1SND);
  676.                 if(!usedoublebuffering || !(i % (PAR_AMOUNT / 50))) VW_UpdateScreen ();
  677.                 while(SD_SoundPlaying ())
  678.                     BJ_Breathe ();
  679.                 if (IN_CheckAck ())
  680.                     goto done;
  681.             }
  682.  
  683.             VW_UpdateScreen ();
  684.  
  685.             SD_PlaySound (ENDBONUS2SND);
  686.             while (SD_SoundPlaying ())
  687.                 BJ_Breathe ();
  688.         }
  689.  
  690.  
  691. #ifdef SPANISH
  692. #define RATIOXX                33
  693. #else
  694. #define RATIOXX                37
  695. #endif
  696.         //
  697.         // KILL RATIO
  698.         //
  699.         ratio = kr;
  700.         for (i = 0; i <= ratio; i++)
  701.         {
  702.             itoa (i, tempstr, 10);
  703.             x = RATIOXX - (int) strlen(tempstr) * 2;
  704.             Write (x, 14, tempstr);
  705.             if (!(i % 10))
  706.                 SD_PlaySound (ENDBONUS1SND);
  707.             if(!usedoublebuffering || !(i & 1)) VW_UpdateScreen ();
  708.             while (SD_SoundPlaying ())
  709.                 BJ_Breathe ();
  710.  
  711.             if (IN_CheckAck ())
  712.                 goto done;
  713.         }
  714.         if (ratio >= 100)
  715.         {
  716.             VW_WaitVBL (VBLWAIT);
  717.             SD_StopSound ();
  718.             bonus += PERCENT100AMT;
  719.             ltoa (bonus, tempstr, 10);
  720.             x = (RATIOXX - 1) - (int) strlen(tempstr) * 2;
  721.             Write (x, 7, tempstr);
  722.             VW_UpdateScreen ();
  723.             SD_PlaySound (PERCENT100SND);
  724.         }
  725.         else if (!ratio)
  726.         {
  727.             VW_WaitVBL (VBLWAIT);
  728.             SD_StopSound ();
  729.             SD_PlaySound (NOBONUSSND);
  730.         }
  731.         else
  732.             SD_PlaySound (ENDBONUS2SND);
  733.  
  734.         VW_UpdateScreen ();
  735.         while (SD_SoundPlaying ())
  736.             BJ_Breathe ();
  737.  
  738.         //
  739.         // SECRET RATIO
  740.         //
  741.         ratio = sr;
  742.         for (i = 0; i <= ratio; i++)
  743.         {
  744.             itoa (i, tempstr, 10);
  745.             x = RATIOXX - (int) strlen(tempstr) * 2;
  746.             Write (x, 16, tempstr);
  747.             if (!(i % 10))
  748.                 SD_PlaySound (ENDBONUS1SND);
  749.             if(!usedoublebuffering || !(i & 1)) VW_UpdateScreen ();
  750.             while (SD_SoundPlaying ())
  751.                 BJ_Breathe ();
  752.  
  753.             if (IN_CheckAck ())
  754.                 goto done;
  755.         }
  756.         if (ratio >= 100)
  757.         {
  758.             VW_WaitVBL (VBLWAIT);
  759.             SD_StopSound ();
  760.             bonus += PERCENT100AMT;
  761.             ltoa (bonus, tempstr, 10);
  762.             x = (RATIOXX - 1) - (int) strlen(tempstr) * 2;
  763.             Write (x, 7, tempstr);
  764.             VW_UpdateScreen ();
  765.             SD_PlaySound (PERCENT100SND);
  766.         }
  767.         else if (!ratio)
  768.         {
  769.             VW_WaitVBL (VBLWAIT);
  770.             SD_StopSound ();
  771.             SD_PlaySound (NOBONUSSND);
  772.         }
  773.         else
  774.             SD_PlaySound (ENDBONUS2SND);
  775.         VW_UpdateScreen ();
  776.         while (SD_SoundPlaying ())
  777.             BJ_Breathe ();
  778.  
  779.         //
  780.         // TREASURE RATIO
  781.         //
  782.         ratio = tr;
  783.         for (i = 0; i <= ratio; i++)
  784.         {
  785.             itoa (i, tempstr, 10);
  786.             x = RATIOXX - (int) strlen(tempstr) * 2;
  787.             Write (x, 18, tempstr);
  788.             if (!(i % 10))
  789.                 SD_PlaySound (ENDBONUS1SND);
  790.             if(!usedoublebuffering || !(i & 1)) VW_UpdateScreen ();
  791.             while (SD_SoundPlaying ())
  792.                 BJ_Breathe ();
  793.             if (IN_CheckAck ())
  794.                 goto done;
  795.         }
  796.         if (ratio >= 100)
  797.         {
  798.             VW_WaitVBL (VBLWAIT);
  799.             SD_StopSound ();
  800.             bonus += PERCENT100AMT;
  801.             ltoa (bonus, tempstr, 10);
  802.             x = (RATIOXX - 1) - (int) strlen(tempstr) * 2;
  803.             Write (x, 7, tempstr);
  804.             VW_UpdateScreen ();
  805.             SD_PlaySound (PERCENT100SND);
  806.         }
  807.         else if (!ratio)
  808.         {
  809.             VW_WaitVBL (VBLWAIT);
  810.             SD_StopSound ();
  811.             SD_PlaySound (NOBONUSSND);
  812.         }
  813.         else
  814.             SD_PlaySound (ENDBONUS2SND);
  815.         VW_UpdateScreen ();
  816.         while (SD_SoundPlaying ())
  817.             BJ_Breathe ();
  818.  
  819.  
  820.         //
  821.         // JUMP STRAIGHT HERE IF KEY PRESSED
  822.         //
  823. done:   itoa (kr, tempstr, 10);
  824.         x = RATIOXX - (int) strlen(tempstr) * 2;
  825.         Write (x, 14, tempstr);
  826.  
  827.         itoa (sr, tempstr, 10);
  828.         x = RATIOXX - (int) strlen(tempstr) * 2;
  829.         Write (x, 16, tempstr);
  830.  
  831.         itoa (tr, tempstr, 10);
  832.         x = RATIOXX - (int) strlen(tempstr) * 2;
  833.         Write (x, 18, tempstr);
  834.  
  835.         bonus = (int32_t) timeleft *PAR_AMOUNT +
  836.             (PERCENT100AMT * (kr >= 100)) +
  837.             (PERCENT100AMT * (sr >= 100)) + (PERCENT100AMT * (tr >= 100));
  838.  
  839.         GivePoints (bonus);
  840.         ltoa (bonus, tempstr, 10);
  841.         x = 36 - (int) strlen(tempstr) * 2;
  842.         Write (x, 7, tempstr);
  843.  
  844.         //
  845.         // SAVE RATIO INFORMATION FOR ENDGAME
  846.         //
  847.         LevelRatios[mapon].kill = kr;
  848.         LevelRatios[mapon].secret = sr;
  849.         LevelRatios[mapon].treasure = tr;
  850.         LevelRatios[mapon].time = min * 60 + sec;
  851.     }
  852.     else
  853.     {
  854. #ifdef SPEAR
  855. #ifndef SPEARDEMO
  856.         switch (mapon)
  857.         {
  858.             case 4:
  859.                 Write (14, 4, " trans\n" " grosse\n" STR_DEFEATED);
  860.                 break;
  861.             case 9:
  862.                 Write (14, 4, "barnacle\n" "wilhelm\n" STR_DEFEATED);
  863.                 break;
  864.             case 15:
  865.                 Write (14, 4, "ubermutant\n" STR_DEFEATED);
  866.                 break;
  867.             case 17:
  868.                 Write (14, 4, " death\n" " knight\n" STR_DEFEATED);
  869.                 break;
  870.             case 18:
  871.                 Write (13, 4, "secret tunnel\n" "    area\n" "  completed!");
  872.                 break;
  873.             case 19:
  874.                 Write (13, 4, "secret castle\n" "    area\n" "  completed!");
  875.                 break;
  876.         }
  877. #endif
  878. #else
  879.         Write (14, 4, "secret floor\n completed!");
  880. #endif
  881.  
  882.         Write (10, 16, "15000 bonus!");
  883.  
  884.         VW_UpdateScreen ();
  885.         VW_FadeIn ();
  886.  
  887.         GivePoints (15000);
  888.     }
  889.  
  890.  
  891.     DrawScore ();
  892.     VW_UpdateScreen ();
  893.  
  894.     lastBreathTime = GetTimeCount();
  895.     IN_StartAck ();
  896.     while (!IN_CheckAck ())
  897.         BJ_Breathe ();
  898.  
  899. //
  900. // done
  901. //
  902. #ifdef SPEARDEMO
  903.     if (gamestate.mapon == 1)
  904.     {
  905.         SD_PlaySound (BONUS1UPSND);
  906.  
  907.         CA_CacheGrChunk (STARTFONT + 1);
  908.         Message ("This concludes your demo\n"
  909.                  "of Spear of Destiny! Now,\n" "go to your local software\n" "store and buy it!");
  910.         UNCACHEGRCHUNK (STARTFONT + 1);
  911.  
  912.         IN_ClearKeysDown ();
  913.         IN_Ack ();
  914.     }
  915. #endif
  916.  
  917. #ifdef JAPDEMO
  918.     if (gamestate.mapon == 3)
  919.     {
  920.         SD_PlaySound (BONUS1UPSND);
  921.  
  922.         CA_CacheGrChunk (STARTFONT + 1);
  923.         Message ("This concludes your demo\n"
  924.                  "of Wolfenstein 3-D! Now,\n" "go to your local software\n" "store and buy it!");
  925.         UNCACHEGRCHUNK (STARTFONT + 1);
  926.  
  927.         IN_ClearKeysDown ();
  928.         IN_Ack ();
  929.     }
  930. #endif
  931.  
  932.     VW_FadeOut ();
  933.     DrawPlayBorder();
  934.  
  935.     UnCacheLump (LEVELEND_LUMP_START, LEVELEND_LUMP_END);
  936. }
  937.  
  938.  
  939.  
  940. //==========================================================================
  941.  
  942.  
  943. /*
  944. =================
  945. =
  946. = PreloadGraphics
  947. =
  948. = Fill the cache up
  949. =
  950. =================
  951. */
  952.  
  953. boolean
  954. PreloadUpdate (unsigned current, unsigned total)
  955. {
  956.     unsigned w = WindowW - scaleFactor * 10;
  957.  
  958.     VWB_BarScaledCoord (WindowX + scaleFactor * 5, WindowY + WindowH - scaleFactor * 3,
  959.         w, scaleFactor * 2, BLACK);
  960.     w = ((int32_t) w * current) / total;
  961.     if (w)
  962.     {
  963.         VWB_BarScaledCoord (WindowX + scaleFactor * 5, WindowY + WindowH - scaleFactor * 3,
  964.             w, scaleFactor * 2, 0x37);       //SECONDCOLOR);
  965.         VWB_BarScaledCoord (WindowX + scaleFactor * 5, WindowY + WindowH - scaleFactor * 3,
  966.             w - scaleFactor * 1, scaleFactor * 1, 0x32);
  967.  
  968.     }
  969.     VW_UpdateScreen ();
  970. //      if (LastScan == sc_Escape)
  971. //      {
  972. //              IN_ClearKeysDown();
  973. //              return(true);
  974. //      }
  975. //      else
  976.     return (false);
  977. }
  978.  
  979. void
  980. PreloadGraphics (void)
  981. {
  982.     DrawLevel ();
  983.     ClearSplitVWB ();           // set up for double buffering in split screen
  984.  
  985.     VWB_BarScaledCoord (0, 0, screenWidth, screenHeight - scaleFactor * (STATUSLINES - 1), bordercol);
  986.     LatchDrawPicScaledCoord ((screenWidth-scaleFactor*224)/16,
  987.         (screenHeight-scaleFactor*(STATUSLINES+48))/2, GETPSYCHEDPIC);
  988.  
  989.     WindowX = (screenWidth - scaleFactor*224)/2;
  990.     WindowY = (screenHeight - scaleFactor*(STATUSLINES+48))/2;
  991.     WindowW = scaleFactor * 28 * 8;
  992.     WindowH = scaleFactor * 48;
  993.  
  994.     VW_UpdateScreen ();
  995.     VW_FadeIn ();
  996.  
  997. //      PM_Preload (PreloadUpdate);
  998.     PreloadUpdate (10, 10);
  999.     IN_UserInput (70);
  1000.     VW_FadeOut ();
  1001.  
  1002.     DrawPlayBorder ();
  1003.     VW_UpdateScreen ();
  1004. }
  1005.  
  1006.  
  1007. //==========================================================================
  1008.  
  1009. /*
  1010. ==================
  1011. =
  1012. = DrawHighScores
  1013. =
  1014. ==================
  1015. */
  1016.  
  1017. void
  1018. DrawHighScores (void)
  1019. {
  1020.     char buffer[16];
  1021. #ifndef SPEAR
  1022.     char *str;
  1023. #ifndef UPLOAD
  1024.     char buffer1[5];
  1025. #endif
  1026. #endif
  1027.     word i, w, h;
  1028.     HighScore *s;
  1029.  
  1030. #ifndef SPEAR
  1031.     CA_CacheGrChunk (HIGHSCORESPIC);
  1032.     CA_CacheGrChunk (STARTFONT);
  1033. #ifndef APOGEE_1_0
  1034.     CA_CacheGrChunk (C_LEVELPIC);
  1035.     CA_CacheGrChunk (C_SCOREPIC);
  1036.     CA_CacheGrChunk (C_NAMEPIC);
  1037. #else
  1038.     CA_CacheGrChunk (C_CODEPIC);
  1039. #endif
  1040.  
  1041.     ClearMScreen ();
  1042.     DrawStripes (10);
  1043.  
  1044.     VWB_DrawPic (48, 0, HIGHSCORESPIC);
  1045.     UNCACHEGRCHUNK (HIGHSCORESPIC);
  1046.  
  1047. #ifndef APOGEE_1_0
  1048.     VWB_DrawPic (4 * 8, 68, C_NAMEPIC);
  1049.     VWB_DrawPic (20 * 8, 68, C_LEVELPIC);
  1050.     VWB_DrawPic (28 * 8, 68, C_SCOREPIC);
  1051. #else
  1052.     VWB_DrawPic(35*8,68,C_CODEPIC);
  1053. #endif
  1054.     fontnumber = 0;
  1055.  
  1056. #else
  1057.     CacheLump (BACKDROP_LUMP_START, BACKDROP_LUMP_END);
  1058.     ClearMScreen ();
  1059.     DrawStripes (10);
  1060.     UnCacheLump (BACKDROP_LUMP_START, BACKDROP_LUMP_END);
  1061.  
  1062.     CacheLump (HIGHSCORES_LUMP_START, HIGHSCORES_LUMP_END);
  1063.     CA_CacheGrChunk (STARTFONT + 1);
  1064.     VWB_DrawPic (0, 0, HIGHSCORESPIC);
  1065.  
  1066.     fontnumber = 1;
  1067. #endif
  1068.  
  1069.  
  1070. #ifndef SPEAR
  1071.     SETFONTCOLOR (15, 0x29);
  1072. #else
  1073.     SETFONTCOLOR (HIGHLIGHT, 0x29);
  1074. #endif
  1075.  
  1076.     for (i = 0, s = Scores; i < MaxScores; i++, s++)
  1077.     {
  1078.         PrintY = 76 + (16 * i);
  1079.  
  1080.         //
  1081.         // name
  1082.         //
  1083. #ifndef SPEAR
  1084.         PrintX = 4 * 8;
  1085. #else
  1086.         PrintX = 16;
  1087. #endif
  1088.         US_Print (s->name);
  1089.  
  1090.         //
  1091.         // level
  1092.         //
  1093.         itoa (s->completed, buffer, 10);
  1094. #ifndef SPEAR
  1095.         for (str = buffer; *str; str++)
  1096.             *str = *str + (129 - '0');  // Used fixed-width numbers (129...)
  1097.         USL_MeasureString (buffer, &w, &h);
  1098.         PrintX = (22 * 8) - w;
  1099. #else
  1100.         USL_MeasureString (buffer, &w, &h);
  1101.         PrintX = 194 - w;
  1102. #endif
  1103.  
  1104. #ifndef UPLOAD
  1105. #ifndef SPEAR
  1106.         PrintX -= 6;
  1107.         itoa (s->episode + 1, buffer1, 10);
  1108.         US_Print ("E");
  1109.         US_Print (buffer1);
  1110.         US_Print ("/L");
  1111. #endif
  1112. #endif
  1113.  
  1114. #ifdef SPEAR
  1115.         if (s->completed == 21)
  1116.             VWB_DrawPic (PrintX + 8, PrintY - 1, C_WONSPEARPIC);
  1117.         else
  1118. #endif
  1119.             US_Print (buffer);
  1120.  
  1121.         //
  1122.         // score
  1123.         //
  1124.         itoa (s->score, buffer, 10);
  1125. #ifndef SPEAR
  1126.         for (str = buffer; *str; str++)
  1127.             *str = *str + (129 - '0');  // Used fixed-width numbers (129...)
  1128.         USL_MeasureString (buffer, &w, &h);
  1129.         PrintX = (34 * 8) - 8 - w;
  1130. #else
  1131.         USL_MeasureString (buffer, &w, &h);
  1132.         PrintX = 292 - w;
  1133. #endif
  1134.         US_Print (buffer);
  1135.  
  1136. #ifdef APOGEE_1_0
  1137. //#ifndef UPLOAD
  1138. #ifndef SPEAR
  1139.         //
  1140.         // verification #
  1141.         //
  1142.         if (!i)
  1143.         {
  1144.             char temp = (((s->score >> 28) & 0xf) ^ ((s->score >> 24) & 0xf)) + 'A';
  1145.             char temp1 = (((s->score >> 20) & 0xf) ^ ((s->score >> 16) & 0xf)) + 'A';
  1146.             char temp2 = (((s->score >> 12) & 0xf) ^ ((s->score >> 8) & 0xf)) + 'A';
  1147.             char temp3 = (((s->score >> 4) & 0xf) ^ ((s->score >> 0) & 0xf)) + 'A';
  1148.  
  1149.             SETFONTCOLOR (0x49, 0x29);
  1150.             PrintX = 35 * 8;
  1151.             buffer[0] = temp;
  1152.             buffer[1] = temp1;
  1153.             buffer[2] = temp2;
  1154.             buffer[3] = temp3;
  1155.             buffer[4] = 0;
  1156.             US_Print (buffer);
  1157.             SETFONTCOLOR (15, 0x29);
  1158.         }
  1159. #endif
  1160. //#endif
  1161. #endif
  1162.     }
  1163.  
  1164.     VW_UpdateScreen ();
  1165.  
  1166. #ifdef SPEAR
  1167.     UnCacheLump (HIGHSCORES_LUMP_START, HIGHSCORES_LUMP_END);
  1168.     fontnumber = 0;
  1169. #endif
  1170. }
  1171.  
  1172. //===========================================================================
  1173.  
  1174.  
  1175. /*
  1176. =======================
  1177. =
  1178. = CheckHighScore
  1179. =
  1180. =======================
  1181. */
  1182.  
  1183. void
  1184. CheckHighScore (int32_t score, word other)
  1185. {
  1186.     word i, j;
  1187.     int n;
  1188.     HighScore myscore;
  1189.  
  1190.     strcpy (myscore.name, "");
  1191.     myscore.score = score;
  1192.     myscore.episode = gamestate.episode;
  1193.     myscore.completed = other;
  1194.  
  1195.     for (i = 0, n = -1; i < MaxScores; i++)
  1196.     {
  1197.         if ((myscore.score > Scores[i].score)
  1198.             || ((myscore.score == Scores[i].score) && (myscore.completed > Scores[i].completed)))
  1199.         {
  1200.             for (j = MaxScores; --j > i;)
  1201.                 Scores[j] = Scores[j - 1];
  1202.             Scores[i] = myscore;
  1203.             n = i;
  1204.             break;
  1205.         }
  1206.     }
  1207.  
  1208. #ifdef SPEAR
  1209.     StartCPMusic (XAWARD_MUS);
  1210. #else
  1211.     StartCPMusic (ROSTER_MUS);
  1212. #endif
  1213.     DrawHighScores ();
  1214.  
  1215.     VW_FadeIn ();
  1216.  
  1217.     if (n != -1)
  1218.     {
  1219.         //
  1220.         // got a high score
  1221.         //
  1222.         PrintY = 76 + (16 * n);
  1223. #ifndef SPEAR
  1224.         PrintX = 4 * 8;
  1225.         backcolor = BORDCOLOR;
  1226.         fontcolor = 15;
  1227.         US_LineInput (PrintX, PrintY, Scores[n].name, 0, true, MaxHighName, 100);
  1228. #else
  1229.         PrintX = 16;
  1230.         fontnumber = 1;
  1231.         VWB_Bar (PrintX - 2, PrintY - 2, 145, 15, 0x9c);
  1232.         VW_UpdateScreen ();
  1233.         backcolor = 0x9c;
  1234.         fontcolor = 15;
  1235.         US_LineInput (PrintX, PrintY, Scores[n].name, 0, true, MaxHighName, 130);
  1236. #endif
  1237.     }
  1238.     else
  1239.     {
  1240.         IN_ClearKeysDown ();
  1241.         IN_UserInput (500);
  1242.     }
  1243.  
  1244. }
  1245.  
  1246.  
  1247. #ifndef UPLOAD
  1248. #ifndef SPEAR
  1249. #ifndef JAPAN
  1250. ////////////////////////////////////////////////////////
  1251. //
  1252. // NON-SHAREWARE NOTICE
  1253. //
  1254. ////////////////////////////////////////////////////////
  1255. void
  1256. NonShareware (void)
  1257. {
  1258.     VW_FadeOut ();
  1259.  
  1260.     ClearMScreen ();
  1261.     DrawStripes (10);
  1262.  
  1263.     CA_CacheGrChunk (STARTFONT + 1);
  1264.     fontnumber = 1;
  1265.  
  1266.     SETFONTCOLOR (READHCOLOR, BKGDCOLOR);
  1267.     PrintX = 110;
  1268.     PrintY = 15;
  1269.  
  1270. #ifdef SPANISH
  1271.     US_Print ("Atencion");
  1272. #else
  1273.     US_Print ("Attention");
  1274. #endif
  1275.  
  1276.     SETFONTCOLOR (HIGHLIGHT, BKGDCOLOR);
  1277.     WindowX = PrintX = 40;
  1278.     PrintY = 60;
  1279. #ifdef SPANISH
  1280.     US_Print ("Este juego NO es gratis y\n");
  1281.     US_Print ("NO es Shareware; favor de\n");
  1282.     US_Print ("no distribuirlo.\n\n");
  1283. #else
  1284.     US_Print ("This game is NOT shareware.\n");
  1285.     US_Print ("Please do not distribute it.\n");
  1286.     US_Print ("Thanks.\n\n");
  1287. #endif
  1288.     US_Print ("        Id Software\n");
  1289.  
  1290.     VW_UpdateScreen ();
  1291.     VW_FadeIn ();
  1292.     IN_Ack ();
  1293. }
  1294. #endif
  1295. #endif
  1296. #endif
  1297.  
  1298. #ifdef SPEAR
  1299. #ifndef GOODTIMES
  1300. #ifndef SPEARDEMO
  1301. ////////////////////////////////////////////////////////
  1302. //
  1303. // COPY PROTECTION FOR FormGen
  1304. //
  1305. ////////////////////////////////////////////////////////
  1306. char CopyProFailedStrs[][100] = {
  1307.     STR_COPY1,
  1308.     STR_COPY2,
  1309.  
  1310.     STR_COPY3,
  1311.     STR_COPY4,
  1312.  
  1313.     STR_COPY5,
  1314.     STR_COPY6,
  1315.  
  1316.     STR_COPY7,
  1317.     STR_COPY8,
  1318.  
  1319.     STR_COPY9,
  1320.     "",
  1321.  
  1322.     STR_COPY10,
  1323.     STR_COPY11,
  1324.  
  1325.     STR_COPY12,
  1326.     "",
  1327.  
  1328.     STR_COPY13,
  1329.     "",
  1330.  
  1331.     STR_COPY14,
  1332.     ""
  1333. };
  1334.  
  1335. char BackDoorStrs[5][16] = {
  1336.     "a spoon?",
  1337.     "bite me!",
  1338.     "joshua",
  1339.     "pelt",
  1340.     "snoops"
  1341. };
  1342.  
  1343. char GoodBoyStrs[10][40] = {
  1344.     "...is the CORRECT ANSWER!",
  1345.     "",
  1346.  
  1347.     "Consider yourself bitten, sir.",
  1348.     "",
  1349.  
  1350.     "Greetings Professor Falken, would you",
  1351.     "like to play Spear of Destiny?",
  1352.  
  1353.     "Do you have any gold spray paint?",
  1354.     "",
  1355.  
  1356.     "I wish I had a 21\" monitor...",
  1357.     ""
  1358. };
  1359.  
  1360. char bossstrs[4][24] = {
  1361.     "DEATH KNIGHT",
  1362.     "BARNACLE WILHELM",
  1363.     "UBERMUTANTUBER MUTANT",
  1364.     "TRANS GROSSE"
  1365. };
  1366.  
  1367. char WordStr[5][20] = {
  1368.     "New Game",
  1369.     "Sound...F4",
  1370.     "Control...F6",
  1371.     "Change View...F5",
  1372.     "Quit...F10"
  1373. };
  1374.  
  1375. char WordCorrect[5][2] = { "3", "4", "4", "5", "5" };
  1376.  
  1377. char MemberStr[10][40] = {
  1378.     STR_COPY15,
  1379.     "",
  1380.  
  1381.     STR_COPY16,
  1382.     "",
  1383.  
  1384.     STR_COPY17,
  1385.     STR_COPY18,
  1386.  
  1387.     STR_COPY19,
  1388.     STR_COPY20,
  1389.  
  1390.     STR_COPY21,
  1391.     STR_COPY22
  1392. };
  1393.  
  1394. char MemberCorrect[5][24] = {
  1395.     "adrian carmack",
  1396.     "john carmackjohn romero",
  1397.     "tom hall",
  1398.     "jay wilbur",
  1399.     "kevin cloud"
  1400. };
  1401.  
  1402. char DosMessages[9][80] = {
  1403.     STR_NOPE1,
  1404.     STR_NOPE2,
  1405.     STR_NOPE3,
  1406.     STR_NOPE4,
  1407.     STR_NOPE5,
  1408.     STR_NOPE6,
  1409.     STR_NOPE7,
  1410.     STR_NOPE8,
  1411.     STR_NOPE9
  1412. };
  1413.  
  1414. char MiscTitle[4][20] = {
  1415.     "BLOOD TEST",
  1416.     "STRAIGHT-LACED",
  1417.     "QUITE SHAPELY",
  1418.     "I AM WHAT I AMMO"
  1419. };
  1420.  
  1421. char MiscStr[12][40] = {
  1422.     STR_MISC1,
  1423.     STR_MISC2,
  1424.     "",
  1425.  
  1426.     STR_MISC3,
  1427.     STR_MISC4,
  1428.     "",
  1429.  
  1430.     STR_MISC5,
  1431.     STR_MISC6,
  1432.     "",
  1433.  
  1434.     STR_MISC7,
  1435.     STR_MISC8,
  1436.     STR_MISC9
  1437. };
  1438.  
  1439. char MiscCorrect[4][5] = { "ss", "8", STR_STAR, "45" };
  1440.  
  1441.  
  1442. int
  1443. BackDoor (char *s)
  1444. {
  1445.     for (int i = 0; i < 5; i++)
  1446.     {
  1447.         if (!strcasecmp (s, BackDoorStrs[i]))
  1448.         {
  1449.             SETFONTCOLOR (14, 15);
  1450.             fontnumber = 0;
  1451.             PrintY = 175;
  1452.             VWB_DrawPic (0, 20 * 8, COPYPROTBOXPIC);
  1453.             US_CPrint (GoodBoyStrs[i * 2]);
  1454.             US_CPrint (GoodBoyStrs[i * 2 + 1]);
  1455.             VW_UpdateScreen ();
  1456.             return 1;
  1457.         }
  1458.     }
  1459.  
  1460.     return 0;
  1461. }
  1462.  
  1463.  
  1464. void
  1465. CopyProtection (void)
  1466. {
  1467. #define TYPEBOX_Y       177
  1468. #define TYPEBOX_BKGD    0x9c
  1469. #define PRINTCOLOR      HIGHLIGHT
  1470.  
  1471.     unsigned i;
  1472.     int match, whichboss, bossnum, attempt, whichline;
  1473.     int enemypicked[4] = { 0, 0, 0, 0 };
  1474.     int bosses[4] = { BOSSPIC1PIC, BOSSPIC2PIC, BOSSPIC3PIC, BOSSPIC4PIC };
  1475.     int whichpicked[4] = { 0, 0, 0, 0 };
  1476.     int whichone, quiztype, whichmem, whichword;
  1477.     int memberpicked[5] = { 0, 0, 0, 0, 0 };
  1478.     int wordpicked[5] = { 0, 0, 0, 0, 0 };
  1479.  
  1480.     char inputbuffer[20];
  1481.     char message[80];
  1482.  
  1483.     enum
  1484.     {
  1485.         debriefing,
  1486.         checkmanual,
  1487.         staffquiz,
  1488.         miscquiz,
  1489.  
  1490.         totaltypes
  1491.     };
  1492.  
  1493.  
  1494.  
  1495.     attempt = 0;
  1496.     VW_FadeOut ();
  1497.     CA_CacheGrChunk (C_BACKDROPPIC);
  1498.     CacheLump (COPYPROT_LUMP_START, COPYPROT_LUMP_END);
  1499.     CA_CacheGrChunk (STARTFONT + 1);
  1500.     CA_LoadAllSounds ();
  1501.     StartCPMusic (COPYPRO_MUS);
  1502.     US_InitRndT (true);
  1503.  
  1504.     while (attempt < 3)
  1505.     {
  1506.         fontnumber = 1;
  1507.         SETFONTCOLOR (PRINTCOLOR - 2, 15);
  1508.         VWB_DrawPic (0, 0, C_BACKDROPPIC);
  1509.         VWB_DrawPic (0, 0, COPYPROTTOPPIC);
  1510.         VWB_DrawPic (0, 20 * 8, COPYPROTBOXPIC);
  1511.         WindowX = WindowY = 0;
  1512.         WindowW = 320;
  1513.         WindowH = 200;
  1514.         PrintY = 65;
  1515.  
  1516.         quiztype = US_RndT () % totaltypes;
  1517.         switch (quiztype)
  1518.         {
  1519.             //
  1520.             // BOSSES QUIZ
  1521.             //
  1522.             case debriefing:
  1523.             {
  1524.                 PrintX = 0;
  1525.                 US_Print (STR_DEBRIEF);
  1526.                 SETFONTCOLOR (PRINTCOLOR, 15);
  1527.  
  1528.                 while (enemypicked[whichboss = US_RndT () & 3]);
  1529.                 enemypicked[whichboss] = 1;
  1530.                 bossnum = bosses[whichboss];
  1531.                 VWB_DrawPic (128, 60, bossnum);
  1532.                 fontnumber = 0;
  1533.                 PrintY = 130;
  1534.                 US_CPrint (STR_ENEMY1 "\n");
  1535.                 US_CPrint (STR_ENEMY2 "\n\n");
  1536.  
  1537.                 VW_UpdateScreen ();
  1538.                 VW_FadeIn ();
  1539.  
  1540.                 PrintX = 100;
  1541.                 fontcolor = 15;
  1542.                 backcolor = TYPEBOX_BKGD;
  1543.                 inputbuffer[0] = 0;
  1544.                 PrintY = TYPEBOX_Y;
  1545.                 fontnumber = 1;
  1546.                 US_LineInput (PrintX, PrintY, inputbuffer, 0, true, 20, 100);
  1547.  
  1548.                 match = 0;
  1549.                 size_t inputlen = strlen(inputbuffer);
  1550.                 if(inputlen > 3)
  1551.                 {
  1552.                     size_t bosslen = strlen(bossstrs[whichboss]);
  1553.                     for (i = 0; i < bosslen; i++)
  1554.                     {
  1555.                         if (!strncasecmp (inputbuffer, bossstrs[whichboss] + i, inputlen))
  1556.                         {
  1557.                             match = 1;
  1558.                             break;
  1559.                         }
  1560.                     }
  1561.                 }
  1562.  
  1563.                 match += BackDoor (inputbuffer);
  1564.                 break;
  1565.             }
  1566.  
  1567.             //
  1568.             // MANUAL CHECK
  1569.             //
  1570.             case checkmanual:
  1571.             {
  1572.                 while (wordpicked[whichword = US_RndT () % 5]);
  1573.                 wordpicked[whichword] = 1;
  1574.                 US_CPrint (STR_CHECKMAN);
  1575.                 SETFONTCOLOR (PRINTCOLOR, 15);
  1576.                 PrintY += 25;
  1577.                 US_CPrint (STR_MAN1);
  1578.                 US_CPrint (STR_MAN2);
  1579.                 sprintf(message, STR_MAN3 " \"%s\" " STR_MAN4, WordStr[whichword]);
  1580.                 US_CPrint (message);
  1581.                 VW_UpdateScreen ();
  1582.                 VW_FadeIn ();
  1583.  
  1584.                 PrintX = 146;
  1585.                 fontcolor = 15;
  1586.                 backcolor = TYPEBOX_BKGD;
  1587.                 inputbuffer[0] = 0;
  1588.                 PrintY = TYPEBOX_Y;
  1589.                 US_LineInput (PrintX, PrintY, inputbuffer, 0, true, 6, 100);
  1590.  
  1591.                 match = 1 - (strcasecmp (inputbuffer, WordCorrect[whichword]) != 0);
  1592.                 match += BackDoor (inputbuffer);
  1593.                 break;
  1594.             }
  1595.  
  1596.             //
  1597.             // STAFF QUIZ
  1598.             //
  1599.             case staffquiz:
  1600.             {
  1601.                 while (memberpicked[whichmem = US_RndT () % 5]);
  1602.                 memberpicked[whichmem] = 1;
  1603.                 US_CPrint (STR_ID1);
  1604.                 SETFONTCOLOR (PRINTCOLOR, 15);
  1605.                 PrintY += 25;
  1606.                 US_CPrint (MemberStr[whichmem * 2]);
  1607.                 US_CPrint (MemberStr[whichmem * 2 + 1]);
  1608.                 VW_UpdateScreen ();
  1609.                 VW_FadeIn ();
  1610.  
  1611.                 PrintX = 100;
  1612.                 fontcolor = 15;
  1613.                 backcolor = TYPEBOX_BKGD;
  1614.                 inputbuffer[0] = 0;
  1615.                 PrintY = TYPEBOX_Y;
  1616.                 US_LineInput (PrintX, PrintY, inputbuffer, 0, true, 20, 120);
  1617.  
  1618.                 match = 0;
  1619.                 size_t inputlen = strlen(inputbuffer);
  1620.                 if(inputlen > 2)
  1621.                 {
  1622.                     size_t memberlen = strlen(MemberCorrect[whichmem]);
  1623.                     for (i = 0; i < memberlen; i++)
  1624.                     {
  1625.                         if (!strncasecmp (inputbuffer, MemberCorrect[whichmem] + i, inputlen))
  1626.                         {
  1627.                             match = 1;
  1628.                             break;
  1629.                         }
  1630.                     }
  1631.                 }
  1632.  
  1633.                 match += BackDoor (inputbuffer);
  1634.                 break;
  1635.             }
  1636.  
  1637.             //
  1638.             // MISCELLANEOUS QUESTIONS
  1639.             //
  1640.             case miscquiz:
  1641.             {
  1642.                 while (whichpicked[whichone = US_RndT () & 3]);
  1643.                 whichpicked[whichone] = 1;
  1644.                 US_CPrint (MiscTitle[whichone]);
  1645.                 SETFONTCOLOR (PRINTCOLOR, 15);
  1646.                 PrintY += 25;
  1647.                 US_CPrint (MiscStr[whichone * 3]);
  1648.                 US_CPrint (MiscStr[whichone * 3 + 1]);
  1649.                 US_CPrint (MiscStr[whichone * 3 + 2]);
  1650.                 VW_UpdateScreen ();
  1651.                 VW_FadeIn ();
  1652.  
  1653.                 PrintX = 146;
  1654.                 fontcolor = 15;
  1655.                 backcolor = TYPEBOX_BKGD;
  1656.                 inputbuffer[0] = 0;
  1657.                 PrintY = TYPEBOX_Y;
  1658.                 US_LineInput (PrintX, PrintY, inputbuffer, 0, true, 6, 100);
  1659.  
  1660.                 match = 1 - (strcasecmp (inputbuffer, MiscCorrect[whichone]) != 0);
  1661.                 match += BackDoor (inputbuffer);
  1662.                 break;
  1663.             }
  1664.         }
  1665.  
  1666.         //
  1667.         // IF NO MATCH, WE'VE GOT A (MINOR) PROBLEM!
  1668.         //
  1669.  
  1670.         if (!match)
  1671.         {
  1672.             whichline = 2 * (US_RndT () % 9);
  1673.             SETFONTCOLOR (14, 15);
  1674.             fontnumber = 0;
  1675.             PrintY = 175;
  1676.             VWB_DrawPic (0, 20 * 8, COPYPROTBOXPIC);
  1677.             US_CPrint (CopyProFailedStrs[whichline]);
  1678.             US_CPrint (CopyProFailedStrs[whichline + 1]);
  1679.  
  1680.             VW_UpdateScreen ();
  1681.             SD_PlaySound (NOWAYSND);
  1682.             IN_UserInput (TickBase * 6);
  1683.             VW_FadeOut ();
  1684.             attempt++;
  1685.         }
  1686.         else
  1687.         {
  1688.             int start;
  1689.  
  1690.             SD_PlaySound (BONUS1UPSND);
  1691.             SD_WaitSoundDone ();
  1692.             UNCACHEGRCHUNK (STARTFONT + 1);
  1693.             UNCACHEGRCHUNK (C_BACKDROPPIC);
  1694.             UnCacheLump (COPYPROT_LUMP_START, COPYPROT_LUMP_END);
  1695.  
  1696.             switch (SoundMode)
  1697.             {
  1698.                 case sdm_Off:
  1699.                     return;
  1700.                 case sdm_PC:
  1701.                     start = STARTPCSOUNDS;
  1702.                     break;
  1703.                 case sdm_AdLib:
  1704.                     start = STARTADLIBSOUNDS;
  1705.             }
  1706.  
  1707. /*                        for (i=0;i<NUMSOUNDS;i++,start++)
  1708.                                 MM_FreePtr ((memptr *)&audiosegs[start]); */
  1709.             return;
  1710.         }
  1711.     }
  1712.  
  1713.     ClearMemory ();
  1714.     ShutdownId ();
  1715.  
  1716.     printf ("%s\n", DosMessages[US_RndT () % 9]);
  1717.     exit (1);
  1718. }
  1719.  
  1720. #endif // SPEARDEMO
  1721. #endif // GOODTIMES
  1722. #endif // SPEAR
  1723. //===========================================================================
  1724.