2
* OpenTyrian: A modern cross-platform port of Tyrian
3
* Copyright (C) 2007-2009 The OpenTyrian Development Team
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
#include "game_menu.h"
57
static int joystick_config = 0; // which joystick is being configured in menu
60
static JE_shortint yChg;
61
static int newPal, curPal, oldPal;
62
static JE_boolean quikSave;
63
static JE_byte oldMenu;
64
static JE_boolean backFromHelp;
65
static JE_integer lastDirection;
66
static JE_boolean firstMenu9, paletteChanged;
67
static JE_MenuChoiceType menuChoices;
68
static JE_integer col, colC;
69
static JE_byte lastCurSel;
70
static JE_integer curMenu;
71
static JE_byte curSel[MENU_MAX]; /* [1..maxmenu] */
72
static JE_byte curItemType, curItem, cursor;
73
static JE_boolean leftPower, rightPower, rightPowerAfford;
74
static JE_byte currentCube;
75
static JE_boolean keyboardUsed;
77
static JE_byte planetAni, planetAniWait;
78
static JE_byte currentDotNum, currentDotWait;
79
static JE_real navX, navY, newNavX, newNavY;
80
static JE_integer tempNavX, tempNavY;
81
static JE_byte planetDots[5]; /* [1..5] */
82
static JE_integer planetDotX[5][10], planetDotY[5][10]; /* [1..5, 1..10] */
83
static PlayerItems old_items[2]; // TODO: should not be global if possible
85
static struct cube_struct cube[4];
87
static const JE_MenuChoiceType menuChoicesDefault = { 7, 9, 8, 0, 0, 11, (SAVE_FILES_NUM / 2) + 2, 0, 0, 6, 4, 6, 7, 5 };
88
static const JE_byte menuEsc[MENU_MAX] = { 0, 1, 1, 1, 2, 3, 3, 1, 8, 0, 0, 11, 3, 0 };
89
static const JE_byte itemAvailMap[7] = { 1, 2, 3, 9, 4, 6, 7 };
90
static const JE_word planetX[21] = { 200, 150, 240, 300, 270, 280, 320, 260, 220, 150, 160, 210, 80, 240, 220, 180, 310, 330, 150, 240, 200 };
91
static const JE_word planetY[21] = { 40, 90, 90, 80, 170, 30, 50, 130, 120, 150, 220, 200, 80, 50, 160, 10, 55, 55, 90, 90, 40 };
92
static const uint cube_line_chars = sizeof(*cube->text) - 1;
93
static const uint cube_line_width = 150;
97
static uint *playeritem_map( PlayerItems *items, uint i )
99
uint * const map[] = { &items->ship, &items->weapon[FRONT_WEAPON].id, &items->weapon[REAR_WEAPON].id, &items->shield, &items->generator, &items->sidekick[LEFT_SIDEKICK], &items->sidekick[RIGHT_SIDEKICK] };
100
assert(i < COUNTOF(map));
105
JE_longint JE_cashLeft( void )
107
JE_longint tempL = player[0].cash;
108
JE_word itemNum = *playeritem_map(&player[0].items, curSel[1] - 2);
110
tempL -= JE_getCost(curSel[1], itemNum);
118
for (uint i = 1; i < player[0].items.weapon[curSel[1]-3].power; ++i)
120
tempW += weaponPort[itemNum].cost * i;
129
void JE_itemScreen( void )
133
/* SYN: Okay, here's the menu numbers. All are reindexed by -1 from the original code.
138
4: upgrade ship submenus
143
9: 2 player arcade game menu
144
10: 1 player arcade game menu
145
11: network game options
146
12: joystick settings
150
free_sprite2s(&shapes6);
151
JE_loadCompShapes(&shapes6, '1'); // item sprites
155
VGAScreen = VGAScreenSeg;
157
memcpy(menuChoices, menuChoicesDefault, sizeof(menuChoices));
161
JE_loadPic(VGAScreen, 1, false);
168
set_palette(colors, 0, 255);
176
for (unsigned int i = 0; i < COUNTOF(curSel); ++i)
181
int temp_weapon_power[7]; // assumes there'll never be more than 6 weapons to choose from, 7th is "Done"
183
/* JE: (* Check for where Pitems and Select match up - if no match then add to the itemavail list *) */
184
for (int i = 0; i < 7; i++)
186
int item = *playeritem_map(&player[0].last_items, i);
190
for ( ; slot < itemAvailMax[itemAvailMap[i]-1]; ++slot)
192
if (itemAvail[itemAvailMap[i]-1][slot] == item)
196
if (slot == itemAvailMax[itemAvailMap[i]-1])
198
itemAvail[itemAvailMap[i]-1][slot] = item;
199
itemAvailMax[itemAvailMap[i]-1]++;
203
memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
205
keyboardUsed = false;
207
backFromHelp = false;
209
/* JE: Sort items in merchant inventory */
210
for (int x = 0; x < 9; x++)
212
if (itemAvailMax[x] > 1)
214
for (temp = 0; temp < itemAvailMax[x] - 1; temp++)
216
for (temp2 = temp; temp2 < itemAvailMax[x]; temp2++)
218
if (itemAvail[x][temp] == 0 || (itemAvail[x][temp] > itemAvail[x][temp2] && itemAvail[x][temp2] != 0))
220
temp3 = itemAvail[x][temp];
221
itemAvail[x][temp] = itemAvail[x][temp2];
222
itemAvail[x][temp2] = temp3;
235
/* JE: If curMenu==1 and twoPlayerMode is on, then force move to menu 10 */
241
if (isNetworkGame || onePlayerAction)
248
paletteChanged = false;
253
/* SYN: note reindexing... "firstMenu9" refers to Menu 8 here :( */
254
if (curMenu != 8 || firstMenu9)
256
memcpy(VGAScreen->pixels, VGAScreen2->pixels, VGAScreen->pitch * VGAScreen->h);
259
defaultBrightness = -3;
261
if (curMenu == 1 && (curSel[curMenu] == 3 || curSel[curMenu] == 4))
263
// reset temp_weapon_power[] every time we select upgrading front or back
264
const uint item = player[0].items.weapon[curSel[1] - 3].id,
265
item_power = player[0].items.weapon[curSel[1] - 3].power,
266
i = curSel[1] - 2; // 1 or 2 (front or rear)
268
// set power level of owned weapon
269
for (int slot = 0; slot < itemAvailMax[itemAvailMap[i]-1]; ++slot)
271
if (itemAvail[itemAvailMap[i]-1][slot] == item)
272
temp_weapon_power[slot] = item_power;
274
temp_weapon_power[slot] = 1;
277
// set power level for "Done"
278
temp_weapon_power[itemAvailMax[itemAvailMap[i]-1]] = item_power;
281
/* play next level menu */
285
keyboardUsed = false;
289
JE_updateNavScreen();
292
/* Draw menu title for everything but upgrade ship submenus */
298
/* Draw menu choices for simple menus */
299
if ((curMenu >= 0 && curMenu <= 3) || (curMenu >= 9 && curMenu <= 11) || curMenu == 13)
301
JE_drawMenuChoices();
304
/* Data cube icons */
307
for (int i = 1; i <= cubeMax; i++)
309
blit_sprite_dark(VGAScreen, 190 + i * 18 + 2, 37 + 1, OPTION_SHAPES, 34, false);
310
blit_sprite(VGAScreen, 190 + i * 18, 37, OPTION_SHAPES, 34); // data cube
330
for (int x = min; x <= max; x++)
332
/* Highlight if current selection */
333
temp2 = (x - min + 2 == curSel[curMenu]) ? 15 : 28;
335
/* Write save game slot */
337
strcpy(tempStr, miscText[6-1]);
338
else if (saveFiles[x-2].level == 0)
339
strcpy(tempStr, miscText[3-1]);
341
strcpy(tempStr, saveFiles[x-2].name);
343
int tempY = 38 + (x - min)*11;
345
JE_textShade(VGAScreen, 163, tempY, tempStr, temp2 / 16, temp2 % 16 - 8, DARKEN);
347
/* If selected with keyboard, move mouse pointer to match? Or something. */
348
if (x - min + 2 == curSel[curMenu])
351
set_mouse_position(305, 38 + (x - min) * 11);
354
if (x < max) /* x == max isn't a save slot */
356
/* Highlight if current selection */
357
temp2 = (x - min + 2 == curSel[curMenu]) ? 252 : 250;
359
if (saveFiles[x-2].level == 0)
361
strcpy(tempStr, "-----"); /* Empty save slot */
367
strcpy(tempStr, saveFiles[x-2].levelName);
369
snprintf(buf, sizeof buf, "%s%d", miscTextB[1-1], saveFiles[x-2].episode);
370
JE_textShade(VGAScreen, 297, tempY, buf, temp2 / 16, temp2 % 16 - 8, DARKEN);
373
JE_textShade(VGAScreen, 245, tempY, tempStr, temp2 / 16, temp2 % 16 - 8, DARKEN);
380
/* keyboard settings menu */
383
for (int x = 2; x <= 11; x++)
385
if (x == curSel[curMenu])
389
set_mouse_position(305, 38 + (x - 2) * 12);
396
JE_textShade(VGAScreen, 166, 38 + (x - 2)*12, menuInt[curMenu + 1][x-1], temp2 / 16, temp2 % 16 - 8, DARKEN);
398
if (x < 10) /* 10 = reset to defaults, 11 = done */
400
temp2 = (x == curSel[curMenu]) ? 252 : 250;
401
JE_textShade(VGAScreen, 236, 38 + (x - 2)*12, SDL_GetKeyName(keySettings[x-2]), temp2 / 16, temp2 % 16 - 8, DARKEN);
408
/* Joystick settings menu */
411
const char *menu_item[] =
431
for (uint i = 0; i < COUNTOF(menu_item); i++)
433
int temp = (i == curSel[curMenu] - 2u) ? 15 : 28;
435
JE_textShade(VGAScreen, 166, 38 + i * 8, menu_item[i], temp / 16, temp % 16 - 8, DARKEN);
437
temp = (i == curSel[curMenu] - 2u) ? 252 : 250;
440
if (joysticks == 0 && i < 14) // no joysticks, everything disabled
444
else if (i == 0) // joystick number
446
sprintf(value, "%d", joystick_config + 1);
448
else if (i == 1) // joystick is analog
450
sprintf(value, "%s", joystick[joystick_config].analog ? "TRUE" : "FALSE");
452
else if (i < 4) // joystick analog settings
454
if (!joystick[joystick_config].analog)
456
sprintf(value, "%d", i == 2 ? joystick[joystick_config].sensitivity : joystick[joystick_config].threshold);
458
else if (i < 14) // assignments
460
joystick_assignments_to_string(value, sizeof(value), joystick[joystick_config].assignment[i - 4]);
463
JE_textShade(VGAScreen, 236, 38 + i * 8, value, temp / 16, temp % 16 - 8, DARKEN);
466
menuChoices[curMenu] = COUNTOF(menu_item) + 1;
469
/* Upgrade weapon submenus, with weapon sim */
472
/* Move cursor until we hit either "Done" or a weapon the player can afford */
473
while (curSel[4] < menuChoices[4] && JE_getCost(curSel[1], itemAvail[itemAvailMap[curSel[1]-2]-1][curSel[4]-2]) > player[0].cash)
475
curSel[4] += lastDirection;
477
curSel[4] = menuChoices[4];
478
else if (curSel[4] > menuChoices[4])
482
if (curSel[4] == menuChoices[4])
484
/* If cursor on "Done", use previous weapon */
485
*playeritem_map(&player[0].items, curSel[1] - 2) = *playeritem_map(&old_items[0], curSel[1] - 2);
489
/* Otherwise display the selected weapon */
490
*playeritem_map(&player[0].items, curSel[1] - 2) = itemAvail[itemAvailMap[curSel[1]-2]-1][curSel[4]-2];
493
/* Get power level info for front and rear weapons */
494
if ((curSel[1] == 3 && curSel[4] < menuChoices[4]) || (curSel[1] == 4 && curSel[4] < menuChoices[4]-1))
496
const uint port = curSel[1] - 3, // 0 or 1 (front or back)
497
item_level = player[0].items.weapon[port].power;
499
// calculate upgradeCost
500
JE_getCost(curSel[1], itemAvail[itemAvailMap[curSel[1]-2]-1][curSel[5]-2]);
502
leftPower = item_level > 1; // can downgrade
503
rightPower = item_level < 11; // can upgrade
506
rightPowerAfford = JE_cashLeft() >= upgradeCost; // can afford upgrade
510
/* Nothing else can be upgraded / downgraded */
515
/* submenu title e.g., "Left Sidekick" */
516
JE_dString(VGAScreen, 74 + JE_fontCenter(menuInt[2][curSel[1]-1], FONT_SHAPES), 10, menuInt[2][curSel[1]-1], FONT_SHAPES);
518
/* Iterate through all submenu options */
519
for (tempW = 1; tempW < menuChoices[curMenu]; tempW++)
521
int tempY = 40 + (tempW-1) * 26; /* Calculate y position */
524
/* Is this a item or None/DONE? */
525
if (tempW < menuChoices[4] - 1)
527
/* Get base cost for choice */
528
temp_cost = JE_getCost(curSel[1], itemAvail[itemAvailMap[curSel[1]-2]-1][tempW-1]);
532
/* "None" is free :) */
536
int afford_shade = (temp_cost > player[0].cash) ? 4 : 0; // can player afford current weapon at all
538
temp = itemAvail[itemAvailMap[curSel[1]-2]-1][tempW-1]; /* Item ID */
544
snprintf(tempStr, sizeof(tempStr), "Custom Ship %d", temp - 90);
546
strcpy(tempStr, ships[temp].name);
549
case 2: /* front and rear weapon */
551
strcpy(tempStr, weaponPort[temp].name);
553
case 4: /* shields */
554
strcpy(tempStr, shields[temp].name);
556
case 5: /* generator */
557
strcpy(tempStr, powerSys[temp].name);
559
case 6: /* sidekicks */
561
strcpy(tempStr, options[temp].name);
564
if (tempW == curSel[curMenu]-1)
568
set_mouse_position(305, tempY + 10);
577
/* item-owned marker */
578
if (temp == *playeritem_map(&old_items[0], curSel[1] - 2) && temp != 0 && tempW != menuChoices[curMenu]-1)
580
fill_rectangle_xy(VGAScreen, 160, tempY+7, 300, tempY+11, 227);
581
blit_sprite2(VGAScreen, 298, tempY+2, shapes6, 247);
585
if (tempW == menuChoices[curMenu]-1)
587
strcpy(tempStr, miscText[13]);
589
JE_textShade(VGAScreen, 185, tempY, tempStr, temp2 / 16, temp2 % 16 - 8 - afford_shade, DARKEN);
591
/* Draw icon if not DONE. NOTE: None is a normal item with a blank icon. */
592
if (tempW < menuChoices[curMenu]-1)
594
JE_drawItem(curSel[1]-1, temp, 160, tempY-4);
597
/* Make selected text brigther */
598
temp2 = (tempW == curSel[curMenu]-1) ? 15 : 28;
600
/* Draw Cost: if it's not the DONE option */
601
if (tempW != menuChoices[curMenu]-1)
605
snprintf(buf, sizeof buf, "Cost: %d", temp_cost);
606
JE_textShade(VGAScreen, 187, tempY+10, buf, temp2 / 16, temp2 % 16 - 8 - afford_shade, DARKEN);
609
} /* /weapon upgrade */
611
/* Draw current money and shield/armor bars, when appropriate */
613
if (((curMenu <= 2 || curMenu == 5 || curMenu == 6 || curMenu >= 10) && !twoPlayerMode) || (curMenu == 4 && (curSel[1] >= 1 && curSel[1] <= 6)))
619
snprintf(buf, sizeof buf, "%lu", player[0].cash);
620
JE_textShade(VGAScreen, 65, 173, buf, 1, 6, DARKEN);
622
JE_barDrawShadow(VGAScreen, 42, 152, 3, 14, player[0].armor, 2, 13);
623
JE_barDrawShadow(VGAScreen, 104, 152, 2, 14, shields[player[0].items.shield].mpwr * 2, 2, 13);
626
/* Draw crap on the left side of the screen, i.e. two player scores, ship graphic, etc. */
627
if (((curMenu >= 0 && curMenu <= 2) || curMenu == 5 || curMenu == 6 || curMenu >= 9) || (curMenu == 4 && (curSel[1] == 2 || curSel[1] == 5)))
633
for (uint i = 0; i < 2; ++i)
635
snprintf(buf, sizeof(buf), "%s %lu", miscText[40 + i], player[i].cash);
636
JE_textShade(VGAScreen, 25, 50 + 10 * i, buf, 15, 0, FULL_SHADE);
639
else if (superArcadeMode != SA_NONE || superTyrian)
642
helpBoxBrightness = 4;
644
JE_helpBox(VGAScreen, 35, 25, superShips[superArcadeMode], 18);
646
JE_helpBox(VGAScreen, 35, 25, superShips[SA+3], 18);
647
helpBoxBrightness = 1;
649
JE_textShade(VGAScreen, 25, 50, superShips[SA+1], 15, 0, FULL_SHADE);
650
JE_helpBox(VGAScreen, 25, 60, weaponPort[player[0].items.weapon[FRONT_WEAPON].id].name, 22);
651
JE_textShade(VGAScreen, 25, 120, superShips[SA+2], 15, 0, FULL_SHADE);
652
JE_helpBox(VGAScreen, 25, 130, special[player[0].items.special].name, 22);
656
draw_ship_illustration();
660
/* Changing the volume? */
661
if ((curMenu == 2) || (curMenu == 11))
663
JE_barDrawShadow(VGAScreen, 225, 70, 1, music_disabled ? 12 : 16, tyrMusicVolume / 12, 3, 13);
664
JE_barDrawShadow(VGAScreen, 225, 86, 1, samples_disabled ? 12 : 16, fxVolume / 12, 3, 13);
667
/* 7 is data cubes menu, 8 is reading a data cube, "firstmenu9" refers to menu 8 because of reindexing */
668
if (curMenu == 7 || ( curMenu == 8 && (firstMenu9 || backFromHelp) ) )
671
menuChoices[7] = cubeMax + 2;
672
fill_rectangle_xy(VGAScreen, 1, 1, 145, 170, 0);
674
blit_sprite(VGAScreenSeg, 1, 1, OPTION_SHAPES, 20); /* Portrait area background */
680
JE_helpBox(VGAScreen, 166, 80, miscText[16 - 1], 30);
686
for (int x = 1; x <= cubeMax; x++)
688
JE_drawCube(VGAScreenSeg, 166, 38 + (x - 1) * 28, 13, 0);
689
if (x + 1 == curSel[curMenu])
692
set_mouse_position(305, 38 + (x - 1) * 28 + 6);
700
helpBoxColor = temp2 / 16;
701
helpBoxBrightness = (temp2 % 16) - 8;
702
helpBoxShadeType = DARKEN;
703
JE_helpBox(VGAScreen, 192, 44 + (x - 1) * 28, cube[x - 1].title, 24);
706
if (x + 1 == curSel[curMenu])
709
set_mouse_position(305, 38 + (x - 1) * 28 + 6);
716
tempW = 44 + (x - 1) * 28;
719
JE_textShade(VGAScreen, 172, tempW, miscText[6 - 1], temp2 / 16, (temp2 % 16) - 8, DARKEN);
722
if (curSel[7] < menuChoices[7])
724
const int face_sprite = cube[curSel[7] - 2].face_sprite;
726
if (face_sprite != -1)
728
const int face_x = 77 - (sprite(FACE_SHAPES, face_sprite)->width / 2),
729
face_y = 92 - (sprite(FACE_SHAPES, face_sprite)->height / 2);
731
blit_sprite(VGAScreenSeg, face_x, face_y, FACE_SHAPES, face_sprite); // datacube face
733
// modify pallete for face
734
paletteChanged = true;
735
temp2 = facepal[face_sprite];
738
for (temp = 1; temp <= 255 - (3 * 16); temp++)
739
colors[temp] = palettes[temp2][temp];
744
/* 2 player input devices */
747
for (uint i = 0; i < COUNTOF(inputDevice); i++)
749
if (inputDevice[i] > 2 + joysticks)
750
inputDevice[i] = inputDevice[i == 0 ? 1 : 0] == 1 ? 2 : 1;
753
if (joysticks > 1 && inputDevice[i] > 2)
754
sprintf(temp, "%s %d", inputDevices[2], inputDevice[i] - 2);
756
sprintf(temp, "%s", inputDevices[inputDevice[i] - 1]);
757
JE_dString(VGAScreen, 186, 38 + 2 * (i + 1) * 16, temp, SMALL_FONT_SHAPES);
761
/* JE: { - Step VI - Help text for current cursor location } */
765
/* JE: {Reset player weapons} */
766
memset(shotMultiPos, 0, sizeof(shotMultiPos));
770
JE_drawMainMenuHelpText();
772
if (newPal > 0) /* can't reindex this :( */
775
memcpy(colors, palettes[newPal - 1], sizeof(colors));
776
set_palette(palettes[newPal - 1], 0, 255);
780
/* datacube title under face */
781
if ( ( (curMenu == 7) || (curMenu == 8) ) && (curSel[7] < menuChoices[7]) )
782
JE_textShade (VGAScreen, 75 - JE_textWidth(cube[curSel[7] - 2].header, TINY_FONT) / 2, 173, cube[curSel[7] - 2].header, 14, 3, DARKEN);
784
/* SYN: Everything above was just drawing the screen. In the rest of it, we process
785
any user input (and do a few other things) */
787
/* SYN: Let's start by getting fresh events from SDL */
788
service_SDL_events(true);
792
mainLevel = mapSection[mapPNum-1];
799
/* Inner loop -- this handles animations on menus that need them and handles
800
some keyboard events. Events it can't handle end the loop and fall through
801
to the main keyboard handler below.
803
Also, I think all timing is handled in here. Somehow. */
805
NETWORK_KEEP_ALIVE();
810
if (col < -2 || col > 6)
818
if (mouseX > 164 && mouseX < 299 && mouseY > 47 && mouseY < 153)
826
fill_rectangle_xy(VGAScreen, 160, 49, 310, 158, 228);
836
tempW = 38 + 12 - temp2;
837
temp3 = cube[curSel[7] - 2].last_line;
839
for (int x = temp + 1; x <= temp + 10; x++)
843
JE_outTextAndDarken(VGAScreen, 161, tempW, cube[curSel[7] - 2].text[x-1], 14, 3, TINY_FONT);
848
fill_rectangle_xy(VGAScreen, 160, 39, 310, 48, 228);
849
fill_rectangle_xy(VGAScreen, 160, 157, 310, 166, 228);
851
int percent_read = (cube[currentCube].last_line <= 9)
853
: (yLoc * 100) / ((cube[currentCube].last_line - 9) * 12);
856
snprintf(buf, sizeof(buf), "%s %d%%", miscText[11], percent_read);
857
JE_outTextAndDarken(VGAScreen, 176, 160, buf, 14, 1, TINY_FONT);
859
JE_dString(VGAScreen, 260, 160, miscText[12], SMALL_FONT_SHAPES);
870
fade_palette(colors, 10, 0, 255);
871
backFromHelp = false;
879
/* current menu is not 8 (read data cube) */
883
JE_updateNavScreen();
884
JE_drawMainMenuHelpText();
886
JE_drawMenuChoices();
888
JE_dString(VGAScreen, 170, 140, miscText[68 - 1], FONT_SHAPES);
891
if (curMenu == 7 && curSel[7] < menuChoices[7])
893
/* Draw flashy cube */
894
blit_sprite_hv_blend(VGAScreenSeg, 166, 38 + (curSel[7] - 2) * 28, OPTION_SHAPES, 25, 13, col);
897
/* IF (curmenu = 5) AND (cursel [2] IN [3, 4, 6, 7, 8]) */
898
if (curMenu == 4 && ( curSel[1] == 3 || curSel[1] == 4 || ( curSel[1] >= 6 && curSel[1] <= 8) ) )
901
JE_weaponSimUpdate();
903
service_SDL_events(false);
908
set_palette(palettes[newPal - 1], 0, 255);
916
set_palette(colors, 0, 255);
917
paletteChanged = false;
920
JE_showVGA(); /* SYN: This is where it updates the screen for the weapon sim */
924
fade_palette(colors, 10, 0, 255);
925
backFromHelp = false;
930
} else { /* current menu is anything but weapon sim or datacube */
935
//JE_waitRetrace(); didn't do anything anyway?
940
set_palette(palettes[newPal - 1], 0, 255);
948
set_palette(colors, 0, 255);
949
paletteChanged = false;
952
JE_showVGA(); /* SYN: This is the where the screen updates for most menus */
958
fade_palette(colors, 10, 0, 255);
959
backFromHelp = false;
967
push_joysticks_as_keyboard();
968
service_SDL_events(false);
969
mouseButton = JE_mousePosition(&mouseX, &mouseY);
970
inputDetected = newkey || mouseButton > 0;
974
if (keysactive[SDLK_s] && (keysactive[SDLK_LALT] || keysactive[SDLK_RALT]) )
976
if (curMenu == 8 || curMenu == 7)
987
if (keysactive[SDLK_l] && (keysactive[SDLK_LALT] || keysactive[SDLK_RALT]) )
989
if (curMenu == 8 || curMenu == 7)
1004
if (mouseButton > 0 && mouseCursor >= 1)
1006
inputDetected = false;
1007
if (mouseCursor == 1)
1015
if (keysactive[SDLK_PAGEUP])
1018
inputDetected = false;
1020
if (keysactive[SDLK_PAGEDOWN])
1023
inputDetected = false;
1026
bool joystick_up = false, joystick_down = false;
1027
for (int j = 0; j < joysticks; j++)
1029
joystick_up |= joystick[j].direction[0];
1030
joystick_down |= joystick[j].direction[2];
1033
if (keysactive[SDLK_UP] || joystick_up)
1036
inputDetected = false;
1039
if (keysactive[SDLK_DOWN] || joystick_down)
1042
inputDetected = false;
1045
if (yChg < 0 && yLoc == 0)
1049
if (yChg > 0 && (yLoc / 12) > cube[currentCube].last_line - 10)
1055
} while (!inputDetected);
1058
keyboardUsed = false;
1060
/* The rest of this just grabs input events, handles them, then proceeds on. */
1062
if (mouseButton > 0)
1066
mouseButton = JE_mousePosition(&mouseX, &mouseY);
1068
if (curMenu == 7 && cubeMax == 0)
1071
JE_playSampleNum(S_SPRING);
1078
if ((mouseX > 258) && (mouseX < 290) && (mouseY > 159) && (mouseY < 171))
1081
JE_playSampleNum(S_SPRING);
1085
if (curMenu == 2 || curMenu == 11)
1087
if ((mouseX >= (225 - 4)) && (mouseY >= 70) && (mouseY <= 82))
1091
music_disabled = false;
1097
tyrMusicVolume = (mouseX - (225 - 4)) / 4 * 12;
1098
if (tyrMusicVolume > 255)
1099
tyrMusicVolume = 255;
1102
if ((mouseX >= (225 - 4)) && (mouseY >= 86) && (mouseY <= 98))
1104
samples_disabled = false;
1108
fxVolume = (mouseX - (225 - 4)) / 4 * 12;
1115
set_volume(tyrMusicVolume, fxVolume);
1117
JE_playSampleNum(S_CURSOR);
1120
if ((mouseY > 20) && (mouseX > 170) && (mouseX < 308) && (curMenu != 8))
1122
const JE_byte mouseSelectionY[MENU_MAX] = { 16, 16, 16, 16, 26, 12, 11, 28, 0, 16, 16, 16, 8, 16 };
1124
int selection = (mouseY - 38) / mouseSelectionY[curMenu]+2;
1140
// is play next level screen?
1143
if (selection == menuChoices[curMenu] + 1)
1144
selection = menuChoices[curMenu];
1147
if (selection <= menuChoices[curMenu])
1149
if ((curMenu == 4) && (selection == menuChoices[4]))
1151
player[0].cash = JE_cashLeft();
1153
JE_playSampleNum(S_ITEM);
1157
JE_playSampleNum(S_CLICK);
1158
if (curSel[curMenu] == selection)
1160
JE_menuFunction(curSel[curMenu]);
1164
if ((curMenu == 4) && (JE_getCost(curSel[1], itemAvail[itemAvailMap[curSel[2]-1]][selection-2]) > player[0].cash))
1166
JE_playSampleNum(S_CLINK);
1171
player[0].weapon_mode = 1;
1173
curSel[curMenu] = selection;
1176
// in front or rear weapon upgrade screen?
1177
if ((curMenu == 4) && ((curSel[1] == 3) || (curSel[1] == 4)))
1178
player[0].items.weapon[curSel[1]-3].power = temp_weapon_power[curSel[4]-2];
1183
wait_noinput(false, true, false);
1186
if ((curMenu == 4) && ((curSel[1] == 3) || (curSel[1] == 4)))
1188
if ((mouseX >= 23) && (mouseX <= 36) && (mouseY >= 149) && (mouseY <= 168))
1190
JE_playSampleNum(S_CURSOR);
1196
player[0].items.weapon[curSel[1]-3].power = --temp_weapon_power[curSel[4]-2];
1198
JE_playSampleNum(S_CLINK);
1202
wait_noinput(false, true, false);
1205
if ((mouseX >= 119) && (mouseX <= 131) && (mouseY >= 149) && (mouseY <= 168))
1207
JE_playSampleNum(S_CURSOR);
1212
if (rightPower && rightPowerAfford)
1213
player[0].items.weapon[curSel[1]-3].power = ++temp_weapon_power[curSel[4]-2];
1215
JE_playSampleNum(S_CLINK);
1219
wait_noinput(false, true, false);
1225
switch (lastkey_sym)
1228
// if in rear weapon upgrade screen
1229
if ( (curMenu == 4) && (curSel[1] == 4))
1231
// cycle weapon modes
1232
if (++player[0].weapon_mode > weaponPort[player[0].items.weapon[REAR_WEAPON].id].opnum)
1233
player[0].weapon_mode = 1;
1239
keyboardUsed = true;
1241
// if front or rear weapon, update "Done" power level
1242
if (curMenu == 4 && (curSel[1] == 3 || curSel[1] == 4))
1243
temp_weapon_power[itemAvailMax[itemAvailMap[curSel[1]-2]-1]] = player[0].items.weapon[curSel[1]-3].power;
1245
JE_menuFunction(curSel[curMenu]);
1249
keyboardUsed = true;
1251
JE_playSampleNum(S_SPRING);
1252
if ( (curMenu == 6) && quikSave)
1257
else if (menuEsc[curMenu] == 0)
1259
if (JE_quitRequest())
1267
if (curMenu == 4) // leaving upgrade menu without buying
1269
player[0].items = old_items[0];
1270
curSel[4] = lastCurSel;
1271
player[0].cash = JE_cashLeft();
1274
if (curMenu != 8) // not data cube
1277
curMenu = menuEsc[curMenu] - 1;
1289
JE_loadPic(VGAScreen, 1, false);
1302
memcpy(VGAScreen2->pixels, VGAScreen->pixels, VGAScreen2->pitch * VGAScreen2->h);
1305
memcpy(colors, palettes[newPal-1], sizeof(colors));
1308
backFromHelp = true;
1313
keyboardUsed = true;
1316
if (curMenu != 8) // not data cube
1317
JE_playSampleNum(S_CURSOR);
1320
if (curSel[curMenu] < 2)
1321
curSel[curMenu] = menuChoices[curMenu];
1323
// if in front or rear weapon upgrade screen
1324
if (curMenu == 4 && (curSel[1] == 3 || curSel[1] == 4))
1326
player[0].items.weapon[curSel[1]-3].power = temp_weapon_power[curSel[4]-2];
1327
if (curSel[curMenu] == 4)
1328
player[0].weapon_mode = 1;
1331
// if joystick config, skip disabled items when digital
1332
if (curMenu == 12 && joysticks > 0 && !joystick[joystick_config].analog && curSel[curMenu] == 5)
1333
curSel[curMenu] = 3;
1338
keyboardUsed = true;
1341
if (curMenu != 8) // not data cube
1342
JE_playSampleNum(S_CURSOR);
1345
if (curSel[curMenu] > menuChoices[curMenu])
1346
curSel[curMenu] = 2;
1348
// if in front or rear weapon upgrade screen
1349
if (curMenu == 4 && (curSel[1] == 3 || curSel[1] == 4))
1351
player[0].items.weapon[curSel[1]-3].power = temp_weapon_power[curSel[4]-2];
1352
if (curSel[curMenu] == 4)
1353
player[0].weapon_mode = 1;
1356
// if in joystick config, skip disabled items when digital
1357
if (curMenu == 12 && joysticks > 0 && !joystick[joystick_config].analog && curSel[curMenu] == 4)
1358
curSel[curMenu] = 6;
1363
if (curMenu == 8) // data cube
1368
if (curMenu == 8) // data cube
1369
yLoc = (cube[currentCube].last_line - 9) * 12;
1373
if (curMenu == 12) // joystick settings menu
1377
switch (curSel[curMenu])
1380
if (joystick_config == 0)
1381
joystick_config = joysticks;
1385
joystick[joystick_config].analog = !joystick[joystick_config].analog;
1388
if (joystick[joystick_config].sensitivity == 0)
1389
joystick[joystick_config].sensitivity = 10;
1391
joystick[joystick_config].sensitivity--;
1394
if (joystick[joystick_config].threshold == 0)
1395
joystick[joystick_config].threshold = 10;
1397
joystick[joystick_config].threshold--;
1407
switch (curSel[curMenu])
1411
JE_playSampleNum(S_CURSOR);
1413
int temp = curSel[curMenu] - 3;
1417
inputDevice[temp == 0 ? 1 : 0] = inputDevice[temp]; // swap controllers
1419
if (inputDevice[temp] <= 1)
1421
inputDevice[temp] = 2 + joysticks;
1423
inputDevice[temp]--;
1425
} while (inputDevice[temp] == inputDevice[temp == 0 ? 1 : 0]);
1430
if (curMenu == 2 || curMenu == 4 || curMenu == 11)
1432
JE_playSampleNum(S_CURSOR);
1439
switch (curSel[curMenu])
1442
JE_changeVolume(&tyrMusicVolume, -12, &fxVolume, 0);
1445
music_disabled = false;
1450
JE_changeVolume(&tyrMusicVolume, 0, &fxVolume, -12);
1451
samples_disabled = false;
1461
player[0].items.weapon[curSel[1]-3].power = --temp_weapon_power[curSel[4]-2];
1463
JE_playSampleNum(S_CLINK);
1472
if (curMenu == 12) // joystick settings menu
1476
switch (curSel[curMenu])
1480
joystick_config %= joysticks;
1483
joystick[joystick_config].analog = !joystick[joystick_config].analog;
1486
joystick[joystick_config].sensitivity++;
1487
joystick[joystick_config].sensitivity %= 11;
1490
joystick[joystick_config].threshold++;
1491
joystick[joystick_config].threshold %= 11;
1501
switch (curSel[curMenu])
1505
JE_playSampleNum(S_CURSOR);
1507
int temp = curSel[curMenu] - 3;
1511
inputDevice[temp == 0 ? 1 : 0] = inputDevice[temp]; // swap controllers
1513
if (inputDevice[temp] >= 2 + joysticks)
1515
inputDevice[temp] = 1;
1517
inputDevice[temp]++;
1519
} while (inputDevice[temp] == inputDevice[temp == 0 ? 1 : 0]);
1524
if (curMenu == 2 || curMenu == 4 || curMenu == 11)
1526
JE_playSampleNum(S_CURSOR);
1533
switch (curSel[curMenu])
1536
JE_changeVolume(&tyrMusicVolume, 12, &fxVolume, 0);
1539
music_disabled = false;
1544
JE_changeVolume(&tyrMusicVolume, 0, &fxVolume, 12);
1545
samples_disabled = false;
1554
if (rightPower && rightPowerAfford)
1555
player[0].items.weapon[curSel[1]-3].power = ++temp_weapon_power[curSel[4]-2];
1557
JE_playSampleNum(S_CLINK);
1570
} while (!(quit || gameLoaded || jumpSection));
1573
if (!quit && isNetworkGame)
1575
JE_barShade(VGAScreen, 3, 3, 316, 196);
1576
JE_barShade(VGAScreen, 1, 1, 318, 198);
1577
JE_dString(VGAScreen, 10, 160, "Waiting for other player.", SMALL_FONT_SHAPES);
1579
network_prepare(PACKET_WAITING);
1580
network_send(4); // PACKET_WAITING
1584
service_SDL_events(false);
1587
if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_WAITING)
1599
network_state_reset();
1604
while (!network_is_sync())
1606
service_SDL_events(false);
1619
void draw_ship_illustration( void )
1621
// full of evil hardcoding
1625
assert(player[0].items.ship > 0);
1627
const int sprite_id = (player[0].items.ship < COUNTOF(ships)) // shipedit ships get a default
1628
? ships[player[0].items.ship].bigshipgraphic - 1
1631
const int ship_x[6] = { 31, 0, 0, 0, 35, 31 },
1632
ship_y[6] = { 36, 0, 0, 0, 33, 35 };
1634
const int x = ship_x[sprite_id - 27],
1635
y = ship_y[sprite_id - 27];
1637
blit_sprite(VGAScreenSeg, x, y, OPTION_SHAPES, sprite_id);
1642
assert(player[0].items.generator > 0 && player[0].items.generator < 7);
1644
const int sprite_id = (player[0].items.generator == 1) // generator 1 and generator 2 have the same sprite
1645
? player[0].items.generator + 15
1646
: player[0].items.generator + 14;
1648
const int generator_x[5] = { 62, 64, 67, 66, 63 },
1649
generator_y[5] = { 84, 85, 86, 84, 97 };
1650
const int x = generator_x[sprite_id - 16],
1651
y = generator_y[sprite_id - 16];
1653
blit_sprite(VGAScreenSeg, x, y, WEAPON_SHAPES, sprite_id);
1656
const int weapon_sprites[43] =
1658
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,
1659
9, 10, 11, 21, 5, 13, -1, 14, 15, 0,
1660
14, 9, 8, 2, 15, 0, 13, 0, 8, 8,
1661
11, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1666
if (player[0].items.weapon[FRONT_WEAPON].id > 0)
1668
const int front_weapon_xy_list[43] =
1670
-1, 4, 9, 3, 8, 2, 5, 10, 1, -1,
1671
-1, -1, -1, 7, 8, -1, -1, 0, -1, 4,
1672
0, -1, -1, 3, -1, 4, -1, 4, -1, -1,
1673
-1, 9, 0, 0, 0, 0, 0, 0, 0, 0,
1677
const int front_weapon_x[12] = { 59, 66, 66, 54, 61, 51, 58, 51, 61, 52, 53, 58 };
1678
const int front_weapon_y[12] = { 38, 53, 41, 36, 48, 35, 41, 35, 53, 41, 39, 31 };
1679
const int x = front_weapon_x[front_weapon_xy_list[player[0].items.weapon[FRONT_WEAPON].id]],
1680
y = front_weapon_y[front_weapon_xy_list[player[0].items.weapon[FRONT_WEAPON].id]];
1682
blit_sprite(VGAScreenSeg, x, y, WEAPON_SHAPES, weapon_sprites[player[0].items.weapon[FRONT_WEAPON].id]); // ship illustration: front weapon
1686
if (player[0].items.weapon[REAR_WEAPON].id > 0)
1688
const int rear_weapon_xy_list[43] =
1690
-1, -1, -1, -1, -1, -1, -1, -1, -1, 0,
1691
1, 2, 3, -1, 4, 5, -1, -1, 6, -1,
1692
-1, 1, 0, -1, 6, -1, 5, -1, 0, 0,
1693
3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1697
const int rear_weapon_x[7] = { 41, 27, 49, 43, 51, 39, 41 };
1698
const int rear_weapon_y[7] = { 92, 92, 113, 102, 97, 96, 76 };
1699
const int x = rear_weapon_x[rear_weapon_xy_list[player[0].items.weapon[REAR_WEAPON].id]],
1700
y = rear_weapon_y[rear_weapon_xy_list[player[0].items.weapon[REAR_WEAPON].id]];
1702
blit_sprite(VGAScreenSeg, x, y, WEAPON_SHAPES, weapon_sprites[player[0].items.weapon[REAR_WEAPON].id]);
1706
JE_drawItem(6, player[0].items.sidekick[LEFT_SIDEKICK], 3, 84);
1707
JE_drawItem(7, player[0].items.sidekick[RIGHT_SIDEKICK], 129, 84);
1710
blit_sprite_hv(VGAScreenSeg, 28, 23, OPTION_SHAPES, 26, 15, shields[player[0].items.shield].mpwr - 10);
1713
void load_cubes( void )
1715
for (int cube_slot = 0; cube_slot < cubeMax; ++cube_slot)
1717
memset(cube[cube_slot].text, 0, sizeof(cube->text));
1719
load_cube(cube_slot, cubeList[cube_slot]);
1723
bool load_cube( int cube_slot, int cube_index )
1725
FILE *f = dir_fopen_die(data_dir(), cube_file, "rb");
1730
while (cube_index > 0)
1732
read_encrypted_pascal_string(buf, sizeof(buf), f);
1744
str_pop_int(&buf[4], &cube[cube_slot].face_sprite);
1745
--cube[cube_slot].face_sprite;
1747
read_encrypted_pascal_string(cube[cube_slot].title, sizeof(cube[cube_slot].title), f);
1748
read_encrypted_pascal_string(cube[cube_slot].header, sizeof(cube[cube_slot].header), f);
1750
uint line = 0, line_chars = 0, line_width = 0;
1752
// for each line of decrypted text, split the line into words
1753
// and add them individually to the lines of wrapped text
1756
read_encrypted_pascal_string(buf, sizeof(buf), f);
1759
if (feof(f) || buf[0] == '*')
1763
if (strlen(buf) == 0)
1765
if (line_chars == 0)
1766
line += 4; // subsequent new paragaphs indicate 4-line break
1775
uint word_start = 0;
1776
for (uint i = 0; ; ++i)
1778
bool end_of_line = (buf[i] == '\0'),
1779
end_of_word = end_of_line || (buf[i] == ' ');
1785
char *word = &buf[word_start];
1788
uint word_chars = strlen(word),
1789
word_width = JE_textWidth(word, TINY_FONT);
1791
// word won't fit; no can do
1792
if (word_chars > cube_line_chars || word_width > cube_line_width)
1795
bool prepend_space = true;
1797
line_chars += word_chars + (prepend_space ? 1 : 0);
1798
line_width += word_width + (prepend_space ? 6 : 0);
1800
// word won't fit on current line; use next
1801
if (line_chars > cube_line_chars || line_width > cube_line_width)
1804
line_chars = word_chars;
1805
line_width = word_width;
1807
prepend_space = false;
1811
if (line < COUNTOF(cube->text))
1814
strcat(cube[cube_slot].text[line], " ");
1815
strcat(cube[cube_slot].text[line], word);
1817
// track last line with text
1818
cube[cube_slot].last_line = line + 1;
1832
void JE_drawItem( JE_byte itemType, JE_word itemNum, JE_word x, JE_word y )
1842
tempW = weaponPort[itemNum].itemgraphic;
1845
tempW = powerSys[itemNum].itemgraphic;
1849
tempW = options[itemNum].itemgraphic;
1852
tempW = shields[itemNum].itemgraphic;
1860
shipGrPtr = &shapes9;
1861
shipGr = JE_SGr(itemNum - 90, &shipGrPtr);
1862
blit_sprite2x2(VGAScreen, x, y, *shipGrPtr, shipGr);
1866
blit_sprite2x2(VGAScreen, x, y, shapes9, ships[itemNum].shipgraphic);
1871
blit_sprite2x2(VGAScreen, x, y, shapes6, tempW);
1876
void JE_drawMenuHeader( void )
1881
strcpy(tempStr, cube[curSel[7]-2].header);
1884
strcpy(tempStr, menuInt[1][1]);
1887
strcpy(tempStr, menuInt[3][performSave + 1]);
1890
strcpy(tempStr, menuInt[curMenu + 1][0]);
1893
JE_dString(VGAScreen, 74 + JE_fontCenter(tempStr, FONT_SHAPES), 10, tempStr, FONT_SHAPES);
1896
void JE_drawMenuChoices( void )
1901
for (x = 2; x <= menuChoices[curMenu]; x++)
1903
int tempY = 38 + (x-1) * 16;
1925
if (!(curMenu == 3 && x == menuChoices[curMenu]))
1930
str = malloc(strlen(menuInt[curMenu + 1][x-1])+2);
1931
if (curSel[curMenu] == x)
1934
strcpy(str+1, menuInt[curMenu + 1][x-1]);
1936
strcpy(str, menuInt[curMenu + 1][x-1]);
1938
JE_dString(VGAScreen, 166, tempY, str, SMALL_FONT_SHAPES);
1941
if (keyboardUsed && curSel[curMenu] == x)
1943
set_mouse_position(305, tempY + 6);
1948
void JE_updateNavScreen( void )
1953
/* TODO: The scroll to the new planet is too fast, I think */
1954
/* TODO: The starting coordinates for the scrolling effect may be wrong, the
1955
yellowish planet below Tyrian isn't visible for as many frames as in the
1958
tempNavX = roundf(navX);
1959
tempNavY = roundf(navY);
1960
fill_rectangle_xy(VGAScreen, 19, 16, 135, 169, 2);
1961
JE_drawNavLines(true);
1962
JE_drawNavLines(false);
1965
for (x = 0; x < 11; x++)
1968
for (x = 0; x < menuChoices[3]-1; x++)
1970
if (mapPlanet[x] > 11)
1971
JE_drawPlanet(mapPlanet[x] - 1);
1975
JE_drawPlanet(mapOrigin - 1);
1977
blit_sprite(VGAScreenSeg, 0, 0, OPTION_SHAPES, 28); // navigation screen interface
1979
if (curSel[3] < menuChoices[3])
1981
const unsigned int origin_x_offset = sprite(PLANET_SHAPES, PGR[mapOrigin-1]-1)->width / 2,
1982
origin_y_offset = sprite(PLANET_SHAPES, PGR[mapOrigin-1]-1)->height / 2,
1983
dest_x_offset = sprite(PLANET_SHAPES, PGR[mapPlanet[curSel[3]-2] - 1]-1)->width / 2,
1984
dest_y_offset = sprite(PLANET_SHAPES, PGR[mapPlanet[curSel[3]-2] - 1]-1)->height / 2;
1986
newNavX = (planetX[mapOrigin-1] - origin_x_offset
1987
+ planetX[mapPlanet[curSel[3]-2] - 1] - dest_x_offset) / 2.0f;
1988
newNavY = (planetY[mapOrigin-1] - origin_y_offset
1989
+ planetY[mapPlanet[curSel[3]-2] - 1] - dest_y_offset) / 2.0f;
1992
navX = navX + (newNavX - navX) / 2.0f;
1993
navY = navY + (newNavY - navY) / 2.0f;
1995
if (abs(newNavX - navX) < 1)
1997
if (abs(newNavY - navY) < 1)
2000
fill_rectangle_xy(VGAScreen, 314, 0, 319, 199, 230);
2002
if (planetAniWait > 0)
2014
if (currentDotWait > 0)
2020
if (currentDotNum < planetDots[curSel[3]-2])
2026
void JE_drawLines( SDL_Surface *surface, JE_boolean dark )
2029
JE_integer tempX, tempY;
2030
JE_integer tempX2, tempY2;
2031
JE_word tempW, tempW2;
2037
for (x = 0; x < 20; x++)
2040
tempX = tempW - tempX2;
2042
if (tempX > 18 && tempX < 135)
2046
JE_rectangle(surface, tempX + 1, 0, tempX + 1, 199, 32+3);
2048
JE_rectangle(surface, tempX, 0, tempX, 199, 32+5);
2054
for (y = 0; y < 20; y++)
2057
tempY = tempW - tempY2;
2059
if (tempY > 15 && tempY < 169)
2063
JE_rectangle(surface, 0, tempY + 1, 319, tempY + 1, 32+3);
2065
JE_rectangle(surface, 0, tempY, 319, tempY, 32+5);
2070
for (x = 0; x < 20; x++)
2073
tempX = tempW2 - tempX2;
2074
if (tempX > 18 && tempX < 135)
2076
JE_pix3(surface, tempX, tempY, 32+6);
2083
/* SYN: This was originally PROC drawlines... yes, there were two different procs called
2084
drawlines in different scopes in the same file. Dammit, Jason, why do you do this to me? */
2086
void JE_drawNavLines( JE_boolean dark )
2089
JE_integer tempX, tempY;
2090
JE_integer tempX2, tempY2;
2091
JE_word tempW, tempW2;
2093
tempX2 = tempNavX >> 1;
2094
tempY2 = tempNavY >> 1;
2097
for (x = 1; x <= 20; x++)
2100
tempX = tempW - tempX2;
2102
if (tempX > 18 && tempX < 135)
2105
JE_rectangle(VGAScreen, tempX + 1, 16, tempX + 1, 169, 1);
2107
JE_rectangle(VGAScreen, tempX, 16, tempX, 169, 5);
2112
for (y = 1; y <= 20; y++)
2115
tempY = tempW - tempY2;
2117
if (tempY > 15 && tempY < 169)
2120
JE_rectangle(VGAScreen, 19, tempY + 1, 135, tempY + 1, 1);
2122
JE_rectangle(VGAScreen, 8, tempY, 160, tempY, 5);
2126
for (x = 0; x < 20; x++)
2129
tempX = tempW2 - tempX2;
2130
if (tempX > 18 && tempX < 135)
2131
JE_pix3(VGAScreen, tempX, tempY, 7);
2137
void JE_drawDots( void )
2140
JE_integer tempX, tempY;
2142
for (x = 0; x < mapPNum; x++)
2144
for (y = 0; y < planetDots[x]; y++)
2146
tempX = planetDotX[x][y] - tempNavX + 66 - 2;
2147
tempY = planetDotY[x][y] - tempNavY + 85 - 2;
2148
if (tempX > 0 && tempX < 140 && tempY > 0 && tempY < 168)
2149
blit_sprite(VGAScreenSeg, tempX, tempY, OPTION_SHAPES, (x == curSel[3]-2 && y < currentDotNum) ? 30 : 29); // navigation dots
2154
void JE_drawPlanet( JE_byte planetNum )
2156
JE_integer tempZ = PGR[planetNum]-1,
2157
tempX = planetX[planetNum] + 66 - tempNavX - sprite(PLANET_SHAPES, tempZ)->width / 2,
2158
tempY = planetY[planetNum] + 85 - tempNavY - sprite(PLANET_SHAPES, tempZ)->height / 2;
2160
if (tempX > -7 && tempX + sprite(PLANET_SHAPES, tempZ)->width < 170 && tempY > 0 && tempY < 160)
2162
if (PAni[planetNum])
2165
blit_sprite_dark(VGAScreenSeg, tempX + 3, tempY + 3, PLANET_SHAPES, tempZ, false);
2166
blit_sprite(VGAScreenSeg, tempX, tempY, PLANET_SHAPES, tempZ); // planets
2170
void JE_scaleBitmap( SDL_Surface *dst_bitmap, const SDL_Surface *src_bitmap, int x1, int y1, int x2, int y2 )
2172
/* This function scales one screen and writes the result to another.
2173
* The only code that calls it is the code run when you select 'ship
2174
* specs' from the main menu.
2176
* Originally this used fixed point math. I haven't seen that in ages :).
2177
* But we're well past the point of needing that.*/
2179
assert(src_bitmap != NULL && dst_bitmap != NULL);
2180
assert(x1 >= 0 && y1 >= 0 && x2 < src_bitmap->pitch && y2 < src_bitmap->h);
2182
int w = x2 - x1 + 1,
2184
float base_skip_w = src_bitmap->pitch / (float)w,
2185
base_skip_h = src_bitmap->h / (float)h;
2186
float cumulative_skip_w, cumulative_skip_h;
2189
//Okay, it's time to loop through and add bits of A to a rectangle in B
2190
Uint8 *dst = dst_bitmap->pixels; /* 8-bit specific */
2191
const Uint8 *src, *src_w; /* 8-bit specific */
2193
dst += y1 * dst_bitmap->pitch + x1;
2194
cumulative_skip_h = 0;
2196
for (int i = 0; i < h; i++)
2198
//this sets src to the beginning of our desired line
2199
src = src_w = (Uint8 *)(src_bitmap->pixels) + (src_bitmap->w * ((unsigned int)cumulative_skip_h));
2200
cumulative_skip_h += base_skip_h;
2201
cumulative_skip_w = 0;
2203
for (int j = 0; j < w; j++)
2205
//copy and move pointers
2209
cumulative_skip_w += base_skip_w;
2210
src = src_w + ((unsigned int)cumulative_skip_w); //value is floored
2213
dst += dst_bitmap->pitch - w;
2217
void JE_initWeaponView( void )
2219
fill_rectangle_xy(VGAScreen, 8, 8, 144, 177, 0);
2221
player[0].sidekick[LEFT_SIDEKICK].x = 72 - 15;
2222
player[0].sidekick[LEFT_SIDEKICK].y = 120;
2223
player[0].sidekick[RIGHT_SIDEKICK].x = 72 + 15;
2224
player[0].sidekick[RIGHT_SIDEKICK].y = 120;
2228
player[0].delta_x_shot_move = 0;
2229
player[0].delta_y_shot_move = 0;
2230
player[0].last_x_explosion_follow = 72;
2231
player[0].last_y_explosion_follow = 110;
2235
memset(shotAvail, 0, sizeof(shotAvail));
2237
memset(shotRepeat, 1, sizeof(shotRepeat));
2238
memset(shotMultiPos, 0, sizeof(shotMultiPos));
2240
initialize_starfield();
2243
void JE_computeDots( void )
2245
JE_integer tempX, tempY;
2246
JE_longint distX, distY;
2249
for (x = 0; x < mapPNum; x++)
2251
distX = (int)(planetX[mapPlanet[x]-1]) - (int)(planetX[mapOrigin-1]);
2252
distY = (int)(planetY[mapPlanet[x]-1]) - (int)(planetY[mapOrigin-1]);
2253
tempX = abs(distX) + abs(distY);
2257
planetDots[x] = roundf(sqrtf(sqrtf((distX * distX) + (distY * distY)))) - 1;
2262
if (planetDots[x] > 10)
2267
for (y = 0; y < planetDots[x]; y++)
2269
tempX = JE_partWay(planetX[mapOrigin-1], planetX[mapPlanet[x]-1], planetDots[x], y);
2270
tempY = JE_partWay(planetY[mapOrigin-1], planetY[mapPlanet[x]-1], planetDots[x], y);
2271
/* ??? Why does it use temp? =P */
2272
planetDotX[x][y] = tempX;
2273
planetDotY[x][y] = tempY;
2278
JE_integer JE_partWay( JE_integer start, JE_integer finish, JE_byte dots, JE_byte dist )
2280
return (finish - start) / (dots + 2) * (dist + 1) + start;
2283
void JE_doShipSpecs( void )
2285
/* This function is called whenever you select 'ship specs' in the
2286
* game menu. It draws the nice green tech screen and scales it onto
2287
* the main window. To do this we need two temp buffers, so we're going
2288
* to use VGAScreen and game_screen for the purpose (making things more
2289
* complex than they would be if we just malloc'd, but faster)
2291
* Originally the whole system was pretty oddly designed. So I changed it.
2292
* Currently drawFunkyScreen creates the image, scaleInPicture draws it,
2293
* and doFunkyScreen ties everything together. Before it was more like
2294
* an oddly designed, unreusable, global sharing hierarchy. */
2296
//create the image we want
2297
wait_noinput(true, true, true);
2298
JE_drawShipSpecs(game_screen, VGAScreen2);
2300
//reset VGAScreen2, which we clobbered
2301
JE_loadPic(VGAScreen2, 1, false);
2304
JE_playSampleNum(16);
2305
JE_scaleInPicture(VGAScreen, game_screen);
2306
wait_input(true, true, true);
2309
void JE_drawMainMenuHelpText( void )
2314
temp = curSel[curMenu] - 2;
2315
if (curMenu == 12) // joystick settings menu help
2317
int help[16] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 24, 11 };
2318
memcpy(tempStr, mainMenuHelp[help[curSel[curMenu] - 2]], sizeof(tempStr));
2320
else if (curMenu < 3 || curMenu == 9 || curMenu > 10)
2322
memcpy(tempStr, mainMenuHelp[(menuHelp[curMenu][temp])-1], sizeof(tempStr));
2324
else if (curMenu == 5 && curSel[5] == 10)
2326
memcpy(tempStr, mainMenuHelp[25-1], sizeof(tempStr));
2328
else if (leftPower || rightPower)
2330
memcpy(tempStr, mainMenuHelp[24-1], sizeof(tempStr));
2332
else if ( (temp == menuChoices[curMenu] - 1) || ( (curMenu == 7) && (cubeMax == 0) ) )
2334
memcpy(tempStr, mainMenuHelp[12-1], sizeof(tempStr));
2338
memcpy(tempStr, mainMenuHelp[17 + curMenu - 3], sizeof(tempStr));
2341
JE_textShade(VGAScreen, 10, 187, tempStr, 14, 1, DARKEN);
2344
JE_boolean JE_quitRequest( void )
2346
bool quit_selected = true, done = false;
2350
wait_noinput(true, true, true);
2352
JE_barShade(VGAScreen, 65, 55, 255, 155);
2361
service_SDL_events(true);
2364
blit_sprite(VGAScreen, 50, 50, OPTION_SHAPES, 35); // message box
2365
JE_textShade(VGAScreen, 70, 60, miscText[28], 0, 5, FULL_SHADE);
2366
JE_helpBox(VGAScreen, 70, 90, miscText[30], 30);
2369
if (col > 8 || col < 2)
2374
temp_x = 54 + 45 - (JE_textWidth(miscText[9], FONT_SHAPES) / 2);
2375
temp_c = quit_selected ? col - 12 : -5;
2377
JE_outTextAdjust(VGAScreen, temp_x, 128, miscText[9], 15, temp_c, FONT_SHAPES, true);
2379
temp_x = 149 + 45 - (JE_textWidth(miscText[10], FONT_SHAPES) / 2);
2380
temp_c = !quit_selected ? col - 12 : -5;
2382
JE_outTextAdjust(VGAScreen, temp_x, 128, miscText[10], 15, temp_c, FONT_SHAPES, true);
2397
push_joysticks_as_keyboard();
2398
service_SDL_events(false);
2400
} while (!newkey && !mousedown);
2404
if (lastmouse_y > 123 && lastmouse_y < 149)
2406
if (lastmouse_x > 56 && lastmouse_x < 142)
2408
quit_selected = true;
2411
else if (lastmouse_x > 151 && lastmouse_x < 237)
2413
quit_selected = false;
2421
switch (lastkey_sym)
2426
quit_selected = !quit_selected;
2427
JE_playSampleNum(S_CURSOR);
2434
quit_selected = false;
2443
JE_playSampleNum(quit_selected ? S_SPRING : S_CLICK);
2446
if (isNetworkGame && quit_selected)
2448
network_prepare(PACKET_QUIT);
2449
network_send(4); // PACKET QUIT
2451
network_tyrian_halt(0, true);
2455
return quit_selected;
2458
void JE_genItemMenu( JE_byte itemNum )
2460
menuChoices[4] = itemAvailMax[itemAvailMap[itemNum - 2] - 1] + 2;
2463
temp2 = *playeritem_map(&player[0].items, itemNum - 2);
2465
strcpy(menuInt[5][0], menuInt[2][itemNum - 1]);
2467
for (tempW = 0; tempW < itemAvailMax[itemAvailMap[itemNum - 2] - 1]; tempW++)
2469
temp = itemAvail[itemAvailMap[itemNum - 2] - 1][tempW];
2473
strcpy(tempStr, ships[temp].name);
2477
strcpy(tempStr, weaponPort[temp].name);
2480
strcpy(tempStr, shields[temp].name);
2483
strcpy(tempStr, powerSys[temp].name);
2487
strcpy(tempStr, options[temp].name);
2494
strcpy(menuInt[5][tempW], tempStr);
2497
strcpy(menuInt[5][tempW], miscText[13]);
2502
void JE_scaleInPicture( SDL_Surface *dst, const SDL_Surface *src )
2504
for (int i = 2; i <= 160; i += 2)
2506
if (JE_anyButton()) { break; }
2508
JE_scaleBitmap(dst, src, 160 - i, 0, 160 + i - 1, 100 + roundf(i * 0.625f) - 1);
2516
void JE_drawScore( void )
2521
sprintf(cl, "%d", JE_cashLeft());
2522
JE_textShade(VGAScreen, 65, 173, cl, 1, 6, DARKEN);
2526
void JE_menuFunction( JE_byte select )
2533
JE_playSampleNum(S_CLICK);
2535
curSelect = curSel[curMenu];
2549
case 4://upgradeship
2559
navX = planetX[mapOrigin - 1];
2560
navY = planetY[mapOrigin - 1];
2563
menuChoices[3] = mapPNum + 2;
2565
strcpy(menuInt[4][0], "Next Level");
2566
for (x = 0; x < mapPNum; x++)
2568
temp = mapPlanet[x];
2569
strcpy(menuInt[4][x + 1], pName[temp - 1]);
2571
strcpy(menuInt[4][x + 1], miscText[5]);
2574
if (JE_quitRequest())
2583
case 1: //upgradeship
2584
if (select == 9) //done
2588
else // selected item to upgrade
2590
old_items[0] = player[0].items;
2593
JE_genItemMenu(select);
2594
JE_initWeaponView();
2596
lastCurSel = curSel[4];
2597
player[0].cash = player[0].cash * 2 - JE_cashLeft();
2606
performSave = false;
2627
if (select == menuChoices[3]) //exit
2632
mainLevel = mapSection[curSelect - 2];
2638
if (curSel[4] < menuChoices[4])
2641
curSel[4] = menuChoices[4];
2643
else // if done is selected
2645
JE_playSampleNum(S_ITEM);
2647
player[0].cash = JE_cashLeft();
2652
case 5: /* keyboard settings */
2653
if (curSelect == 10) /* reset to defaults */
2655
memcpy(keySettings, defaultKeySettings, sizeof(keySettings));
2657
else if (curSelect == 11) /* done */
2659
if (isNetworkGame || onePlayerAction)
2666
else /* change key */
2669
int tempY = 38 + (curSelect - 2) * 12;
2670
JE_textShade(VGAScreen, 236, tempY, SDL_GetKeyName(keySettings[curSelect-2]), (temp2 / 16), (temp2 % 16) - 8, DARKEN);
2673
wait_noinput(true, true, true);
2682
if (col < 243 || col > 248)
2686
JE_rectangle(VGAScreen, 230, tempY - 2, 300, tempY + 7, col);
2689
service_SDL_events(true);
2694
} while (!newkey && !mousedown && !joydown);
2698
// already used? then swap
2699
for (uint i = 0; i < COUNTOF(keySettings); ++i)
2701
if (keySettings[i] == lastkey_sym)
2703
keySettings[i] = keySettings[curSelect-2];
2708
if (lastkey_sym != SDLK_ESCAPE && // reserved for menu
2709
lastkey_sym != SDLK_F11 && // reserved for gamma
2710
lastkey_sym != SDLK_p) // reserved for pause
2712
JE_playSampleNum(S_CLICK);
2713
keySettings[curSelect-2] = lastkey_sym;
2723
if (curSelect == 13)
2739
JE_operation(curSelect - 1 + temp);
2749
if (curSelect == menuChoices[curMenu])
2760
currentCube = curSel[7] - 2;
2773
switch (curSel[curMenu])
2776
mainLevel = mapSection[mapPNum-1];
2781
JE_playSampleNum(S_CURSOR);
2783
int temp = curSel[curMenu] - 3;
2787
inputDevice[temp == 0 ? 1 : 0] = inputDevice[temp]; // swap controllers
2789
if (inputDevice[temp] >= 2 + joysticks)
2791
inputDevice[temp] = 1;
2793
inputDevice[temp]++;
2795
} while (inputDevice[temp] == inputDevice[temp == 0 ? 1 : 0]);
2801
if (JE_quitRequest())
2811
switch (curSel[curMenu])
2814
mainLevel = mapSection[mapPNum-1];
2821
if (JE_quitRequest())
2830
case 11: //dunno, possibly online multiplayer
2846
if (joysticks == 0 && select != 17)
2853
joystick_config %= joysticks;
2856
joystick[joystick_config].analog = !joystick[joystick_config].analog;
2859
if (joystick[joystick_config].analog)
2861
joystick[joystick_config].sensitivity++;
2862
joystick[joystick_config].sensitivity %= 11;
2866
if (joystick[joystick_config].analog)
2868
joystick[joystick_config].threshold++;
2869
joystick[joystick_config].threshold %= 11;
2873
reset_joystick_assignments(joystick_config);
2876
if (isNetworkGame || onePlayerAction)
2888
// JE_textShade(VGAScreen, 236, 38 + i * 8, value, temp / 16, temp % 16 - 8, DARKEN);
2890
JE_rectangle(VGAScreen, 235, 21 + select * 8, 310, 30 + select * 8, 248);
2892
Joystick_assignment temp;
2893
if (detect_joystick_assignment(joystick_config, &temp))
2895
// if the detected assignment was already set, unset it
2896
for (uint i = 0; i < COUNTOF(*joystick->assignment); i++)
2898
if (joystick_assignment_cmp(&temp, &joystick[joystick_config].assignment[select - 6][i]))
2900
joystick[joystick_config].assignment[select - 6][i].type = NONE;
2901
goto joystick_assign_done;
2905
// if there is an empty assignment, set it
2906
for (uint i = 0; i < COUNTOF(*joystick->assignment); i++)
2908
if (joystick[joystick_config].assignment[select - 6][i].type == NONE)
2910
joystick[joystick_config].assignment[select - 6][i] = temp;
2911
goto joystick_assign_done;
2915
// if no assignments are empty, shift them all forward and set the last one
2916
for (uint i = 0; i < COUNTOF(*joystick->assignment); i++)
2918
if (i == COUNTOF(*joystick->assignment) - 1)
2919
joystick[joystick_config].assignment[select - 6][i] = temp;
2921
joystick[joystick_config].assignment[select - 6][i] = joystick[joystick_config].assignment[select - 6][i + 1];
2924
joystick_assign_done:
2933
switch (curSel[curMenu])
2936
mainLevel = mapSection[mapPNum-1];
2946
if (JE_quitRequest())
2959
old_items[0] = player[0].items;
2962
void JE_drawShipSpecs( SDL_Surface * screen, SDL_Surface * temp_screen )
2964
/* In this function we create our ship description image.
2966
* We use a temp screen for convenience. Bad design maybe (Jason!),
2967
* but it'll be okay (and the alternative is malloc/a large stack) */
2969
int temp_x = 0, temp_y = 0, temp_index;
2973
//first, draw the text and other assorted flavoring.
2975
JE_drawLines(screen, true);
2976
JE_drawLines(screen, false);
2977
JE_rectangle(screen, 0, 0, 319, 199, 37);
2978
JE_rectangle(screen, 1, 1, 318, 198, 35);
2981
JE_outText(screen, 10, 2, ships[player[0].items.ship].name, 12, 3);
2982
JE_helpBox(screen, 100, 20, shipInfo[player[0].items.ship-1][0], 40);
2983
JE_helpBox(screen, 100, 100, shipInfo[player[0].items.ship-1][1], 40);
2986
JE_outText(screen, JE_fontCenter(miscText[4], TINY_FONT), 190, miscText[4], 12, 2);
2989
//now draw the green ship over that.
2990
//This hardcoded stuff is for positioning our little ship graphic
2991
if (player[0].items.ship > 90)
2995
else if (player[0].items.ship > 0)
2997
temp_index = ships[player[0].items.ship].bigshipgraphic;
3001
temp_index = ships[old_items[0].ship].bigshipgraphic;
3024
//draw the ship into our temp buffer.
3025
JE_clr256(temp_screen);
3026
blit_sprite(temp_screen, temp_x, temp_y, OPTION_SHAPES, temp_index - 1); // ship illustration
3028
/* But wait! Our ship is fully colored, not green!
3029
* With a little work we could get the sprite dimensions and greenify
3030
* the area it resides in. For now, let's just greenify the (almost
3031
* entirely) black screen.
3033
* We can't work in place. In fact we'll need to overlay the result
3034
* To avoid our temp screen dependence this has been rewritten to
3035
* only write one line at a time.*/
3036
dst = screen->pixels;
3037
src = temp_screen->pixels;
3038
for (int y = 0; y < screen->h; y++)
3040
for (int x = 0; x < screen->pitch; x++)
3044
avg += *(src - screen->pitch) & 0x0f;
3045
if (y < screen->h - 1)
3046
avg += *(src + screen->pitch) & 0x0f;
3048
avg += *(src - 1) & 0x0f;
3049
if (x < screen->pitch - 1)
3050
avg += *(src + 1) & 0x0f;
3053
if ((*src & 0x0f) > avg)
3055
*dst = (*src & 0x0f) | 0xc0;
3066
void JE_weaponSimUpdate( void )
3070
JE_weaponViewFrame();
3072
if ( (curSel[1] == 3 && curSel[4] < menuChoices[4]) || (curSel[1] == 4 && curSel[4] < menuChoices[4] - 1) )
3076
sprintf(buf, "%d", downgradeCost);
3077
JE_outText(VGAScreen, 26, 137, buf, 1, 4);
3081
blit_sprite(VGAScreenSeg, 24, 149, OPTION_SHAPES, 13); // downgrade disabled
3086
if (!rightPowerAfford)
3088
sprintf(buf, "%d", upgradeCost);
3089
JE_outText(VGAScreen, 108, 137, buf, 7, 4);
3090
blit_sprite(VGAScreenSeg, 119, 149, OPTION_SHAPES, 14); // upgrade disabled
3094
sprintf(buf, "%d", upgradeCost);
3095
JE_outText(VGAScreen, 108, 137, buf, 1, 4);
3100
blit_sprite(VGAScreenSeg, 119, 149, OPTION_SHAPES, 14); // upgrade disabled
3103
temp = player[0].items.weapon[curSel[1]-3].power;
3105
for (int x = 1; x <= temp; x++)
3107
fill_rectangle_xy(VGAScreen, 39 + x * 6, 151, 39 + x * 6 + 4, 151, 251);
3108
JE_pix(VGAScreen, 39 + x * 6, 151, 252);
3109
fill_rectangle_xy(VGAScreen, 39 + x * 6, 152, 39 + x * 6 + 4, 164, 250);
3110
fill_rectangle_xy(VGAScreen, 39 + x * 6, 165, 39 + x * 6 + 4, 165, 249);
3113
sprintf(buf, "POWER: %d", temp);
3114
JE_outText(VGAScreen, 58, 137, buf, 15, 4);
3120
blit_sprite(VGAScreenSeg, 20, 146, OPTION_SHAPES, 17); // hide power level interface
3123
JE_drawItem(1, player[0].items.ship, player[0].x - 5, player[0].y - 7);
3126
void JE_weaponViewFrame( void )
3128
fill_rectangle_xy(VGAScreen, 8, 8, 143, 182, 0);
3130
/* JE: (* Port Configuration Display *)
3131
(* drawportconfigbuttons;*/
3133
update_and_draw_starfield(VGAScreen, 1);
3135
mouseX = player[0].x;
3136
mouseY = player[0].y;
3138
// create shots in weapon simulator
3139
for (uint i = 0; i < 2; ++i)
3141
if (shotRepeat[i] > 0)
3147
const uint item = player[0].items.weapon[i].id,
3148
item_power = player[0].items.weapon[i].power - 1,
3149
item_mode = (i == REAR_WEAPON) ? player[0].weapon_mode - 1 : 0;
3151
b = player_shot_create(item, i, player[0].x, player[0].y, mouseX, mouseY, weaponPort[item].op[item_mode][item_power], 1);
3155
if (options[player[0].items.sidekick[LEFT_SIDEKICK]].wport > 0)
3157
if (shotRepeat[SHOT_LEFT_SIDEKICK] > 0)
3159
--shotRepeat[SHOT_LEFT_SIDEKICK];
3163
const uint item = player[0].items.sidekick[LEFT_SIDEKICK];
3164
const int x = player[0].sidekick[LEFT_SIDEKICK].x,
3165
y = player[0].sidekick[LEFT_SIDEKICK].y;
3167
b = player_shot_create(options[item].wport, SHOT_LEFT_SIDEKICK, x, y, mouseX, mouseY, options[item].wpnum, 1);
3171
if (options[player[0].items.sidekick[RIGHT_SIDEKICK]].tr == 2)
3173
player[0].sidekick[RIGHT_SIDEKICK].x = player[0].x;
3174
player[0].sidekick[RIGHT_SIDEKICK].y = MAX(10, player[0].y - 20);
3178
player[0].sidekick[RIGHT_SIDEKICK].x = 72 + 15;
3179
player[0].sidekick[RIGHT_SIDEKICK].y = 120;
3182
if (options[player[0].items.sidekick[RIGHT_SIDEKICK]].wport > 0)
3184
if (shotRepeat[SHOT_RIGHT_SIDEKICK] > 0)
3186
--shotRepeat[SHOT_RIGHT_SIDEKICK];
3190
const uint item = player[0].items.sidekick[RIGHT_SIDEKICK];
3191
const int x = player[0].sidekick[RIGHT_SIDEKICK].x,
3192
y = player[0].sidekick[RIGHT_SIDEKICK].y;
3194
b = player_shot_create(options[item].wport, SHOT_RIGHT_SIDEKICK, x, y, mouseX, mouseY, options[item].wpnum, 1);
3198
simulate_player_shots();
3200
blit_sprite(VGAScreenSeg, 0, 0, OPTION_SHAPES, 12); // upgrade interface
3203
/*========================Power Bar=========================*/
3211
for (temp = 147 - temp; temp <= 146; temp++)
3213
temp2 = 113 + (146 - temp) / 9 + 2;
3214
temp3 = (temp + 1) % 6;
3217
else if (temp3 != 0)
3220
JE_pix(VGAScreen, 141, temp, temp2 - 3);
3221
JE_pix(VGAScreen, 142, temp, temp2 - 3);
3222
JE_pix(VGAScreen, 143, temp, temp2 - 2);
3223
JE_pix(VGAScreen, 144, temp, temp2 - 1);
3224
fill_rectangle_xy(VGAScreen, 145, temp, 149, temp, temp2);
3226
if (temp2 - 3 < 112)
3230
temp = 147 - (power / 10);
3231
temp2 = 113 + (146 - temp) / 9 + 4;
3233
JE_pix(VGAScreen, 141, temp - 1, temp2 - 1);
3234
JE_pix(VGAScreen, 142, temp - 1, temp2 - 1);
3235
JE_pix(VGAScreen, 143, temp - 1, temp2 - 1);
3236
JE_pix(VGAScreen, 144, temp - 1, temp2 - 1);
3238
fill_rectangle_xy(VGAScreen, 145, temp-1, 149, temp-1, temp2);
3242
//JE_waitFrameCount(); TODO: didn't do anything?