Generally what I tried to do, is considered bad and hackish... And there are plenty of topics about it, I think.
And I was told not to, but I couldn't resist!
But this is what I basically copied from the allegro source to display one or more sprites with indexed colour in different colours:
To display a sprite with an alternate set of colours.
It doesn't care about image boundaries though. And there are probably other flaws, perhaps you would like to tell me about, please? Basically it's working.
1 | #include <allegro.h> |
2 | #include "aintern.h" |
3 | #include <string.h> |
4 | #define Charsize 1 |
5 | |
6 | void blit_from_256_custom_noob(BITMAP *src, BITMAP *dest, int s_x, int s_y, int d_x, int d_y, int w, int h, int NOOB_OFFSET) |
7 | { |
8 | uintptr_t s, d; |
9 | unsigned char *ss; |
10 | int x, y, c, rc; |
11 | |
12 | if(bitmap_color_depth(dest)==8){ |
13 | if (is_memory_bitmap(src)) { |
14 | /* fast version when reading from memory bitmap */ |
15 | bmp_select(dest); |
16 | |
17 | for (y=0; y<h; y++) { |
18 | ss = src->line[s_y+y] + s_x; |
19 | d = bmp_write_line(dest, d_y+y) + d_x*Charsize; |
20 | |
21 | for (x=0; x<w; x++) { |
22 | bmp_write8(d, (*ss) + NOOB_OFFSET); |
23 | ss++; |
24 | d += Charsize; |
25 | } |
26 | } |
27 | |
28 | bmp_unwrite_line(dest); |
29 | } |
30 | else { |
31 | /* slower version when reading from the screen */ |
32 | for (y=0; y<h; y++) { |
33 | s = bmp_read_line(src, s_y+y) + s_x; |
34 | d = bmp_write_line(dest, d_y+y) + d_x*Charsize; |
35 | |
36 | for (x=0; x<w; x++) { |
37 | bmp_select(src); |
38 | c = bmp_read8(s); |
39 | |
40 | bmp_select(dest); |
41 | bmp_write8(d, c+NOOB_OFFSET); |
42 | |
43 | s++; |
44 | d += Charsize; |
45 | } |
46 | } |
47 | |
48 | bmp_unwrite_line(src); |
49 | bmp_unwrite_line(dest); |
50 | } |
51 | |
52 | } |
53 | else{ |
54 | |
55 | int *dest_palette_color; |
56 | |
57 | /* lookup table avoids repeated color format conversions */ |
58 | if (_color_conv & COLORCONV_KEEP_TRANS) { |
59 | dest_palette_color = _AL_MALLOC_ATOMIC(256*sizeof(int)); |
60 | memcpy(dest_palette_color, _palette_expansion_table(bitmap_color_depth(dest)), 256*sizeof(int)); |
61 | |
62 | int depth, g = 0; |
63 | depth = bitmap_color_depth(dest); |
64 | if (depth == 8) { |
65 | if (rgb_map) |
66 | rc = rgb_map->data[31][1][31]; |
67 | else |
68 | rc = bestfit_color(_current_palette, 63, 1, 63); |
69 | } |
70 | else { |
71 | do |
72 | rc = makecol_depth(depth, 255, ++g, 255); |
73 | while (rc == bitmap_mask_color(dest)); |
74 | } |
75 | |
76 | dest_palette_color[MASK_COLOR_8] = bitmap_mask_color(dest); |
77 | |
78 | for (c=0; c<256; c++) { |
79 | if ((c != MASK_COLOR_8) && |
80 | (dest_palette_color[c] == bitmap_mask_color(dest))) |
81 | dest_palette_color[c] = rc; |
82 | } |
83 | } |
84 | else |
85 | dest_palette_color = _palette_expansion_table(bitmap_color_depth(dest)); |
86 | |
87 | /* worker macro */ |
88 | #define EXPAND_BLIT(bits, dsize) \ |
89 | { \ |
90 | if (is_memory_bitmap(src)) { \ |
91 | /* fast version when reading from memory bitmap */ \ |
92 | bmp_select(dest); \ |
93 | \ |
94 | for (y=0; y<h; y++) { \ |
95 | ss = src->line[s_y+y] + s_x; \ |
96 | d = bmp_write_line(dest, d_y+y) + d_x*dsize; \ |
97 | \ |
98 | for (x=0; x<w; x++) { \ |
99 | bmp_write##bits(d, dest_palette_color[(*ss)+NOOB_OFFSET]); \ |
100 | ss++; \ |
101 | d += dsize; \ |
102 | } \ |
103 | } \ |
104 | \ |
105 | bmp_unwrite_line(dest); \ |
106 | } \ |
107 | else { \ |
108 | /* slower version when reading from the screen */ \ |
109 | for (y=0; y<h; y++) { \ |
110 | s = bmp_read_line(src, s_y+y) + s_x; \ |
111 | d = bmp_write_line(dest, d_y+y) + d_x*dsize; \ |
112 | \ |
113 | for (x=0; x<w; x++) { \ |
114 | bmp_select(src); \ |
115 | c = bmp_read8(s); \ |
116 | \ |
117 | bmp_select(dest); \ |
118 | bmp_write##bits(d, dest_palette_color[c+NOOB_OFFSET]); \ |
119 | \ |
120 | s++; \ |
121 | d += dsize; \ |
122 | } \ |
123 | } \ |
124 | \ |
125 | bmp_unwrite_line(src); \ |
126 | bmp_unwrite_line(dest); \ |
127 | } \ |
128 | } |
129 | |
130 | /* expand the above macro for each possible output depth */ |
131 | switch (bitmap_color_depth(dest)) { |
132 | |
133 | #ifdef ALLEGRO_COLOR16 |
134 | case 15: |
135 | case 16: |
136 | EXPAND_BLIT(16, sizeof(int16_t)); |
137 | break; |
138 | #endif |
139 | |
140 | #ifdef ALLEGRO_COLOR24 |
141 | case 24: |
142 | EXPAND_BLIT(24, 3); |
143 | break; |
144 | #endif |
145 | |
146 | #ifdef ALLEGRO_COLOR32 |
147 | case 32: |
148 | EXPAND_BLIT(32, sizeof(int32_t)); |
149 | break; |
150 | #endif |
151 | } |
152 | |
153 | if (_color_conv & COLORCONV_KEEP_TRANS) |
154 | _AL_FREE(dest_palette_color); |
155 | }/*else*/ |
156 | } |
Or perhaps you may find it useful... but since I could pull it off, I doubt it.
Have you run any test? In case post the results.
Tests...? With results?! I'm not sure what you are refering to.
I have sort of a test program attached. At first I accidently forgot to set the cutoff of the first picture properly, and it flunked.
For the rest it's working under all the colordepths my computer manages... Unless... I'm not sure what to test for. Unless you mean profiling?
Besides, if you see the original code, you would notice I only changed the lines which contain "NOOB_OFFSET"; not even the comment is mine.
Um, what exactly are you doing there? Replacing colours in a paletted sprite? It can be done without any hacks or custom routines. In paletted mode, set up a custom blending table (mapping the original color index to the desired best match) and draw the sprite as a lit sprite. In hi/truecolor mode, just select a different palette.