/* * OpenTyrian Classic: A modern cross-platform port of Tyrian * Copyright (C) 2007-2009 The OpenTyrian Development Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "backgrnd.h" #include "config.h" #include "editship.h" #include "episodes.h" #include "file.h" #include "fonthand.h" #include "helptext.h" #include "helptext.h" #include "joystick.h" #include "keyboard.h" #include "lds_play.h" #include "loudness.h" #include "mainint.h" #include "menus.h" #include "mouse.h" #include "mtrand.h" #include "network.h" #include "nortsong.h" #include "nortvars.h" #include "opentyr.h" #include "palette.h" #include "params.h" #include "pcxmast.h" #include "picload.h" #include "player.h" #include "setup.h" #include "sndmast.h" #include "sprite.h" #include "varz.h" #include "vga256d.h" #include "video.h" #include #include bool button[4]; #define MAX_PAGE 8 #define TOPICS 6 const JE_byte topicStart[TOPICS] = { 0, 1, 2, 3, 7, 255 }; JE_shortint constantLastX; JE_word textErase; JE_word upgradeCost; JE_word downgradeCost; JE_boolean performSave; JE_boolean jumpSection; JE_boolean useLastBank; /* See if I want to use the last 16 colors for DisplayText */ bool pause_pressed = false, ingamemenu_pressed = false; /* Draws a message at the bottom text window on the playing screen */ void JE_drawTextWindow( const char *text ) { if (textErase > 0) // erase current text blit_sprite(VGAScreenSeg, 16, 189, OPTION_SHAPES, 36); // in-game text area textErase = 100; JE_outText(VGAScreenSeg, 20, 190, text, 0, 4); } void JE_outCharGlow( JE_word x, JE_word y, const char *s ) { JE_integer maxloc, loc, z; JE_shortint glowcol[60]; /* [1..60] */ JE_shortint glowcolc[60]; /* [1..60] */ JE_word textloc[60]; /* [1..60] */ JE_byte bank; setjasondelay2(1); bank = (warningRed) ? 7 : ((useLastBank) ? 15 : 14); if (s[0] == '\0') return; if (frameCountMax == 0) { JE_textShade(VGAScreen, x, y, s, bank, 0, PART_SHADE); JE_showVGA(); } else { maxloc = strlen(s); for (z = 0; z < 60; z++) { glowcol[z] = -8; glowcolc[z] = 1; } loc = x; for (z = 0; z < maxloc; z++) { textloc[z] = loc; int sprite_id = font_ascii[(unsigned char)s[z]]; if (s[z] == ' ') loc += 6; else if (sprite_id != -1) loc += sprite(TINY_FONT, sprite_id)->width + 1; } for (loc = 0; (unsigned)loc < strlen(s) + 28; loc++) { if (!ESCPressed) { setjasondelay(frameCountMax); NETWORK_KEEP_ALIVE(); int sprite_id = -1; for (z = loc - 28; z <= loc; z++) { if (z >= 0 && z < maxloc) { sprite_id = font_ascii[(unsigned char)s[z]]; if (sprite_id != -1) { blit_sprite_hv(VGAScreen, textloc[z], y, TINY_FONT, sprite_id, bank, glowcol[z]); glowcol[z] += glowcolc[z]; if (glowcol[z] > 9) glowcolc[z] = -1; } } } if (sprite_id != -1 && --z < maxloc) blit_sprite_dark(VGAScreen, textloc[z] + 1, y + 1, TINY_FONT, sprite_id, true); if (JE_anyButton()) frameCountMax = 0; do { if (levelWarningDisplay) JE_updateWarning(VGAScreen); SDL_Delay(16); } while (!(delaycount() == 0 || ESCPressed)); JE_showVGA(); } } } } void JE_drawPortConfigButtons( void ) // rear weapon pattern indicator { if (twoPlayerMode) return; if (player[0].weapon_mode == 1) { blit_sprite(VGAScreenSeg, 285, 44, OPTION_SHAPES, 18); // lit blit_sprite(VGAScreenSeg, 302, 44, OPTION_SHAPES, 19); // unlit } else // == 2 { blit_sprite(VGAScreenSeg, 285, 44, OPTION_SHAPES, 19); // unlit blit_sprite(VGAScreenSeg, 302, 44, OPTION_SHAPES, 18); // lit } } void JE_helpSystem( JE_byte startTopic ) { JE_integer page, lastPage = 0; JE_byte menu; page = topicStart[startTopic-1]; fade_black(10); JE_loadPic(VGAScreen, 2, false); play_song(SONG_MAPVIEW); JE_showVGA(); fade_palette(colors, 10, 0, 255); memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h); do { memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h); temp2 = 0; for (temp = 0; temp < TOPICS; temp++) { if (topicStart[temp] <= page) { temp2 = temp; } } if (page > 0) { JE_char buf[128]; sprintf(buf, "%s %d", miscText[24], page-topicStart[temp2]+1); JE_outText(VGAScreen, 10, 192, buf, 13, 5); sprintf(buf, "%s %d of %d", miscText[25], page, MAX_PAGE); JE_outText(VGAScreen, 220, 192, buf, 13, 5); JE_dString(VGAScreen, JE_fontCenter(topicName[temp2], SMALL_FONT_SHAPES), 1, topicName[temp2], SMALL_FONT_SHAPES); } menu = 0; helpBoxBrightness = 3; verticalHeight = 8; switch (page) { case 0: menu = 2; if (lastPage == MAX_PAGE) { menu = TOPICS; } JE_dString(VGAScreen, JE_fontCenter(topicName[0], FONT_SHAPES), 30, topicName[0], FONT_SHAPES); do { for (temp = 1; temp <= TOPICS; temp++) { char buf[21+1]; if (temp == menu-1) { strcpy(buf+1, topicName[temp]); buf[0] = '~'; } else { strcpy(buf, topicName[temp]); } JE_dString(VGAScreen, JE_fontCenter(topicName[temp], SMALL_FONT_SHAPES), temp * 20 + 40, buf, SMALL_FONT_SHAPES); } //JE_waitRetrace(); didn't do anything anyway? JE_showVGA(); tempW = 0; JE_textMenuWait(&tempW, false); if (newkey) { switch (lastkey_sym) { case SDLK_UP: case SDLK_LCTRL: menu--; if (menu < 2) { menu = TOPICS; } JE_playSampleNum(S_CURSOR); break; case SDLK_DOWN: case SDLK_LALT: menu++; if (menu > TOPICS) { menu = 2; } JE_playSampleNum(S_CURSOR); break; default: break; } } } while (!(lastkey_sym == SDLK_ESCAPE || lastkey_sym == SDLK_RETURN || lastkey_sym == SDLK_SPACE)); if (lastkey_sym == SDLK_RETURN || lastkey_sym == SDLK_SPACE) { page = topicStart[menu-1]; JE_playSampleNum(S_CLICK); } break; case 1: /* One-Player Menu */ JE_HBox(VGAScreen, 10, 20, 2, 60); JE_HBox(VGAScreen, 10, 50, 5, 60); JE_HBox(VGAScreen, 10, 80, 21, 60); JE_HBox(VGAScreen, 10, 110, 1, 60); JE_HBox(VGAScreen, 10, 140, 28, 60); break; case 2: /* Two-Player Menu */ JE_HBox(VGAScreen, 10, 20, 1, 60); JE_HBox(VGAScreen, 10, 60, 2, 60); JE_HBox(VGAScreen, 10, 100, 21, 60); JE_HBox(VGAScreen, 10, 140, 28, 60); break; case 3: /* Upgrade Ship */ JE_HBox(VGAScreen, 10, 20, 5, 60); JE_HBox(VGAScreen, 10, 70, 6, 60); JE_HBox(VGAScreen, 10, 110, 7, 60); break; case 4: JE_HBox(VGAScreen, 10, 20, 8, 60); JE_HBox(VGAScreen, 10, 55, 9, 60); JE_HBox(VGAScreen, 10, 87, 10, 60); JE_HBox(VGAScreen, 10, 120, 11, 60); JE_HBox(VGAScreen, 10, 170, 13, 60); break; case 5: JE_HBox(VGAScreen, 10, 20, 14, 60); JE_HBox(VGAScreen, 10, 80, 15, 60); JE_HBox(VGAScreen, 10, 120, 16, 60); break; case 6: JE_HBox(VGAScreen, 10, 20, 17, 60); JE_HBox(VGAScreen, 10, 40, 18, 60); JE_HBox(VGAScreen, 10, 130, 20, 60); break; case 7: /* Options */ JE_HBox(VGAScreen, 10, 20, 21, 60); JE_HBox(VGAScreen, 10, 70, 22, 60); JE_HBox(VGAScreen, 10, 110, 23, 60); JE_HBox(VGAScreen, 10, 140, 24, 60); break; case 8: JE_HBox(VGAScreen, 10, 20, 25, 60); JE_HBox(VGAScreen, 10, 60, 26, 60); JE_HBox(VGAScreen, 10, 100, 27, 60); JE_HBox(VGAScreen, 10, 140, 28, 60); JE_HBox(VGAScreen, 10, 170, 29, 60); break; } helpBoxBrightness = 1; verticalHeight = 7; lastPage = page; if (menu == 0) { do { setjasondelay(3); push_joysticks_as_keyboard(); service_SDL_events(true); JE_showVGA(); wait_delay(); } while (!newkey && !newmouse); wait_noinput(false, true, false); if (newmouse) { switch (lastmouse_but) { case SDL_BUTTON_LEFT: lastkey_sym = SDLK_RIGHT; break; case SDL_BUTTON_RIGHT: lastkey_sym = SDLK_LEFT; break; case SDL_BUTTON_MIDDLE: lastkey_sym = SDLK_ESCAPE; break; } do { service_SDL_events(false); } while (mousedown); newkey = true; } if (newkey) { switch (lastkey_sym) { case SDLK_LEFT: case SDLK_UP: case SDLK_PAGEUP: case SDLK_LCTRL: page--; JE_playSampleNum(S_CURSOR); break; case SDLK_RIGHT: case SDLK_DOWN: case SDLK_PAGEDOWN: case SDLK_RETURN: case SDLK_SPACE: case SDLK_LALT: if (page == MAX_PAGE) { page = 0; } else { page++; } JE_playSampleNum(S_CURSOR); break; case SDLK_F1: page = 0; JE_playSampleNum(S_CURSOR); break; default: break; } } } if (page == 255) { lastkey_sym = SDLK_ESCAPE; } } while (lastkey_sym != SDLK_ESCAPE); } // cost to upgrade a weapon power from power-1 (where power == 0 indicates an unupgraded weapon) long weapon_upgrade_cost( long base_cost, unsigned int power ) { assert(power <= 11); unsigned int temp = 0; // 0 1 3 6 10 15 21 29 ... for (; power > 0; power--) temp += power; return base_cost * temp; } ulong JE_getCost( JE_byte itemType, JE_word itemNum ) { long cost = 0; switch (itemType) { case 2: cost = (itemNum > 90) ? 100 : ships[itemNum].cost; break; case 3: case 4: { cost = weaponPort[itemNum].cost; const uint port = itemType - 3, item_power = player[0].items.weapon[port].power - 1; downgradeCost = weapon_upgrade_cost(cost, item_power); upgradeCost = weapon_upgrade_cost(cost, item_power + 1); } break; case 5: cost = shields[itemNum].cost; break; case 6: cost = powerSys[itemNum].cost; break; case 7: case 8: cost = options[itemNum].cost; break; } return cost; } void JE_loadScreen( void ) { JE_boolean quit; JE_byte sel, screen, min = 0, max = 0; char *tempstr; char *tempstr2; JE_boolean mal_str = false; int len; tempstr = NULL; free_sprite2s(&shapes6); JE_loadCompShapes(&shapes6, '1'); // need arrow sprites fade_black(10); JE_loadPic(VGAScreen, 2, false); JE_showVGA(); fade_palette(colors, 10, 0, 255); screen = 1; sel = 1; quit = false; memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h); do { while (mousedown) { service_SDL_events(false); tempX = mouse_x; tempY = mouse_y; } memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h); JE_dString(VGAScreen, JE_fontCenter(miscText[38 + screen - 1], FONT_SHAPES), 5, miscText[38 + screen - 1], FONT_SHAPES); switch (screen) { case 1: min = 1; max = 12; break; case 2: min = 12; max = 23; } /* SYN: Go through text line by line */ for (x = min; x <= max; x++) { tempY = 30 + (x - min) * 13; if (x == max) { /* Last line is return to main menu, not a save game */ if (mal_str) { free(tempstr); mal_str = false; } tempstr = miscText[34 - 1]; if (x == sel) /* Highlight if selected */ { temp2 = 254; } else { temp2 = 250; } } else { if (x == sel) /* Highlight if selected */ { temp2 = 254; } else { temp2 = 250 - ((saveFiles[x - 1].level == 0) << 1); } if (saveFiles[x - 1].level == 0) /* I think this means the save file is unused */ { if (mal_str) { free(tempstr); mal_str = false; } tempstr = miscText[3 - 1]; } else { if (mal_str) { free(tempstr); mal_str = false; } tempstr = saveFiles[x - 1].name; } } /* Write first column text */ JE_textShade(VGAScreen, 10, tempY, tempstr, 13, (temp2 % 16) - 8, FULL_SHADE); if (x < max) /* Write additional columns for all but the last row */ { if (saveFiles[x - 1].level == 0) { if (mal_str) { free(tempstr); } tempstr = (char *)malloc(7); mal_str = true; strcpy(tempstr, "-----"); /* Unused save slot */ } else { tempstr = saveFiles[x - 1].levelName; tempstr2 = (char *)malloc(5 + strlen(miscTextB[2-1])); sprintf(tempstr2, "%s %d", miscTextB[2-1], saveFiles[x - 1].episode); JE_textShade(VGAScreen, 250, tempY, tempstr2, 5, (temp2 % 16) - 8, FULL_SHADE); free(tempstr2); } len = strlen(miscTextB[3-1]) + 2 + strlen(tempstr); tempstr2 = (char *)malloc(len); sprintf(tempstr2, "%s %s", miscTextB[3 - 1], tempstr); JE_textShade(VGAScreen, 120, tempY, tempstr2, 5, (temp2 % 16) - 8, FULL_SHADE); free(tempstr2); } } if (screen == 2) { blit_sprite2x2(VGAScreen, 90, 180, shapes6, 279); } if (screen == 1) { blit_sprite2x2(VGAScreen, 220, 180, shapes6, 281); } helpBoxColor = 15; JE_helpBox(VGAScreen, 110, 182, miscText[56-1], 25); JE_showVGA(); tempW = 0; JE_textMenuWait(&tempW, false); if (newkey) { switch (lastkey_sym) { case SDLK_UP: case SDLK_LCTRL: sel--; if (sel < min) { sel = max; } JE_playSampleNum(S_CURSOR); break; case SDLK_DOWN: case SDLK_LALT: sel++; if (sel > max) { sel = min; } JE_playSampleNum(S_CURSOR); break; case SDLK_LEFT: case SDLK_RIGHT: if (screen == 1) { screen = 2; sel += 11; } else { screen = 1; sel -= 11; } break; case SDLK_RETURN: case SDLK_SPACE: if (sel < max) { if (saveFiles[sel - 1].level > 0) { JE_playSampleNum (S_SELECT); performSave = false; JE_operation(sel); quit = true; } else { JE_playSampleNum (S_CLINK); } } else { quit = true; } break; case SDLK_ESCAPE: quit = true; break; default: break; } } } while (!quit); } ulong JE_totalScore( const Player *this_player ) { ulong temp = this_player->cash; temp += JE_getValue(2, this_player->items.ship); temp += JE_getValue(3, this_player->items.weapon[FRONT_WEAPON].id); temp += JE_getValue(4, this_player->items.weapon[REAR_WEAPON].id); temp += JE_getValue(5, this_player->items.shield); temp += JE_getValue(6, this_player->items.generator); temp += JE_getValue(7, this_player->items.sidekick[LEFT_SIDEKICK]); temp += JE_getValue(8, this_player->items.sidekick[RIGHT_SIDEKICK]); return temp; } JE_longint JE_getValue( JE_byte itemType, JE_word itemNum ) { long value = 0; switch (itemType) { case 2: value = ships[itemNum].cost; break; case 3: case 4: { const long base_value = weaponPort[itemNum].cost; // if two-player, use first player's front and second player's rear weapon const uint port = itemType - 3; const uint item_power = player[twoPlayerMode ? port : 0].items.weapon[port].power - 1; value = base_value; for (unsigned int i = 1; i <= item_power; ++i) value += weapon_upgrade_cost(base_value, i); } break; case 5: value = shields[itemNum].cost; break; case 6: value = powerSys[itemNum].cost; break; case 7: case 8: value = options[itemNum].cost; break; } return value; } void JE_nextEpisode( void ) { strcpy(lastLevelName, "Completed"); if (episodeNum == initial_episode_num && !gameHasRepeated && episodeNum != 4 && !isNetworkGame && !constantPlay) { JE_highScoreCheck(); } unsigned int newEpisode = JE_findNextEpisode(); if (jumpBackToEpisode1) { // shareware version check if (episodeNum == 1 && !isNetworkGame && !constantPlay) { // JE_loadOrderingInfo(); } if (episodeNum > 2 && !constantPlay) { JE_playCredits(); } // randomly give player the SuperCarrot if ((mt_rand() % 6) == 0) { player[0].items.ship = 2; player[0].items.weapon[FRONT_WEAPON].id = 23; player[0].items.weapon[REAR_WEAPON].id = 24; for (uint i = 0; i < COUNTOF(player[0].items.weapon); ++i) player[0].items.weapon[i].power = 1; player[1].items.weapon[REAR_WEAPON].id = 24; player[0].last_items = player[0].items; } } if (newEpisode != episodeNum) JE_initEpisode(newEpisode); gameLoaded = true; mainLevel = FIRST_LEVEL; saveLevel = FIRST_LEVEL; play_song(26); JE_clr256(VGAScreen); memcpy(colors, palettes[6-1], sizeof(colors)); JE_dString(VGAScreen, JE_fontCenter(episode_name[episodeNum], SMALL_FONT_SHAPES), 130, episode_name[episodeNum], SMALL_FONT_SHAPES); JE_dString(VGAScreen, JE_fontCenter(miscText[5-1], SMALL_FONT_SHAPES), 185, miscText[5-1], SMALL_FONT_SHAPES); JE_showVGA(); fade_palette(colors, 15, 0, 255); JE_wipeKey(); if (!constantPlay) { do { NETWORK_KEEP_ALIVE(); SDL_Delay(16); } while (!JE_anyButton()); } fade_black(15); } void JE_initPlayerData( void ) { /* JE: New Game Items/Data */ player[0].items.ship = 1; // USP Talon player[0].items.weapon[FRONT_WEAPON].id = 1; // Pulse Cannon player[0].items.weapon[REAR_WEAPON].id = 0; // None player[0].items.shield = 4; // Gencore High Energy Shield player[0].items.generator = 2; // Advanced MR-12 for (uint i = 0; i < COUNTOF(player[0].items.sidekick); ++i) player[0].items.sidekick[i] = 0; // None player[0].items.special = 0; // None player[0].last_items = player[0].items; player[1].items = player[0].items; player[1].items.weapon[REAR_WEAPON].id = 15; // Vulcan Cannon player[1].items.sidekick_level = 101; // 101, 102, 103 player[1].items.sidekick_series = 0; // None gameHasRepeated = false; onePlayerAction = false; superArcadeMode = SA_NONE; superTyrian = false; twoPlayerMode = false; secretHint = (mt_rand() % 3) + 1; for (uint p = 0; p < COUNTOF(player); ++p) { for (uint i = 0; i < COUNTOF(player->items.weapon); ++i) { player[p].items.weapon[i].power = 1; } player[p].weapon_mode = 1; player[p].armor = ships[player[p].items.ship].dmg; player[p].is_dragonwing = (p == 1); player[p].lives = &player[p].items.weapon[p].power; } mainLevel = FIRST_LEVEL; saveLevel = FIRST_LEVEL; strcpy(lastLevelName, miscText[19]); } void JE_sortHighScores( void ) { JE_byte x; temp = 0; for (x = 0; x < 6; x++) { JE_sort(); temp += 3; } } void JE_highScoreScreen( void ) { int min = 1; int max = 3; int x, z; short int chg; int quit; char scoretemp[32]; free_sprite2s(&shapes6); JE_loadCompShapes(&shapes6, '1'); // need arrow sprites fade_black(10); JE_loadPic(VGAScreen, 2, false); JE_showVGA(); fade_palette(colors, 10, 0, 255); quit = false; x = 1; chg = 1; memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h); do { if (episodeAvail[x-1]) { memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h); JE_dString(VGAScreen, JE_fontCenter(miscText[51 - 1], FONT_SHAPES), 03, miscText[51 - 1], FONT_SHAPES); JE_dString(VGAScreen, JE_fontCenter(episode_name[x], SMALL_FONT_SHAPES), 30, episode_name[x], SMALL_FONT_SHAPES); /* Player 1 */ temp = (x * 6) - 6; JE_dString(VGAScreen, JE_fontCenter(miscText[47 - 1], SMALL_FONT_SHAPES), 55, miscText[47 - 1], SMALL_FONT_SHAPES); for (z = 0; z < 3; z++) { temp5 = saveFiles[temp + z].highScoreDiff; if (temp5 > 9) { saveFiles[temp + z].highScoreDiff = 0; temp5 = 0; } sprintf(scoretemp, "~#%d:~ %d", z + 1, saveFiles[temp+z].highScore1); JE_textShade(VGAScreen, 250, ((z+1) * 10) + 65 , difficultyNameB[temp5], 15, temp5 + ((JE_byte) (temp5 == 0)) - 1, FULL_SHADE); JE_textShade(VGAScreen, 20, ((z+1) * 10) + 65 , scoretemp, 15, 0, FULL_SHADE); JE_textShade(VGAScreen, 110, ((z+1) * 10) + 65 , saveFiles[temp + z].highScoreName, 15, 2, FULL_SHADE); } /* Player 2 */ temp += 3; JE_dString(VGAScreen, JE_fontCenter( miscText[48 - 1], SMALL_FONT_SHAPES), 120, miscText[48 - 1], SMALL_FONT_SHAPES); /*{ textshade(20,125,misctext[49],15,3,_FullShade); textshade(80,125,misctext[50],15,3,_FullShade);}*/ for (z = 0; z < 3; z++) { temp5 = saveFiles[temp + z].highScoreDiff; if (temp5 > 9) { saveFiles[temp + z].highScoreDiff = 0; temp5 = 0; } sprintf(scoretemp, "~#%d:~ %d", z + 1, saveFiles[temp+z].highScore1); /* Not .highScore2 for some reason */ JE_textShade(VGAScreen, 250, ((z+1) * 10) + 125 , difficultyNameB[temp5], 15, temp5 + ((JE_byte) (temp5 == 0)) - 1, FULL_SHADE); JE_textShade(VGAScreen, 20, ((z+1) * 10) + 125 , scoretemp, 15, 0, FULL_SHADE); JE_textShade(VGAScreen, 110, ((z+1) * 10) + 125 , saveFiles[temp + z].highScoreName, 15, 2, FULL_SHADE); } if (x > 1) { blit_sprite2x2(VGAScreen, 90, 180, shapes6, 279); } if ( ( (x < 2) && episodeAvail[2-1] ) || ( (x < 3) && episodeAvail[3-1] ) ) { blit_sprite2x2(VGAScreen, 220, 180, shapes6, 281); } helpBoxColor = 15; JE_helpBox(VGAScreen, 110, 182, miscText[57 - 1], 25); /* {Dstring(fontcenter(misctext[57],_SmallFontShapes),190,misctext[57],_SmallFontShapes);} */ JE_showVGA(); tempW = 0; JE_textMenuWait(&tempW, false); if (newkey) { switch (lastkey_sym) { case SDLK_LEFT: x--; chg = -1; break; case SDLK_RIGHT: x++; chg = 1; break; default: break; } } } else { x += chg; } x = ( x < min ) ? max : ( x > max ) ? min : x; if (newkey) { switch (lastkey_sym) { case SDLK_RETURN: case SDLK_SPACE: case SDLK_ESCAPE: quit = true; break; default: break; } } } while (!quit); } void JE_gammaCorrect_func( JE_byte *col, JE_real r ) { int temp = roundf(*col * r); if (temp > 255) { temp = 255; } *col = temp; } void JE_gammaCorrect( Palette *colorBuffer, JE_byte gamma ) { int x; JE_real r = 1 + (JE_real)gamma / 10; for (x = 0; x < 256; x++) { JE_gammaCorrect_func(&(*colorBuffer)[x].r, r); JE_gammaCorrect_func(&(*colorBuffer)[x].g, r); JE_gammaCorrect_func(&(*colorBuffer)[x].b, r); } } JE_boolean JE_gammaCheck( void ) { bool temp = keysactive[SDLK_F11] != 0; if (temp) { keysactive[SDLK_F11] = false; newkey = false; gammaCorrection = (gammaCorrection + 1) % 4; memcpy(colors, palettes[pcxpal[3-1]], sizeof(colors)); JE_gammaCorrect(&colors, gammaCorrection); set_palette(colors, 0, 255); } return temp; } void JE_doInGameSetup( void ) { haltGame = false; if (isNetworkGame) { network_prepare(PACKET_GAME_MENU); network_send(4); // PACKET_GAME_MENU while (true) { service_SDL_events(false); if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_GAME_MENU) { network_update(); break; } network_update(); network_check(); SDL_Delay(16); } } if (yourInGameMenuRequest) { if (JE_inGameSetup()) { reallyEndLevel = true; playerEndLevel = true; } quitRequested = false; keysactive[SDLK_ESCAPE] = false; if (isNetworkGame) { if (!playerEndLevel) { network_prepare(PACKET_WAITING); network_send(4); // PACKET_WAITING } else { network_prepare(PACKET_GAME_QUIT); network_send(4); // PACKET_GAMEQUIT } } } if (isNetworkGame) { SDL_Surface *temp_surface = VGAScreen; VGAScreen = VGAScreenSeg; /* side-effect of game_screen */ if (!yourInGameMenuRequest) { JE_barShade(VGAScreen, 3, 60, 257, 80); /*Help Box*/ JE_barShade(VGAScreen, 5, 62, 255, 78); JE_dString(VGAScreen, 10, 65, "Other player in options menu.", SMALL_FONT_SHAPES); JE_showVGA(); while (true) { service_SDL_events(false); JE_showVGA(); if (packet_in[0]) { if (SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_WAITING) { network_check(); break; } else if (SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_GAME_QUIT) { reallyEndLevel = true; playerEndLevel = true; network_check(); break; } } network_update(); network_check(); SDL_Delay(16); } } else { /* JE_barShade(3, 160, 257, 180); /-*Help Box*-/ JE_barShade(5, 162, 255, 178); tempScreenSeg = VGAScreen; JE_dString(VGAScreen, 10, 165, "Waiting for other player.", SMALL_FONT_SHAPES); JE_showVGA(); */ } while (!network_is_sync()) { service_SDL_events(false); network_check(); SDL_Delay(16); } VGAScreen = temp_surface; /* side-effect of game_screen */ } yourInGameMenuRequest = false; //skipStarShowVGA = true; } JE_boolean JE_inGameSetup( void ) { SDL_Surface *temp_surface = VGAScreen; VGAScreen = VGAScreenSeg; /* side-effect of game_screen */ JE_boolean returnvalue = false; const JE_byte help[6] /* [1..6] */ = {15, 15, 28, 29, 26, 27}; JE_byte sel; JE_boolean quit; bool first = true; //tempScreenSeg = VGAScreenSeg; /* ? should work as VGAScreen */ quit = false; sel = 1; JE_barShade(VGAScreen, 3, 13, 217, 137); /*Main Box*/ JE_barShade(VGAScreen, 5, 15, 215, 135); JE_barShade(VGAScreen, 3, 143, 257, 157); /*Help Box*/ JE_barShade(VGAScreen, 5, 145, 255, 155); memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h); do { memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h); for (x = 0; x < 6; x++) { JE_outTextAdjust(VGAScreen, 10, (x + 1) * 20, inGameText[x], 15, ((sel == x+1) << 1) - 4, SMALL_FONT_SHAPES, true); } JE_outTextAdjust(VGAScreen, 120, 3 * 20, detailLevel[processorType-1], 15, ((sel == 3) << 1) - 4, SMALL_FONT_SHAPES, true); JE_outTextAdjust(VGAScreen, 120, 4 * 20, gameSpeedText[gameSpeed-1], 15, ((sel == 4) << 1) - 4, SMALL_FONT_SHAPES, true); JE_outTextAdjust(VGAScreen, 10, 147, mainMenuHelp[help[sel-1]-1], 14, 6, TINY_FONT, true); JE_barDrawShadow(VGAScreen, 120, 20, 1, 16, tyrMusicVolume / 12, 3, 13); JE_barDrawShadow(VGAScreen, 120, 40, 1, 16, fxVolume / 12, 3, 13); JE_showVGA(); if (first) { first = false; wait_noinput(false, false, true); // TODO: should up the joystick repeat temporarily instead } tempW = 0; JE_textMenuWait(&tempW, true); if (inputDetected) { switch (lastkey_sym) { case SDLK_RETURN: case SDLK_SPACE: JE_playSampleNum(S_SELECT); switch (sel) { case 1: case 2: case 3: case 4: sel = 5; break; case 5: quit = true; break; case 6: returnvalue = true; quit = true; if (constantPlay) { JE_tyrianHalt(0); } if (isNetworkGame) { /*Tell other computer to exit*/ haltGame = true; playerEndLevel = true; } break; } break; case SDLK_ESCAPE: quit = true; JE_playSampleNum(S_SPRING); break; case SDLK_UP: case SDLK_LCTRL: if (--sel < 1) { sel = 6; } JE_playSampleNum(S_CURSOR); break; case SDLK_DOWN: case SDLK_LALT: if (++sel > 6) { sel = 1; } JE_playSampleNum(S_CURSOR); break; case SDLK_LEFT: switch (sel) { case 1: JE_changeVolume(&tyrMusicVolume, -12, &fxVolume, 0); if (music_disabled) { music_disabled = false; restart_song(); } break; case 2: JE_changeVolume(&tyrMusicVolume, 0, &fxVolume, -12); samples_disabled = false; break; case 3: if (--processorType < 1) { processorType = 4; } JE_initProcessorType(); JE_setNewGameSpeed(); break; case 4: if (--gameSpeed < 1) { gameSpeed = 5; } JE_initProcessorType(); JE_setNewGameSpeed(); break; } if (sel < 5) { JE_playSampleNum(S_CURSOR); } break; case SDLK_RIGHT: switch (sel) { case 1: JE_changeVolume(&tyrMusicVolume, 12, &fxVolume, 0); if (music_disabled) { music_disabled = false; restart_song(); } break; case 2: JE_changeVolume(&tyrMusicVolume, 0, &fxVolume, 12); samples_disabled = false; break; case 3: if (++processorType > 4) { processorType = 1; } JE_initProcessorType(); JE_setNewGameSpeed(); break; case 4: if (++gameSpeed > 5) { gameSpeed = 1; } JE_initProcessorType(); JE_setNewGameSpeed(); break; } if (sel < 5) { JE_playSampleNum(S_CURSOR); } break; case SDLK_w: if (sel == 3) { processorType = 6; JE_initProcessorType(); } default: break; } } } while (!(quit || haltGame)); VGAScreen = temp_surface; /* side-effect of game_screen */ return returnvalue; } void JE_inGameHelp( void ) { SDL_Surface *temp_surface = VGAScreen; VGAScreen = VGAScreenSeg; /* side-effect of game_screen */ //tempScreenSeg = VGAScreenSeg; JE_clearKeyboard(); JE_wipeKey(); JE_barShade(VGAScreen, 1, 1, 262, 182); /*Main Box*/ JE_barShade(VGAScreen, 3, 3, 260, 180); JE_barShade(VGAScreen, 5, 5, 258, 178); JE_barShade(VGAScreen, 7, 7, 256, 176); fill_rectangle_xy(VGAScreen, 9, 9, 254, 174, 0); if (twoPlayerMode) // Two-Player Help { helpBoxColor = 3; helpBoxBrightness = 3; JE_HBox(VGAScreen, 20, 4, 36, 50); // weapon help blit_sprite(VGAScreenSeg, 2, 21, OPTION_SHAPES, 43); helpBoxColor = 5; helpBoxBrightness = 3; JE_HBox(VGAScreen, 55, 20, 37, 40); // sidekick help blit_sprite(VGAScreenSeg, 5, 36, OPTION_SHAPES, 41); helpBoxColor = 5; helpBoxBrightness = 3; JE_HBox(VGAScreen, 40, 43, 34, 44); // sheild/armor help blit_sprite(VGAScreenSeg, 2, 79, OPTION_SHAPES, 42); helpBoxColor = 5; helpBoxBrightness = 3; JE_HBox(VGAScreen, 54, 84, 35, 40); helpBoxColor = 5; helpBoxBrightness = 3; JE_HBox(VGAScreen, 5, 126, 38, 55); helpBoxColor = 5; helpBoxBrightness = 3; JE_HBox(VGAScreen, 5, 160, 39, 55); } else { // power bar help blit_sprite(VGAScreenSeg, 15, 5, OPTION_SHAPES, 40); helpBoxColor = 5; helpBoxBrightness = 3; JE_HBox(VGAScreen, 40, 10, 31, 45); // weapon help blit_sprite(VGAScreenSeg, 5, 37, OPTION_SHAPES, 39); helpBoxColor = 5; helpBoxBrightness = 3; JE_HBox(VGAScreen, 40, 40, 32, 44); helpBoxColor = 5; helpBoxBrightness = 3; JE_HBox(VGAScreen, 40, 60, 33, 44); // sidekick help blit_sprite(VGAScreenSeg, 5, 98, OPTION_SHAPES, 41); helpBoxColor = 5; helpBoxBrightness = 3; JE_HBox(VGAScreen, 40, 103, 34, 44); // shield/armor help blit_sprite(VGAScreenSeg, 2, 138, OPTION_SHAPES, 42); helpBoxColor = 5; helpBoxBrightness = 3; JE_HBox(VGAScreen, 54, 143, 35, 40); } // "press a key" blit_sprite(VGAScreenSeg, 16, 189, OPTION_SHAPES, 36); // in-game text area JE_outText(VGAScreenSeg, 120 - JE_textWidth(miscText[5-1], TINY_FONT) / 2 + 20, 190, miscText[5-1], 0, 4); JE_showVGA(); do { tempW = 0; JE_textMenuWait(&tempW, true); } while (!inputDetected); textErase = 1; VGAScreen = temp_surface; } void JE_highScoreCheck( void ) { free_sprite2s(&shapes6); JE_loadCompShapes(&shapes6, '1'); // need mouse cursor sprite Sint32 temp_score; for (int temp_p = 0; temp_p < (twoPlayerMode ? 2 : 1); ++temp_p) { JE_sortHighScores(); int p = temp_p; if (twoPlayerMode) { // ask for the highest scorer first if (player[0].cash < player[1].cash) p = (temp_p == 0) ? 1 : 0; temp_score = (p == 0) ? player[0].cash : player[1].cash; } else { // single player highscore includes cost of upgrades temp_score = JE_totalScore(&player[0]); } int slot; const int first_slot = (initial_episode_num - 1) * 6 + (twoPlayerMode ? 3 : 0), slot_limit = first_slot + 3; for (slot = first_slot; slot < slot_limit; ++slot) { if (temp_score > saveFiles[slot].highScore1) break; } // did you get a high score? if (slot < slot_limit) { // shift down old scores for (int i = slot_limit - 1; i > slot; --i) { saveFiles[i].highScore1 = saveFiles[i - 1].highScore1; strcpy(saveFiles[i].highScoreName, saveFiles[i - 1].highScoreName); } wait_noinput(false, true, false); JE_clr256(VGAScreen); JE_showVGA(); memcpy(colors, palettes[0], sizeof(colors)); play_song(33); { /* Enter Thy name */ JE_byte flash = 8 * 16 + 10; JE_boolean fadein = true; JE_boolean quit = false, cancel = false; char stemp[30], tempstr[30]; char buffer[256]; strcpy(stemp, " "); temp = 0; JE_barShade(VGAScreen, 65, 55, 255, 155); do { service_SDL_events(true); JE_dString(VGAScreen, JE_fontCenter(miscText[51], FONT_SHAPES), 3, miscText[51], FONT_SHAPES); temp3 = twoPlayerMode ? 58 + p : 53; JE_dString(VGAScreen, JE_fontCenter(miscText[temp3-1], SMALL_FONT_SHAPES), 30, miscText[temp3-1], SMALL_FONT_SHAPES); blit_sprite(VGAScreenSeg, 50, 50, OPTION_SHAPES, 35); // message box if (twoPlayerMode) { sprintf(buffer, "%s %s", miscText[48 + p], miscText[53]); JE_textShade(VGAScreen, 60, 55, buffer, 11, 4, FULL_SHADE); } else { JE_textShade(VGAScreen, 60, 55, miscText[53], 11, 4, FULL_SHADE); } sprintf(buffer, "%s %d", miscText[37], temp_score); JE_textShade(VGAScreen, 70, 70, buffer, 11, 4, FULL_SHADE); do { flash = (flash == 8 * 16 + 10) ? 8 * 16 + 2 : 8 * 16 + 10; temp3 = (temp3 == 6) ? 2 : 6; strncpy(tempstr, stemp, temp); tempstr[temp] = '\0'; JE_outText(VGAScreen, 65, 89, tempstr, 8, 3); tempW = 65 + JE_textWidth(tempstr, TINY_FONT); JE_barShade(VGAScreen, tempW + 2, 90, tempW + 6, 95); fill_rectangle_xy(VGAScreen, tempW + 1, 89, tempW + 5, 94, flash); for (int i = 0; i < 14; i++) { setjasondelay(1); JE_mouseStart(); JE_showVGA(); if (fadein) { fade_palette(colors, 15, 0, 255); fadein = false; } JE_mouseReplace(); push_joysticks_as_keyboard(); service_wait_delay(); if (newkey || newmouse) break; } } while (!newkey && !newmouse); if (!playing) play_song(31); /* if (mouseButton > 0) { if (mouseX > 56 && mouseX < 142 && mouseY > 123 && mouseY < 149) { quit = true; } else if (mouseX > 151 && mouseX < 237 && mouseY > 123 && mouseY < 149) { quit = true; cancel = true; } } else */ if (newkey || newmouse) { bool validkey = false; lastkey_char = toupper(lastkey_char); if(mouse_pressed[0]) lastkey_char = SDLK_SPACE; switch(lastkey_char) { //case ' ': case '-': case '.': case ',': case ':': case '!': case '?': case '#': case '@': case '$': case '%': case '*': case '(': case ')': case '/': case '=': case '+': case '<': case '>': case ';': case '"': case '\'': validkey = true; default: if (temp < 28 && (validkey || (lastkey_char >= 'A' && lastkey_char <= 'Z') || (lastkey_char >= '0' && lastkey_char <= '9'))) { stemp[temp] = lastkey_char; temp++; } break; case SDLK_BACKSPACE: case SDLK_DELETE: if (temp) { temp--; stemp[temp] = ' '; } break; case SDLK_ESCAPE: quit = true; cancel = true; break; case SDLK_RETURN: case SDLK_SPACE: quit = true; break; } } } while (!quit); if (!cancel) { saveFiles[slot].highScore1 = temp_score; strcpy(saveFiles[slot].highScoreName, stemp); saveFiles[slot].highScoreDiff = difficultyLevel; } fade_black(15); JE_loadPic(VGAScreen, 2, false); JE_dString(VGAScreen, JE_fontCenter(miscText[50], FONT_SHAPES), 10, miscText[50], FONT_SHAPES); JE_dString(VGAScreen, JE_fontCenter(episode_name[episodeNum], SMALL_FONT_SHAPES), 35, episode_name[episodeNum], SMALL_FONT_SHAPES); for (int i = first_slot; i < slot_limit; ++i) { if (i != slot) { sprintf(buffer, "~#%d:~ %d", (i - first_slot + 1), saveFiles[i].highScore1); JE_textShade(VGAScreen, 20, ((i - first_slot + 1) * 12) + 65, buffer, 15, 0, FULL_SHADE); JE_textShade(VGAScreen, 150, ((i - first_slot + 1) * 12) + 65, saveFiles[i].highScoreName, 15, 2, FULL_SHADE); } } JE_showVGA(); fade_palette(colors, 15, 0, 255); sprintf(buffer, "~#%d:~ %d", (slot - first_slot + 1), saveFiles[slot].highScore1); frameCountMax = 6; textGlowFont = TINY_FONT; textGlowBrightness = 10; JE_outTextGlow(VGAScreenSeg, 20, (slot - first_slot + 1) * 12 + 65, buffer); textGlowBrightness = 10; JE_outTextGlow(VGAScreenSeg, 150, (slot - first_slot + 1) * 12 + 65, saveFiles[slot].highScoreName); textGlowBrightness = 10; JE_outTextGlow(VGAScreenSeg, JE_fontCenter(miscText[4], TINY_FONT), 180, miscText[4]); JE_showVGA(); if (frameCountMax != 0) wait_input(true, true, true); fade_black(15); } } } } // increases game difficulty based on player's total score / total of players' scores void adjust_difficulty( void ) { const float score_multiplier[10] = { 0, // Wimp (doesn't exist) 0.4f, // Easy 0.8f, // Normal 1.3f, // Hard 1.6f, // Impossible 2, // Insanity 2, // Suicide 3, // Maniacal 3, // Zinglon 3, // Nortaneous }; assert(initialDifficulty > 0 && initialDifficulty < 10); const ulong score = twoPlayerMode ? (player[0].cash + player[1].cash) : JE_totalScore(&player[0]), adjusted_score = roundf(score * score_multiplier[initialDifficulty]); uint new_difficulty = 0; if (twoPlayerMode) { if (adjusted_score < 10000) new_difficulty = 1; // Easy else if (adjusted_score < 20000) new_difficulty = 2; // Normal else if (adjusted_score < 50000) new_difficulty = 3; // Hard else if (adjusted_score < 80000) new_difficulty = 4; // Impossible else if (adjusted_score < 125000) new_difficulty = 5; // Insanity else if (adjusted_score < 200000) new_difficulty = 6; // Suicide else if (adjusted_score < 400000) new_difficulty = 7; // Maniacal else if (adjusted_score < 600000) new_difficulty = 8; // Zinglon else new_difficulty = 9; // Nortaneous } else { if (adjusted_score < 40000) new_difficulty = 1; // Easy else if (adjusted_score < 70000) new_difficulty = 2; // Normal else if (adjusted_score < 150000) new_difficulty = 3; // Hard else if (adjusted_score < 300000) new_difficulty = 4; // Impossible else if (adjusted_score < 600000) new_difficulty = 5; // Insanity else if (adjusted_score < 1000000) new_difficulty = 6; // Suicide else if (adjusted_score < 2000000) new_difficulty = 7; // Maniacal else if (adjusted_score < 3000000) new_difficulty = 8; // Zinglon else new_difficulty = 9; // Nortaneous } difficultyLevel = MAX((unsigned)difficultyLevel, new_difficulty); } bool load_next_demo( void ) { if (++demo_num > 5) demo_num = 1; char demo_filename[9]; snprintf(demo_filename, sizeof(demo_filename), "demo.%d", demo_num); demo_file = dir_fopen_die(data_dir(), demo_filename, "rb"); // TODO: only play demos from existing file (instead of dying) difficultyLevel = 2; bonusLevelCurrent = false; Uint8 temp = fgetc(demo_file); JE_initEpisode(temp); efread(levelName, 1, 10, demo_file); levelName[10] = '\0'; lvlFileNum = fgetc(demo_file); player[0].items.weapon[FRONT_WEAPON].id = fgetc(demo_file); player[0].items.weapon[REAR_WEAPON].id = fgetc(demo_file); player[0].items.super_arcade_mode = fgetc(demo_file); player[0].items.sidekick[LEFT_SIDEKICK] = fgetc(demo_file); player[0].items.sidekick[RIGHT_SIDEKICK] = fgetc(demo_file); player[0].items.generator = fgetc(demo_file); player[0].items.sidekick_level = fgetc(demo_file); // could probably ignore player[0].items.sidekick_series = fgetc(demo_file); // could probably ignore initial_episode_num = fgetc(demo_file); // could probably ignore player[0].items.shield = fgetc(demo_file); player[0].items.special = fgetc(demo_file); player[0].items.ship = fgetc(demo_file); for (uint i = 0; i < 2; ++i) player[0].items.weapon[i].power = fgetc(demo_file); fseek(demo_file, 3, SEEK_CUR); levelSong = fgetc(demo_file); demo_keys_wait = 0; demo_keys = next_demo_keys = 0; printf("loaded demo '%s'\n", demo_filename); return true; } bool replay_demo_keys( void ) { if (demo_keys_wait == 0) if (read_demo_keys() == false) return false; // no more keys if (demo_keys_wait > 0) demo_keys_wait--; if (demo_keys & (1 << 0)) player[0].y -= CURRENT_KEY_SPEED; if (demo_keys & (1 << 1)) player[0].y += CURRENT_KEY_SPEED; if (demo_keys & (1 << 2)) player[0].x -= CURRENT_KEY_SPEED; if (demo_keys & (1 << 3)) player[0].x += CURRENT_KEY_SPEED; button[0] = (bool)(demo_keys & (1 << 4)); button[3] = (bool)(demo_keys & (1 << 5)); button[1] = (bool)(demo_keys & (1 << 6)); button[2] = (bool)(demo_keys & (1 << 7)); return true; } bool read_demo_keys( void ) { demo_keys = next_demo_keys; efread(&demo_keys_wait, sizeof(Uint16), 1, demo_file); demo_keys_wait = SDL_Swap16(demo_keys_wait); next_demo_keys = getc(demo_file); return !feof(demo_file); } /*Street Fighter codes*/ void JE_SFCodes( JE_byte playerNum_, JE_integer PX_, JE_integer PY_, JE_integer mouseX_, JE_integer mouseY_ ) { JE_byte temp, temp2, temp3, temp4, temp5; uint ship = player[playerNum_-1].items.ship; /*Get direction*/ if (playerNum_ == 2 && ship < 15) { ship = 0; } if (ship < 15) { temp2 = (mouseY_ > PY_) + /*UP*/ (mouseY_ < PY_) + /*DOWN*/ (PX_ < mouseX_) + /*LEFT*/ (PX_ > mouseX_); /*RIGHT*/ temp = (mouseY_ > PY_) * 1 + /*UP*/ (mouseY_ < PY_) * 2 + /*DOWN*/ (PX_ < mouseX_) * 3 + /*LEFT*/ (PX_ > mouseX_) * 4; /*RIGHT*/ if (temp == 0) // no direction being pressed { if (!button[0]) // if fire button is released { temp = 9; temp2 = 1; } else { temp2 = 0; temp = 99; } } if (temp2 == 1) // if exactly one direction pressed or firebutton is released { temp += button[0] * 4; temp3 = superTyrian ? 21 : 3; for (temp2 = 0; temp2 < temp3; temp2++) { /*Use SuperTyrian ShipCombos or not?*/ temp5 = superTyrian ? shipCombosB[temp2] : shipCombos[ship][temp2]; // temp5 == selected combo in ship if (temp5 == 0) /* combo doesn't exists */ { // mark twiddles as cancelled/finished SFCurrentCode[playerNum_-1][temp2] = 0; } else { // get next combo key temp4 = keyboardCombos[temp5-1][SFCurrentCode[playerNum_-1][temp2]]; // correct key if (temp4 == temp) { SFCurrentCode[playerNum_-1][temp2]++; temp4 = keyboardCombos[temp5-1][SFCurrentCode[playerNum_-1][temp2]]; if (temp4 > 100 && temp4 <= 100 + SPECIAL_NUM) { SFCurrentCode[playerNum_-1][temp2] = 0; SFExecuted[playerNum_-1] = temp4 - 100; } } else { if ((temp != 9) && (temp4 - 1) % 4 != (temp - 1) % 4 && (SFCurrentCode[playerNum_-1][temp2] == 0 || keyboardCombos[temp5-1][SFCurrentCode[playerNum_-1][temp2]-1] != temp)) { SFCurrentCode[playerNum_-1][temp2] = 0; } } } } } } } void JE_sort( void ) { JE_byte a, b; for (a = 0; a < 2; a++) { for (b = a + 1; b < 3; b++) { if (saveFiles[temp + a].highScore1 < saveFiles[temp + b].highScore1) { JE_longint tempLI; char tempStr[30]; JE_byte tempByte; tempLI = saveFiles[temp + a].highScore1; saveFiles[temp + a].highScore1 = saveFiles[temp + b].highScore1; saveFiles[temp + b].highScore1 = tempLI; strcpy(tempStr, saveFiles[temp + a].highScoreName); strcpy(saveFiles[temp + a].highScoreName, saveFiles[temp + b].highScoreName); strcpy(saveFiles[temp + b].highScoreName, tempStr); tempByte = saveFiles[temp + a].highScoreDiff; saveFiles[temp + a].highScoreDiff = saveFiles[temp + b].highScoreDiff; saveFiles[temp + b].highScoreDiff = tempByte; } } } } void JE_playCredits( void ) { const int lines_max = 132; const int line_max_length = 65; char credstr[lines_max][line_max_length + 1]; int lines = 0; JE_byte currentpic = 0, fade = 0; JE_shortint fadechg = 1; JE_byte currentship = 0; JE_integer shipx = 0, shipxwait = 0; JE_shortint shipxc = 0, shipxca = 0; load_sprites_file(EXTRA_SHAPES, "estsc.shp"); setjasondelay2(1000); play_song(8); // load credits text FILE *f = dir_fopen_die(data_dir(), "tyrian.cdt", "rb"); for (lines = 0; !feof(f) && lines < lines_max; ++lines) { read_encrypted_pascal_string(credstr[lines], sizeof(credstr[lines]), f); } if (lines == lines_max) --lines; fclose(f); memcpy(colors, palettes[6-1], sizeof(colors)); JE_clr256(VGAScreen); JE_showVGA(); fade_palette(colors, 2, 0, 255); //tempScreenSeg = VGAScreenSeg; const int ticks_max = lines * 20 * 3; for (int ticks = 0; ticks < ticks_max; ++ticks) { setjasondelay(1); JE_clr256(VGAScreen); blit_sprite_hv(VGAScreenSeg, 319 - sprite(EXTRA_SHAPES, currentpic)->width, 100 - (sprite(EXTRA_SHAPES, currentpic)->height / 2), EXTRA_SHAPES, currentpic, 0x0, fade - 15); fade += fadechg; if (fade == 0 && fadechg == -1) { fadechg = 1; ++currentpic; if (currentpic >= sprite_table[EXTRA_SHAPES].count) currentpic = 0; } if (fade == 15) fadechg = 0; if (delaycount2() == 0) { fadechg = -1; setjasondelay2(900); } if (ticks % 200 == 0) { currentship = (mt_rand() % 11) + 1; shipxwait = (mt_rand() % 80) + 10; if ((mt_rand() % 2) == 1) { shipx = 1; shipxc = 0; shipxca = 1; } else { shipx = 900; shipxc = 0; shipxca = -1; } } shipxwait--; if (shipxwait == 0) { if (shipx == 1 || shipx == 900) shipxc = 0; shipxca = -shipxca; shipxwait = (mt_rand() % 40) + 15; } shipxc += shipxca; shipx += shipxc; if (shipx < 1) { shipx = 1; shipxwait = 1; } if (shipx > 900) { shipx = 900; shipxwait = 1; } tempI = shipxc * shipxc; if (450 + tempI < 0 || 450 + tempI > 900) { if (shipxca < 0 && shipxc < 0) shipxwait = 1; if (shipxca > 0 && shipxc > 0) shipxwait = 1; } uint ship_sprite = ships[currentship].shipgraphic; if (shipxc < -10) ship_sprite -= (shipxc < -20) ? 4 : 2; else if (shipxc > 10) ship_sprite += (shipxc > 20) ? 4 : 2; blit_sprite2x2(VGAScreen, shipx / 40, 184 - (ticks % 200), shapes9, ship_sprite); const int bottom_line = (ticks / 3) / 20; int y = 20 - ((ticks / 3) % 20); for (int line = bottom_line - 10; line < bottom_line; ++line) { if (line >= 0 && line < lines_max) { if (strcmp(&credstr[line][0], ".") != 0 && strlen(credstr[line])) { const Uint8 color = credstr[line][0] - 65; const char *text = &credstr[line][1]; const int x = 110 - JE_textWidth(text, SMALL_FONT_SHAPES) / 2; JE_outTextAdjust(VGAScreen, x + abs((y / 18) % 4 - 2) - 1, y - 1, text, color, -8, SMALL_FONT_SHAPES, false); JE_outTextAdjust(VGAScreen, x, y, text, color, -2, SMALL_FONT_SHAPES, false); } } y += 20; } fill_rectangle_xy(VGAScreen, 0, 0, 319, 10, 0); fill_rectangle_xy(VGAScreen, 0, 190, 319, 199, 0); if (currentpic == sprite_table[EXTRA_SHAPES].count - 1) JE_outTextAdjust(VGAScreen, 5, 180, miscText[54], 2, -2, SMALL_FONT_SHAPES, false); // levels-in-episode if (bottom_line == lines_max - 8) fade_song(); if (ticks == ticks_max - 1) { --ticks; play_song(9); } NETWORK_KEEP_ALIVE(); JE_showVGA(); wait_delay(); if (JE_anyButton()) break; } fade_black(10); free_sprites(EXTRA_SHAPES); } void JE_endLevelAni( void ) { JE_word x, y; JE_byte temp; char tempStr[256]; Sint8 i; if (!constantPlay) { // grant shipedit privileges // special if (player[0].items.special < 21) saveTemp[SAVE_FILES_SIZE + 81 + player[0].items.special] = 1; for (uint p = 0; p < COUNTOF(player); ++p) { // front, rear for (uint i = 0; i < COUNTOF(player[p].items.weapon); ++i) saveTemp[SAVE_FILES_SIZE + player[p].items.weapon[i].id] = 1; // options for (uint i = 0; i < COUNTOF(player[p].items.sidekick); ++i) saveTemp[SAVE_FILES_SIZE + 51 + player[p].items.sidekick[i]] = 1; } } adjust_difficulty(); player[0].last_items = player[0].items; strcpy(lastLevelName, levelName); JE_wipeKey(); frameCountMax = 4; textGlowFont = SMALL_FONT_SHAPES; SDL_Color white = { 255, 255, 255 }; set_colors(white, 254, 254); if (!levelTimer || levelTimerCountdown > 0 || !(episodeNum == 4)) JE_playSampleNum(V_LEVEL_END); else play_song(21); if (bonusLevel) { JE_outTextGlow(VGAScreenSeg, 20, 20, miscText[17-1]); } else if (all_players_alive()) { sprintf(tempStr, "%s %s", miscText[27-1], levelName); // "Completed" JE_outTextGlow(VGAScreenSeg, 20, 20, tempStr); } else { sprintf(tempStr, "%s %s", miscText[62-1], levelName); // "Exiting" JE_outTextGlow(VGAScreenSeg, 20, 20, tempStr); } if (twoPlayerMode) { for (uint i = 0; i < 2; ++i) { snprintf(tempStr, sizeof(tempStr), "%s %lu", miscText[40 + i], player[i].cash); JE_outTextGlow(VGAScreenSeg, 30, 50 + 20 * i, tempStr); } } else { sprintf(tempStr, "%s %lu", miscText[28-1], player[0].cash); JE_outTextGlow(VGAScreenSeg, 30, 50, tempStr); } temp = (totalEnemy == 0) ? 0 : roundf(enemyKilled * 100 / totalEnemy); sprintf(tempStr, "%s %d%%", miscText[63-1], temp); JE_outTextGlow(VGAScreenSeg, 40, 90, tempStr); if (!constantPlay) editorLevel += temp / 5; if (!onePlayerAction && !twoPlayerMode) { JE_outTextGlow(VGAScreenSeg, 30, 120, miscText[4-1]); /*Cubes*/ if (cubeMax > 0) { if (cubeMax > 4) cubeMax = 4; if (frameCountMax != 0) frameCountMax = 1; for (temp = 1; temp <= cubeMax; temp++) { NETWORK_KEEP_ALIVE(); JE_playSampleNum(18); x = 20 + 30 * temp; y = 135; JE_drawCube(VGAScreenSeg, x, y, 9, 0); JE_showVGA(); for (i = -15; i <= 10; i++) { setjasondelay(frameCountMax); blit_sprite_hv(VGAScreenSeg, x, y, OPTION_SHAPES, 25, 0x9, i); if (JE_anyButton()) frameCountMax = 0; JE_showVGA(); wait_delay(); } for (i = 10; i >= 0; i--) { setjasondelay(frameCountMax); blit_sprite_hv(VGAScreenSeg, x, y, OPTION_SHAPES, 25, 0x9, i); if (JE_anyButton()) frameCountMax = 0; JE_showVGA(); wait_delay(); } } } else { JE_outTextGlow(VGAScreenSeg, 50, 135, miscText[15-1]); } } if (frameCountMax != 0) { frameCountMax = 6; temp = 1; } else { temp = 0; } temp2 = twoPlayerMode ? 150 : 160; JE_outTextGlow(VGAScreenSeg, 90, temp2, miscText[5-1]); if (!constantPlay) { do { setjasondelay(1); NETWORK_KEEP_ALIVE(); wait_delay(); } while (!(JE_anyButton() || (frameCountMax == 0 && temp == 1))); } wait_noinput(false, false, true); // TODO: should up the joystick repeat temporarily instead fade_black(15); JE_clr256(VGAScreen); } void JE_drawCube( SDL_Surface * screen, JE_word x, JE_word y, JE_byte filter, JE_byte brightness ) { blit_sprite_dark(screen, x + 4, y + 4, OPTION_SHAPES, 25, false); blit_sprite_dark(screen, x + 3, y + 3, OPTION_SHAPES, 25, false); blit_sprite_hv(screen, x, y, OPTION_SHAPES, 25, filter, brightness); } void JE_handleChat( void ) { // STUB(); Annoying piece of crap =P } bool str_pop_int( char *str, int *val ) { bool success = false; char buf[256]; assert(strlen(str) < sizeof(buf)); // grab the value from str char *end; *val = strtol(str, &end, 10); if (end != str) { success = true; // shift the rest to the beginning strcpy(buf, end); strcpy(str, buf); } return success; } void JE_operation( JE_byte slot ) { JE_byte flash; char stemp[21]; char tempStr[51]; if (!performSave) { if (saveFiles[slot-1].level > 0) { gameJustLoaded = true; JE_loadGame(slot); gameLoaded = true; } } else if (slot % 11 != 0) { strcpy(stemp, " "); memcpy(stemp, saveFiles[slot-1].name, strlen(saveFiles[slot-1].name)); temp = strlen(stemp); while (stemp[temp-1] == ' ' && --temp); flash = 8 * 16 + 10; wait_noinput(false, true, false); JE_barShade(VGAScreen, 65, 55, 255, 155); bool quit = false; while (!quit) { service_SDL_events(true); blit_sprite(VGAScreen, 50, 50, OPTION_SHAPES, 35); // message box JE_textShade(VGAScreen, 60, 55, miscText[1-1], 11, 4, DARKEN); JE_textShade(VGAScreen, 70, 70, levelName, 11, 4, DARKEN); do { flash = (flash == 8 * 16 + 10) ? 8 * 16 + 2 : 8 * 16 + 10; temp3 = (temp3 == 6) ? 2 : 6; strcpy(tempStr, miscText[2-1]); strncat(tempStr, stemp, temp); JE_outText(VGAScreen, 65, 89, tempStr, 8, 3); tempW = 65 + JE_textWidth(tempStr, TINY_FONT); JE_barShade(VGAScreen, tempW + 2, 90, tempW + 6, 95); fill_rectangle_xy(VGAScreen, tempW + 1, 89, tempW + 5, 94, flash); for (int i = 0; i < 14; i++) { setjasondelay(1); JE_mouseStart(); JE_showVGA(); JE_mouseReplace(); push_joysticks_as_keyboard(); service_wait_delay(); if (newkey || newmouse) break; } } while (!newkey && !newmouse); /* if (mouseButton > 0) { if (mouseX > 56 && mouseX < 142 && mouseY > 123 && mouseY < 149) { quit = true; JE_saveGame(slot, stemp); JE_playSampleNum(S_SELECT); } else if (mouseX > 151 && mouseX < 237 && mouseY > 123 && mouseY < 149) { quit = true; JE_playSampleNum(S_SPRING); } } else */ if (newkey || newmouse) { bool validkey = false; lastkey_char = toupper(lastkey_char); if(mouse_pressed[0]) lastkey_char = SDLK_SPACE; switch (lastkey_char) { //case ' ': case '-': case '.': case ',': case ':': case '!': case '?': case '#': case '@': case '$': case '%': case '*': case '(': case ')': case '/': case '=': case '+': case '<': case '>': case ';': case '"': case '\'': validkey = true; default: if (temp < 14 && (validkey || (lastkey_char >= 'A' && lastkey_char <= 'Z') || (lastkey_char >= '0' && lastkey_char <= '9'))) { JE_playSampleNum(S_CURSOR); stemp[temp] = lastkey_char; temp++; } break; case SDLK_BACKSPACE: case SDLK_DELETE: if (temp) { temp--; stemp[temp] = ' '; JE_playSampleNum(S_CLICK); } break; case SDLK_ESCAPE: quit = true; JE_playSampleNum(S_SPRING); break; case SDLK_RETURN: case SDLK_SPACE: quit = true; JE_saveGame(slot, stemp); JE_playSampleNum(S_SELECT); break; } } } } wait_noinput(false, true, false); } void JE_inGameDisplays( void ) { char stemp[21]; char tempstr[256]; for (uint i = 0; i < ((twoPlayerMode && !galagaMode) ? 2 : 1); ++i) { snprintf(tempstr, sizeof(tempstr), "%lu", player[i].cash); JE_textShade(VGAScreen, 30 + 200 * i, 175, tempstr, 2, 4, FULL_SHADE); } /*Special Weapon?*/ if (player[0].items.special > 0) blit_sprite2x2(VGAScreen, 25, 1, eShapes6, special[player[0].items.special].itemgraphic); /*Lives Left*/ if (onePlayerAction || twoPlayerMode) { for (int temp = 0; temp < (onePlayerAction ? 1 : 2); temp++) { const uint extra_lives = *player[temp].lives - 1; temp5 = (temp == 0 && player[0].items.special > 0) ? 35 : 15; tempW = (temp == 0) ? 30: 270; if (extra_lives >= 5) { blit_sprite2(VGAScreen, tempW, temp5, shapes9, 285); tempW = (temp == 0) ? 45 : 250; sprintf(tempstr, "%d", extra_lives); JE_textShade(VGAScreen, tempW, temp5 + 3, tempstr, 15, 1, FULL_SHADE); } else if (extra_lives >= 1) { for (uint i = 0; i < extra_lives; ++i) { blit_sprite2(VGAScreen, tempW, temp5, shapes9, 285); tempW += (temp == 0) ? 12 : -12; } } strcpy(stemp, (temp == 0) ? miscText[49-1] : miscText[50-1]); if (isNetworkGame) { strcpy(stemp, JE_getName(temp+1)); } tempW = (temp == 0) ? 28 : (285 - JE_textWidth(stemp, TINY_FONT)); JE_textShade(VGAScreen, tempW, temp5 - 7, stemp, 2, 6, FULL_SHADE); } } /*Super Bombs!!*/ for (uint i = 0; i < COUNTOF(player); ++i) { int x = (i == 0) ? 30 : 270; for (uint j = player[i].superbombs; j > 0; --j) { blit_sprite2(VGAScreen, x, 160, shapes9, 304); x += (i == 0) ? 12 : -12; } } if (youAreCheating) { JE_outText(VGAScreen, 90, 170, "Cheaters always prosper.", 3, 4); } } void JE_mainKeyboardInput( void ) { JE_gammaCheck(); /* { Network Request Commands } */ if (!isNetworkGame) { /* { Edited Ships } for Player 1 */ if (extraAvail && keysactive[SDLK_TAB] && !isNetworkGame && !superTyrian) { for (x = SDLK_0; x <= SDLK_9; x++) { if (keysactive[x]) { int z = x == SDLK_0 ? 10 : x - SDLK_0; player[0].items.ship = 90 + z; /*Ships*/ z = (z - 1) * 15; player[0].items.weapon[FRONT_WEAPON].id = extraShips[z + 1]; player[0].items.weapon[REAR_WEAPON].id = extraShips[z + 2]; player[0].items.special = extraShips[z + 3]; player[0].items.sidekick[LEFT_SIDEKICK] = extraShips[z + 4]; player[0].items.sidekick[RIGHT_SIDEKICK] = extraShips[z + 5]; player[0].items.generator = extraShips[z + 6]; /*Armor*/ player[0].items.shield = extraShips[z + 8]; memset(shotMultiPos, 0, sizeof(shotMultiPos)); if (player[0].weapon_mode > JE_portConfigs()) player[0].weapon_mode = 1; tempW = player[0].armor; JE_getShipInfo(); if (player[0].armor > tempW && editShip1) player[0].armor = tempW; else editShip1 = true; SDL_Surface *temp_surface = VGAScreen; VGAScreen = VGAScreenSeg; JE_wipeShieldArmorBars(); JE_drawArmor(); JE_drawShield(); VGAScreen = temp_surface; JE_drawOptions(); keysactive[x] = false; } } } /* for Player 2 */ if (extraAvail && keysactive[SDLK_CAPSLOCK] && !isNetworkGame && !superTyrian) { for (x = SDLK_0; x <= SDLK_9; x++) { if (keysactive[x]) { int z = x == SDLK_0 ? 10 : x - SDLK_0; player[1].items.ship = 90 + z; z = (z - 1) * 15; player[1].items.weapon[FRONT_WEAPON].id = extraShips[z + 1]; player[1].items.weapon[REAR_WEAPON].id = extraShips[z + 2]; player[1].items.special = extraShips[z + 3]; player[1].items.sidekick[LEFT_SIDEKICK] = extraShips[z + 4]; player[1].items.sidekick[RIGHT_SIDEKICK] = extraShips[z + 5]; player[1].items.generator = extraShips[z + 6]; /*Armor*/ player[1].items.shield = extraShips[z + 8]; memset(shotMultiPos, 0, sizeof(shotMultiPos)); if (player[1].weapon_mode > JE_portConfigs()) player[1].weapon_mode = 1; tempW = player[1].armor; JE_getShipInfo(); if (player[1].armor > tempW && editShip2) player[1].armor = tempW; else editShip2 = true; SDL_Surface *temp_surface = VGAScreen; VGAScreen = VGAScreenSeg; JE_wipeShieldArmorBars(); JE_drawArmor(); JE_drawShield(); VGAScreen = temp_surface; JE_drawOptions(); keysactive[x] = false; } } } } /* { In-Game Help } */ if (keysactive[SDLK_F1]) { if (isNetworkGame) { helpRequest = true; } else { JE_inGameHelp(); skipStarShowVGA = true; } } /* {!Activate Nort Ship!} */ if (keysactive[SDLK_F2] && keysactive[SDLK_F4] && keysactive[SDLK_F6] && keysactive[SDLK_F7] && keysactive[SDLK_F9] && keysactive[SDLK_BACKSLASH] && keysactive[SDLK_SLASH]) { if (isNetworkGame) { nortShipRequest = true; } else { player[0].items.ship = 12; player[0].items.special = 13; player[0].items.weapon[REAR_WEAPON].id = 36; shipGr = 1; } } /* {Cheating} */ if (!isNetworkGame && !twoPlayerMode && !superTyrian && superArcadeMode == SA_NONE) { if (keysactive[SDLK_F2] && keysactive[SDLK_F3] && keysactive[SDLK_F6]) { youAreCheating = !youAreCheating; keysactive[SDLK_F2] = false; } if (keysactive[SDLK_F2] && keysactive[SDLK_F3] && (keysactive[SDLK_F4] || keysactive[SDLK_F5]) && !superTyrian) { for (uint i = 0; i < COUNTOF(player); ++i) player[i].armor = 0; youAreCheating = !youAreCheating; JE_drawTextWindow(miscText[63-1]); } if (constantPlay && keysactive[SDLK_c] && !superTyrian && superArcadeMode == SA_NONE) { youAreCheating = !youAreCheating; keysactive[SDLK_c] = false; } } if (superTyrian) { youAreCheating = false; } /* {Personal Commands} */ /* {DEBUG} */ if (keysactive[SDLK_F10] && keysactive[SDLK_BACKSPACE]) { keysactive[SDLK_F10] = false; debug = !debug; debugHist = 1; debugHistCount = 1; /* YKS: clock ticks since midnight replaced by SDL_GetTicks */ lastDebugTime = SDL_GetTicks(); } /* {CHEAT-SKIP LEVEL} */ if (keysactive[SDLK_F2] && keysactive[SDLK_F6] && (keysactive[SDLK_F7] || keysactive[SDLK_F8]) && !keysactive[SDLK_F9] && !superTyrian && superArcadeMode == SA_NONE) { if (isNetworkGame) { skipLevelRequest = true; } else { levelTimer = true; levelTimerCountdown = 0; endLevel = true; levelEnd = 40; } } /* pause game */ pause_pressed = pause_pressed || keysactive[SDLK_p]; /* in-game setup */ ingamemenu_pressed = ingamemenu_pressed || keysactive[SDLK_ESCAPE]; /* {MUTE SOUND} */ if (keysactive[SDLK_s]) { keysactive[SDLK_s] = false; samples_disabled = !samples_disabled; JE_drawTextWindow(samples_disabled ? miscText[17] : miscText[18]); } /* {MUTE MUSIC} */ if (keysactive[SDLK_m]) { keysactive[SDLK_m] = false; music_disabled = !music_disabled; if (!music_disabled) restart_song(); JE_drawTextWindow(music_disabled ? miscText[35] : miscText[36]); } if (keysactive[SDLK_BACKSPACE]) { /* toggle screenshot pause */ if (keysactive[SDLK_NUMLOCK]) { superPause = !superPause; } /* {SMOOTHIES} */ if (keysactive[SDLK_F12] && keysactive[SDLK_SCROLLOCK]) { for (temp = SDLK_2; temp <= SDLK_9; temp++) { if (keysactive[temp]) { smoothies[temp-SDLK_2] = !smoothies[temp-SDLK_2]; } } if (keysactive[SDLK_0]) { smoothies[8] = !smoothies[8]; } } else /* {CYCLE THROUGH FILTER COLORS} */ if (keysactive[SDLK_MINUS]) { if (levelFilter == -99) { levelFilter = 0; } else { levelFilter++; if (levelFilter == 16) { levelFilter = -99; } } } else /* {HYPER-SPEED} */ if (keysactive[SDLK_1]) { fastPlay++; if (fastPlay > 2) { fastPlay = 0; } keysactive[SDLK_1] = false; JE_setNewGameSpeed(); } /* {IN-GAME RANDOM MUSIC SELECTION} */ if (keysactive[SDLK_SCROLLOCK]) { play_song(mt_rand() % MUSIC_NUM); } } } void JE_pauseGame( void ) { JE_boolean done = false; JE_word mouseX, mouseY; //tempScreenSeg = VGAScreenSeg; // sega000 if (!superPause) { JE_dString(VGAScreenSeg, 120, 90, miscText[22], FONT_SHAPES); VGAScreen = VGAScreenSeg; JE_showVGA(); } set_volume(tyrMusicVolume / 2, fxVolume); if (isNetworkGame) { network_prepare(PACKET_GAME_PAUSE); network_send(4); // PACKET_GAME_PAUSE while (true) { service_SDL_events(false); if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_GAME_PAUSE) { network_update(); break; } network_update(); network_check(); SDL_Delay(16); } } wait_noinput(false, false, true); // TODO: should up the joystick repeat temporarily instead do { setjasondelay(2); push_joysticks_as_keyboard(); service_SDL_events(true); if ((newkey && lastkey_sym != SDLK_LCTRL && lastkey_sym != SDLK_RCTRL && lastkey_sym != SDLK_LALT && lastkey_sym != SDLK_RALT) || JE_mousePosition(&mouseX, &mouseY) > 0) { if (isNetworkGame) { network_prepare(PACKET_WAITING); network_send(4); // PACKET_WAITING } done = true; } if (isNetworkGame) { network_check(); if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_WAITING) { network_check(); done = true; } } wait_delay(); } while (!done); if (isNetworkGame) { while (!network_is_sync()) { service_SDL_events(false); network_check(); SDL_Delay(16); } } set_volume(tyrMusicVolume, fxVolume); //skipStarShowVGA = true; } void JE_playerMovement( Player *this_player, JE_byte inputDevice, JE_byte playerNum_, JE_word shipGr_, Sprite2_array *shapes9ptr_, JE_word *mouseX_, JE_word *mouseY_ ) { JE_integer mouseXC, mouseYC; JE_integer accelXC, accelYC; if (playerNum_ == 2 || !twoPlayerMode) { tempW = weaponPort[this_player->items.weapon[REAR_WEAPON].id].opnum; if (this_player->weapon_mode > tempW) this_player->weapon_mode = 1; } if (isNetworkGame && thisPlayerNum == playerNum_) { network_state_prepare(); memset(&packet_state_out[0]->data[4], 0, 10); } redo: if (isNetworkGame) { inputDevice = 0; } mouseXC = 0; mouseYC = 0; accelXC = 0; accelYC = 0; bool link_gun_analog = false; float link_gun_angle = 0; /* Draw Player */ if (!this_player->is_alive) { if (this_player->exploding_ticks > 0) { --this_player->exploding_ticks; if (levelEndFxWait > 0) { levelEndFxWait--; } else { levelEndFxWait = (mt_rand() % 6) + 3; if ((mt_rand() % 3) == 1) soundQueue[6] = S_EXPLOSION_9; else soundQueue[5] = S_EXPLOSION_11; } tempW = this_player->x + (mt_rand() % 32) - 16; tempW2 = this_player->y + (mt_rand() % 32) - 16; JE_setupExplosionLarge(false, 0, this_player->x + (mt_rand() % 32) - 16, this_player->y + (mt_rand() % 32) - 16 + 7); JE_setupExplosionLarge(false, 0, this_player->x, this_player->y + 7); if (levelEnd > 0) levelEnd--; } else { if (twoPlayerMode || onePlayerAction) // if arcade mode { if (*this_player->lives > 1) // respawn if any extra lives { --(*this_player->lives); reallyEndLevel = false; shotMultiPos[playerNum_-1] = 0; calc_purple_balls_needed(this_player); twoPlayerLinked = false; if (galagaMode) twoPlayerMode = false; this_player->y = 160; this_player->invulnerable_ticks = 100; this_player->is_alive = true; endLevel = false; if (galagaMode || episodeNum == 4) this_player->armor = this_player->initial_armor; else this_player->armor = this_player->initial_armor / 2; if (galagaMode) this_player->shield = 0; else this_player->shield = this_player->shield_max / 2; VGAScreen = VGAScreenSeg; /* side-effect of game_screen */ JE_drawArmor(); JE_drawShield(); VGAScreen = game_screen; /* side-effect of game_screen */ goto redo; } else { if (galagaMode) twoPlayerMode = false; if (allPlayersGone && isNetworkGame) reallyEndLevel = true; } } } } else if (constantDie) { // finished exploding? start dying again if (this_player->exploding_ticks == 0) { this_player->shield = 0; if (this_player->armor > 0) { --this_player->armor; } else { this_player->is_alive = false; this_player->exploding_ticks = 60; levelEnd = 40; } JE_wipeShieldArmorBars(); VGAScreen = VGAScreenSeg; /* side-effect of game_screen */ JE_drawArmor(); VGAScreen = game_screen; /* side-effect of game_screen */ // as if instant death weren't enough, player also gets infinite lives in order to enjoy an infinite number of deaths -_- if (*player[0].lives < 11) ++(*player[0].lives); } } if (!this_player->is_alive) { explosionFollowAmountX = explosionFollowAmountY = 0; return; } if (!endLevel) { *mouseX_ = this_player->x; *mouseY_ = this_player->y; if(autoFireMode != AUTOFIRE_BUTTON && autoFireMode != AUTOFIRE_BUTTON_TOUCH) button[1-1] = false; button[2-1] = false; button[3-1] = false; button[4-1] = false; /* --- Movement Routine Beginning --- */ if (!isNetworkGame || playerNum_ == thisPlayerNum) { if (endLevel) { this_player->y -= 2; } else { if (record_demo || play_demo) inputDevice = 1; // keyboard is required device for demo recording // demo playback input if (play_demo) { if (!replay_demo_keys()) { endLevel = true; levelEnd = 40; } } /* joystick input */ if ((inputDevice == 0 || inputDevice >= 3) && joysticks > 0) { int j = inputDevice == 0 ? 0 : inputDevice - 3; int j_max = inputDevice == 0 ? joysticks : inputDevice - 3 + 1; for (; j < j_max; j++) { poll_joystick(j); if (joystick[j].analog) { mouseXC += joystick_axis_reduce(j, joystick[j].x); mouseYC += joystick_axis_reduce(j, joystick[j].y); link_gun_analog = joystick_analog_angle(j, &link_gun_angle); } else { this_player->x += joystick[j].direction[3] ? -CURRENT_KEY_SPEED : 0 + joystick[j].direction[1] ? CURRENT_KEY_SPEED : 0; this_player->y += joystick[j].direction[0] ? -CURRENT_KEY_SPEED : 0 + joystick[j].direction[2] ? CURRENT_KEY_SPEED : 0; } button[0] |= joystick[j].action[0]; button[1] |= joystick[j].action[2]; button[2] |= joystick[j].action[3]; button[3] |= joystick[j].action_pressed[1]; ingamemenu_pressed |= joystick[j].action_pressed[4]; pause_pressed |= joystick[j].action_pressed[5]; } } service_SDL_events(false); /* mouse input */ /* if ((inputDevice == 0 || inputDevice == 2) && has_mouse) { button[0] |= mouse_pressed[0]; button[1] |= mouse_pressed[1]; button[2] |= mouse_has_three_buttons ? mouse_pressed[2] : mouse_pressed[1]; if (input_grabbed) { mouseXC += mouse_x - 159; mouseYC += mouse_y - 100; } if ((!isNetworkGame || playerNum_ == thisPlayerNum) && (!galagaMode || (playerNum_ == 2 || !twoPlayerMode || player[1].exploding_ticks > 0))) { set_mouse_position(159, 100); } } */ /* keyboard input */ if ((inputDevice == 0 || inputDevice == 1 || inputDevice == 2) && !play_demo) { /* Move ship above user finger */ int shifted_mouse_x = mouse_x + 15; int shifted_mouse_y = mouse_y; if( touchscreenMode == TOUCHSCREEN_SHIP_ABOVE_FINGER ) { if( shifted_mouse_y > 160 ) shifted_mouse_y += shifted_mouse_y - 160; shifted_mouse_y -= 45; } if( touchscreenMode == TOUCHSCREEN_SHIP_TO_THE_LEFT ) { shifted_mouse_x -= 30; } if (keysactive[keySettings[0]] || (has_mouse && mouse_pressed[0] && (shifted_mouse_y < this_player->y && touchscreenMode < TOUCHSCREEN_FIRE_ONLY))) this_player->y -= CURRENT_KEY_SPEED; if (keysactive[keySettings[1]] || (has_mouse && mouse_pressed[0] && (shifted_mouse_y > this_player->y && touchscreenMode < TOUCHSCREEN_FIRE_ONLY))) this_player->y += CURRENT_KEY_SPEED; if (keysactive[keySettings[2]] || (has_mouse && mouse_pressed[0] && (shifted_mouse_x < this_player->x && touchscreenMode < TOUCHSCREEN_FIRE_ONLY))) this_player->x -= CURRENT_KEY_SPEED; if (keysactive[keySettings[3]] || (has_mouse && mouse_pressed[0] && (shifted_mouse_x > this_player->x && touchscreenMode < TOUCHSCREEN_FIRE_ONLY))) this_player->x += CURRENT_KEY_SPEED; if( autoFireMode == AUTOFIRE_BUTTON || autoFireMode == AUTOFIRE_BUTTON_TOUCH ) { if(newkey && keydown && lastkey_sym == keySettings[4]) button[0] = ! button[0]; else if (autoFireMode == AUTOFIRE_BUTTON_TOUCH) { static int prevState = 0; if( mouse_pressed[0] && prevState != button[0] ) { button[0] = ! button[0]; prevState = button[0]; } else if( ! mouse_pressed[0] ) prevState = ! button[0]; } } else { button[0] = button[0] || keysactive[keySettings[4]] || ( mouse_pressed[0] && ( touchscreenMode != TOUCHSCREEN_NONE ) ); } button[3] = button[3] || keysactive[keySettings[5]]; button[1] = button[1] || keysactive[keySettings[6]]; button[2] = button[2] || keysactive[keySettings[7]]; if (constantPlay) { for (unsigned int i = 0; i < 4; i++) button[i] = true; ++this_player->y; this_player->x += constantLastX; } // TODO: check if demo recording still works if (record_demo) { bool new_input = false; for (unsigned int i = 0; i < 8; i++) { bool temp = demo_keys & (1 << i); if (temp != keysactive[keySettings[i]]) new_input = true; } demo_keys_wait++; if (new_input) { demo_keys_wait = SDL_Swap16(demo_keys_wait); efwrite(&demo_keys_wait, sizeof(Uint16), 1, demo_file); demo_keys = 0; for (unsigned int i = 0; i < 8; i++) demo_keys |= keysactive[keySettings[i]] ? (1 << i) : 0; fputc(demo_keys, demo_file); demo_keys_wait = 0; } } } if (smoothies[9-1]) { *mouseY_ = this_player->y - (*mouseY_ - this_player->y); mouseYC = -mouseYC; } accelXC += this_player->x - *mouseX_; accelYC += this_player->y - *mouseY_; if (mouseXC > 30) mouseXC = 30; else if (mouseXC < -30) mouseXC = -30; if (mouseYC > 30) mouseYC = 30; else if (mouseYC < -30) mouseYC = -30; if (mouseXC > 0) this_player->x += (mouseXC + 3) / 4; else if (mouseXC < 0) this_player->x += (mouseXC - 3) / 4; if (mouseYC > 0) this_player->y += (mouseYC + 3) / 4; else if (mouseYC < 0) this_player->y += (mouseYC - 3) / 4; if (mouseXC > 3) accelXC++; else if (mouseXC < -2) accelXC--; if (mouseYC > 2) accelYC++; else if (mouseYC < -2) accelYC--; } /*endLevel*/ if (isNetworkGame && playerNum_ == thisPlayerNum) { Uint16 buttons = 0; for (int i = 4 - 1; i >= 0; i--) { buttons <<= 1; buttons |= button[i]; } SDLNet_Write16(this_player->x - *mouseX_, &packet_state_out[0]->data[4]); SDLNet_Write16(this_player->y - *mouseY_, &packet_state_out[0]->data[6]); SDLNet_Write16(accelXC, &packet_state_out[0]->data[8]); SDLNet_Write16(accelYC, &packet_state_out[0]->data[10]); SDLNet_Write16(buttons, &packet_state_out[0]->data[12]); this_player->x = *mouseX_; this_player->y = *mouseY_; button[0] = false; button[1] = false; button[2] = false; button[3] = false; accelXC = 0; accelYC = 0; } } /*isNetworkGame*/ /* --- Movement Routine Ending --- */ moveOk = true; if (isNetworkGame && !network_state_is_reset()) { if (playerNum_ != thisPlayerNum) { if (thisPlayerNum == 2) difficultyLevel = SDLNet_Read16(&packet_state_in[0]->data[16]); Uint16 buttons = SDLNet_Read16(&packet_state_in[0]->data[12]); for (int i = 0; i < 4; i++) { button[i] = buttons & 1; buttons >>= 1; } this_player->x += (Sint16)SDLNet_Read16(&packet_state_in[0]->data[4]); this_player->y += (Sint16)SDLNet_Read16(&packet_state_in[0]->data[6]); accelXC = (Sint16)SDLNet_Read16(&packet_state_in[0]->data[8]); accelYC = (Sint16)SDLNet_Read16(&packet_state_in[0]->data[10]); } else { Uint16 buttons = SDLNet_Read16(&packet_state_out[network_delay]->data[12]); for (int i = 0; i < 4; i++) { button[i] = buttons & 1; buttons >>= 1; } this_player->x += (Sint16)SDLNet_Read16(&packet_state_out[network_delay]->data[4]); this_player->y += (Sint16)SDLNet_Read16(&packet_state_out[network_delay]->data[6]); accelXC = (Sint16)SDLNet_Read16(&packet_state_out[network_delay]->data[8]); accelYC = (Sint16)SDLNet_Read16(&packet_state_out[network_delay]->data[10]); } } /*Street-Fighter codes*/ JE_SFCodes(playerNum_, this_player->x, this_player->y, *mouseX_, *mouseY_); if (moveOk) { /* END OF MOVEMENT ROUTINES */ /*Linking Routines*/ if (twoPlayerMode && !twoPlayerLinked && this_player->x == *mouseX_ && this_player->y == *mouseY_ && abs(player[0].x - player[1].x) < 8 && abs(player[0].y - player[1].y) < 8 && player[0].is_alive && player[1].is_alive && !galagaMode) { twoPlayerLinked = true; } if (playerNum_ == 1 && (button[3-1] || button[2-1]) && !galagaMode) twoPlayerLinked = false; if (twoPlayerMode && twoPlayerLinked && playerNum_ == 2 && (this_player->x != *mouseX_ || this_player->y != *mouseY_)) { if (button[0]) { if (link_gun_analog) { linkGunDirec = link_gun_angle; } else { JE_real tempR; if (abs(this_player->x - *mouseX_) > abs(this_player->y - *mouseY_)) tempR = (this_player->x - *mouseX_ > 0) ? M_PI_2 : (M_PI + M_PI_2); else tempR = (this_player->y - *mouseY_ > 0) ? 0 : M_PI; if (fabsf(linkGunDirec - tempR) < 0.3f) linkGunDirec = tempR; else if (linkGunDirec < tempR && linkGunDirec - tempR > -3.24f) linkGunDirec += 0.2f; else if (linkGunDirec - tempR < M_PI) linkGunDirec -= 0.2f; else linkGunDirec += 0.2f; } if (linkGunDirec >= (2 * M_PI)) linkGunDirec -= (2 * M_PI); else if (linkGunDirec < 0) linkGunDirec += (2 * M_PI); } else if (!galagaMode) { twoPlayerLinked = false; } } } } if (levelEnd > 0 && all_players_dead()) reallyEndLevel = true; /* End Level Fade-Out */ if (this_player->is_alive && endLevel) { if (levelEnd == 0) { reallyEndLevel = true; } else { this_player->y -= levelEndWarp; if (this_player->y < -200) reallyEndLevel = true; tempI = 1; tempW2 = this_player->y; tempI2 = abs(41 - levelEnd); if (tempI2 > 20) tempI2 = 20; for (int z = 1; z <= tempI2; z++) { tempW2 += tempI; tempI++; } for (int z = 1; z <= tempI2; z++) { tempW2 -= tempI; tempI--; if (tempW2 > 0 && tempW2 < 170) { if (shipGr_ == 0) { blit_sprite2x2(VGAScreen, this_player->x - 17, tempW2 - 7, *shapes9ptr_, 13); blit_sprite2x2(VGAScreen, this_player->x + 7 , tempW2 - 7, *shapes9ptr_, 51); } else if (shipGr_ == 1) { blit_sprite2x2(VGAScreen, this_player->x - 17, tempW2 - 7, *shapes9ptr_, 220); blit_sprite2x2(VGAScreen, this_player->x + 7 , tempW2 - 7, *shapes9ptr_, 222); } else { blit_sprite2x2(VGAScreen, this_player->x - 5, tempW2 - 7, *shapes9ptr_, shipGr_); } } } } } if (play_demo) JE_dString(VGAScreen, 115, 10, miscText[7], SMALL_FONT_SHAPES); // insert coin if (this_player->is_alive && !endLevel) { if (!twoPlayerLinked || playerNum_ < 2) { if (!twoPlayerMode || shipGr2 != 0) // if not dragonwing { if (this_player->sidekick[LEFT_SIDEKICK].style == 0) { this_player->sidekick[LEFT_SIDEKICK].x = *mouseX_ - 14; this_player->sidekick[LEFT_SIDEKICK].y = *mouseY_; } if (this_player->sidekick[RIGHT_SIDEKICK].style == 0) { this_player->sidekick[RIGHT_SIDEKICK].x = *mouseX_ + 16; this_player->sidekick[RIGHT_SIDEKICK].y = *mouseY_; } } if (this_player->x_friction_ticks > 0) { --this_player->x_friction_ticks; } else { this_player->x_friction_ticks = 1; if (this_player->x_velocity < 0) ++this_player->x_velocity; else if (this_player->x_velocity > 0) --this_player->x_velocity; } if (this_player->y_friction_ticks > 0) { --this_player->y_friction_ticks; } else { this_player->y_friction_ticks = 2; if (this_player->y_velocity < 0) ++this_player->y_velocity; else if (this_player->y_velocity > 0) --this_player->y_velocity; } this_player->x_velocity += accelXC; this_player->y_velocity += accelYC; this_player->x_velocity = MIN(MAX(-4, this_player->x_velocity), 4); this_player->y_velocity = MIN(MAX(-4, this_player->y_velocity), 4); this_player->x += this_player->x_velocity; this_player->y += this_player->y_velocity; // if player moved, add new ship x, y history entry if (this_player->x - *mouseX_ != 0 || this_player->y - *mouseY_ != 0) { for (uint i = 1; i < COUNTOF(player->old_x); ++i) { this_player->old_x[i - 1] = this_player->old_x[i]; this_player->old_y[i - 1] = this_player->old_y[i]; } this_player->old_x[COUNTOF(player->old_x) - 1] = this_player->x; this_player->old_y[COUNTOF(player->old_x) - 1] = this_player->y; } } else /*twoPlayerLinked*/ { if (shipGr_ == 0) this_player->x = player[0].x - 1; else this_player->x = player[0].x; this_player->y = player[0].y + 8; this_player->x_velocity = player[0].x_velocity; this_player->y_velocity = 4; // turret direction marker/shield shotMultiPos[SHOT_MISC] = 0; JE_initPlayerShot(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_); shotMultiPos[SHOT_MISC] = 0; JE_initPlayerShot(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_); shotMultiPos[SHOT_MISC] = 0; JE_initPlayerShot(0, SHOT_MISC, this_player->x + 1 + roundf(sinf(linkGunDirec) * 26), this_player->y + roundf(cosf(linkGunDirec) * 26), *mouseX_, *mouseY_, 147, playerNum_); if (shotRepeat[SHOT_REAR] > 0) { --shotRepeat[SHOT_REAR]; } else if (button[1-1]) { shotMultiPos[SHOT_REAR] = 0; JE_initPlayerShot(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_); playerShotData[b].shotXM = -roundf(sinf(linkGunDirec) * playerShotData[b].shotYM); playerShotData[b].shotYM = -roundf(cosf(linkGunDirec) * playerShotData[b].shotYM); switch (this_player->items.weapon[REAR_WEAPON].id) { case 27: case 32: case 10: temp = roundf(linkGunDirec * (16 / (2 * M_PI))); /*16 directions*/ playerShotData[b].shotGr = linkMultiGr[temp]; break; case 28: case 33: case 11: temp = roundf(linkGunDirec * (16 / (2 * M_PI))); /*16 directions*/ playerShotData[b].shotGr = linkSonicGr[temp]; break; case 30: case 35: case 14: if (linkGunDirec > M_PI_2 && linkGunDirec < M_PI + M_PI_2) { playerShotData[b].shotYC = 1; } break; case 38: case 22: temp = roundf(linkGunDirec * (16 / (2 * M_PI))); /*16 directions*/ playerShotData[b].shotGr = linkMult2Gr[temp]; break; } } } } if (!endLevel) { if (this_player->x > 256) { this_player->x = 256; constantLastX = -constantLastX; } if (this_player->x < 40) { this_player->x = 40; constantLastX = -constantLastX; } if (isNetworkGame && playerNum_ == 1) { if (this_player->y > 154) this_player->y = 154; } else { if (this_player->y > 160) this_player->y = 160; } if (this_player->y < 10) this_player->y = 10; tempI2 = this_player->x_velocity / 2; tempI2 += (this_player->x - *mouseX_) / 6; if (tempI2 < -2) tempI2 = -2; else if (tempI2 > 2) tempI2 = 2; tempI = tempI2 * 2 + shipGr_; explosionFollowAmountX = this_player->x - this_player->last_x_explosion_follow; explosionFollowAmountY = this_player->y - this_player->last_y_explosion_follow; if (explosionFollowAmountY < 0) explosionFollowAmountY = 0; this_player->last_x_explosion_follow = this_player->x; this_player->last_y_explosion_follow = this_player->y; if (shipGr_ == 0) { if (background2) { blit_sprite2x2_darken(VGAScreen, this_player->x - 17 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI + 13); blit_sprite2x2_darken(VGAScreen, this_player->x + 7 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI + 51); if (superWild) { blit_sprite2x2_darken(VGAScreen, this_player->x - 16 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI + 13); blit_sprite2x2_darken(VGAScreen, this_player->x + 6 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI + 51); } } } else if (shipGr_ == 1) { if (background2) { blit_sprite2x2_darken(VGAScreen, this_player->x - 17 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, 220); blit_sprite2x2_darken(VGAScreen, this_player->x + 7 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, 222); } } else { if (background2) { blit_sprite2x2_darken(VGAScreen, this_player->x - 5 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI); if (superWild) { blit_sprite2x2_darken(VGAScreen, this_player->x - 4 - mapX2Ofs + 30, this_player->y - 7 + shadowYDist, *shapes9ptr_, tempI); } } } if (this_player->invulnerable_ticks > 0) { --this_player->invulnerable_ticks; if (shipGr_ == 0) { blit_sprite2x2_blend(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, tempI + 13); blit_sprite2x2_blend(VGAScreen, this_player->x + 7 , this_player->y - 7, *shapes9ptr_, tempI + 51); } else if (shipGr_ == 1) { blit_sprite2x2_blend(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, 220); blit_sprite2x2_blend(VGAScreen, this_player->x + 7 , this_player->y - 7, *shapes9ptr_, 222); } else blit_sprite2x2_blend(VGAScreen, this_player->x - 5, this_player->y - 7, *shapes9ptr_, tempI); } else { if (shipGr_ == 0) { blit_sprite2x2(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, tempI + 13); blit_sprite2x2(VGAScreen, this_player->x + 7, this_player->y - 7, *shapes9ptr_, tempI + 51); } else if (shipGr_ == 1) { blit_sprite2x2(VGAScreen, this_player->x - 17, this_player->y - 7, *shapes9ptr_, 220); blit_sprite2x2(VGAScreen, this_player->x + 7, this_player->y - 7, *shapes9ptr_, 222); switch (tempI) { case 5: blit_sprite2(VGAScreen, this_player->x - 17, this_player->y + 7, *shapes9ptr_, 40); tempW = this_player->x - 7; tempI2 = -2; break; case 3: blit_sprite2(VGAScreen, this_player->x - 17, this_player->y + 7, *shapes9ptr_, 39); tempW = this_player->x - 7; tempI2 = -1; break; case 1: tempI2 = 0; break; case -1: blit_sprite2(VGAScreen, this_player->x + 19, this_player->y + 7, *shapes9ptr_, 58); tempW = this_player->x + 9; tempI2 = 1; break; case -3: blit_sprite2(VGAScreen, this_player->x + 19, this_player->y + 7, *shapes9ptr_, 59); tempW = this_player->x + 9; tempI2 = 2; break; } if (tempI2 != 0) // NortSparks { if (shotRepeat[SHOT_NORTSPARKS] > 0) { --shotRepeat[SHOT_NORTSPARKS]; } else { JE_initPlayerShot(0, SHOT_NORTSPARKS, tempW + (mt_rand() % 8) - 4, this_player->y + (mt_rand() % 8) - 4, *mouseX_, *mouseY_, 671, 1); shotRepeat[SHOT_NORTSPARKS] = abs(tempI2) - 1; } } } else blit_sprite2x2(VGAScreen, this_player->x - 5, this_player->y - 7, *shapes9ptr_, tempI); } } // !endLevel /*Options Location*/ if (playerNum_ == 2 && shipGr_ == 0) // if dragonwing { if (this_player->sidekick[LEFT_SIDEKICK].style == 0) { this_player->sidekick[LEFT_SIDEKICK].x = this_player->x - 14 + tempI; this_player->sidekick[LEFT_SIDEKICK].y = this_player->y; } if (this_player->sidekick[RIGHT_SIDEKICK].style == 0) { this_player->sidekick[RIGHT_SIDEKICK].x = this_player->x + 17 + tempI; this_player->sidekick[RIGHT_SIDEKICK].y = this_player->y; } } if (moveOk) { if (this_player->is_alive) { if (!endLevel) { this_player->delta_x_shot_move = this_player->x - this_player->last_x_shot_move; this_player->delta_y_shot_move = this_player->y - this_player->last_y_shot_move; /* PLAYER SHOT Change */ if (button[4-1]) { portConfigChange = true; if (portConfigDone) { shotMultiPos[SHOT_REAR] = 0; if (superArcadeMode != SA_NONE && superArcadeMode <= SA_NORTSHIPZ) { shotMultiPos[SHOT_SPECIAL] = 0; shotMultiPos[SHOT_SPECIAL2] = 0; if (player[0].items.special == SASpecialWeapon[superArcadeMode-1]) { player[0].items.special = SASpecialWeaponB[superArcadeMode-1]; this_player->weapon_mode = 2; } else { player[0].items.special = SASpecialWeapon[superArcadeMode-1]; this_player->weapon_mode = 1; } } else if (++this_player->weapon_mode > JE_portConfigs()) this_player->weapon_mode = 1; JE_drawPortConfigButtons(); portConfigDone = false; } } /* PLAYER SHOT Creation */ /*SpecialShot*/ if (!galagaMode) JE_doSpecialShot(playerNum_, &this_player->armor, &this_player->shield); /*Normal Main Weapons*/ if (!(twoPlayerLinked && playerNum_ == 2)) { int min, max; if (!twoPlayerMode) min = 1, max = 2; else min = max = playerNum_; for (temp = min - 1; temp < max; temp++) { const uint item = this_player->items.weapon[temp].id; if (item > 0) { if (shotRepeat[temp] > 0) { --shotRepeat[temp]; } else if (button[1-1]) { const uint item_power = galagaMode ? 0 : this_player->items.weapon[temp].power - 1, item_mode = (temp == REAR_WEAPON) ? this_player->weapon_mode - 1 : 0; JE_initPlayerShot(item, temp, this_player->x, this_player->y, *mouseX_, *mouseY_, weaponPort[item].op[item_mode][item_power], playerNum_); } } } } /*Super Charge Weapons*/ if (playerNum_ == 2) { if (!twoPlayerLinked) blit_sprite2(VGAScreen, this_player->x + (shipGr_ == 0) + 1, this_player->y - 13, eShapes6, 77 + chargeLevel + chargeGr * 19); if (chargeGrWait > 0) { chargeGrWait--; } else { chargeGr++; if (chargeGr == 4) chargeGr = 0; chargeGrWait = 3; } if (chargeLevel > 0) { fill_rectangle_xy(VGAScreenSeg, 269, 107 + (chargeLevel - 1) * 3, 275, 108 + (chargeLevel - 1) * 3, 193); } if (chargeWait > 0) { chargeWait--; } else { if (chargeLevel < chargeMax) chargeLevel++; chargeWait = 28 - this_player->items.weapon[REAR_WEAPON].power * 2; if (difficultyLevel > 3) chargeWait -= 5; } if (chargeLevel > 0) fill_rectangle_xy(VGAScreenSeg, 269, 107 + (chargeLevel - 1) * 3, 275, 108 + (chargeLevel - 1) * 3, 204); if (shotRepeat[SHOT_P2_CHARGE] > 0) { --shotRepeat[SHOT_P2_CHARGE]; } else if (button[1-1] && (!twoPlayerLinked || chargeLevel > 0)) { shotMultiPos[SHOT_P2_CHARGE] = 0; JE_initPlayerShot(16, SHOT_P2_CHARGE, this_player->x, this_player->y, *mouseX_, *mouseY_, chargeGunWeapons[player[1].items.weapon[REAR_WEAPON].id-1] + chargeLevel, playerNum_); if (chargeLevel > 0) fill_rectangle_xy(VGAScreenSeg, 269, 107 + (chargeLevel - 1) * 3, 275, 108 + (chargeLevel - 1) * 3, 193); chargeLevel = 0; chargeWait = 30 - this_player->items.weapon[REAR_WEAPON].power * 2; } } /*SUPER BOMB*/ temp = playerNum_; if (temp == 0) temp = 1; /*Get whether player 1 or 2*/ if (player[temp-1].superbombs > 0) { if (shotRepeat[SHOT_P1_SUPERBOMB + temp-1] > 0) { --shotRepeat[SHOT_P1_SUPERBOMB + temp-1]; } else if (button[3-1] || button[2-1]) { --player[temp-1].superbombs; shotMultiPos[SHOT_P1_SUPERBOMB + temp-1] = 0; JE_initPlayerShot(16, SHOT_P1_SUPERBOMB + temp-1, this_player->x, this_player->y, *mouseX_, *mouseY_, 535, playerNum_); } } // sidekicks if (this_player->sidekick[LEFT_SIDEKICK].style == 4 && this_player->sidekick[RIGHT_SIDEKICK].style == 4) optionSatelliteRotate += 0.2f; else if (this_player->sidekick[LEFT_SIDEKICK].style == 4 || this_player->sidekick[RIGHT_SIDEKICK].style == 4) optionSatelliteRotate += 0.15f; switch (this_player->sidekick[LEFT_SIDEKICK].style) { case 1: // trailing case 3: this_player->sidekick[LEFT_SIDEKICK].x = this_player->old_x[COUNTOF(player->old_x) / 2 - 1]; this_player->sidekick[LEFT_SIDEKICK].y = this_player->old_y[COUNTOF(player->old_x) / 2 - 1]; break; case 2: // front-mounted this_player->sidekick[LEFT_SIDEKICK].x = this_player->x; this_player->sidekick[LEFT_SIDEKICK].y = MAX(10, this_player->y - 20); break; case 4: // orbitting this_player->sidekick[LEFT_SIDEKICK].x = this_player->x + roundf(sinf(optionSatelliteRotate) * 20); this_player->sidekick[LEFT_SIDEKICK].y = this_player->y + roundf(cosf(optionSatelliteRotate) * 20); break; } switch (this_player->sidekick[RIGHT_SIDEKICK].style) { case 4: // orbitting this_player->sidekick[RIGHT_SIDEKICK].x = this_player->x - roundf(sinf(optionSatelliteRotate) * 20); this_player->sidekick[RIGHT_SIDEKICK].y = this_player->y - roundf(cosf(optionSatelliteRotate) * 20); break; case 1: // trailing case 3: this_player->sidekick[RIGHT_SIDEKICK].x = this_player->old_x[0]; this_player->sidekick[RIGHT_SIDEKICK].y = this_player->old_y[0]; break; case 2: // front-mounted if (!optionAttachmentLinked) { this_player->sidekick[RIGHT_SIDEKICK].y += optionAttachmentMove / 2; if (optionAttachmentMove >= -2) { if (optionAttachmentReturn) temp = 2; else temp = 0; if (this_player->sidekick[RIGHT_SIDEKICK].y > (this_player->y - 20) + 5) { temp = 2; optionAttachmentMove -= 1 + optionAttachmentReturn; } else if (this_player->sidekick[RIGHT_SIDEKICK].y > (this_player->y - 20) - 0) { temp = 3; if (optionAttachmentMove > 0) optionAttachmentMove--; else optionAttachmentMove++; } else if (this_player->sidekick[RIGHT_SIDEKICK].y > (this_player->y - 20) - 5) { temp = 2; optionAttachmentMove++; } else if (optionAttachmentMove < 2 + optionAttachmentReturn * 4) { optionAttachmentMove += 1 + optionAttachmentReturn; } if (optionAttachmentReturn) temp = temp * 2; if (abs(this_player->sidekick[RIGHT_SIDEKICK].x - this_player->x) < temp) temp = 1; if (this_player->sidekick[RIGHT_SIDEKICK].x > this_player->x) this_player->sidekick[RIGHT_SIDEKICK].x -= temp; else if (this_player->sidekick[RIGHT_SIDEKICK].x < this_player->x) this_player->sidekick[RIGHT_SIDEKICK].x += temp; if (abs(this_player->sidekick[RIGHT_SIDEKICK].y - (this_player->y - 20)) + abs(this_player->sidekick[RIGHT_SIDEKICK].x - this_player->x) < 8) { optionAttachmentLinked = true; soundQueue[2] = S_CLINK; } if (button[3-1]) optionAttachmentReturn = true; } else // sidekick needs to catch up to player { optionAttachmentMove += 1 + optionAttachmentReturn; JE_setupExplosion(this_player->sidekick[RIGHT_SIDEKICK].x + 1, this_player->sidekick[RIGHT_SIDEKICK].y + 10, 0, 0, false, false); } } else { this_player->sidekick[RIGHT_SIDEKICK].x = this_player->x; this_player->sidekick[RIGHT_SIDEKICK].y = this_player->y - 20; if (button[3-1]) { optionAttachmentLinked = false; optionAttachmentReturn = false; optionAttachmentMove = -20; soundQueue[3] = S_WEAPON_26; } } if (this_player->sidekick[RIGHT_SIDEKICK].y < 10) this_player->sidekick[RIGHT_SIDEKICK].y = 10; break; } if (playerNum_ == 2 || !twoPlayerMode) // if player has sidekicks { for (uint i = 0; i < COUNTOF(player->items.sidekick); ++i) { uint shot_i = (i == 0) ? SHOT_LEFT_SIDEKICK : SHOT_RIGHT_SIDEKICK; JE_OptionType *this_option = &options[this_player->items.sidekick[i]]; // fire/refill sidekick if (this_option->wport > 0) { if (shotRepeat[shot_i] > 0) { --shotRepeat[shot_i]; } else { const int ammo_max = this_player->sidekick[i].ammo_max; if (ammo_max > 0) // sidekick has limited ammo { if (this_player->sidekick[i].ammo_refill_ticks > 0) { --this_player->sidekick[i].ammo_refill_ticks; } else // refill one ammo { this_player->sidekick[i].ammo_refill_ticks = this_player->sidekick[i].ammo_refill_ticks_max; if (this_player->sidekick[i].ammo < ammo_max) ++this_player->sidekick[i].ammo; // draw sidekick refill ammo gauge const int y = hud_sidekick_y[twoPlayerMode ? 1 : 0][i] + 13; draw_segmented_gauge(VGAScreenSeg, 284, y, 112, 2, 2, MAX(1, ammo_max / 10), this_player->sidekick[i].ammo); } if (button[1 + i] && this_player->sidekick[i].ammo > 0) { JE_initPlayerShot(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_); --this_player->sidekick[i].ammo; if (this_player->sidekick[i].charge > 0) { shotMultiPos[shot_i] = 0; this_player->sidekick[i].charge = 0; } this_player->sidekick[i].charge_ticks = 20; this_player->sidekick[i].animation_enabled = true; // draw sidekick discharge ammo gauge const int y = hud_sidekick_y[twoPlayerMode ? 1 : 0][i] + 13; fill_rectangle_xy(VGAScreenSeg, 284, y, 312, y + 2, 0); draw_segmented_gauge(VGAScreenSeg, 284, y, 112, 2, 2, MAX(1, ammo_max / 10), this_player->sidekick[i].ammo); } } else // has infinite ammo { if (button[0] || button[1 + i]) { JE_initPlayerShot(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_); if (this_player->sidekick[i].charge > 0) { shotMultiPos[shot_i] = 0; this_player->sidekick[i].charge = 0; } this_player->sidekick[i].charge_ticks = 20; this_player->sidekick[i].animation_enabled = true; } } } } } } // end of if player has sidekicks } // !endLevel } // this_player->is_alive } // moveOK // draw sidekicks if ((playerNum_ == 2 || !twoPlayerMode) && !endLevel) { for (uint i = 0; i < COUNTOF(this_player->sidekick); ++i) { JE_OptionType *this_option = &options[this_player->items.sidekick[i]]; if (this_option->option > 0) { if (this_player->sidekick[i].animation_enabled) { if (++this_player->sidekick[i].animation_frame >= this_option->ani) { this_player->sidekick[i].animation_frame = 0; this_player->sidekick[i].animation_enabled = (this_option->option == 1); } } const int x = this_player->sidekick[i].x, y = this_player->sidekick[i].y; const uint sprite = this_option->gr[this_player->sidekick[i].animation_frame] + this_player->sidekick[i].charge; if (this_player->sidekick[i].style == 1 || this_player->sidekick[i].style == 2) blit_sprite2x2(VGAScreen, x - 6, y, eShapes6, sprite); else blit_sprite2(VGAScreen, x, y, shapes9, sprite); } if (--this_player->sidekick[i].charge_ticks == 0) { if (this_player->sidekick[i].charge < this_option->pwr) ++this_player->sidekick[i].charge; this_player->sidekick[i].charge_ticks = 20; } } } } void JE_mainGamePlayerFunctions( void ) { /*PLAYER MOVEMENT/MOUSE ROUTINES*/ if (endLevel && levelEnd > 0) { levelEnd--; levelEndWarp++; } /*Reset Street-Fighter commands*/ memset(SFExecuted, 0, sizeof(SFExecuted)); portConfigChange = false; if (twoPlayerMode) { JE_playerMovement(&player[0], !galagaMode ? inputDevice[0] : 0, 1, shipGr, shipGrPtr, &mouseX, &mouseY); JE_playerMovement(&player[1], !galagaMode ? inputDevice[1] : 0, 2, shipGr2, shipGr2ptr, &mouseXB, &mouseYB); } else { JE_playerMovement(&player[0], 0, 1, shipGr, shipGrPtr, &mouseX, &mouseY); } /* == Parallax Map Scrolling == */ if (twoPlayerMode) { tempX = (player[0].x + player[1].x) / 2; } else { tempX = player[0].x; } tempW = floorf((260.0f - (tempX - 36.0f)) / (260.0f - 36.0f) * (24.0f * 3.0f) - 1.0f); mapX3Ofs = tempW; mapX3Pos = mapX3Ofs % 24; mapX3bpPos = 1 - (mapX3Ofs / 24); mapX2Ofs = (tempW * 2) / 3; mapX2Pos = mapX2Ofs % 24; mapX2bpPos = 1 - (mapX2Ofs / 24); oldMapXOfs = mapXOfs; mapXOfs = mapX2Ofs / 2; mapXPos = mapXOfs % 24; mapXbpPos = 1 - (mapXOfs / 24); if (background3x1) { mapX3Ofs = mapXOfs; mapX3Pos = mapXPos; mapX3bpPos = mapXbpPos - 1; } } const char *JE_getName( JE_byte pnum ) { if (pnum == thisPlayerNum && network_player_name[0] != '\0') return network_player_name; else if (network_opponent_name[0] != '\0') return network_opponent_name; return miscText[47 + pnum]; } void JE_playerCollide( Player *this_player, JE_byte playerNum_ ) { char tempStr[256]; for (int z = 0; z < 100; z++) { if (enemyAvail[z] != 1) { tempI3 = enemy[z].ex + enemy[z].mapoffset; if (abs(this_player->x - tempI3) < 12 && abs(this_player->y - enemy[z].ey) < 14) { /*Collide*/ tempI4 = enemy[z].evalue; if (tempI4 > 29999) { if (tempI4 == 30000) // spawn dragonwing in galaga mode, otherwise just a purple ball { this_player->cash += 100; if (!galagaMode) { handle_got_purple_ball(this_player); } else { // spawn the dragonwing? if (twoPlayerMode) this_player->cash += 2400; twoPlayerMode = true; twoPlayerLinked = true; player[1].items.weapon[REAR_WEAPON].power = 1; player[1].armor = 10; player[1].is_alive = true; } enemyAvail[z] = 1; soundQueue[7] = S_POWERUP; } else if (superArcadeMode != SA_NONE && tempI4 > 30000) { shotMultiPos[SHOT_FRONT] = 0; shotRepeat[SHOT_FRONT] = 10; tempW = SAWeapon[superArcadeMode-1][tempI4 - 30000-1]; // if picked up already-owned weapon, power weapon up if (tempW == player[0].items.weapon[FRONT_WEAPON].id) { this_player->cash += 1000; power_up_weapon(this_player, FRONT_WEAPON); } // else weapon also gives purple ball else { handle_got_purple_ball(this_player); } player[0].items.weapon[FRONT_WEAPON].id = tempW; this_player->cash += 200; soundQueue[7] = S_POWERUP; enemyAvail[z] = 1; } else if (tempI4 > 32100) { if (playerNum_ == 1) { this_player->cash += 250; player[0].items.special = tempI4 - 32100; shotMultiPos[SHOT_SPECIAL] = 0; shotRepeat[SHOT_SPECIAL] = 10; shotMultiPos[SHOT_SPECIAL2] = 0; shotRepeat[SHOT_SPECIAL2] = 0; if (isNetworkGame) sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], special[tempI4 - 32100].name); else if (twoPlayerMode) sprintf(tempStr, "%s %s", miscText[43-1], special[tempI4 - 32100].name); else sprintf(tempStr, "%s %s", miscText[64-1], special[tempI4 - 32100].name); JE_drawTextWindow(tempStr); soundQueue[7] = S_POWERUP; enemyAvail[z] = 1; } } else if (tempI4 > 32000) { if (playerNum_ == 2) { enemyAvail[z] = 1; if (isNetworkGame) sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], options[tempI4 - 32000].name); else sprintf(tempStr, "%s %s", miscText[44-1], options[tempI4 - 32000].name); JE_drawTextWindow(tempStr); // if picked up a different sidekick than player already has, then reset sidekicks to least powerful, else power them up if (tempI4 - 32000u != player[1].items.sidekick_series) { player[1].items.sidekick_series = tempI4 - 32000; player[1].items.sidekick_level = 101; } else if (player[1].items.sidekick_level < 103) { ++player[1].items.sidekick_level; } uint temp = player[1].items.sidekick_level - 100 - 1; for (uint i = 0; i < COUNTOF(player[1].items.sidekick); ++i) player[1].items.sidekick[i] = optionSelect[player[1].items.sidekick_series][temp][i]; shotMultiPos[SHOT_LEFT_SIDEKICK] = 0; shotMultiPos[SHOT_RIGHT_SIDEKICK] = 0; JE_drawOptions(); soundQueue[7] = S_POWERUP; } else if (onePlayerAction) { enemyAvail[z] = 1; sprintf(tempStr, "%s %s", miscText[64-1], options[tempI4 - 32000].name); JE_drawTextWindow(tempStr); for (uint i = 0; i < COUNTOF(player[0].items.sidekick); ++i) player[0].items.sidekick[i] = tempI4 - 32000; shotMultiPos[SHOT_LEFT_SIDEKICK] = 0; shotMultiPos[SHOT_RIGHT_SIDEKICK] = 0; JE_drawOptions(); soundQueue[7] = S_POWERUP; } if (enemyAvail[z] == 1) this_player->cash += 250; } else if (tempI4 > 31000) { this_player->cash += 250; if (playerNum_ == 2) { if (isNetworkGame) sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], weaponPort[tempI4 - 31000].name); else sprintf(tempStr, "%s %s", miscText[44-1], weaponPort[tempI4 - 31000].name); JE_drawTextWindow(tempStr); player[1].items.weapon[REAR_WEAPON].id = tempI4 - 31000; shotMultiPos[SHOT_REAR] = 0; enemyAvail[z] = 1; soundQueue[7] = S_POWERUP; } else if (onePlayerAction) { sprintf(tempStr, "%s %s", miscText[64-1], weaponPort[tempI4 - 31000].name); JE_drawTextWindow(tempStr); player[0].items.weapon[REAR_WEAPON].id = tempI4 - 31000; shotMultiPos[SHOT_REAR] = 0; enemyAvail[z] = 1; soundQueue[7] = S_POWERUP; if (player[0].items.weapon[REAR_WEAPON].power == 0) // does this ever happen? player[0].items.weapon[REAR_WEAPON].power = 1; } } else if (tempI4 > 30000) { if (playerNum_ == 1 && twoPlayerMode) { if (isNetworkGame) sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], weaponPort[tempI4 - 30000].name); else sprintf(tempStr, "%s %s", miscText[43-1], weaponPort[tempI4 - 30000].name); JE_drawTextWindow(tempStr); player[0].items.weapon[FRONT_WEAPON].id = tempI4 - 30000; shotMultiPos[SHOT_FRONT] = 0; enemyAvail[z] = 1; soundQueue[7] = S_POWERUP; } else if (onePlayerAction) { sprintf(tempStr, "%s %s", miscText[64-1], weaponPort[tempI4 - 30000].name); JE_drawTextWindow(tempStr); player[0].items.weapon[FRONT_WEAPON].id = tempI4 - 30000; shotMultiPos[SHOT_FRONT] = 0; enemyAvail[z] = 1; soundQueue[7] = S_POWERUP; } if (enemyAvail[z] == 1) { player[0].items.special = specialArcadeWeapon[tempI4 - 30000-1]; if (player[0].items.special > 0) { shotMultiPos[SHOT_SPECIAL] = 0; shotRepeat[SHOT_SPECIAL] = 0; shotMultiPos[SHOT_SPECIAL2] = 0; shotRepeat[SHOT_SPECIAL2] = 0; } this_player->cash += 250; } } } else if (tempI4 > 20000) { if (twoPlayerLinked) { // share the armor evenly between linked players for (uint i = 0; i < COUNTOF(player); ++i) { player[i].armor += (tempI4 - 20000) / COUNTOF(player); if (player[i].armor > 28) player[i].armor = 28; } } else { this_player->armor += tempI4 - 20000; if (this_player->armor > 28) this_player->armor = 28; } enemyAvail[z] = 1; VGAScreen = VGAScreenSeg; /* side-effect of game_screen */ JE_drawArmor(); VGAScreen = game_screen; /* side-effect of game_screen */ soundQueue[7] = S_POWERUP; } else if (tempI4 > 10000 && enemyAvail[z] == 2) { if (!bonusLevel) { play_song(30); /*Zanac*/ bonusLevel = true; nextLevel = tempI4 - 10000; enemyAvail[z] = 1; displayTime = 150; } } else if (enemy[z].scoreitem) { enemyAvail[z] = 1; soundQueue[7] = S_ITEM; if (tempI4 == 1) { cubeMax++; soundQueue[3] = V_DATA_CUBE; } else if (tempI4 == -1) // got front weapon powerup { if (isNetworkGame) sprintf(tempStr, "%s %s %s", JE_getName(1), miscTextB[4-1], miscText[45-1]); else if (twoPlayerMode) sprintf(tempStr, "%s %s", miscText[43-1], miscText[45-1]); else strcpy(tempStr, miscText[45-1]); JE_drawTextWindow(tempStr); power_up_weapon(&player[0], FRONT_WEAPON); soundQueue[7] = S_POWERUP; } else if (tempI4 == -2) // got rear weapon powerup { if (isNetworkGame) sprintf(tempStr, "%s %s %s", JE_getName(2), miscTextB[4-1], miscText[46-1]); else if (twoPlayerMode) sprintf(tempStr, "%s %s", miscText[44-1], miscText[46-1]); else strcpy(tempStr, miscText[46-1]); JE_drawTextWindow(tempStr); power_up_weapon(twoPlayerMode ? &player[1] : &player[0], REAR_WEAPON); soundQueue[7] = S_POWERUP; } else if (tempI4 == -3) { // picked up orbiting asteroid killer shotMultiPos[SHOT_MISC] = 0; JE_initPlayerShot(0, SHOT_MISC, this_player->x, this_player->y, mouseX, mouseY, 104, playerNum_); shotAvail[z] = 0; } else if (tempI4 == -4) { if (player[playerNum_-1].superbombs < 10) ++player[playerNum_-1].superbombs; } else if (tempI4 == -5) { player[0].items.weapon[FRONT_WEAPON].id = 25; // HOT DOG! player[0].items.weapon[REAR_WEAPON].id = 26; player[1].items.weapon[REAR_WEAPON].id = 26; player[0].last_items = player[0].items; for (uint i = 0; i < COUNTOF(player); ++i) player[i].weapon_mode = 1; memset(shotMultiPos, 0, sizeof(shotMultiPos)); } else if (twoPlayerLinked) { // players get equal share of pick-up cash when linked for (uint i = 0; i < COUNTOF(player); ++i) player[i].cash += tempI4 / COUNTOF(player); } else { this_player->cash += tempI4; } JE_setupExplosion(tempI3, enemy[z].ey, 0, enemyDat[enemy[z].enemytype].explosiontype, true, false); } else if (this_player->invulnerable_ticks == 0 && enemyAvail[z] == 0 && enemyDat[enemy[z].enemytype].explosiontype % 2 == 0) { tempI3 = enemy[z].armorleft; if (tempI3 > damageRate) tempI3 = damageRate; JE_playerDamage(tempI3, this_player); // player ship gets push-back from collision if (enemy[z].armorleft > 0) { this_player->x_velocity += (enemy[z].exc * enemy[z].armorleft) / 2; this_player->y_velocity += (enemy[z].eyc * enemy[z].armorleft) / 2; } tempI = enemy[z].armorleft; if (tempI == 255) tempI = 30000; temp = enemy[z].linknum; if (temp == 0) temp = 255; b = z; if (tempI > tempI2) { if (enemy[z].armorleft != 255) enemy[z].armorleft -= tempI3; soundQueue[5] = S_ENEMY_HIT; } else { for (temp2 = 0; temp2 < 100; temp2++) { if (enemyAvail[temp2] != 1) { temp3 = enemy[temp2].linknum; if (temp2 == b || (temp != 255 && (temp == temp3 || temp - 100 == temp3 || (temp3 > 40 && temp3 / 20 == temp / 20 && temp3 <= temp)))) { tempI3 = enemy[temp2].ex + enemy[temp2].mapoffset; enemy[temp2].linknum = 0; enemyAvail[temp2] = 1; if (enemyDat[enemy[temp2].enemytype].esize == 1) { JE_setupExplosionLarge(enemy[temp2].enemyground, enemy[temp2].explonum, tempI3, enemy[temp2].ey); soundQueue[6] = S_EXPLOSION_9; } else { JE_setupExplosion(tempI3, enemy[temp2].ey, 0, 1, false, false); soundQueue[5] = S_EXPLOSION_4; } } } } enemyAvail[z] = 1; } } } } } } // kate: tab-width 4; vim: set noet: