/**********************************************************************
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 "software/r1_software_globals.hh"
#include "software/inline_fpu.hh"
w32 *texture_perspective_lit_starter()
{
w32 returnval;
_asm
{
mov eax,OFFSET dumb_addr
dumb_addr:
mov returnval,eax
}
return (w32 *)returnval;
}
void texture_scanline_perspective_lit(w16 *start_pixel,
sw32 start_x,
void *_left,//perspective_span *left,
sw32 width)
{
//temporary stuff for lighting calculations
w16 texel;
w32 t1,t2;
w32 l_lookup;
start_pixel = (w16 *)((w8 *)start_pixel + start_x);
perspective_span *left = (perspective_span *)_left;
left_z = 1.f / left->ooz;
left_s = qftoi(left->soz * left_z) + cur_grads.s_adjust;
left_t = qftoi(left->toz * left_z) + cur_grads.t_adjust;
//dont forget the lighting
left_l = left->l;
sw32 had_subdivisions = width & (~15);
num_subdivisions = width >> 4;
num_leftover = width & 15;
if (num_subdivisions)
{
ooz_right = left->ooz + (cur_grads.doozdxspan);
soz_right = left->soz + (cur_grads.dsozdxspan);
toz_right = left->toz + (cur_grads.dtozdxspan);
right_z = 1.f / ooz_right;
while (num_subdivisions)
{
right_s = qftoi(soz_right * right_z) + cur_grads.s_adjust;
if (right_s < 0)
right_s = 0;
else
if (right_s > s_mask)
right_s = s_mask;
right_t = qftoi(toz_right * right_z) + cur_grads.t_adjust;
if (right_t < 0)
right_t = 0;
else
if (right_t > t_mask)
right_t = t_mask;
temp_dsdx = (right_s - left_s) >> 4;
temp_dtdx = (right_t - left_t) >> 4;
if (num_subdivisions!=1)
{
ooz_right += (cur_grads.doozdxspan);
soz_right += (cur_grads.dsozdxspan);
toz_right += (cur_grads.dtozdxspan);
right_z = 1.f / ooz_right;
}
width_global = 16;
while (width_global)
{
texel = *( r1_software_texture_ptr + (left_s>>16) + ((left_t>>16) << r1_software_twidth_log2) );
l_lookup = left_l & (NUM_LIGHT_SHADES<<8);
//lookup low bits
t1 = ((w32 *)(0xDEADBEEF))[l_lookup + (texel & 0xFF)];
//lookup high bits
t2 = ((w32 *)(0xDEADBEEF)+ctable_size)[l_lookup + (texel>>8)];
*start_pixel = (w16)(t1+t2);
start_pixel++;
left_s += temp_dsdx;
left_t += temp_dtdx;
left_l += dldx_fixed;
width_global--;
}
left_s = right_s;
left_t = right_t;
num_subdivisions--;
}
}
if (num_leftover)
{
if (num_leftover > 1)
{
if (had_subdivisions!=0)
{
ooz_right += (cur_grads.doozdx * num_leftover);
soz_right += (cur_grads.dsozdx * num_leftover);
toz_right += (cur_grads.dtozdx * num_leftover);
right_z = 1.f / ooz_right;
}
else
{
ooz_right = left->ooz + (cur_grads.doozdx * num_leftover);
soz_right = left->soz + (cur_grads.dsozdx * num_leftover);
toz_right = left->toz + (cur_grads.dtozdx * num_leftover);
right_z = 1.f / ooz_right;
}
right_s = qftoi(soz_right * right_z) + cur_grads.s_adjust;
if (right_s < 0)
right_s = 0;
else
if (right_s > s_mask)
right_s = s_mask;
right_t = qftoi(toz_right * right_z) + cur_grads.t_adjust;
if (right_t < 0)
right_t = 0;
else
if (right_t > t_mask)
right_t = t_mask;
temp_dsdx = qftoi((float)(right_s - left_s) * inverse_leftover_lookup[num_leftover]);
temp_dtdx = qftoi((float)(right_t - left_t) * inverse_leftover_lookup[num_leftover]);
while (num_leftover)
{
texel = *(r1_software_texture_ptr + (left_s>>16) + ((left_t>>16)<>8)];
*start_pixel = (w16)(t1+t2);
start_pixel++;
left_s += temp_dsdx;
left_t += temp_dtdx;
left_l += dldx_fixed;
num_leftover--;
}
}
else
{
texel = *(r1_software_texture_ptr + (left_s>>16) + ((left_t>>16)<>8)];
*start_pixel = (w16)(t1+t2);
}
}
}
w32 *texture_perspective_lit_sentinel()
{
w32 returnval;
_asm
{
mov eax,OFFSET dumb_addr
dumb_addr:
mov returnval,eax
}
return (w32 *)returnval;
}
void insert_color_modify_address_low(w32 *address);
void insert_color_modify_address_high(w32 *address);
extern w32 color_modify_list[];
extern sw32 num_color_modifies;
void setup_color_modify_perspective_lit()
{
w32 *stop = texture_perspective_lit_sentinel();
w32 *search = texture_perspective_lit_starter();
//start searching for 0xDEADBEEF
while (search < stop)
{
//casting craziness
search = (w32 *)((w8 *)search + 1);
if (*search==0xDEADBEEF)
{
insert_color_modify_address_low(search);
}
else
if (*search==(0xDEADBEEF + ctable_size_bytes))
{
insert_color_modify_address_high(search);
}
}
}