~ubuntu-branches/debian/stretch/opentyrian/stretch

« back to all changes in this revision

Viewing changes to src/tyrian2.c

  • Committer: Package Import Robot
  • Author(s): Etienne Millon
  • Date: 2015-03-31 08:48:54 UTC
  • Revision ID: package-import@ubuntu.com-20150331084854-f5a4uoz7uv3vopk6
Tags: upstream-2.1.20130907+dfsg
ImportĀ upstreamĀ versionĀ 2.1.20130907+dfsg

Show diffs side-by-side

added added

removed removed

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