/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at golgotha_source@usa.net (Subject should have "GOLG" in it) ***********************************************************************/ #include "mip_average.hh" #include "palette/pal.hh" #include "mip.hh" #includevoid setup_pixel_formats(i4_pixel_format ®_fmt, i4_pixel_format &chroma_fmt, i4_pixel_format &alpha_fmt, w32 chroma_color) { //regular format setup mip_b_shift = 8-reg_fmt.blue_bits; mip_b_and = reg_fmt.blue_mask; mip_g_shift = reg_fmt.blue_bits - (8-reg_fmt.green_bits); mip_g_and = reg_fmt.green_mask; mip_r_shift = reg_fmt.green_bits + reg_fmt.blue_bits - (8-reg_fmt.red_bits); mip_r_and = reg_fmt.red_mask; //chroma format setup mip_c_b_shift = 8-chroma_fmt.blue_bits; mip_c_b_and = chroma_fmt.blue_mask; mip_c_g_shift = chroma_fmt.blue_bits - (8-chroma_fmt.green_bits); mip_c_g_and = chroma_fmt.green_mask; mip_c_r_shift = chroma_fmt.green_bits + chroma_fmt.blue_bits - (8-chroma_fmt.red_bits); mip_c_r_and = chroma_fmt.red_mask; mip_c_a_shift = chroma_fmt.green_bits + chroma_fmt.blue_bits + chroma_fmt.red_bits - (8-chroma_fmt.alpha_bits); mip_c_a_and = chroma_fmt.alpha_mask; //alpha format setup mip_a_b_shift = 8-alpha_fmt.blue_bits; mip_a_b_and = alpha_fmt.blue_mask; mip_a_g_shift = alpha_fmt.blue_bits - (8-alpha_fmt.green_bits); mip_a_g_and = alpha_fmt.green_mask; mip_a_r_shift = alpha_fmt.green_bits + alpha_fmt.blue_bits - (8-alpha_fmt.red_bits); mip_a_r_and = alpha_fmt.red_mask; mip_a_a_shift = alpha_fmt.green_bits + alpha_fmt.blue_bits + alpha_fmt.red_bits - (8-alpha_fmt.alpha_bits); mip_a_a_and = alpha_fmt.alpha_mask; //chroma key color setup mip_chroma_red = (chroma_color & 0xFF0000) >> 16; mip_chroma_green = (chroma_color & 0x00FF00) >> 8; mip_chroma_blue = (chroma_color & 0x0000FF); } void r1_dos_paths(char *src) { while (*src) { if (*src=='/') *src='\\'; src++; } } void r1_unix_paths(char *src) { while (*src) { if (*src=='\\') *src='/'; src++; } } char *r1_remove_paths(char *src) { char *ret = src; while (*src) { if (*src=='/') ret=src+1; src++; } return ret; } void r1_remove_extention(char *src) { while (*src) { if (*src=='.') { *src=0; return; } src++; } } void concatenate_path(char *src, char *path) { char temp[256]; char *last_path = r1_remove_paths(src); strcpy(temp,last_path); *last_path=0; strcat(src,path); strcat(src,temp); } void chroma_process(w8 *&p, float &r, float &g, float &b, sw8 &num_regular, sw8 &num_chroma) { if (p[0]==mip_chroma_red && p[1]==mip_chroma_green && p[2]==mip_chroma_blue) { //IS the chroma color. dont average num_chroma++; } else { //not the chroma color. average as a regular pixel r += (float)(p[0]); g += (float)(p[1]); b += (float)(p[2]); num_regular++; } } void average_4x4_chroma(w16 *&dst, w8 *dst_24, w8 *&p0, w8 *p1, w8 *p2, w8 *p3) { sw8 num_chroma = 0; sw8 num_regular = 0; float r=0; float g=0; float b=0; chroma_process(p0,r,g,b,num_regular,num_chroma); chroma_process(p1,r,g,b,num_regular,num_chroma); chroma_process(p2,r,g,b,num_regular,num_chroma); chroma_process(p3,r,g,b,num_regular,num_chroma); //return the chroma color if (num_chroma > num_regular) { //alpha component and rgb component of 16-bit pixel should be entirely 0'd dst_24[0] = mip_chroma_red; dst_24[1] = mip_chroma_green; dst_24[2] = mip_chroma_blue; *dst = 0; return; } float ooreg = 1.f / num_regular; r *= ooreg; if (r<0) r=0; if (r>255) r = 255; g *= ooreg; if (g<0) g=0; if (g>255) g = 255; b *= ooreg; if (b<0) b=0; if (b>255) b = 255; dst_24[0] = (w8)r; dst_24[1] = (w8)g; dst_24[2] = (w8)b; *dst = (( (w16)dst_24[0] << mip_c_r_shift) & mip_c_r_and) | (( (w16)dst_24[1] << mip_c_g_shift) & mip_c_g_and) | (( (w16)dst_24[2] >> mip_c_b_shift) & mip_c_b_and) | (( 0xFFFFFFFF << mip_c_a_shift) & mip_c_a_and); } void average_4x4_chroma(w8 *dst_24, w8 *&p0, w8 *p1, w8 *p2, w8 *p3) { sw8 num_chroma = 0; sw8 num_regular = 0; float r=0; float g=0; float b=0; chroma_process(p0,r,g,b,num_regular,num_chroma); chroma_process(p1,r,g,b,num_regular,num_chroma); chroma_process(p2,r,g,b,num_regular,num_chroma); chroma_process(p3,r,g,b,num_regular,num_chroma); //return the chroma color if (num_chroma > num_regular) { //alpha component and rgb component of 16-bit pixel should be entirely 0'd dst_24[0] = mip_chroma_red; dst_24[1] = mip_chroma_green; dst_24[2] = mip_chroma_blue; return; } float ooreg = 1.f / num_regular; r *= ooreg; if (r<0) r=0; if (r>255) r = 255; g *= ooreg; if (g<0) g=0; if (g>255) g = 255; b *= ooreg; if (b<0) b=0; if (b>255) b = 255; dst_24[0] = (w8)r; dst_24[1] = (w8)g; dst_24[2] = (w8)b; } void average_4x4_alpha(w8 *dst_24, w8 *&p0, w8 *p1, w8 *p2, w8 *p3) { sw32 ia,ir,ig,ib; ia = p0[0]; ir = p0[1]; ig = p0[2]; ib = p0[3]; ia += (p1[0]); ir += (p1[1]); ig += (p1[2]); ib += (p1[3]); ia += (p2[0]); ir += (p2[1]); ig += (p2[2]); ib += (p2[3]); ia += (p3[0]); ir += (p3[1]); ig += (p3[2]); ib += (p3[3]); ia = ia >> 2; ir = ir >> 2; ig = ig >> 2; ib = ib >> 2; dst_24[0] = (w8)ia; dst_24[1] = (w8)ir; dst_24[2] = (w8)ig; dst_24[3] = (w8)ib; } void average_4x4_alpha(w16 *dst, w8 *dst_24, w8 *&p0, w8 *p1, w8 *p2, w8 *p3) { sw32 ia,ir,ig,ib; ia = p0[0]; ir = p0[1]; ig = p0[2]; ib = p0[3]; ia += (p1[0]); ir += (p1[1]); ig += (p1[2]); ib += (p1[3]); ia += (p2[0]); ir += (p2[1]); ig += (p2[2]); ib += (p2[3]); ia += (p3[0]); ir += (p3[1]); ig += (p3[2]); ib += (p3[3]); ia = ia >> 2; ir = ir >> 2; ig = ig >> 2; ib = ib >> 2; dst_24[0] = (w8)ia; dst_24[1] = (w8)ir; dst_24[2] = (w8)ig; dst_24[3] = (w8)ib; *dst = (( (w16)dst_24[1] << mip_a_r_shift) & mip_a_r_and) | (( (w16)dst_24[2] << mip_a_g_shift) & mip_a_g_and) | (( (w16)dst_24[3] >> mip_a_b_shift) & mip_a_b_and) | (( (w16)dst_24[0] << mip_a_a_shift) & mip_a_a_and); } void average_4x4_normal(w16 *dst, w8 *dst_24, w8 *p0, w32 bpl) { #ifndef WIN32 sw32 ir,ig,ib; ir = p0[0]; ig = p0[1]; ib = p0[2]; ir += (p0[0+3]); ig += (p0[1+3]); ib += (p0[2+3]); ir += (p0[0+bpl]); ig += (p0[1+bpl]); ib += (p0[2+bpl]); ir += (p0[0+bpl+3]); ig += (p0[1+bpl+3]); ib += (p0[2+bpl+3]); ir = ir >> 2; ig = ig >> 2; ib = ib >> 2; dst_24[0] = (w8)ir; dst_24[1] = (w8)ig; dst_24[2] = (w8)ib; *dst = (( (w16)p0[0] << mip_r_shift) & mip_r_and) | (( (w16)p0[1] << mip_g_shift) & mip_g_and) | (( (w16)p0[2] >> mip_b_shift) & mip_b_and); #else _asm { mov esi,p0 mov edi,dst mov ecx,bpl mov eax,0 //red mov ebx,0 //green mov edx,0 //blue mov al,byte ptr [esi] add al,byte ptr [esi+3] adc ah,0 add al,byte ptr [esi+ecx] adc ah,0 add al,byte ptr [esi+ecx+3] adc ah,0 mov bl,byte ptr [esi+1] add bl,byte ptr [esi+4] adc bh,0 add bl,byte ptr [esi+ecx+1] adc bh,0 add bl,byte ptr [esi+ecx+4] adc bh,0 mov dl,byte ptr [esi+2] add dl,byte ptr [esi+5] adc dh,0 add dl,byte ptr [esi+ecx+2] adc dh,0 add dl,byte ptr [esi+ecx+5] adc dh,0 shr eax,2 shr ebx,2 shr edx,2 mov esi,dst_24 mov byte ptr [esi],al mov byte ptr [esi+1],bl mov byte ptr [esi+2],dl mov cl,mip_r_shift shl eax,cl and eax,mip_r_and mov cl,mip_g_shift shl ebx,cl and ebx,mip_g_and mov cl,mip_b_shift shr edx,cl and edx,mip_b_and or eax,ebx or eax,edx mov word ptr [edi],ax } #endif } void average_4x4_normal(w8 *dst_24, w8 *p0, w32 bpl) { #ifndef WIN32 sw32 ir,ig,ib; ir = (p0[0]); ig = (p0[1]); ib = (p0[2]); ir += (p0[0+3]); ig += (p0[1+3]); ib += (p0[2+3]); ir += (p0[0+bpl]); ig += (p0[1+bpl]); ib += (p0[2+bpl]); ir += (p0[0+bpl+3]); ig += (p0[1+bpl+3]); ib += (p0[2+bpl+3]); ir = ir >> 2; if (ir<0) ir = 0; else if (ir>255) ir = 255; ig = ig >> 2; if (ig<0) ig = 0; else if (ig>255) ig = 255; ib = ib >> 2; if (ib<0) ib = 0; else if (ib>255) ib = 255; dst_24[0] = (w8)ir; dst_24[1] = (w8)ig; dst_24[2] = (w8)ib; #else _asm { mov esi,p0 mov edx,bpl mov edi,dst_24 mov eax,0 //red mov ebx,0 //green mov ecx,0 //blue mov al,byte ptr [esi] add al,byte ptr [esi+3] adc ah,0 add al,byte ptr [esi+edx] adc ah,0 add al,byte ptr [esi+edx+3] adc ah,0 mov bl,byte ptr [esi+1] add bl,byte ptr [esi+4] adc bh,0 add bl,byte ptr [esi+edx+1] adc bh,0 add bl,byte ptr [esi+edx+4] adc bh,0 mov cl,byte ptr [esi+2] add cl,byte ptr [esi+5] adc ch,0 add cl,byte ptr [esi+edx+2] adc ch,0 add cl,byte ptr [esi+edx+5] adc ch,0 shr eax,2 shr ebx,2 shr ecx,2 mov byte ptr [edi],al mov byte ptr [edi+1],bl mov byte ptr [edi+2],cl } #endif } void mip_24_to_16(w8 *mip24, w16 *mip16, sw32 &width, sw32 &height, sw32 &base_width, w8 &flags) { pf_mip_24_to_16.start(); sw32 i,j,total_pixels; w8 *src = mip24; w16 *dst = mip16; sw32 base_bpl = base_width*3; sw32 src_add = (base_width - width)*3; if (flags & R1_MIP_IS_ALPHATEXTURE) { base_bpl = base_width*4; src_add = (base_width - width)*4; } if (flags & R1_MIP_IS_TRANSPARENT) { for (j=0;j