palpic2png.c: improve, make usable with ppic binary files
[rofl0r-openDOW.git] / palpic.c
blobc6b8f1b314557063c0446f3c01718d135677e412
1 #include "palpic.h"
3 #define PRGB_BLACK PRGB(0x00,0x00,0x00)
5 #if defined(PALPIC_SDL) && !defined(PALPIC_OPENGL)
6 #include "sdl_rgb.h"
7 typedef sdl_rgb_t output_rgb_t;
8 #define output_rgb_as_int asInt
9 #define RGB_WHITE SRGB(0xFF,0xFF,0xFF)
10 #define RGB_BLACK SRGB(0x00,0x00,0x00)
11 #else
12 typedef prgb output_rgb_t;
13 #define output_rgb_as_int val
14 #define RGB_WHITE PRGB(0xFF,0xFF,0xFF)
15 #define RGB_BLACK PRGB(0x00,0x00,0x00)
16 #endif
18 #if 0
19 static output_rgb_t convert_prgb(prgb col) {
20 output_rgb_t ret;
21 ret.colors.r = col.colors.r;
22 ret.colors.g = col.colors.g;
23 ret.colors.b = col.colors.b;
24 ret.colors.a = col.colors.a;
25 return ret;
27 #else
29 #if defined(PALPIC_SDL) && !defined(PALPIC_OPENGL)
30 /* warning: this macro is to get reasonable performance in -O0 mode
31 * it only work as long as the sdl ARGB and the prgb RGBA type remain unchanged
32 * since the alpha value is unused in SDL 2D, we can safely zero it. */
33 #define convert_prgb(x) ((output_rgb_t){ .output_rgb_as_int = x .val >> 8 } )
34 #else
35 #define convert_prgb(x) ((output_rgb_t){ .output_rgb_as_int = x .val } )
36 #endif
38 #endif
39 void blit_sprite(int x_pos, int y_pos, struct vo_desc *video,
40 unsigned scale, const struct palpic* pic, uint16_t spritenum, const prgb *palette) {
41 unsigned sprite_width = palpic_getspritewidth(pic);
42 unsigned sprite_height = palpic_getspriteheight(pic);
43 if(!palette) palette = palpic_getpalette(pic);
44 const uint8_t *bitmap = palpic_getspritedata(pic, spritenum);
45 unsigned int scale_y, scale_x, y, x;
46 int x_tl_off = 0, y_tl_off = 0;
47 int x_br_off = 0, y_br_off = 0;
48 if(x_pos >= (int)video->width) return;
49 else if(x_pos < 0) x_tl_off = -x_pos/scale + !!(x_pos%scale);
50 else if(x_pos + sprite_width * scale >= video->width) {
51 x_br_off = x_pos + sprite_width * scale - video->width;
52 x_br_off=x_br_off/scale+!!(x_br_off%scale);
54 if(y_pos >= (int)video->height) return;
55 else if(y_pos < 0) y_tl_off = -y_pos/scale + !!(y_pos%scale);
56 else if(y_pos + sprite_height * scale >= video->height) {
57 y_br_off = y_pos + sprite_height * scale - video->height;
58 y_br_off=y_br_off/scale+!!(y_br_off%scale);
61 unsigned lineoffset = (y_pos + y_tl_off*scale) * (video->pitch / 4);
62 unsigned pixel_start = y_tl_off * sprite_width + x_tl_off;
63 static const output_rgb_t mask_colors_transp[2] = {
64 [0] = (RGB_BLACK),
65 [1] = (RGB_WHITE),
67 static const output_rgb_t mask_colors_non_transp[2] = {
68 [0] = (RGB_BLACK),
69 [1] = (RGB_BLACK),
71 const output_rgb_t *mask_colors = (pic->flags & PPF_TRANSPARENT ? mask_colors_transp : mask_colors_non_transp);
72 for (y = y_tl_off; y < sprite_height - y_br_off; y++) {
73 for(scale_y = 0; scale_y < scale; scale_y++) {
74 output_rgb_t *ptr = &((output_rgb_t *) video->mem)[lineoffset + x_pos + x_tl_off];
75 const uint8_t *p = &bitmap[pixel_start];
76 for (x = x_tl_off; x < sprite_width - x_br_off; x++) {
77 prgb col = palette[*p++];
78 uint32_t mask = mask_colors[(col.val == PRGB_BLACK.val)].output_rgb_as_int;
79 for(scale_x = 0; scale_x < scale; scale_x++) {
80 ptr[0].output_rgb_as_int &= mask;
81 ptr[0].output_rgb_as_int |= convert_prgb(col).output_rgb_as_int;
82 ptr++;
85 lineoffset += video->pitch / 4;
87 pixel_start += sprite_width;