You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.7 KiB
112 lines
3.7 KiB
#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;
|
|
}
|
|
}
|
|
}
|