This is old C++ code originally intended to be a playground for 3D math.
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

#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;
}
}
}