Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Alternate colour blit

This thread is locked; no one can reply to it. rss feed Print
Alternate colour blit
weapon_S
Member #7,859
October 2006
avatar

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 
6void 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.

Marco Radaelli
Member #3,028
December 2002
avatar

Have you run any test? In case post the results.

weapon_S
Member #7,859
October 2006
avatar

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.

Tobias Dammers
Member #2,604
August 2002
avatar

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.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Go to: