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 "mainint.h"
  20.  
  21. #include "backgrnd.h"
  22. #include "config.h"
  23. #include "editship.h"
  24. #include "episodes.h"
  25. #include "file.h"
  26. #include "fonthand.h"
  27. #include "helptext.h"
  28. #include "helptext.h"
  29. #include "joystick.h"
  30. #include "keyboard.h"
  31. #include "lds_play.h"
  32. #include "loudness.h"
  33. #include "menus.h"
  34. #include "mouse.h"
  35. #include "mtrand.h"
  36. #include "network.h"
  37. #include "nortsong.h"
  38. #include "nortvars.h"
  39. #include "opentyr.h"
  40. #include "palette.h"
  41. #include "params.h"
  42. #include "pcxmast.h"
  43. #include "picload.h"
  44. #include "player.h"
  45. #include "setup.h"
  46. #include "shots.h"
  47. #include "sndmast.h"
  48. #include "sprite.h"
  49. #include "varz.h"
  50. #include "vga256d.h"
  51. #include "video.h"
  52.  
  53. #include <assert.h>
  54. #include <ctype.h>
  55. #include <string.h>
  56.  
  57. bool button[4];
  58.  
  59. #define MAX_PAGE 8
  60. #define TOPICS 6
  61. const JE_byte topicStart[TOPICS] = { 0, 1, 2, 3, 7, 255 };
  62.  
  63. JE_shortint constantLastX;
  64. JE_word textErase;
  65. JE_word upgradeCost;
  66. JE_word downgradeCost;
  67. JE_boolean performSave;
  68. JE_boolean jumpSection;
  69. JE_boolean useLastBank; /* See if I want to use the last 16 colors for DisplayText */
  70.  
  71. bool pause_pressed = false, ingamemenu_pressed = false;
  72.  
  73. /* Draws a message at the bottom text window on the playing screen */
  74. void JE_drawTextWindow( const char *text )
  75. {
  76.         if (textErase > 0) // erase current text
  77.                 blit_sprite(VGAScreenSeg, 16, 189, OPTION_SHAPES, 36);  // in-game text area
  78.  
  79.         textErase = 100;
  80.         JE_outText(VGAScreenSeg, 20, 190, text, 0, 4);
  81. }
  82.  
  83. void JE_outCharGlow( JE_word x, JE_word y, const char *s )
  84. {
  85.         JE_integer maxloc, loc, z;
  86.         JE_shortint glowcol[60]; /* [1..60] */
  87.         JE_shortint glowcolc[60]; /* [1..60] */
  88.         JE_word textloc[60]; /* [1..60] */
  89.         JE_byte bank;
  90.  
  91.         setjasondelay2(1);
  92.  
  93.         bank = (warningRed) ? 7 : ((useLastBank) ? 15 : 14);
  94.  
  95.         if (s[0] == '\0')
  96.                 return;
  97.  
  98.         if (frameCountMax == 0)
  99.         {
  100.                 JE_textShade(VGAScreen, x, y, s, bank, 0, PART_SHADE);
  101.                 JE_showVGA();
  102.         }
  103.         else
  104.         {
  105.                 maxloc = strlen(s);
  106.                 for (z = 0; z < 60; z++)
  107.                 {
  108.                         glowcol[z] = -8;
  109.                         glowcolc[z] = 1;
  110.                 }
  111.  
  112.                 loc = x;
  113.                 for (z = 0; z < maxloc; z++)
  114.                 {
  115.                         textloc[z] = loc;
  116.  
  117.                         int sprite_id = font_ascii[(unsigned char)s[z]];
  118.  
  119.                         if (s[z] == ' ')
  120.                                 loc += 6;
  121.                         else if (sprite_id != -1)
  122.                                 loc += sprite(TINY_FONT, sprite_id)->width + 1;
  123.                 }
  124.  
  125.                 for (loc = 0; (unsigned)loc < strlen(s) + 28; loc++)
  126.                 {
  127.                         if (!ESCPressed)
  128.                         {
  129.                                 setjasondelay(frameCountMax);
  130.  
  131.                                 NETWORK_KEEP_ALIVE();
  132.  
  133.                                 int sprite_id = -1;
  134.  
  135.                                 for (z = loc - 28; z <= loc; z++)
  136.                                 {
  137.                                         if (z >= 0 && z < maxloc)
  138.                                         {
  139.                                                 sprite_id = font_ascii[(unsigned char)s[z]];
  140.  
  141.                                                 if (sprite_id != -1)
  142.                                                 {
  143.                                                         blit_sprite_hv(VGAScreen, textloc[z], y, TINY_FONT, sprite_id, bank, glowcol[z]);
  144.  
  145.                                                         glowcol[z] += glowcolc[z];
  146.                                                         if (glowcol[z] > 9)
  147.                                                                 glowcolc[z] = -1;
  148.                                                 }
  149.                                         }
  150.                                 }
  151.                                 if (sprite_id != -1 && --z < maxloc)
  152.                                         blit_sprite_dark(VGAScreen, textloc[z] + 1, y + 1, TINY_FONT, sprite_id, true);
  153.  
  154.                                 if (JE_anyButton())
  155.                                         frameCountMax = 0;
  156.  
  157.                                 do
  158.                                 {
  159.                                         if (levelWarningDisplay)
  160.                                                 JE_updateWarning(VGAScreen);
  161.  
  162.                                         uSDL_Delay(16);
  163.                                 }
  164.                                 while (!(delaycount() == 0 || ESCPressed));
  165.  
  166.                                 JE_showVGA();
  167.                         }
  168.                 }
  169.         }
  170. }
  171.  
  172. void JE_drawPortConfigButtons( void ) // rear weapon pattern indicator
  173. {
  174.         if (twoPlayerMode)
  175.                 return;
  176.  
  177.         if (player[0].weapon_mode == 1)
  178.         {
  179.                 blit_sprite(VGAScreenSeg, 285, 44, OPTION_SHAPES, 18);  // lit
  180.                 blit_sprite(VGAScreenSeg, 302, 44, OPTION_SHAPES, 19);  // unlit
  181.         }
  182.         else // == 2
  183.         {
  184.                 blit_sprite(VGAScreenSeg, 285, 44, OPTION_SHAPES, 19);  // unlit
  185.                 blit_sprite(VGAScreenSeg, 302, 44, OPTION_SHAPES, 18);  // lit
  186.         }
  187. }
  188.  
  189. void JE_helpSystem( JE_byte startTopic )
  190. {
  191.         JE_integer page, lastPage = 0;
  192.         JE_byte menu;
  193.  
  194.         page = topicStart[startTopic-1];
  195.  
  196.         fade_black(10);
  197.         JE_loadPic(VGAScreen, 2, false);
  198.  
  199.         play_song(SONG_MAPVIEW);
  200.  
  201.         JE_showVGA();
  202.         fade_palette(colors, 10, 0, 255);
  203.  
  204.         memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
  205.  
  206.         do
  207.         {
  208.                 memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
  209.  
  210.                 temp2 = 0;
  211.  
  212.                 for (temp = 0; temp < TOPICS; temp++)
  213.                 {
  214.                         if (topicStart[temp] <= page)
  215.                         {
  216.                                 temp2 = temp;
  217.                         }
  218.                 }
  219.  
  220.                 if (page > 0)
  221.                 {
  222.                         JE_char buf[128];
  223.  
  224.                         sprintf(buf, "%s %d", miscText[24], page-topicStart[temp2]+1);
  225.                         JE_outText(VGAScreen, 10, 192, buf, 13, 5);
  226.  
  227.                         sprintf(buf, "%s %d of %d", miscText[25], page, MAX_PAGE);
  228.                         JE_outText(VGAScreen, 220, 192, buf, 13, 5);
  229.  
  230.                         JE_dString(VGAScreen, JE_fontCenter(topicName[temp2], SMALL_FONT_SHAPES), 1, topicName[temp2], SMALL_FONT_SHAPES);
  231.                 }
  232.  
  233.                 menu = 0;
  234.  
  235.                 helpBoxBrightness = 3;
  236.                 verticalHeight = 8;
  237.  
  238.                 switch (page)
  239.                 {
  240.                         case 0:
  241.                                 menu = 2;
  242.                                 if (lastPage == MAX_PAGE)
  243.                                 {
  244.                                         menu = TOPICS;
  245.                                 }
  246.                                 JE_dString(VGAScreen, JE_fontCenter(topicName[0], FONT_SHAPES), 30, topicName[0], FONT_SHAPES);
  247.  
  248.                                 do
  249.                                 {
  250.                                         for (temp = 1; temp <= TOPICS; temp++)
  251.                                         {
  252.                                                 char buf[21+1];
  253.  
  254.                                                 if (temp == menu-1)
  255.                                                 {
  256.                                                         strcpy(buf+1, topicName[temp]);
  257.                                                         buf[0] = '~';
  258.                                                 } else {
  259.                                                         strcpy(buf, topicName[temp]);
  260.                                                 }
  261.  
  262.                                                 JE_dString(VGAScreen, JE_fontCenter(topicName[temp], SMALL_FONT_SHAPES), temp * 20 + 40, buf, SMALL_FONT_SHAPES);
  263.                                         }
  264.  
  265.                                         //JE_waitRetrace();  didn't do anything anyway?
  266.                                         JE_showVGA();
  267.  
  268.                                         tempW = 0;
  269.                                         JE_textMenuWait(&tempW, false);
  270.                                         if (newkey)
  271.                                         {
  272.                                                 switch (lastkey_sym)
  273.                                                 {
  274.                                                         case SDLK_UP:
  275.                                                                 menu--;
  276.                                                                 if (menu < 2)
  277.                                                                 {
  278.                                                                         menu = TOPICS;
  279.                                                                 }
  280.                                                                 JE_playSampleNum(S_CURSOR);
  281.                                                                 break;
  282.                                                         case SDLK_DOWN:
  283.                                                                 menu++;
  284.                                                                 if (menu > TOPICS)
  285.                                                                 {
  286.                                                                         menu = 2;
  287.                                                                 }
  288.                                                                 JE_playSampleNum(S_CURSOR);
  289.                                                                 break;
  290.                                                         default:
  291.                                                                 break;
  292.                                                 }
  293.                                         }
  294.                                 } while (!(lastkey_sym == SDLK_ESCAPE || lastkey_sym == SDLK_RETURN));
  295.  
  296.                                 if (lastkey_sym == SDLK_RETURN)
  297.                                 {
  298.                                         page = topicStart[menu-1];
  299.                                         JE_playSampleNum(S_CLICK);
  300.                                 }
  301.  
  302.                                 break;
  303.                         case 1: /* One-Player Menu */
  304.                                 JE_HBox(VGAScreen, 10,  20,  2, 60);
  305.                                 JE_HBox(VGAScreen, 10,  50,  5, 60);
  306.                                 JE_HBox(VGAScreen, 10,  80, 21, 60);
  307.                                 JE_HBox(VGAScreen, 10, 110,  1, 60);
  308.                                 JE_HBox(VGAScreen, 10, 140, 28, 60);
  309.                                 break;
  310.                         case 2: /* Two-Player Menu */
  311.                                 JE_HBox(VGAScreen, 10,  20,  1, 60);
  312.                                 JE_HBox(VGAScreen, 10,  60,  2, 60);
  313.                                 JE_HBox(VGAScreen, 10, 100, 21, 60);
  314.                                 JE_HBox(VGAScreen, 10, 140, 28, 60);
  315.                                 break;
  316.                         case 3: /* Upgrade Ship */
  317.                                 JE_HBox(VGAScreen, 10,  20,  5, 60);
  318.                                 JE_HBox(VGAScreen, 10,  70,  6, 60);
  319.                                 JE_HBox(VGAScreen, 10, 110,  7, 60);
  320.                                 break;
  321.                         case 4:
  322.                                 JE_HBox(VGAScreen, 10,  20,  8, 60);
  323.                                 JE_HBox(VGAScreen, 10,  55,  9, 60);
  324.                                 JE_HBox(VGAScreen, 10,  87, 10, 60);
  325.                                 JE_HBox(VGAScreen, 10, 120, 11, 60);
  326.                                 JE_HBox(VGAScreen, 10, 170, 13, 60);
  327.                                 break;
  328.                         case 5:
  329.                                 JE_HBox(VGAScreen, 10,  20, 14, 60);
  330.                                 JE_HBox(VGAScreen, 10,  80, 15, 60);
  331.                                 JE_HBox(VGAScreen, 10, 120, 16, 60);
  332.                                 break;
  333.                         case 6:
  334.                                 JE_HBox(VGAScreen, 10,  20, 17, 60);
  335.                                 JE_HBox(VGAScreen, 10,  40, 18, 60);
  336.                                 JE_HBox(VGAScreen, 10, 130, 20, 60);
  337.                                 break;
  338.                         case 7: /* Options */
  339.                                 JE_HBox(VGAScreen, 10,  20, 21, 60);
  340.                                 JE_HBox(VGAScreen, 10,  70, 22, 60);
  341.                                 JE_HBox(VGAScreen, 10, 110, 23, 60);
  342.                                 JE_HBox(VGAScreen, 10, 140, 24, 60);
  343.                                 break;
  344.                         case 8:
  345.                                 JE_HBox(VGAScreen, 10,  20, 25, 60);
  346.                                 JE_HBox(VGAScreen, 10,  60, 26, 60);
  347.                                 JE_HBox(VGAScreen, 10, 100, 27, 60);
  348.                                 JE_HBox(VGAScreen, 10, 140, 28, 60);
  349.                                 JE_HBox(VGAScreen, 10, 170, 29, 60);
  350.                                 break;
  351.                 }
  352.  
  353.                 helpBoxBrightness = 1;
  354.                 verticalHeight = 7;
  355.  
  356.                 lastPage = page;
  357.  
  358.                 if (menu == 0)
  359.                 {
  360.                         do {
  361.                                 setjasondelay(3);
  362.  
  363.                                 push_joysticks_as_keyboard();
  364.                                 service_SDL_events(true);
  365.  
  366.                                 JE_showVGA();
  367.  
  368.                                 wait_delay();
  369.                         } while (!newkey && !newmouse);
  370.  
  371.                         wait_noinput(false, true, false);
  372.  
  373.                         if (newmouse)
  374.                         {
  375.                                 switch (lastmouse_but)
  376.                                 {
  377.                                         case SDL_BUTTON_LEFT:
  378.                                                 lastkey_sym = SDLK_RIGHT;
  379.                                                 break;
  380.                                         case SDL_BUTTON_RIGHT:
  381.                                                 lastkey_sym = SDLK_LEFT;
  382.                                                 break;
  383.                                         case SDL_BUTTON_MIDDLE:
  384.                                                 lastkey_sym = SDLK_ESCAPE;
  385.                                                 break;
  386.                                 }
  387.                                 do
  388.                                 {
  389.                                         service_SDL_events(false);
  390.                                 } while (mousedown);
  391.                                 newkey = true;
  392.                         }
  393.  
  394.                         if (newkey)
  395.                         {
  396.                                 switch (lastkey_sym)
  397.                                 {
  398.                                         case SDLK_LEFT:
  399.                                         case SDLK_UP:
  400.                                         case SDLK_PAGEUP:
  401.                                                 page--;
  402.                                                 JE_playSampleNum(S_CURSOR);
  403.                                                 break;
  404.                                         case SDLK_RIGHT:
  405.                                         case SDLK_DOWN:
  406.                                         case SDLK_PAGEDOWN:
  407.                                         case SDLK_RETURN:
  408.                                         case SDLK_SPACE:
  409.                                                 if (page == MAX_PAGE)
  410.                                                 {
  411.                                                         page = 0;
  412.                                                 } else {
  413.                                                         page++;
  414.                                                 }
  415.                                                 JE_playSampleNum(S_CURSOR);
  416.                                                 break;
  417.                                         case SDLK_F1:
  418.                                                 page = 0;
  419.                                                 JE_playSampleNum(S_CURSOR);
  420.                                                 break;
  421.                                         default:
  422.                                                 break;
  423.                                 }
  424.                         }
  425.                 }
  426.  
  427.                 if (page == 255)
  428.                 {
  429.                         lastkey_sym = SDLK_ESCAPE;
  430.                 }
  431.         } while (lastkey_sym != SDLK_ESCAPE);
  432. }
  433.  
  434. // cost to upgrade a weapon power from power-1 (where power == 0 indicates an unupgraded weapon)
  435. long weapon_upgrade_cost( long base_cost, unsigned int power )
  436. {
  437.         assert(power <= 11);
  438.  
  439.         unsigned int temp = 0;
  440.  
  441.         // 0 1 3 6 10 15 21 29 ...
  442.         for (; power > 0; power--)
  443.                 temp += power;
  444.  
  445.         return base_cost * temp;
  446. }
  447.  
  448. ulong JE_getCost( JE_byte itemType, JE_word itemNum )
  449. {
  450.         long cost = 0;
  451.  
  452.         switch (itemType)
  453.         {
  454.         case 2:
  455.                 cost = (itemNum > 90) ? 100 : ships[itemNum].cost;
  456.                 break;
  457.         case 3:
  458.         case 4:
  459.                 cost = weaponPort[itemNum].cost;
  460.  
  461.                 const uint port = itemType - 3,
  462.                            item_power = player[0].items.weapon[port].power - 1;
  463.  
  464.                 downgradeCost = weapon_upgrade_cost(cost, item_power);
  465.                 upgradeCost = weapon_upgrade_cost(cost, item_power + 1);
  466.                 break;
  467.         case 5:
  468.                 cost = shields[itemNum].cost;
  469.                 break;
  470.         case 6:
  471.                 cost = powerSys[itemNum].cost;
  472.                 break;
  473.         case 7:
  474.         case 8:
  475.                 cost = options[itemNum].cost;
  476.                 break;
  477.         }
  478.  
  479.         return cost;
  480. }
  481.  
  482. void JE_loadScreen( void )
  483. {
  484.         JE_boolean quit;
  485.         JE_byte sel, screen, min = 0, max = 0;
  486.         char *tempstr;
  487.         char *tempstr2;
  488.         JE_boolean mal_str = false;
  489.         int len;
  490.  
  491.         tempstr = NULL;
  492.  
  493.         free_sprite2s(&shapes6);
  494.         JE_loadCompShapes(&shapes6, '1');  // need arrow sprites
  495.  
  496.         fade_black(10);
  497.         JE_loadPic(VGAScreen, 2, false);
  498.         JE_showVGA();
  499.         fade_palette(colors, 10, 0, 255);
  500.  
  501.         screen = 1;
  502.         sel = 1;
  503.         quit = false;
  504.  
  505.         memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
  506.  
  507.         do
  508.         {
  509.                 while (mousedown)
  510.                 {
  511.                         service_SDL_events(false);
  512.                         tempX = mouse_x;
  513.                         tempY = mouse_y;
  514.                 }
  515.  
  516.                 memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
  517.  
  518.                 JE_dString(VGAScreen, JE_fontCenter(miscText[38 + screen - 1], FONT_SHAPES), 5, miscText[38 + screen - 1], FONT_SHAPES);
  519.  
  520.                 switch (screen)
  521.                 {
  522.                 case 1:
  523.                         min = 1;
  524.                         max = 12;
  525.                         break;
  526.                 case 2:
  527.                         min = 12;
  528.                         max = 23;
  529.                 }
  530.  
  531.                 /* SYN: Go through text line by line */
  532.                 for (x = min; x <= max; x++)
  533.                 {
  534.                         tempY = 30 + (x - min) * 13;
  535.  
  536.                         if (x == max)
  537.                         {
  538.                                 /* Last line is return to main menu, not a save game */
  539.                                 if (mal_str)
  540.                                 {
  541.                                         free(tempstr);
  542.                                         mal_str = false;
  543.                                 }
  544.                                 tempstr = miscText[34 - 1];
  545.  
  546.                                 if (x == sel) /* Highlight if selected */
  547.                                 {
  548.                                         temp2 = 254;
  549.                                 } else {
  550.                                         temp2 = 250;
  551.                                 }
  552.                         } else {
  553.                                 if (x == sel) /* Highlight if selected */
  554.                                 {
  555.                                         temp2 = 254;
  556.                                 } else {
  557.                                         temp2 = 250 - ((saveFiles[x - 1].level == 0) << 1);
  558.                                 }
  559.  
  560.                                 if (saveFiles[x - 1].level == 0) /* I think this means the save file is unused */
  561.                                 {
  562.                                         if (mal_str)
  563.                                         {
  564.                                                 free(tempstr);
  565.                                                 mal_str = false;
  566.                                         }
  567.                                         tempstr = miscText[3 - 1];
  568.                                 } else {
  569.                                         if (mal_str)
  570.                                         {
  571.                                                 free(tempstr);
  572.                                                 mal_str = false;
  573.                                         }
  574.                                         tempstr = saveFiles[x - 1].name;
  575.                                 }
  576.                         }
  577.  
  578.                         /* Write first column text */
  579.                         JE_textShade(VGAScreen, 10, tempY, tempstr, 13, (temp2 % 16) - 8, FULL_SHADE);
  580.  
  581.                         if (x < max) /* Write additional columns for all but the last row */
  582.                         {
  583.                                 if (saveFiles[x - 1].level == 0)
  584.                                 {
  585.                                         if (mal_str)
  586.                                         {
  587.                                                 free(tempstr);
  588.                                         }
  589.                                         tempstr = malloc(7);
  590.                                         mal_str = true;
  591.                                         strcpy(tempstr, "-----"); /* Unused save slot */
  592.                                 } else {
  593.                                         tempstr = saveFiles[x - 1].levelName;
  594.                                         tempstr2 = malloc(5 + strlen(miscTextB[2-1]));
  595.                                         sprintf(tempstr2, "%s %d", miscTextB[2-1], saveFiles[x - 1].episode);
  596.                                         JE_textShade(VGAScreen, 250, tempY, tempstr2, 5, (temp2 % 16) - 8, FULL_SHADE);
  597.                                         free(tempstr2);
  598.                                 }
  599.  
  600.                                 len = strlen(miscTextB[3-1]) + 2 + strlen(tempstr);
  601.                                 tempstr2 = malloc(len);
  602.                                 sprintf(tempstr2, "%s %s", miscTextB[3 - 1], tempstr);
  603.                                 JE_textShade(VGAScreen, 120, tempY, tempstr2, 5, (temp2 % 16) - 8, FULL_SHADE);
  604.                                 free(tempstr2);
  605.                         }
  606.  
  607.                 }
  608.  
  609.                 if (screen == 2)
  610.                 {
  611.                         blit_sprite2x2(VGAScreen, 90, 180, shapes6, 279);
  612.                 }
  613.                 if (screen == 1)
  614.                 {
  615.                         blit_sprite2x2(VGAScreen, 220, 180, shapes6, 281);
  616.                 }
  617.  
  618.                 helpBoxColor = 15;
  619.                 JE_helpBox(VGAScreen, 110, 182, miscText[56-1], 25);
  620.  
  621.                 JE_showVGA();
  622.  
  623.                 tempW = 0;
  624.                 JE_textMenuWait(&tempW, false);
  625.  
  626.  
  627.                 if (newkey)
  628.                 {
  629.                         switch (lastkey_sym)
  630.                         {
  631.                         case SDLK_UP:
  632.                                 sel--;
  633.                                 if (sel < min)
  634.                                 {
  635.                                         sel = max;
  636.                                 }
  637.                                 JE_playSampleNum(S_CURSOR);
  638.                                 break;
  639.                         case SDLK_DOWN:
  640.                                 sel++;
  641.                                 if (sel > max)
  642.                                 {
  643.                                         sel = min;
  644.                                 }
  645.                                 JE_playSampleNum(S_CURSOR);
  646.                                 break;
  647.                         case SDLK_LEFT:
  648.                         case SDLK_RIGHT:
  649.                                 if (screen == 1)
  650.                                 {
  651.                                         screen = 2;
  652.                                         sel += 11;
  653.                                 } else {
  654.                                         screen = 1;
  655.                                         sel -= 11;
  656.                                 }
  657.                                 break;
  658.                         case SDLK_RETURN:
  659.                                 if (sel < max)
  660.                                 {
  661.                                         if (saveFiles[sel - 1].level > 0)
  662.                                         {
  663.                                                 JE_playSampleNum(S_SELECT);
  664.                                                 performSave = false;
  665.                                                 JE_operation(sel);
  666.                                                 quit = true;
  667.                                         } else {
  668.                                                 JE_playSampleNum(S_CLINK);
  669.                                         }
  670.                                 } else {
  671.                                         quit = true;
  672.                                 }
  673.  
  674.  
  675.                                 break;
  676.                         case SDLK_ESCAPE:
  677.                                 quit = true;
  678.                                 break;
  679.                         default:
  680.                                 break;
  681.                         }
  682.  
  683.                 }
  684.         } while (!quit);
  685. }
  686.  
  687. ulong JE_totalScore( const Player *this_player )
  688. {
  689.         ulong temp = this_player->cash;
  690.  
  691.         temp += JE_getValue(2, this_player->items.ship);
  692.         temp += JE_getValue(3, this_player->items.weapon[FRONT_WEAPON].id);
  693.         temp += JE_getValue(4, this_player->items.weapon[REAR_WEAPON].id);
  694.         temp += JE_getValue(5, this_player->items.shield);
  695.         temp += JE_getValue(6, this_player->items.generator);
  696.         temp += JE_getValue(7, this_player->items.sidekick[LEFT_SIDEKICK]);
  697.         temp += JE_getValue(8, this_player->items.sidekick[RIGHT_SIDEKICK]);
  698.  
  699.         return temp;
  700. }
  701.  
  702. JE_longint JE_getValue( JE_byte itemType, JE_word itemNum )
  703. {
  704.         long value = 0;
  705.  
  706.         switch (itemType)
  707.         {
  708.         case 2:
  709.                 value = ships[itemNum].cost;
  710.                 break;
  711.         case 3:
  712.         case 4:;
  713.                 const long base_value = weaponPort[itemNum].cost;
  714.  
  715.                 // if two-player, use first player's front and second player's rear weapon
  716.                 const uint port = itemType - 3;
  717.                 const uint item_power = player[twoPlayerMode ? port : 0].items.weapon[port].power - 1;
  718.  
  719.                 value = base_value;
  720.                 for (unsigned int i = 1; i <= item_power; ++i)
  721.                         value += weapon_upgrade_cost(base_value, i);
  722.                 break;
  723.         case 5:
  724.                 value = shields[itemNum].cost;
  725.                 break;
  726.         case 6:
  727.                 value = powerSys[itemNum].cost;
  728.                 break;
  729.         case 7:
  730.         case 8:
  731.                 value = options[itemNum].cost;
  732.                 break;
  733.         }
  734.  
  735.         return value;
  736. }
  737.  
  738. void JE_nextEpisode( void )
  739. {
  740.         strcpy(lastLevelName, "Completed");
  741.  
  742.         if (episodeNum == initial_episode_num && !gameHasRepeated && episodeNum != EPISODE_AVAILABLE &&
  743.             !isNetworkGame && !constantPlay)
  744.         {
  745.                 JE_highScoreCheck();
  746.         }
  747.  
  748.         unsigned int newEpisode = JE_findNextEpisode();
  749.  
  750.         if (jumpBackToEpisode1)
  751.         {
  752.                 // shareware version check
  753.                 if (episodeNum == 1 &&
  754.                         !isNetworkGame && !constantPlay)
  755.                 {
  756.                         // JE_loadOrderingInfo();
  757.                 }
  758.  
  759.                 if (episodeNum > 2 &&
  760.                         !constantPlay)
  761.                 {
  762.                         JE_playCredits();
  763.                 }
  764.  
  765.                 // randomly give player the SuperCarrot
  766.                 if ((mt_rand() % 6) == 0)
  767.                 {
  768.                         player[0].items.ship = 2;                      // SuperCarrot
  769.                         player[0].items.weapon[FRONT_WEAPON].id = 23;  // Banana Blast
  770.                         player[0].items.weapon[REAR_WEAPON].id = 24;   // Banana Blast Rear
  771.  
  772.                         for (uint i = 0; i < COUNTOF(player[0].items.weapon); ++i)
  773.                                 player[0].items.weapon[i].power = 1;
  774.  
  775.                         player[1].items.weapon[REAR_WEAPON].id = 24;   // Banana Blast Rear
  776.  
  777.                         player[0].last_items = player[0].items;
  778.                 }
  779.         }
  780.  
  781.         if (newEpisode != episodeNum)
  782.                 JE_initEpisode(newEpisode);
  783.  
  784.         gameLoaded = true;
  785.         mainLevel = FIRST_LEVEL;
  786.         saveLevel = FIRST_LEVEL;
  787.  
  788.         play_song(26);
  789.  
  790.         JE_clr256(VGAScreen);
  791.         memcpy(colors, palettes[6-1], sizeof(colors));
  792.  
  793.         JE_dString(VGAScreen, JE_fontCenter(episode_name[episodeNum], SMALL_FONT_SHAPES), 130, episode_name[episodeNum], SMALL_FONT_SHAPES);
  794.         JE_dString(VGAScreen, JE_fontCenter(miscText[5-1], SMALL_FONT_SHAPES), 185, miscText[5-1], SMALL_FONT_SHAPES);
  795.  
  796.         JE_showVGA();
  797.         fade_palette(colors, 15, 0, 255);
  798.  
  799.         JE_wipeKey();
  800.         if (!constantPlay)
  801.         {
  802.                 do
  803.                 {
  804.                         NETWORK_KEEP_ALIVE();
  805.  
  806.                         uSDL_Delay(16);
  807.                 } while (!JE_anyButton());
  808.         }
  809.  
  810.         fade_black(15);
  811. }
  812.  
  813. void JE_initPlayerData( void )
  814. {
  815.         /* JE: New Game Items/Data */
  816.  
  817.         player[0].items.ship = 1;                     // USP Talon
  818.         player[0].items.weapon[FRONT_WEAPON].id = 1;  // Pulse Cannon
  819.         player[0].items.weapon[REAR_WEAPON].id = 0;   // None
  820.         player[0].items.shield = 4;                   // Gencore High Energy Shield
  821.         player[0].items.generator = 2;                // Advanced MR-12
  822.         for (uint i = 0; i < COUNTOF(player[0].items.sidekick); ++i)
  823.                 player[0].items.sidekick[i] = 0;          // None
  824.         player[0].items.special = 0;                  // None
  825.  
  826.         player[0].last_items = player[0].items;
  827.  
  828.         player[1].items = player[0].items;
  829.         player[1].items.weapon[REAR_WEAPON].id = 15;  // Vulcan Cannon
  830.         player[1].items.sidekick_level = 101;         // 101, 102, 103
  831.         player[1].items.sidekick_series = 0;          // None
  832.  
  833.         gameHasRepeated = false;
  834.         onePlayerAction = false;
  835.         superArcadeMode = SA_NONE;
  836.         superTyrian = false;
  837.         twoPlayerMode = false;
  838.  
  839.         secretHint = (mt_rand() % 3) + 1;
  840.  
  841.         for (uint p = 0; p < COUNTOF(player); ++p)
  842.         {
  843.                 for (uint i = 0; i < COUNTOF(player->items.weapon); ++i)
  844.                 {
  845.                         player[p].items.weapon[i].power = 1;
  846.                 }
  847.  
  848.                 player[p].weapon_mode = 1;
  849.                 player[p].armor = ships[player[p].items.ship].dmg;
  850.  
  851.                 player[p].is_dragonwing = (p == 1);
  852.                 player[p].lives = &player[p].items.weapon[p].power;
  853.  
  854.         }
  855.  
  856.         mainLevel = FIRST_LEVEL;
  857.         saveLevel = FIRST_LEVEL;
  858.  
  859.         strcpy(lastLevelName, miscText[19]);
  860. }
  861.  
  862. void JE_sortHighScores( void )
  863. {
  864.         JE_byte x;
  865.  
  866.         temp = 0;
  867.         for (x = 0; x < 6; x++)
  868.         {
  869.                 JE_sort();
  870.                 temp += 3;
  871.         }
  872. }
  873.  
  874. void JE_highScoreScreen( void )
  875. {
  876.         int min = 1;
  877.         int max = 3;
  878.  
  879.         int x, z;
  880.         short int chg;
  881.         int quit;
  882.         char scoretemp[32];
  883.  
  884.         free_sprite2s(&shapes6);
  885.         JE_loadCompShapes(&shapes6, '1');  // need arrow sprites
  886.  
  887.         fade_black(10);
  888.         JE_loadPic(VGAScreen, 2, false);
  889.         JE_showVGA();
  890.         fade_palette(colors, 10, 0, 255);
  891.  
  892.         quit = false;
  893.         x = 1;
  894.         chg = 1;
  895.  
  896.         memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
  897.  
  898.         do
  899.         {
  900.                 if (episodeAvail[x-1])
  901.                 {
  902.                         memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
  903.  
  904.                         JE_dString(VGAScreen, JE_fontCenter(miscText[51 - 1], FONT_SHAPES), 03, miscText[51 - 1], FONT_SHAPES);
  905.                         JE_dString(VGAScreen, JE_fontCenter(episode_name[x], SMALL_FONT_SHAPES), 30, episode_name[x], SMALL_FONT_SHAPES);
  906.  
  907.                         /* Player 1 */
  908.                         temp = (x * 6) - 6;
  909.  
  910.                         JE_dString(VGAScreen, JE_fontCenter(miscText[47 - 1], SMALL_FONT_SHAPES), 55, miscText[47 - 1], SMALL_FONT_SHAPES);
  911.  
  912.                         for (z = 0; z < 3; z++)
  913.                         {
  914.                                 int difficulty = saveFiles[temp + z].highScoreDiff;
  915.                                 if (difficulty > 9)
  916.                                 {
  917.                                         saveFiles[temp + z].highScoreDiff = 0;
  918.                                         difficulty = 0;
  919.                                 }
  920.                                 sprintf(scoretemp, "~#%d:~ %d", z + 1, saveFiles[temp+z].highScore1);
  921.                                 JE_textShade(VGAScreen, 250, ((z+1) * 10) + 65 , difficultyNameB[difficulty], 15, difficulty + (difficulty == 0 ? 0 : -1), FULL_SHADE);
  922.                                 JE_textShade(VGAScreen, 20, ((z+1) * 10) + 65 , scoretemp, 15, 0, FULL_SHADE);
  923.                                 JE_textShade(VGAScreen, 110, ((z+1) * 10) + 65 , saveFiles[temp + z].highScoreName, 15, 2, FULL_SHADE);
  924.                         }
  925.  
  926.                         /* Player 2 */
  927.                         temp += 3;
  928.  
  929.                         JE_dString(VGAScreen, JE_fontCenter( miscText[48 - 1], SMALL_FONT_SHAPES), 120, miscText[48 - 1], SMALL_FONT_SHAPES);
  930.  
  931.                         /*{        textshade(20,125,misctext[49],15,3,_FullShade);
  932.                           textshade(80,125,misctext[50],15,3,_FullShade);}*/
  933.  
  934.                         for (z = 0; z < 3; z++)
  935.                         {
  936.                                 int difficulty = saveFiles[temp + z].highScoreDiff;
  937.                                 if (difficulty > 9)
  938.                                 {
  939.                                         saveFiles[temp + z].highScoreDiff = 0;
  940.                                         difficulty = 0;
  941.                                 }
  942.                                 sprintf(scoretemp, "~#%d:~ %d", z + 1, saveFiles[temp+z].highScore1); /* Not .highScore2 for some reason */
  943.                                 JE_textShade(VGAScreen, 250, ((z+1) * 10) + 125 , difficultyNameB[difficulty], 15, difficulty + (difficulty == 0 ? 0 : -1), FULL_SHADE);
  944.                                 JE_textShade(VGAScreen, 20, ((z+1) * 10) + 125 , scoretemp, 15, 0, FULL_SHADE);
  945.                                 JE_textShade(VGAScreen, 110, ((z+1) * 10) + 125 , saveFiles[temp + z].highScoreName, 15, 2, FULL_SHADE);
  946.                         }
  947.  
  948.                         if (x > 1)
  949.                         {
  950.                                 blit_sprite2x2(VGAScreen,  90, 180, shapes6, 279);
  951.                         }
  952.  
  953.                         if ( ( (x < 2) && episodeAvail[2-1] ) || ( (x < 3) && episodeAvail[3-1] ) )
  954.                         {
  955.                                 blit_sprite2x2(VGAScreen,  220, 180, shapes6, 281);
  956.                         }
  957.  
  958.                         helpBoxColor = 15;
  959.                         JE_helpBox(VGAScreen, 110, 182, miscText[57 - 1], 25);
  960.  
  961.                         /* {Dstring(fontcenter(misctext[57],_SmallFontShapes),190,misctext[57],_SmallFontShapes);} */
  962.  
  963.                         JE_showVGA();
  964.  
  965.                         tempW = 0;
  966.                         JE_textMenuWait(&tempW, false);
  967.  
  968.                         if (newkey)
  969.                         {
  970.                                 switch (lastkey_sym)
  971.                                 {
  972.                                 case SDLK_LEFT:
  973.                                         x--;
  974.                                         chg = -1;
  975.                                         break;
  976.                                 case SDLK_RIGHT:
  977.                                         x++;
  978.                                         chg = 1;
  979.                                         break;
  980.                                 default:
  981.                                         break;
  982.                                 }
  983.                         }
  984.  
  985.                 } else {
  986.                         x += chg;
  987.                 }
  988.  
  989.                 x = ( x < min ) ? max : ( x > max ) ? min : x;
  990.  
  991.                 if (newkey)
  992.                 {
  993.                         switch (lastkey_sym)
  994.                         {
  995.                         case SDLK_RETURN:
  996.                         case SDLK_ESCAPE:
  997.                                 quit = true;
  998.                                 break;
  999.                         default:
  1000.                                 break;
  1001.                         }
  1002.                 }
  1003.  
  1004.         } while (!quit);
  1005.  
  1006. }
  1007.  
  1008. void JE_gammaCorrect_func( JE_byte *col, JE_real r )
  1009. {
  1010.         int temp = roundf(*col * r);
  1011.         if (temp > 255)
  1012.         {
  1013.                 temp = 255;
  1014.         }
  1015.         *col = temp;
  1016. }
  1017.  
  1018. void JE_gammaCorrect( Palette *colorBuffer, JE_byte gamma )
  1019. {
  1020.         int x;
  1021.         JE_real r = 1 + (JE_real)gamma / 10;
  1022.  
  1023.         for (x = 0; x < 256; x++)
  1024.         {
  1025.                 JE_gammaCorrect_func(&(*colorBuffer)[x].r, r);
  1026.                 JE_gammaCorrect_func(&(*colorBuffer)[x].g, r);
  1027.                 JE_gammaCorrect_func(&(*colorBuffer)[x].b, r);
  1028.         }
  1029. }
  1030.  
  1031. JE_boolean JE_gammaCheck( void )
  1032. {
  1033.         bool temp = keysactive[SDLK_F11] != 0;
  1034.         if (temp)
  1035.         {
  1036.                 keysactive[SDLK_F11] = false;
  1037.                 newkey = false;
  1038.                 gammaCorrection = (gammaCorrection + 1) % 4;
  1039.                 memcpy(colors, palettes[pcxpal[3-1]], sizeof(colors));
  1040.                 JE_gammaCorrect(&colors, gammaCorrection);
  1041.                 set_palette(colors, 0, 255);
  1042.         }
  1043.         return temp;
  1044. }
  1045.  
  1046. void JE_doInGameSetup( void )
  1047. {
  1048.         haltGame = false;
  1049.  
  1050. #ifdef WITH_NETWORK
  1051.         if (isNetworkGame)
  1052.         {
  1053.                 network_prepare(PACKET_GAME_MENU);
  1054.                 network_send(4);  // PACKET_GAME_MENU
  1055.  
  1056.                 while (true)
  1057.                 {
  1058.                         service_SDL_events(false);
  1059.  
  1060.                         if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_GAME_MENU)
  1061.                         {
  1062.                                 network_update();
  1063.                                 break;
  1064.                         }
  1065.  
  1066.                         network_update();
  1067.                         network_check();
  1068.  
  1069.                         uSDL_Delay(16);
  1070.                 }
  1071.         }
  1072. #endif
  1073.  
  1074.         if (yourInGameMenuRequest)
  1075.         {
  1076.                 if (JE_inGameSetup())
  1077.                 {
  1078.                         reallyEndLevel = true;
  1079.                         playerEndLevel = true;
  1080.                 }
  1081.                 quitRequested = false;
  1082.  
  1083.                 keysactive[SDLK_ESCAPE] = false;
  1084.  
  1085. #ifdef WITH_NETWORK
  1086.                 if (isNetworkGame)
  1087.                 {
  1088.                         if (!playerEndLevel)
  1089.                         {
  1090.                                 network_prepare(PACKET_WAITING);
  1091.                                 network_send(4);  // PACKET_WAITING
  1092.                         } else {
  1093.                                 network_prepare(PACKET_GAME_QUIT);
  1094.                                 network_send(4);  // PACKET_GAMEQUIT
  1095.                         }
  1096.                 }
  1097. #endif
  1098.         }
  1099.  
  1100. #ifdef WITH_NETWORK
  1101.         if (isNetworkGame)
  1102.         {
  1103.                 SDL_Surface *temp_surface = VGAScreen;
  1104.                 VGAScreen = VGAScreenSeg; /* side-effect of game_screen */
  1105.  
  1106.                 if (!yourInGameMenuRequest)
  1107.                 {
  1108.                         JE_barShade(VGAScreen, 3, 60, 257, 80); /*Help Box*/
  1109.                         JE_barShade(VGAScreen, 5, 62, 255, 78);
  1110.                         JE_dString(VGAScreen, 10, 65, "Other player in options menu.", SMALL_FONT_SHAPES);
  1111.                         JE_showVGA();
  1112.  
  1113.                         while (true)
  1114.                         {
  1115.                                 service_SDL_events(false);
  1116.                                 JE_showVGA();
  1117.  
  1118.                                 if (packet_in[0])
  1119.                                 {
  1120.                                         if (SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_WAITING)
  1121.                                         {
  1122.                                                 network_check();
  1123.                                                 break;
  1124.                                         } else if (SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_GAME_QUIT) {
  1125.                                                 reallyEndLevel = true;
  1126.                                                 playerEndLevel = true;
  1127.  
  1128.                                                 network_check();
  1129.                                                 break;
  1130.                                         }
  1131.                                 }
  1132.  
  1133.                                 network_update();
  1134.                                 network_check();
  1135.  
  1136.                                 uSDL_Delay(16);
  1137.                         }
  1138.                 } else {
  1139.                         /*
  1140.                         JE_barShade(3, 160, 257, 180); /-*Help Box*-/
  1141.                         JE_barShade(5, 162, 255, 178);
  1142.                         tempScreenSeg = VGAScreen;
  1143.                         JE_dString(VGAScreen, 10, 165, "Waiting for other player.", SMALL_FONT_SHAPES);
  1144.                         JE_showVGA();
  1145.                         */
  1146.                 }
  1147.  
  1148.                 while (!network_is_sync())
  1149.                 {
  1150.                         service_SDL_events(false);
  1151.  
  1152.                         network_check();
  1153.                         uSDL_Delay(16);
  1154.                 }
  1155.  
  1156.                 VGAScreen = temp_surface; /* side-effect of game_screen */
  1157.         }
  1158. #endif
  1159.  
  1160.         yourInGameMenuRequest = false;
  1161.  
  1162.         //skipStarShowVGA = true;
  1163. }
  1164.  
  1165. JE_boolean JE_inGameSetup( void )
  1166. {
  1167.         SDL_Surface *temp_surface = VGAScreen;
  1168.         VGAScreen = VGAScreenSeg; /* side-effect of game_screen */
  1169.  
  1170.         JE_boolean returnvalue = false;
  1171.  
  1172.         const JE_byte help[6] /* [1..6] */ = {15, 15, 28, 29, 26, 27};
  1173.         JE_byte  sel;
  1174.         JE_boolean quit;
  1175.  
  1176.         bool first = true;
  1177.  
  1178.         //tempScreenSeg = VGAScreenSeg; /* <MXD> ? should work as VGAScreen */
  1179.  
  1180.         quit = false;
  1181.         sel = 1;
  1182.  
  1183.         JE_barShade(VGAScreen, 3, 13, 217, 137); /*Main Box*/
  1184.         JE_barShade(VGAScreen, 5, 15, 215, 135);
  1185.  
  1186.         JE_barShade(VGAScreen, 3, 143, 257, 157); /*Help Box*/
  1187.         JE_barShade(VGAScreen, 5, 145, 255, 155);
  1188.         memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
  1189.  
  1190.         do
  1191.         {
  1192.                 memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
  1193.  
  1194.                 for (x = 0; x < 6; x++)
  1195.                 {
  1196.                         JE_outTextAdjust(VGAScreen, 10, (x + 1) * 20, inGameText[x], 15, ((sel == x+1) << 1) - 4, SMALL_FONT_SHAPES, true);
  1197.                 }
  1198.  
  1199.                 JE_outTextAdjust(VGAScreen, 120, 3 * 20, detailLevel[processorType-1], 15, ((sel == 3) << 1) - 4, SMALL_FONT_SHAPES, true);
  1200.                 JE_outTextAdjust(VGAScreen, 120, 4 * 20, gameSpeedText[gameSpeed-1],   15, ((sel == 4) << 1) - 4, SMALL_FONT_SHAPES, true);
  1201.  
  1202.                 JE_outTextAdjust(VGAScreen, 10, 147, mainMenuHelp[help[sel-1]-1], 14, 6, TINY_FONT, true);
  1203.  
  1204.                 JE_barDrawShadow(VGAScreen, 120, 20, 1, music_disabled ? 12 : 16, tyrMusicVolume / 12, 3, 13);
  1205.                 JE_barDrawShadow(VGAScreen, 120, 40, 1, samples_disabled ? 12 : 16, fxVolume / 12, 3, 13);
  1206.  
  1207.                 JE_showVGA();
  1208.  
  1209.                 if (first)
  1210.                 {
  1211.                         first = false;
  1212.                         wait_noinput(false, false, true); // TODO: should up the joystick repeat temporarily instead
  1213.                 }
  1214.  
  1215.                 tempW = 0;
  1216.                 JE_textMenuWait(&tempW, true);
  1217.  
  1218.                 if (inputDetected)
  1219.                 {
  1220.                         switch (lastkey_sym)
  1221.                         {
  1222.                                 case SDLK_RETURN:
  1223.                                         JE_playSampleNum(S_SELECT);
  1224.                                         switch (sel)
  1225.                                         {
  1226.                                                 case 1:
  1227.                                                         music_disabled = !music_disabled;
  1228.                                                         break;
  1229.                                                 case 2:
  1230.                                                         samples_disabled = !samples_disabled;
  1231.                                                         break;
  1232.                                                 case 3:
  1233.                                                 case 4:
  1234.                                                         sel = 5;
  1235.                                                         break;
  1236.                                                 case 5:
  1237.                                                         quit = true;
  1238.                                                         break;
  1239.                                                 case 6:
  1240.                                                         returnvalue = true;
  1241.                                                         quit = true;
  1242.                                                         if (constantPlay)
  1243.                                                         {
  1244.                                                                 JE_tyrianHalt(0);
  1245.                                                         }
  1246.  
  1247.                                                         if (isNetworkGame)
  1248.                                                         { /*Tell other computer to exit*/
  1249.                                                                 haltGame = true;
  1250.                                                                 playerEndLevel = true;
  1251.                                                         }
  1252.                                                         break;
  1253.                                         }
  1254.                                         break;
  1255.                                 case SDLK_ESCAPE:
  1256.                                         quit = true;
  1257.                                         JE_playSampleNum(S_SPRING);
  1258.                                         break;
  1259.                                 case SDLK_UP:
  1260.                                         if (--sel < 1)
  1261.                                         {
  1262.                                                 sel = 6;
  1263.                                         }
  1264.                                         JE_playSampleNum(S_CURSOR);
  1265.                                         break;
  1266.                                 case SDLK_DOWN:
  1267.                                         if (++sel > 6)
  1268.                                         {
  1269.                                                 sel = 1;
  1270.                                         }
  1271.                                         JE_playSampleNum(S_CURSOR);
  1272.                                         break;
  1273.                                 case SDLK_LEFT:
  1274.                                         switch (sel)
  1275.                                         {
  1276.                                                 case 1:
  1277.                                                         JE_changeVolume(&tyrMusicVolume, -12, &fxVolume, 0);
  1278.                                                         if (music_disabled)
  1279.                                                         {
  1280.                                                                 music_disabled = false;
  1281.                                                                 restart_song();
  1282.                                                         }
  1283.                                                         break;
  1284.                                                 case 2:
  1285.                                                         JE_changeVolume(&tyrMusicVolume, 0, &fxVolume, -12);
  1286.                                                         samples_disabled = false;
  1287.                                                         break;
  1288.                                                 case 3:
  1289.                                                         if (--processorType < 1)
  1290.                                                         {
  1291.                                                                 processorType = 4;
  1292.                                                         }
  1293.                                                         JE_initProcessorType();
  1294.                                                         JE_setNewGameSpeed();
  1295.                                                         break;
  1296.                                                 case 4:
  1297.                                                         if (--gameSpeed < 1)
  1298.                                                         {
  1299.                                                                 gameSpeed = 5;
  1300.                                                         }
  1301.                                                         JE_initProcessorType();
  1302.                                                         JE_setNewGameSpeed();
  1303.                                                         break;
  1304.                                         }
  1305.                                         if (sel < 5)
  1306.                                         {
  1307.                                                 JE_playSampleNum(S_CURSOR);
  1308.                                         }
  1309.                                         break;
  1310.                                 case SDLK_RIGHT:
  1311.                                         switch (sel)
  1312.                                         {
  1313.                                                 case 1:
  1314.                                                         JE_changeVolume(&tyrMusicVolume, 12, &fxVolume, 0);
  1315.                                                         if (music_disabled)
  1316.                                                         {
  1317.                                                                 music_disabled = false;
  1318.                                                                 restart_song();
  1319.                                                         }
  1320.                                                         break;
  1321.                                                 case 2:
  1322.                                                         JE_changeVolume(&tyrMusicVolume, 0, &fxVolume, 12);
  1323.                                                         samples_disabled = false;
  1324.                                                         break;
  1325.                                                 case 3:
  1326.                                                         if (++processorType > 4)
  1327.                                                         {
  1328.                                                                 processorType = 1;
  1329.                                                         }
  1330.                                                         JE_initProcessorType();
  1331.                                                         JE_setNewGameSpeed();
  1332.                                                         break;
  1333.                                                 case 4:
  1334.                                                         if (++gameSpeed > 5)
  1335.                                                         {
  1336.                                                                 gameSpeed = 1;
  1337.                                                         }
  1338.                                                         JE_initProcessorType();
  1339.                                                         JE_setNewGameSpeed();
  1340.                                                         break;
  1341.                                         }
  1342.                                         if (sel < 5)
  1343.                                         {
  1344.                                                 JE_playSampleNum(S_CURSOR);
  1345.                                         }
  1346.                                         break;
  1347.                                 case SDLK_w:
  1348.                                         if (sel == 3)
  1349.                                         {
  1350.                                                 processorType = 6;
  1351.                                                 JE_initProcessorType();
  1352.                                         }
  1353.                                 default:
  1354.                                         break;
  1355.                         }
  1356.                 }
  1357.  
  1358.         } while (!(quit || haltGame));
  1359.  
  1360.         VGAScreen = temp_surface; /* side-effect of game_screen */
  1361.  
  1362.         return returnvalue;
  1363. }
  1364.  
  1365. void JE_inGameHelp( void )
  1366. {
  1367.         SDL_Surface *temp_surface = VGAScreen;
  1368.         VGAScreen = VGAScreenSeg; /* side-effect of game_screen */
  1369.  
  1370.         //tempScreenSeg = VGAScreenSeg;
  1371.  
  1372.         JE_clearKeyboard();
  1373.         JE_wipeKey();
  1374.  
  1375.         JE_barShade(VGAScreen, 1, 1, 262, 182); /*Main Box*/
  1376.         JE_barShade(VGAScreen, 3, 3, 260, 180);
  1377.         JE_barShade(VGAScreen, 5, 5, 258, 178);
  1378.         JE_barShade(VGAScreen, 7, 7, 256, 176);
  1379.         fill_rectangle_xy(VGAScreen, 9, 9, 254, 174, 0);
  1380.  
  1381.         if (twoPlayerMode)  // Two-Player Help
  1382.         {
  1383.                 helpBoxColor = 3;
  1384.                 helpBoxBrightness = 3;
  1385.                 JE_HBox(VGAScreen, 20,  4, 36, 50);
  1386.  
  1387.                 // weapon help
  1388.                 blit_sprite(VGAScreenSeg, 2, 21, OPTION_SHAPES, 43);
  1389.                 helpBoxColor = 5;
  1390.                 helpBoxBrightness = 3;
  1391.                 JE_HBox(VGAScreen, 55, 20, 37, 40);
  1392.  
  1393.                 // sidekick help
  1394.                 blit_sprite(VGAScreenSeg, 5, 36, OPTION_SHAPES, 41);
  1395.                 helpBoxColor = 5;
  1396.                 helpBoxBrightness = 3;
  1397.                 JE_HBox(VGAScreen, 40, 43, 34, 44);
  1398.  
  1399.                 // sheild/armor help
  1400.                 blit_sprite(VGAScreenSeg, 2, 79, OPTION_SHAPES, 42);
  1401.                 helpBoxColor = 5;
  1402.                 helpBoxBrightness = 3;
  1403.                 JE_HBox(VGAScreen, 54, 84, 35, 40);
  1404.  
  1405.                 helpBoxColor = 5;
  1406.                 helpBoxBrightness = 3;
  1407.                 JE_HBox(VGAScreen, 5, 126, 38, 55);
  1408.                 helpBoxColor = 5;
  1409.                 helpBoxBrightness = 3;
  1410.                 JE_HBox(VGAScreen, 5, 160, 39, 55);
  1411.         }
  1412.         else
  1413.         {
  1414.                 // power bar help
  1415.                 blit_sprite(VGAScreenSeg, 15, 5, OPTION_SHAPES, 40);
  1416.                 helpBoxColor = 5;
  1417.                 helpBoxBrightness = 3;
  1418.                 JE_HBox(VGAScreen, 40, 10, 31, 45);
  1419.  
  1420.                 // weapon help
  1421.                 blit_sprite(VGAScreenSeg, 5, 37, OPTION_SHAPES, 39);
  1422.                 helpBoxColor = 5;
  1423.                 helpBoxBrightness = 3;
  1424.                 JE_HBox(VGAScreen, 40, 40, 32, 44);
  1425.                 helpBoxColor = 5;
  1426.                 helpBoxBrightness = 3;
  1427.                 JE_HBox(VGAScreen, 40, 60, 33, 44);
  1428.  
  1429.                 // sidekick help
  1430.                 blit_sprite(VGAScreenSeg, 5, 98, OPTION_SHAPES, 41);
  1431.                 helpBoxColor = 5;
  1432.                 helpBoxBrightness = 3;
  1433.                 JE_HBox(VGAScreen, 40, 103, 34, 44);
  1434.  
  1435.                 // shield/armor help
  1436.                 blit_sprite(VGAScreenSeg, 2, 138, OPTION_SHAPES, 42);
  1437.                 helpBoxColor = 5;
  1438.                 helpBoxBrightness = 3;
  1439.                 JE_HBox(VGAScreen, 54, 143, 35, 40);
  1440.         }
  1441.  
  1442.         // "press a key"
  1443.         blit_sprite(VGAScreenSeg, 16, 189, OPTION_SHAPES, 36);  // in-game text area
  1444.         JE_outText(VGAScreenSeg, 120 - JE_textWidth(miscText[5-1], TINY_FONT) / 2 + 20, 190, miscText[5-1], 0, 4);
  1445.  
  1446.         JE_showVGA();
  1447.  
  1448.         do
  1449.         {
  1450.                 tempW = 0;
  1451.                 JE_textMenuWait(&tempW, true);
  1452.         }
  1453.         while (!inputDetected);
  1454.  
  1455.         textErase = 1;
  1456.  
  1457.         VGAScreen = temp_surface;
  1458. }
  1459.  
  1460. void JE_highScoreCheck( void )
  1461. {
  1462.         free_sprite2s(&shapes6);
  1463.         JE_loadCompShapes(&shapes6, '1');  // need mouse cursor sprite
  1464.  
  1465.         Sint32 temp_score;
  1466.  
  1467.         for (int temp_p = 0; temp_p < (twoPlayerMode ? 2 : 1); ++temp_p)
  1468.         {
  1469.                 JE_sortHighScores();
  1470.  
  1471.                 int p = temp_p;
  1472.  
  1473.                 if (twoPlayerMode)
  1474.                 {
  1475.                         // ask for the highest scorer first
  1476.                         if (player[0].cash < player[1].cash)
  1477.                                 p = (temp_p == 0) ? 1 : 0;
  1478.  
  1479.                         temp_score = (p == 0) ? player[0].cash : player[1].cash;
  1480.                 }
  1481.                 else
  1482.                 {
  1483.                         // single player highscore includes cost of upgrades
  1484.                         temp_score = JE_totalScore(&player[0]);
  1485.                 }
  1486.  
  1487.                 int slot;
  1488.                 const int first_slot = (initial_episode_num - 1) * 6 + (twoPlayerMode ? 3 : 0),
  1489.                           slot_limit = first_slot + 3;
  1490.  
  1491.                 for (slot = first_slot; slot < slot_limit; ++slot)
  1492.                 {
  1493.                         if (temp_score > saveFiles[slot].highScore1)
  1494.                                 break;
  1495.                 }
  1496.  
  1497.                 // did you get a high score?
  1498.                 if (slot < slot_limit)
  1499.                 {
  1500.                         // shift down old scores
  1501.                         for (int i = slot_limit - 1; i > slot; --i)
  1502.                         {
  1503.                                 saveFiles[i].highScore1 = saveFiles[i - 1].highScore1;
  1504.                                 strcpy(saveFiles[i].highScoreName, saveFiles[i - 1].highScoreName);
  1505.                         }
  1506.  
  1507.                         wait_noinput(false, true, false);
  1508.  
  1509.                         JE_clr256(VGAScreen);
  1510.                         JE_showVGA();
  1511.                         memcpy(colors, palettes[0], sizeof(colors));
  1512.  
  1513.                         play_song(33);
  1514.  
  1515.                         {
  1516.                                 /* Enter Thy name */
  1517.  
  1518.                                 JE_byte flash = 8 * 16 + 10;
  1519.                                 JE_boolean fadein = true;
  1520.                                 JE_boolean quit = false, cancel = false;
  1521.                                 char stemp[30], tempstr[30];
  1522.                                 char buffer[256];
  1523.  
  1524.                                 strcpy(stemp, "                             ");
  1525.                                 temp = 0;
  1526.  
  1527.                                 JE_barShade(VGAScreen, 65, 55, 255, 155);
  1528.  
  1529.                                 do
  1530.                                 {
  1531.                                         service_SDL_events(true);
  1532.  
  1533.                                         JE_dString(VGAScreen, JE_fontCenter(miscText[51], FONT_SHAPES), 3, miscText[51], FONT_SHAPES);
  1534.  
  1535.                                         temp3 = twoPlayerMode ? 58 + p : 53;
  1536.  
  1537.                                         JE_dString(VGAScreen, JE_fontCenter(miscText[temp3-1], SMALL_FONT_SHAPES), 30, miscText[temp3-1], SMALL_FONT_SHAPES);
  1538.  
  1539.                                         blit_sprite(VGAScreenSeg, 50, 50, OPTION_SHAPES, 35);  // message box
  1540.  
  1541.                                         if (twoPlayerMode)
  1542.                                         {
  1543.                                                 sprintf(buffer, "%s %s", miscText[48 + p], miscText[53]);
  1544.                                                 JE_textShade(VGAScreen, 60, 55, buffer, 11, 4, FULL_SHADE);
  1545.                                         }
  1546.                                         else
  1547.                                         {
  1548.                                                 JE_textShade(VGAScreen, 60, 55, miscText[53], 11, 4, FULL_SHADE);
  1549.                                         }
  1550.  
  1551.                                         sprintf(buffer, "%s %d", miscText[37], temp_score);
  1552.                                         JE_textShade(VGAScreen, 70, 70, buffer, 11, 4, FULL_SHADE);
  1553.  
  1554.                                         do
  1555.                                         {
  1556.                                                 flash = (flash == 8 * 16 + 10) ? 8 * 16 + 2 : 8 * 16 + 10;
  1557.                                                 temp3 = (temp3 == 6) ? 2 : 6;
  1558.  
  1559.                                                 strncpy(tempstr, stemp, temp);
  1560.                                                 tempstr[temp] = '\0';
  1561.                                                 JE_outText(VGAScreen, 65, 89, tempstr, 8, 3);
  1562.                                                 tempW = 65 + JE_textWidth(tempstr, TINY_FONT);
  1563.                                                 JE_barShade(VGAScreen, tempW + 2, 90, tempW + 6, 95);
  1564.                                                 fill_rectangle_xy(VGAScreen, tempW + 1, 89, tempW + 5, 94, flash);
  1565.  
  1566.                                                 for (int i = 0; i < 14; i++)
  1567.                                                 {
  1568.                                                         setjasondelay(1);
  1569.  
  1570.                                                         JE_mouseStart();
  1571.                                                         JE_showVGA();
  1572.                                                         if (fadein)
  1573.                                                         {
  1574.                                                                 fade_palette(colors, 15, 0, 255);
  1575.                                                                 fadein = false;
  1576.                                                         }
  1577.                                                         JE_mouseReplace();
  1578.  
  1579.                                                         push_joysticks_as_keyboard();
  1580.                                                         service_wait_delay();
  1581.  
  1582.                                                         if (newkey || newmouse)
  1583.                                                                 break;
  1584.                                                 }
  1585.  
  1586.                                         } while (!newkey && !newmouse);
  1587.  
  1588.                                         if (!playing)
  1589.                                                 play_song(31);
  1590.  
  1591.                                         if (mouseButton > 0)
  1592.                                         {
  1593.                                                 if (mouseX > 56 && mouseX < 142 && mouseY > 123 && mouseY < 149)
  1594.                                                 {
  1595.                                                         quit = true;
  1596.                                                 }
  1597.                                                 else if (mouseX > 151 && mouseX < 237 && mouseY > 123 && mouseY < 149)
  1598.                                                 {
  1599.                                                         quit = true;
  1600.                                                         cancel = true;
  1601.                                                 }
  1602.                                         }
  1603.                                         else if (newkey)
  1604.                                         {
  1605.                                                 bool validkey = false;
  1606.                                                 lastkey_char = toupper(lastkey_char);
  1607.                                                 switch(lastkey_char)
  1608.                                                 {
  1609.                                                         case ' ':
  1610.                                                         case '-':
  1611.                                                         case '.':
  1612.                                                         case ',':
  1613.                                                         case ':':
  1614.                                                         case '!':
  1615.                                                         case '?':
  1616.                                                         case '#':
  1617.                                                         case '@':
  1618.                                                         case '$':
  1619.                                                         case '%':
  1620.                                                         case '*':
  1621.                                                         case '(':
  1622.                                                         case ')':
  1623.                                                         case '/':
  1624.                                                         case '=':
  1625.                                                         case '+':
  1626.                                                         case '<':
  1627.                                                         case '>':
  1628.                                                         case ';':
  1629.                                                         case '"':
  1630.                                                         case '\'':
  1631.                                                                 validkey = true;
  1632.                                                                 // fall through
  1633.                                                         default:
  1634.                                                                 if (temp < 28 && (validkey || (lastkey_char >= 'A' && lastkey_char <= 'Z') || (lastkey_char >= '0' && lastkey_char <= '9')))
  1635.                                                                 {
  1636.                                                                         stemp[temp] = lastkey_char;
  1637.                                                                         temp++;
  1638.                                                                 }
  1639.                                                                 break;
  1640.                                                         case SDLK_BACKSPACE:
  1641.                                                         case SDLK_DELETE:
  1642.                                                                 if (temp)
  1643.                                                                 {
  1644.                                                                         temp--;
  1645.                                                                         stemp[temp] = ' ';
  1646.                                                                 }
  1647.                                                                 break;
  1648.                                                         case SDLK_ESCAPE:
  1649.                                                                 quit = true;
  1650.                                                                 cancel = true;
  1651.                                                                 break;
  1652.                                                         case SDLK_RETURN:
  1653.                                                                 quit = true;
  1654.                                                                 break;
  1655.                                                 }
  1656.                                         }
  1657.                                 }
  1658.                                 while (!quit);
  1659.  
  1660.                                 if (!cancel)
  1661.                                 {
  1662.                                         saveFiles[slot].highScore1 = temp_score;
  1663.                                         strcpy(saveFiles[slot].highScoreName, stemp);
  1664.                                         saveFiles[slot].highScoreDiff = difficultyLevel;
  1665.                                 }
  1666.  
  1667.                                 fade_black(15);
  1668.                                 JE_loadPic(VGAScreen, 2, false);
  1669.  
  1670.                                 JE_dString(VGAScreen, JE_fontCenter(miscText[50], FONT_SHAPES), 10, miscText[50], FONT_SHAPES);
  1671.                                 JE_dString(VGAScreen, JE_fontCenter(episode_name[episodeNum], SMALL_FONT_SHAPES), 35, episode_name[episodeNum], SMALL_FONT_SHAPES);
  1672.  
  1673.                                 for (int i = first_slot; i < slot_limit; ++i)
  1674.                                 {
  1675.                                         if (i != slot)
  1676.                                         {
  1677.                                                 sprintf(buffer, "~#%d:~  %d", (i - first_slot + 1), saveFiles[i].highScore1);
  1678.                                                 JE_textShade(VGAScreen,  20, ((i - first_slot + 1) * 12) + 65, buffer, 15, 0, FULL_SHADE);
  1679.                                                 JE_textShade(VGAScreen, 150, ((i - first_slot + 1) * 12) + 65, saveFiles[i].highScoreName, 15, 2, FULL_SHADE);
  1680.                                         }
  1681.                                 }
  1682.  
  1683.                                 JE_showVGA();
  1684.  
  1685.                                 fade_palette(colors, 15, 0, 255);
  1686.  
  1687.                                 sprintf(buffer, "~#%d:~  %d", (slot - first_slot + 1), saveFiles[slot].highScore1);
  1688.  
  1689.                                 frameCountMax = 6;
  1690.                                 textGlowFont = TINY_FONT;
  1691.  
  1692.                                 textGlowBrightness = 10;
  1693.                                 JE_outTextGlow(VGAScreenSeg,  20, (slot - first_slot + 1) * 12 + 65, buffer);
  1694.                                 textGlowBrightness = 10;
  1695.                                 JE_outTextGlow(VGAScreenSeg, 150, (slot - first_slot + 1) * 12 + 65, saveFiles[slot].highScoreName);
  1696.                                 textGlowBrightness = 10;
  1697.                                 JE_outTextGlow(VGAScreenSeg, JE_fontCenter(miscText[4], TINY_FONT), 180, miscText[4]);
  1698.  
  1699.                                 JE_showVGA();
  1700.  
  1701.                                 if (frameCountMax != 0)
  1702.                                         wait_input(true, true, true);
  1703.  
  1704.                                 fade_black(15);
  1705.                         }
  1706.  
  1707.                 }
  1708.         }
  1709. }
  1710.  
  1711. // increases game difficulty based on player's total score / total of players' scores
  1712. void adjust_difficulty( void )
  1713. {
  1714.         const float score_multiplier[10] =
  1715.         {
  1716.                 0,     // Wimp  (doesn't exist)
  1717.                 0.4f,  // Easy
  1718.                 0.8f,  // Normal
  1719.                 1.3f,  // Hard
  1720.                 1.6f,  // Impossible
  1721.                 2,     // Insanity
  1722.                 2,     // Suicide
  1723.                 3,     // Maniacal
  1724.                 3,     // Zinglon
  1725.                 3,     // Nortaneous
  1726.         };
  1727.  
  1728.         assert(initialDifficulty > 0 && initialDifficulty < 10);
  1729.  
  1730.         const ulong score = twoPlayerMode ? (player[0].cash + player[1].cash) : JE_totalScore(&player[0]),
  1731.                     adjusted_score = roundf(score * score_multiplier[initialDifficulty]);
  1732.  
  1733.         uint new_difficulty = 0;
  1734.  
  1735.         if (twoPlayerMode)
  1736.         {
  1737.                 if (adjusted_score < 10000)
  1738.                         new_difficulty = 1;  // Easy
  1739.                 else if (adjusted_score < 20000)
  1740.                         new_difficulty = 2;  // Normal
  1741.                 else if (adjusted_score < 50000)
  1742.                         new_difficulty = 3;  // Hard
  1743.                 else if (adjusted_score < 80000)
  1744.                         new_difficulty = 4;  // Impossible
  1745.                 else if (adjusted_score < 125000)
  1746.                         new_difficulty = 5;  // Insanity
  1747.                 else if (adjusted_score < 200000)
  1748.                         new_difficulty = 6;  // Suicide
  1749.                 else if (adjusted_score < 400000)
  1750.                         new_difficulty = 7;  // Maniacal
  1751.                 else if (adjusted_score < 600000)
  1752.                         new_difficulty = 8;  // Zinglon
  1753.                 else
  1754.                         new_difficulty = 9;  // Nortaneous
  1755.         }
  1756.         else
  1757.         {
  1758.                 if (adjusted_score < 40000)
  1759.                         new_difficulty = 1;  // Easy
  1760.                 else if (adjusted_score < 70000)
  1761.                         new_difficulty = 2;  // Normal
  1762.                 else if (adjusted_score < 150000)
  1763.                         new_difficulty = 3;  // Hard
  1764.                 else if (adjusted_score < 300000)
  1765.                         new_difficulty = 4;  // Impossible
  1766.                 else if (adjusted_score < 600000)
  1767.                         new_difficulty = 5;  // Insanity
  1768.                 else if (adjusted_score < 1000000)
  1769.                         new_difficulty = 6;  // Suicide
  1770.                 else if (adjusted_score < 2000000)
  1771.                         new_difficulty = 7;  // Maniacal
  1772.                 else if (adjusted_score < 3000000)
  1773.                         new_difficulty = 8;  // Zinglon
  1774.                 else
  1775.                         new_difficulty = 9;  // Nortaneous
  1776.         }
  1777.  
  1778.         difficultyLevel = MAX((unsigned)difficultyLevel, new_difficulty);
  1779. }
  1780.  
  1781. bool load_next_demo( void )
  1782. {
  1783.         if (++demo_num > 5)
  1784.                 demo_num = 1;
  1785.  
  1786.         char demo_filename[9];
  1787.         snprintf(demo_filename, sizeof(demo_filename), "demo.%d", demo_num);
  1788.         demo_file = dir_fopen_die(data_dir(), demo_filename, "rb"); // TODO: only play demos from existing file (instead of dying)
  1789.  
  1790.         difficultyLevel = 2;
  1791.         bonusLevelCurrent = false;
  1792.  
  1793.         Uint8 temp = fgetc(demo_file);
  1794.         JE_initEpisode(temp);
  1795.         efread(levelName, 1, 10, demo_file); levelName[10] = '\0';
  1796.         lvlFileNum = fgetc(demo_file);
  1797.  
  1798.         player[0].items.weapon[FRONT_WEAPON].id  = fgetc(demo_file);
  1799.         player[0].items.weapon[REAR_WEAPON].id   = fgetc(demo_file);
  1800.         player[0].items.super_arcade_mode        = fgetc(demo_file);
  1801.         player[0].items.sidekick[LEFT_SIDEKICK]  = fgetc(demo_file);
  1802.         player[0].items.sidekick[RIGHT_SIDEKICK] = fgetc(demo_file);
  1803.         player[0].items.generator                = fgetc(demo_file);
  1804.  
  1805.         player[0].items.sidekick_level           = fgetc(demo_file); // could probably ignore
  1806.         player[0].items.sidekick_series          = fgetc(demo_file); // could probably ignore
  1807.  
  1808.         initial_episode_num                      = fgetc(demo_file); // could probably ignore
  1809.  
  1810.         player[0].items.shield                   = fgetc(demo_file);
  1811.         player[0].items.special                  = fgetc(demo_file);
  1812.         player[0].items.ship                     = fgetc(demo_file);
  1813.  
  1814.         for (uint i = 0; i < 2; ++i)
  1815.                 player[0].items.weapon[i].power = fgetc(demo_file);
  1816.  
  1817.         fseek(demo_file, 3, SEEK_CUR);
  1818.  
  1819.         levelSong = fgetc(demo_file);
  1820.  
  1821.         demo_keys_wait = 0;
  1822.         demo_keys = next_demo_keys = 0;
  1823.  
  1824.         printf("loaded demo '%s'\n", demo_filename);
  1825.  
  1826.         return true;
  1827. }
  1828.  
  1829. bool replay_demo_keys( void )
  1830. {
  1831.         if (demo_keys_wait == 0)
  1832.                 if (read_demo_keys() == false)
  1833.                         return false; // no more keys
  1834.  
  1835.         if (demo_keys_wait > 0)
  1836.                 demo_keys_wait--;
  1837.  
  1838.         if (demo_keys & (1 << 0))
  1839.                 player[0].y -= CURRENT_KEY_SPEED;
  1840.         if (demo_keys & (1 << 1))
  1841.                 player[0].y += CURRENT_KEY_SPEED;
  1842.  
  1843.         if (demo_keys & (1 << 2))
  1844.                 player[0].x -= CURRENT_KEY_SPEED;
  1845.         if (demo_keys & (1 << 3))
  1846.                 player[0].x += CURRENT_KEY_SPEED;
  1847.  
  1848.         button[0] = (bool)(demo_keys & (1 << 4));
  1849.         button[3] = (bool)(demo_keys & (1 << 5));
  1850.         button[1] = (bool)(demo_keys & (1 << 6));
  1851.         button[2] = (bool)(demo_keys & (1 << 7));
  1852.  
  1853.         return true;
  1854. }
  1855.  
  1856. bool read_demo_keys( void )
  1857. {
  1858.         demo_keys = next_demo_keys;
  1859.  
  1860.         efread(&demo_keys_wait, sizeof(Uint16), 1, demo_file);
  1861.         demo_keys_wait = SDL_Swap16(demo_keys_wait);
  1862.  
  1863.         next_demo_keys = getc(demo_file);
  1864.  
  1865.         return !feof(demo_file);
  1866. }
  1867.  
  1868. /*Street Fighter codes*/
  1869. void JE_SFCodes( JE_byte playerNum_, JE_integer PX_, JE_integer PY_, JE_integer mouseX_, JE_integer mouseY_ )
  1870. {
  1871.         JE_byte temp, temp2, temp3, temp4, temp5;
  1872.  
  1873.         uint ship = player[playerNum_-1].items.ship;
  1874.  
  1875.         /*Get direction*/
  1876.         if (playerNum_ == 2 && ship < 15)
  1877.         {
  1878.                 ship = 0;
  1879.         }
  1880.  
  1881.         if (ship < 15)
  1882.         {
  1883.  
  1884.                 temp2 = (mouseY_ > PY_) +    /*UP*/
  1885.                         (mouseY_ < PY_) +    /*DOWN*/
  1886.                         (PX_ < mouseX_) +    /*LEFT*/
  1887.                         (PX_ > mouseX_);     /*RIGHT*/
  1888.                 temp = (mouseY_ > PY_) * 1 + /*UP*/
  1889.                        (mouseY_ < PY_) * 2 + /*DOWN*/
  1890.                        (PX_ < mouseX_) * 3 + /*LEFT*/
  1891.                        (PX_ > mouseX_) * 4;  /*RIGHT*/
  1892.  
  1893.                 if (temp == 0) // no direction being pressed
  1894.                 {
  1895.                         if (!button[0]) // if fire button is released
  1896.                         {
  1897.                                 temp = 9;
  1898.                                 temp2 = 1;
  1899.                         } else {
  1900.                                 temp2 = 0;
  1901.                                 temp = 99;
  1902.                         }
  1903.                 }
  1904.  
  1905.                 if (temp2 == 1) // if exactly one direction pressed or firebutton is released
  1906.                 {
  1907.                         temp += button[0] * 4;
  1908.  
  1909.                         temp3 = superTyrian ? 21 : 3;
  1910.                         for (temp2 = 0; temp2 < temp3; temp2++)
  1911.                         {
  1912.  
  1913.                                 /*Use SuperTyrian ShipCombos or not?*/
  1914.                                 temp5 = superTyrian ? shipCombosB[temp2] : shipCombos[ship][temp2];
  1915.  
  1916.                                 // temp5 == selected combo in ship
  1917.                                 if (temp5 == 0) /* combo doesn't exists */
  1918.                                 {
  1919.                                         // mark twiddles as cancelled/finished
  1920.                                         SFCurrentCode[playerNum_-1][temp2] = 0;
  1921.                                 } else {
  1922.                                         // get next combo key
  1923.                                         temp4 = keyboardCombos[temp5-1][SFCurrentCode[playerNum_-1][temp2]];
  1924.  
  1925.                                         // correct key
  1926.                                         if (temp4 == temp)
  1927.                                         {
  1928.                                                 SFCurrentCode[playerNum_-1][temp2]++;
  1929.  
  1930.                                                 temp4 = keyboardCombos[temp5-1][SFCurrentCode[playerNum_-1][temp2]];
  1931.                                                 if (temp4 > 100 && temp4 <= 100 + SPECIAL_NUM)
  1932.                                                 {
  1933.                                                         SFCurrentCode[playerNum_-1][temp2] = 0;
  1934.                                                         SFExecuted[playerNum_-1] = temp4 - 100;
  1935.                                                 }
  1936.                                         } else {
  1937.                                                 if ((temp != 9) &&
  1938.                                                     (temp4 - 1) % 4 != (temp - 1) % 4 &&
  1939.                                                     (SFCurrentCode[playerNum_-1][temp2] == 0 ||
  1940.                                                      keyboardCombos[temp5-1][SFCurrentCode[playerNum_-1][temp2]-1] != temp))
  1941.                                                 {
  1942.                                                         SFCurrentCode[playerNum_-1][temp2] = 0;
  1943.                                                 }
  1944.                                         }
  1945.                                 }
  1946.                         }
  1947.                 }
  1948.  
  1949.         }
  1950. }
  1951.  
  1952. void JE_sort( void )
  1953. {
  1954.         JE_byte a, b;
  1955.  
  1956.         for (a = 0; a < 2; a++)
  1957.         {
  1958.                 for (b = a + 1; b < 3; b++)
  1959.                 {
  1960.                         if (saveFiles[temp + a].highScore1 < saveFiles[temp + b].highScore1)
  1961.                         {
  1962.                                 JE_longint tempLI;
  1963.                                 char tempStr[30];
  1964.                                 JE_byte tempByte;
  1965.  
  1966.                                 tempLI = saveFiles[temp + a].highScore1;
  1967.                                 saveFiles[temp + a].highScore1 = saveFiles[temp + b].highScore1;
  1968.                                 saveFiles[temp + b].highScore1 = tempLI;
  1969.  
  1970.                                 strcpy(tempStr, saveFiles[temp + a].highScoreName);
  1971.                                 strcpy(saveFiles[temp + a].highScoreName, saveFiles[temp + b].highScoreName);
  1972.                                 strcpy(saveFiles[temp + b].highScoreName, tempStr);
  1973.  
  1974.                                 tempByte = saveFiles[temp + a].highScoreDiff;
  1975.                                 saveFiles[temp + a].highScoreDiff = saveFiles[temp + b].highScoreDiff;
  1976.                                 saveFiles[temp + b].highScoreDiff = tempByte;
  1977.                         }
  1978.                 }
  1979.         }
  1980. }
  1981.  
  1982. void JE_playCredits( void )
  1983. {
  1984.         enum { lines_max = 132 };
  1985.         enum { line_max_length = 65 };
  1986.        
  1987.         char credstr[lines_max][line_max_length + 1];
  1988.        
  1989.         int lines = 0;
  1990.        
  1991.         JE_byte currentpic = 0, fade = 0;
  1992.         JE_shortint fadechg = 1;
  1993.         JE_byte currentship = 0;
  1994.         JE_integer shipx = 0, shipxwait = 0;
  1995.         JE_shortint shipxc = 0, shipxca = 0;
  1996.  
  1997.         load_sprites_file(EXTRA_SHAPES, "estsc.shp");
  1998.  
  1999.         setjasondelay2(1000);
  2000.  
  2001.         play_song(8);
  2002.        
  2003.         // load credits text
  2004.         FILE *f = dir_fopen_die(data_dir(), "tyrian.cdt", "rb");
  2005.         for (lines = 0; !feof(f) && lines < lines_max; ++lines)
  2006.         {
  2007.                 read_encrypted_pascal_string(credstr[lines], sizeof(credstr[lines]), f);
  2008.         }
  2009.         if (lines == lines_max)
  2010.                 --lines;
  2011.         fclose(f);
  2012.        
  2013.         memcpy(colors, palettes[6-1], sizeof(colors));
  2014.         JE_clr256(VGAScreen);
  2015.         JE_showVGA();
  2016.         fade_palette(colors, 2, 0, 255);
  2017.        
  2018.         //tempScreenSeg = VGAScreenSeg;
  2019.        
  2020.         const int ticks_max = lines * 20 * 3;
  2021.         for (int ticks = 0; ticks < ticks_max; ++ticks)
  2022.         {
  2023.                 setjasondelay(1);
  2024.                 JE_clr256(VGAScreen);
  2025.                
  2026.                 blit_sprite_hv(VGAScreenSeg, 319 - sprite(EXTRA_SHAPES, currentpic)->width, 100 - (sprite(EXTRA_SHAPES, currentpic)->height / 2), EXTRA_SHAPES, currentpic, 0x0, fade - 15);
  2027.                
  2028.                 fade += fadechg;
  2029.                 if (fade == 0 && fadechg == -1)
  2030.                 {
  2031.                         fadechg = 1;
  2032.                         ++currentpic;
  2033.                         if (currentpic >= sprite_table[EXTRA_SHAPES].count)
  2034.                                 currentpic = 0;
  2035.                 }
  2036.                 if (fade == 15)
  2037.                         fadechg = 0;
  2038.  
  2039.                 if (delaycount2() == 0)
  2040.                 {
  2041.                         fadechg = -1;
  2042.                         setjasondelay2(900);
  2043.                 }
  2044.  
  2045.                 if (ticks % 200 == 0)
  2046.                 {
  2047.                         currentship = (mt_rand() % 11) + 1;
  2048.                         shipxwait = (mt_rand() % 80) + 10;
  2049.                         if ((mt_rand() % 2) == 1)
  2050.                         {
  2051.                                 shipx = 1;
  2052.                                 shipxc = 0;
  2053.                                 shipxca = 1;
  2054.                         }
  2055.                         else
  2056.                         {
  2057.                                 shipx = 900;
  2058.                                 shipxc = 0;
  2059.                                 shipxca = -1;
  2060.                         }
  2061.                 }
  2062.  
  2063.                 shipxwait--;
  2064.                 if (shipxwait == 0)
  2065.                 {
  2066.                         if (shipx == 1 || shipx == 900)
  2067.                                 shipxc = 0;
  2068.                         shipxca = -shipxca;
  2069.                         shipxwait = (mt_rand() % 40) + 15;
  2070.                 }
  2071.                 shipxc += shipxca;
  2072.                 shipx += shipxc;
  2073.                 if (shipx < 1)
  2074.                 {
  2075.                         shipx = 1;
  2076.                         shipxwait = 1;
  2077.                 }
  2078.                 if (shipx > 900)
  2079.                 {
  2080.                         shipx = 900;
  2081.                         shipxwait = 1;
  2082.                 }
  2083.         int tmp_unknown = shipxc * shipxc;
  2084.                 if (450 + tmp_unknown < 0 || 450 + tmp_unknown > 900)
  2085.                 {
  2086.                         if (shipxca < 0 && shipxc < 0)
  2087.                                 shipxwait = 1;
  2088.                         if (shipxca > 0 && shipxc > 0)
  2089.                                 shipxwait = 1;
  2090.                 }
  2091.                
  2092.                 uint ship_sprite = ships[currentship].shipgraphic;
  2093.                 if (shipxc < -10)
  2094.                         ship_sprite -= (shipxc < -20) ? 4 : 2;
  2095.                 else if (shipxc > 10)
  2096.                         ship_sprite += (shipxc > 20) ? 4 : 2;
  2097.                
  2098.                 blit_sprite2x2(VGAScreen, shipx / 40, 184 - (ticks % 200), shapes9, ship_sprite);
  2099.                
  2100.                 const int bottom_line = (ticks / 3) / 20;
  2101.                 int y = 20 - ((ticks / 3) % 20);
  2102.                
  2103.                 for (int line = bottom_line - 10; line < bottom_line; ++line)
  2104.                 {
  2105.                         if (line >= 0 && line < lines_max)
  2106.                         {
  2107.                                 if (strcmp(&credstr[line][0], ".") != 0 && strlen(credstr[line]))
  2108.                                 {
  2109.                                         const Uint8 color = credstr[line][0] - 65;
  2110.                                         const char *text = &credstr[line][1];
  2111.                                        
  2112.                                         const int x = 110 - JE_textWidth(text, SMALL_FONT_SHAPES) / 2;
  2113.                                        
  2114.                                         JE_outTextAdjust(VGAScreen, x + abs((y / 18) % 4 - 2) - 1, y - 1, text, color, -8, SMALL_FONT_SHAPES, false);
  2115.                                         JE_outTextAdjust(VGAScreen, x,                             y,     text, color, -2, SMALL_FONT_SHAPES, false);
  2116.                                 }
  2117.                         }
  2118.                        
  2119.                         y += 20;
  2120.                 }
  2121.                
  2122.                 fill_rectangle_xy(VGAScreen, 0,  0, 319, 10, 0);
  2123.                 fill_rectangle_xy(VGAScreen, 0, 190, 319, 199, 0);
  2124.                
  2125.                 if (currentpic == sprite_table[EXTRA_SHAPES].count - 1)
  2126.                         JE_outTextAdjust(VGAScreen, 5, 180, miscText[54], 2, -2, SMALL_FONT_SHAPES, false);  // levels-in-episode
  2127.                
  2128.                 if (bottom_line == lines_max - 8)
  2129.                         fade_song();
  2130.                
  2131.                 if (ticks == ticks_max - 1)
  2132.                 {
  2133.                         --ticks;
  2134.                         play_song(9);
  2135.                 }
  2136.                
  2137.                 NETWORK_KEEP_ALIVE();
  2138.                
  2139.                 JE_showVGA();
  2140.                
  2141.                 wait_delay();
  2142.                
  2143.                 if (JE_anyButton())
  2144.                         break;
  2145.         }
  2146.        
  2147.         fade_black(10);
  2148.        
  2149.         free_sprites(EXTRA_SHAPES);
  2150. }
  2151.  
  2152. void JE_endLevelAni( void )
  2153. {
  2154.         JE_word x, y;
  2155.         JE_byte temp;
  2156.         char tempStr[256];
  2157.  
  2158.         Sint8 i;
  2159.  
  2160.         if (!constantPlay)
  2161.         {
  2162.                 // grant shipedit privileges
  2163.  
  2164.                 // special
  2165.                 if (player[0].items.special < 21)
  2166.                         saveTemp[SAVE_FILES_SIZE + 81 + player[0].items.special] = 1;
  2167.  
  2168.                 for (uint p = 0; p < COUNTOF(player); ++p)
  2169.                 {
  2170.                         // front, rear
  2171.                         for (uint i = 0; i < COUNTOF(player[p].items.weapon); ++i)
  2172.                                 saveTemp[SAVE_FILES_SIZE + player[p].items.weapon[i].id] = 1;
  2173.  
  2174.                         // options
  2175.                         for (uint i = 0; i < COUNTOF(player[p].items.sidekick); ++i)
  2176.                                 saveTemp[SAVE_FILES_SIZE + 51 + player[p].items.sidekick[i]] = 1;
  2177.                 }
  2178.         }
  2179.  
  2180.         adjust_difficulty();
  2181.  
  2182.         player[0].last_items = player[0].items;
  2183.         strcpy(lastLevelName, levelName);
  2184.  
  2185.         JE_wipeKey();
  2186.         frameCountMax = 4;
  2187.         textGlowFont = SMALL_FONT_SHAPES;
  2188.  
  2189.         SDL_Color white = { 255, 255, 255 };
  2190.         set_colors(white, 254, 254);
  2191.  
  2192.         if (!levelTimer || levelTimerCountdown > 0 || !(episodeNum == 4))
  2193.                 JE_playSampleNum(V_LEVEL_END);
  2194.         else
  2195.                 play_song(21);
  2196.  
  2197.         if (bonusLevel)
  2198.         {
  2199.                 JE_outTextGlow(VGAScreenSeg, 20, 20, miscText[17-1]);
  2200.         }
  2201.         else if (all_players_alive())
  2202.         {
  2203.                 sprintf(tempStr, "%s %s", miscText[27-1], levelName); // "Completed"
  2204.                 JE_outTextGlow(VGAScreenSeg, 20, 20, tempStr);
  2205.         }
  2206.         else
  2207.         {
  2208.                 sprintf(tempStr, "%s %s", miscText[62-1], levelName); // "Exiting"
  2209.                 JE_outTextGlow(VGAScreenSeg, 20, 20, tempStr);
  2210.         }
  2211.  
  2212.         if (twoPlayerMode)
  2213.         {
  2214.                 for (uint i = 0; i < 2; ++i)
  2215.                 {
  2216.                         snprintf(tempStr, sizeof(tempStr), "%s %lu", miscText[40 + i], player[i].cash);
  2217.                         JE_outTextGlow(VGAScreenSeg, 30, 50 + 20 * i, tempStr);
  2218.                 }
  2219.         }
  2220.         else
  2221.         {
  2222.                 sprintf(tempStr, "%s %lu", miscText[28-1], player[0].cash);
  2223.                 JE_outTextGlow(VGAScreenSeg, 30, 50, tempStr);
  2224.         }
  2225.  
  2226.         temp = (totalEnemy == 0) ? 0 : roundf(enemyKilled * 100 / totalEnemy);
  2227.         sprintf(tempStr, "%s %d%%", miscText[63-1], temp);
  2228.         JE_outTextGlow(VGAScreenSeg, 40, 90, tempStr);
  2229.  
  2230.         if (!constantPlay)
  2231.                 editorLevel += temp / 5;
  2232.  
  2233.         if (!onePlayerAction && !twoPlayerMode)
  2234.         {
  2235.                 JE_outTextGlow(VGAScreenSeg, 30, 120, miscText[4-1]);   /*Cubes*/
  2236.  
  2237.                 if (cubeMax > 0)
  2238.                 {
  2239.                         if (cubeMax > 4)
  2240.                                 cubeMax = 4;
  2241.  
  2242.                         if (frameCountMax != 0)
  2243.                                 frameCountMax = 1;
  2244.  
  2245.                         for (temp = 1; temp <= cubeMax; temp++)
  2246.                         {
  2247.                                 NETWORK_KEEP_ALIVE();
  2248.  
  2249.                                 JE_playSampleNum(S_ITEM);
  2250.                                 x = 20 + 30 * temp;
  2251.                                 y = 135;
  2252.                                 JE_drawCube(VGAScreenSeg, x, y, 9, 0);
  2253.                                 JE_showVGA();
  2254.  
  2255.                                 for (i = -15; i <= 10; i++)
  2256.                                 {
  2257.                                         setjasondelay(frameCountMax);
  2258.  
  2259.                                         blit_sprite_hv(VGAScreenSeg, x, y, OPTION_SHAPES, 25, 0x9, i);
  2260.  
  2261.                                         if (JE_anyButton())
  2262.                                                 frameCountMax = 0;
  2263.  
  2264.                                         JE_showVGA();
  2265.  
  2266.                                         wait_delay();
  2267.                                 }
  2268.                                 for (i = 10; i >= 0; i--)
  2269.                                 {
  2270.                                         setjasondelay(frameCountMax);
  2271.  
  2272.                                         blit_sprite_hv(VGAScreenSeg, x, y, OPTION_SHAPES, 25, 0x9, i);
  2273.  
  2274.                                         if (JE_anyButton())
  2275.                                                 frameCountMax = 0;
  2276.  
  2277.                                         JE_showVGA();
  2278.  
  2279.                                         wait_delay();
  2280.                                 }
  2281.                         }
  2282.                 }
  2283.                 else
  2284.                 {
  2285.                         JE_outTextGlow(VGAScreenSeg, 50, 135, miscText[15-1]);
  2286.                 }
  2287.  
  2288.         }
  2289.  
  2290.         if (frameCountMax != 0)
  2291.         {
  2292.                 frameCountMax = 6;
  2293.                 temp = 1;
  2294.         } else {
  2295.                 temp = 0;
  2296.         }
  2297.         temp2 = twoPlayerMode ? 150 : 160;
  2298.         JE_outTextGlow(VGAScreenSeg, 90, temp2, miscText[5-1]);
  2299.  
  2300.         if (!constantPlay)
  2301.         {
  2302.                 do
  2303.                 {
  2304.                         setjasondelay(1);
  2305.  
  2306.                         NETWORK_KEEP_ALIVE();
  2307.  
  2308.                         wait_delay();
  2309.                 } while (!(JE_anyButton() || (frameCountMax == 0 && temp == 1)));
  2310.         }
  2311.  
  2312.         wait_noinput(false, false, true); // TODO: should up the joystick repeat temporarily instead
  2313.  
  2314.         fade_black(15);
  2315.         JE_clr256(VGAScreen);
  2316. }
  2317.  
  2318. void JE_drawCube( SDL_Surface * screen, JE_word x, JE_word y, JE_byte filter, JE_byte brightness )
  2319. {
  2320.         blit_sprite_dark(screen, x + 4, y + 4, OPTION_SHAPES, 25, false);
  2321.         blit_sprite_dark(screen, x + 3, y + 3, OPTION_SHAPES, 25, false);
  2322.         blit_sprite_hv(screen, x, y, OPTION_SHAPES, 25, filter, brightness);
  2323. }
  2324.  
  2325. void JE_handleChat( void )
  2326. {
  2327.         // STUB(); Annoying piece of crap =P
  2328. }
  2329.  
  2330. bool str_pop_int( char *str, int *val )
  2331. {
  2332.         bool success = false;
  2333.  
  2334.         char buf[256];
  2335.         assert(strlen(str) < sizeof(buf));
  2336.  
  2337.         // grab the value from str
  2338.         char *end;
  2339.         *val = strtol(str, &end, 10);
  2340.  
  2341.         if (end != str)
  2342.         {
  2343.                 success = true;
  2344.  
  2345.                 // shift the rest to the beginning
  2346.                 strcpy(buf, end);
  2347.                 strcpy(str, buf);
  2348.         }
  2349.  
  2350.         return success;
  2351. }
  2352.  
  2353. void JE_operation( JE_byte slot )
  2354. {
  2355.         JE_byte flash;
  2356.         char stemp[21];
  2357.         char tempStr[51];
  2358.  
  2359.         if (!performSave)
  2360.         {
  2361.                 if (saveFiles[slot-1].level > 0)
  2362.                 {
  2363.                         gameJustLoaded = true;
  2364.                         JE_loadGame(slot);
  2365.                         gameLoaded = true;
  2366.                 }
  2367.         }
  2368.         else if (slot % 11 != 0)
  2369.         {
  2370.                 strcpy(stemp, "              ");
  2371.                 memcpy(stemp, saveFiles[slot-1].name, strlen(saveFiles[slot-1].name));
  2372.                 temp = strlen(stemp);
  2373.                 while (stemp[temp-1] == ' ' && --temp);
  2374.  
  2375.                 flash = 8 * 16 + 10;
  2376.  
  2377.                 wait_noinput(false, true, false);
  2378.  
  2379.                 JE_barShade(VGAScreen, 65, 55, 255, 155);
  2380.  
  2381.                 bool quit = false;
  2382.                 while (!quit)
  2383.                 {
  2384.                         service_SDL_events(true);
  2385.  
  2386.                         blit_sprite(VGAScreen, 50, 50, OPTION_SHAPES, 35);  // message box
  2387.  
  2388.                         JE_textShade(VGAScreen, 60, 55, miscText[1-1], 11, 4, DARKEN);
  2389.                         JE_textShade(VGAScreen, 70, 70, levelName, 11, 4, DARKEN);
  2390.  
  2391.                         do
  2392.                         {
  2393.                                 flash = (flash == 8 * 16 + 10) ? 8 * 16 + 2 : 8 * 16 + 10;
  2394.                                 temp3 = (temp3 == 6) ? 2 : 6;
  2395.  
  2396.                                 strcpy(tempStr, miscText[2-1]);
  2397.                                 strncat(tempStr, stemp, temp);
  2398.                                 JE_outText(VGAScreen, 65, 89, tempStr, 8, 3);
  2399.                                 tempW = 65 + JE_textWidth(tempStr, TINY_FONT);
  2400.                                 JE_barShade(VGAScreen, tempW + 2, 90, tempW + 6, 95);
  2401.                                 fill_rectangle_xy(VGAScreen, tempW + 1, 89, tempW + 5, 94, flash);
  2402.  
  2403.                                 for (int i = 0; i < 14; i++)
  2404.                                 {
  2405.                                         setjasondelay(1);
  2406.  
  2407.                                         JE_mouseStart();
  2408.                                         JE_showVGA();
  2409.                                         JE_mouseReplace();
  2410.  
  2411.                                         push_joysticks_as_keyboard();
  2412.                                         service_wait_delay();
  2413.  
  2414.                                         if (newkey || newmouse)
  2415.                                                 break;
  2416.                                 }
  2417.  
  2418.                         }
  2419.                         while (!newkey && !newmouse);
  2420.  
  2421.                         if (mouseButton > 0)
  2422.                         {
  2423.                                 if (mouseX > 56 && mouseX < 142 && mouseY > 123 && mouseY < 149)
  2424.                                 {
  2425.                                         quit = true;
  2426.                                         JE_saveGame(slot, stemp);
  2427.                                         JE_playSampleNum(S_SELECT);
  2428.                                 }
  2429.                                 else if (mouseX > 151 && mouseX < 237 && mouseY > 123 && mouseY < 149)
  2430.                                 {
  2431.                                         quit = true;
  2432.                                         JE_playSampleNum(S_SPRING);
  2433.                                 }
  2434.                         }
  2435.                         else if (newkey)
  2436.                         {
  2437.                                 bool validkey = false;
  2438.                                 lastkey_char = toupper(lastkey_char);
  2439.                                 switch (lastkey_char)
  2440.                                 {
  2441.                                         case ' ':
  2442.                                         case '-':
  2443.                                         case '.':
  2444.                                         case ',':
  2445.                                         case ':':
  2446.                                         case '!':
  2447.                                         case '?':
  2448.                                         case '#':
  2449.                                         case '@':
  2450.                                         case '$':
  2451.                                         case '%':
  2452.                                         case '*':
  2453.                                         case '(':
  2454.                                         case ')':
  2455.                                         case '/':
  2456.                                         case '=':
  2457.                                         case '+':
  2458.                                         case '<':
  2459.                                         case '>':
  2460.                                         case ';':
  2461.                                         case '"':
  2462.                                         case '\'':
  2463.                                                 validkey = true;
  2464.                                                 // fall through
  2465.                                         default:
  2466.                                                 if (temp < 14 && (validkey || (lastkey_char >= 'A' && lastkey_char <= 'Z') || (lastkey_char >= '0' && lastkey_char <= '9')))
  2467.                                                 {
  2468.                                                         JE_playSampleNum(S_CURSOR);
  2469.                                                         stemp[temp] = lastkey_char;
  2470.                                                         temp++;
  2471.                                                 }
  2472.                                                 break;
  2473.                                         case SDLK_BACKSPACE:
  2474.                                         case SDLK_DELETE:
  2475.                                                 if (temp)
  2476.                                                 {
  2477.                                                         temp--;
  2478.                                                         stemp[temp] = ' ';
  2479.                                                         JE_playSampleNum(S_CLICK);
  2480.                                                 }
  2481.                                                 break;
  2482.                                         case SDLK_ESCAPE:
  2483.                                                 quit = true;
  2484.                                                 JE_playSampleNum(S_SPRING);
  2485.                                                 break;
  2486.                                         case SDLK_RETURN:
  2487.                                                 quit = true;
  2488.                                                 JE_saveGame(slot, stemp);
  2489.                                                 JE_playSampleNum(S_SELECT);
  2490.                                                 break;
  2491.                                 }
  2492.  
  2493.                         }
  2494.                 }
  2495.         }
  2496.  
  2497.         wait_noinput(false, true, false);
  2498. }
  2499.  
  2500. void JE_inGameDisplays( void )
  2501. {
  2502.         char stemp[21];
  2503.         char tempstr[256];
  2504.  
  2505.         for (uint i = 0; i < ((twoPlayerMode && !galagaMode) ? 2 : 1); ++i)
  2506.         {
  2507.                 snprintf(tempstr, sizeof(tempstr), "%lu", player[i].cash);
  2508.                 JE_textShade(VGAScreen, 30 + 200 * i, 175, tempstr, 2, 4, FULL_SHADE);
  2509.         }
  2510.  
  2511.         /*Special Weapon?*/
  2512.         if (player[0].items.special > 0)
  2513.                 blit_sprite2x2(VGAScreen, 25, 1, eShapes[5], special[player[0].items.special].itemgraphic);
  2514.  
  2515.         /*Lives Left*/
  2516.         if (onePlayerAction || twoPlayerMode)
  2517.         {
  2518.                 for (int temp = 0; temp < (onePlayerAction ? 1 : 2); temp++)
  2519.                 {
  2520.                         const uint extra_lives = *player[temp].lives - 1;
  2521.  
  2522.                         int y = (temp == 0 && player[0].items.special > 0) ? 35 : 15;
  2523.                         tempW = (temp == 0) ? 30: 270;
  2524.  
  2525.                         if (extra_lives >= 5)
  2526.                         {
  2527.                                 blit_sprite2(VGAScreen, tempW, y, shapes9, 285);
  2528.                                 tempW = (temp == 0) ? 45 : 250;
  2529.                                 sprintf(tempstr, "%d", extra_lives);
  2530.                                 JE_textShade(VGAScreen, tempW, y + 3, tempstr, 15, 1, FULL_SHADE);
  2531.                         }
  2532.                         else if (extra_lives >= 1)
  2533.                         {
  2534.                                 for (uint i = 0; i < extra_lives; ++i)
  2535.                                 {
  2536.                                         blit_sprite2(VGAScreen, tempW, y, shapes9, 285);
  2537.  
  2538.                                         tempW += (temp == 0) ? 12 : -12;
  2539.                                 }
  2540.                         }
  2541.  
  2542.                         strcpy(stemp, (temp == 0) ? miscText[49-1] : miscText[50-1]);
  2543.                         if (isNetworkGame)
  2544.                         {
  2545.                                 strcpy(stemp, JE_getName(temp+1));
  2546.                         }
  2547.  
  2548.                         tempW = (temp == 0) ? 28 : (285 - JE_textWidth(stemp, TINY_FONT));
  2549.                         JE_textShade(VGAScreen, tempW, y - 7, stemp, 2, 6, FULL_SHADE);
  2550.                 }
  2551.         }
  2552.  
  2553.         /*Super Bombs!!*/
  2554.         for (uint i = 0; i < COUNTOF(player); ++i)
  2555.         {
  2556.                 int x = (i == 0) ? 30 : 270;
  2557.  
  2558.                 for (uint j = player[i].superbombs; j > 0; --j)
  2559.                 {
  2560.                         blit_sprite2(VGAScreen, x, 160, shapes9, 304);
  2561.                         x += (i == 0) ? 12 : -12;
  2562.                 }
  2563.         }
  2564.  
  2565.         if (youAreCheating)
  2566.         {
  2567.                 JE_outText(VGAScreen, 90, 170, "Cheaters always prosper.", 3, 4);
  2568.         }
  2569. }
  2570.  
  2571. void JE_mainKeyboardInput( void )
  2572. {
  2573.         JE_gammaCheck();
  2574.  
  2575.         /* { Network Request Commands } */
  2576.  
  2577.         if (!isNetworkGame)
  2578.         {
  2579.                 /* { Edited Ships } for Player 1 */
  2580.                 if (extraAvail && keysactive[SDLK_TAB] && !isNetworkGame && !superTyrian)
  2581.                 {
  2582.                         for (x = SDLK_0; x <= SDLK_9; x++)
  2583.                         {
  2584.                                 if (keysactive[x])
  2585.                                 {
  2586.                                         int z = x == SDLK_0 ? 10 : x - SDLK_0;
  2587.                                         player[0].items.ship = 90 + z;                     /*Ships*/
  2588.                                         z = (z - 1) * 15;
  2589.                                         player[0].items.weapon[FRONT_WEAPON].id = extraShips[z + 1];
  2590.                                         player[0].items.weapon[REAR_WEAPON].id = extraShips[z + 2];
  2591.                                         player[0].items.special = extraShips[z + 3];
  2592.                                         player[0].items.sidekick[LEFT_SIDEKICK] = extraShips[z + 4];
  2593.                                         player[0].items.sidekick[RIGHT_SIDEKICK] = extraShips[z + 5];
  2594.                                         player[0].items.generator = extraShips[z + 6];
  2595.                                         /*Armor*/
  2596.                                         player[0].items.shield = extraShips[z + 8];
  2597.                                         memset(shotMultiPos, 0, sizeof(shotMultiPos));
  2598.  
  2599.                                         if (player[0].weapon_mode > JE_portConfigs())
  2600.                                                 player[0].weapon_mode = 1;
  2601.  
  2602.                                         tempW = player[0].armor;
  2603.                                         JE_getShipInfo();
  2604.                                         if (player[0].armor > tempW && editShip1)
  2605.                                                 player[0].armor = tempW;
  2606.                                         else
  2607.                                                 editShip1 = true;
  2608.  
  2609.                                         SDL_Surface *temp_surface = VGAScreen;
  2610.                                         VGAScreen = VGAScreenSeg;
  2611.                                         JE_wipeShieldArmorBars();
  2612.                                         JE_drawArmor();
  2613.                                         JE_drawShield();
  2614.                                         VGAScreen = temp_surface;
  2615.                                         JE_drawOptions();
  2616.  
  2617.                                         keysactive[x] = false;
  2618.                                 }
  2619.                         }
  2620.                 }
  2621.  
  2622.                 /* for Player 2 */
  2623.                 if (extraAvail && keysactive[SDLK_CAPSLOCK] && !isNetworkGame && !superTyrian)
  2624.                 {
  2625.                         for (x = SDLK_0; x <= SDLK_9; x++)
  2626.                         {
  2627.                                 if (keysactive[x])
  2628.                                 {
  2629.                                         int z = x == SDLK_0 ? 10 : x - SDLK_0;
  2630.                                         player[1].items.ship = 90 + z;
  2631.                                         z = (z - 1) * 15;
  2632.                                         player[1].items.weapon[FRONT_WEAPON].id = extraShips[z + 1];
  2633.                                         player[1].items.weapon[REAR_WEAPON].id = extraShips[z + 2];
  2634.                                         player[1].items.special = extraShips[z + 3];
  2635.                                         player[1].items.sidekick[LEFT_SIDEKICK] = extraShips[z + 4];
  2636.                                         player[1].items.sidekick[RIGHT_SIDEKICK] = extraShips[z + 5];
  2637.                                         player[1].items.generator = extraShips[z + 6];
  2638.                                         /*Armor*/
  2639.                                         player[1].items.shield = extraShips[z + 8];
  2640.                                         memset(shotMultiPos, 0, sizeof(shotMultiPos));
  2641.  
  2642.                                         if (player[1].weapon_mode > JE_portConfigs())
  2643.                                                 player[1].weapon_mode = 1;
  2644.  
  2645.                                         tempW = player[1].armor;
  2646.                                         JE_getShipInfo();
  2647.                                         if (player[1].armor > tempW && editShip2)
  2648.                                                 player[1].armor = tempW;
  2649.                                         else
  2650.                                                 editShip2 = true;
  2651.  
  2652.                                         SDL_Surface *temp_surface = VGAScreen;
  2653.                                         VGAScreen = VGAScreenSeg;
  2654.                                         JE_wipeShieldArmorBars();
  2655.                                         JE_drawArmor();
  2656.                                         JE_drawShield();
  2657.                                         VGAScreen = temp_surface;
  2658.                                         JE_drawOptions();
  2659.  
  2660.                                         keysactive[x] = false;
  2661.                                 }
  2662.                         }
  2663.                 }
  2664.         }
  2665.  
  2666.         /* { In-Game Help } */
  2667.         if (keysactive[SDLK_F1])
  2668.         {
  2669.                 if (isNetworkGame)
  2670.                 {
  2671.                         helpRequest = true;
  2672.                 } else {
  2673.                         JE_inGameHelp();
  2674.                         skipStarShowVGA = true;
  2675.                 }
  2676.         }
  2677.  
  2678.         /* {!Activate Nort Ship!} */
  2679.         if (keysactive[SDLK_F2] && keysactive[SDLK_F4] && keysactive[SDLK_F6] && keysactive[SDLK_F7] &&
  2680.             keysactive[SDLK_F9] && keysactive[SDLK_BACKSLASH] && keysactive[SDLK_SLASH])
  2681.         {
  2682.                 if (isNetworkGame)
  2683.                 {
  2684.                         nortShipRequest = true;
  2685.                 }
  2686.                 else
  2687.                 {
  2688.                         player[0].items.ship = 12;                     // Nort Ship
  2689.                         player[0].items.special = 13;                  // Astral Zone
  2690.                         player[0].items.weapon[FRONT_WEAPON].id = 36;  // NortShip Super Pulse
  2691.                         player[0].items.weapon[REAR_WEAPON].id = 37;   // NortShip Spreader
  2692.                         shipGr = 1;
  2693.                 }
  2694.         }
  2695.  
  2696.         /* {Cheating} */
  2697.         if (!isNetworkGame && !twoPlayerMode && !superTyrian && superArcadeMode == SA_NONE)
  2698.         {
  2699.                 if (keysactive[SDLK_F2] && keysactive[SDLK_F3] && keysactive[SDLK_F6])
  2700.                 {
  2701.                         youAreCheating = !youAreCheating;
  2702.                         keysactive[SDLK_F2] = false;
  2703.                 }
  2704.  
  2705.                 if (keysactive[SDLK_F2] && keysactive[SDLK_F3] && (keysactive[SDLK_F4] || keysactive[SDLK_F5]))
  2706.                 {
  2707.                         for (uint i = 0; i < COUNTOF(player); ++i)
  2708.                                 player[i].armor = 0;
  2709.  
  2710.                         youAreCheating = !youAreCheating;
  2711.                         JE_drawTextWindow(miscText[63-1]);
  2712.                 }
  2713.  
  2714.                 if (constantPlay && keysactive[SDLK_c])
  2715.                 {
  2716.                         youAreCheating = !youAreCheating;
  2717.                         keysactive[SDLK_c] = false;
  2718.                 }
  2719.         }
  2720.  
  2721.         if (superTyrian)
  2722.         {
  2723.                 youAreCheating = false;
  2724.         }
  2725.  
  2726.         /* {Personal Commands} */
  2727.  
  2728.         /* {DEBUG} */
  2729.         if (keysactive[SDLK_F10] && keysactive[SDLK_BACKSPACE])
  2730.         {
  2731.                 keysactive[SDLK_F10] = false;
  2732.                 debug = !debug;
  2733.  
  2734.                 debugHist = 1;
  2735.                 debugHistCount = 1;
  2736.  
  2737.                 /* YKS: clock ticks since midnight replaced by SDL_GetTicks */
  2738.                 lastDebugTime = SDL_GetTicks();
  2739.         }
  2740.  
  2741.         /* {CHEAT-SKIP LEVEL} */
  2742.         if (keysactive[SDLK_F2] && keysactive[SDLK_F6] && (keysactive[SDLK_F7] || keysactive[SDLK_F8]) && !keysactive[SDLK_F9]
  2743.             && !superTyrian && superArcadeMode == SA_NONE)
  2744.         {
  2745.                 if (isNetworkGame)
  2746.                 {
  2747.                         skipLevelRequest = true;
  2748.                 } else {
  2749.                         levelTimer = true;
  2750.                         levelTimerCountdown = 0;
  2751.                         endLevel = true;
  2752.                         levelEnd = 40;
  2753.                 }
  2754.         }
  2755.  
  2756.         /* pause game */
  2757.         pause_pressed = pause_pressed || keysactive[SDLK_p];
  2758.  
  2759.         /* in-game setup */
  2760.         ingamemenu_pressed = ingamemenu_pressed || keysactive[SDLK_ESCAPE];
  2761.  
  2762.         if (keysactive[SDLK_BACKSPACE])
  2763.         {
  2764.                 /* toggle screenshot pause */
  2765.                 if (keysactive[SDLK_NUMLOCK])
  2766.                 {
  2767.                         superPause = !superPause;
  2768.                 }
  2769.  
  2770.                 /* {SMOOTHIES} */
  2771.                 if (keysactive[SDLK_F12] && keysactive[SDLK_SCROLLOCK])
  2772.                 {
  2773.                         for (temp = SDLK_2; temp <= SDLK_9; temp++)
  2774.                         {
  2775.                                 if (keysactive[temp])
  2776.                                 {
  2777.                                         smoothies[temp-SDLK_2] = !smoothies[temp-SDLK_2];
  2778.                                 }
  2779.                         }
  2780.                         if (keysactive[SDLK_0])
  2781.                         {
  2782.                                 smoothies[8] = !smoothies[8];
  2783.                         }
  2784.                 } else
  2785.  
  2786.                 /* {CYCLE THROUGH FILTER COLORS} */
  2787.                 if (keysactive[SDLK_MINUS])
  2788.                 {
  2789.                         if (levelFilter == -99)
  2790.                         {
  2791.                                 levelFilter = 0;
  2792.                         } else {
  2793.                                 levelFilter++;
  2794.                                 if (levelFilter == 16)
  2795.                                 {
  2796.                                         levelFilter = -99;
  2797.                                 }
  2798.                         }
  2799.                 } else
  2800.  
  2801.                 /* {HYPER-SPEED} */
  2802.                 if (keysactive[SDLK_1])
  2803.                 {
  2804.                         fastPlay++;
  2805.                         if (fastPlay > 2)
  2806.                         {
  2807.                                 fastPlay = 0;
  2808.                         }
  2809.                         keysactive[SDLK_1] = false;
  2810.                         JE_setNewGameSpeed();
  2811.                 }
  2812.  
  2813.                 /* {IN-GAME RANDOM MUSIC SELECTION} */
  2814.                 if (keysactive[SDLK_SCROLLOCK])
  2815.                 {
  2816.                         play_song(mt_rand() % MUSIC_NUM);
  2817.                 }
  2818.         }
  2819. }
  2820.  
  2821. void JE_pauseGame( void )
  2822. {
  2823.         JE_boolean done = false;
  2824.         JE_word mouseX, mouseY;
  2825.  
  2826.         //tempScreenSeg = VGAScreenSeg; // sega000
  2827.         if (!superPause)
  2828.         {
  2829.                 JE_dString(VGAScreenSeg, 120, 90, miscText[22], FONT_SHAPES);
  2830.  
  2831.                 VGAScreen = VGAScreenSeg;
  2832.                 JE_showVGA();
  2833.         }
  2834.  
  2835.         set_volume(tyrMusicVolume / 2, fxVolume);
  2836.  
  2837. #ifdef WITH_NETWORK
  2838.         if (isNetworkGame)
  2839.         {
  2840.                 network_prepare(PACKET_GAME_PAUSE);
  2841.                 network_send(4);  // PACKET_GAME_PAUSE
  2842.  
  2843.                 while (true)
  2844.                 {
  2845.                         service_SDL_events(false);
  2846.  
  2847.                         if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_GAME_PAUSE)
  2848.                         {
  2849.                                 network_update();
  2850.                                 break;
  2851.                         }
  2852.  
  2853.                         network_update();
  2854.                         network_check();
  2855.  
  2856.                         uSDL_Delay(16);
  2857.                 }
  2858.         }
  2859. #endif
  2860.  
  2861.         wait_noinput(false, false, true); // TODO: should up the joystick repeat temporarily instead
  2862.  
  2863.         do
  2864.         {
  2865.                 setjasondelay(2);
  2866.  
  2867.                 push_joysticks_as_keyboard();
  2868.                 service_SDL_events(true);
  2869.  
  2870.                 if ((newkey && lastkey_sym != SDLK_LCTRL && lastkey_sym != SDLK_RCTRL && lastkey_sym != SDLK_LALT && lastkey_sym != SDLK_RALT)
  2871.                     || JE_mousePosition(&mouseX, &mouseY) > 0)
  2872.                 {
  2873. #ifdef WITH_NETWORK
  2874.                         if (isNetworkGame)
  2875.                         {
  2876.                                 network_prepare(PACKET_WAITING);
  2877.                                 network_send(4);  // PACKET_WAITING
  2878.                         }
  2879. #endif
  2880.                         done = true;
  2881.                 }
  2882.  
  2883. #ifdef WITH_NETWORK
  2884.                 if (isNetworkGame)
  2885.                 {
  2886.                         network_check();
  2887.  
  2888.                         if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_WAITING)
  2889.                         {
  2890.                                 network_check();
  2891.  
  2892.                                 done = true;
  2893.                         }
  2894.                 }
  2895. #endif
  2896.  
  2897.                 wait_delay();
  2898.         } while (!done);
  2899.  
  2900. #ifdef WITH_NETWORK
  2901.         if (isNetworkGame)
  2902.         {
  2903.                 while (!network_is_sync())
  2904.                 {
  2905.                         service_SDL_events(false);
  2906.  
  2907.                         network_check();
  2908.                         uSDL_Delay(16);
  2909.                 }
  2910.         }
  2911. #endif
  2912.  
  2913.         set_volume(tyrMusicVolume, fxVolume);
  2914.  
  2915.         //skipStarShowVGA = true;
  2916. }
  2917.  
  2918. void JE_playerMovement( Player *this_player,
  2919.                         JE_byte inputDevice,
  2920.                         JE_byte playerNum_,
  2921.                         JE_word shipGr_,
  2922.                         Sprite2_array *shapes9ptr_,
  2923.                         JE_word *mouseX_, JE_word *mouseY_ )
  2924. {
  2925.         JE_integer mouseXC, mouseYC;
  2926.         JE_integer accelXC, accelYC;
  2927.  
  2928.         if (playerNum_ == 2 || !twoPlayerMode)
  2929.         {
  2930.                 tempW = weaponPort[this_player->items.weapon[REAR_WEAPON].id].opnum;
  2931.  
  2932.                 if (this_player->weapon_mode > tempW)
  2933.                         this_player->weapon_mode = 1;
  2934.         }
  2935.  
  2936. #ifdef WITH_NETWORK
  2937.         if (isNetworkGame && thisPlayerNum == playerNum_)
  2938.         {
  2939.                 network_state_prepare();
  2940.                 memset(&packet_state_out[0]->data[4], 0, 10);
  2941.         }
  2942. #endif
  2943.  
  2944. redo:
  2945.  
  2946.         if (isNetworkGame)
  2947.         {
  2948.                 inputDevice = 0;
  2949.         }
  2950.  
  2951.         mouseXC = 0;
  2952.         mouseYC = 0;
  2953.         accelXC = 0;
  2954.         accelYC = 0;
  2955.  
  2956.         bool link_gun_analog = false;
  2957.         float link_gun_angle = 0;
  2958.  
  2959.         /* Draw Player */
  2960.         if (!this_player->is_alive)
  2961.         {
  2962.                 if (this_player->exploding_ticks > 0)
  2963.                 {
  2964.                         --this_player->exploding_ticks;
  2965.  
  2966.                         if (levelEndFxWait > 0)
  2967.                         {
  2968.                                 levelEndFxWait--;
  2969.                         }
  2970.                         else
  2971.                         {
  2972.                                 levelEndFxWait = (mt_rand() % 6) + 3;
  2973.                                 if ((mt_rand() % 3) == 1)
  2974.                                         soundQueue[6] = S_EXPLOSION_9;
  2975.                                 else
  2976.                                         soundQueue[5] = S_EXPLOSION_11;
  2977.                         }
  2978.  
  2979.                         int explosion_x = this_player->x + (mt_rand() % 32) - 16;
  2980.                         int explosion_y = this_player->y + (mt_rand() % 32) - 16;
  2981.                         JE_setupExplosionLarge(false, 0, explosion_x, explosion_y + 7);
  2982.                         JE_setupExplosionLarge(false, 0, this_player->x, this_player->y + 7);
  2983.  
  2984.                         if (levelEnd > 0)
  2985.                                 levelEnd--;
  2986.                 }
  2987.                 else
  2988.                 {
  2989.                         if (twoPlayerMode || onePlayerAction)  // if arcade mode
  2990.                         {
  2991.                                 if (*this_player->lives > 1)  // respawn if any extra lives
  2992.                                 {
  2993.                                         --(*this_player->lives);
  2994.  
  2995.                                         reallyEndLevel = false;
  2996.                                         shotMultiPos[playerNum_-1] = 0;
  2997.                                         calc_purple_balls_needed(this_player);
  2998.                                         twoPlayerLinked = false;
  2999.                                         if (galagaMode)
  3000.                                                 twoPlayerMode = false;
  3001.                                         this_player->y = 160;
  3002.                                         this_player->invulnerable_ticks = 100;
  3003.                                         this_player->is_alive = true;
  3004.                                         endLevel = false;
  3005.  
  3006.                                         if (galagaMode || episodeNum == 4)
  3007.                                                 this_player->armor = this_player->initial_armor;
  3008.                                         else
  3009.                                                 this_player->armor = this_player->initial_armor / 2;
  3010.  
  3011.                                         if (galagaMode)
  3012.                                                 this_player->shield = 0;
  3013.                                         else
  3014.                                                 this_player->shield = this_player->shield_max / 2;
  3015.  
  3016.                                         VGAScreen = VGAScreenSeg; /* side-effect of game_screen */
  3017.                                         JE_drawArmor();
  3018.                                         JE_drawShield();
  3019.                                         VGAScreen = game_screen; /* side-effect of game_screen */
  3020.                                         goto redo;
  3021.                                 }
  3022.                                 else
  3023.                                 {
  3024.                                         if (galagaMode)
  3025.                                                 twoPlayerMode = false;
  3026.                                         if (allPlayersGone && isNetworkGame)
  3027.                                                 reallyEndLevel = true;
  3028.                                 }
  3029.  
  3030.                         }
  3031.                 }
  3032.         }
  3033.         else if (constantDie)
  3034.         {
  3035.                 // finished exploding?  start dying again
  3036.                 if (this_player->exploding_ticks == 0)
  3037.                 {
  3038.                         this_player->shield = 0;
  3039.  
  3040.                         if (this_player->armor > 0)
  3041.                         {
  3042.                                 --this_player->armor;
  3043.                         }
  3044.                         else
  3045.                         {
  3046.                                 this_player->is_alive = false;
  3047.                                 this_player->exploding_ticks = 60;
  3048.                                 levelEnd = 40;
  3049.                         }
  3050.  
  3051.                         JE_wipeShieldArmorBars();
  3052.                         VGAScreen = VGAScreenSeg; /* side-effect of game_screen */
  3053.                         JE_drawArmor();
  3054.                         VGAScreen = game_screen; /* side-effect of game_screen */
  3055.  
  3056.                         // as if instant death weren't enough, player also gets infinite lives in order to enjoy an infinite number of deaths -_-
  3057.                         if (*player[0].lives < 11)
  3058.                                 ++(*player[0].lives);
  3059.                 }
  3060.         }
  3061.  
  3062.  
  3063.         if (!this_player->is_alive)
  3064.         {
  3065.                 explosionFollowAmountX = explosionFollowAmountY = 0;
  3066.                 return;
  3067.         }
  3068.  
  3069.         if (!endLevel)
  3070.         {
  3071.                 *mouseX_ = this_player->x;
  3072.                 *mouseY_ = this_player->y;
  3073.                 button[1-1] = false;
  3074.                 button[2-1] = false;
  3075.                 button[3-1] = false;
  3076.                 button[4-1] = false;
  3077.  
  3078.                 /* --- Movement Routine Beginning --- */
  3079.  
  3080.                 if (!isNetworkGame || playerNum_ == thisPlayerNum)
  3081.                 {
  3082.                         if (endLevel)
  3083.                         {
  3084.                                 this_player->y -= 2;
  3085.                         }
  3086.                         else
  3087.                         {
  3088.                                 if (record_demo || play_demo)
  3089.                                         inputDevice = 1;  // keyboard is required device for demo recording
  3090.  
  3091.                                 // demo playback input
  3092.                                 if (play_demo)
  3093.                                 {
  3094.                                         if (!replay_demo_keys())
  3095.                                         {
  3096.                                                 endLevel = true;
  3097.                                                 levelEnd = 40;
  3098.                                         }
  3099.                                 }
  3100.  
  3101.                                 /* joystick input */
  3102.                                 if ((inputDevice == 0 || inputDevice >= 3) && joysticks > 0)
  3103.                                 {
  3104.                                         int j = inputDevice  == 0 ? 0 : inputDevice - 3;
  3105.                                         int j_max = inputDevice == 0 ? joysticks : inputDevice - 3 + 1;
  3106.                                         for (; j < j_max; j++)
  3107.                                         {
  3108.                                                 poll_joystick(j);
  3109.  
  3110.                                                 if (joystick[j].analog)
  3111.                                                 {
  3112.                                                         mouseXC += joystick_axis_reduce(j, joystick[j].x);
  3113.                                                         mouseYC += joystick_axis_reduce(j, joystick[j].y);
  3114.  
  3115.                                                         link_gun_analog = joystick_analog_angle(j, &link_gun_angle);
  3116.                                                 }
  3117.                                                 else
  3118.                                                 {
  3119.                                                         this_player->x += (joystick[j].direction[3] ? -CURRENT_KEY_SPEED : 0) + (joystick[j].direction[1] ? CURRENT_KEY_SPEED : 0);
  3120.                                                         this_player->y += (joystick[j].direction[0] ? -CURRENT_KEY_SPEED : 0) + (joystick[j].direction[2] ? CURRENT_KEY_SPEED : 0);
  3121.                                                 }
  3122.  
  3123.                                                 button[0] |= joystick[j].action[0];
  3124.                                                 button[1] |= joystick[j].action[2];
  3125.                                                 button[2] |= joystick[j].action[3];
  3126.                                                 button[3] |= joystick[j].action_pressed[1];
  3127.  
  3128.                                                 ingamemenu_pressed |= joystick[j].action_pressed[4];
  3129.                                                 pause_pressed |= joystick[j].action_pressed[5];
  3130.                                         }
  3131.                                 }
  3132.  
  3133.                                 service_SDL_events(false);
  3134.  
  3135.                                 /* mouse input */
  3136.                                 if ((inputDevice == 0 || inputDevice == 2) && has_mouse)
  3137.                                 {
  3138.                                         button[0] |= mouse_pressed[0];
  3139.                                         button[1] |= mouse_pressed[1];
  3140.                                         button[2] |= mouse_has_three_buttons ? mouse_pressed[2] : mouse_pressed[1];
  3141.  
  3142.                                         if (input_grab_enabled)
  3143.                                         {
  3144.                                                 mouseXC += mouse_x - 159;
  3145.                                                 mouseYC += mouse_y - 100;
  3146.                                         }
  3147.  
  3148.                                         if ((!isNetworkGame || playerNum_ == thisPlayerNum)
  3149.                                             && (!galagaMode || (playerNum_ == 2 || !twoPlayerMode || player[1].exploding_ticks > 0)))
  3150.                                         {
  3151.                                                 set_mouse_position(159, 100);
  3152.                                         }
  3153.                                 }
  3154.  
  3155.                                 /* keyboard input */
  3156.                                 if ((inputDevice == 0 || inputDevice == 1) && !play_demo)
  3157.                                 {
  3158.                                         if (keysactive[keySettings[0]])
  3159.                                                 this_player->y -= CURRENT_KEY_SPEED;
  3160.                                         if (keysactive[keySettings[1]])
  3161.                                                 this_player->y += CURRENT_KEY_SPEED;
  3162.  
  3163.                                         if (keysactive[keySettings[2]])
  3164.                                                 this_player->x -= CURRENT_KEY_SPEED;
  3165.                                         if (keysactive[keySettings[3]])
  3166.                                                 this_player->x += CURRENT_KEY_SPEED;
  3167.  
  3168.                                         button[0] = button[0] || keysactive[keySettings[4]];
  3169.                                         button[3] = button[3] || keysactive[keySettings[5]];
  3170.                                         button[1] = button[1] || keysactive[keySettings[6]];
  3171.                                         button[2] = button[2] || keysactive[keySettings[7]];
  3172.  
  3173.                                         if (constantPlay)
  3174.                                         {
  3175.                                                 for (unsigned int i = 0; i < 4; i++)
  3176.                                                         button[i] = true;
  3177.  
  3178.                                                 ++this_player->y;
  3179.                                                 this_player->x += constantLastX;
  3180.                                         }
  3181.  
  3182.                                         // TODO: check if demo recording still works
  3183.                                         if (record_demo)
  3184.                                         {
  3185.                                                 bool new_input = false;
  3186.  
  3187.                                                 for (unsigned int i = 0; i < 8; i++)
  3188.                                                 {
  3189.                                                         bool temp = demo_keys & (1 << i);
  3190.                                                         if (temp != keysactive[keySettings[i]])
  3191.                                                                 new_input = true;
  3192.                                                 }
  3193.  
  3194.                                                 demo_keys_wait++;
  3195.  
  3196.                                                 if (new_input)
  3197.                                                 {
  3198.                                                         demo_keys_wait = SDL_Swap16(demo_keys_wait);
  3199.                                                         efwrite(&demo_keys_wait, sizeof(Uint16), 1, demo_file);
  3200.  
  3201.                                                         demo_keys = 0;
  3202.                                                         for (unsigned int i = 0; i < 8; i++)
  3203.                                                                 demo_keys |= keysactive[keySettings[i]] ? (1 << i) : 0;
  3204.  
  3205.                                                         fputc(demo_keys, demo_file);
  3206.  
  3207.                                                         demo_keys_wait = 0;
  3208.                                                 }
  3209.                                         }
  3210.                                 }
  3211.  
  3212.                                 if (smoothies[9-1])
  3213.                                 {
  3214.                                         *mouseY_ = this_player->y - (*mouseY_ - this_player->y);
  3215.                                         mouseYC = -mouseYC;
  3216.                                 }
  3217.  
  3218.                                 accelXC += this_player->x - *mouseX_;
  3219.                                 accelYC += this_player->y - *mouseY_;
  3220.  
  3221.                                 if (mouseXC > 30)
  3222.                                         mouseXC = 30;
  3223.                                 else if (mouseXC < -30)
  3224.                                         mouseXC = -30;
  3225.                                 if (mouseYC > 30)
  3226.                                         mouseYC = 30;
  3227.                                 else if (mouseYC < -30)
  3228.                                         mouseYC = -30;
  3229.  
  3230.                                 if (mouseXC > 0)
  3231.                                         this_player->x += (mouseXC + 3) / 4;
  3232.                                 else if (mouseXC < 0)
  3233.                                         this_player->x += (mouseXC - 3) / 4;
  3234.                                 if (mouseYC > 0)
  3235.                                         this_player->y += (mouseYC + 3) / 4;
  3236.                                 else if (mouseYC < 0)
  3237.                                         this_player->y += (mouseYC - 3) / 4;
  3238.  
  3239.                                 if (mouseXC > 3)
  3240.                                         accelXC++;
  3241.                                 else if (mouseXC < -2)
  3242.                                         accelXC--;
  3243.                                 if (mouseYC > 2)
  3244.                                         accelYC++;
  3245.                                 else if (mouseYC < -2)
  3246.                                         accelYC--;
  3247.  
  3248.                         }   /*endLevel*/
  3249.  
  3250. #ifdef WITH_NETWORK
  3251.                         if (isNetworkGame && playerNum_ == thisPlayerNum)
  3252.                         {
  3253.                                 Uint16 buttons = 0;
  3254.                                 for (int i = 4 - 1; i >= 0; i--)
  3255.                                 {
  3256.                                         buttons <<= 1;
  3257.                                         buttons |= button[i];
  3258.                                 }
  3259.  
  3260.                                 SDLNet_Write16(this_player->x - *mouseX_, &packet_state_out[0]->data[4]);
  3261.                                 SDLNet_Write16(this_player->y - *mouseY_, &packet_state_out[0]->data[6]);
  3262.                                 SDLNet_Write16(accelXC,                   &packet_state_out[0]->data[8]);
  3263.                                 SDLNet_Write16(accelYC,                   &packet_state_out[0]->data[10]);
  3264.                                 SDLNet_Write16(buttons,                   &packet_state_out[0]->data[12]);
  3265.  
  3266.                                 this_player->x = *mouseX_;
  3267.                                 this_player->y = *mouseY_;
  3268.  
  3269.                                 button[0] = false;
  3270.                                 button[1] = false;
  3271.                                 button[2] = false;
  3272.                                 button[3] = false;
  3273.  
  3274.                                 accelXC = 0;
  3275.                                 accelYC = 0;
  3276.                         }
  3277. #endif
  3278.                 }  /*isNetworkGame*/
  3279.  
  3280.                 /* --- Movement Routine Ending --- */
  3281.  
  3282.                 moveOk = true;
  3283.  
  3284. #ifdef WITH_NETWORK
  3285.                 if (isNetworkGame && !network_state_is_reset())
  3286.                 {
  3287.                         if (playerNum_ != thisPlayerNum)
  3288.                         {
  3289.                                 if (thisPlayerNum == 2)
  3290.                                         difficultyLevel = SDLNet_Read16(&packet_state_in[0]->data[16]);
  3291.  
  3292.                                 Uint16 buttons = SDLNet_Read16(&packet_state_in[0]->data[12]);
  3293.                                 for (int i = 0; i < 4; i++)
  3294.                                 {
  3295.                                         button[i] = buttons & 1;
  3296.                                         buttons >>= 1;
  3297.                                 }
  3298.  
  3299.                                 this_player->x += (Sint16)SDLNet_Read16(&packet_state_in[0]->data[4]);
  3300.                                 this_player->y += (Sint16)SDLNet_Read16(&packet_state_in[0]->data[6]);
  3301.                                 accelXC = (Sint16)SDLNet_Read16(&packet_state_in[0]->data[8]);
  3302.                                 accelYC = (Sint16)SDLNet_Read16(&packet_state_in[0]->data[10]);
  3303.                         }
  3304.                         else
  3305.                         {
  3306.                                 Uint16 buttons = SDLNet_Read16(&packet_state_out[network_delay]->data[12]);
  3307.                                 for (int i = 0; i < 4; i++)
  3308.                                 {
  3309.                                         button[i] = buttons & 1;
  3310.                                         buttons >>= 1;
  3311.                                 }
  3312.  
  3313.                                 this_player->x += (Sint16)SDLNet_Read16(&packet_state_out[network_delay]->data[4]);
  3314.                                 this_player->y += (Sint16)SDLNet_Read16(&packet_state_out[network_delay]->data[6]);
  3315.                                 accelXC = (Sint16)SDLNet_Read16(&packet_state_out[network_delay]->data[8]);
  3316.                                 accelYC = (Sint16)SDLNet_Read16(&packet_state_out[network_delay]->data[10]);
  3317.                         }
  3318.                 }
  3319. #endif
  3320.  
  3321.                 /*Street-Fighter codes*/
  3322.                 JE_SFCodes(playerNum_, this_player->x, this_player->y, *mouseX_, *mouseY_);
  3323.  
  3324.                 if (moveOk)
  3325.                 {
  3326.                         /* END OF MOVEMENT ROUTINES */
  3327.  
  3328.                         /*Linking Routines*/
  3329.  
  3330.                         if (twoPlayerMode && !twoPlayerLinked && this_player->x == *mouseX_ && this_player->y == *mouseY_
  3331.                             && abs(player[0].x - player[1].x) < 8 && abs(player[0].y - player[1].y) < 8
  3332.                             && player[0].is_alive && player[1].is_alive && !galagaMode)
  3333.                         {
  3334.                                 twoPlayerLinked = true;
  3335.                         }
  3336.  
  3337.                         if (playerNum_ == 1 && (button[3-1] || button[2-1]) && !galagaMode)
  3338.                                 twoPlayerLinked = false;
  3339.  
  3340.                         if (twoPlayerMode && twoPlayerLinked && playerNum_ == 2
  3341.                             && (this_player->x != *mouseX_ || this_player->y != *mouseY_))
  3342.                         {
  3343.                                 if (button[0])
  3344.                                 {
  3345.                                         if (link_gun_analog)
  3346.                                         {
  3347.                                                 linkGunDirec = link_gun_angle;
  3348.                                         }
  3349.                                         else
  3350.                                         {
  3351.                                                 JE_real tempR;
  3352.  
  3353.                                                 if (abs(this_player->x - *mouseX_) > abs(this_player->y - *mouseY_))
  3354.                                                         tempR = (this_player->x - *mouseX_ > 0) ? M_PI_2 : (M_PI + M_PI_2);
  3355.                                                 else
  3356.                                                         tempR = (this_player->y - *mouseY_ > 0) ? 0 : M_PI;
  3357.  
  3358.                                                 if (fabsf(linkGunDirec - tempR) < 0.3f)
  3359.                                                         linkGunDirec = tempR;
  3360.                                                 else if (linkGunDirec < tempR && linkGunDirec - tempR > -3.24f)
  3361.                                                         linkGunDirec += 0.2f;
  3362.                                                 else if (linkGunDirec - tempR < M_PI)
  3363.                                                         linkGunDirec -= 0.2f;
  3364.                                                 else
  3365.                                                         linkGunDirec += 0.2f;
  3366.                                         }
  3367.  
  3368.                                         if (linkGunDirec >= (2 * M_PI))
  3369.                                                 linkGunDirec -= (2 * M_PI);
  3370.                                         else if (linkGunDirec < 0)
  3371.                                                 linkGunDirec += (2 * M_PI);
  3372.                                 }
  3373.                                 else if (!galagaMode)
  3374.                                 {
  3375.                                         twoPlayerLinked = false;
  3376.                                 }
  3377.                         }
  3378.                 }
  3379.         }
  3380.  
  3381.         if (levelEnd > 0 && all_players_dead())
  3382.                 reallyEndLevel = true;
  3383.  
  3384.         /* End Level Fade-Out */
  3385.         if (this_player->is_alive && endLevel)
  3386.         {
  3387.                 if (levelEnd == 0)
  3388.                 {
  3389.                         reallyEndLevel = true;
  3390.                 }
  3391.                 else
  3392.                 {
  3393.                         this_player->y -= levelEndWarp;
  3394.                         if (this_player->y < -200)
  3395.                                 reallyEndLevel = true;
  3396.  
  3397.                         int trail_spacing = 1;
  3398.                         int trail_y = this_player->y;
  3399.                         int num_trails = abs(41 - levelEnd);
  3400.                         if (num_trails > 20)
  3401.                                 num_trails = 20;
  3402.  
  3403.                         for (int i = 0; i < num_trails; i++)
  3404.                         {
  3405.                                 trail_y += trail_spacing;
  3406.                                 trail_spacing++;
  3407.                         }
  3408.  
  3409.                         for (int i = 1; i < num_trails; i++)
  3410.                         {
  3411.                                 trail_y -= trail_spacing;
  3412.                                 trail_spacing--;
  3413.  
  3414.                                 if (trail_y > 0 && trail_y < 170)
  3415.                                 {
  3416.                                         if (shipGr_ == 0)
  3417.                                         {
  3418.                                                 blit_sprite2x2(VGAScreen, this_player->x - 17, trail_y - 7, *shapes9ptr_, 13);
  3419.                                                 blit_sprite2x2(VGAScreen, this_player->x + 7 , trail_y - 7, *shapes9ptr_, 51);
  3420.                                         }
  3421.                                         else if (shipGr_ == 1)
  3422.                                         {
  3423.                                                 blit_sprite2x2(VGAScreen, this_player->x - 17, trail_y - 7, *shapes9ptr_, 220);
  3424.                                                 blit_sprite2x2(VGAScreen, this_player->x + 7 , trail_y - 7, *shapes9ptr_, 222);
  3425.                                         }
  3426.                                         else
  3427.                                         {
  3428.                                                 blit_sprite2x2(VGAScreen, this_player->x - 5, trail_y - 7, *shapes9ptr_, shipGr_);
  3429.                                         }
  3430.                                 }
  3431.                         }
  3432.                 }
  3433.         }
  3434.  
  3435.         if (play_demo)
  3436.                 JE_dString(VGAScreen, 115, 10, miscText[7], SMALL_FONT_SHAPES); // insert coin
  3437.  
  3438.         if (this_player->is_alive && !endLevel)
  3439.         {
  3440.                 if (!twoPlayerLinked || playerNum_ < 2)
  3441.                 {
  3442.                         if (!twoPlayerMode || shipGr2 != 0)  // if not dragonwing
  3443.                         {
  3444.                                 if (this_player->sidekick[LEFT_SIDEKICK].style == 0)
  3445.                                 {
  3446.                                         this_player->sidekick[LEFT_SIDEKICK].x = *mouseX_ - 14;
  3447.                                         this_player->sidekick[LEFT_SIDEKICK].y = *mouseY_;
  3448.                                 }
  3449.  
  3450.                                 if (this_player->sidekick[RIGHT_SIDEKICK].style == 0)
  3451.                                 {
  3452.                                         this_player->sidekick[RIGHT_SIDEKICK].x = *mouseX_ + 16;
  3453.                                         this_player->sidekick[RIGHT_SIDEKICK].y = *mouseY_;
  3454.                                 }
  3455.                         }
  3456.  
  3457.                         if (this_player->x_friction_ticks > 0)
  3458.                         {
  3459.                                 --this_player->x_friction_ticks;
  3460.                         }
  3461.                         else
  3462.                         {
  3463.                                 this_player->x_friction_ticks = 1;
  3464.  
  3465.                                 if (this_player->x_velocity < 0)
  3466.                                         ++this_player->x_velocity;
  3467.                                 else if (this_player->x_velocity > 0)
  3468.                                         --this_player->x_velocity;
  3469.                         }
  3470.  
  3471.                         if (this_player->y_friction_ticks > 0)
  3472.                         {
  3473.                                 --this_player->y_friction_ticks;
  3474.                         }
  3475.                         else
  3476.                         {
  3477.                                 this_player->y_friction_ticks = 2;
  3478.  
  3479.                                 if (this_player->y_velocity < 0)
  3480.                                         ++this_player->y_velocity;
  3481.                                 else if (this_player->y_velocity > 0)
  3482.                                         --this_player->y_velocity;
  3483.                         }
  3484.  
  3485.                         this_player->x_velocity += accelXC;
  3486.                         this_player->y_velocity += accelYC;
  3487.  
  3488.                         this_player->x_velocity = MIN(MAX(-4, this_player->x_velocity), 4);
  3489.                         this_player->y_velocity = MIN(MAX(-4, this_player->y_velocity), 4);
  3490.  
  3491.                         this_player->x += this_player->x_velocity;
  3492.                         this_player->y += this_player->y_velocity;
  3493.  
  3494.                         // if player moved, add new ship x, y history entry
  3495.                         if (this_player->x - *mouseX_ != 0 || this_player->y - *mouseY_ != 0)
  3496.                         {
  3497.                                 for (uint i = 1; i < COUNTOF(player->old_x); ++i)
  3498.                                 {
  3499.                                         this_player->old_x[i - 1] = this_player->old_x[i];
  3500.                                         this_player->old_y[i - 1] = this_player->old_y[i];
  3501.                                 }
  3502.                                 this_player->old_x[COUNTOF(player->old_x) - 1] = this_player->x;
  3503.                                 this_player->old_y[COUNTOF(player->old_x) - 1] = this_player->y;
  3504.                         }
  3505.                 }
  3506.                 else  /*twoPlayerLinked*/
  3507.                 {
  3508.                         if (shipGr_ == 0)
  3509.                                 this_player->x = player[0].x - 1;
  3510.                         else
  3511.                                 this_player->x = player[0].x;
  3512.                         this_player->y = player[0].y + 8;
  3513.  
  3514.                         this_player->x_velocity = player[0].x_velocity;
  3515.                         this_player->y_velocity = 4;
  3516.  
  3517.                         // turret direction marker/shield
  3518.                         shotMultiPos[SHOT_MISC] = 0;
  3519.                         b = player_shot_create(0, SHOT_MISC, this_player->x + 1 + roundf(sinf(linkGunDirec + 0.2f) * 26), this_player->y + roundf(cosf(linkGunDirec + 0.2f) * 26), *mouseX_, *mouseY_, 148, playerNum_);
  3520.                         shotMultiPos[SHOT_MISC] = 0;
  3521.                         b = player_shot_create(0, SHOT_MISC, this_player->x + 1 + roundf(sinf(linkGunDirec - 0.2f) * 26), this_player->y + roundf(cosf(linkGunDirec - 0.2f) * 26), *mouseX_, *mouseY_, 148, playerNum_);
  3522.                         shotMultiPos[SHOT_MISC] = 0;
  3523.                         b = player_shot_create(0, SHOT_MISC, this_player->x + 1 + roundf(sinf(linkGunDirec) * 26), this_player->y + roundf(cosf(linkGunDirec) * 26), *mouseX_, *mouseY_, 147, playerNum_);
  3524.  
  3525.                         if (shotRepeat[SHOT_REAR] > 0)
  3526.                         {
  3527.                                 --shotRepeat[SHOT_REAR];
  3528.                         }
  3529.                         else if (button[1-1])
  3530.                         {
  3531.                                 shotMultiPos[SHOT_REAR] = 0;
  3532.                                 b = player_shot_create(0, SHOT_REAR, this_player->x + 1 + roundf(sinf(linkGunDirec) * 20), this_player->y + roundf(cosf(linkGunDirec) * 20), *mouseX_, *mouseY_, linkGunWeapons[this_player->items.weapon[REAR_WEAPON].id-1], playerNum_);
  3533.                                 player_shot_set_direction(b, this_player->items.weapon[REAR_WEAPON].id, linkGunDirec);
  3534.                         }
  3535.                 }
  3536.         }
  3537.  
  3538.         if (!endLevel)
  3539.         {
  3540.                 if (this_player->x > 256)
  3541.                 {
  3542.                         this_player->x = 256;
  3543.                         constantLastX = -constantLastX;
  3544.                 }
  3545.                 if (this_player->x < 40)
  3546.                 {
  3547.                         this_player->x = 40;
  3548.                         constantLastX = -constantLastX;
  3549.                 }
  3550.  
  3551.                 if (isNetworkGame && playerNum_ == 1)
  3552.                 {
  3553.                         if (this_player->y > 154)
  3554.                                 this_player->y = 154;
  3555.                 }
  3556.                 else
  3557.                 {
  3558.                         if (this_player->y > 160)
  3559.                                 this_player->y = 160;
  3560.                 }
  3561.  
  3562.                 if (this_player->y < 10)
  3563.                         this_player->y = 10;
  3564.  
  3565.                 // Determines the ship banking sprite to display, depending on horizontal velocity and acceleration
  3566.                 int ship_banking = this_player->x_velocity / 2 + (this_player->x - *mouseX_) / 6;
  3567.                 ship_banking = MAX(-2, MIN(ship_banking, 2));
  3568.  
  3569.                 int ship_sprite = ship_banking * 2 + shipGr_;
  3570.  
  3571.                 explosionFollowAmountX = this_player->x - this_player->last_x_explosion_follow;
  3572.                 explosionFollowAmountY = this_player->y - this_player->last_y_explosion_follow;
  3573.  
  3574.                 if (explosionFollowAmountY < 0)
  3575.                         explosionFollowAmountY = 0;
  3576.  
  3577.                 this_player->last_x_explosion_follow = this_player->x;
  3578.                 this_player->last_y_explosion_follow = this_player->y;
  3579.  
  3580.                 if (shipGr_ == 0)
  3581.                 {
  3582.                         if (background2)
  3583.                         {
  3584.                                 blit_sprite2x2_darken(VGAScreen, this_player->x - 17 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite + 13);
  3585.                                 blit_sprite2x2_darken(VGAScreen, this_player->x + 7 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite + 51);
  3586.                                 if (superWild)
  3587.                                 {
  3588.                                         blit_sprite2x2_darken(VGAScreen, this_player->x - 16 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite + 13);
  3589.                                         blit_sprite2x2_darken(VGAScreen, this_player->x + 6 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite + 51);
  3590.                                 }
  3591.                         }
  3592.                 }
  3593.                 else if (shipGr_ == 1)
  3594.                 {
  3595.                         if (background2)
  3596.                         {
  3597.                                 blit_sprite2x2_darken(VGAScreen, this_player->x - 17 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, 220);
  3598.                                 blit_sprite2x2_darken(VGAScreen, this_player->x + 7 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, 222);
  3599.                         }
  3600.                 }
  3601.                 else
  3602.                 {
  3603.                         if (background2)
  3604.                         {
  3605.                                 blit_sprite2x2_darken(VGAScreen, this_player->x - 5 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite);
  3606.                                 if (superWild)
  3607.                                 {
  3608.                                         blit_sprite2x2_darken(VGAScreen, this_player->x - 4 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, ship_sprite);
  3609.                                 }
  3610.                         }
  3611.                 }
  3612.  
  3613.                 if (this_player->invulnerable_ticks > 0)
  3614.                 {
  3615.                         --this_player->invulnerable_ticks;
  3616.  
  3617.                         if (shipGr_ == 0)
  3618.                         {
  3619.                                 blit_sprite2x2_blend(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, ship_sprite + 13);
  3620.                                 blit_sprite2x2_blend(VGAScreen, this_player->x + 7 , this_player->y - 7, *shapes9ptr_, ship_sprite + 51);
  3621.                         }
  3622.                         else if (shipGr_ == 1)
  3623.                         {
  3624.                                 blit_sprite2x2_blend(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, 220);
  3625.                                 blit_sprite2x2_blend(VGAScreen, this_player->x + 7 , this_player->y - 7, *shapes9ptr_, 222);
  3626.                         }
  3627.                         else
  3628.                                 blit_sprite2x2_blend(VGAScreen, this_player->x - 5, this_player->y - 7, *shapes9ptr_, ship_sprite);
  3629.                 }
  3630.                 else
  3631.                 {
  3632.                         if (shipGr_ == 0)
  3633.                         {
  3634.                                 blit_sprite2x2(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, ship_sprite + 13);
  3635.                                 blit_sprite2x2(VGAScreen, this_player->x + 7, this_player->y - 7, *shapes9ptr_, ship_sprite + 51);
  3636.                         }
  3637.                         else if (shipGr_ == 1)
  3638.                         {
  3639.                                 blit_sprite2x2(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, 220);
  3640.                                 blit_sprite2x2(VGAScreen, this_player->x + 7, this_player->y - 7, *shapes9ptr_, 222);
  3641.  
  3642.                                 int ship_banking = 0;
  3643.                                 switch (ship_sprite)
  3644.                                 {
  3645.                                 case 5:
  3646.                                         blit_sprite2(VGAScreen, this_player->x - 17, this_player->y + 7, *shapes9ptr_, 40);
  3647.                                         tempW = this_player->x - 7;
  3648.                                         ship_banking = -2;
  3649.                                         break;
  3650.                                 case 3:
  3651.                                         blit_sprite2(VGAScreen, this_player->x - 17, this_player->y + 7, *shapes9ptr_, 39);
  3652.                                         tempW = this_player->x - 7;
  3653.                                         ship_banking = -1;
  3654.                                         break;
  3655.                                 case 1:
  3656.                                         ship_banking = 0;
  3657.                                         break;
  3658.                                 case -1:
  3659.                                         blit_sprite2(VGAScreen, this_player->x + 19, this_player->y + 7, *shapes9ptr_, 58);
  3660.                                         tempW = this_player->x + 9;
  3661.                                         ship_banking = 1;
  3662.                                         break;
  3663.                                 case -3:
  3664.                                         blit_sprite2(VGAScreen, this_player->x + 19, this_player->y + 7, *shapes9ptr_, 59);
  3665.                                         tempW = this_player->x + 9;
  3666.                                         ship_banking = 2;
  3667.                                         break;
  3668.                                 }
  3669.                                 if (ship_banking != 0)  // NortSparks
  3670.                                 {
  3671.                                         if (shotRepeat[SHOT_NORTSPARKS] > 0)
  3672.                                         {
  3673.                                                 --shotRepeat[SHOT_NORTSPARKS];
  3674.                                         }
  3675.                                         else
  3676.                                         {
  3677.                                                 b = player_shot_create(0, SHOT_NORTSPARKS, tempW + (mt_rand() % 8) - 4, this_player->y + (mt_rand() % 8) - 4, *mouseX_, *mouseY_, 671, 1);
  3678.                                                 shotRepeat[SHOT_NORTSPARKS] = abs(ship_banking) - 1;
  3679.                                         }
  3680.                                 }
  3681.                         }
  3682.                         else
  3683.                         {
  3684.                                 blit_sprite2x2(VGAScreen, this_player->x - 5, this_player->y - 7, *shapes9ptr_, ship_sprite);
  3685.                         }
  3686.                 }
  3687.  
  3688.                 /*Options Location*/
  3689.                 if (playerNum_ == 2 && shipGr_ == 0)  // if dragonwing
  3690.                 {
  3691.                         if (this_player->sidekick[LEFT_SIDEKICK].style == 0)
  3692.                         {
  3693.                                 this_player->sidekick[LEFT_SIDEKICK].x = this_player->x - 14 + ship_banking * 2;
  3694.                                 this_player->sidekick[LEFT_SIDEKICK].y = this_player->y;
  3695.                         }
  3696.  
  3697.                         if (this_player->sidekick[RIGHT_SIDEKICK].style == 0)
  3698.                         {
  3699.                                 this_player->sidekick[RIGHT_SIDEKICK].x = this_player->x + 17 + ship_banking * 2;
  3700.                                 this_player->sidekick[RIGHT_SIDEKICK].y = this_player->y;
  3701.                         }
  3702.                 }
  3703.         }  // !endLevel
  3704.  
  3705.         if (moveOk)
  3706.         {
  3707.                 if (this_player->is_alive)
  3708.                 {
  3709.                         if (!endLevel)
  3710.                         {
  3711.                                 this_player->delta_x_shot_move = this_player->x - this_player->last_x_shot_move;
  3712.                                 this_player->delta_y_shot_move = this_player->y - this_player->last_y_shot_move;
  3713.  
  3714.                                 /* PLAYER SHOT Change */
  3715.                                 if (button[4-1])
  3716.                                 {
  3717.                                         portConfigChange = true;
  3718.                                         if (portConfigDone)
  3719.                                         {
  3720.                                                 shotMultiPos[SHOT_REAR] = 0;
  3721.  
  3722.                                                 if (superArcadeMode != SA_NONE && superArcadeMode <= SA_NORTSHIPZ)
  3723.                                                 {
  3724.                                                         shotMultiPos[SHOT_SPECIAL] = 0;
  3725.                                                         shotMultiPos[SHOT_SPECIAL2] = 0;
  3726.                                                         if (player[0].items.special == SASpecialWeapon[superArcadeMode-1])
  3727.                                                         {
  3728.                                                                 player[0].items.special = SASpecialWeaponB[superArcadeMode-1];
  3729.                                                                 this_player->weapon_mode = 2;
  3730.                                                         }
  3731.                                                         else
  3732.                                                         {
  3733.                                                                 player[0].items.special = SASpecialWeapon[superArcadeMode-1];
  3734.                                                                 this_player->weapon_mode = 1;
  3735.                                                         }
  3736.                                                 }
  3737.                                                 else if (++this_player->weapon_mode > JE_portConfigs())
  3738.                                                         this_player->weapon_mode = 1;
  3739.  
  3740.                                                 JE_drawPortConfigButtons();
  3741.                                                 portConfigDone = false;
  3742.                                         }
  3743.                                 }
  3744.  
  3745.                                 /* PLAYER SHOT Creation */
  3746.  
  3747.                                 /*SpecialShot*/
  3748.                                 if (!galagaMode)
  3749.                                         JE_doSpecialShot(playerNum_, &this_player->armor, &this_player->shield);
  3750.  
  3751.                                 /*Normal Main Weapons*/
  3752.                                 if (!(twoPlayerLinked && playerNum_ == 2))
  3753.                                 {
  3754.                                         int min, max;
  3755.  
  3756.                                         if (!twoPlayerMode)
  3757.                                                 min = 1, max = 2;
  3758.                                         else
  3759.                                                 min = max = playerNum_;
  3760.  
  3761.                                         for (temp = min - 1; temp < max; temp++)
  3762.                                         {
  3763.                                                 const uint item = this_player->items.weapon[temp].id;
  3764.  
  3765.                                                 if (item > 0)
  3766.                                                 {
  3767.                                                         if (shotRepeat[temp] > 0)
  3768.                                                         {
  3769.                                                                 --shotRepeat[temp];
  3770.                                                         }
  3771.                                                         else if (button[1-1])
  3772.                                                         {
  3773.                                                                 const uint item_power = galagaMode ? 0 : this_player->items.weapon[temp].power - 1,
  3774.                                                                            item_mode = (temp == REAR_WEAPON) ? this_player->weapon_mode - 1 : 0;
  3775.  
  3776.                                                                 b = player_shot_create(item, temp, this_player->x, this_player->y, *mouseX_, *mouseY_, weaponPort[item].op[item_mode][item_power], playerNum_);
  3777.                                                         }
  3778.                                                 }
  3779.                                         }
  3780.                                 }
  3781.  
  3782.                                 /*Super Charge Weapons*/
  3783.                                 if (playerNum_ == 2)
  3784.                                 {
  3785.  
  3786.                                         if (!twoPlayerLinked)
  3787.                                                 blit_sprite2(VGAScreen, this_player->x + (shipGr_ == 0) + 1, this_player->y - 13, eShapes[5], 77 + chargeLevel + chargeGr * 19);
  3788.  
  3789.                                         if (chargeGrWait > 0)
  3790.                                         {
  3791.                                                 chargeGrWait--;
  3792.                                         }
  3793.                                         else
  3794.                                         {
  3795.                                                 chargeGr++;
  3796.                                                 if (chargeGr == 4)
  3797.                                                         chargeGr = 0;
  3798.                                                 chargeGrWait = 3;
  3799.                                         }
  3800.  
  3801.                                         if (chargeLevel > 0)
  3802.                                         {
  3803.                                                 fill_rectangle_xy(VGAScreenSeg, 269, 107 + (chargeLevel - 1) * 3, 275, 108 + (chargeLevel - 1) * 3, 193);
  3804.                                         }
  3805.  
  3806.                                         if (chargeWait > 0)
  3807.                                         {
  3808.                                                 chargeWait--;
  3809.                                         }
  3810.                                         else
  3811.                                         {
  3812.                                                 if (chargeLevel < chargeMax)
  3813.                                                         chargeLevel++;
  3814.  
  3815.                                                 chargeWait = 28 - this_player->items.weapon[REAR_WEAPON].power * 2;
  3816.                                                 if (difficultyLevel > 3)
  3817.                                                         chargeWait -= 5;
  3818.                                         }
  3819.  
  3820.                                         if (chargeLevel > 0)
  3821.                                                 fill_rectangle_xy(VGAScreenSeg, 269, 107 + (chargeLevel - 1) * 3, 275, 108 + (chargeLevel - 1) * 3, 204);
  3822.  
  3823.                                         if (shotRepeat[SHOT_P2_CHARGE] > 0)
  3824.                                         {
  3825.                                                 --shotRepeat[SHOT_P2_CHARGE];
  3826.                                         }
  3827.                                         else if (button[1-1] && (!twoPlayerLinked || chargeLevel > 0))
  3828.                                         {
  3829.                                                 shotMultiPos[SHOT_P2_CHARGE] = 0;
  3830.                                                 b = player_shot_create(16, SHOT_P2_CHARGE, this_player->x, this_player->y, *mouseX_, *mouseY_, chargeGunWeapons[player[1].items.weapon[REAR_WEAPON].id-1] + chargeLevel, playerNum_);
  3831.  
  3832.                                                 if (chargeLevel > 0)
  3833.                                                         fill_rectangle_xy(VGAScreenSeg, 269, 107 + (chargeLevel - 1) * 3, 275, 108 + (chargeLevel - 1) * 3, 193);
  3834.  
  3835.                                                 chargeLevel = 0;
  3836.                                                 chargeWait = 30 - this_player->items.weapon[REAR_WEAPON].power * 2;
  3837.                                         }
  3838.                                 }
  3839.  
  3840.                                 /*SUPER BOMB*/
  3841.                                 temp = playerNum_;
  3842.                                 if (temp == 0)
  3843.                                         temp = 1;  /*Get whether player 1 or 2*/
  3844.  
  3845.                                 if (player[temp-1].superbombs > 0)
  3846.                                 {
  3847.                                         if (shotRepeat[SHOT_P1_SUPERBOMB + temp-1] > 0)
  3848.                                         {
  3849.                                                 --shotRepeat[SHOT_P1_SUPERBOMB + temp-1];
  3850.                                         }
  3851.                                         else if (button[3-1] || button[2-1])
  3852.                                         {
  3853.                                                 --player[temp-1].superbombs;
  3854.                                                 shotMultiPos[SHOT_P1_SUPERBOMB + temp-1] = 0;
  3855.                                                 b = player_shot_create(16, SHOT_P1_SUPERBOMB + temp-1, this_player->x, this_player->y, *mouseX_, *mouseY_, 535, playerNum_);
  3856.                                         }
  3857.                                 }
  3858.  
  3859.                                 // sidekicks
  3860.  
  3861.                                 if (this_player->sidekick[LEFT_SIDEKICK].style == 4 && this_player->sidekick[RIGHT_SIDEKICK].style == 4)
  3862.                                         optionSatelliteRotate += 0.2f;
  3863.                                 else if (this_player->sidekick[LEFT_SIDEKICK].style == 4 || this_player->sidekick[RIGHT_SIDEKICK].style == 4)
  3864.                                         optionSatelliteRotate += 0.15f;
  3865.  
  3866.                                 switch (this_player->sidekick[LEFT_SIDEKICK].style)
  3867.                                 {
  3868.                                 case 1:  // trailing
  3869.                                 case 3:
  3870.                                         this_player->sidekick[LEFT_SIDEKICK].x = this_player->old_x[COUNTOF(player->old_x) / 2 - 1];
  3871.                                         this_player->sidekick[LEFT_SIDEKICK].y = this_player->old_y[COUNTOF(player->old_x) / 2 - 1];
  3872.                                         break;
  3873.                                 case 2:  // front-mounted
  3874.                                         this_player->sidekick[LEFT_SIDEKICK].x = this_player->x;
  3875.                                         this_player->sidekick[LEFT_SIDEKICK].y = MAX(10, this_player->y - 20);
  3876.                                         break;
  3877.                                 case 4:  // orbitting
  3878.                                         this_player->sidekick[LEFT_SIDEKICK].x = this_player->x + roundf(sinf(optionSatelliteRotate) * 20);
  3879.                                         this_player->sidekick[LEFT_SIDEKICK].y = this_player->y + roundf(cosf(optionSatelliteRotate) * 20);
  3880.                                         break;
  3881.                                 }
  3882.  
  3883.                                 switch (this_player->sidekick[RIGHT_SIDEKICK].style)
  3884.                                 {
  3885.                                 case 4:  // orbitting
  3886.                                         this_player->sidekick[RIGHT_SIDEKICK].x = this_player->x - roundf(sinf(optionSatelliteRotate) * 20);
  3887.                                         this_player->sidekick[RIGHT_SIDEKICK].y = this_player->y - roundf(cosf(optionSatelliteRotate) * 20);
  3888.                                         break;
  3889.                                 case 1:  // trailing
  3890.                                 case 3:
  3891.                                         this_player->sidekick[RIGHT_SIDEKICK].x = this_player->old_x[0];
  3892.                                         this_player->sidekick[RIGHT_SIDEKICK].y = this_player->old_y[0];
  3893.                                         break;
  3894.                                 case 2:  // front-mounted
  3895.                                         if (!optionAttachmentLinked)
  3896.                                         {
  3897.                                                 this_player->sidekick[RIGHT_SIDEKICK].y += optionAttachmentMove / 2;
  3898.                                                 if (optionAttachmentMove >= -2)
  3899.                                                 {
  3900.                                                         if (optionAttachmentReturn)
  3901.                                                                 temp = 2;
  3902.                                                         else
  3903.                                                                 temp = 0;
  3904.  
  3905.                                                         if (this_player->sidekick[RIGHT_SIDEKICK].y > (this_player->y - 20) + 5)
  3906.                                                         {
  3907.                                                                 temp = 2;
  3908.                                                                 optionAttachmentMove -= 1 + optionAttachmentReturn;
  3909.                                                         }
  3910.                                                         else if (this_player->sidekick[RIGHT_SIDEKICK].y > (this_player->y - 20) - 0)
  3911.                                                         {
  3912.                                                                 temp = 3;
  3913.                                                                 if (optionAttachmentMove > 0)
  3914.                                                                         optionAttachmentMove--;
  3915.                                                                 else
  3916.                                                                         optionAttachmentMove++;
  3917.                                                         }
  3918.                                                         else if (this_player->sidekick[RIGHT_SIDEKICK].y > (this_player->y - 20) - 5)
  3919.                                                         {
  3920.                                                                 temp = 2;
  3921.                                                                 optionAttachmentMove++;
  3922.                                                         }
  3923.                                                         else if (optionAttachmentMove < 2 + optionAttachmentReturn * 4)
  3924.                                                         {
  3925.                                                                 optionAttachmentMove += 1 + optionAttachmentReturn;
  3926.                                                         }
  3927.  
  3928.                                                         if (optionAttachmentReturn)
  3929.                                                                 temp = temp * 2;
  3930.                                                         if (abs(this_player->sidekick[RIGHT_SIDEKICK].x - this_player->x) < temp)
  3931.                                                                 temp = 1;
  3932.  
  3933.                                                         if (this_player->sidekick[RIGHT_SIDEKICK].x > this_player->x)
  3934.                                                                 this_player->sidekick[RIGHT_SIDEKICK].x -= temp;
  3935.                                                         else if (this_player->sidekick[RIGHT_SIDEKICK].x < this_player->x)
  3936.                                                                 this_player->sidekick[RIGHT_SIDEKICK].x += temp;
  3937.  
  3938.                                                         if (abs(this_player->sidekick[RIGHT_SIDEKICK].y - (this_player->y - 20)) + abs(this_player->sidekick[RIGHT_SIDEKICK].x - this_player->x) < 8)
  3939.                                                         {
  3940.                                                                 optionAttachmentLinked = true;
  3941.                                                                 soundQueue[2] = S_CLINK;
  3942.                                                         }
  3943.  
  3944.                                                         if (button[3-1])
  3945.                                                                 optionAttachmentReturn = true;
  3946.                                                 }
  3947.                                                 else  // sidekick needs to catch up to player
  3948.                                                 {
  3949.                                                         optionAttachmentMove += 1 + optionAttachmentReturn;
  3950.                                                         JE_setupExplosion(this_player->sidekick[RIGHT_SIDEKICK].x + 1, this_player->sidekick[RIGHT_SIDEKICK].y + 10, 0, 0, false, false);
  3951.                                                 }
  3952.                                         }
  3953.                                         else
  3954.                                         {
  3955.                                                 this_player->sidekick[RIGHT_SIDEKICK].x = this_player->x;
  3956.                                                 this_player->sidekick[RIGHT_SIDEKICK].y = this_player->y - 20;
  3957.                                                 if (button[3-1])
  3958.                                                 {
  3959.                                                         optionAttachmentLinked = false;
  3960.                                                         optionAttachmentReturn = false;
  3961.                                                         optionAttachmentMove = -20;
  3962.                                                         soundQueue[3] = S_WEAPON_26;
  3963.                                                 }
  3964.                                         }
  3965.  
  3966.                                         if (this_player->sidekick[RIGHT_SIDEKICK].y < 10)
  3967.                                                 this_player->sidekick[RIGHT_SIDEKICK].y = 10;
  3968.                                         break;
  3969.                                 }
  3970.  
  3971.                                 if (playerNum_ == 2 || !twoPlayerMode)  // if player has sidekicks
  3972.                                 {
  3973.                                         for (uint i = 0; i < COUNTOF(player->items.sidekick); ++i)
  3974.                                         {
  3975.                                                 uint shot_i = (i == 0) ? SHOT_LEFT_SIDEKICK : SHOT_RIGHT_SIDEKICK;
  3976.  
  3977.                                                 JE_OptionType *this_option = &options[this_player->items.sidekick[i]];
  3978.  
  3979.                                                 // fire/refill sidekick
  3980.                                                 if (this_option->wport > 0)
  3981.                                                 {
  3982.                                                         if (shotRepeat[shot_i] > 0)
  3983.                                                         {
  3984.                                                                 --shotRepeat[shot_i];
  3985.                                                         }
  3986.                                                         else
  3987.                                                         {
  3988.                                                                 const int ammo_max = this_player->sidekick[i].ammo_max;
  3989.  
  3990.                                                                 if (ammo_max > 0)  // sidekick has limited ammo
  3991.                                                                 {
  3992.                                                                         if (this_player->sidekick[i].ammo_refill_ticks > 0)
  3993.                                                                         {
  3994.                                                                                 --this_player->sidekick[i].ammo_refill_ticks;
  3995.                                                                         }
  3996.                                                                         else  // refill one ammo
  3997.                                                                         {
  3998.                                                                                 this_player->sidekick[i].ammo_refill_ticks = this_player->sidekick[i].ammo_refill_ticks_max;
  3999.  
  4000.                                                                                 if (this_player->sidekick[i].ammo < ammo_max)
  4001.                                                                                         ++this_player->sidekick[i].ammo;
  4002.  
  4003.                                                                                 // draw sidekick refill ammo gauge
  4004.                                                                                 const int y = hud_sidekick_y[twoPlayerMode ? 1 : 0][i] + 13;
  4005.                                                                                 draw_segmented_gauge(VGAScreenSeg, 284, y, 112, 2, 2, MAX(1, ammo_max / 10), this_player->sidekick[i].ammo);
  4006.                                                                         }
  4007.  
  4008.                                                                         if (button[1 + i] && this_player->sidekick[i].ammo > 0)
  4009.                                                                         {
  4010.                                                                                 b = player_shot_create(this_option->wport, shot_i, this_player->sidekick[i].x, this_player->sidekick[i].y, *mouseX_, *mouseY_, this_option->wpnum + this_player->sidekick[i].charge, playerNum_);
  4011.  
  4012.                                                                                 --this_player->sidekick[i].ammo;
  4013.                                                                                 if (this_player->sidekick[i].charge > 0)
  4014.                                                                                 {
  4015.                                                                                         shotMultiPos[shot_i] = 0;
  4016.                                                                                         this_player->sidekick[i].charge = 0;
  4017.                                                                                 }
  4018.                                                                                 this_player->sidekick[i].charge_ticks = 20;
  4019.                                                                                 this_player->sidekick[i].animation_enabled = true;
  4020.  
  4021.                                                                                 // draw sidekick discharge ammo gauge
  4022.                                                                                 const int y = hud_sidekick_y[twoPlayerMode ? 1 : 0][i] + 13;
  4023.                                                                                 fill_rectangle_xy(VGAScreenSeg, 284, y, 312, y + 2, 0);
  4024.                                                                                 draw_segmented_gauge(VGAScreenSeg, 284, y, 112, 2, 2, MAX(1, ammo_max / 10), this_player->sidekick[i].ammo);
  4025.                                                                         }
  4026.                                                                 }
  4027.                                                                 else  // has infinite ammo
  4028.                                                                 {
  4029.                                                                         if (button[0] || button[1 + i])
  4030.                                                                         {
  4031.                                                                                 b = player_shot_create(this_option->wport, shot_i, this_player->sidekick[i].x, this_player->sidekick[i].y, *mouseX_, *mouseY_, this_option->wpnum + this_player->sidekick[i].charge, playerNum_);
  4032.  
  4033.                                                                                 if (this_player->sidekick[i].charge > 0)
  4034.                                                                                 {
  4035.                                                                                         shotMultiPos[shot_i] = 0;
  4036.                                                                                         this_player->sidekick[i].charge = 0;
  4037.                                                                                 }
  4038.                                                                                 this_player->sidekick[i].charge_ticks = 20;
  4039.                                                                                 this_player->sidekick[i].animation_enabled = true;
  4040.                                                                         }
  4041.                                                                 }
  4042.                                                         }
  4043.                                                 }
  4044.                                         }
  4045.                                 }  // end of if player has sidekicks
  4046.                         }  // !endLevel
  4047.                 } // this_player->is_alive
  4048.         } // moveOK
  4049.  
  4050.         // draw sidekicks
  4051.         if ((playerNum_ == 2 || !twoPlayerMode) && !endLevel)
  4052.         {
  4053.                 for (uint i = 0; i < COUNTOF(this_player->sidekick); ++i)
  4054.                 {
  4055.                         JE_OptionType *this_option = &options[this_player->items.sidekick[i]];
  4056.  
  4057.                         if (this_option->option > 0)
  4058.                         {
  4059.                                 if (this_player->sidekick[i].animation_enabled)
  4060.                                 {
  4061.                                         if (++this_player->sidekick[i].animation_frame >= this_option->ani)
  4062.                                         {
  4063.                                                 this_player->sidekick[i].animation_frame = 0;
  4064.                                                 this_player->sidekick[i].animation_enabled = (this_option->option == 1);
  4065.                                         }
  4066.                                 }
  4067.  
  4068.                                 const int x = this_player->sidekick[i].x,
  4069.                                           y = this_player->sidekick[i].y;
  4070.                                 const uint sprite = this_option->gr[this_player->sidekick[i].animation_frame] + this_player->sidekick[i].charge;
  4071.  
  4072.                                 if (this_player->sidekick[i].style == 1 || this_player->sidekick[i].style == 2)
  4073.                                         blit_sprite2x2(VGAScreen, x - 6, y, eShapes[5], sprite);
  4074.                                 else
  4075.                                         blit_sprite2(VGAScreen, x, y, shapes9, sprite);
  4076.                         }
  4077.  
  4078.                         if (--this_player->sidekick[i].charge_ticks == 0)
  4079.                         {
  4080.                                 if (this_player->sidekick[i].charge < this_option->pwr)
  4081.                                         ++this_player->sidekick[i].charge;
  4082.                                 this_player->sidekick[i].charge_ticks = 20;
  4083.                         }
  4084.                 }
  4085.         }
  4086. }
  4087.  
  4088. void JE_mainGamePlayerFunctions( void )
  4089. {
  4090.         /*PLAYER MOVEMENT/MOUSE ROUTINES*/
  4091.  
  4092.         if (endLevel && levelEnd > 0)
  4093.         {
  4094.                 levelEnd--;
  4095.                 levelEndWarp++;
  4096.         }
  4097.  
  4098.         /*Reset Street-Fighter commands*/
  4099.         memset(SFExecuted, 0, sizeof(SFExecuted));
  4100.  
  4101.         portConfigChange = false;
  4102.  
  4103.         if (twoPlayerMode)
  4104.         {
  4105.                 JE_playerMovement(&player[0],
  4106.                                   !galagaMode ? inputDevice[0] : 0, 1, shipGr, shipGrPtr,
  4107.                                   &mouseX, &mouseY);
  4108.                 JE_playerMovement(&player[1],
  4109.                                   !galagaMode ? inputDevice[1] : 0, 2, shipGr2, shipGr2ptr,
  4110.                                   &mouseXB, &mouseYB);
  4111.         }
  4112.         else
  4113.         {
  4114.                 JE_playerMovement(&player[0],
  4115.                                   0, 1, shipGr, shipGrPtr,
  4116.                                   &mouseX, &mouseY);
  4117.         }
  4118.  
  4119.         /* == Parallax Map Scrolling == */
  4120.         if (twoPlayerMode)
  4121.         {
  4122.                 tempX = (player[0].x + player[1].x) / 2;
  4123.         } else {
  4124.                 tempX = player[0].x;
  4125.         }
  4126.  
  4127.         tempW = floorf((260.0f - (tempX - 36.0f)) / (260.0f - 36.0f) * (24.0f * 3.0f) - 1.0f);
  4128.         mapX3Ofs   = tempW;
  4129.         mapX3Pos   = mapX3Ofs % 24;
  4130.         mapX3bpPos = 1 - (mapX3Ofs / 24);
  4131.  
  4132.         mapX2Ofs   = (tempW * 2) / 3;
  4133.         mapX2Pos   = mapX2Ofs % 24;
  4134.         mapX2bpPos = 1 - (mapX2Ofs / 24);
  4135.  
  4136.         oldMapXOfs = mapXOfs;
  4137.         mapXOfs    = mapX2Ofs / 2;
  4138.         mapXPos    = mapXOfs % 24;
  4139.         mapXbpPos  = 1 - (mapXOfs / 24);
  4140.  
  4141.         if (background3x1)
  4142.         {
  4143.                 mapX3Ofs = mapXOfs;
  4144.                 mapX3Pos = mapXPos;
  4145.                 mapX3bpPos = mapXbpPos - 1;
  4146.         }
  4147. }
  4148.  
  4149. const char *JE_getName( JE_byte pnum )
  4150. {
  4151.         if (pnum == thisPlayerNum && network_player_name[0] != '\0')
  4152.                 return network_player_name;
  4153.         else if (network_opponent_name[0] != '\0')
  4154.                 return network_opponent_name;
  4155.  
  4156.         return miscText[47 + pnum];
  4157. }
  4158.  
  4159. void JE_playerCollide( Player *this_player, JE_byte playerNum_ )
  4160. {
  4161.         char tempStr[256];
  4162.  
  4163.         for (int z = 0; z < 100; z++)
  4164.         {
  4165.                 if (enemyAvail[z] != 1)
  4166.                 {
  4167.                         int enemy_screen_x = enemy[z].ex + enemy[z].mapoffset;
  4168.  
  4169.                         if (abs(this_player->x - enemy_screen_x) < 12 && abs(this_player->y - enemy[z].ey) < 14)
  4170.                         {   /*Collide*/
  4171.                                 int evalue = enemy[z].evalue;
  4172.                                 if (evalue > 29999)
  4173.                                 {
  4174.                                         if (evalue == 30000)  // spawn dragonwing in galaga mode, otherwise just a purple ball
  4175.                                         {
  4176.                                                 this_player->cash += 100;
  4177.  
  4178.                                                 if (!galagaMode)
  4179.                                                 {
  4180.                                                         handle_got_purple_ball(this_player);
  4181.                                                 }
  4182.                                                 else
  4183.                                                 {
  4184.                                                         // spawn the dragonwing?
  4185.                                                         if (twoPlayerMode)
  4186.                                                                 this_player->cash += 2400;
  4187.                                                         twoPlayerMode = true;
  4188.                                                         twoPlayerLinked = true;
  4189.                                                         player[1].items.weapon[REAR_WEAPON].power = 1;
  4190.                                                         player[1].armor = 10;
  4191.                                                         player[1].is_alive = true;
  4192.                                                 }
  4193.                                                 enemyAvail[z] = 1;
  4194.                                                 soundQueue[7] = S_POWERUP;
  4195.                                         }
  4196.                                         else if (superArcadeMode != SA_NONE && evalue > 30000)
  4197.                                         {
  4198.                                                 shotMultiPos[SHOT_FRONT] = 0;
  4199.                                                 shotRepeat[SHOT_FRONT] = 10;
  4200.  
  4201.                                                 tempW = SAWeapon[superArcadeMode-1][evalue - 30000-1];
  4202.  
  4203.                                                 // if picked up already-owned weapon, power weapon up
  4204.                                                 if (tempW == player[0].items.weapon[FRONT_WEAPON].id)
  4205.                                                 {
  4206.                                                         this_player->cash += 1000;
  4207.                                                         power_up_weapon(this_player, FRONT_WEAPON);
  4208.                                                 }
  4209.                                                 // else weapon also gives purple ball
  4210.                                                 else
  4211.                                                 {
  4212.                                                         handle_got_purple_ball(this_player);
  4213.                                                 }
  4214.  
  4215.                                                 player[0].items.weapon[FRONT_WEAPON].id = tempW;
  4216.                                                 this_player->cash += 200;
  4217.                                                 soundQueue[7] = S_POWERUP;
  4218.                                                 enemyAvail[z] = 1;
  4219.                                         }
  4220.                                         else if (evalue > 32100)
  4221.                                         {
  4222.                                                 if (playerNum_ == 1)
  4223.                                                 {
  4224.                                                         this_player->cash += 250;
  4225.                                                         player[0].items.special = evalue - 32100;
  4226.                                                         shotMultiPos[SHOT_SPECIAL] = 0;
  4227.                                                         shotRepeat[SHOT_SPECIAL] = 10;
  4228.                                                         shotMultiPos[SHOT_SPECIAL2] = 0;
  4229.                                                         shotRepeat[SHOT_SPECIAL2] = 0;
  4230.  
  4231.                                                         if (isNetworkGame)
  4232.                                                                 sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], special[evalue - 32100].name);
  4233.                                                         else if (twoPlayerMode)
  4234.                                                                 sprintf(tempStr, "%s %s", miscText[43-1], special[evalue - 32100].name);
  4235.                                                         else
  4236.                                                                 sprintf(tempStr, "%s %s", miscText[64-1], special[evalue - 32100].name);
  4237.                                                         JE_drawTextWindow(tempStr);
  4238.                                                         soundQueue[7] = S_POWERUP;
  4239.                                                         enemyAvail[z] = 1;
  4240.                                                 }
  4241.                                         }
  4242.                                         else if (evalue > 32000)
  4243.                                         {
  4244.                                                 if (playerNum_ == 2)
  4245.                                                 {
  4246.                                                         enemyAvail[z] = 1;
  4247.                                                         if (isNetworkGame)
  4248.                                                                 sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], options[evalue - 32000].name);
  4249.                                                         else
  4250.                                                                 sprintf(tempStr, "%s %s", miscText[44-1], options[evalue - 32000].name);
  4251.                                                         JE_drawTextWindow(tempStr);
  4252.  
  4253.                                                         // if picked up a different sidekick than player already has, then reset sidekicks to least powerful, else power them up
  4254.                                                         if (evalue - 32000u != player[1].items.sidekick_series)
  4255.                                                         {
  4256.                                                                 player[1].items.sidekick_series = evalue - 32000;
  4257.                                                                 player[1].items.sidekick_level = 101;
  4258.                                                         }
  4259.                                                         else if (player[1].items.sidekick_level < 103)
  4260.                                                         {
  4261.                                                                 ++player[1].items.sidekick_level;
  4262.                                                         }
  4263.  
  4264.                                                         uint temp = player[1].items.sidekick_level - 100 - 1;
  4265.                                                         for (uint i = 0; i < COUNTOF(player[1].items.sidekick); ++i)
  4266.                                                                 player[1].items.sidekick[i] = optionSelect[player[1].items.sidekick_series][temp][i];
  4267.  
  4268.  
  4269.                                                         shotMultiPos[SHOT_LEFT_SIDEKICK] = 0;
  4270.                                                         shotMultiPos[SHOT_RIGHT_SIDEKICK] = 0;
  4271.                                                         JE_drawOptions();
  4272.                                                         soundQueue[7] = S_POWERUP;
  4273.                                                 }
  4274.                                                 else if (onePlayerAction)
  4275.                                                 {
  4276.                                                         enemyAvail[z] = 1;
  4277.                                                         sprintf(tempStr, "%s %s", miscText[64-1], options[evalue - 32000].name);
  4278.                                                         JE_drawTextWindow(tempStr);
  4279.  
  4280.                                                         for (uint i = 0; i < COUNTOF(player[0].items.sidekick); ++i)
  4281.                                                                 player[0].items.sidekick[i] = evalue - 32000;
  4282.                                                         shotMultiPos[SHOT_LEFT_SIDEKICK] = 0;
  4283.                                                         shotMultiPos[SHOT_RIGHT_SIDEKICK] = 0;
  4284.  
  4285.                                                         JE_drawOptions();
  4286.                                                         soundQueue[7] = S_POWERUP;
  4287.                                                 }
  4288.                                                 if (enemyAvail[z] == 1)
  4289.                                                         this_player->cash += 250;
  4290.                                         }
  4291.                                         else if (evalue > 31000)
  4292.                                         {
  4293.                                                 this_player->cash += 250;
  4294.                                                 if (playerNum_ == 2)
  4295.                                                 {
  4296.                                                         if (isNetworkGame)
  4297.                                                                 sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], weaponPort[evalue - 31000].name);
  4298.                                                         else
  4299.                                                                 sprintf(tempStr, "%s %s", miscText[44-1], weaponPort[evalue - 31000].name);
  4300.                                                         JE_drawTextWindow(tempStr);
  4301.                                                         player[1].items.weapon[REAR_WEAPON].id = evalue - 31000;
  4302.                                                         shotMultiPos[SHOT_REAR] = 0;
  4303.                                                         enemyAvail[z] = 1;
  4304.                                                         soundQueue[7] = S_POWERUP;
  4305.                                                 }
  4306.                                                 else if (onePlayerAction)
  4307.                                                 {
  4308.                                                         sprintf(tempStr, "%s %s", miscText[64-1], weaponPort[evalue - 31000].name);
  4309.                                                         JE_drawTextWindow(tempStr);
  4310.                                                         player[0].items.weapon[REAR_WEAPON].id = evalue - 31000;
  4311.                                                         shotMultiPos[SHOT_REAR] = 0;
  4312.                                                         enemyAvail[z] = 1;
  4313.                                                         soundQueue[7] = S_POWERUP;
  4314.  
  4315.                                                         if (player[0].items.weapon[REAR_WEAPON].power == 0)  // does this ever happen?
  4316.                                                                 player[0].items.weapon[REAR_WEAPON].power = 1;
  4317.                                                 }
  4318.                                         }
  4319.                                         else if (evalue > 30000)
  4320.                                         {
  4321.                                                 if (playerNum_ == 1 && twoPlayerMode)
  4322.                                                 {
  4323.                                                         if (isNetworkGame)
  4324.                                                                 sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], weaponPort[evalue - 30000].name);
  4325.                                                         else
  4326.                                                                 sprintf(tempStr, "%s %s", miscText[43-1], weaponPort[evalue - 30000].name);
  4327.                                                         JE_drawTextWindow(tempStr);
  4328.                                                         player[0].items.weapon[FRONT_WEAPON].id = evalue - 30000;
  4329.                                                         shotMultiPos[SHOT_FRONT] = 0;
  4330.                                                         enemyAvail[z] = 1;
  4331.                                                         soundQueue[7] = S_POWERUP;
  4332.                                                 }
  4333.                                                 else if (onePlayerAction)
  4334.                                                 {
  4335.                                                         sprintf(tempStr, "%s %s", miscText[64-1], weaponPort[evalue - 30000].name);
  4336.                                                         JE_drawTextWindow(tempStr);
  4337.                                                         player[0].items.weapon[FRONT_WEAPON].id = evalue - 30000;
  4338.                                                         shotMultiPos[SHOT_FRONT] = 0;
  4339.                                                         enemyAvail[z] = 1;
  4340.                                                         soundQueue[7] = S_POWERUP;
  4341.                                                 }
  4342.  
  4343.                                                 if (enemyAvail[z] == 1)
  4344.                                                 {
  4345.                                                         player[0].items.special = specialArcadeWeapon[evalue - 30000-1];
  4346.                                                         if (player[0].items.special > 0)
  4347.                                                         {
  4348.                                                                 shotMultiPos[SHOT_SPECIAL] = 0;
  4349.                                                                 shotRepeat[SHOT_SPECIAL] = 0;
  4350.                                                                 shotMultiPos[SHOT_SPECIAL2] = 0;
  4351.                                                                 shotRepeat[SHOT_SPECIAL2] = 0;
  4352.                                                         }
  4353.                                                         this_player->cash += 250;
  4354.                                                 }
  4355.  
  4356.                                         }
  4357.                                 }
  4358.                                 else if (evalue > 20000)
  4359.                                 {
  4360.                                         if (twoPlayerLinked)
  4361.                                         {
  4362.                                                 // share the armor evenly between linked players
  4363.                                                 for (uint i = 0; i < COUNTOF(player); ++i)
  4364.                                                 {
  4365.                                                         player[i].armor += (evalue - 20000) / COUNTOF(player);
  4366.                                                         if (player[i].armor > 28)
  4367.                                                                 player[i].armor = 28;
  4368.                                                 }
  4369.                                         }
  4370.                                         else
  4371.                                         {
  4372.                                                 this_player->armor += evalue - 20000;
  4373.                                                 if (this_player->armor > 28)
  4374.                                                         this_player->armor = 28;
  4375.                                         }
  4376.                                         enemyAvail[z] = 1;
  4377.                                         VGAScreen = VGAScreenSeg; /* side-effect of game_screen */
  4378.                                         JE_drawArmor();
  4379.                                         VGAScreen = game_screen; /* side-effect of game_screen */
  4380.                                         soundQueue[7] = S_POWERUP;
  4381.                                 }
  4382.                                 else if (evalue > 10000 && enemyAvail[z] == 2)
  4383.                                 {
  4384.                                         if (!bonusLevel)
  4385.                                         {
  4386.                                                 play_song(30);  /*Zanac*/
  4387.                                                 bonusLevel = true;
  4388.                                                 nextLevel = evalue - 10000;
  4389.                                                 enemyAvail[z] = 1;
  4390.                                                 displayTime = 150;
  4391.                                         }
  4392.                                 }
  4393.                                 else if (enemy[z].scoreitem)
  4394.                                 {
  4395.                                         enemyAvail[z] = 1;
  4396.                                         soundQueue[7] = S_ITEM;
  4397.                                         if (evalue == 1)
  4398.                                         {
  4399.                                                 cubeMax++;
  4400.                                                 soundQueue[3] = V_DATA_CUBE;
  4401.                                         }
  4402.                                         else if (evalue == -1)  // got front weapon powerup
  4403.                                         {
  4404.                                                 if (isNetworkGame)
  4405.                                                         sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], miscText[45-1]);
  4406.                                                 else if (twoPlayerMode)
  4407.                                                         sprintf(tempStr, "%s %s", miscText[43-1], miscText[45-1]);
  4408.                                                 else
  4409.                                                         strcpy(tempStr, miscText[45-1]);
  4410.                                                 JE_drawTextWindow(tempStr);
  4411.  
  4412.                                                 power_up_weapon(&player[0], FRONT_WEAPON);
  4413.                                                 soundQueue[7] = S_POWERUP;
  4414.                                         }
  4415.                                         else if (evalue == -2)  // got rear weapon powerup
  4416.                                         {
  4417.                                                 if (isNetworkGame)
  4418.                                                         sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], miscText[46-1]);
  4419.                                                 else if (twoPlayerMode)
  4420.                                                         sprintf(tempStr, "%s %s", miscText[44-1], miscText[46-1]);
  4421.                                                 else
  4422.                                                         strcpy(tempStr, miscText[46-1]);
  4423.                                                 JE_drawTextWindow(tempStr);
  4424.  
  4425.                                                 power_up_weapon(twoPlayerMode ? &player[1] : &player[0], REAR_WEAPON);
  4426.                                                 soundQueue[7] = S_POWERUP;
  4427.                                         }
  4428.                                         else if (evalue == -3)
  4429.                                         {
  4430.                                                 // picked up orbiting asteroid killer
  4431.                                                 shotMultiPos[SHOT_MISC] = 0;
  4432.                                                 b = player_shot_create(0, SHOT_MISC, this_player->x, this_player->y, mouseX, mouseY, 104, playerNum_);
  4433.                                                 shotAvail[z] = 0;
  4434.                                         }
  4435.                                         else if (evalue == -4)
  4436.                                         {
  4437.                                                 if (player[playerNum_-1].superbombs < 10)
  4438.                                                         ++player[playerNum_-1].superbombs;
  4439.                                         }
  4440.                                         else if (evalue == -5)
  4441.                                         {
  4442.                                                 player[0].items.weapon[FRONT_WEAPON].id = 25;  // HOT DOG!
  4443.                                                 player[0].items.weapon[REAR_WEAPON].id = 26;
  4444.                                                 player[1].items.weapon[REAR_WEAPON].id = 26;
  4445.  
  4446.                                                 player[0].last_items = player[0].items;
  4447.  
  4448.                                                 for (uint i = 0; i < COUNTOF(player); ++i)
  4449.                                                         player[i].weapon_mode = 1;
  4450.  
  4451.                                                 memset(shotMultiPos, 0, sizeof(shotMultiPos));
  4452.                                         }
  4453.                                         else if (twoPlayerLinked)
  4454.                                         {
  4455.                                                 // players get equal share of pick-up cash when linked
  4456.                                                 for (uint i = 0; i < COUNTOF(player); ++i)
  4457.                                                         player[i].cash += evalue / COUNTOF(player);
  4458.                                         }
  4459.                                         else
  4460.                                         {
  4461.                                                 this_player->cash += evalue;
  4462.                                         }
  4463.                                         JE_setupExplosion(enemy_screen_x, enemy[z].ey, 0, enemyDat[enemy[z].enemytype].explosiontype, true, false);
  4464.                                 }
  4465.                                 else if (this_player->invulnerable_ticks == 0 && enemyAvail[z] == 0 &&
  4466.                                          (enemyDat[enemy[z].enemytype].explosiontype & 1) == 0) // explosiontype & 1 == 0: not ground enemy
  4467.                                 {
  4468.                                         int armorleft = enemy[z].armorleft;
  4469.                                         if (armorleft > damageRate)
  4470.                                                 armorleft = damageRate;
  4471.  
  4472.                                         JE_playerDamage(armorleft, this_player);
  4473.  
  4474.                                         // player ship gets push-back from collision
  4475.                                         if (enemy[z].armorleft > 0)
  4476.                                         {
  4477.                                                 this_player->x_velocity += (enemy[z].exc * enemy[z].armorleft) / 2;
  4478.                                                 this_player->y_velocity += (enemy[z].eyc * enemy[z].armorleft) / 2;
  4479.                                         }
  4480.  
  4481.                                         int armorleft2 = enemy[z].armorleft;
  4482.                                         if (armorleft2 == 255)
  4483.                                                 armorleft2 = 30000;
  4484.  
  4485.                                         temp = enemy[z].linknum;
  4486.                                         if (temp == 0)
  4487.                                                 temp = 255;
  4488.  
  4489.                                         b = z;
  4490.  
  4491.                                         if (armorleft2 > armorleft)
  4492.                                         {
  4493.                                                 // damage enemy
  4494.                                                 if (enemy[z].armorleft != 255)
  4495.                                                         enemy[z].armorleft -= armorleft;
  4496.                                                 soundQueue[5] = S_ENEMY_HIT;
  4497.                                         }
  4498.                                         else
  4499.                                         {
  4500.                                                 // kill enemy
  4501.                                                 for (temp2 = 0; temp2 < 100; temp2++)
  4502.                                                 {
  4503.                                                         if (enemyAvail[temp2] != 1)
  4504.                                                         {
  4505.                                                                 temp3 = enemy[temp2].linknum;
  4506.                                                                 if (temp2 == b ||
  4507.                                                                         (temp != 255 &&
  4508.                                                                          (temp == temp3 || temp - 100 == temp3
  4509.                                                                           || (temp3 > 40 && temp3 / 20 == temp / 20 && temp3 <= temp))))
  4510.                                                                 {
  4511.                                                                         int enemy_screen_x = enemy[temp2].ex + enemy[temp2].mapoffset;
  4512.  
  4513.                                                                         enemy[temp2].linknum = 0;
  4514.  
  4515.                                                                         enemyAvail[temp2] = 1;
  4516.  
  4517.                                                                         if (enemyDat[enemy[temp2].enemytype].esize == 1)
  4518.                                                                         {
  4519.                                                                                 JE_setupExplosionLarge(enemy[temp2].enemyground, enemy[temp2].explonum, enemy_screen_x, enemy[temp2].ey);
  4520.                                                                                 soundQueue[6] = S_EXPLOSION_9;
  4521.                                                                         }
  4522.                                                                         else
  4523.                                                                         {
  4524.                                                                                 JE_setupExplosion(enemy_screen_x, enemy[temp2].ey, 0, 1, false, false);
  4525.                                                                                 soundQueue[5] = S_EXPLOSION_4;
  4526.                                                                         }
  4527.                                                                 }
  4528.                                                         }
  4529.                                                 }
  4530.                                                 enemyAvail[z] = 1;
  4531.                                         }
  4532.                                 }
  4533.                         }
  4534.  
  4535.                 }
  4536.         }
  4537. }
  4538.  
  4539.