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 "file.h"
20 #include "opentyr.h"
21 #include "sprite.h"
22 #include "video.h"
23 
24 #include <assert.h>
25 
26 Sprite_array sprite_table[SPRITE_TABLES_MAX];
27 
28 Sprite2_array eShapes[6];
29 Sprite2_array shapesC1, shapes6, shapes9, shapesW2;
30 
load_sprites_file(unsigned int table,const char * filename)31 void load_sprites_file( unsigned int table, const char *filename )
32 {
33 	free_sprites(table);
34 
35 	FILE *f = dir_fopen_die(data_dir(), filename, "rb");
36 
37 	load_sprites(table, f);
38 
39 	fclose(f);
40 }
41 
load_sprites(unsigned int table,FILE * f)42 void load_sprites( unsigned int table, FILE *f )
43 {
44 	free_sprites(table);
45 
46 	Uint16 temp;
47 	efread(&temp, sizeof(Uint16), 1, f);
48 
49 	sprite_table[table].count = temp;
50 
51 	assert(sprite_table[table].count <= SPRITES_PER_TABLE_MAX);
52 
53 	for (unsigned int i = 0; i < sprite_table[table].count; ++i)
54 	{
55 		Sprite * const cur_sprite = sprite(table, i);
56 
57 		if (!getc(f)) // sprite is empty
58 			continue;
59 
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);
63 
64 		cur_sprite->data = malloc(cur_sprite->size);
65 
66 		efread(cur_sprite->data, sizeof(Uint8), cur_sprite->size, f);
67 	}
68 }
69 
free_sprites(unsigned int table)70 void free_sprites( unsigned int table )
71 {
72 	for (unsigned int i = 0; i < sprite_table[table].count; ++i)
73 	{
74 		Sprite * const cur_sprite = sprite(table, i);
75 
76 		cur_sprite->width  = 0;
77 		cur_sprite->height = 0;
78 		cur_sprite->size   = 0;
79 
80 		free(cur_sprite->data);
81 		cur_sprite->data = NULL;
82 	}
83 
84 	sprite_table[table].count = 0;
85 }
86 
87 // does not clip on left or right edges of surface
blit_sprite(SDL_Surface * surface,int x,int y,unsigned int table,unsigned int index)88 void blit_sprite( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index )
89 {
90 	if (index >= sprite_table[table].count || !sprite_exists(table, index))
91 	{
92 		assert(false);
93 		return;
94 	}
95 
96 	const Sprite * const cur_sprite = sprite(table, index);
97 
98 	const Uint8 *data = cur_sprite->data;
99 	const Uint8 * const data_ul = data + cur_sprite->size;
100 
101 	const unsigned int width = cur_sprite->width;
102 	unsigned int x_offset = 0;
103 
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
108 
109 	for (; data < data_ul; ++data)
110 	{
111 		switch (*data)
112 		{
113 		case 255:  // transparent pixels
114 			data++;  // next byte tells how many
115 			pixels += *data;
116 			x_offset += *data;
117 			break;
118 
119 		case 254:  // next pixel row
120 			pixels += width - x_offset;
121 			x_offset = width;
122 			break;
123 
124 		case 253:  // 1 transparent pixel
125 			pixels++;
126 			x_offset++;
127 			break;
128 
129 		default:  // set a pixel
130 			if (pixels >= pixels_ul)
131 				return;
132 			if (pixels >= pixels_ll)
133 				*pixels = *data;
134 
135 			pixels++;
136 			x_offset++;
137 			break;
138 		}
139 		if (x_offset >= width)
140 		{
141 			pixels += surface->pitch - x_offset;
142 			x_offset = 0;
143 		}
144 	}
145 }
146 
147 // does not clip on left or right edges of surface
blit_sprite_blend(SDL_Surface * surface,int x,int y,unsigned int table,unsigned int index)148 void blit_sprite_blend( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index )
149 {
150 	if (index >= sprite_table[table].count || !sprite_exists(table, index))
151 	{
152 		assert(false);
153 		return;
154 	}
155 
156 	const Sprite * const cur_sprite = sprite(table, index);
157 
158 	const Uint8 *data = cur_sprite->data;
159 	const Uint8 * const data_ul = data + cur_sprite->size;
160 
161 	const unsigned int width = cur_sprite->width;
162 	unsigned int x_offset = 0;
163 
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
168 
169 	for (; data < data_ul; ++data)
170 	{
171 		switch (*data)
172 		{
173 		case 255:  // transparent pixels
174 			data++;  // next byte tells how many
175 			pixels += *data;
176 			x_offset += *data;
177 			break;
178 
179 		case 254:  // next pixel row
180 			pixels += width - x_offset;
181 			x_offset = width;
182 			break;
183 
184 		case 253:  // 1 transparent pixel
185 			pixels++;
186 			x_offset++;
187 			break;
188 
189 		default:  // set a pixel
190 			if (pixels >= pixels_ul)
191 				return;
192 			if (pixels >= pixels_ll)
193 				*pixels = (*data & 0xf0) | (((*pixels & 0x0f) + (*data & 0x0f)) / 2);
194 
195 			pixels++;
196 			x_offset++;
197 			break;
198 		}
199 		if (x_offset >= width)
200 		{
201 			pixels += surface->pitch - x_offset;
202 			x_offset = 0;
203 		}
204 	}
205 }
206 
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'
blit_sprite_hv_unsafe(SDL_Surface * surface,int x,int y,unsigned int table,unsigned int index,Uint8 hue,Sint8 value)210 void blit_sprite_hv_unsafe( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index, Uint8 hue, Sint8 value )
211 {
212 	if (index >= sprite_table[table].count || !sprite_exists(table, index))
213 	{
214 		assert(false);
215 		return;
216 	}
217 
218 	hue <<= 4;
219 
220 	const Sprite * const cur_sprite = sprite(table, index);
221 
222 	const Uint8 *data = cur_sprite->data;
223 	const Uint8 * const data_ul = data + cur_sprite->size;
224 
225 	const unsigned int width = cur_sprite->width;
226 	unsigned int x_offset = 0;
227 
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
232 
233 	for (; data < data_ul; ++data)
234 	{
235 		switch (*data)
236 		{
237 		case 255:  // transparent pixels
238 			data++;  // next byte tells how many
239 			pixels += *data;
240 			x_offset += *data;
241 			break;
242 
243 		case 254:  // next pixel row
244 			pixels += width - x_offset;
245 			x_offset = width;
246 			break;
247 
248 		case 253:  // 1 transparent pixel
249 			pixels++;
250 			x_offset++;
251 			break;
252 
253 		default:  // set a pixel
254 			if (pixels >= pixels_ul)
255 				return;
256 			if (pixels >= pixels_ll)
257 				*pixels = hue | ((*data & 0x0f) + value);
258 
259 			pixels++;
260 			x_offset++;
261 			break;
262 		}
263 		if (x_offset >= width)
264 		{
265 			pixels += surface->pitch - x_offset;
266 			x_offset = 0;
267 		}
268 	}
269 }
270 
271 // does not clip on left or right edges of surface
blit_sprite_hv(SDL_Surface * surface,int x,int y,unsigned int table,unsigned int index,Uint8 hue,Sint8 value)272 void blit_sprite_hv( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index, Uint8 hue, Sint8 value )
273 {
274 	if (index >= sprite_table[table].count || !sprite_exists(table, index))
275 	{
276 		assert(false);
277 		return;
278 	}
279 
280 	hue <<= 4;
281 
282 	const Sprite * const cur_sprite = sprite(table, index);
283 
284 	const Uint8 *data = cur_sprite->data;
285 	const Uint8 * const data_ul = data + cur_sprite->size;
286 
287 	const unsigned int width = cur_sprite->width;
288 	unsigned int x_offset = 0;
289 
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
294 
295 	for (; data < data_ul; ++data)
296 	{
297 		switch (*data)
298 		{
299 		case 255:  // transparent pixels
300 			data++;  // next byte tells how many
301 			pixels += *data;
302 			x_offset += *data;
303 			break;
304 
305 		case 254:  // next pixel row
306 			pixels += width - x_offset;
307 			x_offset = width;
308 			break;
309 
310 		case 253:  // 1 transparent pixel
311 			pixels++;
312 			x_offset++;
313 			break;
314 
315 		default:  // set a pixel
316 			if (pixels >= pixels_ul)
317 				return;
318 			if (pixels >= pixels_ll)
319 			{
320 				Uint8 temp_value = (*data & 0x0f) + value;
321 				if (temp_value > 0xf)
322 					temp_value = (temp_value >= 0x1f) ? 0x0 : 0xf;
323 
324 				*pixels = hue | temp_value;
325 			}
326 
327 			pixels++;
328 			x_offset++;
329 			break;
330 		}
331 		if (x_offset >= width)
332 		{
333 			pixels += surface->pitch - x_offset;
334 			x_offset = 0;
335 		}
336 	}
337 }
338 
339 // does not clip on left or right edges of surface
blit_sprite_hv_blend(SDL_Surface * surface,int x,int y,unsigned int table,unsigned int index,Uint8 hue,Sint8 value)340 void blit_sprite_hv_blend( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index, Uint8 hue, Sint8 value )
341 {
342 	if (index >= sprite_table[table].count || !sprite_exists(table, index))
343 	{
344 		assert(false);
345 		return;
346 	}
347 
348 	hue <<= 4;
349 
350 	const Sprite * const cur_sprite = sprite(table, index);
351 
352 	const Uint8 *data = cur_sprite->data;
353 	const Uint8 * const data_ul = data + cur_sprite->size;
354 
355 	const unsigned int width = cur_sprite->width;
356 	unsigned int x_offset = 0;
357 
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
362 
363 	for (; data < data_ul; ++data)
364 	{
365 		switch (*data)
366 		{
367 		case 255:  // transparent pixels
368 			data++;  // next byte tells how many
369 			pixels += *data;
370 			x_offset += *data;
371 			break;
372 
373 		case 254:  // next pixel row
374 			pixels += width - x_offset;
375 			x_offset = width;
376 			break;
377 
378 		case 253:  // 1 transparent pixel
379 			pixels++;
380 			x_offset++;
381 			break;
382 
383 		default:  // set a pixel
384 			if (pixels >= pixels_ul)
385 				return;
386 			if (pixels >= pixels_ll)
387 			{
388 				Uint8 temp_value = (*data & 0x0f) + value;
389 				if (temp_value > 0xf)
390 					temp_value = (temp_value >= 0x1f) ? 0x0 : 0xf;
391 
392 				*pixels = hue | (((*pixels & 0x0f) + temp_value) / 2);
393 			}
394 
395 			pixels++;
396 			x_offset++;
397 			break;
398 		}
399 		if (x_offset >= width)
400 		{
401 			pixels += surface->pitch - x_offset;
402 			x_offset = 0;
403 		}
404 	}
405 }
406 
407 // does not clip on left or right edges of surface
blit_sprite_dark(SDL_Surface * surface,int x,int y,unsigned int table,unsigned int index,bool black)408 void blit_sprite_dark( SDL_Surface *surface, int x, int y, unsigned int table, unsigned int index, bool black )
409 {
410 	if (index >= sprite_table[table].count || !sprite_exists(table, index))
411 	{
412 		assert(false);
413 		return;
414 	}
415 
416 	const Sprite * const cur_sprite = sprite(table, index);
417 
418 	const Uint8 *data = cur_sprite->data;
419 	const Uint8 * const data_ul = data + cur_sprite->size;
420 
421 	const unsigned int width = cur_sprite->width;
422 	unsigned int x_offset = 0;
423 
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
428 
429 	for (; data < data_ul; ++data)
430 	{
431 		switch (*data)
432 		{
433 		case 255:  // transparent pixels
434 			data++;  // next byte tells how many
435 			pixels += *data;
436 			x_offset += *data;
437 			break;
438 
439 		case 254:  // next pixel row
440 			pixels += width - x_offset;
441 			x_offset = width;
442 			break;
443 
444 		case 253:  // 1 transparent pixel
445 			pixels++;
446 			x_offset++;
447 			break;
448 
449 		default:  // set a pixel
450 			if (pixels >= pixels_ul)
451 				return;
452 			if (pixels >= pixels_ll)
453 				*pixels = black ? 0x00 : ((*pixels & 0xf0) | ((*pixels & 0x0f) / 2));
454 
455 			pixels++;
456 			x_offset++;
457 			break;
458 		}
459 		if (x_offset >= width)
460 		{
461 			pixels += surface->pitch - x_offset;
462 			x_offset = 0;
463 		}
464 	}
465 }
466 
467 
JE_loadCompShapes(Sprite2_array * sprite2s,char s)468 void JE_loadCompShapes( Sprite2_array *sprite2s, char s )
469 {
470 	char buffer[20];
471 	snprintf(buffer, sizeof(buffer), "newsh%c.shp", tolower((unsigned char)s));
472 
473 	FILE *f = dir_fopen_die(data_dir(), buffer, "rb");
474 
475 	sprite2s->size = ftell_eof(f);
476 
477 	JE_loadCompShapesB(sprite2s, f);
478 
479 	fclose(f);
480 }
481 
JE_loadCompShapesB(Sprite2_array * sprite2s,FILE * f)482 void JE_loadCompShapesB( Sprite2_array *sprite2s, FILE *f )
483 {
484 	free_sprite2s(sprite2s);
485 
486 	sprite2s->data = malloc(sizeof(Uint8) * sprite2s->size);
487 	efread(sprite2s->data, sizeof(Uint8), sprite2s->size, f);
488 }
489 
free_sprite2s(Sprite2_array * sprite2s)490 void free_sprite2s( Sprite2_array *sprite2s )
491 {
492 	free(sprite2s->data);
493 	sprite2s->data = NULL;
494 }
495 
496 // does not clip on left or right edges of surface
blit_sprite2(SDL_Surface * surface,int x,int y,Sprite2_array sprite2s,unsigned int index)497 void blit_sprite2( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
498 {
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
503 
504 	const Uint8 *data = sprite2s.data + SDL_SwapLE16(((Uint16 *)sprite2s.data)[index - 1]);
505 
506 	for (; *data != 0x0f; ++data)
507 	{
508 		pixels += *data & 0x0f;                   // second nibble: transparent pixel count
509 		unsigned int count = (*data & 0xf0) >> 4; // first nibble: opaque pixel count
510 
511 		if (count == 0) // move to next pixel row
512 		{
513 			pixels += VGAScreen->pitch - 12;
514 		}
515 		else
516 		{
517 			while (count--)
518 			{
519 				++data;
520 
521 				if (pixels >= pixels_ul)
522 					return;
523 				if (pixels >= pixels_ll)
524 					*pixels = *data;
525 
526 				++pixels;
527 			}
528 		}
529 	}
530 }
531 
532 // does not clip on left or right edges of surface
blit_sprite2_blend(SDL_Surface * surface,int x,int y,Sprite2_array sprite2s,unsigned int index)533 void blit_sprite2_blend( SDL_Surface *surface,  int x, int y, Sprite2_array sprite2s, unsigned int index )
534 {
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
539 
540 	const Uint8 *data = sprite2s.data + SDL_SwapLE16(((Uint16 *)sprite2s.data)[index - 1]);
541 
542 	for (; *data != 0x0f; ++data)
543 	{
544 		pixels += *data & 0x0f;                   // second nibble: transparent pixel count
545 		unsigned int count = (*data & 0xf0) >> 4; // first nibble: opaque pixel count
546 
547 		if (count == 0) // move to next pixel row
548 		{
549 			pixels += VGAScreen->pitch - 12;
550 		}
551 		else
552 		{
553 			while (count--)
554 			{
555 				++data;
556 
557 				if (pixels >= pixels_ul)
558 					return;
559 				if (pixels >= pixels_ll)
560 					*pixels = (((*data & 0x0f) + (*pixels & 0x0f)) / 2) | (*data & 0xf0);
561 
562 				++pixels;
563 			}
564 		}
565 	}
566 }
567 
568 // does not clip on left or right edges of surface
blit_sprite2_darken(SDL_Surface * surface,int x,int y,Sprite2_array sprite2s,unsigned int index)569 void blit_sprite2_darken( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
570 {
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
575 
576 	const Uint8 *data = sprite2s.data + SDL_SwapLE16(((Uint16 *)sprite2s.data)[index - 1]);
577 
578 	for (; *data != 0x0f; ++data)
579 	{
580 		pixels += *data & 0x0f;                   // second nibble: transparent pixel count
581 		unsigned int count = (*data & 0xf0) >> 4; // first nibble: opaque pixel count
582 
583 		if (count == 0) // move to next pixel row
584 		{
585 			pixels += VGAScreen->pitch - 12;
586 		}
587 		else
588 		{
589 			while (count--)
590 			{
591 				++data;
592 
593 				if (pixels >= pixels_ul)
594 					return;
595 				if (pixels >= pixels_ll)
596 					*pixels = ((*pixels & 0x0f) / 2) + (*pixels & 0xf0);
597 
598 				++pixels;
599 			}
600 		}
601 	}
602 }
603 
604 // does not clip on left or right edges of surface
blit_sprite2_filter(SDL_Surface * surface,int x,int y,Sprite2_array sprite2s,unsigned int index,Uint8 filter)605 void blit_sprite2_filter( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index, Uint8 filter )
606 {
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
611 
612 	const Uint8 *data = sprite2s.data + SDL_SwapLE16(((Uint16 *)sprite2s.data)[index - 1]);
613 
614 	for (; *data != 0x0f; ++data)
615 	{
616 		pixels += *data & 0x0f;                   // second nibble: transparent pixel count
617 		unsigned int count = (*data & 0xf0) >> 4; // first nibble: opaque pixel count
618 
619 		if (count == 0) // move to next pixel row
620 		{
621 			pixels += VGAScreen->pitch - 12;
622 		}
623 		else
624 		{
625 			while (count--)
626 			{
627 				++data;
628 
629 				if (pixels >= pixels_ul)
630 					return;
631 				if (pixels >= pixels_ll)
632 					*pixels = filter | (*data & 0x0f);
633 
634 				++pixels;
635 			}
636 		}
637 	}
638 }
639 
640 // does not clip on left or right edges of surface
blit_sprite2x2(SDL_Surface * surface,int x,int y,Sprite2_array sprite2s,unsigned int index)641 void blit_sprite2x2( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
642 {
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);
647 }
648 
649 // does not clip on left or right edges of surface
blit_sprite2x2_blend(SDL_Surface * surface,int x,int y,Sprite2_array sprite2s,unsigned int index)650 void blit_sprite2x2_blend( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
651 {
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);
656 }
657 
658 // does not clip on left or right edges of surface
blit_sprite2x2_darken(SDL_Surface * surface,int x,int y,Sprite2_array sprite2s,unsigned int index)659 void blit_sprite2x2_darken( SDL_Surface *surface, int x, int y, Sprite2_array sprite2s, unsigned int index )
660 {
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);
665 }
666 
667 
JE_loadMainShapeTables(const char * shpfile)668 void JE_loadMainShapeTables( const char *shpfile )
669 {
670 #ifdef TYRIAN2000
671 	const int SHP_NUM = 13;
672 #else
673 	const int SHP_NUM = 12;
674 #endif
675 
676 	FILE *f = dir_fopen_die(data_dir(), shpfile, "rb");
677 
678 	JE_word shpNumb;
679 	JE_longint shpPos[SHP_NUM + 1]; // +1 for storing file length
680 
681 	efread(&shpNumb, sizeof(JE_word), 1, f);
682 	assert(shpNumb + 1u == COUNTOF(shpPos));
683 
684 	for (unsigned int i = 0; i < shpNumb; ++i)
685 		efread(&shpPos[i], sizeof(JE_longint), 1, f);
686 
687 	fseek(f, 0, SEEK_END);
688 	for (unsigned int i = shpNumb; i < COUNTOF(shpPos); ++i)
689 		shpPos[i] = ftell(f);
690 
691 	int i;
692 	// fonts, interface, option sprites
693 	for (i = 0; i < 7; i++)
694 	{
695 		fseek(f, shpPos[i], SEEK_SET);
696 		load_sprites(i, f);
697 	}
698 
699 	// player shot sprites
700 	shapesC1.size = shpPos[i + 1] - shpPos[i];
701 	JE_loadCompShapesB(&shapesC1, f);
702 	i++;
703 
704 	// player ship sprites
705 	shapes9.size = shpPos[i + 1] - shpPos[i];
706 	JE_loadCompShapesB(&shapes9 , f);
707 	i++;
708 
709 	// power-up sprites
710 	eShapes[5].size = shpPos[i + 1] - shpPos[i];
711 	JE_loadCompShapesB(&eShapes[5], f);
712 	i++;
713 
714 	// coins, datacubes, etc sprites
715 	eShapes[4].size = shpPos[i + 1] - shpPos[i];
716 	JE_loadCompShapesB(&eShapes[4], f);
717 	i++;
718 
719 	// more player shot sprites
720 	shapesW2.size = shpPos[i + 1] - shpPos[i];
721 	JE_loadCompShapesB(&shapesW2, f);
722 
723 	fclose(f);
724 }
725 
free_main_shape_tables(void)726 void free_main_shape_tables( void )
727 {
728 	for (uint i = 0; i < COUNTOF(sprite_table); ++i)
729 		free_sprites(i);
730 
731 	free_sprite2s(&shapesC1);
732 	free_sprite2s(&shapes9);
733 	free_sprite2s(&eShapes[5]);
734 	free_sprite2s(&eShapes[4]);
735 	free_sprite2s(&shapesW2);
736 }
737