~ubuntu-branches/ubuntu/trusty/meritous/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/data_in_share.patch/src/levelblit.c

  • Committer: Package Import Robot
  • Author(s): Sylvain Beucler
  • Date: 2013-11-09 12:15:49 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20131109121549-yrlazwlls19a0ae7
Tags: 1.3-1
New upstream release - all patches merged, non-free files removed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
//   levelblit.c
3
 
//
4
 
//   Copyright 2007, 2008 Lancer-X/ASCEAI
5
 
//
6
 
//   This file is part of Meritous.
7
 
//
8
 
//   Meritous is free software: you can redistribute it and/or modify
9
 
//   it under the terms of the GNU General Public License as published by
10
 
//   the Free Software Foundation, either version 3 of the License, or
11
 
//   (at your option) any later version.
12
 
//
13
 
//   Meritous is distributed in the hope that it will be useful,
14
 
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
//   GNU General Public License for more details.
17
 
//
18
 
//   You should have received a copy of the GNU General Public License
19
 
//   along with Meritous.  If not, see <http://www.gnu.org/licenses/>.
20
 
//
21
 
 
22
 
#include <stdio.h>
23
 
#include <stdlib.h>
24
 
#include <string.h>
25
 
#include <math.h>
26
 
#include <time.h>
27
 
#include <SDL.h>
28
 
#include <SDL_image.h>
29
 
#include <assert.h>
30
 
 
31
 
#include "mapgen.h"
32
 
#include "demon.h"
33
 
#include "gamemap.h"
34
 
#include "tiles.h"
35
 
#include "save.h"
36
 
#include "help.h"
37
 
#include "audio.h"
38
 
#include "boss.h"
39
 
#include "ending.h"
40
 
 
41
 
#define PLAYERW 16
42
 
#define PLAYERH 24
43
 
 
44
 
#define MERITOUS_VERSION "v 1.1"
45
 
int RECORDING = 0;
46
 
int PLAYBACK = 0;
47
 
 
48
 
int expired_ms = 0;
49
 
int frame_len = 33;
50
 
int WriteBitmaps = 0;
51
 
int WB_StartRange = 0;
52
 
int WB_EndRange = 1000000;
53
 
int training = 0;
54
 
int game_paused = 0;
55
 
int show_ending = 0;
56
 
int voluntary_exit = 0;
57
 
int tele_select = 0;
58
 
int enter_room_x = 0, enter_room_y = 0;
59
 
 
60
 
int agate_knife_loc = -1;
61
 
 
62
 
FILE *record_file;
63
 
char record_filename[256];
64
 
 
65
 
void DrawLevel(int off_x, int off_y, int hide_not_visited, int fog_of_war);
66
 
void DrawPlayer(int x, int y, int pl_dir, int pl_frm);
67
 
void LoadLevel();
68
 
void ActivateRoom(int room);
69
 
 
70
 
void DrawCircuit();
71
 
void ReleaseCircuit();
72
 
void DrawCircle(int x, int y, int r, unsigned char c);
73
 
 
74
 
void DrawArtifacts();
75
 
 
76
 
void HandleEvents();
77
 
 
78
 
void text_init();
79
 
void draw_text(int x, int y, char *str, Uint8 tcol);
80
 
unsigned char font_data[128][8][8];
81
 
 
82
 
void DrawShield();
83
 
 
84
 
int key_held[10] = {0};
85
 
int game_running = 1;
86
 
 
87
 
int player_x;
88
 
int player_y;
89
 
int player_dying;
90
 
int magic_circuit;
91
 
int circuit_range;
92
 
int release_range;
93
 
int release_x;
94
 
int release_y;
95
 
int release_str;
96
 
 
97
 
int shield_hp;
98
 
int shield_recover;
99
 
int player_gems;
100
 
int checkpoints_found;
101
 
int circuit_size;
102
 
int first_game;
103
 
int player_hp;
104
 
int player_lives = 5;
105
 
int player_lives_part = 0;
106
 
 
107
 
int player_room;
108
 
int player_dir;
109
 
int player_wlk;
110
 
int player_walk_speed;
111
 
int wlk_wait;
112
 
int circuit_release;
113
 
int scroll_home;
114
 
int enter_pressed;
115
 
 
116
 
int opening_door_x, opening_door_y, opening_door_i = 0, opening_door_n;
117
 
 
118
 
int checkpoint_x;
119
 
int checkpoint_y;
120
 
 
121
 
int explored = 0;
122
 
//#define DEBUG_STATS 1
123
 
 
124
 
int artifacts[12];
125
 
SDL_Surface *artifact_spr = NULL;
126
 
 
127
 
int player_shield;
128
 
int circuit_fillrate;
129
 
int circuit_recoverrate;
130
 
 
131
 
int scroll_x, scroll_y;
132
 
 
133
 
int map_enabled;
134
 
 
135
 
int prv_player_room;
136
 
 
137
 
int specialmessage;
138
 
int specialmessagetimer;
139
 
 
140
 
int timer_ps = 0;
141
 
int timer_v[10];
142
 
 
143
 
float RandomDir()
144
 
{
145
 
        return (float)(rand()%256)*M_PI*2.0/256.0;
146
 
}
147
 
 
148
 
int UpgradePrice(int t);
149
 
 
150
 
void PlayerDefaultStats()
151
 
{
152
 
        int i;
153
 
        
154
 
        player_dying = 0;
155
 
        magic_circuit = 0;
156
 
        circuit_range = 100;
157
 
        release_range = 100;
158
 
        shield_hp = 0;
159
 
        shield_recover = 0;
160
 
        player_gems = 0;
161
 
        checkpoints_found = 0;
162
 
        circuit_size = 1000;
163
 
        first_game = 1;
164
 
        player_hp = 3;
165
 
        
166
 
        explored = 0;
167
 
        
168
 
        voluntary_exit = 0;
169
 
        player_room = 0;
170
 
        player_dir = 0;
171
 
        player_wlk = 0;
172
 
        player_walk_speed = 5;
173
 
        player_lives = 5;
174
 
        player_lives_part = 0;
175
 
        wlk_wait = 8;
176
 
        circuit_release = 0;
177
 
        scroll_home = 0;
178
 
        enter_pressed = 0;
179
 
        show_ending = 0;
180
 
        
181
 
        game_paused = 0;
182
 
        
183
 
        player_shield = 0;
184
 
        circuit_fillrate = 2;
185
 
        circuit_recoverrate = 3;
186
 
        
187
 
        prv_player_room = -1;
188
 
 
189
 
        specialmessage = 0;
190
 
        specialmessagetimer = 0;
191
 
        
192
 
        opening_door_i = 0;
193
 
 
194
 
        map_enabled = 0;
195
 
        
196
 
        for (i = 0; i < 12; i++) {
197
 
                artifacts[i] = 0;
198
 
        }
199
 
        
200
 
        #ifdef DEBUG_STATS
201
 
        
202
 
        player_shield = 24;
203
 
        circuit_fillrate = 24;
204
 
        circuit_recoverrate = 24;
205
 
        
206
 
        for (i = 0; i < 12; i++) {
207
 
                artifacts[i] = 1;
208
 
        }
209
 
        
210
 
        #endif
211
 
}
212
 
 
213
 
 
214
 
void ScrollTo(int x, int y);
215
 
#define K_UP 0
216
 
#define K_DN 1
217
 
#define K_LT 2
218
 
#define K_RT 3
219
 
#define K_SP 4
220
 
 
221
 
SDL_Surface *screen;
222
 
 
223
 
void SetGreyscalePalette();
224
 
void SetTonedPalette(float pct);
225
 
void SetTitlePalette(int curve_start, int curve_end);
226
 
void SetTitlePalette2(int t);
227
 
int TouchTile(int ix, int iy);
228
 
void SpecialTile(int x, int y);
229
 
void DrawRect(int x, int y, int w, int h, unsigned char c);
230
 
 
231
 
void DrawCircleEx(int x, int y, int r, int r2, unsigned char c);
232
 
 
233
 
void ThinLine(SDL_Surface *scr, int x1, int y1, int x2, int y2, Uint8 col);
234
 
void LockDoors(int r);
235
 
 
236
 
#define SCREEN_W 640
237
 
#define SCREEN_H 480
238
 
 
239
 
void VideoUpdate()
240
 
{
241
 
        static int bmp = 0;
242
 
        char bmp_name[256];
243
 
        
244
 
        SDL_UpdateRect(screen, 0, 0, 0, 0);
245
 
        if (WriteBitmaps) {
246
 
                if ((bmp >= WB_StartRange)&&(bmp < WB_EndRange)) {
247
 
                        sprintf(bmp_name, "v/bmp%d.bmp", bmp);
248
 
                        SDL_SaveBMP(screen, bmp_name);
249
 
                }
250
 
                bmp++;
251
 
        }
252
 
}
253
 
 
254
 
void EndCycle(int n)
255
 
{
256
 
        static int last_ticks;
257
 
        int tick_delta;
258
 
        tick_delta = SDL_GetTicks() - last_ticks;
259
 
        
260
 
        if (n == 0) n = frame_len;
261
 
 
262
 
        if (tick_delta < n) {
263
 
                SDL_Delay(n-tick_delta);
264
 
        }
265
 
        
266
 
        if (!game_paused) expired_ms += n;
267
 
                
268
 
        last_ticks = SDL_GetTicks();
269
 
}
270
 
 
271
 
void WritePlayerData()
272
 
{
273
 
        int i;
274
 
 
275
 
        FWInt(expired_ms);
276
 
        FWInt(checkpoint_x);
277
 
        FWInt(checkpoint_y);
278
 
        FWInt(scroll_x);
279
 
        FWInt(scroll_y);
280
 
        FWInt(magic_circuit);
281
 
        FWInt(checkpoint_x);
282
 
        FWInt(checkpoint_y);
283
 
        FWInt(player_walk_speed);
284
 
        FWInt(wlk_wait);
285
 
        FWInt(circuit_fillrate);
286
 
        FWInt(circuit_recoverrate);
287
 
        FWInt(explored);
288
 
        FWInt(player_shield);
289
 
        FWInt(shield_recover);
290
 
        FWInt(shield_hp);
291
 
        FWInt(player_gems);
292
 
        FWInt(checkpoints_found);
293
 
        FWInt(player_hp);
294
 
        FWInt(player_lives);
295
 
        FWInt(player_lives_part);
296
 
        FWInt(current_boss);
297
 
        FWInt(training);
298
 
        FWInt(agate_knife_loc);
299
 
 
300
 
        for (i = 0; i < 12; i++) {
301
 
                FWChar(artifacts[i]);
302
 
        }
303
 
}
304
 
 
305
 
void ReadPlayerData()
306
 
{
307
 
        int i;
308
 
 
309
 
        expired_ms = FRInt();
310
 
        player_x = FRInt();
311
 
        player_y = FRInt();
312
 
        scroll_x = FRInt();
313
 
        scroll_y = FRInt();
314
 
        magic_circuit = FRInt();
315
 
        checkpoint_x = FRInt();
316
 
        checkpoint_y = FRInt();
317
 
        player_walk_speed = FRInt();
318
 
        wlk_wait = FRInt();
319
 
        circuit_fillrate = FRInt();
320
 
        circuit_recoverrate = FRInt();
321
 
        explored = FRInt();
322
 
        player_shield = FRInt();
323
 
        shield_recover = FRInt();
324
 
        shield_hp = FRInt();
325
 
        player_gems = FRInt();
326
 
        checkpoints_found = FRInt();
327
 
        player_hp = FRInt();
328
 
        player_lives = FRInt();
329
 
        player_lives_part = FRInt();
330
 
        current_boss = FRInt();
331
 
        training = FRInt();
332
 
 
333
 
        agate_knife_loc = FRInt();
334
 
 
335
 
        for (i = 0; i < 12; i++) {
336
 
                artifacts[i] = FRChar();
337
 
        }
338
 
}
339
 
 
340
 
int min(int x, int y)
341
 
{
342
 
        if (x<y) return x;
343
 
        return y;
344
 
}
345
 
 
346
 
void DummyEventPoll()
347
 
{
348
 
        SDL_Event e;
349
 
        SDL_PollEvent(&e);
350
 
}
351
 
 
352
 
int DungeonPlay(char *fname);
353
 
 
354
 
Uint8 Uint8_Bound(int c)
355
 
{
356
 
        if (c<0) return 0;
357
 
        if (c>255) return 255;
358
 
        return c;
359
 
}
360
 
 
361
 
int dist(int x1, int y1, int x2, int y2)
362
 
{
363
 
        int dx, dy;
364
 
        dx = x2 - x1;
365
 
        dy = y2 - y1;
366
 
 
367
 
        return sqrt((dx*dx)+(dy*dy));
368
 
}
369
 
 
370
 
void ClearInput()
371
 
{
372
 
        key_held[K_SP] = 0;
373
 
        key_held[K_UP] = 0;
374
 
        key_held[K_DN] = 0;
375
 
        key_held[K_LT] = 0;
376
 
        key_held[K_RT] = 0;
377
 
}
378
 
 
379
 
int main(int argc, char **argv)
380
 
{
381
 
        int on_title = 1;
382
 
        int executable_running = 1;
383
 
        SDL_Surface *title, *title_pr, *asceai;
384
 
        SDL_Surface *wm_icon;
385
 
        Uint8 *src_p, *col_p;
386
 
        Uint8 wm_mask[128];
387
 
        int i;
388
 
        int light = 0;
389
 
        int x, y;
390
 
        int pulse[SCREEN_W * SCREEN_H];
391
 
        int precalc_sine[400];
392
 
        int tick = 10000000;
393
 
        int option = 0;
394
 
        int can_continue = 0;
395
 
        int maxoptions;
396
 
        
397
 
        int last_key = 0;
398
 
        
399
 
        int fullscreen = 0;
400
 
        int ticker_tick = 0;
401
 
        unsigned int stime = 0;
402
 
        
403
 
        FILE *wm_mask_file;
404
 
 
405
 
        if (argc > 1) {
406
 
                for (i = 1; i < argc; i++) {
407
 
                        if (!strcasecmp(argv[i], "fullscreen")) {
408
 
                                fullscreen = 1;
409
 
                        }
410
 
/*                      if (!strcasecmp(argv[i], "record")) {
411
 
                                RECORDING = 1;
412
 
                                strcpy(record_filename, argv[i+1]);
413
 
                        }
414
 
                        if (!strcasecmp(argv[i], "play")) {
415
 
                                PLAYBACK = 1;
416
 
                                strcpy(record_filename, argv[i+1]);
417
 
                        }
418
 
                        if (!strcasecmp(argv[i], "framedelay")) {
419
 
                                frame_len = atoi(argv[i+1]);
420
 
                        }
421
 
                        if (!strcasecmp(argv[i], "bmpwrite")) {
422
 
                                WriteBitmaps = 1;
423
 
                        }
424
 
                        if (!strcasecmp(argv[i], "bmpstart")) {
425
 
                                WB_StartRange = atoi(argv[i+1]);
426
 
                        }
427
 
                        if (!strcasecmp(argv[i], "bmpend")) {
428
 
                                WB_EndRange = atoi(argv[i+1]);
429
 
                        } */
430
 
                }
431
 
        }
432
 
 
433
 
        if ((RECORDING) && (PLAYBACK)) {
434
 
                exit(1);
435
 
        }
436
 
        srand(time(NULL));
437
 
        if (RECORDING) {
438
 
                record_file = fopen(record_filename, "wb");
439
 
                stime = time(NULL);
440
 
                
441
 
                fputc(stime & 0x000000FF, record_file);
442
 
                fputc((stime & 0x0000FF00) >> 8, record_file);
443
 
                fputc((stime & 0x00FF0000) >> 16, record_file);
444
 
                fputc((stime & 0xFF000000) >> 24, record_file);
445
 
                
446
 
                srand(stime);
447
 
        }
448
 
        if (PLAYBACK) {
449
 
                record_file = fopen(record_filename, "rb");
450
 
                stime = fgetc(record_file);
451
 
                stime |= fgetc(record_file) << 8;
452
 
                stime |= fgetc(record_file) << 16;
453
 
                stime |= fgetc(record_file) << 24;
454
 
                
455
 
                srand(stime);
456
 
        }
457
 
        
458
 
        asceai = IMG_Load("dat/i/asceai.png");
459
 
        wm_icon = IMG_Load("dat/i/icon.png");
460
 
        
461
 
        screen = SDL_SetVideoMode(SCREEN_W, SCREEN_H, 8, SDL_SWSURFACE | (SDL_FULLSCREEN * fullscreen));
462
 
        
463
 
        wm_mask_file = fopen("dat/d/icon_bitmask.dat", "rb");
464
 
        fread(wm_mask, 1, 128, wm_mask_file);
465
 
        fclose(wm_mask_file);
466
 
        SDL_WM_SetCaption("~ m e r i t o u s ~", "MT");
467
 
        SDL_WM_SetIcon(wm_icon, wm_mask);
468
 
        InitAudio();
469
 
        
470
 
        text_init();
471
 
        for (i = 0; i < 400; i++) {
472
 
                precalc_sine[i] = sin((float)i / 400 * M_PI * 2)*24+24;
473
 
        }
474
 
        
475
 
                
476
 
        for (i = 0; i < screen->w * screen->h; i++) {
477
 
                x = i % SCREEN_W;
478
 
                y = i / SCREEN_W;
479
 
 
480
 
                pulse[i] = dist(x, y, SCREEN_W / 2, SCREEN_H / 2);
481
 
        }
482
 
        SetGreyscalePalette();
483
 
        
484
 
        // asceai logo
485
 
        SDL_BlitSurface(asceai, NULL, screen, NULL);
486
 
        
487
 
        for (i = 0; i < 75; i++) {
488
 
                SetTitlePalette(i * 5 - 375, i * 5 - 120);
489
 
                VideoUpdate();
490
 
                DummyEventPoll();
491
 
                EndCycle(20);
492
 
        }
493
 
        SDL_Delay(500);
494
 
        for (i = 0; i < 50; i++) {
495
 
                SetTitlePalette(i * 5, 255 - (i * 5));
496
 
                VideoUpdate();
497
 
                DummyEventPoll();
498
 
                EndCycle(20);
499
 
        }
500
 
        SDL_Delay(500);
501
 
        for (i = 0; i < 50; i++) {
502
 
                SetTitlePalette(255, (i * 5)+5);
503
 
                VideoUpdate();
504
 
                DummyEventPoll();
505
 
                EndCycle(20);
506
 
        }
507
 
        
508
 
        while (executable_running) {
509
 
                ticker_tick = 0;
510
 
                TitleScreenMusic();
511
 
                
512
 
                if (IsSaveFile()) {
513
 
                        can_continue = 1;
514
 
                } else {
515
 
                        can_continue = 0;
516
 
                }
517
 
                
518
 
                maxoptions = 2 + can_continue;
519
 
        
520
 
                title = IMG_Load("dat/i/title.png");
521
 
                title_pr = IMG_Load("dat/i/title.png");
522
 
                
523
 
                while (on_title) {
524
 
                        SetTitlePalette2(ticker_tick);
525
 
                        col_p = (Uint8 *)title_pr->pixels;
526
 
                        src_p = (Uint8 *)title->pixels;
527
 
                        if ((tick % 10) == 0) {
528
 
                                for (i = 0; i < 640*480; i++) {
529
 
                                        *(col_p++) = Uint8_Bound(*(src_p++)+precalc_sine[(pulse[i]+tick)%400]);
530
 
                                }
531
 
                        }
532
 
                        SDL_BlitSurface(title_pr, NULL, screen, NULL);
533
 
                        
534
 
                        draw_text(17, 156, MERITOUS_VERSION, 225 + sin((float)ticker_tick / 15)*30);
535
 
                        if (can_continue) draw_text((SCREEN_W - 14*8)/2, 310, "Continue", 255);
536
 
                        draw_text((SCREEN_W - 14*8)/2, 310 + can_continue*10, "New Game", 255);
537
 
                        draw_text((SCREEN_W - 14*8)/2, 320 + can_continue*10, "New Game (Wuss mode)", 255);
538
 
                        
539
 
                        if (ticker_tick >= 30) {
540
 
                                draw_text((SCREEN_W - 14*8)/2 - 17, 310 + option * 10, "-", 205 + sin((float)ticker_tick / 5.0)*24);
541
 
                                draw_text((SCREEN_W - 14*8)/2 - 20, 310 + option * 10, " >", 205 + sin((float)ticker_tick / 5.0)*24);
542
 
                                draw_text((SCREEN_W - 14*8)/2 - 19, 310 + option * 10, " >", 190 + sin((float)ticker_tick / 5.0)*24);
543
 
                                draw_text((SCREEN_W - 14*8)/2 - 21, 310 + option * 10, " >", 190 + sin((float)ticker_tick / 5.0)*24);
544
 
                                draw_text((SCREEN_W - 14*8)/2 - 18, 310 + option * 10, " >", 165 + sin((float)ticker_tick / 5.0)*24);
545
 
                                draw_text((SCREEN_W - 14*8)/2 - 22, 310 + option * 10, " >", 165 + sin((float)ticker_tick / 5.0)*24);
546
 
                        }
547
 
        
548
 
                        VideoUpdate();
549
 
                        
550
 
                        if (ticker_tick++ > 30) {
551
 
                                HandleEvents();
552
 
                
553
 
                                if (key_held[K_UP]) {
554
 
                                        if (last_key != 1)
555
 
                                                if (option > 0) option--;
556
 
                                        last_key = 1;
557
 
                                } else {
558
 
                                        if (key_held[K_DN]) {
559
 
                                                if (last_key != 2)
560
 
                                                        if (option < maxoptions-1) option++;
561
 
                                                last_key = 2;
562
 
                                        } else {
563
 
                                                last_key = 0;
564
 
                                                if (key_held[K_SP] || enter_pressed) {
565
 
                                                        on_title = 0;
566
 
                                                }
567
 
                                        }
568
 
                                }
569
 
                                
570
 
                                if (voluntary_exit) {
571
 
                                        executable_running = 0;
572
 
                                        on_title = 0;
573
 
                                        SDL_Quit();
574
 
                                        exit(0);
575
 
                                }
576
 
                        }
577
 
                        
578
 
                        EndCycle(10);
579
 
        
580
 
                        light = 0;
581
 
                        tick -= 2;
582
 
                }
583
 
                
584
 
                ClearInput();
585
 
                
586
 
                if (executable_running == 1) {
587
 
                        SDL_FreeSurface(title);
588
 
                        SDL_FreeSurface(title_pr);
589
 
                        if ((option == 0) && can_continue) {
590
 
                                DungeonPlay("SaveFile.sav");
591
 
                        } else {
592
 
                                if (option == (0 + can_continue)) {
593
 
                                        training = 0;
594
 
                                        DungeonPlay("");
595
 
                                } else {
596
 
                                        training = 1;
597
 
                                        DungeonPlay("");
598
 
                                }
599
 
                        }
600
 
                        // clean up
601
 
                        ClearInput();
602
 
                        DestroyDungeon();
603
 
                        DestroyThings();
604
 
                        on_title = 1;
605
 
                        game_load = 0;
606
 
                        
607
 
                        game_running = 1;
608
 
                }
609
 
        }
610
 
 
611
 
//      if (argc >= 2) DungeonPlay(argv[1]);
612
 
//      else DungeonPlay("");
613
 
 
614
 
        SDL_Quit();
615
 
        return 0;
616
 
}
617
 
 
618
 
void DrawMeter(int x, int y, int n)
619
 
{
620
 
        static SDL_Surface *meter = NULL;
621
 
        SDL_Rect drawfrom, drawto;
622
 
        if (meter == NULL) {
623
 
                meter = IMG_Load("dat/i/meter.png");
624
 
                SDL_SetColorKey(meter, SDL_SRCCOLORKEY | SDL_RLEACCEL, 0);
625
 
        }
626
 
        
627
 
        drawfrom.x = 0;
628
 
        drawfrom.y = 6;
629
 
        drawfrom.w = 150;
630
 
        drawfrom.h = 6;
631
 
        
632
 
        drawto.x = x;
633
 
        drawto.y = y;
634
 
        
635
 
        SDL_BlitSurface(meter, &drawfrom, screen, &drawto);
636
 
        
637
 
        drawfrom.w = n*6;
638
 
        drawfrom.y = 0;
639
 
        
640
 
        SDL_BlitSurface(meter, &drawfrom, screen, &drawto);
641
 
}
642
 
 
643
 
void ProgressBarScreen(int part, float progress, char *message, float t_parts)
644
 
{
645
 
        memset(screen->pixels, 0, 640*480);
646
 
        
647
 
        DrawRect(200, 217, 240, 50, 80);
648
 
        DrawRect(202, 219, 236, 46, 20);
649
 
        draw_text(232, 228, message, 255);
650
 
        DrawRect(232, 244, 176, 12, 128);
651
 
        DrawRect(234, 246, 172, 8, 0);
652
 
        
653
 
        if ((int)(172.0 * progress / t_parts + (172.0 / t_parts * part)) > 0) {
654
 
                DrawRect(234, 246, (int)(172.0 * progress / t_parts + (172.0 / t_parts * part)), 8, 200);
655
 
        }
656
 
        VideoUpdate();
657
 
        DummyEventPoll();
658
 
}
659
 
 
660
 
void LoadingScreen(int part, float progress)
661
 
{
662
 
        float t_parts;
663
 
        
664
 
        if (game_load) t_parts = 5.0;
665
 
        else t_parts = 3.0;
666
 
        
667
 
        ProgressBarScreen(part, progress, "Loading... please wait", t_parts);
668
 
        ClearInput();
669
 
}
670
 
 
671
 
void SavingScreen(int part, float progress)
672
 
{
673
 
        ProgressBarScreen(part, progress, "Saving... please wait", 4.0);
674
 
        ClearInput();
675
 
}
676
 
 
677
 
void Arc(SDL_Surface *s, int x, int y, int r, float dir)
678
 
{
679
 
        int bright;
680
 
        int i, c;
681
 
        float pdir, cdir, ndir;
682
 
        
683
 
        int l_x = x, l_y = y;
684
 
        int cx, cy, c1x, c1y, c2x, c2y;
685
 
        
686
 
        bright = rand()%128+63;
687
 
        i = 0;
688
 
        while (i < r) {
689
 
                i += rand()%5+25;
690
 
                pdir = dir + (float)(rand()%16)/16.0*2.0*(M_PI / 15.0);
691
 
                ndir = dir - (float)(rand()%16)/16.0*2.0*(M_PI / 15.0);
692
 
                cdir = dir + (float)(rand()%16)/16.0*2.0*(M_PI / 20.0) - (float)(rand()%16)/16.0*2.0*(M_PI / 20.0);
693
 
 
694
 
                bright += rand()%30;
695
 
                bright -= rand()%30;
696
 
                
697
 
                if (bright < 0) bright = 0;
698
 
                if (bright > 255) bright = 255;
699
 
                
700
 
                c1x = x + cos(pdir) * i;
701
 
                c1y = y + sin(pdir) * i;
702
 
                ThinLine(s, l_x, l_y, c1x, c1y, bright);
703
 
                c2x = x + cos(ndir) * i;
704
 
                c2y = y + sin(ndir) * i;
705
 
                ThinLine(s, l_x, l_y, c2x, c2y, bright);
706
 
                
707
 
                for (c = 0; c < 5; c++) {
708
 
                        DrawRect(x + cos(dir - (M_PI / 10.0) + (float)(rand()%16)/16.0*2.0*(M_PI / 10.0)) * i, y + sin(dir - (M_PI / 10.0) +
709
 
                                          (float)(rand()%16)/16.0*2.0*(M_PI / 10.0)) * i, 1, 1, rand()%128+63);
710
 
                }
711
 
                
712
 
                i += rand()%5+25;
713
 
                cx = x + cos(cdir) * i;
714
 
                cy = y + sin(cdir) * i;
715
 
                ThinLine(s, c1x, c1y, cx, cy, bright);
716
 
                ThinLine(s, c2x, c2y, cx, cy, bright);
717
 
                l_x = cx;
718
 
                l_y = cy;
719
 
        }
720
 
        
721
 
}
722
 
 
723
 
int DungeonPlay(char *fname)
724
 
{
725
 
        int ix,  iy;
726
 
        int off_x, off_y;
727
 
        int t = 0;
728
 
        int i, j;
729
 
        int lost_gems;
730
 
        int rg_x, rg_y, rg_v;
731
 
        int max_dist;
732
 
        int last_killed = 0;
733
 
        int n_arcs = 0;
734
 
        int can_move;
735
 
        
736
 
        float arcdir;
737
 
        
738
 
        char buf[50];
739
 
        
740
 
        expired_ms = 0;
741
 
        LoadingScreen(0, 0.0);
742
 
        if (fname[0] != 0) {
743
 
                LoadGame(fname);
744
 
        }
745
 
 
746
 
        RandomGenerateMap();
747
 
        InitEnemies();
748
 
        InitBossVars();
749
 
 
750
 
        PlayerDefaultStats();
751
 
        if (game_load) {
752
 
                first_game = 0;
753
 
                ReadPlayerData();
754
 
                //Paint(rooms[0].x+1, rooms[0].y+1, rooms[0].w-2, rooms[0].h-2, "dat/d/fbossroom.loc");
755
 
        } else {
756
 
                player_x = map.w * 32 / 2 - PLAYERW/2;
757
 
                player_y = map.h * 32 / 2 - PLAYERH/2;
758
 
        }
759
 
 
760
 
        InitAutomap();
761
 
 
762
 
        if (game_load) CloseFile();
763
 
 
764
 
        max_dist = 0;
765
 
        for (i = 0; i < 3000; i++) {
766
 
                if (rooms[i].s_dist > max_dist) {
767
 
                        max_dist = rooms[i].s_dist;
768
 
                }
769
 
        }
770
 
        
771
 
        game_running = 1;
772
 
        while (game_running) {
773
 
                //sprintf(buf, "X: %d  Y: %d", (player_x + PLAYERW/2)/32*32 + PLAYERW/2, (player_y + PLAYERH/2)/32*32 + PLAYERH/2);
774
 
                //SDL_WM_SetCaption(buf, "MT");
775
 
                if (!game_paused) {
776
 
                        if (player_dying > 30) {
777
 
                                player_hp--;
778
 
                                
779
 
                                if (player_hp <= 0) {
780
 
                                        if (!training) player_lives--;
781
 
                                        lost_gems = player_gems / 3;
782
 
                                        player_gems -= lost_gems;
783
 
                
784
 
                                        lost_gems = lost_gems * 95 / 100;
785
 
                                        while (lost_gems > 0) {
786
 
                                                rg_x = rooms[player_room].x * 32 + 32 + rand()%(rooms[player_room].w*32-64);
787
 
                                                rg_y = rooms[player_room].y * 32 + 32 + rand()%(rooms[player_room].h*32-64);
788
 
                                                rg_v = rand() % (lost_gems / 4 + 2);
789
 
                                                CreateGem(rg_x, rg_y, player_room, rg_v);
790
 
                                                lost_gems -= rg_v;
791
 
                                        }
792
 
                
793
 
                                        player_dying = 0;
794
 
                                        shield_hp = 0;
795
 
                                        
796
 
                                        if ( (current_boss == 3) && (boss_fight_mode != 0) ) {
797
 
                                                player_x = enter_room_x;
798
 
                                                player_y = enter_room_y;
799
 
                                                prv_player_room = 1;
800
 
                                        } else {
801
 
                                                player_x = checkpoint_x;
802
 
                                                player_y = checkpoint_y;
803
 
                                        }
804
 
                                        scroll_home = 1;
805
 
                                        CircuitBullets(player_x, player_y, 100);
806
 
                                        player_hp = 3 + (player_shield == 30)*3;
807
 
                                } else {
808
 
                                        player_dying = 0;
809
 
                                }
810
 
                        }
811
 
                }
812
 
                
813
 
                circuit_size = 250 + 50*(circuit_fillrate + circuit_recoverrate);
814
 
                
815
 
                if (magic_circuit > 0) {
816
 
                        circuit_range = (sqrt(magic_circuit + 1) * 6 + min(magic_circuit / 2, 50))*1.66;
817
 
                        if (artifacts[3]) circuit_range += circuit_range / 2.4;
818
 
                } else circuit_range = -1;
819
 
                player_room = GetRoom(player_x/32, player_y/32);
820
 
 
821
 
                if (player_room != prv_player_room) {
822
 
                        SetTonedPalette((float)rooms[player_room].s_dist / (float)max_dist);
823
 
                        prv_player_room = player_room;
824
 
                        RecordRoom(player_room);
825
 
                        
826
 
                        enter_room_x = player_x;
827
 
                        enter_room_y = player_y;
828
 
                                                
829
 
                        if (rooms[player_room].room_type == 2) {
830
 
                                // lock the doors
831
 
                                LockDoors(player_room);
832
 
                                // it's a boss room
833
 
                                BossRoom(player_room);
834
 
                        }
835
 
                        if (((rooms[player_room].checkpoint)||(player_room==0))&&(!artifacts[11])) {
836
 
                                checkpoint_x = rooms[player_room].x * 32 + (rooms[player_room].w / 2 * 32) + 8;
837
 
                                checkpoint_y = rooms[player_room].y * 32 + (rooms[player_room].h / 2 * 32) + 4;
838
 
                        }
839
 
                        if (rooms[player_room].visited == 0) {
840
 
                                rooms[player_room].visited = 1;
841
 
                                explored++;
842
 
                                
843
 
                                if (explored == 3000) {
844
 
                                        agate_knife_loc = player_room;
845
 
                                }
846
 
                                
847
 
                                ActivateRoom(player_room);
848
 
                        }
849
 
                }
850
 
                
851
 
                if (last_killed != killed_enemies) {
852
 
                        SetTonedPalette((float)rooms[player_room].s_dist / (float)max_dist);
853
 
                        last_killed = killed_enemies;
854
 
                } else {
855
 
                        if ((player_room == 0)&&(artifacts[11] == 1)) {
856
 
                                SetTonedPalette(0);
857
 
                        }
858
 
                }
859
 
 
860
 
                if (!map_enabled) {
861
 
                        ScrollTo(player_x + PLAYERW/2 - 320, player_y + PLAYERH/2 - 240);
862
 
                        DrawLevel(scroll_x, scroll_y, 1, 1);
863
 
                        //DrawLevel(player_x + 8 - 320, player_y + 12 - 240);
864
 
        
865
 
                        if (player_dying == 0) {
866
 
                                DrawShield();
867
 
                                
868
 
                                if (magic_circuit > 0) {
869
 
                                        if (player_dying == 0) {
870
 
                                                if (circuit_release == 0) {
871
 
                                                        arcdir = RandomDir();
872
 
                                                        n_arcs = 1 + (circuit_size / 200 + 2) * magic_circuit / circuit_size;
873
 
                                                        for (i = 0; i < n_arcs; i++) {
874
 
                                                                Arc(screen, player_x - scroll_x + PLAYERW/2, player_y - scroll_y + PLAYERH/2, circuit_range, arcdir);
875
 
                                                                arcdir += (float)(rand()%16) / 16.0 * (M_PI*2/(float)n_arcs);
876
 
                                                        }
877
 
                                                }
878
 
                                        }
879
 
                                }
880
 
                        
881
 
                                DrawPlayer(312, 228, player_dir, player_wlk / wlk_wait);
882
 
                        } else {
883
 
                                if (t % 2 == 0) DrawPlayer(312, 228, player_dir, player_wlk / wlk_wait);
884
 
        
885
 
                                if (!game_paused)
886
 
                                        player_dying++;
887
 
                        }
888
 
                        t++;
889
 
                        if ((boss_fight_mode != 0)&&(boss_fight_mode < 23)&&(!game_paused)) {
890
 
                                BossControl();
891
 
                        }
892
 
                        DrawEntities();
893
 
                        if (!game_paused) MoveEntities();
894
 
                        
895
 
                        if (boss_fight_mode == 2) {
896
 
                                DrawBossHP(100);
897
 
                        }
898
 
                        
899
 
                        if (rooms[player_room].room_type == 5) {
900
 
                                DrawPowerObject();
901
 
                        }
902
 
                        if ( (rooms[player_room].room_type == 6) && (current_boss == 3) ) {
903
 
                                DrawPowerObject();
904
 
                        }
905
 
                        if ((rooms[player_room].room_type == 4) && ((player_room % 1000) == 999)) {
906
 
                                DrawPowerObject();
907
 
                        }
908
 
                        if (player_room == agate_knife_loc) {
909
 
                                {
910
 
                                        static float agate_t = 0.0;
911
 
                                        static SDL_Surface *agate_knife = NULL;
912
 
                                        int xpos, ypos;
913
 
                                        int room_w, room_h;
914
 
                                        int room_x, room_y;
915
 
                                        
916
 
                                        room_x = rooms[player_room].x * 32 + 32;
917
 
                                        room_y = rooms[player_room].y * 32 + 32;
918
 
                                        room_w = rooms[player_room].w * 32 - 64;
919
 
                                        room_h = rooms[player_room].h * 32 - 64;
920
 
                                        
921
 
                                        SDL_Rect draw_to;
922
 
                                        if (agate_knife == NULL) {
923
 
                                                agate_knife = IMG_Load("dat/i/agate.png");
924
 
                                                SDL_SetColorKey(agate_knife, SDL_SRCCOLORKEY | SDL_RLEACCEL, 0);
925
 
                                        }
926
 
                                        xpos = (int)((sin(agate_t * 1.33)*0.5+0.5) * (float)room_w) + room_x;
927
 
                                        ypos = (int)((cos(agate_t * 0.7)*0.5+0.5) * (float)room_h) + room_y;
928
 
                                        
929
 
                                        if (dist(player_x, player_y, xpos, ypos) < 20) {
930
 
                                                agate_knife_loc = -1;
931
 
                                                specialmessage = 50;
932
 
                                                specialmessagetimer = 150;
933
 
                                                SND_Pos("dat/a/crystal2.wav", 128, 0);
934
 
                                                
935
 
                                                player_shield = 30;
936
 
                                                circuit_fillrate = 30;
937
 
                                                circuit_recoverrate = 30;
938
 
                                                player_hp = 6;
939
 
                                        }
940
 
                                        draw_to.x = xpos - 16 - scroll_x;
941
 
                                        draw_to.y = ypos - 16 - scroll_y;
942
 
                                        
943
 
                                        SDL_BlitSurface(agate_knife, NULL, screen, &draw_to);
944
 
                                                                                
945
 
                                        agate_t += 0.05;
946
 
                                }
947
 
                        }
948
 
                        
949
 
                        if (opening_door_i > 0) {
950
 
                                DrawArtifactOverhead(opening_door_n);
951
 
                                for (i = 0; i < 5; i++) {
952
 
                                        j = i * 50 - 250 + (opening_door_i * 5);
953
 
                                        if (j > 0) {
954
 
                                                DrawCircle(player_x - scroll_x, player_y - scroll_y, j, 255);
955
 
                                        }
956
 
                                }
957
 
                                
958
 
                                if (!game_paused) {
959
 
                                        opening_door_i++;
960
 
                                        if (opening_door_i >= 100) {
961
 
                                                opening_door_i = 0;
962
 
                                                Put(opening_door_x, opening_door_y, Get(opening_door_x, opening_door_y) - 38 + 13, GetRoom(opening_door_x, opening_door_y));
963
 
                                        }
964
 
                                }
965
 
                        }
966
 
        
967
 
                        if (circuit_release > 0) {
968
 
                                DrawCircle(release_x - player_x + 320, release_y - player_y + 240, circuit_release * release_range / 20, sin((float)circuit_release / 20.0)*127+127);
969
 
                                if (!game_paused) {
970
 
                                        CircuitBullets(release_x, release_y, circuit_release * release_range / 20);
971
 
                                        //HurtEnemies(release_x, release_y, circuit_release * release_range / 20, release_str);
972
 
                                        circuit_release+=2;
973
 
                
974
 
                                        if (circuit_release > 24) {
975
 
                                                circuit_release = 0;
976
 
                                                HurtEnemies(release_x, release_y, release_range, release_str);
977
 
                                                if (boss_fight_mode == 2) TryHurtBoss(release_x, release_y, release_range, release_str);
978
 
                                        }
979
 
                                }
980
 
                        }
981
 
        
982
 
                        if (!game_paused) {
983
 
                                if (shield_hp < player_shield) {
984
 
                                        shield_recover += player_shield * 3 / (3 - training - (player_shield == 30));
985
 
                                        if (artifacts[1]) shield_recover += player_shield * 3 / (3 - training - (player_shield == 30));
986
 
                                        if (shield_recover >= 50) {
987
 
                                                shield_hp++;
988
 
                                                shield_recover -= 50 - (player_shield == 30)*25;
989
 
                                        }
990
 
                                }
991
 
                        }
992
 
                }
993
 
                
994
 
                DrawRect(0, 0, 640, 29, 0);
995
 
                DrawRect(1, 1, 638, 27, 32);
996
 
                DrawRect(2, 2, 636, 25, 64);
997
 
                
998
 
                if (!tele_select) {
999
 
                        sprintf(buf, "Psi Crystals: %d", player_gems);
1000
 
                        draw_text(3, 3, buf, 200);
1001
 
                        sprintf(buf, "Explored: %.1f%% (%d/%d rooms)", (float)explored/30.0, explored, 3000);
1002
 
                        draw_text(3, 11, buf, 200);
1003
 
                        sprintf(buf, "Cleared: %.1f%% (%d/%d monsters)", (float)killed_enemies/(float)total_enemies*100.0, killed_enemies, total_enemies);
1004
 
                        draw_text(3, 19, buf, 200);
1005
 
                        
1006
 
                        draw_text(316, 3, "Reflect shield", (player_gems >= UpgradePrice(0))&&(player_shield!=30) ? (231 + (t%13)*2) : 200);
1007
 
                        DrawMeter(434, 3, player_shield);
1008
 
                        
1009
 
                        draw_text(316, 11, "Circuit charge", (player_gems >= UpgradePrice(1))&&(circuit_fillrate!=30) ? (231 + (t%13)*2) : 200);
1010
 
                        DrawMeter(434, 11, circuit_fillrate);
1011
 
                        
1012
 
                        draw_text(316, 19, "Circuit refill", (player_gems >= UpgradePrice(2))&&(circuit_recoverrate!=30) ? (231 + (t%13)*2) : 200);
1013
 
                        DrawMeter(434, 19, circuit_recoverrate);
1014
 
                        
1015
 
                } else {
1016
 
                        draw_text(80, 11-6, "Use the movement keys to locate a checkpoint. Press ENTER to", 240);
1017
 
                        draw_text(52, 11+6, "teleport to this checkpoint. Press ESCAPE or TAB once you are done.", 240);
1018
 
                }
1019
 
                
1020
 
                if (!training) {
1021
 
                        buf[0] = 30;
1022
 
                
1023
 
                        if (player_lives <= 99) {
1024
 
                                if (player_lives < 10) {
1025
 
                                        sprintf(buf+1, " %d", player_lives);
1026
 
                                } else {
1027
 
                                        sprintf(buf+1, "%d", player_lives);
1028
 
                                }
1029
 
                        } else {
1030
 
                                sprintf(buf+1, "**");
1031
 
                        }
1032
 
                        
1033
 
                        draw_text(615, 4, buf, 200);
1034
 
                        
1035
 
                        DrawRect(615, 13, 24, 4, 240);
1036
 
                        DrawRect(616, 14, 22, 2, 0);
1037
 
                        i = (player_lives_part * 22 / 88);
1038
 
                        if (i > 0) {
1039
 
                                DrawRect(616, 14, i, 2, 160 + (t % 40));
1040
 
                        }
1041
 
                }
1042
 
                
1043
 
                if (player_shield != 30) {
1044
 
                        for (i = 0; i < player_hp; i++) {
1045
 
                                buf[i] = 3;
1046
 
                        }
1047
 
                        buf[player_hp]=0;
1048
 
                } else {
1049
 
                        for (i = 0; i < (player_hp / 2); i++) {
1050
 
                                buf[i] = 3;
1051
 
                        }
1052
 
                        if ((player_hp % 2) == 1) {
1053
 
                                buf[(player_hp + 1) / 2 - 1] = 2;
1054
 
                        }
1055
 
                        buf[(player_hp+1)/2]=0;
1056
 
                }
1057
 
                
1058
 
                draw_text(615, 18 - (5*training), buf, 200);
1059
 
 
1060
 
                DrawRect(0, 466, 640, 14, 0);
1061
 
                DrawRect(1, 467, 638, 12, 32);
1062
 
                DrawRect(2, 468, 636, 10, 64);
1063
 
                
1064
 
                DrawCircuit();
1065
 
                DrawArtifacts();
1066
 
                
1067
 
                SpecialTile((player_x+PLAYERW/2)/32, (player_y+PLAYERH/2)/32);
1068
 
 
1069
 
                if (map_enabled) DisplayAutomap();
1070
 
                
1071
 
                if ((boss_fight_mode != 0)&&(boss_fight_mode == 23)&&(!game_paused)) {
1072
 
                        BossControl();
1073
 
                }
1074
 
                if ( (boss_dlg != 0) && (!game_paused)) {
1075
 
                        BossDialog();
1076
 
                }
1077
 
                
1078
 
                if (game_paused && (!map_enabled) && (!voluntary_exit)) {
1079
 
                        for (i = 0; i < 10; i++) {
1080
 
                                DrawRect((640 - 6 * 8) / 2 - i, (480 - 8) / 2 - i, 6*8 + 2*i, 8 + 2*i, 64 - i*5);
1081
 
                        }
1082
 
                        draw_text((640 - 6 * 8) / 2, (480 - 8) / 2, "Paused", 255);
1083
 
                        
1084
 
                        {
1085
 
                                int t_days;
1086
 
                                int t_hours;
1087
 
                                int t_minutes;
1088
 
                                int t_seconds;
1089
 
                                
1090
 
                                t_seconds = (expired_ms / 1000) % 60;
1091
 
                                t_minutes = ((expired_ms / 1000) / 60) % 60;
1092
 
                                t_hours = (((expired_ms / 1000) / 60) / 60) % 24;
1093
 
                                t_days = (((expired_ms / 1000) / 60) / 60) / 24;
1094
 
                                
1095
 
                                if (t_days > 0) {
1096
 
                                        sprintf(buf, "%dd %dh %dm %ds", t_days, t_hours, t_minutes, t_seconds);
1097
 
                                } else {
1098
 
                                        if (t_hours > 0) {
1099
 
                                                sprintf(buf, "%dh %dm %ds", t_hours, t_minutes, t_seconds);
1100
 
                                        } else {
1101
 
                                                sprintf(buf, "%dm %ds", t_minutes, t_seconds);
1102
 
                                        }
1103
 
                                }
1104
 
                                draw_text(636 - strlen(buf)*8, 470, buf, 255);
1105
 
                        }
1106
 
                }
1107
 
                
1108
 
                if (voluntary_exit) {
1109
 
                        DrawRect(152, 200, 336, 80, 128);
1110
 
                        DrawRect(160, 208, 320, 64, 64);
1111
 
                        draw_text((640 - 30 * 8) / 2, (480 - 8) / 2 - 4, "Are you sure you want to quit?", 255);
1112
 
                        draw_text((640 - 23 * 8) / 2, (480 - 8) / 2 + 4, "Press enter to confirm.", 255);
1113
 
                }
1114
 
                
1115
 
                VideoUpdate();
1116
 
                
1117
 
                MusicUpdate();
1118
 
                
1119
 
                EndCycle(0);
1120
 
                
1121
 
                can_move = 1;
1122
 
                
1123
 
                if ((player_dying != 0) && (player_hp <= 1)) can_move = 0;
1124
 
                if (rooms[player_room].room_type == 5)
1125
 
                        if (CanGetArtifact())
1126
 
                                if (Get((player_x+PLAYERW/2)/32, (player_y+PLAYERH/2)/32)==42)
1127
 
                                        if (rooms[player_room].enemies == 0)
1128
 
                                                can_move = 0;
1129
 
                                                
1130
 
                if (rooms[player_room].room_type == 6)
1131
 
                        if (CanGetArtifact())
1132
 
                                if (PlayerDist(rooms[player_room].w * 16 + rooms[player_room].x * 32,
1133
 
                                                        rooms[player_room].h * 16 + rooms[player_room].y * 32) < 32)
1134
 
                                        if (rooms[player_room].enemies == 0)
1135
 
                                                if (current_boss == 3)
1136
 
                                                        can_move = 0;
1137
 
                                        
1138
 
                if (scroll_home != 0) can_move = 0;
1139
 
                if (boss_fight_mode == 1) can_move = 0;
1140
 
                if (boss_fight_mode >= 3) can_move = 0;
1141
 
                if (opening_door_i != 0) can_move = 0;
1142
 
                if (game_paused) can_move = 0;
1143
 
                
1144
 
                HandleEvents();
1145
 
                if (map_enabled) {
1146
 
                        game_paused = 1;
1147
 
                }
1148
 
                
1149
 
                if (can_move) {
1150
 
                        
1151
 
                        ix = player_x;
1152
 
                        iy = player_y;
1153
 
                        off_x = 0;
1154
 
                        off_y = 0;
1155
 
                        if (key_held[K_UP] && !key_held[K_DN]) {
1156
 
                                iy -= player_walk_speed * (artifacts[4]?1.4:1);
1157
 
                                player_dir = 0;
1158
 
                        }
1159
 
                        if (key_held[K_DN] && !key_held[K_UP]) {
1160
 
                                iy += player_walk_speed * (artifacts[4]?1.4:1);;
1161
 
                                player_dir = 1;
1162
 
                                off_y = 24;
1163
 
                        }
1164
 
                        if (key_held[K_LT] && !key_held[K_RT]) {
1165
 
                                ix -= player_walk_speed * (artifacts[4]?1.4:1);;
1166
 
                                if (!(key_held[K_UP] || key_held[K_DN])) {
1167
 
                                        player_dir = 3;
1168
 
                                }
1169
 
                        }
1170
 
                        if (key_held[K_RT] && !key_held[K_LT]) {
1171
 
                                off_x = 16;
1172
 
                                ix += player_walk_speed * (artifacts[4]?1.4:1);;
1173
 
                                if (!(key_held[K_UP] || key_held[K_DN])) {
1174
 
                                        player_dir = 2;
1175
 
                                        
1176
 
                                }
1177
 
                        }
1178
 
                        if ((key_held[K_SP])&&(magic_circuit >= 0)) {
1179
 
                                magic_circuit += (circuit_fillrate * (3+training+(circuit_fillrate==30))/3);
1180
 
                        } else {
1181
 
                                if (magic_circuit < 0) {
1182
 
                                        magic_circuit += (circuit_recoverrate * (3+training+(circuit_recoverrate==30))/3);
1183
 
                                        if (magic_circuit > 0) magic_circuit = 0;
1184
 
                                } else {
1185
 
                                        if (magic_circuit > 0) {
1186
 
                                                ReleaseCircuit();
1187
 
                                        }
1188
 
                                }
1189
 
                        }
1190
 
 
1191
 
                        if (magic_circuit > circuit_size) magic_circuit = circuit_size;
1192
 
                        
1193
 
                        if ((ix!=player_x)||(iy!=player_y)) {
1194
 
                                // Are we changing to a new square?
1195
 
                                if (((player_x / 32)!=((ix+off_x) / 32)) || ((player_y / 32)!=((iy+off_y) / 32))) {
1196
 
                                        //printf("%d\n", tile);
1197
 
                                        if (TouchTile(ix, iy)) {
1198
 
                                                player_wlk = (player_wlk + 1 + artifacts[4]*3) % (4*wlk_wait);
1199
 
                                        } else {
1200
 
                                                if (TouchTile(player_x, iy)) {
1201
 
                                                        player_wlk = (player_wlk + 1 + artifacts[4]*3) % (4*wlk_wait);
1202
 
                                                } else {
1203
 
                                                        if (TouchTile(ix, player_y)) {
1204
 
                                                                player_wlk = (player_wlk + 1 + artifacts[4]*3) % (4*wlk_wait);
1205
 
                                                                if (off_x > 0) player_dir = 2;
1206
 
                                                                else player_dir = 3;
1207
 
                                                        }
1208
 
                                                }
1209
 
                                                
1210
 
                                        }
1211
 
                                } else {
1212
 
                                        player_x = ix;
1213
 
                                        player_y = iy;
1214
 
                                        
1215
 
                                        player_wlk = (player_wlk + 1 + artifacts[4]*3) % (4*wlk_wait);
1216
 
                                }
1217
 
                        }
1218
 
                }
1219
 
                
1220
 
                if ((t % (33 * 10))==(33 * 10 - 1)) {
1221
 
                        ActivateRand();
1222
 
                }
1223
 
                
1224
 
                if (voluntary_exit && enter_pressed) {
1225
 
                        voluntary_exit = 0;
1226
 
                        game_running = 0;
1227
 
                        game_paused = 0;
1228
 
                }
1229
 
                
1230
 
                if ((player_lives == 0) && (!training)) {
1231
 
                        break;
1232
 
                }
1233
 
                if (show_ending) {
1234
 
                        break;
1235
 
                }
1236
 
        }
1237
 
        
1238
 
        if (show_ending) {
1239
 
                show_ending = 0;
1240
 
                ShowEnding();
1241
 
        }
1242
 
        
1243
 
        if ((player_lives == 0) && (!training)) {
1244
 
                SDL_FillRect(screen, NULL, 0);
1245
 
                draw_text(252, 236, "G A M E   O V E R", 255);
1246
 
                VideoUpdate();
1247
 
                SDL_Delay(2000);
1248
 
        }
1249
 
        
1250
 
        return 0;
1251
 
}
1252
 
 
1253
 
void UpRoom()
1254
 
{
1255
 
        int i, nd;
1256
 
        
1257
 
        nd = rooms[player_room].s_dist + 1;
1258
 
        
1259
 
        for (i = 0; i < 3000; i++) {
1260
 
                if (rooms[i].s_dist == nd) {
1261
 
                        player_x = rooms[i].x * 32 + 64;
1262
 
                        player_y = rooms[i].y * 32 + 64;
1263
 
                }
1264
 
        }
1265
 
}
1266
 
 
1267
 
void CancelVoluntaryExit()
1268
 
{
1269
 
        if (voluntary_exit) {
1270
 
                voluntary_exit = 0;
1271
 
                game_paused = 0;
1272
 
        }
1273
 
}
1274
 
 
1275
 
void HandleEvents()
1276
 
{
1277
 
        unsigned short db;
1278
 
        static SDL_Event event;
1279
 
        int pressed_tab = 0;
1280
 
        
1281
 
        if (PLAYBACK) {
1282
 
                db = fgetc(record_file);
1283
 
                db |= fgetc(record_file) << 8;
1284
 
                
1285
 
                key_held[K_UP] = (db & 0x0001)>0;
1286
 
                key_held[K_DN] = (db & 0x0002)>0;
1287
 
                key_held[K_LT] = (db & 0x0004)>0;
1288
 
                key_held[K_RT] = (db & 0x0008)>0;
1289
 
                key_held[K_SP] = (db & 0x0010)>0;
1290
 
                enter_pressed  = (db & 0x0020)>0;
1291
 
                map_enabled    = (db & 0x0040)>0;
1292
 
                game_running   = (db & 0x0080)>0;
1293
 
                game_paused    = (db & 0x0100)>0;
1294
 
                voluntary_exit = (db & 0x0200)>0;
1295
 
                pressed_tab    = (db & 0x0400)>0;
1296
 
                tele_select    = (db & 0x0800)>0;
1297
 
 
1298
 
                return;
1299
 
        }
1300
 
        
1301
 
        if (pressed_tab) {
1302
 
                c_scroll_x = player_x;
1303
 
                c_scroll_y = player_y;
1304
 
        }
1305
 
        
1306
 
        enter_pressed = 0;
1307
 
                while (SDL_PollEvent(&event)) {
1308
 
                        if (event.type == SDL_KEYDOWN) {
1309
 
                                switch (event.key.keysym.sym) {
1310
 
                                        case SDLK_w:
1311
 
                                        case SDLK_UP:
1312
 
                                                key_held[K_UP] = 1;
1313
 
                                                CancelVoluntaryExit();
1314
 
                                                break;
1315
 
                                        case SDLK_s:
1316
 
                                        case SDLK_DOWN:
1317
 
                                                key_held[K_DN] = 1;
1318
 
                                                CancelVoluntaryExit();
1319
 
                                                break;
1320
 
                                        case SDLK_a:
1321
 
                                        case SDLK_LEFT:
1322
 
                                                key_held[K_LT] = 1;
1323
 
                                                CancelVoluntaryExit();
1324
 
                                                break;
1325
 
                                        case SDLK_d:
1326
 
                                        case SDLK_RIGHT:
1327
 
                                                key_held[K_RT] = 1;
1328
 
                                                CancelVoluntaryExit();
1329
 
                                                break;
1330
 
                                        case SDLK_SPACE:
1331
 
                                                key_held[K_SP] = 1;
1332
 
                                                CancelVoluntaryExit();
1333
 
                                                break;
1334
 
                                        case SDLK_RETURN:
1335
 
                                                enter_pressed = 1;
1336
 
                                                break;
1337
 
                                        case SDLK_ESCAPE:
1338
 
                                                if (map_enabled) {
1339
 
                                                        map_enabled = 0;
1340
 
                                                        game_paused = 0;
1341
 
                                                        tele_select = 0;
1342
 
                                                } else {
1343
 
                                                        voluntary_exit ^= 1;
1344
 
                                                        game_paused = voluntary_exit;
1345
 
                                                }
1346
 
                                                break;
1347
 
                                        case SDLK_TAB:
1348
 
                                                if (tele_select) {
1349
 
                                                        map_enabled = 0;
1350
 
                                                        game_paused = 0;
1351
 
                                                        tele_select = 0;
1352
 
                                                } else {
1353
 
                                                        pressed_tab = 1;
1354
 
                                                        map_enabled ^= 1;
1355
 
                                                        game_paused = map_enabled;
1356
 
                                                        c_scroll_x = player_x;
1357
 
                                                        c_scroll_y = player_y;
1358
 
                                                }
1359
 
                                                CancelVoluntaryExit();
1360
 
                                                break;
1361
 
                                        case SDLK_h:
1362
 
                                                CancelVoluntaryExit();
1363
 
                                                ShowHelp();
1364
 
                                                break;
1365
 
                                        case SDLK_p:
1366
 
                                                game_paused ^= 1;
1367
 
                                                CancelVoluntaryExit();
1368
 
                                                break;
1369
 
                                                
1370
 
                                                
1371
 
                                        /*
1372
 
                                        case SDLK_j:
1373
 
                                                {
1374
 
                                                        player_shield = 20;
1375
 
                                                        circuit_recoverrate = 20;
1376
 
                                                        circuit_fillrate = 20;
1377
 
                                                }
1378
 
                                                break;
1379
 
                                        case SDLK_k:
1380
 
                                                {
1381
 
                                                        int i, n, j;
1382
 
                                                        for (j = 0; j < 1; j++) {
1383
 
                                                                for (i = 0; i < 50000; i++) {
1384
 
                                                                        n = rand()%3000;
1385
 
                                                                        if (rooms[n].visited == 0) {
1386
 
                                                                                player_x = rooms[n].x * 32 + rooms[n].w * 16;
1387
 
                                                                                player_y = rooms[n].y * 32 + rooms[n].h * 16;
1388
 
                                                                                rooms[n].visited = 1;
1389
 
                                                                                explored++;
1390
 
                                                                                break;
1391
 
                                                                        }
1392
 
                                                                }
1393
 
                                                        }
1394
 
                                                }
1395
 
                                                break;
1396
 
 
1397
 
                                        case SDLK_m:
1398
 
                                                {
1399
 
                                                        int i;
1400
 
                                                        for (i = 0; i < 8; i++) {
1401
 
                                                                artifacts[i] = 1;
1402
 
                                                        }
1403
 
                                                        for (i = 8; i < 11; i++) {
1404
 
                                                                artifacts[i] = 0;
1405
 
                                                        }
1406
 
                                                        artifacts[11] = 0;
1407
 
                                                }
1408
 
                                                break;
1409
 
                                                
1410
 
                                        case SDLK_n:
1411
 
                                                {
1412
 
                                                        current_boss = 3;
1413
 
                                                        expired_ms = 1000000;
1414
 
                                                }
1415
 
                                                break;
1416
 
                                        */
1417
 
                                        default:
1418
 
                                                break;
1419
 
                                }
1420
 
                        }
1421
 
                        if (event.type == SDL_KEYUP) {
1422
 
                                switch (event.key.keysym.sym) {
1423
 
                                        case SDLK_w:
1424
 
                                        case SDLK_UP:
1425
 
                                                key_held[K_UP] = 0;
1426
 
                                                break;
1427
 
                                        case SDLK_s:
1428
 
                                        case SDLK_DOWN:
1429
 
                                                key_held[K_DN] = 0;
1430
 
                                                break;
1431
 
                                        case SDLK_a:
1432
 
                                        case SDLK_LEFT:
1433
 
                                                key_held[K_LT] = 0;
1434
 
                                                break;
1435
 
                                        case SDLK_d:
1436
 
                                        case SDLK_RIGHT:
1437
 
                                                key_held[K_RT] = 0;
1438
 
                                                break;
1439
 
                                        case SDLK_SPACE:
1440
 
                                                key_held[K_SP] = 0;
1441
 
                                                break;
1442
 
                                        default:
1443
 
                                                break;
1444
 
                                }
1445
 
                        }
1446
 
                        if (event.type == SDL_QUIT) {
1447
 
                                voluntary_exit = 1;
1448
 
                        }
1449
 
                }
1450
 
                
1451
 
        if (RECORDING) {
1452
 
                db = 0;
1453
 
                
1454
 
                db |= 0x0001 * key_held[K_UP];
1455
 
                db |= 0x0002 * key_held[K_DN];
1456
 
                db |= 0x0004 * key_held[K_LT];
1457
 
                db |= 0x0008 * key_held[K_RT];
1458
 
                db |= 0x0010 * key_held[K_SP];
1459
 
                db |= 0x0020 * enter_pressed;
1460
 
                db |= 0x0040 * map_enabled;
1461
 
                db |= 0x0080 * game_running;
1462
 
                db |= 0x0100 * game_paused;
1463
 
                db |= 0x0200 * voluntary_exit;
1464
 
                db |= 0x0400 * pressed_tab;
1465
 
                db |= 0x0800 * tele_select;
1466
 
                
1467
 
                fputc(db & 0x00FF, record_file);
1468
 
                fputc((db & 0xFF00)>>8, record_file);
1469
 
                return;
1470
 
        }
1471
 
        
1472
 
}
1473
 
 
1474
 
void DrawLevel(int off_x, int off_y, int hide_not_visited, int fog_of_war)
1475
 
{
1476
 
        static SDL_Surface *tiles = NULL;
1477
 
        static SDL_Surface *fog = NULL;
1478
 
        Uint8 *pp;
1479
 
        SDL_Rect tilerec, screenrec;
1480
 
        int x, y, i;
1481
 
        int resolve_x, resolve_y;
1482
 
        
1483
 
        DrawRect(0, 0, 640, 480, 255);
1484
 
        
1485
 
        if (tiles == NULL) {
1486
 
                tiles = IMG_Load("dat/i/tileset.png");
1487
 
                fog = IMG_Load("dat/i/tileset.png");
1488
 
                                
1489
 
                pp = fog->pixels;
1490
 
                
1491
 
                for (i = 0; i < fog->w*fog->h; i++) {
1492
 
                        *pp = *pp / 2 + 128;
1493
 
                        pp++;
1494
 
                }
1495
 
        }
1496
 
        for (y = 0; y < 16; y++) {
1497
 
                for (x = 0; x < 21; x++) {
1498
 
                        resolve_x = x + (off_x/32);
1499
 
                        resolve_y = y + (off_y/32);
1500
 
                        
1501
 
                        if ((GetVisited(resolve_x, resolve_y) == 0)&&(player_room != GetRoom(resolve_x, resolve_y))&&(hide_not_visited)) {
1502
 
                                tilerec.x = 17 * 32;
1503
 
                        } else {
1504
 
                                tilerec.x = Get(resolve_x, resolve_y) * 32;
1505
 
                        }
1506
 
                        tilerec.y = 0;
1507
 
                        tilerec.w = 32;
1508
 
                        tilerec.h = 32;
1509
 
                        
1510
 
                        screenrec.x = x*32 - ( (off_x) %32);
1511
 
                        screenrec.y = y*32 - ( (off_y) %32);
1512
 
                        
1513
 
                        if ((player_room != GetRoom(resolve_x, resolve_y))&&(fog_of_war)) {
1514
 
                                SDL_BlitSurface(fog, &tilerec, screen, &screenrec);
1515
 
                        } else {
1516
 
                                SDL_BlitSurface(tiles, &tilerec, screen, &screenrec);
1517
 
                        }
1518
 
                }
1519
 
        }
1520
 
}
1521
 
 
1522
 
void DrawPlayer(int x, int y, int pl_dir, int pl_frm)
1523
 
{
1524
 
        static SDL_Surface *playersprite = NULL;
1525
 
        SDL_Rect playerrec, screenrec;
1526
 
        
1527
 
        if (playersprite == NULL) {
1528
 
                playersprite = IMG_Load("dat/i/player.png");
1529
 
                SDL_SetColorKey(playersprite, SDL_SRCCOLORKEY | SDL_RLEACCEL, 0);
1530
 
        }
1531
 
        
1532
 
        playerrec.x = pl_frm * 16;
1533
 
        playerrec.y = pl_dir * 24;
1534
 
        playerrec.w = 16;
1535
 
        playerrec.h = 24;
1536
 
        
1537
 
        screenrec.x = x;
1538
 
        screenrec.y = y;
1539
 
        
1540
 
        SDL_BlitSurface(playersprite, &playerrec, screen, &screenrec);
1541
 
}
1542
 
 
1543
 
void SetGreyscalePalette()
1544
 
{
1545
 
        SDL_Color grey[256];
1546
 
        SDL_Color pal[256];
1547
 
        int i;
1548
 
        
1549
 
        float ip;
1550
 
        
1551
 
        for (i = 0; i < 256; i++) {
1552
 
                grey[i].r = grey[i].g = grey[i].b = i;
1553
 
        }
1554
 
        
1555
 
        for (i = 0; i < 256; i++) {
1556
 
                ip = (float)i / 255.0;
1557
 
                pal[i].r = (cos(ip * M_PI / 2.0 + M_PI) + 1.0) * 255;
1558
 
                pal[i].g = (sin(ip * M_PI / 2.0) * 255 + i) / 2;
1559
 
                pal[i].b = sin(ip * M_PI / 2.0) * 255;
1560
 
        }
1561
 
        
1562
 
        SDL_SetPalette(screen, SDL_LOGPAL, grey, 0, 256);
1563
 
        SDL_SetPalette(screen, SDL_PHYSPAL, pal, 0, 256);
1564
 
}
1565
 
 
1566
 
void SetTonedPalette(float dct)
1567
 
{
1568
 
        SDL_Color pal[256];
1569
 
        float pct = 1.0 - dct;
1570
 
        float rp_dct, rp_pct;
1571
 
        float ip;
1572
 
        int ec;
1573
 
        int i;
1574
 
        static int tk = 0;
1575
 
        
1576
 
        ec = rooms[player_room].enemies;
1577
 
        
1578
 
        if (ec < 50) {
1579
 
                rp_dct = (float)ec / 50.0;
1580
 
        } else {
1581
 
                rp_dct = 1.0;
1582
 
        }
1583
 
        rp_pct = 1.0 - rp_dct;
1584
 
        
1585
 
        if ( (player_room == 0) && (current_boss == 3) && (boss_fight_mode >= 3) ) {
1586
 
                if (boss_fight_mode == 23) {
1587
 
                        for (i = 0; i < 256; i++) {
1588
 
                                pal[i].r = i;
1589
 
                                pal[i].g = i;
1590
 
                                pal[i].b = i;
1591
 
                        }
1592
 
                } else {
1593
 
                        tk++;
1594
 
                        pct = sin((float)tk / 20.0 * M_PI) * (0.5 - (float)(boss_fight_mode-3)*0.025) + (0.5 - (float)(boss_fight_mode-3)*0.025);
1595
 
                        
1596
 
                        if (magic_circuit < 0.1) pct = 1.0;
1597
 
 
1598
 
                        for (i = 0; i < 256; i++) {
1599
 
                                ip = (float)i / 255.0;
1600
 
                                pal[i].r = 255 - (255 - (cos(ip * M_PI / 2.0 + M_PI) + 1.0) * 255)*pct;
1601
 
                                pal[i].g = 255 - (255 - i)*pct;
1602
 
                                pal[i].b = 255 - (255 - sin(ip * M_PI / 2.0) * 255) * pct;
1603
 
                        }
1604
 
                        
1605
 
                        
1606
 
                        pal[1].r = 0;
1607
 
                        pal[1].g = 0;
1608
 
                        pal[1].b = 0;
1609
 
                }
1610
 
        } else {
1611
 
                if (artifacts[11]) {
1612
 
                        if (player_room == 0) {
1613
 
                                tk++;
1614
 
                                pct = sin((float)tk / 33.0 * M_PI) * 0.5 + 0.5;
1615
 
                                for (i = 0; i < 256; i++) {
1616
 
                                        pal[i].r = i;
1617
 
                                        pal[i].g = (i / 3)*pct;
1618
 
                                        pal[i].b = (i * 2 / 3)*pct;
1619
 
                                }
1620
 
                        } else {
1621
 
                                for (i = 0; i < 256; i++) {
1622
 
                                        ip = (float)i / 255.0;
1623
 
                                        pal[i].r = i;
1624
 
                                        pal[i].g = i * dct;
1625
 
                                        pal[i].b = (cos(ip * M_PI / 2.0 + M_PI) + 1.0) * 255 * dct;
1626
 
                                }
1627
 
                        }
1628
 
                        
1629
 
                        if ( (current_boss == 3) && (player_shield == 30) && (player_room == 0)) {
1630
 
                                if (boss_lives <= 1) {
1631
 
                                        tk++;
1632
 
                                        for (i = 0; i < 256; i++) {
1633
 
                                                pct = sin((float) (tk + i) / 24.0 * M_PI) * 0.5 + 0.5;
1634
 
                                                
1635
 
                                                pal[i].r = (i * 0.5 + 128)*pct;
1636
 
                                                pal[i].g = i * 0.5 + 128;
1637
 
                                                pal[i].b = (i * 0.5 + 128)*pct;
1638
 
                                        }
1639
 
                                }
1640
 
                        }
1641
 
                } else {
1642
 
                        for (i = 0; i < 256; i++) {
1643
 
                                ip = (float)i / 255.0;
1644
 
                                pal[i].r = (((cos(ip * M_PI / 2.0 + M_PI) + 1.0) * 255)*pct + i*dct)*rp_pct + (sin(ip * M_PI / 2.0) * 207 + 48)*rp_dct;
1645
 
                                pal[i].g = (i)*rp_pct + ((cos(ip * M_PI / 2.0 + M_PI) + 1.0) * 255)*rp_dct;
1646
 
                                pal[i].b = ((sin(ip * M_PI / 2.0) * 255 * pct)+((cos(ip * M_PI / 2.0 + M_PI) + 1.0) * 255 * dct))*rp_pct + ((cos(ip * M_PI / 2.0 + M_PI) + 1.0) * 255)*rp_dct;
1647
 
                        }
1648
 
                }
1649
 
        }
1650
 
        
1651
 
        SDL_SetPalette(screen, SDL_PHYSPAL, pal, 0, 256);
1652
 
}
1653
 
 
1654
 
void SetTitlePalette(int curve_start, int curve_end)
1655
 
{
1656
 
        SDL_Color pal[256];
1657
 
        int ec;
1658
 
        int i;
1659
 
        
1660
 
        for (i = 0; i < 256; i++) {
1661
 
                ec = (i - curve_start) * 255 / (curve_end-curve_start);
1662
 
                if (ec < 0) ec = 0;
1663
 
                if (ec > 255) ec = 255;
1664
 
                
1665
 
                pal[i].r = ec;
1666
 
                pal[i].g = ec;
1667
 
                pal[i].b = ec;
1668
 
        }
1669
 
        
1670
 
        SDL_SetPalette(screen, SDL_PHYSPAL, pal, 0, 256);
1671
 
}
1672
 
 
1673
 
void SetTitlePalette2(int t)
1674
 
{
1675
 
        SDL_Color pal[256];
1676
 
        int i;
1677
 
        
1678
 
        float ip;
1679
 
        float bright;
1680
 
        float b_coeff;
1681
 
        
1682
 
        bright = 1 - ((float)t / 30.0);
1683
 
        if (bright < 0.0) bright = 0.0;
1684
 
        b_coeff = 1 - bright;
1685
 
        
1686
 
        for (i = 0; i < 256; i++) {
1687
 
                ip = (float)i / 255.0;
1688
 
                pal[i].r = (cos(ip * M_PI / 2.0 + M_PI) + 1.0) * 255 * b_coeff + 255*bright;
1689
 
                pal[i].g = (sin(ip * M_PI / 2.0) * 255 + i) / 2 * b_coeff + 255*bright;
1690
 
                pal[i].b = sin(ip * M_PI / 2.0) * 255 * b_coeff + 255*bright;
1691
 
        }
1692
 
        
1693
 
        SDL_SetPalette(screen, SDL_PHYSPAL, pal, 0, 256);
1694
 
}
1695
 
 
1696
 
int IsSolid(unsigned char tile)
1697
 
{
1698
 
        return TileData[tile].Is_Solid;
1699
 
}
1700
 
 
1701
 
void ActivateBossDoor(int x, int y)
1702
 
{
1703
 
        static int bd_timer = 0;
1704
 
        int bx = x, by = y;
1705
 
        
1706
 
        // find boss room
1707
 
        if (rooms[GetRoom(x+1, y)].room_type == 2) {
1708
 
                bx += 1;
1709
 
        } else
1710
 
                if (rooms[GetRoom(x-1, y)].room_type == 2) {
1711
 
                bx -= 1;
1712
 
        } else
1713
 
                if (rooms[GetRoom(x, y+1)].room_type == 2) {
1714
 
                by += 1;
1715
 
        } else
1716
 
                if (rooms[GetRoom(x, y-1)].room_type == 2) {
1717
 
                by -= 1;
1718
 
        } else
1719
 
                return;
1720
 
        
1721
 
        if (artifacts[8 + rooms[GetRoom(bx, by)].room_param]) {
1722
 
                opening_door_x = x;
1723
 
                opening_door_y = y;
1724
 
                opening_door_i = 1;
1725
 
                opening_door_n = rooms[GetRoom(bx, by)].room_param;
1726
 
                if ((SDL_GetTicks() - bd_timer) > 100) {
1727
 
                        SND_Pos("dat/a/crystal2.wav", 100, 0);
1728
 
                        bd_timer = SDL_GetTicks();
1729
 
                }
1730
 
        }
1731
 
}
1732
 
 
1733
 
int TouchTile(int ix, int iy)
1734
 
{
1735
 
                int i;
1736
 
                int off_x, off_y;
1737
 
                int ret = 1;
1738
 
                unsigned char tile;
1739
 
                
1740
 
                for (i = 0; i < 4; i++) {
1741
 
                        off_x = 15*(i%2);
1742
 
                        off_y = 23*(i/2);
1743
 
 
1744
 
                        tile = Get((ix+off_x)/32, (iy+off_y)/32);
1745
 
                        switch (tile) {
1746
 
                                case 38:
1747
 
                                case 39:
1748
 
                                case 40:
1749
 
                                case 41:
1750
 
                                        ActivateBossDoor((ix+off_x)/32, (iy+off_y)/32);
1751
 
                                        ret = 0;
1752
 
                                        break;
1753
 
                                case 13:
1754
 
                                        player_x = (ix + off_x) / 32 * 32 + 8;
1755
 
                                        player_y = (iy/32 + 2)*32 + 32;
1756
 
                                        return 1;
1757
 
                                        break;
1758
 
                                case 14:
1759
 
                                        player_x = (ix + off_x) / 32 * 32 + 8;
1760
 
                                        player_y = (iy/32 - 2)*32 + 8;
1761
 
                                        return 1;
1762
 
                                        break;
1763
 
                                case 15:
1764
 
                                        player_x = (ix/32 + 2)*32 + 32;
1765
 
                                        player_y = (iy + off_y) / 32 * 32 + 4;
1766
 
                                        return 1;
1767
 
                                        break;
1768
 
                                case 16:
1769
 
                                        player_x = (ix/32 - 2)*32 + 16;
1770
 
                                        player_y = (iy + off_y) / 32 * 32 + 4;
1771
 
                                        return 1;
1772
 
                                        break;
1773
 
                                default:
1774
 
                                        if (TileData[tile].Is_Solid) ret = 0;
1775
 
                                        //ret = 0;
1776
 
                                        break;
1777
 
                        }
1778
 
                }
1779
 
                if (ret == 1) {
1780
 
                        player_x = ix;
1781
 
                        player_y = iy;
1782
 
                }
1783
 
                return ret;
1784
 
}
1785
 
 
1786
 
void text_init()
1787
 
{
1788
 
        FILE *font_data_file;
1789
 
        int chr, x, y;
1790
 
        font_data_file = fopen("dat/d/font.dat", "rb");
1791
 
        
1792
 
        for (chr = 0; chr < 128; chr++) {
1793
 
                for (y = 0; y < 8; y++) {
1794
 
                        for (x = 0; x < 8; x++) {
1795
 
                                font_data[chr][x][y] = fgetc(font_data_file);
1796
 
                        }
1797
 
                }
1798
 
        }
1799
 
 
1800
 
        fclose(font_data_file);
1801
 
}
1802
 
 
1803
 
void draw_char(int cur_x, int cur_y, int c, Uint8 tcol)
1804
 
{
1805
 
        int px, py;
1806
 
        Uint8 *pix;
1807
 
        
1808
 
        for (py = 0; py < 8; py++) {
1809
 
                pix = (Uint8 *)screen->pixels;
1810
 
                pix += (py+cur_y)*screen->w;
1811
 
                pix += cur_x;
1812
 
                
1813
 
                if ((cur_x >= 0)&&(py+cur_y >= 0)&&(cur_x < screen->w-8)&&(py+cur_y < screen->h)) {
1814
 
                        for (px = 0; px < 8; px++) {
1815
 
                                if (font_data[c][px][py] == 255) {
1816
 
                                        *pix = tcol;
1817
 
                                }
1818
 
                                if ((font_data[c][px][py] < 255)&&(font_data[c][px][py] > 0)) {
1819
 
                                        *pix = ((int)tcol * font_data[c][px][py] / 256) + ((int)*pix * (256-font_data[c][px][py]) / 256);
1820
 
                                }
1821
 
                                pix++;
1822
 
                        }
1823
 
                }
1824
 
        }
1825
 
}
1826
 
 
1827
 
void draw_text(int x, int y, char *str, Uint8 tcol)
1828
 
{
1829
 
        int c, cur_x, cur_y;
1830
 
        
1831
 
        cur_x = x;
1832
 
        cur_y = y;
1833
 
 
1834
 
        while (*str != 0) {
1835
 
                c = *(str++);
1836
 
                if (c == '\n') {
1837
 
                        cur_x = x;
1838
 
                        cur_y+=10;
1839
 
                } else {
1840
 
                        draw_char(cur_x, cur_y, c, tcol);
1841
 
                        cur_x+=8;
1842
 
                }
1843
 
        }
1844
 
}
1845
 
 
1846
 
void draw_text_ex(int x, int y, char *str, Uint8 tcol, SDL_Surface *srf)
1847
 
{
1848
 
        Uint8 *pix;
1849
 
        int c, cur_x, cur_y, px, py;
1850
 
        
1851
 
        cur_x = x;
1852
 
        cur_y = y;
1853
 
 
1854
 
        while (*str != 0) {
1855
 
                c = *(str++);
1856
 
                if (c == '\n') {
1857
 
                        cur_x = x;
1858
 
                        cur_y+=8;
1859
 
                } else {
1860
 
                        for (py = 0; py < 8; py++) {
1861
 
                                pix = (Uint8 *)srf->pixels;
1862
 
                                pix += (py+cur_y)*srf->w;
1863
 
                                pix += cur_x;
1864
 
                                for (px = 0; px < 8; px++) {
1865
 
                                        if (font_data[c][px][py]) {
1866
 
                                                *pix = tcol;
1867
 
                                        }
1868
 
                                        pix++;
1869
 
                                }
1870
 
                        }
1871
 
                        cur_x+=8;
1872
 
                }
1873
 
        }
1874
 
}
1875
 
 
1876
 
void LockDoors(int r)
1877
 
{
1878
 
        //printf("Locking room %d...", r);
1879
 
        int x, y;
1880
 
        int rx, ry;
1881
 
        int rt;
1882
 
        int rcount = 0;
1883
 
        
1884
 
        for (y = 0; y < rooms[r].h; y++) {
1885
 
                for (x = 0; x < rooms[r].w; x++) {
1886
 
                        rx = x + rooms[r].x;
1887
 
                        ry = y + rooms[r].y;
1888
 
                        rt = Get(rx, ry);
1889
 
                        
1890
 
                        if ((rt >= 13) && (rt <= 16)) {
1891
 
                                rcount++;
1892
 
                                Put(rx, ry, rt - 13 + 21, r);
1893
 
                        }
1894
 
                }
1895
 
        }
1896
 
        //printf("locked %d doors\n", rcount);
1897
 
}
1898
 
 
1899
 
void ActivateRoom(int room)
1900
 
{
1901
 
        //printf("Activating room %d (type %d)\n", room, rooms[room].room_type);
1902
 
        if (rooms[room].checkpoint) {
1903
 
                checkpoints_found++;
1904
 
        }
1905
 
        if (rooms[room].room_type == 3) {
1906
 
                // lock the doors!
1907
 
                LockDoors(room);
1908
 
        }
1909
 
        ActivateEnemies(room);
1910
 
}
1911
 
 
1912
 
void DrawRect(int x, int y, int w, int h, unsigned char c)
1913
 
{
1914
 
        SDL_Rect r;
1915
 
 
1916
 
        r.x = x;
1917
 
        r.y = y;
1918
 
        r.w = w;
1919
 
        r.h = h;
1920
 
 
1921
 
        SDL_FillRect(screen, &r, c);
1922
 
}
1923
 
 
1924
 
void DrawCircuit()
1925
 
{
1926
 
        int vd = 520;
1927
 
        char buf[20];
1928
 
 
1929
 
        if (magic_circuit != 0) {
1930
 
                DrawRect(110, 469, 8+abs(magic_circuit) * vd / circuit_size, 9, (magic_circuit > 0) ? 159 : 72);
1931
 
                DrawRect(111, 470, 6+abs(magic_circuit) * vd / circuit_size, 7, (magic_circuit > 0) ? 183 : 80);
1932
 
                DrawRect(112, 471, 4+abs(magic_circuit) * vd / circuit_size, 5, (magic_circuit > 0) ? 207 : 96);
1933
 
                DrawRect(113, 472, 2+abs(magic_circuit) * vd / circuit_size, 3, (magic_circuit > 0) ? 231 : 112);
1934
 
                DrawRect(114, 473, abs(magic_circuit) * vd / circuit_size, 1, (magic_circuit > 0) ? 255 : 128);
1935
 
        }
1936
 
        sprintf(buf, "%.1f", fabs((float)magic_circuit / 100.0));
1937
 
        draw_text(115, 470, buf, 0);
1938
 
        draw_text(3, 469, "Psi Circuit", 200);
1939
 
}
1940
 
 
1941
 
void ReleaseCircuit()
1942
 
{
1943
 
        circuit_release = 1;
1944
 
        release_range = circuit_range;
1945
 
        release_x = player_x;
1946
 
        release_y = player_y;
1947
 
        release_str = magic_circuit;
1948
 
        if (circuit_fillrate==30) {
1949
 
                release_str *= 1.25;
1950
 
        }
1951
 
        
1952
 
        SND_CircuitRelease(release_str);
1953
 
        magic_circuit *= -1;
1954
 
}
1955
 
 
1956
 
void DrawCircle(int x, int y, int r, unsigned char c)
1957
 
{
1958
 
        int circ_y;
1959
 
 
1960
 
        int len_x, outer_len_x, inner_len_x;
1961
 
 
1962
 
        int inner_r = r - 10;
1963
 
        if (inner_r < 1) inner_r = 1;
1964
 
 
1965
 
        if (r < 1) return;
1966
 
        // a^2 + b^2 = c^2
1967
 
        for (circ_y = 0; circ_y < r; circ_y++) {
1968
 
                if (circ_y < (r-10)) {
1969
 
                        outer_len_x = sqrt(r*r - circ_y*circ_y);
1970
 
                        inner_len_x = sqrt((r-10)*(r-10) - circ_y*circ_y);
1971
 
                        DrawRect(x - outer_len_x, y - circ_y, (outer_len_x - inner_len_x), 1, c);
1972
 
                        DrawRect(x + inner_len_x, y - circ_y, (outer_len_x - inner_len_x), 1, c);
1973
 
                        DrawRect(x - outer_len_x, y + circ_y, (outer_len_x - inner_len_x), 1, c);
1974
 
                        DrawRect(x + inner_len_x, y + circ_y, (outer_len_x - inner_len_x), 1, c);
1975
 
                } else {
1976
 
                        len_x = sqrt(r*r - circ_y*circ_y);
1977
 
                
1978
 
                        DrawRect(x - len_x, y - circ_y, len_x*2, 1, c);
1979
 
                        DrawRect(x - len_x, y + circ_y, len_x*2, 1, c);
1980
 
                }
1981
 
        }
1982
 
}
1983
 
 
1984
 
void DrawCircleEx(int x, int y, int r, int r2, unsigned char c)
1985
 
{
1986
 
        int circ_y;
1987
 
 
1988
 
        int len_x, outer_len_x, inner_len_x;
1989
 
 
1990
 
        int inner_r = r2;
1991
 
        int diffi = r-r2;
1992
 
        if (inner_r < 1) inner_r = 1;
1993
 
 
1994
 
 
1995
 
 
1996
 
        if (r < 1) return;
1997
 
        // a^2 + b^2 = c^2
1998
 
        for (circ_y = 0; circ_y < r; circ_y++) {
1999
 
                if (circ_y < (r-diffi)) {
2000
 
                        outer_len_x = sqrt(r*r - circ_y*circ_y);
2001
 
                        inner_len_x = sqrt((r-diffi)*(r-diffi) - circ_y*circ_y);
2002
 
                        DrawRect(x - outer_len_x, y - circ_y, (outer_len_x - inner_len_x), 1, c);
2003
 
                        DrawRect(x + inner_len_x, y - circ_y, (outer_len_x - inner_len_x), 1, c);
2004
 
                        DrawRect(x - outer_len_x, y + circ_y, (outer_len_x - inner_len_x), 1, c);
2005
 
                        DrawRect(x + inner_len_x, y + circ_y, (outer_len_x - inner_len_x), 1, c);
2006
 
                } else {
2007
 
                        len_x = sqrt(r*r - circ_y*circ_y);
2008
 
                
2009
 
                        DrawRect(x - len_x, y - circ_y, len_x*2, 1, c);
2010
 
                        DrawRect(x - len_x, y + circ_y, len_x*2, 1, c);
2011
 
                }
2012
 
        }
2013
 
}
2014
 
 
2015
 
void DrawShield()
2016
 
{
2017
 
        static int t=0;
2018
 
        int s_size;
2019
 
        int belts = 0;
2020
 
        int i, bpos;
2021
 
        t++;
2022
 
        
2023
 
        if (player_shield == 0) return;
2024
 
        if (shield_hp == 0) return;
2025
 
        
2026
 
        s_size = shield_hp;
2027
 
        if (s_size > 15) {
2028
 
                belts = s_size - 15;
2029
 
                s_size = 15;
2030
 
        }
2031
 
        DrawCircleEx(320, 240, 28+s_size, 28-s_size, 128 + (shield_hp*127/player_shield) - (50*(shield_hp<player_shield) + shield_recover) - 45 + ((t%4)*15));
2032
 
        
2033
 
        for (i = 0; i < belts; i++) {
2034
 
                bpos = 13 + (30 * (i+1) / (belts+1));
2035
 
                DrawCircleEx(320, 240, bpos + 1, bpos - 1, ((i+t)%6*12));
2036
 
        }
2037
 
}
2038
 
 
2039
 
void ST_Teleport()
2040
 
{
2041
 
}
2042
 
 
2043
 
int UpgradePrice(int t)
2044
 
{
2045
 
        int price = 0;
2046
 
        switch (t) {
2047
 
                case 0:
2048
 
                        price = (100 - training*50) * player_shield + (5<<player_shield) * (5 - training*2);
2049
 
                        break;
2050
 
                case 1:
2051
 
                        price = (80 - training*40) * circuit_fillrate + (5<<circuit_fillrate) * (4 - training*2);
2052
 
                        break;
2053
 
                case 2:
2054
 
                        price = (80 - training*40) * circuit_recoverrate + (5<<circuit_recoverrate) * (4 - training*2);
2055
 
                        break;
2056
 
                default:
2057
 
                        price = 123;
2058
 
                        break;
2059
 
        }
2060
 
 
2061
 
        return price;
2062
 
}
2063
 
 
2064
 
void RoomTreasure(int room, int typ)
2065
 
{
2066
 
        int treasure;
2067
 
        int given_treasure = 0;
2068
 
        
2069
 
        if (typ == 0) {
2070
 
                // Treasure
2071
 
                treasure = rooms[room].room_param;
2072
 
                artifacts[treasure] = 1;
2073
 
                specialmessage = treasure + 1;
2074
 
                specialmessagetimer = 30;
2075
 
                SND_Pos("dat/a/crystal2.wav", 128, 0);
2076
 
        }
2077
 
        if (typ == 1) {
2078
 
                // Reward
2079
 
                while (!given_treasure) {
2080
 
                        treasure = rand() % 4;
2081
 
                        
2082
 
                        switch (treasure) {
2083
 
                                case 0:
2084
 
                                        specialmessage = 20;
2085
 
                                        player_gems += rand()%((1 << (rooms[room].s_dist / 7)) * 1500);
2086
 
                                        given_treasure = 1;
2087
 
                                        SND_Pos("dat/a/tone.wav", 128, 0);
2088
 
                                        break;
2089
 
                                case 1:
2090
 
                                        if (player_shield < 25) {
2091
 
                                                specialmessage = 10;
2092
 
                                                player_shield += 1;
2093
 
                                                given_treasure = 1;
2094
 
                                                SND_Pos("dat/a/tone.wav", 128, 0);
2095
 
                                        }
2096
 
                                        break;
2097
 
                                case 2:
2098
 
                                        if (circuit_fillrate < 25) {
2099
 
                                                specialmessage = 11;
2100
 
                                                circuit_fillrate += 1;
2101
 
                                                given_treasure = 1;
2102
 
                                                SND_Pos("dat/a/tone.wav", 128, 0);
2103
 
                                        }
2104
 
                                        break;
2105
 
                                case 3:
2106
 
                                        if (circuit_recoverrate < 25) {
2107
 
                                                specialmessage = 12;
2108
 
                                                circuit_recoverrate += 1;
2109
 
                                                given_treasure = 1;
2110
 
                                                SND_Pos("dat/a/tone.wav", 128, 0);
2111
 
                                        }
2112
 
                                        break;
2113
 
                                default:
2114
 
                                        break;
2115
 
                        }
2116
 
                }
2117
 
                specialmessagetimer = 30;
2118
 
        }
2119
 
}
2120
 
 
2121
 
int GetNearestCheckpoint(int nx, int ny)
2122
 
{
2123
 
        int i;
2124
 
        int nearest_checkpoint = -1;
2125
 
        int nearest_dist = 10000000;
2126
 
        int cp_x, cp_y, cp_dist;
2127
 
        int room_chk[3000] = {0};
2128
 
        int x, y, rx, ry;
2129
 
 
2130
 
        i = GetRoom(nx/32, ny/32);
2131
 
        if (i != -1) {
2132
 
                room_chk[i] = 1;
2133
 
                if ((rooms[i].checkpoint != 0)&&(rooms[i].visited!=0)) {
2134
 
                        nearest_checkpoint = i;
2135
 
                }
2136
 
        }
2137
 
        if (nearest_checkpoint == -1) {
2138
 
                                
2139
 
                for (y = 0; y < 54;) {
2140
 
                        for (x = 0; x < 54;) {
2141
 
                                rx = nx/32 - 27 + x;
2142
 
                                ry = ny/32 - 27 + y;
2143
 
                                
2144
 
                                i = GetRoom(rx, ry);
2145
 
                                if (i != -1) {
2146
 
                                        if (room_chk[i] == 0) {
2147
 
                                                room_chk[i] = 1;
2148
 
                                                if ((rooms[i].checkpoint != 0)&&(rooms[i].visited!=0)) {
2149
 
                                                        cp_x = rooms[i].x * 32 + rooms[i].w * 16;
2150
 
                                                        cp_y = rooms[i].y * 32 + rooms[i].h * 16;
2151
 
                                                        cp_dist = dist(cp_x, cp_y, nx, ny);
2152
 
                                                        if (cp_dist < nearest_dist) {
2153
 
                                                                nearest_dist = cp_dist;
2154
 
                                                                nearest_checkpoint = i;
2155
 
                                                        }
2156
 
                                                }
2157
 
                                        }
2158
 
                                }
2159
 
                                x += 2;
2160
 
                        }
2161
 
                        y += 2;
2162
 
                }
2163
 
                
2164
 
        }
2165
 
        
2166
 
        return nearest_checkpoint;
2167
 
}
2168
 
 
2169
 
void TeleportPlayerToRoom(int c_room)
2170
 
{
2171
 
        if (c_room == 0) {
2172
 
                player_x = 8232;
2173
 
                player_y = 8108;
2174
 
        } else {
2175
 
                player_x = rooms[c_room].x * 32 + (rooms[c_room].w / 2 * 32) + 8;
2176
 
                player_y = rooms[c_room].y * 32 + (rooms[c_room].h / 2 * 32) + 4;
2177
 
        }
2178
 
        c_scroll_x = player_x;
2179
 
        c_scroll_y = player_y;
2180
 
        scroll_home = 1;
2181
 
}
2182
 
 
2183
 
 
2184
 
void TeleportPlayerToNextRoom()
2185
 
{
2186
 
        int c_room;
2187
 
        c_room = (player_room + 1) % 3000;
2188
 
        while (! ((rooms[c_room].checkpoint!=0)&&(rooms[c_room].visited!=0))) {
2189
 
                c_room = (c_room + 1) % 3000;
2190
 
        }
2191
 
        
2192
 
        if (c_room == 0) {
2193
 
                player_x = 8232;
2194
 
                player_y = 8108;
2195
 
        } else {
2196
 
                player_x = rooms[c_room].x * 32 + (rooms[c_room].w / 2 * 32) + 8;
2197
 
                player_y = rooms[c_room].y * 32 + (rooms[c_room].h / 2 * 32) + 4;
2198
 
        }
2199
 
        c_scroll_x = player_x;
2200
 
        c_scroll_y = player_y;
2201
 
        scroll_home = 1;
2202
 
}
2203
 
 
2204
 
void ActivateTile(unsigned char tile, int x, int y)
2205
 
{
2206
 
        int c_room;
2207
 
        
2208
 
        enter_pressed = 0;
2209
 
        switch (tile) {
2210
 
                case 25:
2211
 
                        if (artifacts[11]) break;
2212
 
 
2213
 
                        c_room = GetNearestCheckpoint(c_scroll_x, c_scroll_y);
2214
 
                        if (tele_select) {
2215
 
                                if (c_room != -1) {
2216
 
                                        if (c_room == player_room) {
2217
 
                                                TeleportPlayerToNextRoom();
2218
 
                                        } else {
2219
 
                                                TeleportPlayerToRoom(c_room);
2220
 
                                        }
2221
 
                                }
2222
 
                        } else {
2223
 
                                map_enabled = 1;
2224
 
                                game_paused = 1;
2225
 
                                tele_select = 1;
2226
 
                                
2227
 
                                c_scroll_x = player_x;
2228
 
                                c_scroll_y = player_y;
2229
 
                        }
2230
 
                        
2231
 
                        break;
2232
 
                case 26:
2233
 
                        RoomTreasure(GetRoom(x, y), (x+y)%2);
2234
 
                        Put(x, y, 27, GetRoom(x, y));
2235
 
                        break;
2236
 
                case 28:
2237
 
                        if (player_shield >= 24) return;
2238
 
                        if (player_gems >= UpgradePrice(0)) {
2239
 
                                player_gems -= UpgradePrice(0);
2240
 
                                player_shield += 1;
2241
 
                                SND_Pos("dat/a/crystal.wav", 128, 0);
2242
 
                        }
2243
 
                        break;
2244
 
                case 29:
2245
 
                        if (circuit_fillrate >= 24) return;
2246
 
                        if (player_gems >= UpgradePrice(1)) {
2247
 
                                player_gems -= UpgradePrice(1);
2248
 
                                circuit_fillrate += 1;
2249
 
                                SND_Pos("dat/a/crystal.wav", 128, 0);
2250
 
                        }
2251
 
                        break;
2252
 
                case 30:
2253
 
                        if (circuit_recoverrate >= 24) return;
2254
 
                        if (player_gems >= UpgradePrice(2)) {
2255
 
                                player_gems -= UpgradePrice(2);
2256
 
                                circuit_recoverrate += 1;
2257
 
                                SND_Pos("dat/a/crystal.wav", 128, 0);
2258
 
                        }
2259
 
                        break;
2260
 
                case 31:
2261
 
                        DoSaveGame();
2262
 
                        break;
2263
 
                case 32:
2264
 
                        CrystalSummon();
2265
 
                        SND_Pos("dat/a/crystal.wav", 80, 0);
2266
 
                        break;
2267
 
                default:
2268
 
                        break;
2269
 
        }
2270
 
}
2271
 
 
2272
 
void CompassPoint()
2273
 
{
2274
 
        int nearest = 1000000;
2275
 
        int n_room = -1;
2276
 
        int i;
2277
 
        int loc_x, loc_y;
2278
 
        int cdist;
2279
 
        int rplx, rply;
2280
 
        int bosses_defeated = current_boss;
2281
 
        float pdir_1 = 0;
2282
 
        float pdir_2 = 0;
2283
 
        int pdir_1t = 0, pdir_2t = 0;
2284
 
        
2285
 
        rplx = player_x + PLAYERW/2;
2286
 
        rply = player_y + PLAYERH/2;
2287
 
        // Find the nearest SIGNIFICANT LOCATION for the player
2288
 
        
2289
 
        // Look at the three artifacts
2290
 
        // Unless the player is going for the place of power
2291
 
        
2292
 
        if (current_boss < 3) {
2293
 
                for (i = 0; i < 3; i++) {
2294
 
                        // Has the player got this artifact already?
2295
 
                        if (artifacts[8+i] == 0) { // no
2296
 
                                // Has the player already destroyed the boss?
2297
 
                                if (rooms[i * 1000 + 999].room_type == 2) { // no
2298
 
                                        // Can the player get the artifact?
2299
 
                                        if (CanGetArtifact()) {
2300
 
                                                // Point player to this artifact room, if it is the nearest
2301
 
                                                loc_x = rooms[i * 1000 + 499].x * 32 + rooms[i * 1000 + 499].w * 16;
2302
 
                                                loc_y = rooms[i * 1000 + 499].y * 32 + rooms[i * 1000 + 499].h * 16;
2303
 
                                                cdist = dist(rplx, rply, loc_x, loc_y);
2304
 
                                                if (cdist < nearest) {
2305
 
                                                        nearest = cdist;
2306
 
                                                        n_room = i * 1000 + 499;
2307
 
                                                }
2308
 
                                        }
2309
 
                                }
2310
 
                        } else { // has artifact
2311
 
                                // Has the player already destroyed the boss?
2312
 
                                if (rooms[i * 1000 + 999].room_type == 2) { // no
2313
 
                                        // Point player to the boss room, if it is the nearest
2314
 
                                        loc_x = rooms[i * 1000 + 999].x * 32 + rooms[i * 1000 + 999].w * 16;
2315
 
                                        loc_y = rooms[i * 1000 + 999].y * 32 + rooms[i * 1000 + 999].h * 16;
2316
 
                                        cdist = dist(rplx, rply, loc_x, loc_y);
2317
 
                                        if (cdist < nearest) {
2318
 
                                                nearest = cdist;
2319
 
                                                n_room = i * 1000 + 999;
2320
 
                                        }
2321
 
                                } else { // yes
2322
 
                                        bosses_defeated++;
2323
 
                                }
2324
 
                        }
2325
 
                }
2326
 
        }
2327
 
        // If, on the other hand, the player has destroyed all three bosses, point them towards the
2328
 
        // PLACE OF POWER
2329
 
        if (bosses_defeated == 3) {
2330
 
                // If the player already has the seal, point them to home
2331
 
                if (artifacts[11] == 1) {
2332
 
                        loc_x = rooms[0].x * 32 + rooms[0].w * 16;
2333
 
                        loc_y = rooms[0].y * 32 + rooms[0].h * 16;
2334
 
                        cdist = dist(rplx, rply, loc_x, loc_y);
2335
 
                        if (cdist < nearest) {
2336
 
                                nearest = cdist;
2337
 
                                n_room = 0;
2338
 
                        }
2339
 
                } else {
2340
 
                        // Can the player touch the seal?
2341
 
                        if (CanGetArtifact()) {
2342
 
                                loc_x = rooms[place_of_power].x * 32 + rooms[place_of_power].w * 16;
2343
 
                                loc_y = rooms[place_of_power].y * 32 + rooms[place_of_power].h * 16;
2344
 
                                cdist = dist(rplx, rply, loc_x, loc_y);
2345
 
                                if (cdist < nearest) {
2346
 
                                        nearest = cdist;
2347
 
                                        n_room = place_of_power;
2348
 
                                }
2349
 
                        }
2350
 
                }
2351
 
        }
2352
 
        
2353
 
        // Did we find a room? If so, point to it
2354
 
        
2355
 
        if (n_room != -1) {
2356
 
                loc_x = rooms[n_room].x * 32 + rooms[n_room].w * 16;
2357
 
                loc_y = rooms[n_room].y * 32 + rooms[n_room].h * 16;
2358
 
        
2359
 
                pdir_1 = PlayerDir(loc_x, loc_y) + M_PI;
2360
 
                pdir_1t = 1;
2361
 
                
2362
 
                n_room = -1;
2363
 
        }
2364
 
        
2365
 
        nearest = 1000000;
2366
 
        // Find the nearest uncleared artifact room
2367
 
        for (i = 0; i < 3000; i++) {
2368
 
                if (rooms[i].room_type == 3) {
2369
 
                        loc_x = rooms[i].x * 32 + rooms[i].w * 16;
2370
 
                        loc_y = rooms[i].y * 32 + rooms[i].h * 16;
2371
 
                        cdist = dist(rplx, rply, loc_x, loc_y);
2372
 
                        if (cdist < nearest) {
2373
 
                                nearest = cdist;
2374
 
                                n_room = i;
2375
 
                        }
2376
 
                }
2377
 
        }
2378
 
        
2379
 
        if (n_room != -1) {
2380
 
                loc_x = rooms[n_room].x * 32 + rooms[n_room].w * 16;
2381
 
                loc_y = rooms[n_room].y * 32 + rooms[n_room].h * 16;
2382
 
        
2383
 
                pdir_2 = PlayerDir(loc_x, loc_y) + M_PI;
2384
 
                pdir_2t = 1;
2385
 
                
2386
 
                n_room = -1;
2387
 
        }
2388
 
        
2389
 
        // Did we find at least one thing to point to? If not, abort
2390
 
        if (!(pdir_1t || pdir_2t))
2391
 
                return;
2392
 
        
2393
 
        DrawCircleEx(rplx - scroll_x, rply - scroll_y, 200, 190, 255);
2394
 
        if (pdir_1t)
2395
 
                DrawCircleEx(rplx - scroll_x + cos(pdir_1) * 170, rply - scroll_y + sin(pdir_1) * 170, 30, 20, 255);
2396
 
        if (pdir_2t)
2397
 
                DrawCircleEx(rplx - scroll_x + cos(pdir_2) * 170, rply - scroll_y + sin(pdir_2) * 170, 30, 20, 195);
2398
 
                
2399
 
        for (i = 0; i < 50; i++) {
2400
 
                if (pdir_1t)
2401
 
                        DrawCircle(rplx - scroll_x + cos(pdir_1) * (25 + i * 4), rply - scroll_y + sin(pdir_1) * (25 + i * 4), 5, 255);
2402
 
                if (pdir_2t)
2403
 
                        DrawCircle(rplx - scroll_x + cos(pdir_2) * (25 + i * 4), rply - scroll_y + sin(pdir_2) * (25 + i * 4), 5, 195);
2404
 
        }
2405
 
        DrawCircleEx(rplx - scroll_x, rply - scroll_y, 30, 20, 255);
2406
 
        
2407
 
        DrawCircleEx(rplx - scroll_x, rply - scroll_y, 197, 193, 128);
2408
 
        if (pdir_1t)
2409
 
                DrawCircleEx(rplx - scroll_x + cos(pdir_1) * 170, rply - scroll_y + sin(pdir_1) * 170, 27, 23, 128);
2410
 
        if (pdir_2t)
2411
 
                DrawCircleEx(rplx - scroll_x + cos(pdir_2) * 170, rply - scroll_y + sin(pdir_2) * 170, 27, 23, 78);
2412
 
        
2413
 
        for (i = 0; i < 50; i++) {
2414
 
                if (pdir_1t)
2415
 
                        DrawCircle(rplx - scroll_x + cos(pdir_1) * (25 + i * 4), rply - scroll_y + sin(pdir_1) * (25 + i * 4), 3, 128);
2416
 
                if (pdir_2t)
2417
 
                        DrawCircle(rplx - scroll_x + cos(pdir_2) * (25 + i * 4), rply - scroll_y + sin(pdir_2) * (25 + i * 4), 3, 78);
2418
 
        }
2419
 
        DrawCircleEx(rplx - scroll_x, rply - scroll_y, 27, 23, 128);
2420
 
}
2421
 
 
2422
 
void SpecialTile(int x, int y)
2423
 
{
2424
 
        static int otext = 0;
2425
 
        static int t = 0;
2426
 
        unsigned char tile;
2427
 
        char message[100] = "";
2428
 
 
2429
 
        tile = Get(x, y);
2430
 
        switch (tile) {
2431
 
                case 25:
2432
 
                        if (artifacts[11]) {
2433
 
                                sprintf(message, "This is a checkpoint, but it doesn't seem to be working");
2434
 
                                break;
2435
 
                        }
2436
 
                        if (checkpoints_found <= 1) {
2437
 
                                sprintf(message, "This is a checkpoint. You will return here when you die.");
2438
 
                        } else {
2439
 
                                sprintf(message, "Press ENTER to teleport between checkpoints.");
2440
 
                        }
2441
 
                        break;
2442
 
                case 26:
2443
 
                        sprintf(message, "Press ENTER to open the storage chest");
2444
 
                        break;
2445
 
                case 28:
2446
 
                        if (player_shield >= 25) {
2447
 
                                sprintf(message, "Your shield is already at full efficiency");
2448
 
                        } else {
2449
 
                                sprintf(message, "Press ENTER to upgrade shields (%d crystals)", UpgradePrice(0));
2450
 
                        }
2451
 
                        break;
2452
 
                case 29:
2453
 
                        if (circuit_fillrate >= 25) {
2454
 
                                sprintf(message, "Your circuit charge rate is already at its highest");
2455
 
                        } else {
2456
 
                                sprintf(message, "Press ENTER to upgrade circuit charge (%d crystals)", UpgradePrice(1));
2457
 
                        }
2458
 
                        break;
2459
 
                case 30:
2460
 
                        if (circuit_recoverrate >= 25) {
2461
 
                                sprintf(message, "Your circuit refill rate is already at its highest");
2462
 
                        } else {
2463
 
                                sprintf(message, "Press ENTER to upgrade circuit refill (%d crystals)", UpgradePrice(2));
2464
 
                        }
2465
 
                        break;
2466
 
                case 31:
2467
 
                        sprintf(message, "Press ENTER to record your progress");
2468
 
                        break;
2469
 
                case 32:
2470
 
                        if (total_gems == 0) {
2471
 
                                sprintf(message, "This is a crystal device. It isn't working at the moment.");
2472
 
                        } else {
2473
 
                                sprintf(message, "Press ENTER to activate the crystal device");
2474
 
                        }
2475
 
                        break;
2476
 
                case 42:
2477
 
                        if (rooms[player_room].room_type == 5) {
2478
 
                                if (CanGetArtifact(rooms[player_room].room_param)) {
2479
 
                                        
2480
 
                                } else {
2481
 
                                        sprintf(message, "The artifact is tainted with shadow. You must slay more of the shadow first.");
2482
 
                                }
2483
 
                        }
2484
 
                        break;
2485
 
                case 53:
2486
 
                        CompassPoint();
2487
 
                        break;
2488
 
                default:
2489
 
                        if (first_game) {
2490
 
                                if (otext < 60) {
2491
 
                                        sprintf(message, "Press H to read the help file");
2492
 
                                        otext++;
2493
 
                                }
2494
 
                        }
2495
 
                        break;
2496
 
        }
2497
 
        
2498
 
        if (message[0] == 0) {
2499
 
                if (specialmessage != 0) {
2500
 
                        switch (specialmessage) {
2501
 
                                case 1: sprintf(message, "Ancient artifact: Complete Map"); break;
2502
 
                                case 2: sprintf(message, "Ancient artifact: Shield boost"); break;
2503
 
                                case 3: sprintf(message, "Ancient artifact: Extra crystal efficiency"); break;
2504
 
                                case 4: sprintf(message, "Ancient artifact: Circuit booster"); break;
2505
 
                                case 5: sprintf(message, "Ancient artifact: Metabolism increase"); break;
2506
 
                                case 6: sprintf(message, "Ancient artifact: Dodge enhancer"); break;
2507
 
                                case 7: sprintf(message, "Ancient artifact: Ethereal Monocle"); break;
2508
 
                                case 8: sprintf(message, "Ancient artifact: Crystal gatherer"); break;
2509
 
                                
2510
 
                                case 10: sprintf(message, "Enhancement: Shield upgrade"); break;
2511
 
                                case 11: sprintf(message, "Enhancement: Circuit charge upgrade"); break;
2512
 
                                case 12: sprintf(message, "Enhancement: Circuit refill upgrade"); break;
2513
 
                                
2514
 
                                case 20: sprintf(message, "Reward: Psi crystals"); break;
2515
 
                                
2516
 
                                case 30: sprintf(message, "Holy Sword 'Balmung' answers your call"); break;
2517
 
                                case 31: sprintf(message, "Mystic Halberd 'Amenonuhoko' answers your call"); break;
2518
 
                                case 32: sprintf(message, "Divine Bow 'Gandiva' answers your call"); break;
2519
 
                                case 33: sprintf(message, "You capture the cursed seal. Return to the entrance"); break;
2520
 
                                
2521
 
                                case 40: sprintf(message, "Balmung will remain here, where the ley lines are strong"); break;
2522
 
                                case 41: sprintf(message, "Amenonuhoko will remain here, where the ley lines are strong"); break;
2523
 
                                case 42: sprintf(message, "Gandiva will remain here, where the ley lines are strong"); break;
2524
 
                                
2525
 
                                case 50: sprintf(message, ". . . . . .   retrieved 'Agate Knife'"); break;
2526
 
                                
2527
 
                                default: sprintf(message, "ERROR: NO MESSAGE VALUE GIVEN"); break;
2528
 
                        }
2529
 
                        specialmessagetimer--;
2530
 
                        if (specialmessagetimer <= 0) {
2531
 
                                specialmessage = 0;
2532
 
                        }
2533
 
                }
2534
 
        }
2535
 
        
2536
 
        if (message[0] == 0) return;
2537
 
        
2538
 
        DrawRect(320 - strlen(message)*8 / 2 - 20, 100, strlen(message)*8+40, 48, 200);
2539
 
        DrawRect(320 - strlen(message)*8 / 2 - 15, 105, strlen(message)*8+30, 38, 32);
2540
 
        DrawRect(320 - strlen(message)*8 / 2 - 10, 110, strlen(message)*8+20, 28, 64);
2541
 
 
2542
 
        draw_text(320 - strlen(message)*8 / 2, 120, message, t%16<8 ? 255 : 192);
2543
 
        t++;
2544
 
        if (enter_pressed) {
2545
 
                ActivateTile(tile, x, y);
2546
 
        }
2547
 
}
2548
 
 
2549
 
void ScrollTo(int x, int y)
2550
 
{
2551
 
        static int scrollspeed_x = 1, scrollspeed_y = 1;
2552
 
        if (scroll_home == 0) {
2553
 
                scroll_x = x;
2554
 
                scroll_y = y;
2555
 
                return;
2556
 
        }
2557
 
 
2558
 
        if (scroll_home == 1) {
2559
 
                scrollspeed_x = (x - scroll_x)/20;
2560
 
                scrollspeed_y = (y - scroll_y)/20;
2561
 
                scroll_home = 2;
2562
 
        }
2563
 
 
2564
 
        if (scroll_home == 2) {
2565
 
                scroll_x += (x - scroll_x)/2;
2566
 
                scroll_y += (y - scroll_y)/2;
2567
 
 
2568
 
                if ((abs(scroll_x-x)<2)&&(abs(scroll_y-y)<2)) {
2569
 
                        scroll_x = x;
2570
 
                        scroll_y = y;
2571
 
                        scroll_home = 0;
2572
 
                }
2573
 
        }
2574
 
}
2575
 
 
2576
 
void DrawArtifacts()
2577
 
{
2578
 
        int i;
2579
 
        SDL_Rect from, to;
2580
 
        
2581
 
        if (artifact_spr == NULL) {
2582
 
                artifact_spr = IMG_Load("dat/i/artifacts.png");
2583
 
                SDL_SetColorKey(artifact_spr, SDL_SRCCOLORKEY | SDL_RLEACCEL, 0);
2584
 
        }
2585
 
        
2586
 
        for (i = 0; i < 12; i++) {
2587
 
                if (artifacts[i]) {
2588
 
                        from.x = i * 32;
2589
 
                        from.y = 0;
2590
 
                        from.w = 32;
2591
 
                        from.h = 32;
2592
 
                        
2593
 
                        to.x = 608;
2594
 
                        to.y = 47 + i * 35;
2595
 
                        SDL_BlitSurface(artifact_spr, &from, screen, &to);
2596
 
                }
2597
 
        }
2598
 
}
2599
 
 
2600
 
void Swap(int *a, int *b)
2601
 
{
2602
 
        *a ^= *b ^= *a ^= *b;
2603
 
}
2604
 
 
2605
 
void ThinLine(SDL_Surface *scr, int x1, int y1, int x2, int y2, Uint8 col)
2606
 
{
2607
 
        int dx, dy, dm;
2608
 
        int i, j;
2609
 
        
2610
 
        dx = (x2 - x1);
2611
 
        dy = (y2 - y1);
2612
 
        
2613
 
        dm = abs(dx) > abs(dy) ? dx : dy;
2614
 
        
2615
 
        if (dm == 0) return;
2616
 
        
2617
 
        if (dm < 0) {
2618
 
                Swap(&x1, &x2);
2619
 
                Swap(&y1, &y2);
2620
 
                dx = (x2 - x1);
2621
 
                dy = (y2 - y1);
2622
 
                
2623
 
                dm = dm * -1;
2624
 
        }
2625
 
 
2626
 
        if (dm == dx) {
2627
 
                if (dy == 0) {
2628
 
                        DrawRect(x1, y1, x2-x1+1, 1, col);
2629
 
                        return;
2630
 
                }
2631
 
                for (i = 0; i < dm; i++) {
2632
 
                        j = (dy * i / dm);
2633
 
                        DrawRect(i+x1, j+y1, 1, 1, col);
2634
 
                }
2635
 
        }
2636
 
        if (dm == dy) {
2637
 
                if (dx == 0) {
2638
 
                        DrawRect(x1, y1, 1, y2-y1+1, col);
2639
 
                        return;
2640
 
                }
2641
 
                for (i = 0; i < dm; i++) {
2642
 
                        j = (dx * i / dm);
2643
 
                        DrawRect(j+x1, i+y1, 1, 1, col);
2644
 
                }
2645
 
        }
2646
 
}