canvas_imp_rgb.cpp
3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "canvas_imp_rgb.h"
#include <cstdio>
void canvas_imp_rgb::compute_color_resolution(void) {
for(unsigned rgb=red; rgb<=blue; rgb++) {
unsigned mask_tmp=col_mask[rgb];
for(col_shift[rgb]=0; (mask_tmp & 0x01) == 0; col_shift[rgb]++)
mask_tmp>>=1;
for(col_max[rgb]=1; mask_tmp & 0x01 == 1; col_max[rgb]*=2)
mask_tmp>>=1;
col_max[rgb]--;
}
}
void canvas_imp_rgb::compute_light_table(void) {
for(unsigned rgb=red; rgb<=blue; rgb++)
for(unsigned c=0; c<=col_max[rgb]; c++)
for(unsigned i=0; i<NUM_LIGHT_LEVELS; i++)
light_table[rgb][c*NUM_LIGHT_LEVELS+i]=c*i/MAX_LIGHT_LEVELS;
}
void canvas_imp_rgb::compute_fog_table(void) {
for(unsigned rgb=red; rgb<=blue; rgb++)
for(unsigned c=0; c<=col_max[rgb]; c++)
for(unsigned i=0; i<NUM_FOG_LEVELS; i++)
fog_table[rgb][c*NUM_FOG_LEVELS+i]=
c+(unsigned)(((float)i/MAX_FOG_LEVELS)*(col_max[rgb]-c));
}
canvas_imp_rgb::canvas_imp_rgb(unsigned long red_mask,
unsigned long green_mask,
unsigned long blue_mask,
char bytes_per_pixel,
char bytes_per_rgb) {
this->col_mask[red]=red_mask;
this->col_mask[green]=green_mask;
this->col_mask[blue]=blue_mask;
this->bytes_per_pixel=bytes_per_pixel;
this->bytes_per_rgb=bytes_per_rgb;
ext_max_red=255;
ext_max_green=255;
ext_max_blue=255;
compute_color_resolution();
light_table[red]=new unsigned[(col_max[red]+1)*NUM_LIGHT_LEVELS];
light_table[green]=new unsigned[(col_max[green]+1)*NUM_LIGHT_LEVELS];
light_table[blue]=new unsigned[(col_max[blue]+1)*NUM_LIGHT_LEVELS];
fog_table[red]=new unsigned[(col_max[red]+1)*NUM_FOG_LEVELS];
fog_table[green]=new unsigned[(col_max[green]+1)*NUM_FOG_LEVELS];
fog_table[blue]=new unsigned[(col_max[blue]+1)*NUM_FOG_LEVELS];
compute_light_table();
compute_fog_table();
}
unsigned long canvas_imp_rgb::ext_to_native(unsigned red,
unsigned green,
unsigned blue) {
unsigned long red_rescaled=red * col_max[this->red] / ext_max_red;
unsigned long green_rescaled=green * col_max[this->green] / ext_max_green;
unsigned long blue_rescaled=blue * col_max[this->blue] / ext_max_blue;
return (red_rescaled << col_shift[this->red]) |
(green_rescaled << col_shift[this->green]) |
(blue_rescaled << col_shift[this->blue]);
}
void canvas_imp_rgb::light_native(unsigned long* col, unsigned intense) {
unsigned char* c2=(unsigned char*)col;
unsigned long color=0;
unsigned long color_shift=0;
for(register int p=0; p<bytes_per_rgb; p++) {
color += (*c2++) << color_shift;
color_shift += 8; // 8=BITS_PER_BYTE
}
// mögliche restliche bytes zwischen bytes_per_rgb und
// bytes_per_pixel überspringen (warum muss ich nochmal
// rausfinden.
for(register int p=bytes_per_rgb; p<bytes_per_pixel; p++)
c2++;
unsigned long r=(color&col_mask[red]) >> col_shift[red];
unsigned long g=(color&col_mask[green]) >> col_shift[green];
unsigned long b=(color&col_mask[blue]) >> col_shift[blue];
color=(light_table[red][r*NUM_LIGHT_LEVELS+intense] <<
col_shift[red]) |
(light_table[green][g*NUM_LIGHT_LEVELS+intense] <<
col_shift[green]) |
(light_table[blue][b*NUM_LIGHT_LEVELS+intense] <<
col_shift[blue]);
{
register int i;
unsigned long mask = 255;
char shift = 0;
for(c2-=bytes_per_pixel, i=0; i<bytes_per_pixel; i++) {
*c2 = (color & mask) >> shift;
c2++;
mask <<= 8;
shift += 8;
}
}
}