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

« back to all changes in this revision

Viewing changes to src/backgrnd.c

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * OpenTyrian: A modern cross-platform port of Tyrian
 
3
 * Copyright (C) 2007-2009  The OpenTyrian Development Team
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License
 
7
 * as published by the Free Software Foundation; either version 2
 
8
 * of the License, or (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
18
 */
 
19
#include "opentyr.h"
 
20
#include "backgrnd.h"
 
21
 
 
22
#include "config.h"
 
23
#include "mtrand.h"
 
24
#include "varz.h"
 
25
#include "video.h"
 
26
 
 
27
#include <assert.h>
 
28
 
 
29
/*Special Background 2 and Background 3*/
 
30
 
 
31
/*Back Pos 3*/
 
32
JE_word backPos, backPos2, backPos3;
 
33
JE_word backMove, backMove2, backMove3;
 
34
 
 
35
/*Main Maps*/
 
36
JE_word mapX, mapY, mapX2, mapX3, mapY2, mapY3;
 
37
JE_byte **mapYPos, **mapY2Pos, **mapY3Pos;
 
38
JE_word mapXPos, oldMapXOfs, mapXOfs, mapX2Ofs, mapX2Pos, mapX3Pos, oldMapX3Ofs, mapX3Ofs, tempMapXOfs;
 
39
intptr_t mapXbpPos, mapX2bpPos, mapX3bpPos;
 
40
JE_byte map1YDelay, map1YDelayMax, map2YDelay, map2YDelayMax;
 
41
 
 
42
 
 
43
JE_boolean  anySmoothies;
 
44
JE_byte     smoothie_data[9]; /* [1..9] */
 
45
 
 
46
void JE_darkenBackground( JE_word neat )  /* wild detail level */
 
47
{
 
48
        Uint8 *s = VGAScreen->pixels; /* screen pointer, 8-bit specific */
 
49
        int x, y;
 
50
        
 
51
        s += 24;
 
52
        
 
53
        for (y = 184; y; y--)
 
54
        {
 
55
                for (x = 264; x; x--)
 
56
                {
 
57
                        *s = ((((*s & 0x0f) << 4) - (*s & 0x0f) + ((((x - neat - y) >> 2) + *(s-2) + (y == 184 ? 0 : *(s-(VGAScreen->pitch-1)))) & 0x0f)) >> 4) | (*s & 0xf0);
 
58
                        s++;
 
59
                }
 
60
                s += VGAScreen->pitch - 264;
 
61
        }
 
62
}
 
63
 
 
64
void blit_background_row( SDL_Surface *surface, int x, int y, Uint8 **map )
 
65
{
 
66
        assert(surface->format->BitsPerPixel == 8);
 
67
        
 
68
        Uint8 *pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x,
 
69
              *pixels_ll = (Uint8 *)surface->pixels,  // lower limit
 
70
              *pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch);  // upper limit
 
71
        
 
72
        for (int y = 0; y < 28; y++)
 
73
        {
 
74
                // not drawing on screen yet; skip y
 
75
                if ((pixels + (12 * 24)) < pixels_ll)
 
76
                {
 
77
                        pixels += surface->pitch;
 
78
                        continue;
 
79
                }
 
80
                
 
81
                for (int tile = 0; tile < 12; tile++)
 
82
                {
 
83
                        Uint8 *data = *(map + tile);
 
84
                        
 
85
                        // no tile; skip tile
 
86
                        if (data == NULL)
 
87
                        {
 
88
                                pixels += 24;
 
89
                                continue;
 
90
                        }
 
91
                        
 
92
                        data += y * 24;
 
93
                        
 
94
                        for (int x = 24; x; x--)
 
95
                        {
 
96
                                if (pixels >= pixels_ul)
 
97
                                        return;
 
98
                                if (pixels >= pixels_ll && *data != 0)
 
99
                                        *pixels = *data;
 
100
                                
 
101
                                pixels++;
 
102
                                data++;
 
103
                        }
 
104
                }
 
105
                
 
106
                pixels += surface->pitch - 12 * 24;
 
107
        }
 
108
}
 
109
 
 
110
void blit_background_row_blend( SDL_Surface *surface, int x, int y, Uint8 **map )
 
111
{
 
112
        assert(surface->format->BitsPerPixel == 8);
 
113
        
 
114
        Uint8 *pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x,
 
115
              *pixels_ll = (Uint8 *)surface->pixels,  // lower limit
 
116
              *pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch);  // upper limit
 
117
        
 
118
        for (int y = 0; y < 28; y++)
 
119
        {
 
120
                // not drawing on screen yet; skip y
 
121
                if ((pixels + (12 * 24)) < pixels_ll)
 
122
                {
 
123
                        pixels += surface->pitch;
 
124
                        continue;
 
125
                }
 
126
                
 
127
                for (int tile = 0; tile < 12; tile++)
 
128
                {
 
129
                        Uint8 *data = *(map + tile);
 
130
                        
 
131
                        // no tile; skip tile
 
132
                        if (data == NULL)
 
133
                        {
 
134
                                pixels += 24;
 
135
                                continue;
 
136
                        }
 
137
                        
 
138
                        data += y * 24;
 
139
                        
 
140
                        for (int x = 24; x; x--)
 
141
                        {
 
142
                                if (pixels >= pixels_ul)
 
143
                                        return;
 
144
                                if (pixels >= pixels_ll && *data != 0)
 
145
                                        *pixels = (*data & 0xf0) | (((*pixels & 0x0f) + (*data & 0x0f)) / 2);
 
146
                                
 
147
                                pixels++;
 
148
                                data++;
 
149
                        }
 
150
                }
 
151
                
 
152
                pixels += surface->pitch - 12 * 24;
 
153
        }
 
154
}
 
155
 
 
156
void draw_background_1( SDL_Surface *surface )
 
157
{
 
158
        SDL_FillRect(surface, NULL, 0);
 
159
        
 
160
        Uint8 **map = (Uint8 **)mapYPos + mapXbpPos - 12;
 
161
        
 
162
        for (int i = -1; i < 7; i++)
 
163
        {
 
164
                blit_background_row(surface, mapXPos, (i * 28) + backPos, map);
 
165
                
 
166
                map += 14;
 
167
        }
 
168
}
 
169
 
 
170
void draw_background_2( SDL_Surface *surface )
 
171
{
 
172
        if (map2YDelayMax > 1 && backMove2 < 2)
 
173
                backMove2 = (map2YDelay == 1) ? 1 : 0;
 
174
        
 
175
        if (background2 != 0)
 
176
        {
 
177
                // water effect combines background 1 and 2 by syncronizing the x coordinate
 
178
                int x = smoothies[1] ? mapXPos : mapX2Pos;
 
179
                
 
180
                Uint8 **map = (Uint8 **)mapY2Pos + (smoothies[1] ? mapXbpPos : mapX2bpPos) - 12;
 
181
                
 
182
                for (int i = -1; i < 7; i++)
 
183
                {
 
184
                        blit_background_row(surface, x, (i * 28) + backPos2, map);
 
185
                        
 
186
                        map += 14;
 
187
                }
 
188
        }
 
189
        
 
190
        /*Set Movement of background*/
 
191
        if (--map2YDelay == 0)
 
192
        {
 
193
                map2YDelay = map2YDelayMax;
 
194
                
 
195
                backPos2 += backMove2;
 
196
                
 
197
                if (backPos2 >  27)
 
198
                {
 
199
                        backPos2 -= 28;
 
200
                        mapY2--;
 
201
                        mapY2Pos -= 14;  /*Map Width*/
 
202
                }
 
203
        }
 
204
}
 
205
 
 
206
void draw_background_2_blend( SDL_Surface *surface )
 
207
{
 
208
        if (map2YDelayMax > 1 && backMove2 < 2)
 
209
                backMove2 = (map2YDelay == 1) ? 1 : 0;
 
210
        
 
211
        Uint8 **map = (Uint8 **)mapY2Pos + mapX2bpPos - 12;
 
212
        
 
213
        for (int i = -1; i < 7; i++)
 
214
        {
 
215
                blit_background_row_blend(surface, mapX2Pos, (i * 28) + backPos2, map);
 
216
                
 
217
                map += 14;
 
218
        }
 
219
        
 
220
        /*Set Movement of background*/
 
221
        if (--map2YDelay == 0)
 
222
        {
 
223
                map2YDelay = map2YDelayMax;
 
224
                
 
225
                backPos2 += backMove2;
 
226
                
 
227
                if (backPos2 >  27)
 
228
                {
 
229
                        backPos2 -= 28;
 
230
                        mapY2--;
 
231
                        mapY2Pos -= 14;  /*Map Width*/
 
232
                }
 
233
        }
 
234
}
 
235
 
 
236
void draw_background_3( SDL_Surface *surface )
 
237
{
 
238
        /* Movement of background */
 
239
        backPos3 += backMove3;
 
240
        
 
241
        if (backPos3 > 27)
 
242
        {
 
243
                backPos3 -= 28;
 
244
                mapY3--;
 
245
                mapY3Pos -= 15;   /*Map Width*/
 
246
        }
 
247
        
 
248
        Uint8 **map = (Uint8 **)mapY3Pos + mapX3bpPos - 12;
 
249
        
 
250
        for (int i = -1; i < 7; i++)
 
251
        {
 
252
                blit_background_row(surface, mapX3Pos, (i * 28) + backPos3, map);
 
253
                
 
254
                map += 15;
 
255
        }
 
256
}
 
257
 
 
258
void JE_filterScreen( JE_shortint col, JE_shortint int_)
 
259
{
 
260
        Uint8 *s = NULL; /* screen pointer, 8-bit specific */
 
261
        int x, y;
 
262
        unsigned int temp;
 
263
        
 
264
        if (filterFade)
 
265
        {
 
266
                levelBrightness += levelBrightnessChg;
 
267
                if ((filterFadeStart && levelBrightness < -14) || levelBrightness > 14)
 
268
                {
 
269
                        levelBrightnessChg = -levelBrightnessChg;
 
270
                        filterFadeStart = false;
 
271
                        levelFilter = levelFilterNew;
 
272
                }
 
273
                if (!filterFadeStart && levelBrightness == 0)
 
274
                {
 
275
                        filterFade = false;
 
276
                        levelBrightness = -99;
 
277
                }
 
278
        }
 
279
        
 
280
        if (col != -99 && filtrationAvail)
 
281
        {
 
282
                s = VGAScreen->pixels;
 
283
                s += 24;
 
284
                
 
285
                col <<= 4;
 
286
                
 
287
                for (y = 184; y; y--)
 
288
                {
 
289
                        for (x = 264; x; x--)
 
290
                        {
 
291
                                *s = col | (*s & 0x0f);
 
292
                                s++;
 
293
                        }
 
294
                        s += VGAScreen->pitch - 264;
 
295
                }
 
296
        }
 
297
        
 
298
        if (int_ != -99 && explosionTransparent)
 
299
        {
 
300
                s = VGAScreen->pixels;
 
301
                s += 24;
 
302
                
 
303
                for (y = 184; y; y--)
 
304
                {
 
305
                        for (x = 264; x; x--)
 
306
                        {
 
307
                                temp = (*s & 0x0f) + int_;
 
308
                                *s = (*s & 0xf0) | (temp >= 0x1f ? 0 : (temp >= 0x0f ? 0x0f : temp));
 
309
                                s++;
 
310
                        }
 
311
                        s += VGAScreen->pitch - 264;
 
312
                }
 
313
        }
 
314
}
 
315
 
 
316
void JE_checkSmoothies( void )
 
317
{
 
318
        anySmoothies = (processorType > 2 && (smoothies[1-1] || smoothies[2-1])) || (processorType > 1 && (smoothies[3-1] || smoothies[4-1] || smoothies[5-1]));
 
319
}
 
320
 
 
321
void lava_filter( SDL_Surface *dst, SDL_Surface *src )
 
322
{
 
323
        assert(src->format->BitsPerPixel == 8 && dst->format->BitsPerPixel == 8);
 
324
        
 
325
        /* we don't need to check for over-reading the pixel surfaces since we only
 
326
         * read from the top 185+1 scanlines, and there should be 320 */
 
327
        
 
328
        const int dst_pitch = dst->pitch;
 
329
        Uint8 *dst_pixel = (Uint8 *)dst->pixels + (185 * dst_pitch);
 
330
        const Uint8 * const dst_pixel_ll = (Uint8 *)dst->pixels;  // lower limit
 
331
        
 
332
        const int src_pitch = src->pitch;
 
333
        const Uint8 *src_pixel = (Uint8 *)src->pixels + (185 * src->pitch);
 
334
        const Uint8 * const src_pixel_ll = (Uint8 *)src->pixels;  // lower limit
 
335
        
 
336
        int w = 320 * 185 - 1;
 
337
        
 
338
        for (int y = 185 - 1; y >= 0; --y)
 
339
        {
 
340
                dst_pixel -= (dst_pitch - 320);  // in case pitch is not 320
 
341
                src_pixel -= (src_pitch - 320);  // in case pitch is not 320
 
342
                
 
343
                for (int x = 320 - 1; x >= 0; x -= 8)
 
344
                {
 
345
                        int waver = abs(((w >> 9) & 0x0f) - 8) - 1;
 
346
                        w -= 8;
 
347
                        
 
348
                        for (int xi = 8 - 1; xi >= 0; --xi)
 
349
                        {
 
350
                                --dst_pixel;
 
351
                                --src_pixel;
 
352
                                
 
353
                                // value is average value of source pixel (2x), destination pixel above, and destination pixel below (all with waver)
 
354
                                // hue is red
 
355
                                Uint8 value = 0;
 
356
                                
 
357
                                if (src_pixel + waver >= src_pixel_ll)
 
358
                                        value += (*(src_pixel + waver) & 0x0f) * 2;
 
359
                                value += *(dst_pixel + waver + dst_pitch) & 0x0f;
 
360
                                if (dst_pixel + waver - dst_pitch >= dst_pixel_ll)
 
361
                                        value += *(dst_pixel + waver - dst_pitch) & 0x0f;
 
362
                                
 
363
                                *dst_pixel = (value / 4) | 0x70;
 
364
                        }
 
365
                }
 
366
        }
 
367
}
 
368
 
 
369
void water_filter( SDL_Surface *dst, SDL_Surface *src )
 
370
{
 
371
        assert(src->format->BitsPerPixel == 8 && dst->format->BitsPerPixel == 8);
 
372
        
 
373
        Uint8 hue = smoothie_data[1] << 4;
 
374
        
 
375
        /* we don't need to check for over-reading the pixel surfaces since we only
 
376
         * read from the top 185+1 scanlines, and there should be 320 */
 
377
        
 
378
        const int dst_pitch = dst->pitch;
 
379
        Uint8 *dst_pixel = (Uint8 *)dst->pixels + (185 * dst_pitch);
 
380
        
 
381
        const Uint8 *src_pixel = (Uint8 *)src->pixels + (185 * src->pitch);
 
382
        
 
383
        int w = 320 * 185 - 1;
 
384
        
 
385
        for (int y = 185 - 1; y >= 0; --y)
 
386
        {
 
387
                dst_pixel -= (dst_pitch - 320);  // in case pitch is not 320
 
388
                src_pixel -= (src->pitch - 320);  // in case pitch is not 320
 
389
                
 
390
                for (int x = 320 - 1; x >= 0; x -= 8)
 
391
                {
 
392
                        int waver = abs(((w >> 10) & 0x07) - 4) - 1;
 
393
                        w -= 8;
 
394
                        
 
395
                        for (int xi = 8 - 1; xi >= 0; --xi)
 
396
                        {
 
397
                                --dst_pixel;
 
398
                                --src_pixel;
 
399
                                
 
400
                                // pixel is copied from source if not blue
 
401
                                // otherwise, value is average of value of source pixel and destination pixel below (with waver)
 
402
                                if ((*src_pixel & 0x30) == 0)
 
403
                                {
 
404
                                        *dst_pixel = *src_pixel;
 
405
                                }
 
406
                                else
 
407
                                {
 
408
                                        Uint8 value = *src_pixel & 0x0f;
 
409
                                        value += *(dst_pixel + waver + dst_pitch) & 0x0f;
 
410
                                        *dst_pixel = (value / 2) | hue;
 
411
                                }
 
412
                        }
 
413
                }
 
414
        }
 
415
}
 
416
 
 
417
void iced_blur_filter( SDL_Surface *dst, SDL_Surface *src )
 
418
{
 
419
        assert(src->format->BitsPerPixel == 8 && dst->format->BitsPerPixel == 8);
 
420
        
 
421
        Uint8 *dst_pixel = dst->pixels;
 
422
        const Uint8 *src_pixel = src->pixels;
 
423
        
 
424
        for (int y = 0; y < 184; ++y)
 
425
        {
 
426
                for (int x = 0; x < 320; ++x)
 
427
                {
 
428
                        // value is average value of source pixel and destination pixel
 
429
                        // hue is icy blue
 
430
                        
 
431
                        const Uint8 value = (*src_pixel & 0x0f) + (*dst_pixel & 0x0f);
 
432
                        *dst_pixel = (value / 2) | 0x80;
 
433
                        
 
434
                        ++dst_pixel;
 
435
                        ++src_pixel;
 
436
                }
 
437
                
 
438
                dst_pixel += (dst->pitch - 320);  // in case pitch is not 320
 
439
                src_pixel += (src->pitch - 320);  // in case pitch is not 320
 
440
        }
 
441
}
 
442
 
 
443
void blur_filter( SDL_Surface *dst, SDL_Surface *src )
 
444
{
 
445
        assert(src->format->BitsPerPixel == 8 && dst->format->BitsPerPixel == 8);
 
446
        
 
447
        Uint8 *dst_pixel = dst->pixels;
 
448
        const Uint8 *src_pixel = src->pixels;
 
449
        
 
450
        for (int y = 0; y < 184; ++y)
 
451
        {
 
452
                for (int x = 0; x < 320; ++x)
 
453
                {
 
454
                        // value is average value of source pixel and destination pixel
 
455
                        // hue is source pixel hue
 
456
                        
 
457
                        const Uint8 value = (*src_pixel & 0x0f) + (*dst_pixel & 0x0f);
 
458
                        *dst_pixel = (value / 2) | (*src_pixel & 0xf0);
 
459
                        
 
460
                        ++dst_pixel;
 
461
                        ++src_pixel;
 
462
                }
 
463
                
 
464
                dst_pixel += (dst->pitch - 320);  // in case pitch is not 320
 
465
                src_pixel += (src->pitch - 320);  // in case pitch is not 320
 
466
        }
 
467
}
 
468
 
 
469
 
 
470
/* Background Starfield */
 
471
typedef struct
 
472
{
 
473
        Uint8 color;
 
474
        JE_word position; // relies on overflow wrap-around
 
475
        int speed;
 
476
} StarfieldStar;
 
477
 
 
478
#define MAX_STARS 100
 
479
#define STARFIELD_HUE 0x90
 
480
static StarfieldStar starfield_stars[MAX_STARS];
 
481
int starfield_speed;
 
482
 
 
483
void initialize_starfield( void )
 
484
{
 
485
        for (int i = MAX_STARS-1; i >= 0; --i)
 
486
        {
 
487
                starfield_stars[i].position = mt_rand() % 320 + mt_rand() % 200 * VGAScreen->pitch;
 
488
                starfield_stars[i].speed = mt_rand() % 3 + 2;
 
489
                starfield_stars[i].color = mt_rand() % 16 + STARFIELD_HUE;
 
490
        }
 
491
}
 
492
 
 
493
void update_and_draw_starfield( SDL_Surface* surface, int move_speed )
 
494
{
 
495
        Uint8* p = (Uint8*)surface->pixels;
 
496
 
 
497
        for (int i = MAX_STARS-1; i >= 0; --i)
 
498
        {
 
499
                StarfieldStar* star = &starfield_stars[i];
 
500
 
 
501
                star->position += (star->speed + move_speed) * surface->pitch;
 
502
 
 
503
                if (star->position < 177 * surface->pitch)
 
504
                {
 
505
                        if (p[star->position] == 0)
 
506
                        {
 
507
                                p[star->position] = star->color;
 
508
                        }
 
509
 
 
510
                        // If star is bright enough, draw surrounding pixels
 
511
                        if (star->color - 4 >= STARFIELD_HUE)
 
512
                        {
 
513
                                if (p[star->position + 1] == 0)
 
514
                                        p[star->position + 1] = star->color - 4;
 
515
 
 
516
                                if (star->position > 0 && p[star->position - 1] == 0)
 
517
                                        p[star->position - 1] = star->color - 4;
 
518
 
 
519
                                if (p[star->position + surface->pitch] == 0)
 
520
                                        p[star->position + surface->pitch] = star->color - 4;
 
521
 
 
522
                                if (star->position >= surface->pitch && p[star->position - surface->pitch] == 0)
 
523
                                        p[star->position - surface->pitch] = star->color - 4;
 
524
                        }
 
525
                }
 
526
        }
 
527
}