Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * OpenTyrian: A modern cross-platform port of Tyrian
  3.  * Copyright (C) 2007-2009  The OpenTyrian Development Team
  4.  *
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License
  7.  * as published by the Free Software Foundation; either version 2
  8.  * of the License, or (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  18.  */
  19. #include "tyrian2.h"
  20.  
  21. #include "animlib.h"
  22. #include "backgrnd.h"
  23. #include "episodes.h"
  24. #include "file.h"
  25. #include "font.h"
  26. #include "fonthand.h"
  27. #include "game_menu.h"
  28. #include "joystick.h"
  29. #include "keyboard.h"
  30. #include "lds_play.h"
  31. #include "loudness.h"
  32. #include "lvllib.h"
  33. #include "menus.h"
  34. #include "mainint.h"
  35. #include "mouse.h"
  36. #include "mtrand.h"
  37. #include "network.h"
  38. #include "nortsong.h"
  39. #include "nortvars.h"
  40. #include "opentyr.h"
  41. #include "params.h"
  42. #include "pcxload.h"
  43. #include "pcxmast.h"
  44. #include "picload.h"
  45. #include "setup.h"
  46. #include "shots.h"
  47. #include "sprite.h"
  48. #include "vga256d.h"
  49. #include "video.h"
  50.  
  51. #include <assert.h>
  52. #include <ctype.h>
  53. #include <math.h>
  54. #include <stdlib.h>
  55. #include <string.h>
  56. #include <stdint.h>
  57.  
  58. inline static void blit_enemy( SDL_Surface *surface, unsigned int i, signed int x_offset, signed int y_offset, signed int sprite_offset );
  59.  
  60. boss_bar_t boss_bar[2];
  61.  
  62. /* Level Event Data */
  63. JE_boolean quit, loadLevelOk;
  64.  
  65. struct JE_EventRecType eventRec[EVENT_MAXIMUM]; /* [1..eventMaximum] */
  66. JE_word levelEnemyMax;
  67. JE_word levelEnemyFrequency;
  68. JE_word levelEnemy[40]; /* [1..40] */
  69.  
  70. char tempStr[31];
  71.  
  72. /* Data used for ItemScreen procedure to indicate items available */
  73. JE_byte itemAvail[9][10]; /* [1..9, 1..10] */
  74. JE_byte itemAvailMax[9]; /* [1..9] */
  75.  
  76. void JE_starShowVGA( void )
  77. {
  78.         JE_byte *src;
  79.         Uint8 *s = NULL; /* screen pointer, 8-bit specific */
  80.  
  81.         int x, y, lightx, lighty, lightdist;
  82.  
  83.         if (!playerEndLevel && !skipStarShowVGA)
  84.         {
  85.  
  86.                 s = VGAScreenSeg->pixels;
  87.  
  88.                 src = game_screen->pixels;
  89.                 src += 24;
  90.  
  91.                 if (smoothScroll != 0 /*&& thisPlayerNum != 2*/)
  92.                 {
  93.                         wait_delay();
  94.                         setjasondelay(frameCountMax);
  95.                 }
  96.  
  97.                 if (starShowVGASpecialCode == 1)
  98.                 {
  99.                         src += game_screen->pitch * 183;
  100.                         for (y = 0; y < 184; y++)
  101.                         {
  102.                                 memmove(s, src, 264);
  103.                                 s += VGAScreenSeg->pitch;
  104.                                 src -= game_screen->pitch;
  105.                         }
  106.                 }
  107.                 else if (starShowVGASpecialCode == 2 && processorType >= 2)
  108.                 {
  109.                         lighty = 172 - player[0].y;
  110.                         lightx = 281 - player[0].x;
  111.  
  112.                         for (y = 184; y; y--)
  113.                         {
  114.                                 if (lighty > y)
  115.                                 {
  116.                                         for (x = 320 - 56; x; x--)
  117.                                         {
  118.                                                 *s = (*src & 0xf0) | ((*src >> 2) & 0x03);
  119.                                                 s++;
  120.                                                 src++;
  121.                                         }
  122.                                 }
  123.                                 else
  124.                                 {
  125.                                         for (x = 320 - 56; x; x--)
  126.                                         {
  127.                                                 lightdist = abs(lightx - x) + lighty;
  128.                                                 if (lightdist < y)
  129.                                                         *s = *src;
  130.                                                 else if (lightdist - y <= 5)
  131.                                                         *s = (*src & 0xf0) | (((*src & 0x0f) + (3 * (5 - (lightdist - y)))) / 4);
  132.                                                 else
  133.                                                         *s = (*src & 0xf0) | ((*src & 0x0f) >> 2);
  134.                                                 s++;
  135.                                                 src++;
  136.                                         }
  137.                                 }
  138.                                 s += 56 + VGAScreenSeg->pitch - 320;
  139.                                 src += 56 + VGAScreenSeg->pitch - 320;
  140.                         }
  141.                 }
  142.                 else
  143.                 {
  144.                         for (y = 0; y < 184; y++)
  145.                         {
  146.                                 memmove(s, src, 264);
  147.                                 s += VGAScreenSeg->pitch;
  148.                                 src += game_screen->pitch;
  149.                         }
  150.                 }
  151.                 JE_showVGA();
  152.         }
  153.  
  154.         quitRequested = false;
  155.         skipStarShowVGA = false;
  156. }
  157.  
  158. inline static void blit_enemy( SDL_Surface *surface, unsigned int i, signed int x_offset, signed int y_offset, signed int sprite_offset )
  159. {
  160.         if (enemy[i].sprite2s == NULL)
  161.         {
  162.                 fprintf(stderr, "warning: enemy %d sprite missing\n", i);
  163.                 return;
  164.         }
  165.        
  166.         const int x = enemy[i].ex + x_offset + tempMapXOfs,
  167.                   y = enemy[i].ey + y_offset;
  168.         const unsigned int index = enemy[i].egr[enemy[i].enemycycle - 1] + sprite_offset;
  169.  
  170.         if (enemy[i].filter != 0)
  171.                 blit_sprite2_filter(surface, x, y, *enemy[i].sprite2s, index, enemy[i].filter);
  172.         else
  173.                 blit_sprite2(surface, x, y, *enemy[i].sprite2s, index);
  174. }
  175.  
  176. void JE_drawEnemy( int enemyOffset ) // actually does a whole lot more than just drawing
  177. {
  178.         player[0].x -= 25;
  179.  
  180.         for (int i = enemyOffset - 25; i < enemyOffset; i++)
  181.         {
  182.                 if (enemyAvail[i] != 1)
  183.                 {
  184.                         enemy[i].mapoffset = tempMapXOfs;
  185.  
  186.                         if (enemy[i].xaccel && enemy[i].xaccel - 89u > mt_rand() % 11)
  187.                         {
  188.                                 if (player[0].x > enemy[i].ex)
  189.                                 {
  190.                                         if (enemy[i].exc < enemy[i].xaccel - 89)
  191.                                                 enemy[i].exc++;
  192.                                 }
  193.                                 else
  194.                                 {
  195.                                         if (enemy[i].exc >= 0 || -enemy[i].exc < enemy[i].xaccel - 89)
  196.                                                 enemy[i].exc--;
  197.                                 }
  198.                         }
  199.  
  200.                         if (enemy[i].yaccel && enemy[i].yaccel - 89u > mt_rand() % 11)
  201.                         {
  202.                                 if (player[0].y > enemy[i].ey)
  203.                                 {
  204.                                         if (enemy[i].eyc < enemy[i].yaccel - 89)
  205.                                                 enemy[i].eyc++;
  206.                                 }
  207.                                 else
  208.                                 {
  209.                                         if (enemy[i].eyc >= 0 || -enemy[i].eyc < enemy[i].yaccel - 89)
  210.                                                 enemy[i].eyc--;
  211.                                 }
  212.                         }
  213.  
  214.                         if (enemy[i].ex + tempMapXOfs > -29 && enemy[i].ex + tempMapXOfs < 300)
  215.                         {
  216.                                 if (enemy[i].aniactive == 1)
  217.                                 {
  218.                                         enemy[i].enemycycle++;
  219.  
  220.                                         if (enemy[i].enemycycle == enemy[i].animax)
  221.                                                 enemy[i].aniactive = enemy[i].aniwhenfire;
  222.                                         else if (enemy[i].enemycycle > enemy[i].ani)
  223.                                                 enemy[i].enemycycle = enemy[i].animin;
  224.                                 }
  225.  
  226.                                 if (enemy[i].egr[enemy[i].enemycycle - 1] == 999)
  227.                                         goto enemy_gone;
  228.  
  229.                                 if (enemy[i].size == 1) // 2x2 enemy
  230.                                 {
  231.                                         if (enemy[i].ey > -13)
  232.                                         {
  233.                                                 blit_enemy(VGAScreen, i, -6, -7, 0);
  234.                                                 blit_enemy(VGAScreen, i,  6, -7, 1);
  235.                                         }
  236.                                         if (enemy[i].ey > -26 && enemy[i].ey < 182)
  237.                                         {
  238.                                                 blit_enemy(VGAScreen, i, -6,  7, 19);
  239.                                                 blit_enemy(VGAScreen, i,  6,  7, 20);
  240.                                         }
  241.                                 }
  242.                                 else
  243.                                 {
  244.                                         if (enemy[i].ey > -13)
  245.                                                 blit_enemy(VGAScreen, i, 0, 0, 0);
  246.                                 }
  247.  
  248.                                 enemy[i].filter = 0;
  249.                         }
  250.  
  251.                         if (enemy[i].excc)
  252.                         {
  253.                                 if (--enemy[i].exccw <= 0)
  254.                                 {
  255.                                         if (enemy[i].exc == enemy[i].exrev)
  256.                                         {
  257.                                                 enemy[i].excc = -enemy[i].excc;
  258.                                                 enemy[i].exrev = -enemy[i].exrev;
  259.                                                 enemy[i].exccadd = -enemy[i].exccadd;
  260.                                         }
  261.                                         else
  262.                                         {
  263.                                                 enemy[i].exc += enemy[i].exccadd;
  264.                                                 enemy[i].exccw = enemy[i].exccwmax;
  265.                                                 if (enemy[i].exc == enemy[i].exrev)
  266.                                                 {
  267.                                                         enemy[i].excc = -enemy[i].excc;
  268.                                                         enemy[i].exrev = -enemy[i].exrev;
  269.                                                         enemy[i].exccadd = -enemy[i].exccadd;
  270.                                                 }
  271.                                         }
  272.                                 }
  273.                         }
  274.  
  275.                         if (enemy[i].eycc)
  276.                         {
  277.                                 if (--enemy[i].eyccw <= 0)
  278.                                 {
  279.                                         if (enemy[i].eyc == enemy[i].eyrev)
  280.                                         {
  281.                                                 enemy[i].eycc = -enemy[i].eycc;
  282.                                                 enemy[i].eyrev = -enemy[i].eyrev;
  283.                                                 enemy[i].eyccadd = -enemy[i].eyccadd;
  284.                                         }
  285.                                         else
  286.                                         {
  287.                                                 enemy[i].eyc += enemy[i].eyccadd;
  288.                                                 enemy[i].eyccw = enemy[i].eyccwmax;
  289.                                                 if (enemy[i].eyc == enemy[i].eyrev)
  290.                                                 {
  291.                                                         enemy[i].eycc = -enemy[i].eycc;
  292.                                                         enemy[i].eyrev = -enemy[i].eyrev;
  293.                                                         enemy[i].eyccadd = -enemy[i].eyccadd;
  294.                                                 }
  295.                                         }
  296.                                 }
  297.                         }
  298.  
  299.                         enemy[i].ey += enemy[i].fixedmovey;
  300.  
  301.                         enemy[i].ex += enemy[i].exc;
  302.                         if (enemy[i].ex < -80 || enemy[i].ex > 340)
  303.                                 goto enemy_gone;
  304.  
  305.                         enemy[i].ey += enemy[i].eyc;
  306.                         if (enemy[i].ey < -112 || enemy[i].ey > 190)
  307.                                 goto enemy_gone;
  308.  
  309.                         goto enemy_still_exists;
  310.  
  311. enemy_gone:
  312.                         /* enemy[i].egr[10] &= 0x00ff; <MXD> madness? */
  313.                         enemyAvail[i] = 1;
  314.                         goto draw_enemy_end;
  315.  
  316. enemy_still_exists:
  317.  
  318.                         /*X bounce*/
  319.                         if (enemy[i].ex <= enemy[i].xminbounce || enemy[i].ex >= enemy[i].xmaxbounce)
  320.                                 enemy[i].exc = -enemy[i].exc;
  321.  
  322.                         /*Y bounce*/
  323.                         if (enemy[i].ey <= enemy[i].yminbounce || enemy[i].ey >= enemy[i].ymaxbounce)
  324.                                 enemy[i].eyc = -enemy[i].eyc;
  325.  
  326.                         /* Evalue != 0 - score item at boundary */
  327.                         if (enemy[i].scoreitem)
  328.                         {
  329.                                 if (enemy[i].ex < -5)
  330.                                         enemy[i].ex++;
  331.                                 if (enemy[i].ex > 245)
  332.                                         enemy[i].ex--;
  333.                         }
  334.  
  335.                         enemy[i].ey += tempBackMove;
  336.  
  337.                         if (enemy[i].ex <= -24 || enemy[i].ex >= 296)
  338.                                 goto draw_enemy_end;
  339.  
  340.                         tempX = enemy[i].ex;
  341.                         tempY = enemy[i].ey;
  342.  
  343.                         temp = enemy[i].enemytype;
  344.  
  345.                         /* Enemy Shots */
  346.                         if (enemy[i].edamaged == 1)
  347.                                 goto draw_enemy_end;
  348.  
  349.                         enemyOnScreen++;
  350.  
  351.                         if (enemy[i].iced)
  352.                         {
  353.                                 enemy[i].iced--;
  354.                                 if (enemy[i].enemyground != 0)
  355.                                 {
  356.                                         enemy[i].filter = 0x09;
  357.                                 }
  358.                                 goto draw_enemy_end;
  359.                         }
  360.  
  361.                         for (int j = 3; j > 0; j--)
  362.                         {
  363.                                 if (enemy[i].freq[j-1])
  364.                                 {
  365.                                         temp3 = enemy[i].tur[j-1];
  366.  
  367.                                         if (--enemy[i].eshotwait[j-1] == 0 && temp3)
  368.                                         {
  369.                                                 enemy[i].eshotwait[j-1] = enemy[i].freq[j-1];
  370.                                                 if (difficultyLevel > 2)
  371.                                                 {
  372.                                                         enemy[i].eshotwait[j-1] = (enemy[i].eshotwait[j-1] / 2) + 1;
  373.                                                         if (difficultyLevel > 7)
  374.                                                                 enemy[i].eshotwait[j-1] = (enemy[i].eshotwait[j-1] / 2) + 1;
  375.                                                 }
  376.  
  377.                                                 if (galagaMode && (enemy[i].eyc == 0 || (mt_rand() % 400) >= galagaShotFreq))
  378.                                                         goto draw_enemy_end;
  379.  
  380.                                                 switch (temp3)
  381.                                                 {
  382.                                                 case 252: /* Savara Boss DualMissile */
  383.                                                         if (enemy[i].ey > 20)
  384.                                                         {
  385.                                                                 JE_setupExplosion(tempX - 8 + tempMapXOfs, tempY - 20 - backMove * 8, -2, 6, false, false);
  386.                                                                 JE_setupExplosion(tempX + 4 + tempMapXOfs, tempY - 20 - backMove * 8, -2, 6, false, false);
  387.                                                         }
  388.                                                         break;
  389.                                                 case 251:; /* Suck-O-Magnet */
  390.                                                         const int attractivity = 4 - (abs(player[0].x - tempX) + abs(player[0].y - tempY)) / 100;
  391.                                                         player[0].x_velocity += (player[0].x > tempX) ? -attractivity : attractivity;
  392.                                                         break;
  393.                                                 case 253: /* Left ShortRange Magnet */
  394.                                                         if (abs(player[0].x + 25 - 14 - tempX) < 24 && abs(player[0].y - tempY) < 28)
  395.                                                         {
  396.                                                                 player[0].x_velocity += 2;
  397.                                                         }
  398.                                                         if (twoPlayerMode &&
  399.                                                            (abs(player[1].x - 14 - tempX) < 24 && abs(player[1].y - tempY) < 28))
  400.                                                         {
  401.                                                                 player[1].x_velocity += 2;
  402.                                                         }
  403.                                                         break;
  404.                                                 case 254: /* Left ShortRange Magnet */
  405.                                                         if (abs(player[0].x + 25 - 14 - tempX) < 24 && abs(player[0].y - tempY) < 28)
  406.                                                         {
  407.                                                                 player[0].x_velocity -= 2;
  408.                                                         }
  409.                                                         if (twoPlayerMode &&
  410.                                                            (abs(player[1].x - 14 - tempX) < 24 && abs(player[1].y - tempY) < 28))
  411.                                                         {
  412.                                                                 player[1].x_velocity -= 2;
  413.                                                         }
  414.                                                         break;
  415.                                                 case 255: /* Magneto RePulse!! */
  416.                                                         if (difficultyLevel != 1) /*DIF*/
  417.                                                         {
  418.                                                                 if (j == 3)
  419.                                                                 {
  420.                                                                         enemy[i].filter = 0x70;
  421.                                                                 }
  422.                                                                 else
  423.                                                                 {
  424.                                                                         const int repulsivity = 4 - (abs(player[0].x - tempX) + abs(player[0].y - tempY)) / 20;
  425.                                                                         if (repulsivity > 0)
  426.                                                                                 player[0].x_velocity += (player[0].x > tempX) ? repulsivity : -repulsivity;
  427.                                                                 }
  428.                                                         }
  429.                                                         break;
  430.                                                 default:
  431.                                                 /*Rot*/
  432.                                                         for (int tempCount = weapons[temp3].multi; tempCount > 0; tempCount--)
  433.                                                         {
  434.                                                                 for (b = 0; b < ENEMY_SHOT_MAX; b++)
  435.                                                                 {
  436.                                                                         if (enemyShotAvail[b] == 1)
  437.                                                                                 break;
  438.                                                                 }
  439.                                                                 if (b == ENEMY_SHOT_MAX)
  440.                                                                         goto draw_enemy_end;
  441.  
  442.                                                                 enemyShotAvail[b] = !enemyShotAvail[b];
  443.  
  444.                                                                 if (weapons[temp3].sound > 0)
  445.                                                                 {
  446.                                                                         do
  447.                                                                                 temp = mt_rand() % 8;
  448.                                                                         while (temp == 3);
  449.                                                                         soundQueue[temp] = weapons[temp3].sound;
  450.                                                                 }
  451.  
  452.                                                                 if (enemy[i].aniactive == 2)
  453.                                                                         enemy[i].aniactive = 1;
  454.  
  455.                                                                 if (++enemy[i].eshotmultipos[j-1] > weapons[temp3].max)
  456.                                                                         enemy[i].eshotmultipos[j-1] = 1;
  457.  
  458.                                                                 int tempPos = enemy[i].eshotmultipos[j-1] - 1;
  459.  
  460.                                                                 if (j == 1)
  461.                                                                         temp2 = 4;
  462.  
  463.                                                                 enemyShot[b].sx = tempX + weapons[temp3].bx[tempPos] + tempMapXOfs;
  464.                                                                 enemyShot[b].sy = tempY + weapons[temp3].by[tempPos];
  465.                                                                 enemyShot[b].sdmg = weapons[temp3].attack[tempPos];
  466.                                                                 enemyShot[b].tx = weapons[temp3].tx;
  467.                                                                 enemyShot[b].ty = weapons[temp3].ty;
  468.                                                                 enemyShot[b].duration = weapons[temp3].del[tempPos];
  469.                                                                 enemyShot[b].animate = 0;
  470.                                                                 enemyShot[b].animax = weapons[temp3].weapani;
  471.  
  472.                                                                 enemyShot[b].sgr = weapons[temp3].sg[tempPos];
  473.                                                                 switch (j)
  474.                                                                 {
  475.                                                                 case 1:
  476.                                                                         enemyShot[b].syc = weapons[temp3].acceleration;
  477.                                                                         enemyShot[b].sxc = weapons[temp3].accelerationx;
  478.  
  479.                                                                         enemyShot[b].sxm = weapons[temp3].sx[tempPos];
  480.                                                                         enemyShot[b].sym = weapons[temp3].sy[tempPos];
  481.                                                                         break;
  482.                                                                 case 3:
  483.                                                                         enemyShot[b].sxc = -weapons[temp3].acceleration;
  484.                                                                         enemyShot[b].syc = weapons[temp3].accelerationx;
  485.  
  486.                                                                         enemyShot[b].sxm = -weapons[temp3].sy[tempPos];
  487.                                                                         enemyShot[b].sym = -weapons[temp3].sx[tempPos];
  488.                                                                         break;
  489.                                                                 case 2:
  490.                                                                         enemyShot[b].sxc = weapons[temp3].acceleration;
  491.                                                                         enemyShot[b].syc = -weapons[temp3].acceleration;
  492.  
  493.                                                                         enemyShot[b].sxm = weapons[temp3].sy[tempPos];
  494.                                                                         enemyShot[b].sym = -weapons[temp3].sx[tempPos];
  495.                                                                         break;
  496.                                                                 }
  497.  
  498.                                                                 if (weapons[temp3].aim > 0)
  499.                                                                 {
  500.                                                                         int aim = weapons[temp3].aim;
  501.  
  502.                                                                         /*DIF*/
  503.                                                                         if (difficultyLevel > 2)
  504.                                                                         {
  505.                                                                                 aim += difficultyLevel - 2;
  506.                                                                         }
  507.  
  508.                                                                         JE_word target_x = player[0].x;
  509.                                                                         JE_word target_y = player[0].y;
  510.  
  511.                                                                         if (twoPlayerMode)
  512.                                                                         {
  513.                                                                                 // fire at live player(s)
  514.                                                                                 if (player[0].is_alive && !player[1].is_alive)
  515.                                                                                         temp = 0;
  516.                                                                                 else if (player[1].is_alive && !player[0].is_alive)
  517.                                                                                         temp = 1;
  518.                                                                                 else
  519.                                                                                         temp = mt_rand() % 2;
  520.  
  521.                                                                                 if (temp == 1)
  522.                                                                                 {
  523.                                                                                         target_x = player[1].x - 25;
  524.                                                                                         target_y = player[1].y;
  525.                                                                                 }
  526.                                                                         }
  527.  
  528.                                                                         int relative_x = (target_x + 25) - tempX - tempMapXOfs - 4;
  529.                                                                         if (relative_x == 0)
  530.                                                                                 relative_x = 1;
  531.                                                                         int relative_y = target_y - tempY;
  532.                                                                         if (relative_y == 0)
  533.                                                                                 relative_y = 1;
  534.                                                                         const int longest_side = MAX(abs(relative_x), abs(relative_y));
  535.                                                                         enemyShot[b].sxm = roundf((float)relative_x / longest_side * aim);
  536.                                                                         enemyShot[b].sym = roundf((float)relative_y / longest_side * aim);
  537.                                                                 }
  538.                                                         }
  539.                                                         break;
  540.                                                 }
  541.                                         }
  542.                                 }
  543.                         }
  544.  
  545.                         /* Enemy Launch Routine */
  546.                         if (enemy[i].launchfreq)
  547.                         {
  548.                                 if (--enemy[i].launchwait == 0)
  549.                                 {
  550.                                         enemy[i].launchwait = enemy[i].launchfreq;
  551.  
  552.                                         if (enemy[i].launchspecial != 0)
  553.                                         {
  554.                                                 /*Type  1 : Must be inline with player*/
  555.                                                 if (abs(enemy[i].ey - player[0].y) > 5)
  556.                                                         goto draw_enemy_end;
  557.                                         }
  558.  
  559.                                         if (enemy[i].aniactive == 2)
  560.                                         {
  561.                                                 enemy[i].aniactive = 1;
  562.                                         }
  563.  
  564.                                         if (enemy[i].launchtype == 0)
  565.                                                 goto draw_enemy_end;
  566.  
  567.                                         tempW = enemy[i].launchtype;
  568.                                         b = JE_newEnemy(enemyOffset == 50 ? 75 : enemyOffset - 25, tempW, 0);
  569.  
  570.                                         /*Launch Enemy Placement*/
  571.                                         if (b > 0)
  572.                                         {
  573.                                                 struct JE_SingleEnemyType* e = &enemy[b-1];
  574.  
  575.                                                 e->ex = tempX;
  576.                                                 e->ey = tempY + enemyDat[e->enemytype].startyc;
  577.                                                 if (e->size == 0)
  578.                                                         e->ey -= 7;
  579.  
  580.                                                 if (e->launchtype > 0 && e->launchfreq == 0)
  581.                                                 {
  582.                                                         if (e->launchtype > 90)
  583.                                                         {
  584.                                                                 e->ex += mt_rand() % ((e->launchtype - 90) * 4) - (e->launchtype - 90) * 2;
  585.                                                         }
  586.                                                         else
  587.                                                         {
  588.                                                                 int target_x = (player[0].x + 25) - tempX - tempMapXOfs - 4;
  589.                                                                 if (target_x == 0)
  590.                                                                         target_x = 1;
  591.                                                                 int tempI5 = player[0].y - tempY;
  592.                                                                 if (tempI5 == 0)
  593.                                                                         tempI5 = 1;
  594.                                                                 const int longest_side = MAX(abs(target_x), abs(tempI5));
  595.                                                                 e->exc = roundf(((float)target_x / longest_side) * e->launchtype);
  596.                                                                 e->eyc = roundf(((float)tempI5 / longest_side) * e->launchtype);
  597.                                                         }
  598.                                                 }
  599.  
  600.                                                 do
  601.                                                         temp = mt_rand() % 8;
  602.                                                 while (temp == 3);
  603.                                                 soundQueue[temp] = randomEnemyLaunchSounds[(mt_rand() % 3)];
  604.  
  605.                                                 if (enemy[i].launchspecial == 1
  606.                                                     && enemy[i].linknum < 100)
  607.                                                 {
  608.                                                         e->linknum = enemy[i].linknum;
  609.                                                 }
  610.                                         }
  611.                                 }
  612.                         }
  613.                 }
  614. draw_enemy_end:
  615.                 ;
  616.         }
  617.  
  618.         player[0].x += 25;
  619. }
  620.  
  621. void JE_main( void )
  622. {
  623.         char buffer[256];
  624.  
  625.         int lastEnemyOnScreen;
  626.  
  627.         /* NOTE: BEGIN MAIN PROGRAM HERE AFTER LOADING A GAME OR STARTING A NEW ONE */
  628.  
  629.         /* ----------- GAME ROUTINES ------------------------------------- */
  630.         /* We need to jump to the beginning to make space for the routines */
  631.         /* --------------------------------------------------------------- */
  632.         goto start_level_first;
  633.  
  634.  
  635.         /*------------------------------GAME LOOP-----------------------------------*/
  636.  
  637.  
  638.         /* Startlevel is called after a previous level is over.  If the first level
  639.            is started for a gaming session, startlevelfirst is called instead and
  640.            this code is skipped.  The code here finishes the level and prepares for
  641.            the loadmap function. */
  642.  
  643. start_level:
  644.  
  645.         if (galagaMode)
  646.                 twoPlayerMode = false;
  647.  
  648.         JE_clearKeyboard();
  649.  
  650.         free_sprite2s(&eShapes[0]);
  651.         free_sprite2s(&eShapes[1]);
  652.         free_sprite2s(&eShapes[2]);
  653.         free_sprite2s(&eShapes[3]);
  654.  
  655.         /* Normal speed */
  656.         if (fastPlay != 0)
  657.         {
  658.                 smoothScroll = true;
  659.                 speed = 0x4300;
  660.                 JE_resetTimerInt();
  661.                 JE_setTimerInt();
  662.         }
  663.  
  664.         if (play_demo || record_demo)
  665.         {
  666.                 if (demo_file)
  667.                 {
  668.                         fclose(demo_file);
  669.                         demo_file = NULL;
  670.                 }
  671.  
  672.                 if (play_demo)
  673.                 {
  674.                         stop_song();
  675.                         fade_black(10);
  676.  
  677.                         wait_noinput(true, true, true);
  678.                 }
  679.         }
  680.  
  681.         difficultyLevel = oldDifficultyLevel;   /*Return difficulty to normal*/
  682.  
  683.         if (!play_demo)
  684.         {
  685.                 if ((!all_players_dead() || normalBonusLevelCurrent || bonusLevelCurrent) && !playerEndLevel)
  686.                 {
  687.                         mainLevel = nextLevel;
  688.                         JE_endLevelAni();
  689.  
  690.                         fade_song();
  691.                 }
  692.                 else
  693.                 {
  694.                         fade_song();
  695.                         fade_black(10);
  696.  
  697.                         JE_loadGame(twoPlayerMode ? 22 : 11);
  698.                         if (doNotSaveBackup)
  699.                         {
  700.                                 superTyrian = false;
  701.                                 onePlayerAction = false;
  702.                                 player[0].items.super_arcade_mode = SA_NONE;
  703.                         }
  704.                         if (bonusLevelCurrent && !playerEndLevel)
  705.                         {
  706.                                 mainLevel = nextLevel;
  707.                         }
  708.                 }
  709.         }
  710.         doNotSaveBackup = false;
  711.  
  712.         if (play_demo)
  713.                 return;
  714.  
  715. start_level_first:
  716.  
  717.         set_volume(tyrMusicVolume, fxVolume);
  718.  
  719.         endLevel = false;
  720.         reallyEndLevel = false;
  721.         playerEndLevel = false;
  722.         extraGame = false;
  723.  
  724.         doNotSaveBackup = false;
  725.         JE_loadMap();
  726.  
  727.         if (mainLevel == 0)  // if quit itemscreen
  728.                 return;          // back to titlescreen
  729.  
  730.         fade_song();
  731.  
  732.         for (uint i = 0; i < COUNTOF(player); ++i)
  733.                 player[i].is_alive = true;
  734.  
  735.         oldDifficultyLevel = difficultyLevel;
  736.         if (episodeNum == EPISODE_AVAILABLE)
  737.                 difficultyLevel--;
  738.         if (difficultyLevel < 1)
  739.                 difficultyLevel = 1;
  740.  
  741.         player[0].x = 100;
  742.         player[0].y = 180;
  743.  
  744.         player[1].x = 190;
  745.         player[1].y = 180;
  746.  
  747.         assert(COUNTOF(player->old_x) == COUNTOF(player->old_y));
  748.  
  749.         for (uint i = 0; i < COUNTOF(player); ++i)
  750.         {
  751.                 for (uint j = 0; j < COUNTOF(player->old_x); ++j)
  752.                 {
  753.                         player[i].old_x[j] = player[i].x - (19 - j);
  754.                         player[i].old_y[j] = player[i].y - 18;
  755.                 }
  756.                
  757.                 player[i].last_x_shot_move = player[i].x;
  758.                 player[i].last_y_shot_move = player[i].y;
  759.         }
  760.        
  761.         JE_loadPic(VGAScreen, twoPlayerMode ? 6 : 3, false);
  762.  
  763.         JE_drawOptions();
  764.  
  765.         JE_outText(VGAScreen, 268, twoPlayerMode ? 76 : 118, levelName, 12, 4);
  766.  
  767.         JE_showVGA();
  768.         JE_gammaCorrect(&colors, gammaCorrection);
  769.         fade_palette(colors, 50, 0, 255);
  770.  
  771.         free_sprite2s(&shapes6);
  772.         JE_loadCompShapes(&shapes6, '6'); // explosion sprites
  773.  
  774.         /* MAPX will already be set correctly */
  775.         mapY = 300 - 8;
  776.         mapY2 = 600 - 8;
  777.         mapY3 = 600 - 8;
  778.         mapYPos = &megaData1.mainmap[mapY][0] - 1;
  779.         mapY2Pos = &megaData2.mainmap[mapY2][0] - 1;
  780.         mapY3Pos = &megaData3.mainmap[mapY3][0] - 1;
  781.         mapXPos = 0;
  782.         mapXOfs = 0;
  783.         mapX2Pos = 0;
  784.         mapX3Pos = 0;
  785.         mapX3Ofs = 0;
  786.         mapXbpPos = 0;
  787.         mapX2bpPos = 0;
  788.         mapX3bpPos = 0;
  789.  
  790.         map1YDelay = 1;
  791.         map1YDelayMax = 1;
  792.         map2YDelay = 1;
  793.         map2YDelayMax = 1;
  794.  
  795.         musicFade = false;
  796.  
  797.         backPos = 0;
  798.         backPos2 = 0;
  799.         backPos3 = 0;
  800.         power = 0;
  801.         starfield_speed = 1;
  802.  
  803.         /* Setup player ship graphics */
  804.         JE_getShipInfo();
  805.  
  806.         for (uint i = 0; i < COUNTOF(player); ++i)
  807.         {
  808.                 player[i].x_velocity = 0;
  809.                 player[i].y_velocity = 0;
  810.  
  811.                 player[i].invulnerable_ticks = 100;
  812.         }
  813.  
  814.         newkey = newmouse = false;
  815.  
  816.         /* Initialize Level Data and Debug Mode */
  817.         levelEnd = 255;
  818.         levelEndWarp = -4;
  819.         levelEndFxWait = 0;
  820.         warningCol = 120;
  821.         warningColChange = 1;
  822.         warningSoundDelay = 0;
  823.         armorShipDelay = 50;
  824.  
  825.         bonusLevel = false;
  826.         readyToEndLevel = false;
  827.         firstGameOver = true;
  828.         eventLoc = 1;
  829.         curLoc = 0;
  830.         backMove = 1;
  831.         backMove2 = 2;
  832.         backMove3 = 3;
  833.         explodeMove = 2;
  834.         enemiesActive = true;
  835.         for(temp = 0; temp < 3; temp++)
  836.         {
  837.                 button[temp] = false;
  838.         }
  839.         stopBackgrounds = false;
  840.         stopBackgroundNum = 0;
  841.         background3x1   = false;
  842.         background3x1b  = false;
  843.         background3over = 0;
  844.         background2over = 1;
  845.         topEnemyOver = false;
  846.         skyEnemyOverAll = false;
  847.         smallEnemyAdjust = false;
  848.         starActive = true;
  849.         enemyContinualDamage = false;
  850.         levelEnemyFrequency = 96;
  851.         quitRequested = false;
  852.  
  853.         for (unsigned int i = 0; i < COUNTOF(boss_bar); i++)
  854.                 boss_bar[i].link_num = 0;
  855.  
  856.         forceEvents = false;  /*Force events to continue if background movement = 0*/
  857.  
  858.         superEnemy254Jump = 0;   /*When Enemy with PL 254 dies*/
  859.  
  860.         /* Filter Status */
  861.         filterActive = true;
  862.         filterFade = true;
  863.         filterFadeStart = false;
  864.         levelFilter = -99;
  865.         levelBrightness = -14;
  866.         levelBrightnessChg = 1;
  867.  
  868.         background2notTransparent = false;
  869.  
  870.         uint old_weapon_bar[2] = { 0, 0 };  // only redrawn when they change
  871.  
  872.         /* Initially erase power bars */
  873.         lastPower = power / 10;
  874.  
  875.         /* Initial Text */
  876.         JE_drawTextWindow(miscText[20]);
  877.  
  878.         /* Setup Armor/Shield Data */
  879.         shieldWait = 1;
  880.         shieldT    = shields[player[0].items.shield].tpwr * 20;
  881.  
  882.         for (uint i = 0; i < COUNTOF(player); ++i)
  883.         {
  884.                 player[i].shield     = shields[player[i].items.shield].mpwr;
  885.                 player[i].shield_max = player[i].shield * 2;
  886.         }
  887.  
  888.         JE_drawShield();
  889.         JE_drawArmor();
  890.  
  891.         for (uint i = 0; i < COUNTOF(player); ++i)
  892.                 player[i].superbombs = 0;
  893.  
  894.         /* Set cubes to 0 */
  895.         cubeMax = 0;
  896.  
  897.         /* Secret Level Display */
  898.         flash = 0;
  899.         flashChange = 1;
  900.         displayTime = 0;
  901.  
  902.         play_song(levelSong - 1);
  903.  
  904.         JE_drawPortConfigButtons();
  905.  
  906.         /* --- MAIN LOOP --- */
  907.  
  908.         newkey = false;
  909.  
  910. #ifdef WITH_NETWORK
  911.         if (isNetworkGame)
  912.         {
  913.                 JE_clearSpecialRequests();
  914.                 mt_srand(32402394);
  915.         }
  916. #endif
  917.  
  918.         initialize_starfield();
  919.  
  920.         JE_setNewGameSpeed();
  921.  
  922.         /* JE_setVol(tyrMusicVolume, fxPlayVol >> 2); NOTE: MXD killed this because it was broken */
  923.  
  924.         /*Save backup game*/
  925.         if (!play_demo && !doNotSaveBackup)
  926.         {
  927.                 temp = twoPlayerMode ? 22 : 11;
  928.                 JE_saveGame(temp, "LAST LEVEL    ");
  929.         }
  930.  
  931.         if (!play_demo && record_demo)
  932.         {
  933.                 Uint8 new_demo_num = 0;
  934.  
  935.                 do
  936.                 {
  937.                         sprintf(tempStr, "demorec.%d", new_demo_num++);
  938.                 }
  939.                 while (dir_file_exists(get_user_directory(), tempStr)); // until file doesn't exist
  940.  
  941.                 demo_file = dir_fopen_warn(get_user_directory(), tempStr, "wb");
  942.                 if (!demo_file)
  943.                         exit(1);
  944.  
  945.                 efwrite(&episodeNum, 1,  1, demo_file);
  946.                 efwrite(levelName,   1, 10, demo_file);
  947.                 efwrite(&lvlFileNum, 1,  1, demo_file);
  948.  
  949.                 fputc(player[0].items.weapon[FRONT_WEAPON].id,  demo_file);
  950.                 fputc(player[0].items.weapon[REAR_WEAPON].id,   demo_file);
  951.                 fputc(player[0].items.super_arcade_mode,        demo_file);
  952.                 fputc(player[0].items.sidekick[LEFT_SIDEKICK],  demo_file);
  953.                 fputc(player[0].items.sidekick[RIGHT_SIDEKICK], demo_file);
  954.                 fputc(player[0].items.generator,                demo_file);
  955.  
  956.                 fputc(player[0].items.sidekick_level,           demo_file);
  957.                 fputc(player[0].items.sidekick_series,          demo_file);
  958.  
  959.                 fputc(initial_episode_num,                      demo_file);
  960.  
  961.                 fputc(player[0].items.shield,                   demo_file);
  962.                 fputc(player[0].items.special,                  demo_file);
  963.                 fputc(player[0].items.ship,                     demo_file);
  964.  
  965.                 for (uint i = 0; i < 2; ++i)
  966.                         fputc(player[0].items.weapon[i].power, demo_file);
  967.  
  968.                 for (uint i = 0; i < 3; ++i)
  969.                         fputc(0, demo_file);
  970.  
  971.                 efwrite(&levelSong,  1,  1, demo_file);
  972.  
  973.                 demo_keys = 0;
  974.                 demo_keys_wait = 0;
  975.         }
  976.  
  977.         twoPlayerLinked = false;
  978.         linkGunDirec = M_PI;
  979.  
  980.         for (uint i = 0; i < COUNTOF(player); ++i)
  981.                 calc_purple_balls_needed(&player[i]);
  982.  
  983.         damageRate = 2;  /*Normal Rate for Collision Damage*/
  984.  
  985.         chargeWait   = 5;
  986.         chargeLevel  = 0;
  987.         chargeMax    = 5;
  988.         chargeGr     = 0;
  989.         chargeGrWait = 3;
  990.  
  991.         portConfigChange = false;
  992.  
  993.         /*Destruction Ratio*/
  994.         totalEnemy = 0;
  995.         enemyKilled = 0;
  996.  
  997.         astralDuration = 0;
  998.  
  999.         superArcadePowerUp = 1;
  1000.  
  1001.         yourInGameMenuRequest = false;
  1002.  
  1003.         constantLastX = -1;
  1004.  
  1005.         for (uint i = 0; i < COUNTOF(player); ++i)
  1006.                 player[i].exploding_ticks = 0;
  1007.  
  1008.         if (isNetworkGame)
  1009.         {
  1010.                 JE_loadItemDat();
  1011.         }
  1012.  
  1013.         memset(enemyAvail,       1, sizeof(enemyAvail));
  1014.         for (uint i = 0; i < COUNTOF(enemyShotAvail); i++)
  1015.                 enemyShotAvail[i] = 1;
  1016.  
  1017.         /*Initialize Shots*/
  1018.         memset(playerShotData,   0, sizeof(playerShotData));
  1019.         memset(shotAvail,        0, sizeof(shotAvail));
  1020.         memset(shotMultiPos,     0, sizeof(shotMultiPos));
  1021.         memset(shotRepeat,       1, sizeof(shotRepeat));
  1022.  
  1023.         memset(button,           0, sizeof(button));
  1024.  
  1025.         memset(globalFlags,      0, sizeof(globalFlags));
  1026.  
  1027.         memset(explosions,       0, sizeof(explosions));
  1028.         memset(rep_explosions,   0, sizeof(rep_explosions));
  1029.  
  1030.         /* --- Clear Sound Queue --- */
  1031.         memset(soundQueue,       0, sizeof(soundQueue));
  1032.         soundQueue[3] = V_GOOD_LUCK;
  1033.  
  1034.         memset(enemyShapeTables, 0, sizeof(enemyShapeTables));
  1035.         memset(enemy,            0, sizeof(enemy));
  1036.  
  1037.         memset(SFCurrentCode,    0, sizeof(SFCurrentCode));
  1038.         memset(SFExecuted,       0, sizeof(SFExecuted));
  1039.  
  1040.         zinglonDuration = 0;
  1041.         specialWait = 0;
  1042.         nextSpecialWait = 0;
  1043.         optionAttachmentMove  = 0;    /*Launch the Attachments!*/
  1044.         optionAttachmentLinked = true;
  1045.  
  1046.         editShip1 = false;
  1047.         editShip2 = false;
  1048.  
  1049.         memset(smoothies, 0, sizeof(smoothies));
  1050.  
  1051.         levelTimer = false;
  1052.         randomExplosions = false;
  1053.  
  1054.         last_superpixel = 0;
  1055.         memset(superpixels, 0, sizeof(superpixels));
  1056.  
  1057.         returnActive = false;
  1058.  
  1059.         galagaShotFreq = 0;
  1060.  
  1061.         if (galagaMode)
  1062.         {
  1063.                 difficultyLevel = 2;
  1064.         }
  1065.         galagaLife = 10000;
  1066.  
  1067.         JE_drawOptionLevel();
  1068.  
  1069.         // keeps map from scrolling past the top
  1070.         BKwrap1 = BKwrap1to = &megaData1.mainmap[1][0];
  1071.         BKwrap2 = BKwrap2to = &megaData2.mainmap[1][0];
  1072.         BKwrap3 = BKwrap3to = &megaData3.mainmap[1][0];
  1073.  
  1074. level_loop:
  1075.  
  1076.         //tempScreenSeg = game_screen; /* side-effect of game_screen */
  1077.  
  1078.         if (isNetworkGame)
  1079.         {
  1080.                 smoothies[9-1] = false;
  1081.                 smoothies[6-1] = false;
  1082.         } else {
  1083.                 starShowVGASpecialCode = smoothies[9-1] + (smoothies[6-1] << 1);
  1084.         }
  1085.  
  1086.         /*Background Wrapping*/
  1087.         if (mapYPos <= BKwrap1)
  1088.         {
  1089.                 mapYPos = BKwrap1to;
  1090.         }
  1091.         if (mapY2Pos <= BKwrap2)
  1092.         {
  1093.                 mapY2Pos = BKwrap2to;
  1094.         }
  1095.         if (mapY3Pos <= BKwrap3)
  1096.         {
  1097.                 mapY3Pos = BKwrap3to;
  1098.         }
  1099.  
  1100.  
  1101.         allPlayersGone = all_players_dead() &&
  1102.                          ((*player[0].lives == 1 && player[0].exploding_ticks == 0) || (!onePlayerAction && !twoPlayerMode)) &&
  1103.                          ((*player[1].lives == 1 && player[1].exploding_ticks == 0) || !twoPlayerMode);
  1104.  
  1105.  
  1106.         /*-----MUSIC FADE------*/
  1107.         if (musicFade)
  1108.         {
  1109.                 if (tempVolume > 10)
  1110.                 {
  1111.                         tempVolume--;
  1112.                         set_volume(tempVolume, fxVolume);
  1113.                 }
  1114.                 else
  1115.                 {
  1116.                         musicFade = false;
  1117.                 }
  1118.         }
  1119.  
  1120.         if (!allPlayersGone && levelEnd > 0 && endLevel)
  1121.         {
  1122.                 play_song(9);
  1123.                 musicFade = false;
  1124.         }
  1125.         else if (!playing && firstGameOver)
  1126.         {
  1127.                 play_song(levelSong - 1);
  1128.         }
  1129.  
  1130.  
  1131.         if (!endLevel) // draw HUD
  1132.         {
  1133.                 VGAScreen = VGAScreenSeg; /* side-effect of game_screen */
  1134.  
  1135.                 /*-----------------------Message Bar------------------------*/
  1136.                 if (textErase > 0 && --textErase == 0)
  1137.                         blit_sprite(VGAScreenSeg, 16, 189, OPTION_SHAPES, 36);  // in-game message area
  1138.  
  1139.                 /*------------------------Shield Gen-------------------------*/
  1140.                 if (galagaMode)
  1141.                 {
  1142.                         for (uint i = 0; i < COUNTOF(player); ++i)
  1143.                                 player[i].shield = 0;
  1144.  
  1145.                         // spawned dragonwing died :(
  1146.                         if (*player[1].lives == 0 || player[1].armor == 0)
  1147.                                 twoPlayerMode = false;
  1148.  
  1149.                         if (player[0].cash >= (unsigned)galagaLife)
  1150.                         {
  1151.                                 soundQueue[6] = S_EXPLOSION_11;
  1152.                                 soundQueue[7] = S_SOUL_OF_ZINGLON;
  1153.  
  1154.                                 if (*player[0].lives < 11)
  1155.                                         ++(*player[0].lives);
  1156.                                 else
  1157.                                         player[0].cash += 1000;
  1158.  
  1159.                                 if (galagaLife == 10000)
  1160.                                         galagaLife = 20000;
  1161.                                 else
  1162.                                         galagaLife += 25000;
  1163.                         }
  1164.                 }
  1165.                 else // not galagaMode
  1166.                 {
  1167.                         if (twoPlayerMode)
  1168.                         {
  1169.                                 if (--shieldWait == 0)
  1170.                                 {
  1171.                                         shieldWait = 15;
  1172.  
  1173.                                         for (uint i = 0; i < COUNTOF(player); ++i)
  1174.                                         {
  1175.                                                 if (player[i].shield < player[i].shield_max && player[i].is_alive)
  1176.                                                         ++player[i].shield;
  1177.                                         }
  1178.  
  1179.                                         JE_drawShield();
  1180.                                 }
  1181.                         }
  1182.                         else if (player[0].is_alive && player[0].shield < player[0].shield_max && power > shieldT)
  1183.                         {
  1184.                                 if (--shieldWait == 0)
  1185.                                 {
  1186.                                         shieldWait = 15;
  1187.  
  1188.                                         power -= shieldT;
  1189.  
  1190.                                         ++player[0].shield;
  1191.                                         if (player[1].shield < player[0].shield_max)
  1192.                                                 ++player[1].shield;
  1193.  
  1194.                                         JE_drawShield();
  1195.                                 }
  1196.                         }
  1197.                 }
  1198.  
  1199.                 /*---------------------Weapon Display-------------------------*/
  1200.                 for (uint i = 0; i < 2; ++i)
  1201.                 {
  1202.                         uint item_power = player[twoPlayerMode ? i : 0].items.weapon[i].power;
  1203.  
  1204.                         if (old_weapon_bar[i] != item_power)
  1205.                         {
  1206.                                 old_weapon_bar[i] = item_power;
  1207.  
  1208.                                 int x = twoPlayerMode ? 286 : 289,
  1209.                                     y = (i == 0) ? (twoPlayerMode ? 6 : 17) : (twoPlayerMode ? 100 : 38);
  1210.  
  1211.                                 fill_rectangle_xy(VGAScreenSeg, x, y, x + 1 + 10 * 2, y + 2, 0);
  1212.  
  1213.                                 for (uint j = 1; j <= item_power; ++j)
  1214.                                 {
  1215.                                         JE_rectangle(VGAScreen, x, y, x + 1, y + 2, 115 + j); /* SEGa000 */
  1216.                                         x += 2;
  1217.                                 }
  1218.                         }
  1219.                 }
  1220.  
  1221.                 /*------------------------Power Bar-------------------------*/
  1222.                 if (twoPlayerMode || onePlayerAction)
  1223.                 {
  1224.                         power = 900;
  1225.                 }
  1226.                 else
  1227.                 {
  1228.                         power += powerAdd;
  1229.                         if (power > 900)
  1230.                                 power = 900;
  1231.  
  1232.                         temp = power / 10;
  1233.  
  1234.                         if (temp != lastPower)
  1235.                         {
  1236.                                 if (temp > lastPower)
  1237.                                         fill_rectangle_xy(VGAScreenSeg, 269, 113 - 11 - temp, 276, 114 - 11 - lastPower, 113 + temp / 7);
  1238.                                 else
  1239.                                         fill_rectangle_xy(VGAScreenSeg, 269, 113 - 11 - lastPower, 276, 114 - 11 - temp, 0);
  1240.                                
  1241.                                 lastPower = temp;
  1242.                         }
  1243.                 }
  1244.  
  1245.                 oldMapX3Ofs = mapX3Ofs;
  1246.  
  1247.                 enemyOnScreen = 0;
  1248.         }
  1249.  
  1250.         /* use game_screen for all the generic drawing functions */
  1251.         VGAScreen = game_screen;
  1252.  
  1253.         /*---------------------------EVENTS-------------------------*/
  1254.         while (eventRec[eventLoc-1].eventtime <= curLoc && eventLoc <= maxEvent)
  1255.                 JE_eventSystem();
  1256.  
  1257.         if (isNetworkGame && reallyEndLevel)
  1258.                 goto start_level;
  1259.  
  1260.  
  1261.         /* SMOOTHIES! */
  1262.         JE_checkSmoothies();
  1263.         if (anySmoothies)
  1264.                 VGAScreen = VGAScreen2;  // this makes things complicated, but we do it anyway :(
  1265.  
  1266.         /* --- BACKGROUNDS --- */
  1267.         /* --- BACKGROUND 1 --- */
  1268.  
  1269.         if (forceEvents && !backMove)
  1270.                 curLoc++;
  1271.  
  1272.         if (map1YDelayMax > 1 && backMove < 2)
  1273.                 backMove = (map1YDelay == 1) ? 1 : 0;
  1274.  
  1275.         /*Draw background*/
  1276.         if (astralDuration == 0)
  1277.                 draw_background_1(VGAScreen);
  1278.         else
  1279.                 JE_clr256(VGAScreen);
  1280.  
  1281.         /*Set Movement of background 1*/
  1282.         if (--map1YDelay == 0)
  1283.         {
  1284.                 map1YDelay = map1YDelayMax;
  1285.  
  1286.                 curLoc += backMove;
  1287.  
  1288.                 backPos += backMove;
  1289.  
  1290.                 if (backPos > 27)
  1291.                 {
  1292.                         backPos -= 28;
  1293.                         mapY--;
  1294.                         mapYPos -= 14;  /*Map Width*/
  1295.                 }
  1296.         }
  1297.  
  1298.         if (starActive || astralDuration > 0)
  1299.         {
  1300.                 update_and_draw_starfield(VGAScreen, starfield_speed);
  1301.         }
  1302.  
  1303.         if (processorType > 1 && smoothies[5-1])
  1304.         {
  1305.                 iced_blur_filter(game_screen, VGAScreen);
  1306.                 VGAScreen = game_screen;
  1307.         }
  1308.  
  1309.         /*-----------------------BACKGROUNDS------------------------*/
  1310.         /*-----------------------BACKGROUND 2------------------------*/
  1311.         if (background2over == 3)
  1312.         {
  1313.                 draw_background_2(VGAScreen);
  1314.                 background2 = true;
  1315.         }
  1316.  
  1317.         if (background2over == 0)
  1318.         {
  1319.                 if (!(smoothies[2-1] && processorType < 4) && !(smoothies[1-1] && processorType == 3))
  1320.                 {
  1321.                         if (wild && !background2notTransparent)
  1322.                                 draw_background_2_blend(VGAScreen);
  1323.                         else
  1324.                                 draw_background_2(VGAScreen);
  1325.                 }
  1326.         }
  1327.  
  1328.         if (smoothies[0] && processorType > 2 && smoothie_data[0] == 0)
  1329.         {
  1330.                 lava_filter(game_screen, VGAScreen);
  1331.                 VGAScreen = game_screen;
  1332.         }
  1333.         if (smoothies[2-1] && processorType > 2)
  1334.         {
  1335.                 water_filter(game_screen, VGAScreen);
  1336.                 VGAScreen = game_screen;
  1337.         }
  1338.  
  1339.         /*-----------------------Ground Enemy------------------------*/
  1340.         lastEnemyOnScreen = enemyOnScreen;
  1341.  
  1342.         tempMapXOfs = mapXOfs;
  1343.         tempBackMove = backMove;
  1344.         JE_drawEnemy(50);
  1345.         JE_drawEnemy(100);
  1346.  
  1347.         if (enemyOnScreen == 0 || enemyOnScreen == lastEnemyOnScreen)
  1348.         {
  1349.                 if (stopBackgroundNum == 1)
  1350.                         stopBackgroundNum = 9;
  1351.         }
  1352.  
  1353.         if (smoothies[0] && processorType > 2 && smoothie_data[0] > 0)
  1354.         {
  1355.                 lava_filter(game_screen, VGAScreen);
  1356.                 VGAScreen = game_screen;
  1357.         }
  1358.  
  1359.         if (superWild)
  1360.         {
  1361.                 neat += 3;
  1362.                 JE_darkenBackground(neat);
  1363.         }
  1364.  
  1365.         /*-----------------------BACKGROUNDS------------------------*/
  1366.         /*-----------------------BACKGROUND 2------------------------*/
  1367.         if (!(smoothies[2-1] && processorType < 4) &&
  1368.             !(smoothies[1-1] && processorType == 3))
  1369.         {
  1370.                 if (background2over == 1)
  1371.                 {
  1372.                         if (wild && !background2notTransparent)
  1373.                                 draw_background_2_blend(VGAScreen);
  1374.                         else
  1375.                                 draw_background_2(VGAScreen);
  1376.                 }
  1377.         }
  1378.  
  1379.         if (superWild)
  1380.         {
  1381.                 neat++;
  1382.                 JE_darkenBackground(neat);
  1383.         }
  1384.  
  1385.         if (background3over == 2)
  1386.                 draw_background_3(VGAScreen);
  1387.  
  1388.         /* New Enemy */
  1389.         if (enemiesActive && mt_rand() % 100 > levelEnemyFrequency)
  1390.         {
  1391.                 tempW = levelEnemy[mt_rand() % levelEnemyMax];
  1392.                 if (tempW == 2)
  1393.                         soundQueue[3] = S_WEAPON_7;
  1394.                 b = JE_newEnemy(0, tempW, 0);
  1395.         }
  1396.  
  1397.         if (processorType > 1 && smoothies[3-1])
  1398.         {
  1399.                 iced_blur_filter(game_screen, VGAScreen);
  1400.                 VGAScreen = game_screen;
  1401.         }
  1402.         if (processorType > 1 && smoothies[4-1])
  1403.         {
  1404.                 blur_filter(game_screen, VGAScreen);
  1405.                 VGAScreen = game_screen;
  1406.         }
  1407.  
  1408.         /* Draw Sky Enemy */
  1409.         if (!skyEnemyOverAll)
  1410.         {
  1411.                 lastEnemyOnScreen = enemyOnScreen;
  1412.  
  1413.                 tempMapXOfs = mapX2Ofs;
  1414.                 tempBackMove = 0;
  1415.                 JE_drawEnemy(25);
  1416.  
  1417.                 if (enemyOnScreen == lastEnemyOnScreen)
  1418.                 {
  1419.                         if (stopBackgroundNum == 2)
  1420.                                 stopBackgroundNum = 9;
  1421.                 }
  1422.         }
  1423.  
  1424.         if (background3over == 0)
  1425.                 draw_background_3(VGAScreen);
  1426.  
  1427.         /* Draw Top Enemy */
  1428.         if (!topEnemyOver)
  1429.         {
  1430.                 tempMapXOfs = (background3x1 == 0) ? oldMapX3Ofs : mapXOfs;
  1431.                 tempBackMove = backMove3;
  1432.                 JE_drawEnemy(75);
  1433.         }
  1434.  
  1435.         /* Player Shot Images */
  1436.         for (int z = 0; z < MAX_PWEAPON; z++)
  1437.         {
  1438.                 if (shotAvail[z] != 0)
  1439.                 {
  1440.                         bool is_special = false;
  1441.                         int tempShotX = 0, tempShotY = 0;
  1442.                         JE_byte chain;
  1443.                         JE_byte playerNum;
  1444.                         JE_word tempX2, tempY2;
  1445.                         JE_integer damage;
  1446.                        
  1447.                         if (!player_shot_move_and_draw(z, &is_special, &tempShotX, &tempShotY, &damage, &temp2, &chain, &playerNum, &tempX2, &tempY2))
  1448.                         {
  1449.                                 goto draw_player_shot_loop_end;
  1450.                         }
  1451.  
  1452.                         for (b = 0; b < 100; b++)
  1453.                         {
  1454.                                 if (enemyAvail[b] == 0)
  1455.                                 {
  1456.                                         bool collided;
  1457.  
  1458.                                         if (z == MAX_PWEAPON - 1)
  1459.                                         {
  1460.                                                 temp = 25 - abs(zinglonDuration - 25);
  1461.                                                 collided = abs(enemy[b].ex + enemy[b].mapoffset - (player[0].x + 7)) < temp;
  1462.                                                 temp2 = 9;
  1463.                                                 chain = 0;
  1464.                                                 damage = 10;
  1465.                                         }
  1466.                                         else if (is_special)
  1467.                                         {
  1468.                                                 collided = ((enemy[b].enemycycle == 0) &&
  1469.                                                             (abs(enemy[b].ex + enemy[b].mapoffset - tempShotX - tempX2) < (25 + tempX2)) &&
  1470.                                                             (abs(enemy[b].ey - tempShotY - 12 - tempY2)                 < (29 + tempY2))) ||
  1471.                                                            ((enemy[b].enemycycle > 0) &&
  1472.                                                             (abs(enemy[b].ex + enemy[b].mapoffset - tempShotX - tempX2) < (13 + tempX2)) &&
  1473.                                                             (abs(enemy[b].ey - tempShotY - 6 - tempY2)                  < (15 + tempY2)));
  1474.                                         }
  1475.                                         else
  1476.                                         {
  1477.                                                 collided = ((enemy[b].enemycycle == 0) &&
  1478.                                                             (abs(enemy[b].ex + enemy[b].mapoffset - tempShotX) < 25) && (abs(enemy[b].ey - tempShotY - 12) < 29)) ||
  1479.                                                            ((enemy[b].enemycycle > 0) &&
  1480.                                                             (abs(enemy[b].ex + enemy[b].mapoffset - tempShotX) < 13) && (abs(enemy[b].ey - tempShotY - 6) < 15));
  1481.                                         }
  1482.  
  1483.                                         if (collided)
  1484.                                         {
  1485.                                                 if (chain > 0)
  1486.                                                 {
  1487.                                                         shotMultiPos[SHOT_MISC] = 0;
  1488.                                                         b = player_shot_create(0, SHOT_MISC, tempShotX, tempShotY, mouseX, mouseY, chain, playerNum);
  1489.                                                         shotAvail[z] = 0;
  1490.                                                         goto draw_player_shot_loop_end;
  1491.                                                 }
  1492.  
  1493.                                                 infiniteShot = false;
  1494.  
  1495.                                                 if (damage == 99)
  1496.                                                 {
  1497.                                                         damage = 0;
  1498.                                                         doIced = 40;
  1499.                                                         enemy[b].iced = 40;
  1500.                                                 }
  1501.                                                 else
  1502.                                                 {
  1503.                                                         doIced = 0;
  1504.                                                         if (damage >= 250)
  1505.                                                         {
  1506.                                                                 damage = damage - 250;
  1507.                                                                 infiniteShot = true;
  1508.                                                         }
  1509.                                                 }
  1510.  
  1511.                                                 int armorleft = enemy[b].armorleft;
  1512.  
  1513.                                                 temp = enemy[b].linknum;
  1514.                                                 if (temp == 0)
  1515.                                                         temp = 255;
  1516.  
  1517.                                                 if (enemy[b].armorleft < 255)
  1518.                                                 {
  1519.                                                         for (unsigned int i = 0; i < COUNTOF(boss_bar); i++)
  1520.                                                                 if (temp == boss_bar[i].link_num)
  1521.                                                                         boss_bar[i].color = 6;
  1522.  
  1523.                                                         if (enemy[b].enemyground)
  1524.                                                                 enemy[b].filter = temp2;
  1525.  
  1526.                                                         for (unsigned int e = 0; e < COUNTOF(enemy); e++)
  1527.                                                         {
  1528.                                                                 if (enemy[e].linknum == temp &&
  1529.                                                                     enemyAvail[e] != 1 &&
  1530.                                                                     enemy[e].enemyground != 0)
  1531.                                                                 {
  1532.                                                                         if (doIced)
  1533.                                                                                 enemy[e].iced = doIced;
  1534.                                                                         enemy[e].filter = temp2;
  1535.                                                                 }
  1536.                                                         }
  1537.                                                 }
  1538.  
  1539.                                                 if (armorleft > damage)
  1540.                                                 {
  1541.                                                         if (z != MAX_PWEAPON - 1)
  1542.                                                         {
  1543.                                                                 if (enemy[b].armorleft != 255)
  1544.                                                                 {
  1545.                                                                         enemy[b].armorleft -= damage;
  1546.                                                                         JE_setupExplosion(tempShotX, tempShotY, 0, 0, false, false);
  1547.                                                                 }
  1548.                                                                 else
  1549.                                                                 {
  1550.                                                                         JE_doSP(tempShotX + 6, tempShotY + 6, damage / 2 + 3, damage / 4 + 2, temp2);
  1551.                                                                 }
  1552.                                                         }
  1553.  
  1554.                                                         soundQueue[5] = S_ENEMY_HIT;
  1555.  
  1556.                                                         if ((armorleft - damage <= enemy[b].edlevel) &&
  1557.                                                             ((!enemy[b].edamaged) ^ (enemy[b].edani < 0)))
  1558.                                                         {
  1559.  
  1560.                                                                 for (temp3 = 0; temp3 < 100; temp3++)
  1561.                                                                 {
  1562.                                                                         if (enemyAvail[temp3] != 1)
  1563.                                                                         {
  1564.                                                                                 int linknum = enemy[temp3].linknum;
  1565.                                                                                 if (
  1566.                                                                                      (temp3 == b) ||
  1567.                                                                                      (
  1568.                                                                                        (temp != 255) &&
  1569.                                                                                        (
  1570.                                                                                          ((enemy[temp3].edlevel > 0) && (linknum == temp)) ||
  1571.                                                                                          (
  1572.                                                                                            (enemyContinualDamage && (temp - 100 == linknum)) ||
  1573.                                                                                            ((linknum > 40) && (linknum / 20 == temp / 20) && (linknum <= temp))
  1574.                                                                                          )
  1575.                                                                                        )
  1576.                                                                                      )
  1577.                                                                                    )
  1578.                                                                                 {
  1579.                                                                                         enemy[temp3].enemycycle = 1;
  1580.  
  1581.                                                                                         enemy[temp3].edamaged = !enemy[temp3].edamaged;
  1582.  
  1583.                                                                                         if (enemy[temp3].edani != 0)
  1584.                                                                                         {
  1585.                                                                                                 enemy[temp3].ani = abs(enemy[temp3].edani);
  1586.                                                                                                 enemy[temp3].aniactive = 1;
  1587.                                                                                                 enemy[temp3].animax = 0;
  1588.                                                                                                 enemy[temp3].animin = enemy[temp3].edgr;
  1589.                                                                                                 enemy[temp3].enemycycle = enemy[temp3].animin - 1;
  1590.  
  1591.                                                                                         }
  1592.                                                                                         else if (enemy[temp3].edgr > 0)
  1593.                                                                                         {
  1594.                                                                                                 enemy[temp3].egr[1-1] = enemy[temp3].edgr;
  1595.                                                                                                 enemy[temp3].ani = 1;
  1596.                                                                                                 enemy[temp3].aniactive = 0;
  1597.                                                                                                 enemy[temp3].animax = 0;
  1598.                                                                                                 enemy[temp3].animin = 1;
  1599.                                                                                         }
  1600.                                                                                         else
  1601.                                                                                         {
  1602.                                                                                                 enemyAvail[temp3] = 1;
  1603.                                                                                                 enemyKilled++;
  1604.                                                                                         }
  1605.  
  1606.                                                                                         enemy[temp3].aniwhenfire = 0;
  1607.  
  1608.                                                                                         if (enemy[temp3].armorleft > (unsigned char)enemy[temp3].edlevel)
  1609.                                                                                                 enemy[temp3].armorleft = enemy[temp3].edlevel;
  1610.  
  1611.                                                                                         tempX = enemy[temp3].ex + enemy[temp3].mapoffset;
  1612.                                                                                         tempY = enemy[temp3].ey;
  1613.  
  1614.                                                                                         if (enemyDat[enemy[temp3].enemytype].esize != 1)
  1615.                                                                                                 JE_setupExplosion(tempX, tempY - 6, 0, 1, false, false);
  1616.                                                                                         else
  1617.                                                                                                 JE_setupExplosionLarge(enemy[temp3].enemyground, enemy[temp3].explonum / 2, tempX, tempY);
  1618.                                                                                 }
  1619.                                                                         }
  1620.                                                                 }
  1621.                                                         }
  1622.                                                 }
  1623.                                                 else
  1624.                                                 {
  1625.  
  1626.                                                         if ((temp == 254) && (superEnemy254Jump > 0))
  1627.                                                                 JE_eventJump(superEnemy254Jump);
  1628.  
  1629.                                                         for (temp2 = 0; temp2 < 100; temp2++)
  1630.                                                         {
  1631.                                                                 if (enemyAvail[temp2] != 1)
  1632.                                                                 {
  1633.                                                                         temp3 = enemy[temp2].linknum;
  1634.                                                                         if ((temp2 == b) || (temp == 254) ||
  1635.                                                                             ((temp != 255) && ((temp == temp3) || (temp - 100 == temp3)
  1636.                                                                             || ((temp3 > 40) && (temp3 / 20 == temp / 20) && (temp3 <= temp)))))
  1637.                                                                         {
  1638.  
  1639.                                                                                 int enemy_screen_x = enemy[temp2].ex + enemy[temp2].mapoffset;
  1640.  
  1641.                                                                                 if (enemy[temp2].special)
  1642.                                                                                 {
  1643.                                                                                         assert((unsigned int) enemy[temp2].flagnum-1 < COUNTOF(globalFlags));
  1644.                                                                                         globalFlags[enemy[temp2].flagnum-1] = enemy[temp2].setto;
  1645.                                                                                 }
  1646.  
  1647.                                                                                 if ((enemy[temp2].enemydie > 0) &&
  1648.                                                                                     !((superArcadeMode != SA_NONE) &&
  1649.                                                                                       (enemyDat[enemy[temp2].enemydie].value == 30000)))
  1650.                                                                                 {
  1651.                                                                                         int temp_b = b;
  1652.                                                                                         tempW = enemy[temp2].enemydie;
  1653.                                                                                         int enemy_offset = temp2 - (temp2 % 25);
  1654.                                                                                         if (enemyDat[tempW].value > 30000)
  1655.                                                                                         {
  1656.                                                                                                 enemy_offset = 0;
  1657.                                                                                         }
  1658.                                                                                         b = JE_newEnemy(enemy_offset, tempW, 0);
  1659.                                                                                         if (b != 0) {
  1660.                                                                                                 if ((superArcadeMode != SA_NONE) && (enemy[b-1].evalue > 30000))
  1661.                                                                                                 {
  1662.                                                                                                         superArcadePowerUp++;
  1663.                                                                                                         if (superArcadePowerUp > 5)
  1664.                                                                                                                 superArcadePowerUp = 1;
  1665.                                                                                                         enemy[b-1].egr[1-1] = 5 + superArcadePowerUp * 2;
  1666.                                                                                                         enemy[b-1].evalue = 30000 + superArcadePowerUp;
  1667.                                                                                                 }
  1668.  
  1669.                                                                                                 if (enemy[b-1].evalue != 0)
  1670.                                                                                                         enemy[b-1].scoreitem = true;
  1671.                                                                                                 else
  1672.                                                                                                         enemy[b-1].scoreitem = false;
  1673.  
  1674.                                                                                                 enemy[b-1].ex = enemy[temp2].ex;
  1675.                                                                                                 enemy[b-1].ey = enemy[temp2].ey;
  1676.                                                                                         }
  1677.                                                                                         b = temp_b;
  1678.                                                                                 }
  1679.  
  1680.                                                                                 if ((enemy[temp2].evalue > 0) && (enemy[temp2].evalue < 10000))
  1681.                                                                                 {
  1682.                                                                                         if (enemy[temp2].evalue == 1)
  1683.                                                                                         {
  1684.                                                                                                 cubeMax++;
  1685.                                                                                         }
  1686.                                                                                         else
  1687.                                                                                         {
  1688.                                                                                                 // in galaga mode player 2 is sidekick, so give cash to player 1
  1689.                                                                                                 player[galagaMode ? 0 : playerNum - 1].cash += enemy[temp2].evalue;
  1690.                                                                                         }
  1691.                                                                                 }
  1692.  
  1693.                                                                                 if ((enemy[temp2].edlevel == -1) && (temp == temp3))
  1694.                                                                                 {
  1695.                                                                                         enemy[temp2].edlevel = 0;
  1696.                                                                                         enemyAvail[temp2] = 2;
  1697.                                                                                         enemy[temp2].egr[1-1] = enemy[temp2].edgr;
  1698.                                                                                         enemy[temp2].ani = 1;
  1699.                                                                                         enemy[temp2].aniactive = 0;
  1700.                                                                                         enemy[temp2].animax = 0;
  1701.                                                                                         enemy[temp2].animin = 1;
  1702.                                                                                         enemy[temp2].edamaged = true;
  1703.                                                                                         enemy[temp2].enemycycle = 1;
  1704.                                                                                 } else {
  1705.                                                                                         enemyAvail[temp2] = 1;
  1706.                                                                                         enemyKilled++;
  1707.                                                                                 }
  1708.  
  1709.                                                                                 if (enemyDat[enemy[temp2].enemytype].esize == 1)
  1710.                                                                                 {
  1711.                                                                                         JE_setupExplosionLarge(enemy[temp2].enemyground, enemy[temp2].explonum, enemy_screen_x, enemy[temp2].ey);
  1712.                                                                                         soundQueue[6] = S_EXPLOSION_9;
  1713.                                                                                 }
  1714.                                                                                 else
  1715.                                                                                 {
  1716.                                                                                         JE_setupExplosion(enemy_screen_x, enemy[temp2].ey, 0, 1, false, false);
  1717.                                                                                         soundQueue[6] = S_EXPLOSION_8;
  1718.                                                                                 }
  1719.                                                                         }
  1720.                                                                 }
  1721.                                                         }
  1722.                                                 }
  1723.  
  1724.                                                 if (infiniteShot)
  1725.                                                 {
  1726.                                                         damage += 250;
  1727.                                                 }
  1728.                                                 else if (z != MAX_PWEAPON - 1)
  1729.                                                 {
  1730.                                                         if (damage <= armorleft)
  1731.                                                         {
  1732.                                                                 shotAvail[z] = 0;
  1733.                                                                 goto draw_player_shot_loop_end;
  1734.                                                         }
  1735.                                                         else
  1736.                                                         {
  1737.                                                                 playerShotData[z].shotDmg -= armorleft;
  1738.                                                         }
  1739.                                                 }
  1740.                                         }
  1741.                                 }
  1742.                         }
  1743.  
  1744. draw_player_shot_loop_end:
  1745.                         ;
  1746.                 }
  1747.         }
  1748.  
  1749.         /* Player movement indicators for shots that track your ship */
  1750.         for (uint i = 0; i < COUNTOF(player); ++i)
  1751.         {
  1752.                 player[i].last_x_shot_move = player[i].x;
  1753.                 player[i].last_y_shot_move = player[i].y;
  1754.         }
  1755.        
  1756.         /*=================================*/
  1757.         /*=======Collisions Detection======*/
  1758.         /*=================================*/
  1759.        
  1760.         for (uint i = 0; i < (twoPlayerMode ? 2 : 1); ++i)
  1761.                 if (player[i].is_alive && !endLevel)
  1762.                         JE_playerCollide(&player[i], i + 1);
  1763.        
  1764.         if (firstGameOver)
  1765.                 JE_mainGamePlayerFunctions();      /*--------PLAYER DRAW+MOVEMENT---------*/
  1766.  
  1767.         if (!endLevel)
  1768.         {    /*MAIN DRAWING IS STOPPED STARTING HERE*/
  1769.  
  1770.                 /* Draw Enemy Shots */
  1771.                 for (int z = 0; z < ENEMY_SHOT_MAX; z++)
  1772.                 {
  1773.                         if (enemyShotAvail[z] == 0)
  1774.                         {
  1775.                                 enemyShot[z].sxm += enemyShot[z].sxc;
  1776.                                 enemyShot[z].sx += enemyShot[z].sxm;
  1777.  
  1778.                                 if (enemyShot[z].tx != 0)
  1779.                                 {
  1780.                                         if (enemyShot[z].sx > player[0].x)
  1781.                                         {
  1782.                                                 if (enemyShot[z].sxm > -enemyShot[z].tx)
  1783.                                                 {
  1784.                                                         enemyShot[z].sxm--;
  1785.                                                 }
  1786.                                         } else {
  1787.                                                 if (enemyShot[z].sxm < enemyShot[z].tx)
  1788.                                                 {
  1789.                                                         enemyShot[z].sxm++;
  1790.                                                 }
  1791.                                         }
  1792.                                 }
  1793.  
  1794.                                 enemyShot[z].sym += enemyShot[z].syc;
  1795.                                 enemyShot[z].sy += enemyShot[z].sym;
  1796.  
  1797.                                 if (enemyShot[z].ty != 0)
  1798.                                 {
  1799.                                         if (enemyShot[z].sy > player[0].y)
  1800.                                         {
  1801.                                                 if (enemyShot[z].sym > -enemyShot[z].ty)
  1802.                                                 {
  1803.                                                         enemyShot[z].sym--;
  1804.                                                 }
  1805.                                         } else {
  1806.                                                 if (enemyShot[z].sym < enemyShot[z].ty)
  1807.                                                 {
  1808.                                                         enemyShot[z].sym++;
  1809.                                                 }
  1810.                                         }
  1811.                                 }
  1812.  
  1813.                                 if (enemyShot[z].duration-- == 0 || enemyShot[z].sy > 190 || enemyShot[z].sy <= -14 || enemyShot[z].sx > 275 || enemyShot[z].sx <= 0)
  1814.                                 {
  1815.                                         enemyShotAvail[z] = true;
  1816.                                 }
  1817.                                 else  // check if shot collided with player
  1818.                                 {
  1819.                                         for (uint i = 0; i < (twoPlayerMode ? 2 : 1); ++i)
  1820.                                         {
  1821.                                                 if (player[i].is_alive &&
  1822.                                                     enemyShot[z].sx > player[i].x - (signed)player[i].shot_hit_area_x &&
  1823.                                                     enemyShot[z].sx < player[i].x + (signed)player[i].shot_hit_area_x &&
  1824.                                                     enemyShot[z].sy > player[i].y - (signed)player[i].shot_hit_area_y &&
  1825.                                                     enemyShot[z].sy < player[i].y + (signed)player[i].shot_hit_area_y)
  1826.                                                 {
  1827.                                                         tempX = enemyShot[z].sx;
  1828.                                                         tempY = enemyShot[z].sy;
  1829.                                                         temp = enemyShot[z].sdmg;
  1830.  
  1831.                                                         enemyShotAvail[z] = true;
  1832.  
  1833.                                                         JE_setupExplosion(tempX, tempY, 0, 0, false, false);
  1834.  
  1835.                                                         if (player[i].invulnerable_ticks == 0)
  1836.                                                         {
  1837.                                                                 if ((temp = JE_playerDamage(temp, &player[i])) > 0)
  1838.                                                                 {
  1839.                                                                         player[i].x_velocity += (enemyShot[z].sxm * temp) / 2;
  1840.                                                                         player[i].y_velocity += (enemyShot[z].sym * temp) / 2;
  1841.                                                                 }
  1842.                                                         }
  1843.  
  1844.                                                         break;
  1845.                                                 }
  1846.                                         }
  1847.  
  1848.                                         if (enemyShotAvail[z] == false)
  1849.                                         {
  1850.                                                 if (enemyShot[z].animax != 0)
  1851.                                                 {
  1852.                                                         if (++enemyShot[z].animate >= enemyShot[z].animax)
  1853.                                                                 enemyShot[z].animate = 0;
  1854.                                                 }
  1855.  
  1856.                                                 if (enemyShot[z].sgr >= 500)
  1857.                                                         blit_sprite2(VGAScreen, enemyShot[z].sx, enemyShot[z].sy, shapesW2, enemyShot[z].sgr + enemyShot[z].animate - 500);
  1858.                                                 else
  1859.                                                         blit_sprite2(VGAScreen, enemyShot[z].sx, enemyShot[z].sy, shapesC1, enemyShot[z].sgr + enemyShot[z].animate);
  1860.                                         }
  1861.                                 }
  1862.  
  1863.                         }
  1864.                 }
  1865.         }
  1866.  
  1867.         if (background3over == 1)
  1868.                 draw_background_3(VGAScreen);
  1869.  
  1870.         /* Draw Top Enemy */
  1871.         if (topEnemyOver)
  1872.         {
  1873.                 tempMapXOfs = (background3x1 == 0) ? oldMapX3Ofs : oldMapXOfs;
  1874.                 tempBackMove = backMove3;
  1875.                 JE_drawEnemy(75);
  1876.         }
  1877.  
  1878.         /* Draw Sky Enemy */
  1879.         if (skyEnemyOverAll)
  1880.         {
  1881.                 lastEnemyOnScreen = enemyOnScreen;
  1882.  
  1883.                 tempMapXOfs = mapX2Ofs;
  1884.                 tempBackMove = 0;
  1885.                 JE_drawEnemy(25);
  1886.  
  1887.                 if (enemyOnScreen == lastEnemyOnScreen)
  1888.                 {
  1889.                         if (stopBackgroundNum == 2)
  1890.                                 stopBackgroundNum = 9;
  1891.                 }
  1892.         }
  1893.  
  1894.         /*-------------------------- Sequenced Explosions -------------------------*/
  1895.         enemyStillExploding = false;
  1896.         for (int i = 0; i < MAX_REPEATING_EXPLOSIONS; i++)
  1897.         {
  1898.                 if (rep_explosions[i].ttl != 0)
  1899.                 {
  1900.                         enemyStillExploding = true;
  1901.  
  1902.                         if (rep_explosions[i].delay > 0)
  1903.                         {
  1904.                                 rep_explosions[i].delay--;
  1905.                                 continue;
  1906.                         }
  1907.  
  1908.                         rep_explosions[i].y += backMove2 + 1;
  1909.                         tempX = rep_explosions[i].x + (mt_rand() % 24) - 12;
  1910.                         tempY = rep_explosions[i].y + (mt_rand() % 27) - 24;
  1911.  
  1912.                         if (rep_explosions[i].big)
  1913.                         {
  1914.                                 JE_setupExplosionLarge(false, 2, tempX, tempY);
  1915.  
  1916.                                 if (rep_explosions[i].ttl == 1 || mt_rand() % 5 == 1)
  1917.                                         soundQueue[7] = S_EXPLOSION_11;
  1918.                                 else
  1919.                                         soundQueue[6] = S_EXPLOSION_9;
  1920.  
  1921.                                 rep_explosions[i].delay = 4 + (mt_rand() % 3);
  1922.                         }
  1923.                         else
  1924.                         {
  1925.                                 JE_setupExplosion(tempX, tempY, 0, 1, false, false);
  1926.  
  1927.                                 soundQueue[5] = S_EXPLOSION_4;
  1928.  
  1929.                                 rep_explosions[i].delay = 3;
  1930.                         }
  1931.  
  1932.                         rep_explosions[i].ttl--;
  1933.                 }
  1934.         }
  1935.  
  1936.         /*---------------------------- Draw Explosions ----------------------------*/
  1937.         for (int j = 0; j < MAX_EXPLOSIONS; j++)
  1938.         {
  1939.                 if (explosions[j].ttl != 0)
  1940.                 {
  1941.                         if (explosions[j].fixed_position != true)
  1942.                         {
  1943.                                 explosions[j].sprite++;
  1944.                                 explosions[j].y += explodeMove;
  1945.                         }
  1946.                         else if (explosions[j].follow_player == true)
  1947.                         {
  1948.                                 explosions[j].x += explosionFollowAmountX;
  1949.                                 explosions[j].y += explosionFollowAmountY;
  1950.                         }
  1951.                         explosions[j].y += explosions[j].delta_y;
  1952.                         explosions[j].x += explosions[j].delta_x;
  1953.  
  1954.                         if (explosions[j].y > 200 - 14)
  1955.                         {
  1956.                                 explosions[j].ttl = 0;
  1957.                         }
  1958.                         else
  1959.                         {
  1960.                                 if (explosionTransparent)
  1961.                                         blit_sprite2_blend(VGAScreen, explosions[j].x, explosions[j].y, shapes6, explosions[j].sprite + 1);
  1962.                                 else
  1963.                                         blit_sprite2(VGAScreen, explosions[j].x, explosions[j].y, shapes6, explosions[j].sprite + 1);
  1964.  
  1965.                                 explosions[j].ttl--;
  1966.                         }
  1967.                 }
  1968.         }
  1969.  
  1970.         if (!portConfigChange)
  1971.                 portConfigDone = true;
  1972.  
  1973.  
  1974.         /*-----------------------BACKGROUNDS------------------------*/
  1975.         /*-----------------------BACKGROUND 2------------------------*/
  1976.         if (!(smoothies[2-1] && processorType < 4) &&
  1977.             !(smoothies[1-1] && processorType == 3))
  1978.         {
  1979.                 if (background2over == 2)
  1980.                 {
  1981.                         if (wild && !background2notTransparent)
  1982.                                 draw_background_2_blend(VGAScreen);
  1983.                         else
  1984.                                 draw_background_2(VGAScreen);
  1985.                 }
  1986.         }
  1987.  
  1988.         /*-------------------------Warning---------------------------*/
  1989.         if ((player[0].is_alive && player[0].armor < 6) ||
  1990.             (twoPlayerMode && !galagaMode && player[1].is_alive && player[1].armor < 6))
  1991.         {
  1992.                 int armor_amount = (player[0].is_alive && player[0].armor < 6) ? player[0].armor : player[1].armor;
  1993.  
  1994.                 if (armorShipDelay > 0)
  1995.                 {
  1996.                         armorShipDelay--;
  1997.                 }
  1998.                 else
  1999.                 {
  2000.                         tempW = 560;
  2001.                         b = JE_newEnemy(50, tempW, 0);
  2002.                         if (b > 0)
  2003.                         {
  2004.                                 enemy[b-1].enemydie = 560 + (mt_rand() % 3) + 1;
  2005.                                 enemy[b-1].eyc -= backMove3;
  2006.                                 enemy[b-1].armorleft = 4;
  2007.                         }
  2008.                         armorShipDelay = 500;
  2009.                 }
  2010.  
  2011.                 if ((player[0].is_alive && player[0].armor < 6 && (!isNetworkGame || thisPlayerNum == 1)) ||
  2012.                     (twoPlayerMode && player[1].is_alive && player[1].armor < 6 && (!isNetworkGame || thisPlayerNum == 2)))
  2013.                 {
  2014.  
  2015.                         tempW = armor_amount * 4 + 8;
  2016.                         if (warningSoundDelay > tempW)
  2017.                                 warningSoundDelay = tempW;
  2018.  
  2019.                         if (warningSoundDelay > 1)
  2020.                         {
  2021.                                 warningSoundDelay--;
  2022.                         }
  2023.                         else
  2024.                         {
  2025.                                 soundQueue[7] = S_WARNING;
  2026.                                 warningSoundDelay = tempW;
  2027.                         }
  2028.  
  2029.                         warningCol += warningColChange;
  2030.                         if (warningCol > 113 + (14 - (armor_amount * 2)))
  2031.                         {
  2032.                                 warningColChange = -warningColChange;
  2033.                                 warningCol = 113 + (14 - (armor_amount * 2));
  2034.                         }
  2035.                         else if (warningCol < 113)
  2036.                         {
  2037.                                 warningColChange = -warningColChange;
  2038.                         }
  2039.                         fill_rectangle_xy(VGAScreen, 24, 181, 138, 183, warningCol);
  2040.                         fill_rectangle_xy(VGAScreen, 175, 181, 287, 183, warningCol);
  2041.                         fill_rectangle_xy(VGAScreen, 24, 0, 287, 3, warningCol);
  2042.  
  2043.                         JE_outText(VGAScreen, 140, 178, "WARNING", 7, (warningCol % 16) / 2);
  2044.  
  2045.                 }
  2046.         }
  2047.  
  2048.         /*------- Random Explosions --------*/
  2049.         if (randomExplosions && mt_rand() % 10 == 1)
  2050.                 JE_setupExplosionLarge(false, 20, mt_rand() % 280, mt_rand() % 180);
  2051.  
  2052.         /*=================================*/
  2053.         /*=======The Sound Routine=========*/
  2054.         /*=================================*/
  2055.         if (firstGameOver)
  2056.         {
  2057.                 temp = 0;
  2058.                 for (temp2 = 0; temp2 < SFX_CHANNELS; temp2++)
  2059.                 {
  2060.                         if (soundQueue[temp2] != S_NONE)
  2061.                         {
  2062.                                 temp = soundQueue[temp2];
  2063.                                 if (temp2 == 3)
  2064.                                         temp3 = fxPlayVol;
  2065.                                 else if (temp == 15)
  2066.                                         temp3 = fxPlayVol / 4;
  2067.                                 else   /*Lightning*/
  2068.                                         temp3 = fxPlayVol / 2;
  2069.  
  2070.                                 JE_multiSamplePlay(digiFx[temp-1], fxSize[temp-1], temp2, temp3);
  2071.  
  2072.                                 soundQueue[temp2] = S_NONE;
  2073.                         }
  2074.                 }
  2075.         }
  2076.  
  2077.         if (returnActive && enemyOnScreen == 0)
  2078.         {
  2079.                 JE_eventJump(65535);
  2080.                 returnActive = false;
  2081.         }
  2082.  
  2083.         /*-------      DEbug      ---------*/
  2084.         debugTime = SDL_GetTicks();
  2085.         tempW = lastmouse_but;
  2086.         tempX = mouse_x;
  2087.         tempY = mouse_y;
  2088.  
  2089.         if (debug)
  2090.         {
  2091.                 for (size_t i = 0; i < 9; i++)
  2092.                 {
  2093.                         tempStr[i] = '0' + smoothies[i];
  2094.                 }
  2095.                 tempStr[9] = '\0';
  2096.                 sprintf(buffer, "SM = %s", tempStr);
  2097.                 JE_outText(VGAScreen, 30, 70, buffer, 4, 0);
  2098.  
  2099.                 sprintf(buffer, "Memory left = %d", -1);
  2100.                 JE_outText(VGAScreen, 30, 80, buffer, 4, 0);
  2101.                 sprintf(buffer, "Enemies onscreen = %d", enemyOnScreen);
  2102.                 JE_outText(VGAScreen, 30, 90, buffer, 6, 0);
  2103.  
  2104.                 debugHist = debugHist + abs((JE_longint)debugTime - (JE_longint)lastDebugTime);
  2105.                 debugHistCount++;
  2106.                 sprintf(tempStr, "%2.3f", 1000.0f / roundf(debugHist / debugHistCount));
  2107.                 sprintf(buffer, "X:%d Y:%-5d  %s FPS  %d %d %d %d", (mapX - 1) * 12 + player[0].x, curLoc, tempStr, player[0].x_velocity, player[0].y_velocity, player[0].x, player[0].y);
  2108.                 JE_outText(VGAScreen, 45, 175, buffer, 15, 3);
  2109.                 lastDebugTime = debugTime;
  2110.         }
  2111.  
  2112.         if (displayTime > 0)
  2113.         {
  2114.                 displayTime--;
  2115.                 JE_outTextAndDarken(VGAScreen, 90, 10, miscText[59], 15, (JE_byte)flash - 8, FONT_SHAPES);
  2116.                 flash += flashChange;
  2117.                 if (flash > 4 || flash == 0)
  2118.                         flashChange = -flashChange;
  2119.         }
  2120.  
  2121.         /*Pentium Speed Mode?*/
  2122.         if (pentiumMode)
  2123.         {
  2124.                 frameCountMax = (frameCountMax == 2) ? 3 : 2;
  2125.         }
  2126.  
  2127.         /*--------  Level Timer    ---------*/
  2128.         if (levelTimer && levelTimerCountdown > 0)
  2129.         {
  2130.                 levelTimerCountdown--;
  2131.                 if (levelTimerCountdown == 0)
  2132.                         JE_eventJump(levelTimerJumpTo);
  2133.  
  2134.                 if (levelTimerCountdown > 200)
  2135.                 {
  2136.                         if (levelTimerCountdown % 100 == 0)
  2137.                                 soundQueue[7] = S_WARNING;
  2138.  
  2139.                         if (levelTimerCountdown % 10 == 0)
  2140.                                 soundQueue[6] = S_CLICK;
  2141.                 }
  2142.                 else if (levelTimerCountdown % 20 == 0)
  2143.                 {
  2144.                         soundQueue[7] = S_WARNING;
  2145.                 }
  2146.  
  2147.                 JE_textShade (VGAScreen, 140, 6, miscText[66], 7, (levelTimerCountdown % 20) / 3, FULL_SHADE);
  2148.                 sprintf(buffer, "%.1f", levelTimerCountdown / 100.0f);
  2149.                 JE_dString (VGAScreen, 100, 2, buffer, SMALL_FONT_SHAPES);
  2150.         }
  2151.  
  2152.         /*GAME OVER*/
  2153.         if (!constantPlay && !constantDie)
  2154.         {
  2155.                 if (allPlayersGone)
  2156.                 {
  2157.                         if (player[0].exploding_ticks > 0 || player[1].exploding_ticks > 0)
  2158.                         {
  2159.                                 if (galagaMode)
  2160.                                         player[1].exploding_ticks = 0;
  2161.  
  2162.                                 musicFade = true;
  2163.                         }
  2164.                         else
  2165.                         {
  2166.                                 if (play_demo || normalBonusLevelCurrent || bonusLevelCurrent)
  2167.                                         reallyEndLevel = true;
  2168.                                 else
  2169.                                         JE_dString(VGAScreen, 120, 60, miscText[21], FONT_SHAPES); // game over
  2170.  
  2171.                                 set_mouse_position(159, 100);
  2172.                                 if (firstGameOver)
  2173.                                 {
  2174.                                         if (!play_demo)
  2175.                                         {
  2176.                                                 play_song(SONG_GAMEOVER);
  2177.                                                 set_volume(tyrMusicVolume, fxVolume);
  2178.                                         }
  2179.                                         firstGameOver = false;
  2180.                                 }
  2181.  
  2182.                                 if (!play_demo)
  2183.                                 {
  2184.                                         push_joysticks_as_keyboard();
  2185.                                         service_SDL_events(true);
  2186.                                         if ((newkey || button[0] || button[1] || button[2]) || newmouse)
  2187.                                         {
  2188.                                                 reallyEndLevel = true;
  2189.                                         }
  2190.                                 }
  2191.  
  2192.                                 if (isNetworkGame)
  2193.                                         reallyEndLevel = true;
  2194.                         }
  2195.                 }
  2196.         }
  2197.  
  2198.         if (play_demo) // input kills demo
  2199.         {
  2200.                 push_joysticks_as_keyboard();
  2201.                 service_SDL_events(false);
  2202.  
  2203.                 if (newkey || newmouse)
  2204.                 {
  2205.                         reallyEndLevel = true;
  2206.  
  2207.                         stopped_demo = true;
  2208.                 }
  2209.         }
  2210.         else // input handling for pausing, menu, cheats
  2211.         {
  2212.                 service_SDL_events(false);
  2213.  
  2214.                 if (newkey)
  2215.                 {
  2216.                         skipStarShowVGA = false;
  2217.                         JE_mainKeyboardInput();
  2218.                         newkey = false;
  2219.                         if (skipStarShowVGA)
  2220.                                 goto level_loop;
  2221.                 }
  2222.  
  2223.                 if (pause_pressed)
  2224.                 {
  2225.                         pause_pressed = false;
  2226.  
  2227.                         if (isNetworkGame)
  2228.                                 pauseRequest = true;
  2229.                         else
  2230.                                 JE_pauseGame();
  2231.                 }
  2232.  
  2233.                 if (ingamemenu_pressed)
  2234.                 {
  2235.                         ingamemenu_pressed = false;
  2236.  
  2237.                         if (isNetworkGame)
  2238.                         {
  2239.                                 inGameMenuRequest = true;
  2240.                         }
  2241.                         else
  2242.                         {
  2243.                                 yourInGameMenuRequest = true;
  2244.                                 JE_doInGameSetup();
  2245.                                 skipStarShowVGA = true;
  2246.                         }
  2247.                 }
  2248.         }
  2249.  
  2250.         /*Network Update*/
  2251. #ifdef WITH_NETWORK
  2252.         if (isNetworkGame)
  2253.         {
  2254.                 if (!reallyEndLevel)
  2255.                 {
  2256.                         Uint16 requests = (pauseRequest == true) |
  2257.                                           (inGameMenuRequest == true) << 1 |
  2258.                                           (skipLevelRequest == true) << 2 |
  2259.                                           (nortShipRequest == true) << 3;
  2260.                         SDLNet_Write16(requests,        &packet_state_out[0]->data[14]);
  2261.  
  2262.                         SDLNet_Write16(difficultyLevel, &packet_state_out[0]->data[16]);
  2263.                         SDLNet_Write16(player[0].x,     &packet_state_out[0]->data[18]);
  2264.                         SDLNet_Write16(player[1].x,     &packet_state_out[0]->data[20]);
  2265.                         SDLNet_Write16(player[0].y,     &packet_state_out[0]->data[22]);
  2266.                         SDLNet_Write16(player[1].y,     &packet_state_out[0]->data[24]);
  2267.                         SDLNet_Write16(curLoc,          &packet_state_out[0]->data[26]);
  2268.  
  2269.                         network_state_send();
  2270.  
  2271.                         if (network_state_update())
  2272.                         {
  2273.                                 assert(SDLNet_Read16(&packet_state_in[0]->data[26]) == SDLNet_Read16(&packet_state_out[network_delay]->data[26]));
  2274.  
  2275.                                 requests = SDLNet_Read16(&packet_state_in[0]->data[14]) ^ SDLNet_Read16(&packet_state_out[network_delay]->data[14]);
  2276.                                 if (requests & 1)
  2277.                                 {
  2278.                                         JE_pauseGame();
  2279.                                 }
  2280.                                 if (requests & 2)
  2281.                                 {
  2282.                                         yourInGameMenuRequest = SDLNet_Read16(&packet_state_out[network_delay]->data[14]) & 2;
  2283.                                         JE_doInGameSetup();
  2284.                                         yourInGameMenuRequest = false;
  2285.                                         if (haltGame)
  2286.                                                 reallyEndLevel = true;
  2287.                                 }
  2288.                                 if (requests & 4)
  2289.                                 {
  2290.                                         levelTimer = true;
  2291.                                         levelTimerCountdown = 0;
  2292.                                         endLevel = true;
  2293.                                         levelEnd = 40;
  2294.                                 }
  2295.                                 if (requests & 8) // nortship
  2296.                                 {
  2297.                                         player[0].items.ship = 12;                     // Nort Ship
  2298.                                         player[0].items.special = 13;                  // Astral Zone
  2299.                                         player[0].items.weapon[FRONT_WEAPON].id = 36;  // NortShip Super Pulse
  2300.                                         player[0].items.weapon[REAR_WEAPON].id = 37;   // NortShip Spreader
  2301.                                         shipGr = 1;
  2302.                                 }
  2303.  
  2304.                                 for (int i = 0; i < 2; i++)
  2305.                                 {
  2306.                                         if (SDLNet_Read16(&packet_state_in[0]->data[18 + i * 2]) != SDLNet_Read16(&packet_state_out[network_delay]->data[18 + i * 2]) || SDLNet_Read16(&packet_state_in[0]->data[20 + i * 2]) != SDLNet_Read16(&packet_state_out[network_delay]->data[20 + i * 2]))
  2307.                                         {
  2308.                                                 char temp[64];
  2309.                                                 sprintf(temp, "Player %d is unsynchronized!", i + 1);
  2310.  
  2311.                                                 JE_textShade(game_screen, 40, 110 + i * 10, temp, 9, 2, FULL_SHADE);
  2312.                                         }
  2313.                                 }
  2314.                         }
  2315.                 }
  2316.  
  2317.                 JE_clearSpecialRequests();
  2318.         }
  2319. #endif
  2320.  
  2321.         /** Test **/
  2322.         JE_drawSP();
  2323.  
  2324.         /*Filtration*/
  2325.         if (filterActive)
  2326.         {
  2327.                 JE_filterScreen(levelFilter, levelBrightness);
  2328.         }
  2329.  
  2330.         draw_boss_bar();
  2331.  
  2332.         JE_inGameDisplays();
  2333.  
  2334.         VGAScreen = VGAScreenSeg; /* side-effect of game_screen */
  2335.  
  2336.         JE_starShowVGA();
  2337.  
  2338.         /*Start backgrounds if no enemies on screen
  2339.           End level if number of enemies left to kill equals 0.*/
  2340.         if (stopBackgroundNum == 9 && backMove == 0 && !enemyStillExploding)
  2341.         {
  2342.                 backMove = 1;
  2343.                 backMove2 = 2;
  2344.                 backMove3 = 3;
  2345.                 explodeMove = 2;
  2346.                 stopBackgroundNum = 0;
  2347.                 stopBackgrounds = false;
  2348.                 if (waitToEndLevel)
  2349.                 {
  2350.                         endLevel = true;
  2351.                         levelEnd = 40;
  2352.                 }
  2353.                 if (allPlayersGone)
  2354.                 {
  2355.                         reallyEndLevel = true;
  2356.                 }
  2357.         }
  2358.  
  2359.         if (!endLevel && enemyOnScreen == 0)
  2360.         {
  2361.                 if (readyToEndLevel && !enemyStillExploding)
  2362.                 {
  2363.                         if (levelTimerCountdown > 0)
  2364.                         {
  2365.                                 levelTimer = false;
  2366.                         }
  2367.                         readyToEndLevel = false;
  2368.                         endLevel = true;
  2369.                         levelEnd = 40;
  2370.                         if (allPlayersGone)
  2371.                         {
  2372.                                 reallyEndLevel = true;
  2373.                         }
  2374.                 }
  2375.                 if (stopBackgrounds)
  2376.                 {
  2377.                         stopBackgrounds = false;
  2378.                         backMove = 1;
  2379.                         backMove2 = 2;
  2380.                         backMove3 = 3;
  2381.                         explodeMove = 2;
  2382.                 }
  2383.         }
  2384.  
  2385.  
  2386.         /*Other Network Functions*/
  2387.         JE_handleChat();
  2388.  
  2389.         if (reallyEndLevel)
  2390.         {
  2391.                 goto start_level;
  2392.         }
  2393.         goto level_loop;
  2394. }
  2395.  
  2396. /* --- Load Level/Map Data --- */
  2397. void JE_loadMap( void )
  2398. {
  2399.         JE_DanCShape shape;
  2400.  
  2401.         JE_word x, y;
  2402.         JE_integer yy;
  2403.         JE_word mapSh[3][128]; /* [1..3, 0..127] */
  2404.         JE_byte *ref[3][128]; /* [1..3, 0..127] */
  2405.         char s[256];
  2406.  
  2407.         JE_byte mapBuf[15 * 600]; /* [1..15 * 600] */
  2408.         JE_word bufLoc;
  2409.  
  2410.         char buffer[256];
  2411.         int i;
  2412.         Uint8 pic_buffer[320*200]; /* screen buffer, 8-bit specific */
  2413.         Uint8 *vga, *pic, *vga2; /* screen pointer, 8-bit specific */
  2414.  
  2415.         lastCubeMax = cubeMax;
  2416.  
  2417.         /*Defaults*/
  2418.         songBuy = DEFAULT_SONG_BUY;  /*Item Screen default song*/
  2419.  
  2420.         /* Load LEVELS.DAT - Section = MAINLEVEL */
  2421.         saveLevel = mainLevel;
  2422.  
  2423. new_game:
  2424.         galagaMode  = false;
  2425.         useLastBank = false;
  2426.         extraGame   = false;
  2427.         haltGame = false;
  2428.  
  2429.         gameLoaded = false;
  2430.  
  2431.         if (!play_demo)
  2432.         {
  2433.                 do
  2434.                 {
  2435.                         FILE *ep_f = dir_fopen_die(data_dir(), episode_file, "rb");
  2436.  
  2437.                         jumpSection = false;
  2438.                         loadLevelOk = false;
  2439.  
  2440.                         /* Seek Section # Mainlevel */
  2441.                         int x = 0;
  2442.                         while (x < mainLevel)
  2443.                         {
  2444.                                 read_encrypted_pascal_string(s, sizeof(s), ep_f);
  2445.                                 if (s[0] == '*')
  2446.                                 {
  2447.                                         x++;
  2448.                                         s[0] = ' ';
  2449.                                 }
  2450.                         }
  2451.  
  2452.                         ESCPressed = false;
  2453.  
  2454.                         do
  2455.                         {
  2456.                                 if (gameLoaded)
  2457.                                 {
  2458.                                         fclose(ep_f);
  2459.  
  2460.                                         if (mainLevel == 0)  // if quit itemscreen
  2461.                                                 return;          // back to title screen
  2462.                                         else
  2463.                                                 goto new_game;
  2464.                                 }
  2465.  
  2466.                                 strcpy(s, " ");
  2467.                                 read_encrypted_pascal_string(s, sizeof(s), ep_f);
  2468.  
  2469.                                 if (s[0] == ']')
  2470.                                 {
  2471.                                         switch (s[1])
  2472.                                         {
  2473.                                         case 'A':
  2474.                                                 JE_playAnim("tyrend.anm", 0, 7);
  2475.                                                 break;
  2476.  
  2477.                                         case 'G':
  2478.                                                 mapOrigin = atoi(s + 4);
  2479.                                                 mapPNum   = atoi(s + 7);
  2480.                                                 for (i = 0; i < mapPNum; i++)
  2481.                                                 {
  2482.                                                         mapPlanet[i] = atoi(s + 1 + (i + 1) * 8);
  2483.                                                         mapSection[i] = atoi(s + 4 + (i + 1) * 8);
  2484.                                                 }
  2485.                                                 break;
  2486.  
  2487.                                         case '?':
  2488.                                                 temp = atoi(s + 4);
  2489.                                                 for (i = 0; i < temp; i++)
  2490.                                                 {
  2491.                                                         cubeList[i] = atoi(s + 3 + (i + 1) * 4);
  2492.                                                 }
  2493.                                                 if (cubeMax > temp)
  2494.                                                         cubeMax = temp;
  2495.                                                 break;
  2496.  
  2497.                                         case '!':
  2498.                                                 cubeMax = atoi(s + 4);    /*Auto set CubeMax*/
  2499.                                                 break;
  2500.  
  2501.                                         case '+':
  2502.                                                 temp = atoi(s + 4);
  2503.                                                 cubeMax += temp;
  2504.                                                 if (cubeMax > 4)
  2505.                                                         cubeMax = 4;
  2506.                                                 break;
  2507.  
  2508.                                         case 'g':
  2509.                                                 galagaMode = true;   /*GALAGA mode*/
  2510.  
  2511.                                                 player[1].items = player[0].items;
  2512.                                                 player[1].items.weapon[REAR_WEAPON].id = 15;  // Vulcan Cannon
  2513.                                                 for (uint i = 0; i < COUNTOF(player[1].items.sidekick); ++i)
  2514.                                                         player[1].items.sidekick[i] = 0;          // None
  2515.                                                 break;
  2516.  
  2517.                                         case 'x':
  2518.                                                 extraGame = true;
  2519.                                                 break;
  2520.  
  2521.                                         case 'e': // ENGAGE mode, used for mini-games
  2522.                                                 doNotSaveBackup = true;
  2523.                                                 constantDie = false;
  2524.                                                 onePlayerAction = true;
  2525.                                                 superTyrian = true;
  2526.                                                 twoPlayerMode = false;
  2527.  
  2528.                                                 player[0].cash = 0;
  2529.  
  2530.                                                 player[0].items.ship = 13;                     // The Stalker 21.126
  2531.                                                 player[0].items.weapon[FRONT_WEAPON].id = 39;  // Atomic RailGun
  2532.                                                 player[0].items.weapon[REAR_WEAPON].id = 0;    // None
  2533.                                                 for (uint i = 0; i < COUNTOF(player[0].items.sidekick); ++i)
  2534.                                                         player[0].items.sidekick[i] = 0;           // None
  2535.                                                 player[0].items.generator = 2;                 // Advanced MR-12
  2536.                                                 player[0].items.shield = 4;                    // Advanced Integrity Field
  2537.                                                 player[0].items.special = 0;                   // None
  2538.  
  2539.                                                 player[0].items.weapon[FRONT_WEAPON].power = 3;
  2540.                                                 player[0].items.weapon[REAR_WEAPON].power = 1;
  2541.                                                 break;
  2542.  
  2543.                                         case 'J':  // section jump
  2544.                                                 temp = atoi(s + 3);
  2545.                                                 mainLevel = temp;
  2546.                                                 jumpSection = true;
  2547.                                                 break;
  2548.  
  2549.                                         case '2':  // two-player section jump
  2550.                                                 temp = atoi(s + 3);
  2551.                                                 if (twoPlayerMode || onePlayerAction)
  2552.                                                 {
  2553.                                                         mainLevel = temp;
  2554.                                                         jumpSection = true;
  2555.                                                 }
  2556.                                                 break;
  2557.  
  2558.                                         case 'w':  // Stalker 21.126 section jump
  2559.                                                 temp = atoi(s + 3);   /*Allowed to go to Time War?*/
  2560.                                                 if (player[0].items.ship == 13)
  2561.                                                 {
  2562.                                                         mainLevel = temp;
  2563.                                                         jumpSection = true;
  2564.                                                 }
  2565.                                                 break;
  2566.  
  2567.                                         case 't':
  2568.                                                 temp = atoi(s + 3);
  2569.                                                 if (levelTimer && levelTimerCountdown == 0)
  2570.                                                 {
  2571.                                                         mainLevel = temp;
  2572.                                                         jumpSection = true;
  2573.                                                 }
  2574.                                                 break;
  2575.  
  2576.                                         case 'l':
  2577.                                                 temp = atoi(s + 3);
  2578.                                                 if (!all_players_alive())
  2579.                                                 {
  2580.                                                         mainLevel = temp;
  2581.                                                         jumpSection = true;
  2582.                                                 }
  2583.                                                 break;
  2584.  
  2585.                                         case 's':
  2586.                                                 saveLevel = mainLevel;
  2587.                                                 break; /*store savepoint*/
  2588.  
  2589.                                         case 'b':
  2590.                                                 if (twoPlayerMode)
  2591.                                                 {
  2592.                                                         temp = 22;
  2593.                                                 } else {
  2594.                                                         temp = 11;
  2595.                                                 }
  2596.                                                 JE_saveGame(11, "LAST LEVEL    ");
  2597.                                                 break;
  2598.  
  2599.                                         case 'i':
  2600.                                                 temp = atoi(s + 3);
  2601.                                                 songBuy = temp - 1;
  2602.                                                 break;
  2603.  
  2604.                                         case 'I': /*Load Items Available Information*/
  2605.                                                 memset(&itemAvail, 0, sizeof(itemAvail));
  2606.  
  2607.                                                 for (int i = 0; i < 9; ++i)
  2608.                                                 {
  2609.                                                         read_encrypted_pascal_string(s, sizeof(s), ep_f);
  2610.  
  2611.                                                         char buf[256];
  2612.                                                         strncpy(buf, (strlen(s) > 8) ? s + 8 : "", sizeof(buf));
  2613.  
  2614.                                                         int j = 0, temp;
  2615.                                                         while (str_pop_int(buf, &temp))
  2616.                                                                 itemAvail[i][j++] = temp;
  2617.                                                         itemAvailMax[i] = j;
  2618.                                                 }
  2619.  
  2620.                                                 JE_itemScreen();
  2621.                                                 break;
  2622.  
  2623.                                         case 'L':
  2624.                                                 nextLevel = atoi(s + 9);
  2625.                                                 SDL_strlcpy(levelName, s + 13, 10);
  2626.                                                 levelSong = atoi(s + 22);
  2627.                                                 if (nextLevel == 0)
  2628.                                                 {
  2629.                                                         nextLevel = mainLevel + 1;
  2630.                                                 }
  2631.                                                 lvlFileNum = atoi(s + 25);
  2632.                                                 loadLevelOk = true;
  2633.                                                 bonusLevelCurrent = (strlen(s) > 28) & (s[28] == '$');
  2634.                                                 normalBonusLevelCurrent = (strlen(s) > 27) & (s[27] == '$');
  2635.                                                 gameJustLoaded = false;
  2636.                                                 break;
  2637.  
  2638.                                         case '@':
  2639.                                                 useLastBank = !useLastBank;
  2640.                                                 break;
  2641.  
  2642.                                         case 'Q':
  2643.                                                 ESCPressed = false;
  2644.                                                 temp = secretHint + (mt_rand() % 3) * 3;
  2645.  
  2646.                                                 if (twoPlayerMode)
  2647.                                                 {
  2648.                                                         for (uint i = 0; i < 2; ++i)
  2649.                                                                 snprintf(levelWarningText[i], sizeof(*levelWarningText), "%s %lu", miscText[40], player[i].cash);
  2650.                                                         strcpy(levelWarningText[2], "");
  2651.                                                         levelWarningLines = 3;
  2652.                                                 }
  2653.                                                 else
  2654.                                                 {
  2655.                                                         sprintf(levelWarningText[0], "%s %lu", miscText[37], JE_totalScore(&player[0]));
  2656.                                                         strcpy(levelWarningText[1], "");
  2657.                                                         levelWarningLines = 2;
  2658.                                                 }
  2659.  
  2660.                                                 for (x = 0; x < temp - 1; x++)
  2661.                                                 {
  2662.                                                         do
  2663.                                                                 read_encrypted_pascal_string(s, sizeof(s), ep_f);
  2664.                                                         while (s[0] != '#');
  2665.                                                 }
  2666.  
  2667.                                                 do
  2668.                                                 {
  2669.                                                         read_encrypted_pascal_string(s, sizeof(s), ep_f);
  2670.                                                         strcpy(levelWarningText[levelWarningLines], s);
  2671.                                                         levelWarningLines++;
  2672.                                                 }
  2673.                                                 while (s[0] != '#');
  2674.                                                 levelWarningLines--;
  2675.  
  2676.                                                 JE_wipeKey();
  2677.                                                 frameCountMax = 4;
  2678.                                                 if (!constantPlay)
  2679.                                                         JE_displayText();
  2680.  
  2681.                                                 fade_black(15);
  2682.  
  2683.                                                 JE_nextEpisode();
  2684.  
  2685.                                                 if (jumpBackToEpisode1 && !twoPlayerMode)
  2686.                                                 {
  2687.                                                         JE_loadPic(VGAScreen, 1, false); // huh?
  2688.                                                         JE_clr256(VGAScreen);
  2689.  
  2690.                                                         if (superTyrian)
  2691.                                                         {
  2692.                                                                 // if completed Zinglon's Revenge, show SuperTyrian and Destruct codes
  2693.                                                                 // if completed SuperTyrian, show Nort-Ship Z code
  2694.                                                                 superArcadeMode = (initialDifficulty == 8) ? 8 : 1;
  2695.                                                         }
  2696.  
  2697.                                                         if (superArcadeMode < SA_ENGAGE)
  2698.                                                         {
  2699.                                                                 if (SANextShip[superArcadeMode] == SA_ENGAGE)
  2700.                                                                 {
  2701.                                                                         sprintf(buffer, "%s %s", miscTextB[4], pName[0]);
  2702.                                                                         JE_dString(VGAScreen, JE_fontCenter(buffer, FONT_SHAPES), 100, buffer, FONT_SHAPES);
  2703.  
  2704.                                                                         sprintf(buffer, "Or play... %s", specialName[7]);
  2705.                                                                         JE_dString(VGAScreen, 80, 180, buffer, SMALL_FONT_SHAPES);
  2706.                                                                 }
  2707.                                                                 else
  2708.                                                                 {
  2709.                                                                         JE_dString(VGAScreen, JE_fontCenter(superShips[0], FONT_SHAPES), 30, superShips[0], FONT_SHAPES);
  2710.                                                                         JE_dString(VGAScreen, JE_fontCenter(superShips[SANextShip[superArcadeMode]], SMALL_FONT_SHAPES), 100, superShips[SANextShip[superArcadeMode]], SMALL_FONT_SHAPES);
  2711.                                                                 }
  2712.  
  2713.                                                                 if (SANextShip[superArcadeMode] < SA_NORTSHIPZ)
  2714.                                                                         blit_sprite2x2(VGAScreen, 148, 70, shapes9, ships[SAShip[SANextShip[superArcadeMode]-1]].shipgraphic);
  2715.                                                                 else if (SANextShip[superArcadeMode] == SA_NORTSHIPZ)
  2716.                                                                         trentWin = true;
  2717.  
  2718.                                                                 sprintf(buffer, "Type %s at Title", specialName[SANextShip[superArcadeMode]-1]);
  2719.                                                                 JE_dString(VGAScreen, JE_fontCenter(buffer, SMALL_FONT_SHAPES), 160, buffer, SMALL_FONT_SHAPES);
  2720.                                                                 JE_showVGA();
  2721.  
  2722.                                                                 fade_palette(colors, 50, 0, 255);
  2723.  
  2724.                                                                 if (!constantPlay)
  2725.                                                                         wait_input(true, true, true);
  2726.                                                         }
  2727.  
  2728.                                                         jumpSection = true;
  2729.  
  2730.                                                         if (isNetworkGame)
  2731.                                                                 JE_readTextSync();
  2732.  
  2733.                                                         if (superTyrian)
  2734.                                                         {
  2735.                                                                 fade_black(10);
  2736.  
  2737.                                                                 // back to titlescreen
  2738.                                                                 mainLevel = 0;
  2739.                                                                 return;
  2740.                                                         }
  2741.                                                 }
  2742.                                                 break;
  2743.  
  2744.                                         case 'P':
  2745.                                                 if (!constantPlay)
  2746.                                                 {
  2747.                                                         tempX = atoi(s + 3);
  2748.                                                         if (tempX > 900)
  2749.                                                         {
  2750.                                                                 memcpy(colors, palettes[pcxpal[tempX-1 - 900]], sizeof(colors));
  2751.                                                                 JE_clr256(VGAScreen);
  2752.                                                                 JE_showVGA();
  2753.                                                                 fade_palette(colors, 1, 0, 255);
  2754.                                                         }
  2755.                                                         else
  2756.                                                         {
  2757.                                                                 if (tempX == 0)
  2758.                                                                         JE_loadPCX("tshp2.pcx");
  2759.                                                                 else
  2760.                                                                         JE_loadPic(VGAScreen, tempX, false);
  2761.  
  2762.                                                                 JE_showVGA();
  2763.                                                                 fade_palette(colors, 10, 0, 255);
  2764.                                                         }
  2765.                                                 }
  2766.                                                 break;
  2767.  
  2768.                                         case 'U':
  2769.                                                 if (!constantPlay)
  2770.                                                 {
  2771.                                                         memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
  2772.  
  2773.                                                         tempX = atoi(s + 3);
  2774.                                                         JE_loadPic(VGAScreen, tempX, false);
  2775.                                                         memcpy(pic_buffer, VGAScreen->pixels, sizeof(pic_buffer));
  2776.  
  2777.                                                         service_SDL_events(true);
  2778.  
  2779.                                                         for (int z = 0; z <= 199; z++)
  2780.                                                         {
  2781.                                                                 if (!newkey)
  2782.                                                                 {
  2783.                                                                         vga = VGAScreen->pixels;
  2784.                                                                         vga2 = VGAScreen2->pixels;
  2785.                                                                         pic = pic_buffer + (199 - z) * 320;
  2786.  
  2787.                                                                         setjasondelay(1); /* attempting to emulate JE_waitRetrace();*/
  2788.  
  2789.                                                                         for (y = 0; y <= 199; y++)
  2790.                                                                         {
  2791.                                                                                 if (y <= z)
  2792.                                                                                 {
  2793.                                                                                         memcpy(vga, pic, 320);
  2794.                                                                                         pic += 320;
  2795.                                                                                 }
  2796.                                                                                 else
  2797.                                                                                 {
  2798.                                                                                         memcpy(vga, vga2, VGAScreen->pitch);
  2799.                                                                                         vga2 += VGAScreen->pitch;
  2800.                                                                                 }
  2801.                                                                                 vga += VGAScreen->pitch;
  2802.                                                                         }
  2803.  
  2804.                                                                         JE_showVGA();
  2805.  
  2806.                                                                         if (isNetworkGame)
  2807.                                                                         {
  2808.                                                                                 /* TODO: NETWORK */
  2809.                                                                         }
  2810.  
  2811.                                                                         service_wait_delay();
  2812.                                                                 }
  2813.                                                         }
  2814.  
  2815.                                                         memcpy(VGAScreen->pixels, pic_buffer, sizeof(pic_buffer));
  2816.                                                 }
  2817.                                                 break;
  2818.  
  2819.                                         case 'V':
  2820.                                                 if (!constantPlay)
  2821.                                                 {
  2822.                                                         /* TODO: NETWORK */
  2823.                                                         memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
  2824.  
  2825.                                                         tempX = atoi(s + 3);
  2826.                                                         JE_loadPic(VGAScreen, tempX, false);
  2827.                                                         memcpy(pic_buffer, VGAScreen->pixels, sizeof(pic_buffer));
  2828.  
  2829.                                                         service_SDL_events(true);
  2830.                                                         for (int z = 0; z <= 199; z++)
  2831.                                                         {
  2832.                                                                 if (!newkey)
  2833.                                                                 {
  2834.                                                                         vga = VGAScreen->pixels;
  2835.                                                                         vga2 = VGAScreen2->pixels;
  2836.                                                                         pic = pic_buffer;
  2837.  
  2838.                                                                         setjasondelay(1); /* attempting to emulate JE_waitRetrace();*/
  2839.  
  2840.                                                                         for (y = 0; y < 199; y++)
  2841.                                                                         {
  2842.                                                                                 if (y <= 199 - z)
  2843.                                                                                 {
  2844.                                                                                         memcpy(vga, vga2, VGAScreen->pitch);
  2845.                                                                                         vga2 += VGAScreen->pitch;
  2846.                                                                                 }
  2847.                                                                                 else
  2848.                                                                                 {
  2849.                                                                                         memcpy(vga, pic, 320);
  2850.                                                                                         pic += 320;
  2851.                                                                                 }
  2852.                                                                                 vga += VGAScreen->pitch;
  2853.                                                                         }
  2854.  
  2855.                                                                         JE_showVGA();
  2856.  
  2857.                                                                         if (isNetworkGame)
  2858.                                                                         {
  2859.                                                                                 /* TODO: NETWORK */
  2860.                                                                         }
  2861.  
  2862.                                                                         service_wait_delay();
  2863.                                                                 }
  2864.                                                         }
  2865.  
  2866.                                                         memcpy(VGAScreen->pixels, pic_buffer, sizeof(pic_buffer));
  2867.                                                 }
  2868.                                                 break;
  2869.  
  2870.                                         case 'R':
  2871.                                                 if (!constantPlay)
  2872.                                                 {
  2873.                                                         /* TODO: NETWORK */
  2874.                                                         memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
  2875.  
  2876.                                                         tempX = atoi(s + 3);
  2877.                                                         JE_loadPic(VGAScreen, tempX, false);
  2878.                                                         memcpy(pic_buffer, VGAScreen->pixels, sizeof(pic_buffer));
  2879.  
  2880.                                                         service_SDL_events(true);
  2881.  
  2882.                                                         for (int z = 0; z <= 318; z++)
  2883.                                                         {
  2884.                                                                 if (!newkey)
  2885.                                                                 {
  2886.                                                                         vga = VGAScreen->pixels;
  2887.                                                                         vga2 = VGAScreen2->pixels;
  2888.                                                                         pic = pic_buffer;
  2889.  
  2890.                                                                         setjasondelay(1); /* attempting to emulate JE_waitRetrace();*/
  2891.  
  2892.                                                                         for(y = 0; y < 200; y++)
  2893.                                                                         {
  2894.                                                                                 memcpy(vga, vga2 + z, 319 - z);
  2895.                                                                                 vga += 320 - z;
  2896.                                                                                 vga2 += VGAScreen2->pitch;
  2897.                                                                                 memcpy(vga, pic, z + 1);
  2898.                                                                                 vga += z;
  2899.                                                                                 pic += 320;
  2900.                                                                         }
  2901.  
  2902.                                                                         JE_showVGA();
  2903.  
  2904.                                                                         if (isNetworkGame)
  2905.                                                                         {
  2906.                                                                                 /* TODO: NETWORK */
  2907.                                                                         }
  2908.  
  2909.                                                                         service_wait_delay();
  2910.                                                                 }
  2911.                                                         }
  2912.  
  2913.                                                         memcpy(VGAScreen->pixels, pic_buffer, sizeof(pic_buffer));
  2914.                                                 }
  2915.                                                 break;
  2916.  
  2917.                                         case 'C':
  2918.                                                 if (!isNetworkGame)
  2919.                                                 {
  2920.                                                         fade_black(10);
  2921.                                                 }
  2922.                                                 JE_clr256(VGAScreen);
  2923.                                                 JE_showVGA();
  2924.                                                 memcpy(colors, palettes[7], sizeof(colors));
  2925.                                                 set_palette(colors, 0, 255);
  2926.                                                 break;
  2927.  
  2928.                                         case 'B':
  2929.                                                 if (!isNetworkGame)
  2930.                                                 {
  2931.                                                         fade_black(10);
  2932.                                                 }
  2933.                                                 break;
  2934.                                         case 'F':
  2935.                                                 if (!isNetworkGame)
  2936.                                                 {
  2937.                                                         fade_white(100);
  2938.                                                         fade_black(30);
  2939.                                                 }
  2940.                                                 JE_clr256(VGAScreen);
  2941.                                                 JE_showVGA();
  2942.                                                 break;
  2943.  
  2944.                                         case 'W':
  2945.                                                 if (!constantPlay)
  2946.                                                 {
  2947.                                                         if (!ESCPressed)
  2948.                                                         {
  2949.                                                                 JE_wipeKey();
  2950.                                                                 warningCol = 14 * 16 + 5;
  2951.                                                                 warningColChange = 1;
  2952.                                                                 warningSoundDelay = 0;
  2953.                                                                 levelWarningDisplay = (s[2] == 'y');
  2954.                                                                 levelWarningLines = 0;
  2955.                                                                 frameCountMax = atoi(s + 4);
  2956.                                                                 setjasondelay2(6);
  2957.                                                                 warningRed = frameCountMax / 10;
  2958.                                                                 frameCountMax = frameCountMax % 10;
  2959.  
  2960.                                                                 do
  2961.                                                                 {
  2962.                                                                         read_encrypted_pascal_string(s, sizeof(s), ep_f);
  2963.  
  2964.                                                                         if (s[0] != '#')
  2965.                                                                         {
  2966.                                                                                 strcpy(levelWarningText[levelWarningLines], s);
  2967.                                                                                 levelWarningLines++;
  2968.                                                                         }
  2969.                                                                 }
  2970.                                                                 while (!(s[0] == '#'));
  2971.  
  2972.                                                                 JE_displayText();
  2973.                                                                 newkey = false;
  2974.                                                         }
  2975.                                                 }
  2976.                                                 break;
  2977.  
  2978.                                         case 'H':
  2979.                                                 if (initialDifficulty < 3)
  2980.                                                 {
  2981.                                                         mainLevel = atoi(s + 4);
  2982.                                                         jumpSection = true;
  2983.                                                 }
  2984.                                                 break;
  2985.  
  2986.                                         case 'h':
  2987.                                                 if (initialDifficulty > 2)
  2988.                                                 {
  2989.                                                         read_encrypted_pascal_string(s, sizeof(s), ep_f);
  2990.                                                 }
  2991.                                                 break;
  2992.  
  2993.                                         case 'S':
  2994.                                                 if (isNetworkGame)
  2995.                                                 {
  2996.                                                         JE_readTextSync();
  2997.                                                 }
  2998.                                                 break;
  2999.  
  3000.                                         case 'n':
  3001.                                                 ESCPressed = false;
  3002.                                                 break;
  3003.  
  3004.                                         case 'M':
  3005.                                                 temp = atoi(s + 3);
  3006.                                                 play_song(temp - 1);
  3007.                                                 break;
  3008.                                         }
  3009.                                 }
  3010.  
  3011.                         } while (!(loadLevelOk || jumpSection));
  3012.  
  3013.  
  3014.                         fclose(ep_f);
  3015.  
  3016.                 } while (!loadLevelOk);
  3017.         }
  3018.  
  3019.         if (play_demo)
  3020.                 load_next_demo();
  3021.         else
  3022.                 fade_black(50);
  3023.  
  3024.         FILE *level_f = dir_fopen_die(data_dir(), levelFile, "rb");
  3025.         fseek(level_f, lvlPos[(lvlFileNum-1) * 2], SEEK_SET);
  3026.  
  3027.         fgetc(level_f); // char_mapFile
  3028.         JE_char char_shapeFile = fgetc(level_f);
  3029.         efread(&mapX,  sizeof(JE_word), 1, level_f);
  3030.         efread(&mapX2, sizeof(JE_word), 1, level_f);
  3031.         efread(&mapX3, sizeof(JE_word), 1, level_f);
  3032.  
  3033.         efread(&levelEnemyMax, sizeof(JE_word), 1, level_f);
  3034.         for (x = 0; x < levelEnemyMax; x++)
  3035.         {
  3036.                 efread(&levelEnemy[x], sizeof(JE_word), 1, level_f);
  3037.         }
  3038.  
  3039.         efread(&maxEvent, sizeof(JE_word), 1, level_f);
  3040.         for (x = 0; x < maxEvent; x++)
  3041.         {
  3042.                 efread(&eventRec[x].eventtime, sizeof(JE_word), 1, level_f);
  3043.                 efread(&eventRec[x].eventtype, sizeof(JE_byte), 1, level_f);
  3044.                 efread(&eventRec[x].eventdat,  sizeof(JE_integer), 1, level_f);
  3045.                 efread(&eventRec[x].eventdat2, sizeof(JE_integer), 1, level_f);
  3046.                 efread(&eventRec[x].eventdat3, sizeof(JE_shortint), 1, level_f);
  3047.                 efread(&eventRec[x].eventdat5, sizeof(JE_shortint), 1, level_f);
  3048.                 efread(&eventRec[x].eventdat6, sizeof(JE_shortint), 1, level_f);
  3049.                 efread(&eventRec[x].eventdat4, sizeof(JE_byte), 1, level_f);
  3050.         }
  3051.         eventRec[x].eventtime = 65500;  /*Not needed but just in case*/
  3052.  
  3053.         /*debuginfo('Level loaded.');*/
  3054.  
  3055.         /*debuginfo('Loading Map');*/
  3056.  
  3057.         /* MAP SHAPE LOOKUP TABLE - Each map is directly after level */
  3058.         efread(mapSh, sizeof(JE_word), sizeof(mapSh) / sizeof(JE_word), level_f);
  3059.         for (temp = 0; temp < 3; temp++)
  3060.         {
  3061.                 for (temp2 = 0; temp2 < 128; temp2++)
  3062.                 {
  3063.                         mapSh[temp][temp2] = SDL_Swap16(mapSh[temp][temp2]);
  3064.                 }
  3065.         }
  3066.  
  3067.         /* Read Shapes.DAT */
  3068.         sprintf(tempStr, "shapes%c.dat", tolower((unsigned char)char_shapeFile));
  3069.         FILE *shpFile = dir_fopen_die(data_dir(), tempStr, "rb");
  3070.  
  3071.         for (int z = 0; z < 600; z++)
  3072.         {
  3073.                 JE_boolean shapeBlank = fgetc(shpFile);
  3074.  
  3075.                 if (shapeBlank)
  3076.                         memset(shape, 0, sizeof(shape));
  3077.                 else
  3078.                         efread(shape, sizeof(JE_byte), sizeof(shape), shpFile);
  3079.  
  3080.                 /* Match 1 */
  3081.                 for (int x = 0; x <= 71; ++x)
  3082.                 {
  3083.                         if (mapSh[0][x] == z+1)
  3084.                         {
  3085.                                 memcpy(megaData1.shapes[x].sh, shape, sizeof(JE_DanCShape));
  3086.  
  3087.                                 ref[0][x] = (JE_byte *)megaData1.shapes[x].sh;
  3088.                         }
  3089.                 }
  3090.  
  3091.                 /* Match 2 */
  3092.                 for (int x = 0; x <= 71; ++x)
  3093.                 {
  3094.                         if (mapSh[1][x] == z+1)
  3095.                         {
  3096.                                 if (x != 71 && !shapeBlank)
  3097.                                 {
  3098.                                         memcpy(megaData2.shapes[x].sh, shape, sizeof(JE_DanCShape));
  3099.  
  3100.                                         y = 1;
  3101.                                         for (yy = 0; yy < (24 * 28) >> 1; yy++)
  3102.                                                 if (shape[yy] == 0)
  3103.                                                         y = 0;
  3104.  
  3105.                                         megaData2.shapes[x].fill = y;
  3106.                                         ref[1][x] = (JE_byte *)megaData2.shapes[x].sh;
  3107.                                 }
  3108.                                 else
  3109.                                 {
  3110.                                         ref[1][x] = NULL;
  3111.                                 }
  3112.                         }
  3113.                 }
  3114.  
  3115.                 /*Match 3*/
  3116.                 for (int x = 0; x <= 71; ++x)
  3117.                 {
  3118.                         if (mapSh[2][x] == z+1)
  3119.                         {
  3120.                                 if (x < 70 && !shapeBlank)
  3121.                                 {
  3122.                                         memcpy(megaData3.shapes[x].sh, shape, sizeof(JE_DanCShape));
  3123.  
  3124.                                         y = 1;
  3125.                                         for (yy = 0; yy < (24 * 28) >> 1; yy++)
  3126.                                                 if (shape[yy] == 0)
  3127.                                                         y = 0;
  3128.  
  3129.                                         megaData3.shapes[x].fill = y;
  3130.                                         ref[2][x] = (JE_byte *)megaData3.shapes[x].sh;
  3131.                                 }
  3132.                                 else
  3133.                                 {
  3134.                                         ref[2][x] = NULL;
  3135.                                 }
  3136.                         }
  3137.                 }
  3138.         }
  3139.  
  3140.         fclose(shpFile);
  3141.  
  3142.         efread(mapBuf, sizeof(JE_byte), 14 * 300, level_f);
  3143.         bufLoc = 0;              /* MAP NUMBER 1 */
  3144.         for (y = 0; y < 300; y++)
  3145.         {
  3146.                 for (x = 0; x < 14; x++)
  3147.                 {
  3148.                         megaData1.mainmap[y][x] = ref[0][mapBuf[bufLoc]];
  3149.                         bufLoc++;
  3150.                 }
  3151.         }
  3152.  
  3153.         efread(mapBuf, sizeof(JE_byte), 14 * 600, level_f);
  3154.         bufLoc = 0;              /* MAP NUMBER 2 */
  3155.         for (y = 0; y < 600; y++)
  3156.         {
  3157.                 for (x = 0; x < 14; x++)
  3158.                 {
  3159.                         megaData2.mainmap[y][x] = ref[1][mapBuf[bufLoc]];
  3160.                         bufLoc++;
  3161.                 }
  3162.         }
  3163.  
  3164.         efread(mapBuf, sizeof(JE_byte), 15 * 600, level_f);
  3165.         bufLoc = 0;              /* MAP NUMBER 3 */
  3166.         for (y = 0; y < 600; y++)
  3167.         {
  3168.                 for (x = 0; x < 15; x++)
  3169.                 {
  3170.                         megaData3.mainmap[y][x] = ref[2][mapBuf[bufLoc]];
  3171.                         bufLoc++;
  3172.                 }
  3173.         }
  3174.  
  3175.         fclose(level_f);
  3176.  
  3177.         /* Note: The map data is automatically calculated with the correct mapsh
  3178.         value and then the pointer is calculated using the formula (MAPSH-1)*168.
  3179.         Then, we'll automatically add S2Ofs to get the exact offset location into
  3180.         the shape table! This makes it VERY FAST! */
  3181.  
  3182.         /*debuginfo('Map file done.');*/
  3183.         /* End of find loop for LEVEL??.DAT */
  3184. }
  3185.  
  3186. bool JE_titleScreen( JE_boolean animate )
  3187. {
  3188.         bool quit = false;
  3189.  
  3190.         const int menunum = 7;
  3191.  
  3192.         unsigned int arcade_code_i[SA_ENGAGE] = { 0 };
  3193.  
  3194.         JE_word waitForDemo;
  3195.         JE_byte menu = 0;
  3196.         JE_boolean redraw = true,
  3197.                    fadeIn = false;
  3198.  
  3199.         JE_word temp; /* JE_byte temp; from varz.h will overflow in for loop */
  3200.  
  3201.         play_demo = false;
  3202.         stopped_demo = false;
  3203.  
  3204.         redraw = true;
  3205.         fadeIn = false;
  3206.  
  3207.         gameLoaded = false;
  3208.         jumpSection = false;
  3209.  
  3210. #ifdef WITH_NETWORK
  3211.         if (isNetworkGame)
  3212.         {
  3213.                 JE_loadPic(VGAScreen, 2, false);
  3214.                 memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
  3215.                 JE_dString(VGAScreen, JE_fontCenter("Waiting for other player.", SMALL_FONT_SHAPES), 140, "Waiting for other player.", SMALL_FONT_SHAPES);
  3216.                 JE_showVGA();
  3217.                 fade_palette(colors, 10, 0, 255);
  3218.  
  3219.                 network_connect();
  3220.  
  3221.                 twoPlayerMode = true;
  3222.                 if (thisPlayerNum == 1)
  3223.                 {
  3224.                         fade_black(10);
  3225.  
  3226.                         if (select_episode() && select_difficulty())
  3227.                         {
  3228.                                 initialDifficulty = difficultyLevel;
  3229.  
  3230.                                 difficultyLevel++;  /*Make it one step harder for 2-player mode!*/
  3231.  
  3232.                                 network_prepare(PACKET_DETAILS);
  3233.                                 SDLNet_Write16(episodeNum,      &packet_out_temp->data[4]);
  3234.                                 SDLNet_Write16(difficultyLevel, &packet_out_temp->data[6]);
  3235.                                 network_send(8);  // PACKET_DETAILS
  3236.                         }
  3237.                         else
  3238.                         {
  3239.                                 network_prepare(PACKET_QUIT);
  3240.                                 network_send(4);  // PACKET QUIT
  3241.  
  3242.                                 network_tyrian_halt(0, true);
  3243.                         }
  3244.                 }
  3245.                 else
  3246.                 {
  3247.                         memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
  3248.                         JE_dString(VGAScreen, JE_fontCenter(networkText[4-1], SMALL_FONT_SHAPES), 140, networkText[4-1], SMALL_FONT_SHAPES);
  3249.                         JE_showVGA();
  3250.  
  3251.                         // until opponent sends details packet
  3252.                         while (true)
  3253.                         {
  3254.                                 service_SDL_events(false);
  3255.                                 JE_showVGA();
  3256.  
  3257.                                 if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_DETAILS)
  3258.                                         break;
  3259.  
  3260.                                 network_update();
  3261.                                 network_check();
  3262.  
  3263.                                 uSDL_Delay(16);
  3264.                         }
  3265.  
  3266.                         JE_initEpisode(SDLNet_Read16(&packet_in[0]->data[4]));
  3267.                         difficultyLevel = SDLNet_Read16(&packet_in[0]->data[6]);
  3268.                         initialDifficulty = difficultyLevel - 1;
  3269.                         fade_black(10);
  3270.  
  3271.                         network_update();
  3272.                 }
  3273.  
  3274.                 for (uint i = 0; i < COUNTOF(player); ++i)
  3275.                         player[i].cash = 0;
  3276.  
  3277.                 player[0].items.ship = 11;  // Silver Ship
  3278.  
  3279.                 while (!network_is_sync())
  3280.                 {
  3281.                         service_SDL_events(false);
  3282.                         JE_showVGA();
  3283.  
  3284.                         network_check();
  3285.                         uSDL_Delay(16);
  3286.                 }
  3287.         }
  3288.         else
  3289. #endif
  3290.         {
  3291.                 do
  3292.                 {
  3293.                         /* Animate instead of quickly fading in */
  3294.                         if (redraw)
  3295.                         {
  3296.                                 play_song(SONG_TITLE);
  3297.  
  3298.                                 menu = 0;
  3299.                                 redraw = false;
  3300.                                 if (animate)
  3301.                                 {
  3302.                                         if (fadeIn)
  3303.                                         {
  3304.                                                 fade_black(10);
  3305.                                                 fadeIn = false;
  3306.                                         }
  3307.  
  3308.                                         JE_loadPic(VGAScreen, 4, false);
  3309.  
  3310.                                         draw_font_hv_shadow(VGAScreen, 2, 192, opentyrian_version, small_font, left_aligned, 15, 0, false, 1);
  3311.  
  3312.                                         memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
  3313.  
  3314.                                         temp = moveTyrianLogoUp ? 62 : 4;
  3315.  
  3316.                                         blit_sprite(VGAScreenSeg, 11, temp, PLANET_SHAPES, 146); // tyrian logo
  3317.  
  3318.                                         JE_showVGA();
  3319.  
  3320.                                         fade_palette(colors, 10, 0, 255 - 16);
  3321.  
  3322.                                         if (moveTyrianLogoUp)
  3323.                                         {
  3324.                                                 for (temp = 61; temp >= 4; temp -= 2)
  3325.                                                 {
  3326.                                                         setjasondelay(2);
  3327.  
  3328.                                                         memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
  3329.  
  3330.                                                         blit_sprite(VGAScreenSeg, 11, temp, PLANET_SHAPES, 146); // tyrian logo
  3331.  
  3332.                                                         JE_showVGA();
  3333.  
  3334.                                                         service_wait_delay();
  3335.                                                 }
  3336.                                                 moveTyrianLogoUp = false;
  3337.                                         }
  3338.  
  3339.                                         strcpy(menuText[4], opentyrian_str);  // OpenTyrian override
  3340.  
  3341.                                         /* Draw Menu Text on Screen */
  3342.                                         for (int i = 0; i < menunum; ++i)
  3343.                                         {
  3344.                                                 int x = VGAScreen->w / 2, y = 104 + i * 13;
  3345.  
  3346.                                                 draw_font_hv(VGAScreen, x - 1, y - 1, menuText[i], normal_font, centered, 15, -10);
  3347.                                                 draw_font_hv(VGAScreen, x + 1, y + 1, menuText[i], normal_font, centered, 15, -10);
  3348.                                                 draw_font_hv(VGAScreen, x + 1, y - 1, menuText[i], normal_font, centered, 15, -10);
  3349.                                                 draw_font_hv(VGAScreen, x - 1, y + 1, menuText[i], normal_font, centered, 15, -10);
  3350.                                                 draw_font_hv(VGAScreen, x,     y,     menuText[i], normal_font, centered, 15, -3);
  3351.                                         }
  3352.  
  3353.                                         JE_showVGA();
  3354.  
  3355.                                         fade_palette(colors, 20, 255 - 16 + 1, 255); // fade in menu items
  3356.  
  3357.                                         memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
  3358.                                 }
  3359.                         }
  3360.  
  3361.                         memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
  3362.  
  3363.                         // highlight selected menu item
  3364.                         draw_font_hv(VGAScreen, VGAScreen->w / 2, 104 + menu * 13, menuText[menu], normal_font, centered, 15, -1);
  3365.  
  3366.                         JE_showVGA();
  3367.  
  3368.                         if (trentWin)
  3369.                         {
  3370.                                 quit = true;
  3371.                                 goto trentWinsGame;
  3372.                         }
  3373.  
  3374.                         waitForDemo = 2000;
  3375.                         JE_textMenuWait(&waitForDemo, false);
  3376.  
  3377.                         if (waitForDemo == 1)
  3378.                                 play_demo = true;
  3379.  
  3380.                         if (newkey)
  3381.                         {
  3382.                                 switch (lastkey_sym)
  3383.                                 {
  3384.                                 case SDLK_UP:
  3385.                                         if (menu == 0)
  3386.                                                 menu = menunum-1;
  3387.                                         else
  3388.                                                 menu--;
  3389.                                         JE_playSampleNum(S_CURSOR);
  3390.                                         break;
  3391.                                 case SDLK_DOWN:
  3392.                                         if (menu == menunum-1)
  3393.                                                 menu = 0;
  3394.                                         else
  3395.                                                 menu++;
  3396.                                         JE_playSampleNum(S_CURSOR);
  3397.                                         break;
  3398.                                 default:
  3399.                                         break;
  3400.                                 }
  3401.                         }
  3402.  
  3403.                         for (unsigned int i = 0; i < SA_ENGAGE; i++)
  3404.                         {
  3405.                                 if (toupper(lastkey_char) == specialName[i][arcade_code_i[i]])
  3406.                                         arcade_code_i[i]++;
  3407.                                 else
  3408.                                         arcade_code_i[i] = 0;
  3409.  
  3410.                                 if (arcade_code_i[i] > 0 && arcade_code_i[i] == strlen(specialName[i]))
  3411.                                 {
  3412.                                         if (i+1 == SA_DESTRUCT)
  3413.                                         {
  3414.                                                 loadDestruct = true;
  3415.                                         }
  3416.                                         else if (i+1 == SA_ENGAGE)
  3417.                                         {
  3418.                                                 /* SuperTyrian */
  3419.  
  3420.                                                 JE_playSampleNum(V_DATA_CUBE);
  3421.                                                 JE_whoa();
  3422.  
  3423.                                                 initialDifficulty = keysactive[SDLK_SCROLLOCK] ? 6 : 8;
  3424.  
  3425.                                                 JE_clr256(VGAScreen);
  3426.                                                 JE_outText(VGAScreen, 10, 10, "Cheat codes have been disabled.", 15, 4);
  3427.                                                 if (initialDifficulty == 8)
  3428.                                                         JE_outText(VGAScreen, 10, 20, "Difficulty level has been set to Lord of Game.", 15, 4);
  3429.                                                 else
  3430.                                                         JE_outText(VGAScreen, 10, 20, "Difficulty level has been set to Suicide.", 15, 4);
  3431.                                                 JE_outText(VGAScreen, 10, 30, "It is imperative that you discover the special codes.", 15, 4);
  3432.                                                 if (initialDifficulty == 8)
  3433.                                                         JE_outText(VGAScreen, 10, 40, "(Next time, for an easier challenge hold down SCROLL LOCK.)", 15, 4);
  3434.                                                 JE_outText(VGAScreen, 10, 60, "Prepare to play...", 15, 4);
  3435.  
  3436.                                                 char buf[10+1+15+1];
  3437.                                                 snprintf(buf, sizeof(buf), "%s %s", miscTextB[4], pName[0]);
  3438.                                                 JE_dString(VGAScreen, JE_fontCenter(buf, FONT_SHAPES), 110, buf, FONT_SHAPES);
  3439.  
  3440.                                                 play_song(16);
  3441.                                                 JE_playSampleNum(V_DANGER);
  3442.                                                 JE_showVGA();
  3443.  
  3444.                                                 wait_noinput(true, true, true);
  3445.                                                 wait_input(true, true, true);
  3446.  
  3447.                                                 JE_initEpisode(1);
  3448.                                                 constantDie = false;
  3449.                                                 superTyrian = true;
  3450.                                                 onePlayerAction = true;
  3451.                                                 gameLoaded = true;
  3452.                                                 difficultyLevel = initialDifficulty;
  3453.  
  3454.                                                 player[0].cash = 0;
  3455.  
  3456.                                                 player[0].items.ship = 13;                     // The Stalker 21.126
  3457.                                                 player[0].items.weapon[FRONT_WEAPON].id = 39;  // Atomic RailGun
  3458.                                         }
  3459.                                         else
  3460.                                         {
  3461.                                                 player[0].items.ship = SAShip[i];
  3462.  
  3463.                                                 fade_black(10);
  3464.                                                 if (select_episode() && select_difficulty())
  3465.                                                 {
  3466.                                                         /* Start special mode! */
  3467.                                                         fade_black(10);
  3468.                                                         JE_loadPic(VGAScreen, 1, false);
  3469.                                                         JE_clr256(VGAScreen);
  3470.                                                         JE_dString(VGAScreen, JE_fontCenter(superShips[0], FONT_SHAPES), 30, superShips[0], FONT_SHAPES);
  3471.                                                         JE_dString(VGAScreen, JE_fontCenter(superShips[i+1], SMALL_FONT_SHAPES), 100, superShips[i+1], SMALL_FONT_SHAPES);
  3472.                                                         tempW = ships[player[0].items.ship].shipgraphic;
  3473.                                                         if (tempW != 1)
  3474.                                                                 blit_sprite2x2(VGAScreen, 148, 70, shapes9, tempW);
  3475.  
  3476.                                                         JE_showVGA();
  3477.                                                         fade_palette(colors, 50, 0, 255);
  3478.  
  3479.                                                         wait_input(true, true, true);
  3480.  
  3481.                                                         twoPlayerMode = false;
  3482.                                                         onePlayerAction = true;
  3483.                                                         superArcadeMode = i+1;
  3484.                                                         gameLoaded = true;
  3485.                                                         initialDifficulty = ++difficultyLevel;
  3486.  
  3487.                                                         player[0].cash = 0;
  3488.  
  3489.                                                         player[0].items.weapon[FRONT_WEAPON].id = SAWeapon[i][0];
  3490.                                                         player[0].items.special = SASpecialWeapon[i];
  3491.                                                         if (superArcadeMode == SA_NORTSHIPZ)
  3492.                                                         {
  3493.                                                                 for (uint i = 0; i < COUNTOF(player[0].items.sidekick); ++i)
  3494.                                                                         player[0].items.sidekick[i] = 24;  // Companion Ship Quicksilver
  3495.                                                         }
  3496.                                                 }
  3497.                                                 else
  3498.                                                 {
  3499.                                                         redraw = true;
  3500.                                                         fadeIn = true;
  3501.                                                 }
  3502.                                         }
  3503.                                         newkey = false;
  3504.                                 }
  3505.                         }
  3506.                         lastkey_char = '\0';
  3507.  
  3508.                         if (newkey)
  3509.                         {
  3510.                                 switch (lastkey_sym)
  3511.                                 {
  3512.                                 case SDLK_ESCAPE:
  3513.                                         quit = true;
  3514.                                         break;
  3515.                                 case SDLK_RETURN:
  3516.                                         JE_playSampleNum(S_SELECT);
  3517.                                         switch (menu)
  3518.                                         {
  3519.                                         case 0: /* New game */
  3520.                                                 fade_black(10);
  3521.                                                
  3522.                                                 if (select_gameplay())
  3523.                                                 {
  3524.                                                         if (select_episode() && select_difficulty())
  3525.                                                                 gameLoaded = true;
  3526.  
  3527.                                                         initialDifficulty = difficultyLevel;
  3528.  
  3529.                                                         if (onePlayerAction)
  3530.                                                         {
  3531.                                                                 player[0].cash = 0;
  3532.  
  3533.                                                                 player[0].items.ship = 8;  // Stalker
  3534.                                                         }
  3535.                                                         else if (twoPlayerMode)
  3536.                                                         {
  3537.                                                                 for (uint i = 0; i < COUNTOF(player); ++i)
  3538.                                                                         player[i].cash = 0;
  3539.                                                                
  3540.                                                                 player[0].items.ship = 11;  // Silver Ship
  3541.                                                                
  3542.                                                                 difficultyLevel++;
  3543.                                                                
  3544.                                                                 inputDevice[0] = 1;
  3545.                                                                 inputDevice[1] = 2;
  3546.                                                         }
  3547.                                                         else if (richMode)
  3548.                                                         {
  3549.                                                                 player[0].cash = 1000000;
  3550.                                                         }
  3551.                                                         else if (gameLoaded)
  3552.                                                         {
  3553.                                                                 // allows player to smuggle arcade/super-arcade ships into full game
  3554.                                                                
  3555.                                                                 ulong initial_cash[] = { 10000, 15000, 20000, 30000 };
  3556.  
  3557.                                                                 assert(episodeNum >= 1 && episodeNum <= EPISODE_AVAILABLE);
  3558.                                                                 player[0].cash = initial_cash[episodeNum-1];
  3559.                                                         }
  3560.                                                 }
  3561.                                                 fadeIn = true;
  3562.                                                 break;
  3563.                                         case 1: /* Load game */
  3564.                                                 JE_loadScreen();
  3565.                                                 fadeIn = true;
  3566.                                                 break;
  3567.                                         case 2: /* High scores */
  3568.                                                 JE_highScoreScreen();
  3569.                                                 fadeIn = true;
  3570.                                                 break;
  3571.                                         case 3: /* Instructions */
  3572.                                                 JE_helpSystem(1);
  3573.                                                 fadeIn = true;
  3574.                                                 break;
  3575.                                         case 4: /* Ordering info, now OpenTyrian menu */
  3576.                                                 opentyrian_menu();
  3577.                                                 fadeIn = true;
  3578.                                                 break;
  3579.                                         case 5: /* Demo */
  3580.                                                 play_demo = true;
  3581.                                                 break;
  3582.                                         case 6: /* Quit */
  3583.                                                 quit = true;
  3584.                                                 break;
  3585.                                         }
  3586.                                         redraw = true;
  3587.                                         break;
  3588.                                 default:
  3589.                                         break;
  3590.                                 }
  3591.                         }
  3592.                 }
  3593.                 while (!(quit || gameLoaded || jumpSection || play_demo || loadDestruct));
  3594.  
  3595. trentWinsGame:
  3596.                 fade_black(15);
  3597.         }
  3598.  
  3599.         return quit;
  3600. }
  3601.  
  3602. void intro_logos( void )
  3603. {
  3604.         SDL_FillRect(VGAScreen, NULL, 0);
  3605.  
  3606.         fade_white(50);
  3607.  
  3608.         JE_loadPic(VGAScreen, 10, false);
  3609.         JE_showVGA();
  3610.  
  3611.         fade_palette(colors, 50, 0, 255);
  3612.  
  3613.         setjasondelay(200);
  3614.         wait_delayorinput(true, true, true);
  3615.  
  3616.         fade_black(10);
  3617.  
  3618.         JE_loadPic(VGAScreen, 12, false);
  3619.         JE_showVGA();
  3620.  
  3621.         fade_palette(colors, 10, 0, 255);
  3622.  
  3623.         setjasondelay(200);
  3624.         wait_delayorinput(true, true, true);
  3625.  
  3626.         fade_black(10);
  3627. }
  3628.  
  3629. void JE_readTextSync( void )
  3630. {
  3631. #if 0  // this function seems to be unnecessary
  3632.         JE_clr256(VGAScreen);
  3633.         JE_showVGA();
  3634.         JE_loadPic(VGAScreen, 1, true);
  3635.  
  3636.         JE_barShade(VGAScreen, 3, 3, 316, 196);
  3637.         JE_barShade(VGAScreen, 1, 1, 318, 198);
  3638.         JE_dString(VGAScreen, 10, 160, "Waiting for other player.", SMALL_FONT_SHAPES);
  3639.         JE_showVGA();
  3640.  
  3641.         /* TODO: NETWORK */
  3642.  
  3643.         do
  3644.         {
  3645.                 setjasondelay(2);
  3646.  
  3647.                 /* TODO: NETWORK */
  3648.  
  3649.                 wait_delay();
  3650.  
  3651.         } while (0 /* TODO: NETWORK */);
  3652. #endif
  3653. }
  3654.  
  3655.  
  3656. void JE_displayText( void )
  3657. {
  3658.         /* Display Warning Text */
  3659.         tempY = 55;
  3660.         if (warningRed)
  3661.         {
  3662.                 tempY = 2;
  3663.         }
  3664.         for (temp = 0; temp < levelWarningLines; temp++)
  3665.         {
  3666.                 if (!ESCPressed)
  3667.                 {
  3668.                         JE_outCharGlow(10, tempY, levelWarningText[temp]);
  3669.  
  3670.                         if (haltGame)
  3671.                         {
  3672.                                 JE_tyrianHalt(5);
  3673.                         }
  3674.  
  3675.                         tempY += 10;
  3676.                 }
  3677.         }
  3678.         if (frameCountMax != 0)
  3679.         {
  3680.                 frameCountMax = 6;
  3681.                 temp = 1;
  3682.         } else {
  3683.                 temp = 0;
  3684.         }
  3685.         textGlowFont = TINY_FONT;
  3686.         tempW = 184;
  3687.         if (warningRed)
  3688.         {
  3689.                 tempW = 7 * 16 + 6;
  3690.         }
  3691.  
  3692.         JE_outCharGlow(JE_fontCenter(miscText[4], TINY_FONT), tempW, miscText[4]);
  3693.  
  3694.         do
  3695.         {
  3696.                 if (levelWarningDisplay)
  3697.                 {
  3698.                         JE_updateWarning(VGAScreen);
  3699.                 }
  3700.  
  3701.                 setjasondelay(1);
  3702.  
  3703.                 NETWORK_KEEP_ALIVE();
  3704.  
  3705.                 wait_delay();
  3706.  
  3707.         } while (!(JE_anyButton() || (frameCountMax == 0 && temp == 1) || ESCPressed));
  3708.         levelWarningDisplay = false;
  3709. }
  3710.  
  3711. Sint16 JE_newEnemy( int enemyOffset, Uint16 eDatI, Sint16 uniqueShapeTableI )
  3712. {
  3713.         for (int i = enemyOffset; i < enemyOffset + 25; ++i)
  3714.         {
  3715.                 if (enemyAvail[i] == 1)
  3716.                 {
  3717.                         enemyAvail[i] = JE_makeEnemy(&enemy[i], eDatI, uniqueShapeTableI);
  3718.                         return i + 1;
  3719.                 }
  3720.         }
  3721.        
  3722.         return 0;
  3723. }
  3724.  
  3725. uint JE_makeEnemy( struct JE_SingleEnemyType *enemy, Uint16 eDatI, Sint16 uniqueShapeTableI )
  3726. {
  3727.         uint avail;
  3728.  
  3729.         JE_byte shapeTableI;
  3730.  
  3731.         if (superArcadeMode != SA_NONE && eDatI == 534)
  3732.                 eDatI = 533;
  3733.  
  3734.         enemyShapeTables[5-1] = 21;   /*Coins&Gems*/
  3735.         enemyShapeTables[6-1] = 26;   /*Two-Player Stuff*/
  3736.  
  3737.         if (uniqueShapeTableI > 0)
  3738.         {
  3739.                 shapeTableI = uniqueShapeTableI;
  3740.         }
  3741.         else
  3742.         {
  3743.                 shapeTableI = enemyDat[eDatI].shapebank;
  3744.         }
  3745.        
  3746.         Sprite2_array *sprite2s = NULL;
  3747.         for (uint i = 0; i < 6; ++i)
  3748.                 if (shapeTableI == enemyShapeTables[i])
  3749.                         sprite2s = &eShapes[i];
  3750.        
  3751.         if (sprite2s != NULL)
  3752.                 enemy->sprite2s = sprite2s;
  3753.         else
  3754.                 // maintain buggy Tyrian behavior (use shape table value from previous enemy that occupied this index in the enemy array)
  3755.                 fprintf(stderr, "warning: ignoring sprite from unloaded shape table %d\n", shapeTableI);
  3756.  
  3757.         enemy->enemydatofs = &enemyDat[eDatI];
  3758.  
  3759.         enemy->mapoffset = 0;
  3760.  
  3761.         for (uint i = 0; i < 3; ++i)
  3762.         {
  3763.                 enemy->eshotmultipos[i] = 0;
  3764.         }
  3765.  
  3766.         enemy->enemyground = (enemyDat[eDatI].explosiontype & 1) == 0;
  3767.         enemy->explonum = enemyDat[eDatI].explosiontype >> 1;
  3768.  
  3769.         enemy->launchfreq = enemyDat[eDatI].elaunchfreq;
  3770.         enemy->launchwait = enemyDat[eDatI].elaunchfreq;
  3771.         enemy->launchtype = enemyDat[eDatI].elaunchtype % 1000;
  3772.         enemy->launchspecial = enemyDat[eDatI].elaunchtype / 1000;
  3773.  
  3774.         enemy->xaccel = enemyDat[eDatI].xaccel;
  3775.         enemy->yaccel = enemyDat[eDatI].yaccel;
  3776.  
  3777.         enemy->xminbounce = -10000;
  3778.         enemy->xmaxbounce = 10000;
  3779.         enemy->yminbounce = -10000;
  3780.         enemy->ymaxbounce = 10000;
  3781.         /*Far enough away to be impossible to reach*/
  3782.  
  3783.         for (uint i = 0; i < 3; ++i)
  3784.         {
  3785.                 enemy->tur[i] = enemyDat[eDatI].tur[i];
  3786.         }
  3787.  
  3788.         enemy->ani = enemyDat[eDatI].ani;
  3789.         enemy->animin = 1;
  3790.  
  3791.         switch (enemyDat[eDatI].animate)
  3792.         {
  3793.         case 0:
  3794.                 enemy->enemycycle = 1;
  3795.                 enemy->aniactive = 0;
  3796.                 enemy->animax = 0;
  3797.                 enemy->aniwhenfire = 0;
  3798.                 break;
  3799.         case 1:
  3800.                 enemy->enemycycle = 0;
  3801.                 enemy->aniactive = 1;
  3802.                 enemy->animax = 0;
  3803.                 enemy->aniwhenfire = 0;
  3804.                 break;
  3805.         case 2:
  3806.                 enemy->enemycycle = 1;
  3807.                 enemy->aniactive = 2;
  3808.                 enemy->animax = enemy->ani;
  3809.                 enemy->aniwhenfire = 2;
  3810.                 break;
  3811.         }
  3812.  
  3813.         if (enemyDat[eDatI].startxc != 0)
  3814.                 enemy->ex = enemyDat[eDatI].startx + (mt_rand() % (enemyDat[eDatI].startxc * 2)) - enemyDat[eDatI].startxc + 1;
  3815.         else
  3816.                 enemy->ex = enemyDat[eDatI].startx + 1;
  3817.  
  3818.         if (enemyDat[eDatI].startyc != 0)
  3819.                 enemy->ey = enemyDat[eDatI].starty + (mt_rand() % (enemyDat[eDatI].startyc * 2)) - enemyDat[eDatI].startyc + 1;
  3820.         else
  3821.                 enemy->ey = enemyDat[eDatI].starty + 1;
  3822.  
  3823.         enemy->exc = enemyDat[eDatI].xmove;
  3824.         enemy->eyc = enemyDat[eDatI].ymove;
  3825.         enemy->excc = enemyDat[eDatI].xcaccel;
  3826.         enemy->eycc = enemyDat[eDatI].ycaccel;
  3827.         enemy->exccw = abs(enemy->excc);
  3828.         enemy->exccwmax = enemy->exccw;
  3829.         enemy->eyccw = abs(enemy->eycc);
  3830.         enemy->eyccwmax = enemy->eyccw;
  3831.         enemy->exccadd = (enemy->excc > 0) ? 1 : -1;
  3832.         enemy->eyccadd = (enemy->eycc > 0) ? 1 : -1;
  3833.         enemy->special = false;
  3834.         enemy->iced = 0;
  3835.  
  3836.         if (enemyDat[eDatI].xrev == 0)
  3837.                 enemy->exrev = 100;
  3838.         else if (enemyDat[eDatI].xrev == -99)
  3839.                 enemy->exrev = 0;
  3840.         else
  3841.                 enemy->exrev = enemyDat[eDatI].xrev;
  3842.  
  3843.         if (enemyDat[eDatI].yrev == 0)
  3844.                 enemy->eyrev = 100;
  3845.         else if (enemyDat[eDatI].yrev == -99)
  3846.                 enemy->eyrev = 0;
  3847.         else
  3848.                 enemy->eyrev = enemyDat[eDatI].yrev;
  3849.  
  3850.         enemy->exca = (enemy->xaccel > 0) ? 1 : -1;
  3851.         enemy->eyca = (enemy->yaccel > 0) ? 1 : -1;
  3852.  
  3853.         enemy->enemytype = eDatI;
  3854.  
  3855.         for (uint i = 0; i < 3; ++i)
  3856.         {
  3857.                 if (enemy->tur[i] == 252)
  3858.                         enemy->eshotwait[i] = 1;
  3859.                 else if (enemy->tur[i] > 0)
  3860.                         enemy->eshotwait[i] = 20;
  3861.                 else
  3862.                         enemy->eshotwait[i] = 255;
  3863.         }
  3864.         for (uint i = 0; i < 20; ++i)
  3865.                 enemy->egr[i] = enemyDat[eDatI].egraphic[i];
  3866.         enemy->size = enemyDat[eDatI].esize;
  3867.         enemy->linknum = 0;
  3868.         enemy->edamaged = enemyDat[eDatI].dani < 0;
  3869.         enemy->enemydie = enemyDat[eDatI].eenemydie;
  3870.  
  3871.         enemy->freq[1-1] = enemyDat[eDatI].freq[1-1];
  3872.         enemy->freq[2-1] = enemyDat[eDatI].freq[2-1];
  3873.         enemy->freq[3-1] = enemyDat[eDatI].freq[3-1];
  3874.  
  3875.         enemy->edani   = enemyDat[eDatI].dani;
  3876.         enemy->edgr    = enemyDat[eDatI].dgr;
  3877.         enemy->edlevel = enemyDat[eDatI].dlevel;
  3878.  
  3879.         enemy->fixedmovey = 0;
  3880.  
  3881.         enemy->filter = 0x00;
  3882.  
  3883.         int tempValue = 0;
  3884.         if (enemyDat[eDatI].value > 1 && enemyDat[eDatI].value < 10000)
  3885.         {
  3886.                 switch (difficultyLevel)
  3887.                 {
  3888.                 case -1:
  3889.                 case 0:
  3890.                         tempValue = enemyDat[eDatI].value * 0.75f;
  3891.                         break;
  3892.                 case 1:
  3893.                 case 2:
  3894.                         tempValue = enemyDat[eDatI].value;
  3895.                         break;
  3896.                 case 3:
  3897.                         tempValue = enemyDat[eDatI].value * 1.125f;
  3898.                         break;
  3899.                 case 4:
  3900.                         tempValue = enemyDat[eDatI].value * 1.5f;
  3901.                         break;
  3902.                 case 5:
  3903.                         tempValue = enemyDat[eDatI].value * 2;
  3904.                         break;
  3905.                 case 6:
  3906.                         tempValue = enemyDat[eDatI].value * 2.5f;
  3907.                         break;
  3908.                 case 7:
  3909.                 case 8:
  3910.                         tempValue = enemyDat[eDatI].value * 4;
  3911.                         break;
  3912.                 case 9:
  3913.                 case 10:
  3914.                         tempValue = enemyDat[eDatI].value * 8;
  3915.                         break;
  3916.                 }
  3917.                 if (tempValue > 10000)
  3918.                         tempValue = 10000;
  3919.                 enemy->evalue = tempValue;
  3920.         }
  3921.         else
  3922.         {
  3923.                 enemy->evalue = enemyDat[eDatI].value;
  3924.         }
  3925.  
  3926.         int tempArmor = 1;
  3927.         if (enemyDat[eDatI].armor > 0)
  3928.         {
  3929.                 if (enemyDat[eDatI].armor != 255)
  3930.                 {
  3931.                         switch (difficultyLevel)
  3932.                         {
  3933.                         case -1:
  3934.                         case 0:
  3935.                                 tempArmor = enemyDat[eDatI].armor * 0.5f + 1;
  3936.                                 break;
  3937.                         case 1:
  3938.                                 tempArmor = enemyDat[eDatI].armor * 0.75f + 1;
  3939.                                 break;
  3940.                         case 2:
  3941.                                 tempArmor = enemyDat[eDatI].armor;
  3942.                                 break;
  3943.                         case 3:
  3944.                                 tempArmor = enemyDat[eDatI].armor * 1.2f;
  3945.                                 break;
  3946.                         case 4:
  3947.                                 tempArmor = enemyDat[eDatI].armor * 1.5f;
  3948.                                 break;
  3949.                         case 5:
  3950.                                 tempArmor = enemyDat[eDatI].armor * 1.8f;
  3951.                                 break;
  3952.                         case 6:
  3953.                                 tempArmor = enemyDat[eDatI].armor * 2;
  3954.                                 break;
  3955.                         case 7:
  3956.                                 tempArmor = enemyDat[eDatI].armor * 3;
  3957.                                 break;
  3958.                         case 8:
  3959.                                 tempArmor = enemyDat[eDatI].armor * 4;
  3960.                                 break;
  3961.                         case 9:
  3962.                         case 10:
  3963.                                 tempArmor = enemyDat[eDatI].armor * 8;
  3964.                                 break;
  3965.                         }
  3966.  
  3967.                         if (tempArmor > 254)
  3968.                         {
  3969.                                 tempArmor = 254;
  3970.                         }
  3971.                 }
  3972.                 else
  3973.                 {
  3974.                         tempArmor = 255;
  3975.                 }
  3976.  
  3977.                 enemy->armorleft = tempArmor;
  3978.  
  3979.                 avail = 0;
  3980.                 enemy->scoreitem = false;
  3981.         }
  3982.         else
  3983.         {
  3984.                 avail = 2;
  3985.                 enemy->armorleft = 255;
  3986.                 if (enemy->evalue != 0)
  3987.                         enemy->scoreitem = true;
  3988.         }
  3989.  
  3990.         if (!enemy->scoreitem)
  3991.         {
  3992.                 totalEnemy++;  /*Destruction ratio*/
  3993.         }
  3994.  
  3995.         /* indicates what to set ENEMYAVAIL to */
  3996.         return avail;
  3997. }
  3998.  
  3999. void JE_createNewEventEnemy( JE_byte enemyTypeOfs, JE_word enemyOffset, Sint16 uniqueShapeTableI )
  4000. {
  4001.         int i;
  4002.  
  4003.         b = 0;
  4004.  
  4005.         for(i = enemyOffset; i < enemyOffset + 25; i++)
  4006.         {
  4007.                 if (enemyAvail[i] == 1)
  4008.                 {
  4009.                         b = i + 1;
  4010.                         break;
  4011.                 }
  4012.         }
  4013.  
  4014.         if (b == 0)
  4015.         {
  4016.                 return;
  4017.         }
  4018.  
  4019.         tempW = eventRec[eventLoc-1].eventdat + enemyTypeOfs;
  4020.  
  4021.         enemyAvail[b-1] = JE_makeEnemy(&enemy[b-1], tempW, uniqueShapeTableI);
  4022.  
  4023.         if (eventRec[eventLoc-1].eventdat2 != -99)
  4024.         {
  4025.                 switch (enemyOffset)
  4026.                 {
  4027.                 case 0:
  4028.                         enemy[b-1].ex = eventRec[eventLoc-1].eventdat2 - (mapX - 1) * 24;
  4029.                         enemy[b-1].ey -= backMove2;
  4030.                         break;
  4031.                 case 25:
  4032.                 case 75:
  4033.                         enemy[b-1].ex = eventRec[eventLoc-1].eventdat2 - (mapX - 1) * 24 - 12;
  4034.                         enemy[b-1].ey -= backMove;
  4035.                         break;
  4036.                 case 50:
  4037.                         if (background3x1)
  4038.                         {
  4039.                                 enemy[b-1].ex = eventRec[eventLoc-1].eventdat2 - (mapX - 1) * 24 - 12;
  4040.                         } else {
  4041.                                 enemy[b-1].ex = eventRec[eventLoc-1].eventdat2 - mapX3 * 24 - 24 * 2 + 6;
  4042.                         }
  4043.                         enemy[b-1].ey -= backMove3;
  4044.  
  4045.                         if (background3x1b)
  4046.                         {
  4047.                                 enemy[b-1].ex -= 6;
  4048.                         }
  4049.                         break;
  4050.                 }
  4051.                 enemy[b-1].ey = -28;
  4052.                 if (background3x1b && enemyOffset == 50)
  4053.                 {
  4054.                         enemy[b-1].ey += 4;
  4055.                 }
  4056.         }
  4057.  
  4058.         if (smallEnemyAdjust && enemy[b-1].size == 0)
  4059.         {
  4060.                 enemy[b-1].ex -= 10;
  4061.                 enemy[b-1].ey -= 7;
  4062.         }
  4063.  
  4064.         enemy[b-1].ey += eventRec[eventLoc-1].eventdat5;
  4065.         enemy[b-1].eyc += eventRec[eventLoc-1].eventdat3;
  4066.         enemy[b-1].linknum = eventRec[eventLoc-1].eventdat4;
  4067.         enemy[b-1].fixedmovey = eventRec[eventLoc-1].eventdat6;
  4068. }
  4069.  
  4070. void JE_eventJump( JE_word jump )
  4071. {
  4072.         JE_word tempW;
  4073.  
  4074.         if (jump == 65535)
  4075.         {
  4076.                 curLoc = returnLoc;
  4077.         }
  4078.         else
  4079.         {
  4080.                 returnLoc = curLoc + 1;
  4081.                 curLoc = jump;
  4082.         }
  4083.         tempW = 0;
  4084.         do
  4085.         {
  4086.                 tempW++;
  4087.         }
  4088.         while (!(eventRec[tempW-1].eventtime >= curLoc));
  4089.         eventLoc = tempW - 1;
  4090. }
  4091.  
  4092. bool JE_searchFor/*enemy*/( JE_byte PLType, JE_byte* out_index )
  4093. {
  4094.         int found_id = -1;
  4095.  
  4096.         for (int i = 0; i < 100; i++)
  4097.         {
  4098.                 if (enemyAvail[i] == 0 && enemy[i].linknum == PLType)
  4099.                 {
  4100.                         found_id = i;
  4101.                         if (galagaMode)
  4102.                         {
  4103.                                 enemy[i].evalue += enemy[i].evalue;
  4104.                         }
  4105.                 }
  4106.         }
  4107.  
  4108.         if (found_id != -1) {
  4109.                 if (out_index) {
  4110.                         *out_index = found_id;
  4111.                 }
  4112.                 return true;
  4113.         } else {
  4114.                 return false;
  4115.         }
  4116. }
  4117.  
  4118. void JE_eventSystem( void )
  4119. {
  4120.         switch (eventRec[eventLoc-1].eventtype)
  4121.         {
  4122.         case 1:
  4123.                 starfield_speed = eventRec[eventLoc-1].eventdat;
  4124.                 break;
  4125.  
  4126.         case 2:
  4127.                 map1YDelay = 1;
  4128.                 map1YDelayMax = 1;
  4129.                 map2YDelay = 1;
  4130.                 map2YDelayMax = 1;
  4131.  
  4132.                 backMove = eventRec[eventLoc-1].eventdat;
  4133.                 backMove2 = eventRec[eventLoc-1].eventdat2;
  4134.  
  4135.                 if (backMove2 > 0)
  4136.                         explodeMove = backMove2;
  4137.                 else
  4138.                         explodeMove = backMove;
  4139.  
  4140.                 backMove3 = eventRec[eventLoc-1].eventdat3;
  4141.  
  4142.                 if (backMove > 0)
  4143.                         stopBackgroundNum = 0;
  4144.                 break;
  4145.  
  4146.         case 3:
  4147.                 backMove = 1;
  4148.                 map1YDelay = 3;
  4149.                 map1YDelayMax = 3;
  4150.                 backMove2 = 1;
  4151.                 map2YDelay = 2;
  4152.                 map2YDelayMax = 2;
  4153.                 backMove3 = 1;
  4154.                 break;
  4155.  
  4156.         case 4:
  4157.                 stopBackgrounds = true;
  4158.                 switch (eventRec[eventLoc-1].eventdat)
  4159.                 {
  4160.                 case 0:
  4161.                 case 1:
  4162.                         stopBackgroundNum = 1;
  4163.                         break;
  4164.                 case 2:
  4165.                         stopBackgroundNum = 2;
  4166.                         break;
  4167.                 case 3:
  4168.                         stopBackgroundNum = 3;
  4169.                         break;
  4170.                 }
  4171.                 break;
  4172.  
  4173.         case 5:  // load enemy shape banks
  4174.                 {
  4175.                         Uint8 newEnemyShapeTables[] =
  4176.                         {
  4177.                                 eventRec[eventLoc-1].eventdat > 0 ? eventRec[eventLoc-1].eventdat : 0,
  4178.                                 eventRec[eventLoc-1].eventdat2 > 0 ? eventRec[eventLoc-1].eventdat2 : 0,
  4179.                                 eventRec[eventLoc-1].eventdat3 > 0 ? eventRec[eventLoc-1].eventdat3 : 0,
  4180.                                 eventRec[eventLoc-1].eventdat4 > 0 ? eventRec[eventLoc-1].eventdat4 : 0,
  4181.                         };
  4182.                        
  4183.                         for (unsigned int i = 0; i < COUNTOF(newEnemyShapeTables); ++i)
  4184.                         {
  4185.                                 if (enemyShapeTables[i] != newEnemyShapeTables[i])
  4186.                                 {
  4187.                                         if (newEnemyShapeTables[i] > 0)
  4188.                                         {
  4189.                                                 assert(newEnemyShapeTables[i] <= COUNTOF(shapeFile));
  4190.                                                 JE_loadCompShapes(&eShapes[i], shapeFile[newEnemyShapeTables[i] - 1]);
  4191.                                         }
  4192.                                         else
  4193.                                                 free_sprite2s(&eShapes[i]);
  4194.  
  4195.                                         enemyShapeTables[i] = newEnemyShapeTables[i];
  4196.                                 }
  4197.                         }
  4198.                 }
  4199.                 break;
  4200.  
  4201.         case 6: /* Ground Enemy */
  4202.                 JE_createNewEventEnemy(0, 25, 0);
  4203.                 break;
  4204.  
  4205.         case 7: /* Top Enemy */
  4206.                 JE_createNewEventEnemy(0, 50, 0);
  4207.                 break;
  4208.  
  4209.         case 8:
  4210.                 starActive = false;
  4211.                 break;
  4212.  
  4213.         case 9:
  4214.                 starActive = true;
  4215.                 break;
  4216.  
  4217.         case 10: /* Ground Enemy 2 */
  4218.                 JE_createNewEventEnemy(0, 75, 0);
  4219.                 break;
  4220.  
  4221.         case 11:
  4222.                 if (allPlayersGone || eventRec[eventLoc-1].eventdat == 1)
  4223.                         reallyEndLevel = true;
  4224.                 else
  4225.                         if (!endLevel)
  4226.                         {
  4227.                                 readyToEndLevel = false;
  4228.                                 endLevel = true;
  4229.                                 levelEnd = 40;
  4230.                         }
  4231.                 break;
  4232.  
  4233.         case 12: /* Custom 4x4 Ground Enemy */
  4234.                 {
  4235.                         uint temp = 0;
  4236.                         switch (eventRec[eventLoc-1].eventdat6)
  4237.                         {
  4238.                         case 0:
  4239.                         case 1:
  4240.                                 temp = 25;
  4241.                                 break;
  4242.                         case 2:
  4243.                                 temp = 0;
  4244.                                 break;
  4245.                         case 3:
  4246.                                 temp = 50;
  4247.                                 break;
  4248.                         case 4:
  4249.                                 temp = 75;
  4250.                                 break;
  4251.                         }
  4252.                         eventRec[eventLoc-1].eventdat6 = 0;   /* We use EVENTDAT6 for the background */
  4253.                         JE_createNewEventEnemy(0, temp, 0);
  4254.                         JE_createNewEventEnemy(1, temp, 0);
  4255.                         if (b > 0)
  4256.                                 enemy[b-1].ex += 24;
  4257.                         JE_createNewEventEnemy(2, temp, 0);
  4258.                         if (b > 0)
  4259.                                 enemy[b-1].ey -= 28;
  4260.                         JE_createNewEventEnemy(3, temp, 0);
  4261.                         if (b > 0)
  4262.                         {
  4263.                                 enemy[b-1].ex += 24;
  4264.                                 enemy[b-1].ey -= 28;
  4265.                         }
  4266.                         break;
  4267.                 }
  4268.         case 13:
  4269.                 enemiesActive = false;
  4270.                 break;
  4271.  
  4272.         case 14:
  4273.                 enemiesActive = true;
  4274.                 break;
  4275.  
  4276.         case 15: /* Sky Enemy */
  4277.                 JE_createNewEventEnemy(0, 0, 0);
  4278.                 break;
  4279.  
  4280.         case 16:
  4281.                 if (eventRec[eventLoc-1].eventdat > 9)
  4282.                 {
  4283.                         fprintf(stderr, "warning: event 16: bad event data\n");
  4284.                 }
  4285.                 else
  4286.                 {
  4287.                         JE_drawTextWindow(outputs[eventRec[eventLoc-1].eventdat-1]);
  4288.                         soundQueue[3] = windowTextSamples[eventRec[eventLoc-1].eventdat-1];
  4289.                 }
  4290.                 break;
  4291.  
  4292.         case 17: /* Ground Bottom */
  4293.                 JE_createNewEventEnemy(0, 25, 0);
  4294.                 if (b > 0)
  4295.                 {
  4296.                         enemy[b-1].ey = 190 + eventRec[eventLoc-1].eventdat5;
  4297.                 }
  4298.                 break;
  4299.  
  4300.         case 18: /* Sky Enemy on Bottom */
  4301.                 JE_createNewEventEnemy(0, 0, 0);
  4302.                 if (b > 0)
  4303.                 {
  4304.                         enemy[b-1].ey = 190 + eventRec[eventLoc-1].eventdat5;
  4305.                 }
  4306.                 break;
  4307.  
  4308.         case 19: /* Enemy Global Move */
  4309.         {
  4310.                 int initial_i = 0, max_i = 0;
  4311.                 bool all_enemies = false;
  4312.  
  4313.                 if (eventRec[eventLoc-1].eventdat3 > 79 && eventRec[eventLoc-1].eventdat3 < 90)
  4314.                 {
  4315.                         initial_i = 0;
  4316.                         max_i = 100;
  4317.                         all_enemies = false;
  4318.                         eventRec[eventLoc-1].eventdat4 = newPL[eventRec[eventLoc-1].eventdat3 - 80];
  4319.                 }
  4320.                 else
  4321.                 {
  4322.                         switch (eventRec[eventLoc-1].eventdat3)
  4323.                         {
  4324.                         case 0:
  4325.                                 initial_i = 0;
  4326.                                 max_i = 100;
  4327.                                 all_enemies = false;
  4328.                                 break;
  4329.                         case 2:
  4330.                                 initial_i = 0;
  4331.                                 max_i = 25;
  4332.                                 all_enemies = true;
  4333.                                 break;
  4334.                         case 1:
  4335.                                 initial_i = 25;
  4336.                                 max_i = 50;
  4337.                                 all_enemies = true;
  4338.                                 break;
  4339.                         case 3:
  4340.                                 initial_i = 50;
  4341.                                 max_i = 75;
  4342.                                 all_enemies = true;
  4343.                                 break;
  4344.                         case 99:
  4345.                                 initial_i = 0;
  4346.                                 max_i = 100;
  4347.                                 all_enemies = true;
  4348.                                 break;
  4349.                         }
  4350.                 }
  4351.  
  4352.                 for (int i = initial_i; i < max_i; i++)
  4353.                 {
  4354.                         if (all_enemies || enemy[i].linknum == eventRec[eventLoc-1].eventdat4)
  4355.                         {
  4356.                                 if (eventRec[eventLoc-1].eventdat != -99)
  4357.                                         enemy[i].exc = eventRec[eventLoc-1].eventdat;
  4358.  
  4359.                                 if (eventRec[eventLoc-1].eventdat2 != -99)
  4360.                                         enemy[i].eyc = eventRec[eventLoc-1].eventdat2;
  4361.  
  4362.                                 if (eventRec[eventLoc-1].eventdat6 != 0)
  4363.                                         enemy[i].fixedmovey = eventRec[eventLoc-1].eventdat6;
  4364.  
  4365.                                 if (eventRec[eventLoc-1].eventdat6 == -99)
  4366.                                         enemy[i].fixedmovey = 0;
  4367.  
  4368.                                 if (eventRec[eventLoc-1].eventdat5 > 0)
  4369.                                         enemy[i].enemycycle = eventRec[eventLoc-1].eventdat5;
  4370.                         }
  4371.                 }
  4372.                 break;
  4373.         }
  4374.  
  4375.         case 20: /* Enemy Global Accel */
  4376.                 if (eventRec[eventLoc-1].eventdat3 > 79 && eventRec[eventLoc-1].eventdat3 < 90)
  4377.                         eventRec[eventLoc-1].eventdat4 = newPL[eventRec[eventLoc-1].eventdat3 - 80];
  4378.  
  4379.                 for (temp = 0; temp < 100; temp++)
  4380.                 {
  4381.                         if (enemyAvail[temp] != 1
  4382.                             && (enemy[temp].linknum == eventRec[eventLoc-1].eventdat4 || eventRec[eventLoc-1].eventdat4 == 0))
  4383.                         {
  4384.                                 if (eventRec[eventLoc-1].eventdat != -99)
  4385.                                 {
  4386.                                         enemy[temp].excc = eventRec[eventLoc-1].eventdat;
  4387.                                         enemy[temp].exccw = abs(eventRec[eventLoc-1].eventdat);
  4388.                                         enemy[temp].exccwmax = abs(eventRec[eventLoc-1].eventdat);
  4389.                                         if (eventRec[eventLoc-1].eventdat > 0)
  4390.                                                 enemy[temp].exccadd = 1;
  4391.                                         else
  4392.                                                 enemy[temp].exccadd = -1;
  4393.                                 }
  4394.  
  4395.                                 if (eventRec[eventLoc-1].eventdat2 != -99)
  4396.                                 {
  4397.                                         enemy[temp].eycc = eventRec[eventLoc-1].eventdat2;
  4398.                                         enemy[temp].eyccw = abs(eventRec[eventLoc-1].eventdat2);
  4399.                                         enemy[temp].eyccwmax = abs(eventRec[eventLoc-1].eventdat2);
  4400.                                         if (eventRec[eventLoc-1].eventdat2 > 0)
  4401.                                                 enemy[temp].eyccadd = 1;
  4402.                                         else
  4403.                                                 enemy[temp].eyccadd = -1;
  4404.                                 }
  4405.  
  4406.                                 if (eventRec[eventLoc-1].eventdat5 > 0)
  4407.                                 {
  4408.                                         enemy[temp].enemycycle = eventRec[eventLoc-1].eventdat5;
  4409.                                 }
  4410.                                 if (eventRec[eventLoc-1].eventdat6 > 0)
  4411.                                 {
  4412.                                         enemy[temp].ani = eventRec[eventLoc-1].eventdat6;
  4413.                                         enemy[temp].animin = eventRec[eventLoc-1].eventdat5;
  4414.                                         enemy[temp].animax = 0;
  4415.                                         enemy[temp].aniactive = 1;
  4416.                                 }
  4417.                         }
  4418.                 }
  4419.                 break;
  4420.  
  4421.         case 21:
  4422.                 background3over = 1;
  4423.                 break;
  4424.  
  4425.         case 22:
  4426.                 background3over = 0;
  4427.                 break;
  4428.  
  4429.         case 23: /* Sky Enemy on Bottom */
  4430.                 JE_createNewEventEnemy(0, 50, 0);
  4431.                 if (b > 0)
  4432.                         enemy[b-1].ey = 180 + eventRec[eventLoc-1].eventdat5;
  4433.                 break;
  4434.  
  4435.         case 24: /* Enemy Global Animate */
  4436.                 for (temp = 0; temp < 100; temp++)
  4437.                 {
  4438.                         if (enemy[temp].linknum == eventRec[eventLoc-1].eventdat4)
  4439.                         {
  4440.                                 enemy[temp].aniactive = 1;
  4441.                                 enemy[temp].aniwhenfire = 0;
  4442.                                 if (eventRec[eventLoc-1].eventdat2 > 0)
  4443.                                 {
  4444.                                         enemy[temp].enemycycle = eventRec[eventLoc-1].eventdat2;
  4445.                                         enemy[temp].animin = enemy[temp].enemycycle;
  4446.                                 }
  4447.                                 else
  4448.                                 {
  4449.                                         enemy[temp].enemycycle = 0;
  4450.                                 }
  4451.  
  4452.                                 if (eventRec[eventLoc-1].eventdat > 0)
  4453.                                         enemy[temp].ani = eventRec[eventLoc-1].eventdat;
  4454.  
  4455.                                 if (eventRec[eventLoc-1].eventdat3 == 1)
  4456.                                 {
  4457.                                         enemy[temp].animax = enemy[temp].ani;
  4458.                                 }
  4459.                                 else if (eventRec[eventLoc-1].eventdat3 == 2)
  4460.                                 {
  4461.                                         enemy[temp].aniactive = 2;
  4462.                                         enemy[temp].animax = enemy[temp].ani;
  4463.                                         enemy[temp].aniwhenfire = 2;
  4464.                                 }
  4465.                         }
  4466.                 }
  4467.                 break;
  4468.  
  4469.         case 25: /* Enemy Global Damage change */
  4470.                 for (temp = 0; temp < 100; temp++)
  4471.                 {
  4472.                         if (eventRec[eventLoc-1].eventdat4 == 0 || enemy[temp].linknum == eventRec[eventLoc-1].eventdat4)
  4473.                         {
  4474.                                 if (galagaMode)
  4475.                                         enemy[temp].armorleft = roundf(eventRec[eventLoc-1].eventdat * (difficultyLevel / 2));
  4476.                                 else
  4477.                                         enemy[temp].armorleft = eventRec[eventLoc-1].eventdat;
  4478.                         }
  4479.                 }
  4480.                 break;
  4481.  
  4482.         case 26:
  4483.                 smallEnemyAdjust = eventRec[eventLoc-1].eventdat;
  4484.                 break;
  4485.  
  4486.         case 27: /* Enemy Global AccelRev */
  4487.                 if (eventRec[eventLoc-1].eventdat3 > 79 && eventRec[eventLoc-1].eventdat3 < 90)
  4488.                         eventRec[eventLoc-1].eventdat4 = newPL[eventRec[eventLoc-1].eventdat3 - 80];
  4489.  
  4490.                 for (temp = 0; temp < 100; temp++)
  4491.                 {
  4492.                         if (eventRec[eventLoc-1].eventdat4 == 0 || enemy[temp].linknum == eventRec[eventLoc-1].eventdat4)
  4493.                         {
  4494.                                 if (eventRec[eventLoc-1].eventdat != -99)
  4495.                                         enemy[temp].exrev = eventRec[eventLoc-1].eventdat;
  4496.                                 if (eventRec[eventLoc-1].eventdat2 != -99)
  4497.                                         enemy[temp].eyrev = eventRec[eventLoc-1].eventdat2;
  4498.                                 if (eventRec[eventLoc-1].eventdat3 != 0 && eventRec[eventLoc-1].eventdat3 < 17)
  4499.                                         enemy[temp].filter = eventRec[eventLoc-1].eventdat3;
  4500.                         }
  4501.                 }
  4502.                 break;
  4503.  
  4504.         case 28:
  4505.                 topEnemyOver = false;
  4506.                 break;
  4507.  
  4508.         case 29:
  4509.                 topEnemyOver = true;
  4510.                 break;
  4511.  
  4512.         case 30:
  4513.                 map1YDelay = 1;
  4514.                 map1YDelayMax = 1;
  4515.                 map2YDelay = 1;
  4516.                 map2YDelayMax = 1;
  4517.  
  4518.                 backMove = eventRec[eventLoc-1].eventdat;
  4519.                 backMove2 = eventRec[eventLoc-1].eventdat2;
  4520.                 explodeMove = backMove2;
  4521.                 backMove3 = eventRec[eventLoc-1].eventdat3;
  4522.                 break;
  4523.  
  4524.         case 31: /* Enemy Fire Override */
  4525.                 for (temp = 0; temp < 100; temp++)
  4526.                 {
  4527.                         if (eventRec[eventLoc-1].eventdat4 == 99 || enemy[temp].linknum == eventRec[eventLoc-1].eventdat4)
  4528.                         {
  4529.                                 enemy[temp].freq[1-1] = eventRec[eventLoc-1].eventdat ;
  4530.                                 enemy[temp].freq[2-1] = eventRec[eventLoc-1].eventdat2;
  4531.                                 enemy[temp].freq[3-1] = eventRec[eventLoc-1].eventdat3;
  4532.                                 for (temp2 = 0; temp2 < 3; temp2++)
  4533.                                 {
  4534.                                         enemy[temp].eshotwait[temp2] = 1;
  4535.                                 }
  4536.                                 if (enemy[temp].launchtype > 0)
  4537.                                 {
  4538.                                         enemy[temp].launchfreq = eventRec[eventLoc-1].eventdat5;
  4539.                                         enemy[temp].launchwait = 1;
  4540.                                 }
  4541.                         }
  4542.                 }
  4543.                 break;
  4544.  
  4545.         case 32:  // create enemy
  4546.                 JE_createNewEventEnemy(0, 50, 0);
  4547.                 if (b > 0)
  4548.                         enemy[b-1].ey = 190;
  4549.                 break;
  4550.  
  4551.         case 33: /* Enemy From other Enemies */
  4552.                 if (!((eventRec[eventLoc-1].eventdat == 512 || eventRec[eventLoc-1].eventdat == 513) && (twoPlayerMode || onePlayerAction || superTyrian)))
  4553.                 {
  4554.                         if (superArcadeMode != SA_NONE)
  4555.                         {
  4556.                                 if (eventRec[eventLoc-1].eventdat == 534)
  4557.                                         eventRec[eventLoc-1].eventdat = 827;
  4558.                         }
  4559.                         else if (!superTyrian)
  4560.                         {
  4561.                                 const uint lives = *player[0].lives;
  4562.  
  4563.                                 if (eventRec[eventLoc-1].eventdat == 533 && (lives == 11 || (mt_rand() % 15) < lives))
  4564.                                 {
  4565.                                         // enemy will drop random special weapon
  4566.                                         eventRec[eventLoc-1].eventdat = 829 + (mt_rand() % 6);
  4567.                                 }
  4568.                         }
  4569.                         if (eventRec[eventLoc-1].eventdat == 534 && superTyrian)
  4570.                                 eventRec[eventLoc-1].eventdat = 828 + superTyrianSpecials[mt_rand() % 4];
  4571.  
  4572.                         for (temp = 0; temp < 100; temp++)
  4573.                         {
  4574.                                 if (enemy[temp].linknum == eventRec[eventLoc-1].eventdat4)
  4575.                                         enemy[temp].enemydie = eventRec[eventLoc-1].eventdat;
  4576.                         }
  4577.                 }
  4578.                 break;
  4579.  
  4580.         case 34: /* Start Music Fade */
  4581.                 if (firstGameOver)
  4582.                 {
  4583.                         musicFade = true;
  4584.                         tempVolume = tyrMusicVolume;
  4585.                 }
  4586.                 break;
  4587.  
  4588.         case 35: /* Play new song */
  4589.                 if (firstGameOver)
  4590.                 {
  4591.                         play_song(eventRec[eventLoc-1].eventdat - 1);
  4592.                         set_volume(tyrMusicVolume, fxVolume);
  4593.                 }
  4594.                 musicFade = false;
  4595.                 break;
  4596.  
  4597.         case 36:
  4598.                 readyToEndLevel = true;
  4599.                 break;
  4600.  
  4601.         case 37:
  4602.                 levelEnemyFrequency = eventRec[eventLoc-1].eventdat;
  4603.                 break;
  4604.  
  4605.         case 38:
  4606.                 curLoc = eventRec[eventLoc-1].eventdat;
  4607.                 int new_event_loc = 1;
  4608.                 for (tempW = 0; tempW < maxEvent; tempW++)
  4609.                 {
  4610.                         if (eventRec[tempW].eventtime <= curLoc)
  4611.                         {
  4612.                                 new_event_loc = tempW+1 - 1;
  4613.                         }
  4614.                 }
  4615.                 eventLoc = new_event_loc;
  4616.                 break;
  4617.  
  4618.         case 39: /* Enemy Global Linknum Change */
  4619.                 for (temp = 0; temp < 100; temp++)
  4620.                 {
  4621.                         if (enemy[temp].linknum == eventRec[eventLoc-1].eventdat)
  4622.                                 enemy[temp].linknum = eventRec[eventLoc-1].eventdat2;
  4623.                 }
  4624.                 break;
  4625.  
  4626.         case 40: /* Enemy Continual Damage */
  4627.                 enemyContinualDamage = true;
  4628.                 break;
  4629.  
  4630.         case 41:
  4631.                 if (eventRec[eventLoc-1].eventdat == 0)
  4632.                 {
  4633.                         memset(enemyAvail, 1, sizeof(enemyAvail));
  4634.                 }
  4635.                 else
  4636.                 {
  4637.                         for (x = 0; x <= 24; x++)
  4638.                                 enemyAvail[x] = 1;
  4639.                 }
  4640.                 break;
  4641.  
  4642.         case 42:
  4643.                 background3over = 2;
  4644.                 break;
  4645.  
  4646.         case 43:
  4647.                 background2over = eventRec[eventLoc-1].eventdat;
  4648.                 break;
  4649.  
  4650.         case 44:
  4651.                 filterActive       = (eventRec[eventLoc-1].eventdat > 0);
  4652.                 filterFade         = (eventRec[eventLoc-1].eventdat == 2);
  4653.                 levelFilter        = eventRec[eventLoc-1].eventdat2;
  4654.                 levelBrightness    = eventRec[eventLoc-1].eventdat3;
  4655.                 levelFilterNew     = eventRec[eventLoc-1].eventdat4;
  4656.                 levelBrightnessChg = eventRec[eventLoc-1].eventdat5;
  4657.                 filterFadeStart    = (eventRec[eventLoc-1].eventdat6 == 0);
  4658.                 break;
  4659.  
  4660.         case 45: /* arcade-only enemy from other enemies */
  4661.                 if (!superTyrian)
  4662.                 {
  4663.                         const uint lives = *player[0].lives;
  4664.  
  4665.                         if (eventRec[eventLoc-1].eventdat == 533 && (lives == 11 || (mt_rand() % 15) < lives))
  4666.                         {
  4667.                                 eventRec[eventLoc-1].eventdat = 829 + (mt_rand() % 6);
  4668.                         }
  4669.                         if (twoPlayerMode || onePlayerAction)
  4670.                         {
  4671.                                 for (temp = 0; temp < 100; temp++)
  4672.                                 {
  4673.                                         if (enemy[temp].linknum == eventRec[eventLoc-1].eventdat4)
  4674.                                                 enemy[temp].enemydie = eventRec[eventLoc-1].eventdat;
  4675.                                 }
  4676.                         }
  4677.                 }
  4678.                 break;
  4679.  
  4680.         case 46:  // change difficulty
  4681.                 if (eventRec[eventLoc-1].eventdat3 != 0)
  4682.                         damageRate = eventRec[eventLoc-1].eventdat3;
  4683.  
  4684.                 if (eventRec[eventLoc-1].eventdat2 == 0 || twoPlayerMode || onePlayerAction)
  4685.                 {
  4686.                         difficultyLevel += eventRec[eventLoc-1].eventdat;
  4687.                         if (difficultyLevel < 1)
  4688.                                 difficultyLevel = 1;
  4689.                         if (difficultyLevel > 10)
  4690.                                 difficultyLevel = 10;
  4691.                 }
  4692.                 break;
  4693.  
  4694.         case 47: /* Enemy Global AccelRev */
  4695.                 for (temp = 0; temp < 100; temp++)
  4696.                 {
  4697.                         if (eventRec[eventLoc-1].eventdat4 == 0 || enemy[temp].linknum == eventRec[eventLoc-1].eventdat4)
  4698.                                 enemy[temp].armorleft = eventRec[eventLoc-1].eventdat;
  4699.                 }
  4700.                 break;
  4701.  
  4702.         case 48: /* Background 2 Cannot be Transparent */
  4703.                 background2notTransparent = true;
  4704.                 break;
  4705.  
  4706.         case 49:
  4707.         case 50:
  4708.         case 51:
  4709.         case 52:
  4710.                 tempDat2 = eventRec[eventLoc-1].eventdat;
  4711.                 eventRec[eventLoc-1].eventdat = 0;
  4712.                 tempDat = eventRec[eventLoc-1].eventdat3;
  4713.                 eventRec[eventLoc-1].eventdat3 = 0;
  4714.                 tempDat3 = eventRec[eventLoc-1].eventdat6;
  4715.                 eventRec[eventLoc-1].eventdat6 = 0;
  4716.                 enemyDat[0].armor = tempDat3;
  4717.                 enemyDat[0].egraphic[1-1] = tempDat2;
  4718.                 switch (eventRec[eventLoc-1].eventtype - 48)
  4719.                 {
  4720.                 case 1:
  4721.                         temp = 25;
  4722.                         break;
  4723.                 case 2:
  4724.                         temp = 0;
  4725.                         break;
  4726.                 case 3:
  4727.                         temp = 50;
  4728.                         break;
  4729.                 case 4:
  4730.                         temp = 75;
  4731.                         break;
  4732.                 }
  4733.                 JE_createNewEventEnemy(0, temp, tempDat);
  4734.                 eventRec[eventLoc-1].eventdat = tempDat2;
  4735.                 eventRec[eventLoc-1].eventdat3 = tempDat;
  4736.                 eventRec[eventLoc-1].eventdat6 = tempDat3;
  4737.                 break;
  4738.  
  4739.         case 53:
  4740.                 forceEvents = (eventRec[eventLoc-1].eventdat != 99);
  4741.                 break;
  4742.  
  4743.         case 54:
  4744.                 JE_eventJump(eventRec[eventLoc-1].eventdat);
  4745.                 break;
  4746.  
  4747.         case 55: /* Enemy Global AccelRev */
  4748.                 if (eventRec[eventLoc-1].eventdat3 > 79 && eventRec[eventLoc-1].eventdat3 < 90)
  4749.                         eventRec[eventLoc-1].eventdat4 = newPL[eventRec[eventLoc-1].eventdat3 - 80];
  4750.  
  4751.                 for (temp = 0; temp < 100; temp++)
  4752.                 {
  4753.                         if (eventRec[eventLoc-1].eventdat4 == 0 || enemy[temp].linknum == eventRec[eventLoc-1].eventdat4)
  4754.                         {
  4755.                                 if (eventRec[eventLoc-1].eventdat != -99)
  4756.                                         enemy[temp].xaccel = eventRec[eventLoc-1].eventdat;
  4757.                                 if (eventRec[eventLoc-1].eventdat2 != -99)
  4758.                                         enemy[temp].yaccel = eventRec[eventLoc-1].eventdat2;
  4759.                         }
  4760.                 }
  4761.                 break;
  4762.  
  4763.         case 56: /* Ground2 Bottom */
  4764.                 JE_createNewEventEnemy(0, 75, 0);
  4765.                 if (b > 0)
  4766.                         enemy[b-1].ey = 190;
  4767.                 break;
  4768.  
  4769.         case 57:
  4770.                 superEnemy254Jump = eventRec[eventLoc-1].eventdat;
  4771.                 break;
  4772.  
  4773.         case 60: /*Assign Special Enemy*/
  4774.                 for (temp = 0; temp < 100; temp++)
  4775.                 {
  4776.                         if (enemy[temp].linknum == eventRec[eventLoc-1].eventdat4)
  4777.                         {
  4778.                                 enemy[temp].special = true;
  4779.                                 enemy[temp].flagnum = eventRec[eventLoc-1].eventdat;
  4780.                                 enemy[temp].setto  = (eventRec[eventLoc-1].eventdat2 == 1);
  4781.                         }
  4782.                 }
  4783.                 break;
  4784.  
  4785.         case 61:  // if specific flag set to specific value, skip events
  4786.                 if (globalFlags[eventRec[eventLoc-1].eventdat-1] == eventRec[eventLoc-1].eventdat2)
  4787.                         eventLoc += eventRec[eventLoc-1].eventdat3;
  4788.                 break;
  4789.  
  4790.         case 62: /*Play sound effect*/
  4791.                 soundQueue[3] = eventRec[eventLoc-1].eventdat;
  4792.                 break;
  4793.  
  4794.         case 63:  // skip events if not in 2-player mode
  4795.                 if (!twoPlayerMode && !onePlayerAction)
  4796.                         eventLoc += eventRec[eventLoc-1].eventdat;
  4797.                 break;
  4798.  
  4799.         case 64:
  4800.                 if (!(eventRec[eventLoc-1].eventdat == 6 && twoPlayerMode && difficultyLevel > 2))
  4801.                 {
  4802.                         smoothies[eventRec[eventLoc-1].eventdat-1] = eventRec[eventLoc-1].eventdat2;
  4803.                         temp = eventRec[eventLoc-1].eventdat;
  4804.                         if (temp == 5)
  4805.                                 temp = 3;
  4806.                         smoothie_data[temp-1] = eventRec[eventLoc-1].eventdat3;
  4807.                 }
  4808.                 break;
  4809.  
  4810.         case 65:
  4811.                 background3x1 = (eventRec[eventLoc-1].eventdat == 0);
  4812.                 break;
  4813.  
  4814.         case 66: /*If not on this difficulty level or higher then...*/
  4815.                 if (initialDifficulty <= eventRec[eventLoc-1].eventdat)
  4816.                         eventLoc += eventRec[eventLoc-1].eventdat2;
  4817.                 break;
  4818.  
  4819.         case 67:
  4820.                 levelTimer = (eventRec[eventLoc-1].eventdat == 1);
  4821.                 levelTimerCountdown = eventRec[eventLoc-1].eventdat3 * 100;
  4822.                 levelTimerJumpTo   = eventRec[eventLoc-1].eventdat2;
  4823.                 break;
  4824.  
  4825.         case 68:
  4826.                 randomExplosions = (eventRec[eventLoc-1].eventdat == 1);
  4827.                 break;
  4828.  
  4829.         case 69:
  4830.                 for (uint i = 0; i < COUNTOF(player); ++i)
  4831.                         player[i].invulnerable_ticks = eventRec[eventLoc-1].eventdat;
  4832.                 break;
  4833.  
  4834.         case 70:
  4835.                 if (eventRec[eventLoc-1].eventdat2 == 0)
  4836.                 {  /*1-10*/
  4837.                         bool found = false;
  4838.  
  4839.                         for (temp = 1; temp <= 19; temp++)
  4840.                                 found = found || JE_searchFor(temp, NULL);
  4841.  
  4842.                         if (!found)
  4843.                                 JE_eventJump(eventRec[eventLoc-1].eventdat);
  4844.                 }
  4845.                 else if (!JE_searchFor(eventRec[eventLoc-1].eventdat2, NULL)
  4846.                          && (eventRec[eventLoc-1].eventdat3 == 0 || !JE_searchFor(eventRec[eventLoc-1].eventdat3, NULL))
  4847.                          && (eventRec[eventLoc-1].eventdat4 == 0 || !JE_searchFor(eventRec[eventLoc-1].eventdat4, NULL)))
  4848.                 {
  4849.                         JE_eventJump(eventRec[eventLoc-1].eventdat);
  4850.                 }
  4851.                 break;
  4852.  
  4853.         case 71:
  4854.                 if (((((intptr_t)mapYPos - (intptr_t)&megaData1.mainmap) / sizeof(JE_byte *)) * 2) <= (unsigned)eventRec[eventLoc-1].eventdat2)
  4855.                 {
  4856.                         JE_eventJump(eventRec[eventLoc-1].eventdat);
  4857.                 }
  4858.                 break;
  4859.  
  4860.         case 72:
  4861.                 background3x1b = (eventRec[eventLoc-1].eventdat == 1);
  4862.                 break;
  4863.  
  4864.         case 73:
  4865.                 skyEnemyOverAll = (eventRec[eventLoc-1].eventdat == 1);
  4866.                 break;
  4867.  
  4868.         case 74: /* Enemy Global BounceParams */
  4869.                 for (temp = 0; temp < 100; temp++)
  4870.                 {
  4871.                         if (eventRec[eventLoc-1].eventdat4 == 0 || enemy[temp].linknum == eventRec[eventLoc-1].eventdat4)
  4872.                         {
  4873.                                 if (eventRec[eventLoc-1].eventdat5 != -99)
  4874.                                         enemy[temp].xminbounce = eventRec[eventLoc-1].eventdat5;
  4875.  
  4876.                                 if (eventRec[eventLoc-1].eventdat6 != -99)
  4877.                                         enemy[temp].yminbounce = eventRec[eventLoc-1].eventdat6;
  4878.  
  4879.                                 if (eventRec[eventLoc-1].eventdat != -99)
  4880.                                         enemy[temp].xmaxbounce = eventRec[eventLoc-1].eventdat;
  4881.  
  4882.                                 if (eventRec[eventLoc-1].eventdat2 != -99)
  4883.                                         enemy[temp].ymaxbounce = eventRec[eventLoc-1].eventdat2;
  4884.                         }
  4885.                 }
  4886.                 break;
  4887.  
  4888.         case 75:;
  4889.                 bool temp_no_clue = false; // TODO: figure out what this is doing
  4890.  
  4891.                 for (temp = 0; temp < 100; temp++)
  4892.                 {
  4893.                         if (enemyAvail[temp] == 0
  4894.                             && enemy[temp].eyc == 0
  4895.                             && enemy[temp].linknum >= eventRec[eventLoc-1].eventdat
  4896.                             && enemy[temp].linknum <= eventRec[eventLoc-1].eventdat2)
  4897.                         {
  4898.                                 temp_no_clue = true;
  4899.                         }
  4900.                 }
  4901.  
  4902.                 if (temp_no_clue)
  4903.                 {
  4904.                         JE_byte enemy_i;
  4905.                         do
  4906.                         {
  4907.                                 temp = (mt_rand() % (eventRec[eventLoc-1].eventdat2 + 1 - eventRec[eventLoc-1].eventdat)) + eventRec[eventLoc-1].eventdat;
  4908.                         }
  4909.                         while (!(JE_searchFor(temp, &enemy_i) && enemy[enemy_i].eyc == 0));
  4910.  
  4911.                         newPL[eventRec[eventLoc-1].eventdat3 - 80] = temp;
  4912.                 }
  4913.                 else
  4914.                 {
  4915.                         newPL[eventRec[eventLoc-1].eventdat3 - 80] = 255;
  4916.                         if (eventRec[eventLoc-1].eventdat4 > 0)
  4917.                         { /*Skip*/
  4918.                                 curLoc = eventRec[eventLoc-1 + eventRec[eventLoc-1].eventdat4].eventtime - 1;
  4919.                                 eventLoc += eventRec[eventLoc-1].eventdat4 - 1;
  4920.                         }
  4921.                 }
  4922.  
  4923.                 break;
  4924.  
  4925.         case 76:
  4926.                 returnActive = true;
  4927.                 break;
  4928.  
  4929.         case 77:
  4930.                 mapYPos = &megaData1.mainmap[0][0];
  4931.                 mapYPos += eventRec[eventLoc-1].eventdat / 2;
  4932.                 if (eventRec[eventLoc-1].eventdat2 > 0)
  4933.                 {
  4934.                         mapY2Pos = &megaData2.mainmap[0][0];
  4935.                         mapY2Pos += eventRec[eventLoc-1].eventdat2 / 2;
  4936.                 }
  4937.                 else
  4938.                 {
  4939.                         mapY2Pos = &megaData2.mainmap[0][0];
  4940.                         mapY2Pos += eventRec[eventLoc-1].eventdat / 2;
  4941.                 }
  4942.                 break;
  4943.  
  4944.         case 78:
  4945.                 if (galagaShotFreq < 10)
  4946.                         galagaShotFreq++;
  4947.                 break;
  4948.  
  4949.         case 79:
  4950.                 boss_bar[0].link_num = eventRec[eventLoc-1].eventdat;
  4951.                 boss_bar[1].link_num = eventRec[eventLoc-1].eventdat2;
  4952.                 break;
  4953.  
  4954.         case 80:  // skip events if in 2-player mode
  4955.                 if (twoPlayerMode)
  4956.                         eventLoc += eventRec[eventLoc-1].eventdat;
  4957.                 break;
  4958.  
  4959.         case 81: /*WRAP2*/
  4960.                 BKwrap2   = &megaData2.mainmap[0][0];
  4961.                 BKwrap2   += eventRec[eventLoc-1].eventdat / 2;
  4962.                 BKwrap2to = &megaData2.mainmap[0][0];
  4963.                 BKwrap2to += eventRec[eventLoc-1].eventdat2 / 2;
  4964.                 break;
  4965.  
  4966.         case 82: /*Give SPECIAL WEAPON*/
  4967.                 player[0].items.special = eventRec[eventLoc-1].eventdat;
  4968.                 shotMultiPos[SHOT_SPECIAL] = 0;
  4969.                 shotRepeat[SHOT_SPECIAL] = 0;
  4970.                 shotMultiPos[SHOT_SPECIAL2] = 0;
  4971.                 shotRepeat[SHOT_SPECIAL2] = 0;
  4972.                 break;
  4973.  
  4974.         default:
  4975.                 fprintf(stderr, "warning: ignoring unknown event %d\n", eventRec[eventLoc-1].eventtype);
  4976.                 break;
  4977.         }
  4978.  
  4979.         eventLoc++;
  4980. }
  4981.  
  4982. void JE_whoa( void )
  4983. {
  4984.         unsigned int i, j, color, offset, timer;
  4985.         unsigned int screenSize, topBorder, bottomBorder;
  4986.         Uint8 * TempScreen1, * TempScreen2, * TempScreenSwap;
  4987.  
  4988.         /* 'whoa' gets us that nifty screen fade used when you type in
  4989.          * 'engage'.  We need two temporary screen buffers (char arrays can
  4990.          * work too, but these screens already exist) for our effect.
  4991.          * This could probably be a lot more efficient (there's probably a
  4992.          * way to get vgascreen as one of the temp buffers), but it's only called
  4993.          * once so don't worry about it. */
  4994.  
  4995.         TempScreen1  = game_screen->pixels;
  4996.         TempScreen2  = VGAScreen2->pixels;
  4997.  
  4998.         screenSize   = VGAScreenSeg->h * VGAScreenSeg->pitch;
  4999.         topBorder    = VGAScreenSeg->pitch * 4; /* Seems an arbitrary number of lines */
  5000.         bottomBorder = VGAScreenSeg->pitch * 7;
  5001.  
  5002.         /* Okay, one disadvantage to using other screens as temp buffers: they
  5003.          * need to be the right size.  I doubt they'l ever be anything but 320x200,
  5004.          * but just in case, these asserts will clue in whoever stumbles across
  5005.          * the problem.  You can fix it with the stack or malloc. */
  5006.         assert( (unsigned)VGAScreen2->h *  VGAScreen2->pitch >= screenSize
  5007.             && (unsigned)game_screen->h * game_screen->pitch >= screenSize);
  5008.  
  5009.  
  5010.         /* Clear the top and bottom borders.  We don't want to process
  5011.          * them and we don't want to draw them. */
  5012.         memset((Uint8 *)VGAScreenSeg->pixels, 0, topBorder);
  5013.         memset((Uint8 *)VGAScreenSeg->pixels + screenSize - bottomBorder, 0, bottomBorder);
  5014.  
  5015.         /* Copy our test subject to one of the temporary buffers.  Blank the other */
  5016.         memset(TempScreen1, 0, screenSize);
  5017.         memcpy(TempScreen2, VGAScreenSeg->pixels, VGAScreenSeg->h * VGAScreenSeg->pitch);
  5018.  
  5019.  
  5020.         service_SDL_events(true);
  5021.         timer = 300; /* About 300 rounds is enough to make the screen mostly black */
  5022.  
  5023.         do
  5024.         {
  5025.                 setjasondelay(1);
  5026.  
  5027.                 /* This gets us our 'whoa' effect with pixel bleeding magic.
  5028.                  * I'm willing to bet the guy who originally wrote the asm was goofing
  5029.                  * around on acid and thought this looked good enough to use. */
  5030.                 for (i = screenSize - bottomBorder, j = topBorder / 2; i > 0; i--, j++)
  5031.                 {
  5032.                         offset = j + i/8192 - 4;
  5033.                         color = (TempScreen2[offset                    ] * 12 +
  5034.                                  TempScreen1[offset-VGAScreenSeg->pitch]      +
  5035.                                  TempScreen1[offset-1                  ]      +
  5036.                                  TempScreen1[offset+1                  ]      +
  5037.                                  TempScreen1[offset+VGAScreenSeg->pitch]) / 16;
  5038.  
  5039.                         TempScreen1[j] = color;
  5040.                 }
  5041.  
  5042.                 /* Now copy that mess to the buffer. */
  5043.                 memcpy((Uint8 *)VGAScreenSeg->pixels + topBorder, TempScreen1 + topBorder, screenSize - bottomBorder);
  5044.  
  5045.                 JE_showVGA();
  5046.  
  5047.                 timer--;
  5048.                 wait_delay();
  5049.  
  5050.                 /* Flip the buffer. */
  5051.                 TempScreenSwap = TempScreen1;
  5052.                 TempScreen1    = TempScreen2;
  5053.                 TempScreen2    = TempScreenSwap;
  5054.  
  5055.         } while (!(timer == 0 || JE_anyButton()));
  5056.  
  5057.         levelWarningLines = 4;
  5058. }
  5059.  
  5060. void JE_barX( JE_word x1, JE_word y1, JE_word x2, JE_word y2, JE_byte col )
  5061. {
  5062.         fill_rectangle_xy(VGAScreen, x1, y1,     x2, y1,     col + 1);
  5063.         fill_rectangle_xy(VGAScreen, x1, y1 + 1, x2, y2 - 1, col    );
  5064.         fill_rectangle_xy(VGAScreen, x1, y2,     x2, y2,     col - 1);
  5065. }
  5066.  
  5067. void draw_boss_bar( void )
  5068. {
  5069.         for (unsigned int b = 0; b < COUNTOF(boss_bar); b++)
  5070.         {
  5071.                 if (boss_bar[b].link_num == 0)
  5072.                         continue;
  5073.  
  5074.                 unsigned int armor = 256;  // higher than armor max
  5075.  
  5076.                 for (unsigned int e = 0; e < COUNTOF(enemy); e++)  // find most damaged
  5077.                 {
  5078.                         if (enemyAvail[e] != 1 && enemy[e].linknum == boss_bar[b].link_num)
  5079.                                 if (enemy[e].armorleft < armor)
  5080.                                         armor = enemy[e].armorleft;
  5081.                 }
  5082.  
  5083.                 if (armor > 255 || armor == 0)  // boss dead?
  5084.                         boss_bar[b].link_num = 0;
  5085.                 else
  5086.                         boss_bar[b].armor = (armor == 255) ? 254 : armor;  // 255 would make the bar too long
  5087.         }
  5088.  
  5089.         unsigned int bars = (boss_bar[0].link_num != 0 ? 1 : 0)
  5090.                           + (boss_bar[1].link_num != 0 ? 1 : 0);
  5091.  
  5092.         // if only one bar left, make it the first one
  5093.         if (bars == 1 && boss_bar[0].link_num == 0)
  5094.         {
  5095.                 memcpy(&boss_bar[0], &boss_bar[1], sizeof(boss_bar_t));
  5096.                 boss_bar[1].link_num = 0;
  5097.         }
  5098.  
  5099.         for (unsigned int b = 0; b < bars; b++)
  5100.         {
  5101.                 unsigned int x = (bars == 2)
  5102.                                ? ((b == 0) ? 125 : 185)
  5103.                                : ((levelTimer) ? 250 : 155);  // level timer and boss bar would overlap
  5104.  
  5105.                 JE_barX(x - 25, 7, x + 25, 12, 115);
  5106.                 JE_barX(x - (boss_bar[b].armor / 10), 7, x + (boss_bar[b].armor + 5) / 10, 12, 118 + boss_bar[b].color);
  5107.  
  5108.                 if (boss_bar[b].color > 0)
  5109.                         boss_bar[b].color--;
  5110.         }
  5111. }
  5112.  
  5113.