4
// Copyright 2007, 2008 Lancer-X/ASCEAI
6
// This file is part of Meritous.
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.
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.
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/>.
26
#include <SDL_image.h>
29
#include "levelblit.h"
34
void DrawScrolly(int t);
35
void DrawPText(int t);
36
void DrawSText(int t);
37
void DrawSTextV(int t);
38
void DrawCircuitFlash(int t, int method);
39
void DrawStream(int t);
41
void InitParticleStorm();
42
void RunParticleStorm(int offset);
44
SDL_Surface *streamspr = NULL, *glitter = NULL;
46
SDL_Color ending_pal[256];
50
SDL_SetPalette(screen, SDL_PHYSPAL, ending_pal, 0, 256);
55
int credits_scroll = 0;
59
static SDL_Event event;
67
while (SDL_PollEvent(&event)) {
68
if (event.type == SDL_KEYDOWN) {
69
switch (event.key.keysym.sym) {
77
if (event.type == SDL_QUIT) {
89
if (streamspr == NULL) {
90
streamspr = IMG_Load("dat/i/stream.png");
91
SDL_SetColorKey(streamspr, SDL_SRCCOLORKEY | SDL_RLEACCEL, 0);
92
glitter = IMG_Load("dat/i/glitter.png");
93
SDL_SetColorKey(glitter, SDL_SRCCOLORKEY | SDL_RLEACCEL, 0);
96
for (i = 0; i < 500; i += 1) {
97
if (((i % 60) >= 24)&&((i % 60) < 34)) {
98
DrawCircuitFlash((i % 60) - 24, 0);
103
if (EndingEvents()) return;
105
for (i = 0; i < 30; i++) {
106
DrawCircuitFlash(i, 1);
109
if (EndingEvents()) return;
111
SDL_FillRect(screen, NULL, 255);
112
for (i = 0; i < 350; i++) {
115
if (EndingEvents()) return;
118
Paint(0, 0, 22, 27, "dat/d/cstream.loc");
120
if (player_shield < 30) {
121
for (i = 0; i < 400; i++) {
124
if (EndingEvents()) return;
127
for (i = 0; i < 240; i++) {
128
RunParticleStorm(240-i);
130
if (EndingEvents()) return;
132
for (i = 0; i < 60; i++) {
135
if (EndingEvents()) return;
137
for (i = 0; i < 180; i++) {
138
RunParticleStorm(i*3);
140
if (EndingEvents()) return;
142
for (i = 0; i < 500; i++) {
145
if (EndingEvents()) return;
148
for (i = 0; i < 250; i++) {
151
if (EndingEvents()) return;
153
for (i = 0; i < 500; i++) {
156
if (EndingEvents()) return;
164
if (EndingEvents()) return;
168
char *SText[15] = { "Merit released the locks on the PSI flowing through the Dome,",
169
"releasing the flow of PSI into the atmosphere.",
171
"The Orcus Dome was originally built to centralise the limited",
172
"PSI available to everyone. However, this made the existing",
173
"reserves more vulnerable to malicious PSI users",
175
"While other PSI users initially resented Merit for his rash",
176
"behaviour, they eventually adjusted to the decentralisation.",
178
"Eventually, PSI users grew so adept at manipulating the",
179
"diluted flows of PSI that they were capable of the same things",
180
"as before. Each PSI user would keep their own individual",
181
"reserves of PSI for when they needed to weild greater power,",
182
"and the balance of power was restored." };
184
char *STextV[15] = {"Merit decided to assume the role of custodian over the Orcus",
185
"Dome, in Wervyn Anixil's place. He resumed the experiments on",
186
"PSI and found ways of making the Dome's remaining supply go as",
189
"Other PSI users were suspicious of MERIT, just as they were",
190
"wary of Wervyn Anixil before him, but they soon adjusted.",
192
"The balance of power was quickly restored, and stabilised for",
193
"eternity due to the work of Wervyn Anixil and now MERIT.",
196
" [[ BEST ENDING ]]",
200
void DrawSText(int t)
202
int offset = 540 + (t / 2);
207
for (i = 0; i < 64; i++) {
208
DrawRect(0, i * 15 - offset, 640, 15, (64 - i) * cl / 350);
210
for (i = 64; i < 128; i++) {
211
DrawRect(0, i * 15 - offset, 640, 15, (i - 64) * cl / 350);
215
for (i = 0; i < 15; i++) {
216
c = (255 + (i * 100) - t*10);
218
if (c > 255) c = 255;
220
draw_text(68, 150+i*12, SText[i], 255-c);
223
for (i = 0; i < 15; i++) {
226
draw_text(68, 150+i*12, SText[i], 255-c);
233
void DrawSTextV(int t)
235
int offset = 540 + (t / 2);
240
for (i = 0; i < 64; i++) {
241
DrawRect(0, i * 15 - offset, 640, 15, (64 - i) * cl / 350);
243
for (i = 64; i < 128; i++) {
244
DrawRect(0, i * 15 - offset, 640, 15, (i - 64) * cl / 350);
248
for (i = 0; i < 15; i++) {
249
c = (255 + (i * 100) - t*10);
251
if (c > 255) c = 255;
253
draw_text(68, 150+i*12, STextV[i], 255-c);
256
for (i = 0; i < 15; i++) {
259
draw_text(68, 150+i*12, STextV[i], 255-c);
274
void InitParticleStorm()
278
for (i = 0; i < 500; i++) {
281
pt_vx[i] = (float)(rand()%101) / 33.333 - 1.5;
282
pt_vy[i] = (float)(rand()%101) / 10.0 - 16.1;
283
pt_t[i] = rand()%100;
288
"Concept: Lancer-X/Asceai",
289
"Game design: Lancer-X/Asceai",
290
"Graphics: Lancer-X/Asceai",
291
"Programming: Lancer-X/Asceai",
292
"Sound Effects: Various (public domain) sources",
293
"Music: Various artists",
294
"Beta testing: Quasar",
295
"Beta testing: Terryn",
296
"Beta testing: Wervyn"
297
"\"Ambient Light\" Vogue of Triton"
298
"\"Battle of Ragnarok\" Frostbite"
299
"\"Dragon Cave\" TICAZ"
301
"\"Caverns Boss\" Alexis Janson"
302
"\"Forest Boss\" Alexis Janson"
303
"\"Catacombs Boss\" Alexis Janson"
304
"\"Fear 2\" Mick Rippon"
305
"\"The Final Battle\" Goose/Cļæ½DA & iNVASiON"
306
"\"Ice Frontier\" Skaven/FC"
307
"\"KnarkLoader 1.0\" Rapacious"
309
"\"Metallic Forest\" Joseph Fox"
314
static SDL_Surface *fin = NULL;
315
static SDL_Surface *theend[2] = {NULL};
320
int n_credits = sizeof(credits)/sizeof(*credits);
323
finish_point = 400 + (n_credits * 50);
328
SDL_FillRect(screen, NULL, 0);
331
fin = IMG_Load("dat/i/fin.png");
333
theend[0] = IMG_Load("dat/i/theend.png");
334
theend[1] = IMG_Load("dat/i/true_end.png");
337
if (credits_scroll >= (finish_point + 80)) {
338
SDL_BlitSurface(theend[(player_shield == 30)], NULL, screen, NULL);
340
SDL_BlitSurface(fin, NULL, screen, &draw_to);
342
// Show each line of credits
344
for (i = 0; i < n_credits; i++) {
345
ypos = 800 + (i * 100) - credits_scroll * 2;
347
if ((ypos >= 0)&&(ypos < 480)) {
348
c = 255 - abs(ypos - 240);
349
draw_text(120, ypos, credits[i], c);
355
for (i = 0; i < 128; i++) {
358
ending_pal[i].b = i*2;
360
for (i = 128; i < 256; i++) {
361
ending_pal[i].r = (i - 128)*2+1;
363
ending_pal[i].b = 255;
366
// Dim palette if we're just starting
368
if (credits_scroll < 80) {
369
for (i = 0; i < 256; i++) {
370
ending_pal[i].r = ending_pal[i].r * credits_scroll / 80;
371
ending_pal[i].g = ending_pal[i].g * credits_scroll / 80;
372
ending_pal[i].b = ending_pal[i].b * credits_scroll / 80;
376
// Also palette if we're finishing
378
if ((credits_scroll >= (finish_point))&&(credits_scroll < (finish_point + 80))) {
379
for (i = 0; i < 256; i++) {
380
ending_pal[i].r = ending_pal[i].r * (finish_point+80-credits_scroll) / 80;
381
ending_pal[i].g = ending_pal[i].g * (finish_point+80-credits_scroll) / 80;
382
ending_pal[i].b = ending_pal[i].b * (finish_point+80-credits_scroll) / 80;
386
if ((credits_scroll >= (finish_point + 80))&&(credits_scroll < (finish_point + 160))) {
387
for (i = 0; i < 256; i++) {
388
ending_pal[i].r = ending_pal[i].r * (credits_scroll - (finish_point + 80)) / 80;
389
ending_pal[i].g = ending_pal[i].g * (credits_scroll - (finish_point + 80)) / 80;
390
ending_pal[i].b = ending_pal[i].b * (credits_scroll - (finish_point + 80)) / 80;
400
void RunParticleStorm(int offset)
402
SDL_Rect draw_from, draw_to;
405
for (i = 0; i < 64; i++) {
406
DrawRect(0, i * 15 - offset, 640, 15, 64 - i);
409
for (i = 0; i < 500; i++) {
418
draw_from.x = (rand()%3)*32;
423
draw_to.x = (int)pt_x[i] - 16;
424
draw_to.y = (int)pt_y[i] - 16 - offset;
425
SDL_BlitSurface(glitter, &draw_from, screen, &draw_to);
428
for (i = 0; i < 128; i++) {
429
ending_pal[i].r = i*2;
430
ending_pal[i].g = i*2;
433
for (i = 128; i < 256; i++) {
434
ending_pal[i].r = 255;
435
ending_pal[i].g = 255;
436
ending_pal[i].b = (i - 128)*2+1;
443
void DrawStream(int t)
449
SDL_Rect draw_from, draw_to;
451
for (i = 0; i < 256; i++) {
453
ending_pal[i].g = (i * 7 / 8) + 16 + sin( (float)t / 8 )*16;
454
ending_pal[i].b = (i * 3 / 4) + 32 + sin( (float)t / 8 )*32;
459
scr_x = 32 + rand()%32 - rand()%32;
464
scr_y = (20 - t * 2);
467
DrawLevel(scr_x, scr_y, 0, 0);
468
DrawPlayer(344 - scr_x, 228 - scr_y, 0, 0);
470
for (i = 0; i < 7; i++) {
471
strm_scrl = (t * 20) % 128;
472
draw_to.x = 0 - strm_scrl - scr_x + (128*i);
473
draw_to.y = 19 - scr_y;
476
draw_to.y += rand()%4;
477
draw_to.y -= rand()%4;
479
SDL_BlitSurface(streamspr, NULL, screen, &draw_to);
483
for (i = 0; i < 20; i++) {
484
draw_from.x = (rand()%3)*32;
489
draw_to.x = rand()%(640+32)-32;
490
draw_to.y = (rand()%(124)) + 3;
492
SDL_BlitSurface(glitter, &draw_from, screen, &draw_to);
498
SND_CircuitRelease(1000);
500
DrawCircle(320+32 - scr_x, 240 - scr_y, (t - 254) * 10, 255);
501
DrawCircle(320+32 - scr_x, 240 - scr_y, (t - 252) * 10, 225);
502
DrawCircle(320+32 - scr_x, 240 - scr_y, (t - 250) * 10, 195);
510
char *PText[10] = { "Activating the seal quickly unblocked the ley lines and allowed",
511
"PSI to flow through the Dome again. The remaining shadows were",
512
"quickly flushed out.",
514
"Wervyn Anixil's unconventional use of the PSI resulted in him",
515
"being burned out and rendered powerless. Merit will see to it",
516
"that he faces judgement for his crimes.",
518
"Neither of the two PSI weapons housed within the Dome had been",
519
"touched. However . . ." };
520
char *PTextV[10] ={ "Activating the seal quickly unblocked the ley lines and allowed",
521
"PSI to flow through the Dome again. The remaining shadows were",
522
"quickly flushed out.",
524
"The traitor, who was never identified, perished in the Sealing.",
525
"It soon became clear that the traitor had managed to betray and",
526
"kill the real Wervyn Anixil during his experiments on the PSI.",
527
"If the Agate Knife was never found, nobody would have been any",
528
"the wiser, and things could have turned out very differently.",
529
"However, there was one last thing for MERIT to do."};
531
void DrawPText(int t)
538
for (i = 0; i < 256; i++) {
541
ending_pal[i].b = (i * 3 / 4) + 64;
546
for (i = 0; i < 10; i++) {
547
c = (255 + (i * 100) - t*10);
549
if (c > 255) c = 255;
551
if (player_shield != 30) {
552
draw_text(68, 180+i*12, PText[i], c);
554
draw_text(68, 180+i*12, PTextV[i], c);
558
for (i = 0; i < 10; i++) {
561
if (player_shield != 30) {
562
draw_text(68, 180+i*12, PText[i], c);
564
draw_text(68, 180+i*12, PTextV[i], c);
569
for (i = 0; i < (32 * 8); i++) {
573
c = 237 + (i/32*2) + (rand()% (19 - (i/32) *2));
574
DrawRect(x, y, 20, 20, c);
575
c = 237 + (i/32*2) + (rand()% (19 - (i/32) *2));
576
DrawRect(x, 460 - y, 20, 20, c);
584
void DrawScrolly(int t)
592
SDL_Rect draw_from, draw_to;
599
xp = 8192 - 320 - 3180 + (t * 4);
602
xp = 8192 - 320 + ( (t-795) * 10);
603
yp = 795 * 20 - (t-795)*10;
609
if ((rand() % 10)==9) {
612
for (i = 0; i < 256; i++) {
613
bright = sin((float)t / 10.0) * 0.2 + 0.4;
614
ending_pal[i].r = (i * bright + (256*(1.0-bright))) * ((float)(all_blue == 0) * 0.5 + 0.5);
615
ending_pal[i].g = (i * bright + (256*(1.0-bright))) * ((float)(all_blue == 0) * 0.5 + 0.5);
616
ending_pal[i].b = i * bright + (256*(1.0-bright));
618
DrawLevel(xp, yp, 0, 0);
620
v_radius = sin((float)t / 10.0)*20 + 100;
622
for (i = 0; i < 5; i++) {
627
DrawCircleEx(x, y, r+2, r-4, 128);
628
DrawCircleEx(x, y, r, r-2, 255);
631
for (i = 0; i < 4; i++) {
632
draw_from.x = (8 + i) * 32;
637
a_dir = ((float)t / 10.0) + (M_PI*(float)i/2);
639
for (j = 10; j >= 0; j--) {
640
DrawCircleEx(320+cos(a_dir)*v_radius, 240+sin(a_dir)*v_radius, 22 + j * 2, 0, abs(j-3) * 15);
642
DrawCircleEx(320+cos(a_dir)*v_radius, 240+sin(a_dir)*v_radius, 20, 0, 0);
644
draw_to.x = 320 + cos(a_dir) * v_radius - 16;
645
draw_to.y = 240 + sin(a_dir) * v_radius - 16;
646
SDL_BlitSurface(artifact_spr, &draw_from, screen, &draw_to);
653
void DrawCircuitFlash(int t, int method)
655
static SDL_Surface *circ = NULL;
656
static int xpos, ypos;
661
circ = IMG_Load("dat/i/circuits_1.png");
679
SDL_BlitSurface(circ, &from, screen, NULL);
681
for (i = 0; i < 256; i++) {
691
if (j > 255) j = 255;