2
* OpenTyrian: A modern cross-platform port of Tyrian
3
* Copyright (C) 2007-2009 The OpenTyrian Development Team
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.
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.
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.
26
Sprite_array sprite_table[SPRITE_TABLES_MAX];
28
Sprite2_array eShapes[6];
29
Sprite2_array shapesC1, shapes6, shapes9, shapesW2;
31
void load_sprites_file( unsigned int table, const char *filename )
35
FILE *f = dir_fopen_die(data_dir(), filename, "rb");
37
load_sprites(table, f);
42
void load_sprites( unsigned int table, FILE *f )
47
efread(&temp, sizeof(Uint16), 1, f);
49
sprite_table[table].count = temp;
51
assert(sprite_table[table].count <= SPRITES_PER_TABLE_MAX);
53
for (unsigned int i = 0; i < sprite_table[table].count; ++i)
55
Sprite * const cur_sprite = sprite(table, i);
57
if (!getc(f)) // sprite is empty
60
efread(&cur_sprite->width, sizeof(Uint16), 1, f);
61
efread(&cur_sprite->height, sizeof(Uint16), 1, f);
62
efread(&cur_sprite->size, sizeof(Uint16), 1, f);
64
cur_sprite->data = malloc(cur_sprite->size);
66
efread(cur_sprite->data, sizeof(Uint8), cur_sprite->size, f);
70
void free_sprites( unsigned int table )
72
for (unsigned int i = 0; i < sprite_table[table].count; ++i)
74
Sprite * const cur_sprite = sprite(table, i);
76
cur_sprite->width = 0;
77
cur_sprite->height = 0;
80
free(cur_sprite->data);
81
cur_sprite->data = NULL;
84
sprite_table[table].count = 0;
87
// does not clip on left or right edges of surface
88
void blit_sprite( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index )
90
if (index >= sprite_table[table].count || !sprite_exists(table, index))
96
const Sprite * const cur_sprite = sprite(table, index);
98
const Uint8 *data = cur_sprite->data;
99
const Uint8 * const data_ul = data + cur_sprite->size;
101
const unsigned int width = cur_sprite->width;
102
unsigned int x_offset = 0;
104
assert(surface->format->BitsPerPixel == 8);
105
Uint8 * pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x;
106
const Uint8 * const pixels_ll = (Uint8 *)surface->pixels, // lower limit
107
* const pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch); // upper limit
109
for (; data < data_ul; ++data)
113
case 255: // transparent pixels
114
data++; // next byte tells how many
119
case 254: // next pixel row
120
pixels += width - x_offset;
124
case 253: // 1 transparent pixel
129
default: // set a pixel
130
if (pixels >= pixels_ul)
132
if (pixels >= pixels_ll)
139
if (x_offset >= width)
141
pixels += surface->pitch - x_offset;
147
// does not clip on left or right edges of surface
148
void blit_sprite_blend( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index )
150
if (index >= sprite_table[table].count || !sprite_exists(table, index))
156
const Sprite * const cur_sprite = sprite(table, index);
158
const Uint8 *data = cur_sprite->data;
159
const Uint8 * const data_ul = data + cur_sprite->size;
161
const unsigned int width = cur_sprite->width;
162
unsigned int x_offset = 0;
164
assert(surface->format->BitsPerPixel == 8);
165
Uint8 * pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x;
166
const Uint8 * const pixels_ll = (Uint8 *)surface->pixels, // lower limit
167
* const pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch); // upper limit
169
for (; data < data_ul; ++data)
173
case 255: // transparent pixels
174
data++; // next byte tells how many
179
case 254: // next pixel row
180
pixels += width - x_offset;
184
case 253: // 1 transparent pixel
189
default: // set a pixel
190
if (pixels >= pixels_ul)
192
if (pixels >= pixels_ll)
193
*pixels = (*data & 0xf0) | (((*pixels & 0x0f) + (*data & 0x0f)) / 2);
199
if (x_offset >= width)
201
pixels += surface->pitch - x_offset;
207
// does not clip on left or right edges of surface
208
// unsafe because it doesn't check that value won't overflow into hue
209
// we can replace it when we know that we don't rely on that 'feature'
210
void blit_sprite_hv_unsafe( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index, Uint8 hue, Sint8 value )
212
if (index >= sprite_table[table].count || !sprite_exists(table, index))
220
const Sprite * const cur_sprite = sprite(table, index);
222
const Uint8 *data = cur_sprite->data;
223
const Uint8 * const data_ul = data + cur_sprite->size;
225
const unsigned int width = cur_sprite->width;
226
unsigned int x_offset = 0;
228
assert(surface->format->BitsPerPixel == 8);
229
Uint8 * pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x;
230
const Uint8 * const pixels_ll = (Uint8 *)surface->pixels, // lower limit
231
* const pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch); // upper limit
233
for (; data < data_ul; ++data)
237
case 255: // transparent pixels
238
data++; // next byte tells how many
243
case 254: // next pixel row
244
pixels += width - x_offset;
248
case 253: // 1 transparent pixel
253
default: // set a pixel
254
if (pixels >= pixels_ul)
256
if (pixels >= pixels_ll)
257
*pixels = hue | ((*data & 0x0f) + value);
263
if (x_offset >= width)
265
pixels += surface->pitch - x_offset;
271
// does not clip on left or right edges of surface
272
void blit_sprite_hv( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index, Uint8 hue, Sint8 value )
274
if (index >= sprite_table[table].count || !sprite_exists(table, index))
282
const Sprite * const cur_sprite = sprite(table, index);
284
const Uint8 *data = cur_sprite->data;
285
const Uint8 * const data_ul = data + cur_sprite->size;
287
const unsigned int width = cur_sprite->width;
288
unsigned int x_offset = 0;
290
assert(surface->format->BitsPerPixel == 8);
291
Uint8 * pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x;
292
const Uint8 * const pixels_ll = (Uint8 *)surface->pixels, // lower limit
293
* const pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch); // upper limit
295
for (; data < data_ul; ++data)
299
case 255: // transparent pixels
300
data++; // next byte tells how many
305
case 254: // next pixel row
306
pixels += width - x_offset;
310
case 253: // 1 transparent pixel
315
default: // set a pixel
316
if (pixels >= pixels_ul)
318
if (pixels >= pixels_ll)
320
Uint8 temp_value = (*data & 0x0f) + value;
321
if (temp_value > 0xf)
322
temp_value = (temp_value >= 0x1f) ? 0x0 : 0xf;
324
*pixels = hue | temp_value;
331
if (x_offset >= width)
333
pixels += surface->pitch - x_offset;
339
// does not clip on left or right edges of surface
340
void blit_sprite_hv_blend( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index, Uint8 hue, Sint8 value )
342
if (index >= sprite_table[table].count || !sprite_exists(table, index))
350
const Sprite * const cur_sprite = sprite(table, index);
352
const Uint8 *data = cur_sprite->data;
353
const Uint8 * const data_ul = data + cur_sprite->size;
355
const unsigned int width = cur_sprite->width;
356
unsigned int x_offset = 0;
358
assert(surface->format->BitsPerPixel == 8);
359
Uint8 * pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x;
360
const Uint8 * const pixels_ll = (Uint8 *)surface->pixels, // lower limit
361
* const pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch); // upper limit
363
for (; data < data_ul; ++data)
367
case 255: // transparent pixels
368
data++; // next byte tells how many
373
case 254: // next pixel row
374
pixels += width - x_offset;
378
case 253: // 1 transparent pixel
383
default: // set a pixel
384
if (pixels >= pixels_ul)
386
if (pixels >= pixels_ll)
388
Uint8 temp_value = (*data & 0x0f) + value;
389
if (temp_value > 0xf)
390
temp_value = (temp_value >= 0x1f) ? 0x0 : 0xf;
392
*pixels = hue | (((*pixels & 0x0f) + temp_value) / 2);
399
if (x_offset >= width)
401
pixels += surface->pitch - x_offset;
407
// does not clip on left or right edges of surface
408
void blit_sprite_dark( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index, bool black )
410
if (index >= sprite_table[table].count || !sprite_exists(table, index))
416
const Sprite * const cur_sprite = sprite(table, index);
418
const Uint8 *data = cur_sprite->data;
419
const Uint8 * const data_ul = data + cur_sprite->size;
421
const unsigned int width = cur_sprite->width;
422
unsigned int x_offset = 0;
424
assert(surface->format->BitsPerPixel == 8);
425
Uint8 * pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x;
426
const Uint8 * const pixels_ll = (Uint8 *)surface->pixels, // lower limit
427
* const pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch); // upper limit
429
for (; data < data_ul; ++data)
433
case 255: // transparent pixels
434
data++; // next byte tells how many
439
case 254: // next pixel row
440
pixels += width - x_offset;
444
case 253: // 1 transparent pixel
449
default: // set a pixel
450
if (pixels >= pixels_ul)
452
if (pixels >= pixels_ll)
453
*pixels = black ? 0x00 : ((*pixels & 0xf0) | ((*pixels & 0x0f) / 2));
459
if (x_offset >= width)
461
pixels += surface->pitch - x_offset;
468
void JE_loadCompShapes( Sprite2_array *sprite2s, char s )
471
snprintf(buffer, sizeof(buffer), "newsh%c.shp", tolower((unsigned char)s));
473
FILE *f = dir_fopen_die(data_dir(), buffer, "rb");
475
sprite2s->size = ftell_eof(f);
477
JE_loadCompShapesB(sprite2s, f);
482
void JE_loadCompShapesB( Sprite2_array *sprite2s, FILE *f )
484
free_sprite2s(sprite2s);
486
sprite2s->data = malloc(sizeof(Uint8) * sprite2s->size);
487
efread(sprite2s->data, sizeof(Uint8), sprite2s->size, f);
490
void free_sprite2s( Sprite2_array *sprite2s )
492
free(sprite2s->data);
493
sprite2s->data = NULL;
496
// does not clip on left or right edges of surface
497
void blit_sprite2( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
499
assert(surface->format->BitsPerPixel == 8);
500
Uint8 * pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x;
501
const Uint8 * const pixels_ll = (Uint8 *)surface->pixels, // lower limit
502
* const pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch); // upper limit
504
const Uint8 *data = sprite2s.data + SDL_SwapLE16(((Uint16 *)sprite2s.data)[index - 1]);
506
for (; *data != 0x0f; ++data)
508
pixels += *data & 0x0f; // second nibble: transparent pixel count
509
unsigned int count = (*data & 0xf0) >> 4; // first nibble: opaque pixel count
511
if (count == 0) // move to next pixel row
513
pixels += VGAScreen->pitch - 12;
521
if (pixels >= pixels_ul)
523
if (pixels >= pixels_ll)
532
// does not clip on left or right edges of surface
533
void blit_sprite2_blend( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
535
assert(surface->format->BitsPerPixel == 8);
536
Uint8 * pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x;
537
const Uint8 * const pixels_ll = (Uint8 *)surface->pixels, // lower limit
538
* const pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch); // upper limit
540
const Uint8 *data = sprite2s.data + SDL_SwapLE16(((Uint16 *)sprite2s.data)[index - 1]);
542
for (; *data != 0x0f; ++data)
544
pixels += *data & 0x0f; // second nibble: transparent pixel count
545
unsigned int count = (*data & 0xf0) >> 4; // first nibble: opaque pixel count
547
if (count == 0) // move to next pixel row
549
pixels += VGAScreen->pitch - 12;
557
if (pixels >= pixels_ul)
559
if (pixels >= pixels_ll)
560
*pixels = (((*data & 0x0f) + (*pixels & 0x0f)) / 2) | (*data & 0xf0);
568
// does not clip on left or right edges of surface
569
void blit_sprite2_darken( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
571
assert(surface->format->BitsPerPixel == 8);
572
Uint8 * pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x;
573
const Uint8 * const pixels_ll = (Uint8 *)surface->pixels, // lower limit
574
* const pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch); // upper limit
576
const Uint8 *data = sprite2s.data + SDL_SwapLE16(((Uint16 *)sprite2s.data)[index - 1]);
578
for (; *data != 0x0f; ++data)
580
pixels += *data & 0x0f; // second nibble: transparent pixel count
581
unsigned int count = (*data & 0xf0) >> 4; // first nibble: opaque pixel count
583
if (count == 0) // move to next pixel row
585
pixels += VGAScreen->pitch - 12;
593
if (pixels >= pixels_ul)
595
if (pixels >= pixels_ll)
596
*pixels = ((*pixels & 0x0f) / 2) + (*pixels & 0xf0);
604
// does not clip on left or right edges of surface
605
void blit_sprite2_filter( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index, Uint8 filter )
607
assert(surface->format->BitsPerPixel == 8);
608
Uint8 * pixels = (Uint8 *)surface->pixels + (y * surface->pitch) + x;
609
const Uint8 * const pixels_ll = (Uint8 *)surface->pixels, // lower limit
610
* const pixels_ul = (Uint8 *)surface->pixels + (surface->h * surface->pitch); // upper limit
612
const Uint8 *data = sprite2s.data + SDL_SwapLE16(((Uint16 *)sprite2s.data)[index - 1]);
614
for (; *data != 0x0f; ++data)
616
pixels += *data & 0x0f; // second nibble: transparent pixel count
617
unsigned int count = (*data & 0xf0) >> 4; // first nibble: opaque pixel count
619
if (count == 0) // move to next pixel row
621
pixels += VGAScreen->pitch - 12;
629
if (pixels >= pixels_ul)
631
if (pixels >= pixels_ll)
632
*pixels = filter | (*data & 0x0f);
640
// does not clip on left or right edges of surface
641
void blit_sprite2x2( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
643
blit_sprite2(surface, x, y, sprite2s, index);
644
blit_sprite2(surface, x + 12, y, sprite2s, index + 1);
645
blit_sprite2(surface, x, y + 14, sprite2s, index + 19);
646
blit_sprite2(surface, x + 12, y + 14, sprite2s, index + 20);
649
// does not clip on left or right edges of surface
650
void blit_sprite2x2_blend( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
652
blit_sprite2_blend(surface, x, y, sprite2s, index);
653
blit_sprite2_blend(surface, x + 12, y, sprite2s, index + 1);
654
blit_sprite2_blend(surface, x, y + 14, sprite2s, index + 19);
655
blit_sprite2_blend(surface, x + 12, y + 14, sprite2s, index + 20);
658
// does not clip on left or right edges of surface
659
void blit_sprite2x2_darken( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
661
blit_sprite2_darken(surface, x, y, sprite2s, index);
662
blit_sprite2_darken(surface, x + 12, y, sprite2s, index + 1);
663
blit_sprite2_darken(surface, x, y + 14, sprite2s, index + 19);
664
blit_sprite2_darken(surface, x + 12, y + 14, sprite2s, index + 20);
668
void JE_loadMainShapeTables( const char *shpfile )
671
const int SHP_NUM = 13;
673
const int SHP_NUM = 12;
676
FILE *f = dir_fopen_die(data_dir(), shpfile, "rb");
679
JE_longint shpPos[SHP_NUM + 1]; // +1 for storing file length
681
efread(&shpNumb, sizeof(JE_word), 1, f);
682
assert(shpNumb + 1u == COUNTOF(shpPos));
684
for (unsigned int i = 0; i < shpNumb; ++i)
685
efread(&shpPos[i], sizeof(JE_longint), 1, f);
687
fseek(f, 0, SEEK_END);
688
for (unsigned int i = shpNumb; i < COUNTOF(shpPos); ++i)
689
shpPos[i] = ftell(f);
692
// fonts, interface, option sprites
693
for (i = 0; i < 7; i++)
695
fseek(f, shpPos[i], SEEK_SET);
699
// player shot sprites
700
shapesC1.size = shpPos[i + 1] - shpPos[i];
701
JE_loadCompShapesB(&shapesC1, f);
704
// player ship sprites
705
shapes9.size = shpPos[i + 1] - shpPos[i];
706
JE_loadCompShapesB(&shapes9 , f);
710
eShapes[5].size = shpPos[i + 1] - shpPos[i];
711
JE_loadCompShapesB(&eShapes[5], f);
714
// coins, datacubes, etc sprites
715
eShapes[4].size = shpPos[i + 1] - shpPos[i];
716
JE_loadCompShapesB(&eShapes[4], f);
719
// more player shot sprites
720
shapesW2.size = shpPos[i + 1] - shpPos[i];
721
JE_loadCompShapesB(&shapesW2, f);
726
void free_main_shape_tables( void )
728
for (uint i = 0; i < COUNTOF(sprite_table); ++i)
731
free_sprite2s(&shapesC1);
732
free_sprite2s(&shapes9);
733
free_sprite2s(&eShapes[5]);
734
free_sprite2s(&eShapes[4]);
735
free_sprite2s(&shapesW2);