Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
9169 | turbocat | 1 | /* |
2 | * OpenTyrian: A modern cross-platform port of Tyrian |
||
3 | * Copyright (C) 2007-2009 The OpenTyrian Development Team |
||
4 | * |
||
5 | * This program is free software; you can redistribute it and/or |
||
6 | * modify it under the terms of the GNU General Public License |
||
7 | * as published by the Free Software Foundation; either version 2 |
||
8 | * of the License, or (at your option) any later version. |
||
9 | * |
||
10 | * This program is distributed in the hope that it will be useful, |
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
13 | * GNU General Public License for more details. |
||
14 | * |
||
15 | * You should have received a copy of the GNU General Public License |
||
16 | * along with this program; if not, write to the Free Software |
||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||
18 | */ |
||
19 | #include "varz.h" |
||
20 | |||
21 | #include "config.h" |
||
22 | #include "editship.h" |
||
23 | #include "episodes.h" |
||
24 | #include "joystick.h" |
||
25 | #include "lds_play.h" |
||
26 | #include "loudness.h" |
||
27 | #include "mainint.h" |
||
28 | #include "mouse.h" |
||
29 | #include "mtrand.h" |
||
30 | #include "network.h" |
||
31 | #include "nortsong.h" |
||
32 | #include "nortvars.h" |
||
33 | #include "opentyr.h" |
||
34 | #include "shots.h" |
||
35 | #include "sprite.h" |
||
36 | #include "vga256d.h" |
||
37 | #include "video.h" |
||
38 | |||
39 | JE_integer tempDat, tempDat2, tempDat3; |
||
40 | |||
41 | const JE_byte SANextShip[SA + 2] /* [0..SA + 1] */ = { 3, 9, 6, 2, 5, 1, 4, 3, 7 }; // 0 -> 3 -> 2 -> 6 -> 4 -> 5 -> 1 -> 9 -> 7 |
||
42 | const JE_word SASpecialWeapon[SA] /* [1..SA] */ = { 7, 8, 9, 10, 11, 12, 13 }; |
||
43 | const JE_word SASpecialWeaponB[SA] /* [1..SA] */ = {37, 6, 15, 40, 16, 14, 41 }; |
||
44 | const JE_byte SAShip[SA] /* [1..SA] */ = { 3, 1, 5, 10, 2, 11, 12 }; |
||
45 | const JE_word SAWeapon[SA][5] /* [1..SA, 1..5] */ = |
||
46 | { /* R Bl Bk G P */ |
||
47 | { 9, 31, 32, 33, 34 }, /* Stealth Ship */ |
||
48 | { 19, 8, 22, 41, 34 }, /* StormWind */ |
||
49 | { 27, 5, 20, 42, 31 }, /* Techno */ |
||
50 | { 15, 3, 28, 22, 12 }, /* Enemy */ |
||
51 | { 23, 35, 25, 14, 6 }, /* Weird */ |
||
52 | { 2, 5, 21, 4, 7 }, /* Unknown */ |
||
53 | { 40, 38, 37, 41, 36 } /* NortShip Z */ |
||
54 | }; |
||
55 | |||
56 | const JE_byte specialArcadeWeapon[PORT_NUM] /* [1..Portnum] */ = |
||
57 | { |
||
58 | 17,17,18,0,0,0,10,0,0,0,0,0,44,0,10,0,19,0,0,-0,0,0,0,0,0,0, |
||
59 | -0,0,0,0,45,0,0,0,0,0,0,0,0,0,0,0 |
||
60 | }; |
||
61 | |||
62 | const JE_byte optionSelect[16][3][2] /* [0..15, 1..3, 1..2] */ = |
||
63 | { /* MAIN OPT FRONT */ |
||
64 | { { 0, 0},{ 0, 0},{ 0, 0} }, /**/ |
||
65 | { { 1, 1},{16,16},{30,30} }, /*Single Shot*/ |
||
66 | { { 2, 2},{29,29},{29,20} }, /*Dual Shot*/ |
||
67 | { { 3, 3},{21,21},{12, 0} }, /*Charge Cannon*/ |
||
68 | { { 4, 4},{18,18},{16,23} }, /*Vulcan*/ |
||
69 | { { 0, 0},{ 0, 0},{ 0, 0} }, /**/ |
||
70 | { { 6, 6},{29,16},{ 0,22} }, /*Super Missile*/ |
||
71 | { { 7, 7},{19,19},{19,28} }, /*Atom Bomb*/ |
||
72 | { { 0, 0},{ 0, 0},{ 0, 0} }, /**/ |
||
73 | { { 0, 0},{ 0, 0},{ 0, 0} }, /**/ |
||
74 | { {10,10},{21,21},{21,27} }, /*Mini Missile*/ |
||
75 | { { 0, 0},{ 0, 0},{ 0, 0} }, /**/ |
||
76 | { { 0, 0},{ 0, 0},{ 0, 0} }, /**/ |
||
77 | { {13,13},{17,17},{13,26} }, /*MicroBomb*/ |
||
78 | { { 0, 0},{ 0, 0},{ 0, 0} }, /**/ |
||
79 | { {15,15},{15,16},{15,16} } /*Post-It*/ |
||
80 | }; |
||
81 | |||
82 | const JE_word PGR[21] /* [1..21] */ = |
||
83 | { |
||
84 | 4, |
||
85 | 1,2,3, |
||
86 | 41-21,57-21,73-21,89-21,105-21, |
||
87 | 121-21,137-21,153-21, |
||
88 | 151,151,151,151,73-21,73-21,1,2,4 |
||
89 | /*151,151,151*/ |
||
90 | }; |
||
91 | const JE_byte PAni[21] /* [1..21] */ = {1,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1}; |
||
92 | |||
93 | const JE_word linkGunWeapons[38] /* [1..38] */ = |
||
94 | { |
||
95 | 0,0,0,0,0,0,0,0,444,445,446,447,0,448,449,0,0,0,0,0,450,451,0,506,0,564, |
||
96 | 445,446,447,448,449,445,446,447,448,449,450,451 |
||
97 | }; |
||
98 | const JE_word chargeGunWeapons[38] /* [1..38] */ = |
||
99 | { |
||
100 | 0,0,0,0,0,0,0,0,476,458,464,482,0,488,470,0,0,0,0,0,494,500,0,528,0,558, |
||
101 | 458,458,458,458,458,458,458,458,458,458,458,458 |
||
102 | }; |
||
103 | const JE_byte randomEnemyLaunchSounds[3] /* [1..3] */ = {13,6,26}; |
||
104 | |||
105 | /* YKS: Twiddle cheat sheet: |
||
106 | * 1: UP |
||
107 | * 2: DOWN |
||
108 | * 3: LEFT |
||
109 | * 4: RIGHT |
||
110 | * 5: UP+FIRE |
||
111 | * 6: DOWN+FIRE |
||
112 | * 7: LEFT+FIRE |
||
113 | * 8: RIGHT+FIRE |
||
114 | * 9: Release all keys (directions and fire) |
||
115 | */ |
||
116 | const JE_byte keyboardCombos[26][8] /* [1..26, 1..8] */ = |
||
117 | { |
||
118 | { 2, 1, 2, 5, 137, 0, 0, 0}, /*Invulnerability*/ |
||
119 | { 4, 3, 2, 5, 138, 0, 0, 0}, /*Atom Bomb*/ |
||
120 | { 3, 4, 6, 139, 0, 0, 0, 0}, /*Seeker Bombs*/ |
||
121 | { 2, 5, 142, 0, 0, 0, 0, 0}, /*Ice Blast*/ |
||
122 | { 6, 2, 6, 143, 0, 0, 0, 0}, /*Auto Repair*/ |
||
123 | { 6, 7, 5, 8, 6, 7, 5, 112 }, /*Spin Wave*/ |
||
124 | { 7, 8, 101, 0, 0, 0, 0, 0}, /*Repulsor*/ |
||
125 | { 1, 7, 6, 146, 0, 0, 0, 0}, /*Protron Field*/ |
||
126 | { 8, 6, 7, 1, 120, 0, 0, 0}, /*Minefield*/ |
||
127 | { 3, 6, 8, 5, 121, 0, 0, 0}, /*Post-It Blast*/ |
||
128 | { 1, 2, 7, 8, 119, 0, 0, 0}, /*Drone Ship - TBC*/ |
||
129 | { 3, 4, 3, 6, 123, 0, 0, 0}, /*Repair Player 2*/ |
||
130 | { 6, 7, 5, 8, 124, 0, 0, 0}, /*Super Bomb - TBC*/ |
||
131 | { 1, 6, 125, 0, 0, 0, 0, 0}, /*Hot Dog*/ |
||
132 | { 9, 5, 126, 0, 0, 0, 0, 0}, /*Lightning UP */ |
||
133 | { 1, 7, 127, 0, 0, 0, 0, 0}, /*Lightning UP+LEFT */ |
||
134 | { 1, 8, 128, 0, 0, 0, 0, 0}, /*Lightning UP+RIGHT*/ |
||
135 | { 9, 7, 129, 0, 0, 0, 0, 0}, /*Lightning LEFT */ |
||
136 | { 9, 8, 130, 0, 0, 0, 0, 0}, /*Lightning RIGHT*/ |
||
137 | { 4, 2, 3, 5, 131, 0, 0, 0}, /*Warfly */ |
||
138 | { 3, 1, 2, 8, 132, 0, 0, 0}, /*FrontBlaster */ |
||
139 | { 2, 4, 5, 133, 0, 0, 0, 0}, /*Gerund */ |
||
140 | { 3, 4, 2, 8, 134, 0, 0, 0}, /*FireBomb */ |
||
141 | { 1, 4, 6, 135, 0, 0, 0, 0}, /*Indigo */ |
||
142 | { 1, 3, 6, 137, 0, 0, 0, 0}, /*Invulnerability [easier] */ |
||
143 | { 1, 4, 3, 4, 7, 136, 0, 0} /*D-Media Protron Drone */ |
||
144 | }; |
||
145 | |||
146 | const JE_byte shipCombosB[21] /* [1..21] */ = |
||
147 | {15,16,17,18,19,20,21,22,23,24, 7, 8, 5,25,14, 4, 6, 3, 9, 2,26}; |
||
148 | /*!! SUPER Tyrian !!*/ |
||
149 | const JE_byte superTyrianSpecials[4] /* [1..4] */ = {1,2,4,5}; |
||
150 | |||
151 | const JE_byte shipCombos[14][3] /* [0..12, 1..3] */ = |
||
152 | { |
||
153 | { 5, 4, 7}, /*2nd Player ship*/ |
||
154 | { 1, 2, 0}, /*USP Talon*/ |
||
155 | {14, 4, 0}, /*Super Carrot*/ |
||
156 | { 4, 5, 0}, /*Gencore Phoenix*/ |
||
157 | { 6, 5, 0}, /*Gencore Maelstrom*/ |
||
158 | { 7, 8, 0}, /*MicroCorp Stalker*/ |
||
159 | { 7, 9, 0}, /*MicroCorp Stalker-B*/ |
||
160 | {10, 3, 5}, /*Prototype Stalker-C*/ |
||
161 | { 5, 8, 9}, /*Stalker*/ |
||
162 | { 1, 3, 0}, /*USP Fang*/ |
||
163 | { 7,16,17}, /*U-Ship*/ |
||
164 | { 2,11,12}, /*1st Player ship*/ |
||
165 | { 3, 8,10}, /*Nort ship*/ |
||
166 | { 0, 0, 0} // Dummy entry added for Stalker 21.126 |
||
167 | }; |
||
168 | |||
169 | /*Street-Fighter Commands*/ |
||
170 | JE_byte SFCurrentCode[2][21]; /* [1..2, 1..21] */ |
||
171 | JE_byte SFExecuted[2]; /* [1..2] */ |
||
172 | |||
173 | /*Special General Data*/ |
||
174 | JE_byte lvlFileNum; |
||
175 | JE_word maxEvent, eventLoc; |
||
176 | /*JE_word maxenemies;*/ |
||
177 | JE_word tempBackMove, explodeMove; /*Speed of background movement*/ |
||
178 | JE_byte levelEnd; |
||
179 | JE_word levelEndFxWait; |
||
180 | JE_shortint levelEndWarp; |
||
181 | JE_boolean endLevel, reallyEndLevel, waitToEndLevel, playerEndLevel, |
||
182 | normalBonusLevelCurrent, bonusLevelCurrent, |
||
183 | smallEnemyAdjust, readyToEndLevel, quitRequested; |
||
184 | |||
185 | JE_byte newPL[10]; /* [0..9] */ /*Eventsys event 75 parameter*/ |
||
186 | JE_word returnLoc; |
||
187 | JE_boolean returnActive; |
||
188 | JE_word galagaShotFreq; |
||
189 | JE_longint galagaLife; |
||
190 | |||
191 | JE_boolean debug = false; /*Debug Mode*/ |
||
192 | Uint32 debugTime, lastDebugTime; |
||
193 | JE_longint debugHistCount; |
||
194 | JE_real debugHist; |
||
195 | JE_word curLoc; /*Current Pixel location of background 1*/ |
||
196 | |||
197 | JE_boolean firstGameOver, gameLoaded, enemyStillExploding; |
||
198 | |||
199 | |||
200 | /* Destruction Ratio */ |
||
201 | JE_word totalEnemy; |
||
202 | JE_word enemyKilled; |
||
203 | |||
204 | /* Shape/Map Data - All in one Segment! */ |
||
205 | struct JE_MegaDataType1 megaData1; |
||
206 | struct JE_MegaDataType2 megaData2; |
||
207 | struct JE_MegaDataType3 megaData3; |
||
208 | |||
209 | /* Secret Level Display */ |
||
210 | JE_byte flash; |
||
211 | JE_shortint flashChange; |
||
212 | JE_byte displayTime; |
||
213 | |||
214 | /* Demo Stuff */ |
||
215 | bool play_demo = false, record_demo = false, stopped_demo = false; |
||
216 | Uint8 demo_num = 0; |
||
217 | FILE *demo_file = NULL; |
||
218 | |||
219 | Uint8 demo_keys, next_demo_keys; |
||
220 | Uint16 demo_keys_wait; |
||
221 | |||
222 | /* Sound Effects Queue */ |
||
223 | JE_byte soundQueue[8]; /* [0..7] */ |
||
224 | |||
225 | /*Level Event Data*/ |
||
226 | JE_boolean enemyContinualDamage; |
||
227 | JE_boolean enemiesActive; |
||
228 | JE_boolean forceEvents; |
||
229 | JE_boolean stopBackgrounds; |
||
230 | JE_byte stopBackgroundNum; |
||
231 | JE_byte damageRate; /*Rate at which a player takes damage*/ |
||
232 | JE_boolean background3x1; /*Background 3 enemies use Background 1 X offset*/ |
||
233 | JE_boolean background3x1b; /*Background 3 enemies moved 8 pixels left*/ |
||
234 | |||
235 | JE_boolean levelTimer; |
||
236 | JE_word levelTimerCountdown; |
||
237 | JE_word levelTimerJumpTo; |
||
238 | JE_boolean randomExplosions; |
||
239 | |||
240 | JE_boolean editShip1, editShip2; |
||
241 | |||
242 | JE_boolean globalFlags[10]; /* [1..10] */ |
||
243 | JE_byte levelSong; |
||
244 | |||
245 | /* DESTRUCT game */ |
||
246 | JE_boolean loadDestruct; |
||
247 | |||
248 | /* MapView Data */ |
||
249 | JE_word mapOrigin, mapPNum; |
||
250 | JE_byte mapPlanet[5], mapSection[5]; /* [1..5] */ |
||
251 | |||
252 | /* Interface Constants */ |
||
253 | JE_boolean moveTyrianLogoUp; |
||
254 | JE_boolean skipStarShowVGA; |
||
255 | |||
256 | /*EnemyData*/ |
||
257 | JE_MultiEnemyType enemy; |
||
258 | JE_EnemyAvailType enemyAvail; /* values: 0: used, 1: free, 2: secret pick-up */ |
||
259 | JE_word enemyOffset; |
||
260 | JE_word enemyOnScreen; |
||
261 | JE_byte enemyShapeTables[6]; /* [1..6] */ |
||
262 | JE_word superEnemy254Jump; |
||
263 | |||
264 | /*EnemyShotData*/ |
||
265 | JE_boolean fireButtonHeld; |
||
266 | JE_boolean enemyShotAvail[ENEMY_SHOT_MAX]; /* [1..Enemyshotmax] */ |
||
267 | EnemyShotType enemyShot[ENEMY_SHOT_MAX]; /* [1..Enemyshotmax] */ |
||
268 | |||
269 | /* Player Shot Data */ |
||
270 | JE_byte zinglonDuration; |
||
271 | JE_byte astralDuration; |
||
272 | JE_word flareDuration; |
||
273 | JE_boolean flareStart; |
||
274 | JE_shortint flareColChg; |
||
275 | JE_byte specialWait; |
||
276 | JE_byte nextSpecialWait; |
||
277 | JE_boolean spraySpecial; |
||
278 | JE_byte doIced; |
||
279 | JE_boolean infiniteShot; |
||
280 | |||
281 | /*PlayerData*/ |
||
282 | JE_boolean allPlayersGone; /*Both players dead and finished exploding*/ |
||
283 | |||
284 | const uint shadowYDist = 10; |
||
285 | |||
286 | JE_real optionSatelliteRotate; |
||
287 | |||
288 | JE_integer optionAttachmentMove; |
||
289 | JE_boolean optionAttachmentLinked, optionAttachmentReturn; |
||
290 | |||
291 | |||
292 | JE_byte chargeWait, chargeLevel, chargeMax, chargeGr, chargeGrWait; |
||
293 | |||
294 | JE_word neat; |
||
295 | |||
296 | |||
297 | /*ExplosionData*/ |
||
298 | explosion_type explosions[MAX_EXPLOSIONS]; /* [1..ExplosionMax] */ |
||
299 | JE_integer explosionFollowAmountX, explosionFollowAmountY; |
||
300 | |||
301 | /*Repeating Explosions*/ |
||
302 | rep_explosion_type rep_explosions[MAX_REPEATING_EXPLOSIONS]; /* [1..20] */ |
||
303 | |||
304 | /*SuperPixels*/ |
||
305 | superpixel_type superpixels[MAX_SUPERPIXELS]; /* [0..MaxSP] */ |
||
306 | unsigned int last_superpixel; |
||
307 | |||
308 | /*Temporary Numbers*/ |
||
309 | JE_byte temp, temp2, temp3; |
||
310 | JE_word tempX, tempY; |
||
311 | JE_word tempW; |
||
312 | |||
313 | JE_boolean doNotSaveBackup; |
||
314 | |||
315 | JE_word x, y; |
||
316 | JE_integer b; |
||
317 | |||
318 | JE_byte **BKwrap1to, **BKwrap2to, **BKwrap3to, |
||
319 | **BKwrap1, **BKwrap2, **BKwrap3; |
||
320 | |||
321 | JE_shortint specialWeaponFilter, specialWeaponFreq; |
||
322 | JE_word specialWeaponWpn; |
||
323 | JE_boolean linkToPlayer; |
||
324 | |||
325 | JE_word shipGr, shipGr2; |
||
326 | Sprite2_array *shipGrPtr, *shipGr2ptr; |
||
327 | |||
328 | void JE_getShipInfo( void ) |
||
329 | { |
||
330 | JE_boolean extraShip, extraShip2; |
||
331 | |||
332 | shipGrPtr = &shapes9; |
||
333 | shipGr2ptr = &shapes9; |
||
334 | |||
335 | powerAdd = powerSys[player[0].items.generator].power; |
||
336 | |||
337 | extraShip = player[0].items.ship > 90; |
||
338 | if (extraShip) |
||
339 | { |
||
340 | JE_byte base = (player[0].items.ship - 91) * 15; |
||
341 | shipGr = JE_SGr(player[0].items.ship - 90, &shipGrPtr); |
||
342 | player[0].armor = extraShips[base + 7]; |
||
343 | } |
||
344 | else |
||
345 | { |
||
346 | shipGr = ships[player[0].items.ship].shipgraphic; |
||
347 | player[0].armor = ships[player[0].items.ship].dmg; |
||
348 | } |
||
349 | |||
350 | extraShip2 = player[1].items.ship > 90; |
||
351 | if (extraShip2) |
||
352 | { |
||
353 | JE_byte base2 = (player[1].items.ship - 91) * 15; |
||
354 | shipGr2 = JE_SGr(player[1].items.ship - 90, &shipGr2ptr); |
||
355 | player[1].armor = extraShips[base2 + 7]; /* bug? */ |
||
356 | } |
||
357 | else |
||
358 | { |
||
359 | shipGr2 = 0; |
||
360 | player[1].armor = 10; |
||
361 | } |
||
362 | |||
363 | for (uint i = 0; i < COUNTOF(player); ++i) |
||
364 | { |
||
365 | player[i].initial_armor = player[i].armor; |
||
366 | |||
367 | |||
368 | uint temp = ((i == 0 && extraShip) || |
||
369 | (i == 1 && extraShip2)) ? 2 : ships[player[i].items.ship].ani; |
||
370 | |||
371 | if (temp == 0) |
||
372 | { |
||
373 | player[i].shot_hit_area_x = 12; |
||
374 | player[i].shot_hit_area_y = 10; |
||
375 | } |
||
376 | else |
||
377 | { |
||
378 | player[i].shot_hit_area_x = 11; |
||
379 | player[i].shot_hit_area_y = 14; |
||
380 | } |
||
381 | } |
||
382 | } |
||
383 | |||
384 | JE_word JE_SGr( JE_word ship, Sprite2_array **ptr ) |
||
385 | { |
||
386 | const JE_word GR[15] /* [1..15] */ = {233, 157, 195, 271, 81, 0, 119, 5, 43, 81, 119, 157, 195, 233, 271}; |
||
387 | |||
388 | JE_word tempW = extraShips[(ship - 1) * 15]; |
||
389 | if (tempW > 7) |
||
390 | *ptr = extraShapes; |
||
391 | |||
392 | return GR[tempW-1]; |
||
393 | } |
||
394 | |||
395 | void JE_drawOptions( void ) |
||
396 | { |
||
397 | SDL_Surface *temp_surface = VGAScreen; |
||
398 | VGAScreen = VGAScreenSeg; |
||
399 | |||
400 | Player *this_player = &player[twoPlayerMode ? 1 : 0]; |
||
401 | |||
402 | for (uint i = 0; i < COUNTOF(this_player->sidekick); ++i) |
||
403 | { |
||
404 | JE_OptionType *this_option = &options[this_player->items.sidekick[i]]; |
||
405 | |||
406 | this_player->sidekick[i].ammo = |
||
407 | this_player->sidekick[i].ammo_max = this_option->ammo; |
||
408 | |||
409 | this_player->sidekick[i].ammo_refill_ticks = |
||
410 | this_player->sidekick[i].ammo_refill_ticks_max = (105 - this_player->sidekick[i].ammo) * 4; |
||
411 | |||
412 | this_player->sidekick[i].style = this_option->tr; |
||
413 | |||
414 | this_player->sidekick[i].animation_enabled = (this_option->option == 1); |
||
415 | this_player->sidekick[i].animation_frame = 0; |
||
416 | |||
417 | this_player->sidekick[i].charge = 0; |
||
418 | this_player->sidekick[i].charge_ticks = 20; |
||
419 | |||
420 | |||
421 | // draw initial sidekick HUD |
||
422 | const int y = hud_sidekick_y[twoPlayerMode ? 1 : 0][i]; |
||
423 | |||
424 | fill_rectangle_xy(VGAScreenSeg, 284, y, 284 + 28, y + 15, 0); |
||
425 | if (this_option->icongr > 0) |
||
426 | blit_sprite(VGAScreenSeg, 284, y, OPTION_SHAPES, this_option->icongr - 1); // sidekick HUD icon |
||
427 | draw_segmented_gauge(VGAScreenSeg, 284, y + 13, 112, 2, 2, MAX(1, this_player->sidekick[i].ammo_max / 10), this_player->sidekick[i].ammo); |
||
428 | } |
||
429 | |||
430 | VGAScreen = temp_surface; |
||
431 | |||
432 | JE_drawOptionLevel(); |
||
433 | } |
||
434 | |||
435 | void JE_drawOptionLevel( void ) |
||
436 | { |
||
437 | if (twoPlayerMode) |
||
438 | { |
||
439 | for (temp = 1; temp <= 3; temp++) |
||
440 | { |
||
441 | fill_rectangle_xy(VGAScreenSeg, 268, 127 + (temp - 1) * 6, 269, 127 + 3 + (temp - 1) * 6, 193 + ((player[1].items.sidekick_level - 100) == temp) * 11); |
||
442 | } |
||
443 | } |
||
444 | } |
||
445 | |||
446 | void JE_tyrianHalt( JE_byte code ) |
||
447 | { |
||
448 | deinit_audio(); |
||
449 | deinit_video(); |
||
450 | deinit_joysticks(); |
||
451 | |||
452 | /* TODO: NETWORK */ |
||
453 | |||
454 | free_main_shape_tables(); |
||
455 | |||
456 | free_sprite2s(&shapes6); |
||
457 | |||
458 | for (int i = 0; i < SAMPLE_COUNT; i++) |
||
459 | { |
||
460 | free(digiFx[i]); |
||
461 | } |
||
462 | |||
463 | if (code != 9) |
||
464 | { |
||
465 | /* |
||
466 | TODO? |
||
467 | JE_drawANSI("exitmsg.bin"); |
||
468 | JE_gotoXY(1,22);*/ |
||
469 | |||
470 | JE_saveConfiguration(); |
||
471 | } |
||
472 | |||
473 | /* endkeyboard; */ |
||
474 | |||
475 | if (code == 9) |
||
476 | { |
||
477 | /* OutputString('call=file0002.EXE' + #0'); TODO? */ |
||
478 | } |
||
479 | |||
480 | if (code == 5) |
||
481 | { |
||
482 | code = 0; |
||
483 | } |
||
484 | |||
485 | if (trentWin) |
||
486 | { |
||
487 | printf("\n" |
||
488 | "\n" |
||
489 | "\n" |
||
490 | "\n" |
||
491 | "Sleep well, Trent, you deserve the rest.\n" |
||
492 | "You now have permission to borrow my ship on your next mission.\n" |
||
493 | "\n" |
||
494 | "Also, you might want to try out the YESXMAS parameter.\n" |
||
495 | " Type: File0001 YESXMAS\n" |
||
496 | "\n" |
||
497 | "You'll need the 2.1 patch, though!\n" |
||
498 | "\n"); |
||
499 | } |
||
500 | |||
501 | SDL_Quit(); |
||
502 | exit(code); |
||
503 | } |
||
504 | |||
505 | void JE_specialComplete( JE_byte playerNum, JE_byte specialType ) |
||
506 | { |
||
507 | nextSpecialWait = 0; |
||
508 | switch (special[specialType].stype) |
||
509 | { |
||
510 | /*Weapon*/ |
||
511 | case 1: |
||
512 | if (playerNum == 1) |
||
513 | b = player_shot_create(0, SHOT_SPECIAL2, player[0].x, player[0].y, mouseX, mouseY, special[specialType].wpn, playerNum); |
||
514 | else |
||
515 | b = player_shot_create(0, SHOT_SPECIAL2, player[1].x, player[1].y, mouseX, mouseY, special[specialType].wpn, playerNum); |
||
516 | |||
517 | shotRepeat[SHOT_SPECIAL] = shotRepeat[SHOT_SPECIAL2]; |
||
518 | break; |
||
519 | /*Repulsor*/ |
||
520 | case 2: |
||
521 | for (temp = 0; temp < ENEMY_SHOT_MAX; temp++) |
||
522 | { |
||
523 | if (!enemyShotAvail[temp]) |
||
524 | { |
||
525 | if (player[0].x > enemyShot[temp].sx) |
||
526 | enemyShot[temp].sxm--; |
||
527 | else if (player[0].x < enemyShot[temp].sx) |
||
528 | enemyShot[temp].sxm++; |
||
529 | |||
530 | if (player[0].y > enemyShot[temp].sy) |
||
531 | enemyShot[temp].sym--; |
||
532 | else if (player[0].y < enemyShot[temp].sy) |
||
533 | enemyShot[temp].sym++; |
||
534 | } |
||
535 | } |
||
536 | break; |
||
537 | /*Zinglon Blast*/ |
||
538 | case 3: |
||
539 | zinglonDuration = 50; |
||
540 | shotRepeat[SHOT_SPECIAL] = 100; |
||
541 | soundQueue[7] = S_SOUL_OF_ZINGLON; |
||
542 | break; |
||
543 | /*Attractor*/ |
||
544 | case 4: |
||
545 | for (temp = 0; temp < 100; temp++) |
||
546 | { |
||
547 | if (enemyAvail[temp] != 1 && enemy[temp].scoreitem |
||
548 | && enemy[temp].evalue != 0) |
||
549 | { |
||
550 | if (player[0].x > enemy[temp].ex) |
||
551 | enemy[temp].exc++; |
||
552 | else if (player[0].x < enemy[temp].ex) |
||
553 | enemy[temp].exc--; |
||
554 | |||
555 | if (player[0].y > enemy[temp].ey) |
||
556 | enemy[temp].eyc++; |
||
557 | else if (player[0].y < enemy[temp].ey) |
||
558 | enemy[temp].eyc--; |
||
559 | } |
||
560 | } |
||
561 | break; |
||
562 | /*Flare*/ |
||
563 | case 5: |
||
564 | case 6: |
||
565 | case 7: |
||
566 | case 8: |
||
567 | case 9: |
||
568 | case 10: |
||
569 | case 11: |
||
570 | case 16: |
||
571 | if (flareDuration == 0) |
||
572 | flareStart = true; |
||
573 | |||
574 | specialWeaponWpn = special[specialType].wpn; |
||
575 | linkToPlayer = false; |
||
576 | spraySpecial = false; |
||
577 | switch (special[specialType].stype) |
||
578 | { |
||
579 | case 5: |
||
580 | specialWeaponFilter = 7; |
||
581 | specialWeaponFreq = 2; |
||
582 | flareDuration = 50; |
||
583 | break; |
||
584 | case 6: |
||
585 | specialWeaponFilter = 1; |
||
586 | specialWeaponFreq = 7; |
||
587 | flareDuration = 200 + 25 * player[0].items.weapon[FRONT_WEAPON].power; |
||
588 | break; |
||
589 | case 7: |
||
590 | specialWeaponFilter = 3; |
||
591 | specialWeaponFreq = 3; |
||
592 | flareDuration = 50 + 10 * player[0].items.weapon[FRONT_WEAPON].power; |
||
593 | zinglonDuration = 50; |
||
594 | shotRepeat[SHOT_SPECIAL] = 100; |
||
595 | soundQueue[7] = S_SOUL_OF_ZINGLON; |
||
596 | break; |
||
597 | case 8: |
||
598 | specialWeaponFilter = -99; |
||
599 | specialWeaponFreq = 7; |
||
600 | flareDuration = 10 + player[0].items.weapon[FRONT_WEAPON].power; |
||
601 | break; |
||
602 | case 9: |
||
603 | specialWeaponFilter = -99; |
||
604 | specialWeaponFreq = 8; |
||
605 | flareDuration = 8 + 2 * player[0].items.weapon[FRONT_WEAPON].power; |
||
606 | linkToPlayer = true; |
||
607 | nextSpecialWait = special[specialType].pwr; |
||
608 | break; |
||
609 | case 10: |
||
610 | specialWeaponFilter = -99; |
||
611 | specialWeaponFreq = 8; |
||
612 | flareDuration = 14 + 4 * player[0].items.weapon[FRONT_WEAPON].power; |
||
613 | linkToPlayer = true; |
||
614 | break; |
||
615 | case 11: |
||
616 | specialWeaponFilter = -99; |
||
617 | specialWeaponFreq = special[specialType].pwr; |
||
618 | flareDuration = 10 + 10 * player[0].items.weapon[FRONT_WEAPON].power; |
||
619 | astralDuration = 20 + 10 * player[0].items.weapon[FRONT_WEAPON].power; |
||
620 | break; |
||
621 | case 16: |
||
622 | specialWeaponFilter = -99; |
||
623 | specialWeaponFreq = 8; |
||
624 | flareDuration = temp2 * 16 + 8; |
||
625 | linkToPlayer = true; |
||
626 | spraySpecial = true; |
||
627 | break; |
||
628 | } |
||
629 | break; |
||
630 | case 12: |
||
631 | player[playerNum-1].invulnerable_ticks = temp2 * 10; |
||
632 | |||
633 | if (superArcadeMode > 0 && superArcadeMode <= SA) |
||
634 | { |
||
635 | shotRepeat[SHOT_SPECIAL] = 250; |
||
636 | b = player_shot_create(0, SHOT_SPECIAL2, player[0].x, player[0].y, mouseX, mouseY, 707, 1); |
||
637 | player[0].invulnerable_ticks = 100; |
||
638 | } |
||
639 | break; |
||
640 | case 13: |
||
641 | player[0].armor += temp2 / 4 + 1; |
||
642 | |||
643 | soundQueue[3] = S_POWERUP; |
||
644 | break; |
||
645 | case 14: |
||
646 | player[1].armor += temp2 / 4 + 1; |
||
647 | |||
648 | soundQueue[3] = S_POWERUP; |
||
649 | break; |
||
650 | |||
651 | case 17: // spawn left or right sidekick |
||
652 | soundQueue[3] = S_POWERUP; |
||
653 | |||
654 | if (player[0].items.sidekick[LEFT_SIDEKICK] == special[specialType].wpn) |
||
655 | { |
||
656 | player[0].items.sidekick[RIGHT_SIDEKICK] = special[specialType].wpn; |
||
657 | shotMultiPos[RIGHT_SIDEKICK] = 0; |
||
658 | } |
||
659 | else |
||
660 | { |
||
661 | player[0].items.sidekick[LEFT_SIDEKICK] = special[specialType].wpn; |
||
662 | shotMultiPos[LEFT_SIDEKICK] = 0; |
||
663 | } |
||
664 | |||
665 | JE_drawOptions(); |
||
666 | break; |
||
667 | |||
668 | case 18: // spawn right sidekick |
||
669 | player[0].items.sidekick[RIGHT_SIDEKICK] = special[specialType].wpn; |
||
670 | |||
671 | JE_drawOptions(); |
||
672 | |||
673 | soundQueue[4] = S_POWERUP; |
||
674 | |||
675 | shotMultiPos[RIGHT_SIDEKICK] = 0; |
||
676 | break; |
||
677 | } |
||
678 | } |
||
679 | |||
680 | void JE_doSpecialShot( JE_byte playerNum, uint *armor, uint *shield ) |
||
681 | { |
||
682 | if (player[0].items.special > 0) |
||
683 | { |
||
684 | if (shotRepeat[SHOT_SPECIAL] == 0 && specialWait == 0 && flareDuration < 2 && zinglonDuration < 2) |
||
685 | blit_sprite2(VGAScreen, 47, 4, shapes9, 94); |
||
686 | else |
||
687 | blit_sprite2(VGAScreen, 47, 4, shapes9, 93); |
||
688 | } |
||
689 | |||
690 | if (shotRepeat[SHOT_SPECIAL] > 0) |
||
691 | { |
||
692 | --shotRepeat[SHOT_SPECIAL]; |
||
693 | } |
||
694 | if (specialWait > 0) |
||
695 | { |
||
696 | specialWait--; |
||
697 | } |
||
698 | temp = SFExecuted[playerNum-1]; |
||
699 | if (temp > 0 && shotRepeat[SHOT_SPECIAL] == 0 && flareDuration == 0) |
||
700 | { |
||
701 | temp2 = special[temp].pwr; |
||
702 | |||
703 | bool can_afford = true; |
||
704 | |||
705 | if (temp2 > 0) |
||
706 | { |
||
707 | if (temp2 < 98) // costs some shield |
||
708 | { |
||
709 | if (*shield >= temp2) |
||
710 | *shield -= temp2; |
||
711 | else |
||
712 | can_afford = false; |
||
713 | } |
||
714 | else if (temp2 == 98) // costs all shield |
||
715 | { |
||
716 | if (*shield < 4) |
||
717 | can_afford = false; |
||
718 | temp2 = *shield; |
||
719 | *shield = 0; |
||
720 | } |
||
721 | else if (temp2 == 99) // costs half shield |
||
722 | { |
||
723 | temp2 = *shield / 2; |
||
724 | *shield = temp2; |
||
725 | } |
||
726 | else // costs some armor |
||
727 | { |
||
728 | temp2 -= 100; |
||
729 | if (*armor > temp2) |
||
730 | *armor -= temp2; |
||
731 | else |
||
732 | can_afford = false; |
||
733 | } |
||
734 | } |
||
735 | |||
736 | shotMultiPos[SHOT_SPECIAL] = 0; |
||
737 | shotMultiPos[SHOT_SPECIAL2] = 0; |
||
738 | |||
739 | if (can_afford) |
||
740 | JE_specialComplete(playerNum, temp); |
||
741 | |||
742 | SFExecuted[playerNum-1] = 0; |
||
743 | |||
744 | JE_wipeShieldArmorBars(); |
||
745 | VGAScreen = VGAScreenSeg; /* side-effect of game_screen */ |
||
746 | JE_drawShield(); |
||
747 | JE_drawArmor(); |
||
748 | VGAScreen = game_screen; /* side-effect of game_screen */ |
||
749 | } |
||
750 | |||
751 | if (playerNum == 1 && player[0].items.special > 0) |
||
752 | { /*Main Begin*/ |
||
753 | |||
754 | if (superArcadeMode > 0 && (button[2-1] || button[3-1])) |
||
755 | { |
||
756 | fireButtonHeld = false; |
||
757 | } |
||
758 | if (!button[1-1] && !(superArcadeMode != SA_NONE && (button[2-1] || button[3-1]))) |
||
759 | { |
||
760 | fireButtonHeld = false; |
||
761 | } |
||
762 | else if (shotRepeat[SHOT_SPECIAL] == 0 && !fireButtonHeld && !(flareDuration > 0) && specialWait == 0) |
||
763 | { |
||
764 | fireButtonHeld = true; |
||
765 | JE_specialComplete(playerNum, player[0].items.special); |
||
766 | } |
||
767 | |||
768 | } /*Main End*/ |
||
769 | |||
770 | if (astralDuration > 0) |
||
771 | astralDuration--; |
||
772 | |||
773 | shotAvail[MAX_PWEAPON-1] = 0; |
||
774 | if (flareDuration > 1) |
||
775 | { |
||
776 | if (specialWeaponFilter != -99) |
||
777 | { |
||
778 | if (levelFilter == -99 && levelBrightness == -99) |
||
779 | { |
||
780 | filterActive = false; |
||
781 | } |
||
782 | if (!filterActive) |
||
783 | { |
||
784 | levelFilter = specialWeaponFilter; |
||
785 | if (levelFilter == 7) |
||
786 | { |
||
787 | levelBrightness = 0; |
||
788 | } |
||
789 | filterActive = true; |
||
790 | } |
||
791 | |||
792 | if (mt_rand() % 2 == 0) |
||
793 | flareColChg = -1; |
||
794 | else |
||
795 | flareColChg = 1; |
||
796 | |||
797 | if (levelFilter == 7) |
||
798 | { |
||
799 | if (levelBrightness < -6) |
||
800 | { |
||
801 | flareColChg = 1; |
||
802 | } |
||
803 | if (levelBrightness > 6) |
||
804 | { |
||
805 | flareColChg = -1; |
||
806 | } |
||
807 | levelBrightness += flareColChg; |
||
808 | } |
||
809 | } |
||
810 | |||
811 | if ((signed)(mt_rand() % 6) < specialWeaponFreq) |
||
812 | { |
||
813 | b = MAX_PWEAPON; |
||
814 | |||
815 | if (linkToPlayer) |
||
816 | { |
||
817 | if (shotRepeat[SHOT_SPECIAL] == 0) |
||
818 | { |
||
819 | b = player_shot_create(0, SHOT_SPECIAL, player[0].x, player[0].y, mouseX, mouseY, specialWeaponWpn, playerNum); |
||
820 | } |
||
821 | } |
||
822 | else |
||
823 | { |
||
824 | b = player_shot_create(0, SHOT_SPECIAL, mt_rand() % 280, mt_rand() % 180, mouseX, mouseY, specialWeaponWpn, playerNum); |
||
825 | } |
||
826 | |||
827 | if (spraySpecial && b != MAX_PWEAPON) |
||
828 | { |
||
829 | playerShotData[b].shotXM = (mt_rand() % 5) - 2; |
||
830 | playerShotData[b].shotYM = (mt_rand() % 5) - 2; |
||
831 | if (playerShotData[b].shotYM == 0) |
||
832 | { |
||
833 | playerShotData[b].shotYM++; |
||
834 | } |
||
835 | } |
||
836 | } |
||
837 | |||
838 | flareDuration--; |
||
839 | if (flareDuration == 1) |
||
840 | { |
||
841 | specialWait = nextSpecialWait; |
||
842 | } |
||
843 | } |
||
844 | else if (flareStart) |
||
845 | { |
||
846 | flareStart = false; |
||
847 | shotRepeat[SHOT_SPECIAL] = linkToPlayer ? 15 : 200; |
||
848 | flareDuration = 0; |
||
849 | if (levelFilter == specialWeaponFilter) |
||
850 | { |
||
851 | levelFilter = -99; |
||
852 | levelBrightness = -99; |
||
853 | filterActive = false; |
||
854 | } |
||
855 | } |
||
856 | |||
857 | if (zinglonDuration > 1) |
||
858 | { |
||
859 | temp = 25 - abs(zinglonDuration - 25); |
||
860 | |||
861 | JE_barBright(VGAScreen, player[0].x + 7 - temp, 0, player[0].x + 7 + temp, 184); |
||
862 | JE_barBright(VGAScreen, player[0].x + 7 - temp - 2, 0, player[0].x + 7 + temp + 2, 184); |
||
863 | |||
864 | zinglonDuration--; |
||
865 | if (zinglonDuration % 5 == 0) |
||
866 | { |
||
867 | shotAvail[MAX_PWEAPON-1] = 1; |
||
868 | } |
||
869 | } |
||
870 | } |
||
871 | |||
872 | void JE_setupExplosion( signed int x, signed int y, signed int delta_y, unsigned int type, bool fixed_position, bool follow_player ) |
||
873 | { |
||
874 | const struct { |
||
875 | JE_word sprite; |
||
876 | JE_byte ttl; |
||
877 | } explosion_data[53] /* [1..53] */ = { |
||
878 | { 144, 7 }, |
||
879 | { 120, 12 }, |
||
880 | { 190, 12 }, |
||
881 | { 209, 12 }, |
||
882 | { 152, 12 }, |
||
883 | { 171, 12 }, |
||
884 | { 133, 7 }, /*White Smoke*/ |
||
885 | { 1, 12 }, |
||
886 | { 20, 12 }, |
||
887 | { 39, 12 }, |
||
888 | { 58, 12 }, |
||
889 | { 110, 3 }, |
||
890 | { 76, 7 }, |
||
891 | { 91, 3 }, |
||
892 | /*15*/ { 227, 3 }, |
||
893 | { 230, 3 }, |
||
894 | { 233, 3 }, |
||
895 | { 252, 3 }, |
||
896 | { 246, 3 }, |
||
897 | /*20*/ { 249, 3 }, |
||
898 | { 265, 3 }, |
||
899 | { 268, 3 }, |
||
900 | { 271, 3 }, |
||
901 | { 236, 3 }, |
||
902 | /*25*/ { 239, 3 }, |
||
903 | { 242, 3 }, |
||
904 | { 261, 3 }, |
||
905 | { 274, 3 }, |
||
906 | { 277, 3 }, |
||
907 | /*30*/ { 280, 3 }, |
||
908 | { 299, 3 }, |
||
909 | { 284, 3 }, |
||
910 | { 287, 3 }, |
||
911 | { 290, 3 }, |
||
912 | /*35*/ { 293, 3 }, |
||
913 | { 165, 8 }, /*Coin Values*/ |
||
914 | { 184, 8 }, |
||
915 | { 203, 8 }, |
||
916 | { 222, 8 }, |
||
917 | { 168, 8 }, |
||
918 | { 187, 8 }, |
||
919 | { 206, 8 }, |
||
920 | { 225, 10 }, |
||
921 | { 169, 10 }, |
||
922 | { 188, 10 }, |
||
923 | { 207, 20 }, |
||
924 | { 226, 14 }, |
||
925 | { 170, 14 }, |
||
926 | { 189, 14 }, |
||
927 | { 208, 14 }, |
||
928 | { 246, 14 }, |
||
929 | { 227, 14 }, |
||
930 | { 265, 14 } |
||
931 | }; |
||
932 | |||
933 | if (y > -16 && y < 190) |
||
934 | { |
||
935 | for (int i = 0; i < MAX_EXPLOSIONS; i++) |
||
936 | { |
||
937 | if (explosions[i].ttl == 0) |
||
938 | { |
||
939 | explosions[i].x = x; |
||
940 | explosions[i].y = y; |
||
941 | if (type == 6) |
||
942 | { |
||
943 | explosions[i].y += 12; |
||
944 | explosions[i].x += 2; |
||
945 | } else if (type == 98) |
||
946 | { |
||
947 | type = 6; |
||
948 | } |
||
949 | explosions[i].sprite = explosion_data[type].sprite; |
||
950 | explosions[i].ttl = explosion_data[type].ttl; |
||
951 | explosions[i].follow_player = follow_player; |
||
952 | explosions[i].fixed_position = fixed_position; |
||
953 | explosions[i].delta_x = 0; |
||
954 | explosions[i].delta_y = delta_y; |
||
955 | break; |
||
956 | } |
||
957 | } |
||
958 | } |
||
959 | } |
||
960 | |||
961 | void JE_setupExplosionLarge( JE_boolean enemyGround, JE_byte exploNum, JE_integer x, JE_integer y ) |
||
962 | { |
||
963 | if (y >= 0) |
||
964 | { |
||
965 | if (enemyGround) |
||
966 | { |
||
967 | JE_setupExplosion(x - 6, y - 14, 0, 2, false, false); |
||
968 | JE_setupExplosion(x + 6, y - 14, 0, 4, false, false); |
||
969 | JE_setupExplosion(x - 6, y, 0, 3, false, false); |
||
970 | JE_setupExplosion(x + 6, y, 0, 5, false, false); |
||
971 | } else { |
||
972 | JE_setupExplosion(x - 6, y - 14, 0, 7, false, false); |
||
973 | JE_setupExplosion(x + 6, y - 14, 0, 9, false, false); |
||
974 | JE_setupExplosion(x - 6, y, 0, 8, false, false); |
||
975 | JE_setupExplosion(x + 6, y, 0, 10, false, false); |
||
976 | } |
||
977 | |||
978 | bool big; |
||
979 | |||
980 | if (exploNum > 10) |
||
981 | { |
||
982 | exploNum -= 10; |
||
983 | big = true; |
||
984 | } |
||
985 | else |
||
986 | { |
||
987 | big = false; |
||
988 | } |
||
989 | |||
990 | if (exploNum) |
||
991 | { |
||
992 | for (int i = 0; i < MAX_REPEATING_EXPLOSIONS; i++) |
||
993 | { |
||
994 | if (rep_explosions[i].ttl == 0) |
||
995 | { |
||
996 | rep_explosions[i].ttl = exploNum; |
||
997 | rep_explosions[i].delay = 2; |
||
998 | rep_explosions[i].x = x; |
||
999 | rep_explosions[i].y = y; |
||
1000 | rep_explosions[i].big = big; |
||
1001 | break; |
||
1002 | } |
||
1003 | } |
||
1004 | } |
||
1005 | } |
||
1006 | } |
||
1007 | |||
1008 | void JE_wipeShieldArmorBars( void ) |
||
1009 | { |
||
1010 | if (!twoPlayerMode || galagaMode) |
||
1011 | { |
||
1012 | fill_rectangle_xy(VGAScreenSeg, 270, 137, 278, 194 - player[0].shield * 2, 0); |
||
1013 | } |
||
1014 | else |
||
1015 | { |
||
1016 | fill_rectangle_xy(VGAScreenSeg, 270, 60 - 44, 278, 60, 0); |
||
1017 | fill_rectangle_xy(VGAScreenSeg, 270, 194 - 44, 278, 194, 0); |
||
1018 | } |
||
1019 | if (!twoPlayerMode || galagaMode) |
||
1020 | { |
||
1021 | fill_rectangle_xy(VGAScreenSeg, 307, 137, 315, 194 - player[0].armor * 2, 0); |
||
1022 | } |
||
1023 | else |
||
1024 | { |
||
1025 | fill_rectangle_xy(VGAScreenSeg, 307, 60 - 44, 315, 60, 0); |
||
1026 | fill_rectangle_xy(VGAScreenSeg, 307, 194 - 44, 315, 194, 0); |
||
1027 | } |
||
1028 | } |
||
1029 | |||
1030 | JE_byte JE_playerDamage( JE_byte temp, |
||
1031 | Player *this_player ) |
||
1032 | { |
||
1033 | int playerDamage = 0; |
||
1034 | soundQueue[7] = S_SHIELD_HIT; |
||
1035 | |||
1036 | /* Player Damage Routines */ |
||
1037 | if (this_player->shield < temp) |
||
1038 | { |
||
1039 | playerDamage = temp; |
||
1040 | temp -= this_player->shield; |
||
1041 | this_player->shield = 0; |
||
1042 | |||
1043 | if (temp > 0) |
||
1044 | { |
||
1045 | /*Through Shields - Now Armor */ |
||
1046 | |||
1047 | if (this_player->armor < temp) |
||
1048 | { |
||
1049 | temp -= this_player->armor; |
||
1050 | this_player->armor = 0; |
||
1051 | |||
1052 | if (this_player->is_alive && !youAreCheating) |
||
1053 | { |
||
1054 | levelTimer = false; |
||
1055 | this_player->is_alive = false; |
||
1056 | this_player->exploding_ticks = 60; |
||
1057 | levelEnd = 40; |
||
1058 | tempVolume = tyrMusicVolume; |
||
1059 | soundQueue[1] = S_EXPLOSION_22; |
||
1060 | } |
||
1061 | } |
||
1062 | else |
||
1063 | { |
||
1064 | this_player->armor -= temp; |
||
1065 | soundQueue[7] = S_HULL_HIT; |
||
1066 | } |
||
1067 | } |
||
1068 | } |
||
1069 | else |
||
1070 | { |
||
1071 | this_player->shield -= temp; |
||
1072 | |||
1073 | JE_setupExplosion(this_player->x - 17, this_player->y - 12, 0, 14, false, !twoPlayerMode); |
||
1074 | JE_setupExplosion(this_player->x - 5 , this_player->y - 12, 0, 15, false, !twoPlayerMode); |
||
1075 | JE_setupExplosion(this_player->x + 7 , this_player->y - 12, 0, 16, false, !twoPlayerMode); |
||
1076 | JE_setupExplosion(this_player->x + 19, this_player->y - 12, 0, 17, false, !twoPlayerMode); |
||
1077 | |||
1078 | JE_setupExplosion(this_player->x - 17, this_player->y + 2, 0, 18, false, !twoPlayerMode); |
||
1079 | JE_setupExplosion(this_player->x + 19, this_player->y + 2, 0, 19, false, !twoPlayerMode); |
||
1080 | |||
1081 | JE_setupExplosion(this_player->x - 17, this_player->y + 16, 0, 20, false, !twoPlayerMode); |
||
1082 | JE_setupExplosion(this_player->x - 5 , this_player->y + 16, 0, 21, false, !twoPlayerMode); |
||
1083 | JE_setupExplosion(this_player->x + 7 , this_player->y + 16, 0, 22, false, !twoPlayerMode); |
||
1084 | } |
||
1085 | |||
1086 | JE_wipeShieldArmorBars(); |
||
1087 | VGAScreen = VGAScreenSeg; /* side-effect of game_screen */ |
||
1088 | JE_drawShield(); |
||
1089 | JE_drawArmor(); |
||
1090 | VGAScreen = game_screen; /* side-effect of game_screen */ |
||
1091 | |||
1092 | return playerDamage; |
||
1093 | } |
||
1094 | |||
1095 | JE_word JE_portConfigs( void ) |
||
1096 | { |
||
1097 | const uint player_index = twoPlayerMode ? 1 : 0; |
||
1098 | return tempW = weaponPort[player[player_index].items.weapon[REAR_WEAPON].id].opnum; |
||
1099 | } |
||
1100 | |||
1101 | void JE_drawShield( void ) |
||
1102 | { |
||
1103 | if (twoPlayerMode && !galagaMode) |
||
1104 | { |
||
1105 | for (uint i = 0; i < COUNTOF(player); ++i) |
||
1106 | JE_dBar3(VGAScreen, 270, 60 + 134 * i, roundf(player[i].shield * 0.8f), 144); |
||
1107 | } |
||
1108 | else |
||
1109 | { |
||
1110 | JE_dBar3(VGAScreen, 270, 194, player[0].shield, 144); |
||
1111 | if (player[0].shield != player[0].shield_max) |
||
1112 | { |
||
1113 | const uint y = 193 - (player[0].shield_max * 2); |
||
1114 | JE_rectangle(VGAScreen, 270, y, 278, y, 68); /* |
||
1115 | } |
||
1116 | } |
||
1117 | } |
||
1118 | |||
1119 | void JE_drawArmor( void ) |
||
1120 | { |
||
1121 | for (uint i = 0; i < COUNTOF(player); ++i) |
||
1122 | if (player[i].armor > 28) |
||
1123 | player[i].armor = 28; |
||
1124 | |||
1125 | if (twoPlayerMode && !galagaMode) |
||
1126 | { |
||
1127 | for (uint i = 0; i < COUNTOF(player); ++i) |
||
1128 | JE_dBar3(VGAScreen, 307, 60 + 134 * i, roundf(player[i].armor * 0.8f), 224); |
||
1129 | } |
||
1130 | else |
||
1131 | { |
||
1132 | JE_dBar3(VGAScreen, 307, 194, player[0].armor, 224); |
||
1133 | } |
||
1134 | } |
||
1135 | |||
1136 | void JE_doSP( JE_word x, JE_word y, JE_word num, JE_byte explowidth, JE_byte color ) /* superpixels */ |
||
1137 | { |
||
1138 | for (temp = 0; temp < num; temp++) |
||
1139 | { |
||
1140 | JE_real tempr = mt_rand_lt1() * (2 * M_PI); |
||
1141 | signed int tempy = roundf(cosf(tempr) * mt_rand_1() * explowidth); |
||
1142 | signed int tempx = roundf(sinf(tempr) * mt_rand_1() * explowidth); |
||
1143 | |||
1144 | if (++last_superpixel >= MAX_SUPERPIXELS) |
||
1145 | last_superpixel = 0; |
||
1146 | superpixels[last_superpixel].x = tempx + x; |
||
1147 | superpixels[last_superpixel].y = tempy + y; |
||
1148 | superpixels[last_superpixel].delta_x = tempx; |
||
1149 | superpixels[last_superpixel].delta_y = tempy + 1; |
||
1150 | superpixels[last_superpixel].color = color; |
||
1151 | superpixels[last_superpixel].z = 15; |
||
1152 | } |
||
1153 | } |
||
1154 | |||
1155 | void JE_drawSP( void ) |
||
1156 | { |
||
1157 | for (int i = MAX_SUPERPIXELS; i--; ) |
||
1158 | { |
||
1159 | if (superpixels[i].z) |
||
1160 | { |
||
1161 | superpixels[i].x += superpixels[i].delta_x; |
||
1162 | superpixels[i].y += superpixels[i].delta_y; |
||
1163 | |||
1164 | if (superpixels[i].x < (unsigned)VGAScreen->w && superpixels[i].y < (unsigned)VGAScreen->h) |
||
1165 | { |
||
1166 | Uint8 *s = (Uint8 *)VGAScreen->pixels; /* screen pointer, 8-bit specific */ |
||
1167 | s += superpixels[i].y * VGAScreen->pitch; |
||
1168 | s += superpixels[i].x; |
||
1169 | |||
1170 | *s = (((*s & 0x0f) + superpixels[i].z) >> 1) + superpixels[i].color; |
||
1171 | if (superpixels[i].x > 0) |
||
1172 | *(s - 1) = (((*(s - 1) & 0x0f) + (superpixels[i].z >> 1)) >> 1) + superpixels[i].color; |
||
1173 | if (superpixels[i].x < VGAScreen->w - 1u) |
||
1174 | *(s + 1) = (((*(s + 1) & 0x0f) + (superpixels[i].z >> 1)) >> 1) + superpixels[i].color; |
||
1175 | if (superpixels[i].y > 0) |
||
1176 | *(s - VGAScreen->pitch) = (((*(s - VGAScreen->pitch) & 0x0f) + (superpixels[i].z >> 1)) >> 1) + superpixels[i].color; |
||
1177 | if (superpixels[i].y < VGAScreen->h - 1u) |
||
1178 | *(s + VGAScreen->pitch) = (((*(s + VGAScreen->pitch) & 0x0f) + (superpixels[i].z >> 1)) >> 1) + superpixels[i].color; |
||
1179 | } |
||
1180 | |||
1181 | superpixels[i].z--; |
||
1182 | } |
||
1183 | } |
||
1184 | }>>>>>>>>>>>>>>>>>>>=>>>>>>>>=>>> |
||
1185 |