/**********************************************************************
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 "map_cell.hh"
#include "map_vert.hh"
#include "map_man.hh"
#include "lisp/lisp.hh"
#include "lisp/li_init.hh"
#include "map.hh"
#include "objs/path_object.hh"
#include "g1_render.hh"
#include "r1_api.hh"
#include "tmanage.hh"
#include "tile.hh"
#include "app/app.hh"
#include "window/window.hh"
#include "r1_win.hh"
#include "loaders/tga_write.hh"
#include "window/wmanager.hh"
static float tri1_s[8*3]={0,1,1, 1,1,0, 1,0,0, 0,0,1, 0,0,1, 1,0,0, 1,1,0, 0,1,1};
static float tri1_t[8*3]={1,1,0, 1,0,0, 0,0,1, 0,1,1, 1,0,0, 1,1,0, 0,1,1, 0,0,1};
static float tri2_s[8*3]={0,1,0, 1,0,0, 1,0,1, 0,1,1, 0,1,1, 1,0,1, 1,0,0, 0,1,0};
static float tri2_t[8*3]={1,0,0, 1,0,1, 0,1,1, 0,1,0, 1,0,1, 1,0,0, 0,1,0, 0,1,1};
class map_renderer_class : public i4_window_class
{
public:
i4_bool do_it_again;
int ax1, ay1, ax2, ay2;
map_renderer_class(int w, int h) : i4_window_class(w,h)
{
do_it_again=i4_T;
}
void request_redraw(i4_bool for_a_child=i4_F)
{
i4_window_class::request_redraw(for_a_child);
do_it_again=i4_T;
}
void draw(i4_draw_context_class &context)
{
r1_render_api_class *api=g1_render.r_api;
r1_texture_manager_class *tman=api->get_tmanager();
do_it_again=i4_F;
float s, t, s_step, t_step;
s_step=width()/(float)(ax2-ax1);
t_step=height()/(float)(ay2-ay1);
api->default_state();
api->clear_area(0,0,width()-1,height()-1, 0, 100);
api->set_filter_mode(R1_NO_FILTERING);
int x,y;
t=0;
for (y=ay1; ytype)->texture;
api->use_texture(texture, (int)s_step, 0);
int st_index=c->get_rotation();
if (c->mirrored())
st_index+=4;
st_index*=3;
r1_vert v[4];
v[0].px=s; v[0].py=t;
v[1].px=s+s_step; v[1].py=t;
v[2].px=s+s_step; v[2].py=t+t_step;
v[3].px=s; v[3].py=t+t_step;
v[0].s=tri1_s[st_index]; v[0].t=tri1_t[st_index];
v[1].s=tri1_s[st_index+1]; v[1].t=tri1_t[st_index+1];
v[2].s=tri1_s[st_index+2]; v[2].t=tri1_t[st_index+2];
v[3].s=tri2_s[st_index+2]; v[3].t=tri2_t[st_index+2];
float z=1.0;
float w=1.0/z;
v[0].w=w; v[0].v.z=z;
v[1].w=w; v[1].v.z=z;
v[2].w=w; v[2].v.z=z;
v[3].w=w; v[3].v.z=z;
v[0].a=v[1].a=v[2].a=v[3].a=1;
#if 0
v[0].r=v[0].g=v[0].b=v1->get_non_dynamic_ligth_intensity(x,y);
v[1].r=v[1].g=v[1].b=v2->get_non_dynamic_ligth_intensity(x+1,y);
v[2].r=v[2].g=v[2].b=v3->get_non_dynamic_ligth_intensity(x+1,y+1);
v[3].r=v[3].g=v[3].b=v4->get_non_dynamic_ligth_intensity(x,y+1);
#else
v[0].r = v[0].g = v[0].b = 1.0;
v[1].r = v[1].g = v[1].b = 1.0;
v[2].r = v[2].g = v[2].b = 1.0;
v[3].r = v[3].g = v[3].b = 1.0;
#endif
api->render_poly(4, v);
}
}
api->set_filter_mode(R1_BILINEAR_FILTERING);
}
char *name() { return "renderer"; }
};
i4_image_class *render_map_section(int x1, int y1, int x2, int y2, int im_w, int im_h)
{
r1_render_api_class *api=g1_render.r_api;
r1_render_window_class *rwin=api->create_render_window(im_w, im_h);
map_renderer_class *map_r=new map_renderer_class(im_w, im_h);
map_r->ax1=x1;
map_r->ay1=y1;
map_r->ax2=x2;
map_r->ay2=y2;
rwin->add_child(0,0, map_r);
i4_current_app->get_window_manager()->add_child(0,0,rwin);
i4_draw_context_class context(0,0,im_w-1, im_h-1);
i4_display_class *display=i4_current_app->get_display();
int tries=0;
r1_texture_manager_class *tman=api->get_tmanager();
do
{
tman->next_frame();
rwin->draw(context);
display->flush();
tries++;
// repeat until textures have rez-ed in
// or it doens't look like it'll happen
} while (map_r->do_it_again && tries<100);
i4_pixel_format fmt;
fmt.default_format();
fmt.alpha_mask=0;
fmt.calc_shift();
const i4_pal *pal=i4_pal_man.register_pal(&fmt);
i4_image_class *fb;
i4_image_class *to=0;
fb=display->lock_frame_buffer(I4_BACK_FRAME_BUFFER, I4_FRAME_BUFFER_READ);
if (fb)
{
to = i4_create_image(im_w, im_h, pal);
fb->put_part(to, 0,0, 0,0, im_w-1, im_h-1, context);
display->unlock_frame_buffer(I4_BACK_FRAME_BUFFER);
}
delete rwin;
return to;
}
struct area
{
int x1,y1,x2,y2;
area(int x1, int y1, int x2, int y2) : x1(x1),y1(y1),x2(x2),y2(y2) {}
area() {}
};
static i4_array *list;
static void split_gather(int x1, int y1, int x2, int y2, int level)
{
if (list->size()>=6)
return ;
int xd=x2-x1+1, yd=y2-y1+1;
if (xd>yd)
{
int xs=(x2+x1)/2;
list->add(new area(x1, y1, xs, y2));
list->add(new area(xs, y1, x2, y2));
if (level!=1)
{
split_gather(x1, y1, xs, y2, level+1);
split_gather(xs, y1, x2, y2, level+1);
}
}
else
{
int ys=(y2+y1)/2;
list->add(new area(x1, y1, x2, ys));
list->add(new area(x1, ys, x2, y2));
if (level!=1)
{
split_gather(x1, y1, x2, ys, level+1);
split_gather(x1, ys, x2, y2, level+1);
}
}
}
li_object *g1_dump_level(li_object *o, li_environment *env)
{
i4_file_class *fp=i4_open("dump_level", I4_WRITE);
if (!fp)
return 0;
g1_map_class *map=g1_get_map();
int w=map->width(), h=map->height(),i,x,y;
fp->write_32(0xabcf); // version
fp->write_16(w);
fp->write_16(h);
// save off a 1 pixel bitmap
g1_map_cell_class *c=g1_cells;
for (y=0; ytype);
w32 color= g1_render.r_api->get_tmanager()->average_texture_color(type, 0);
g1_map_vertex_class *v=g1_verts+x+y*(w+1);
float tr,tg,tb;
v->get_rgb(tr,tg,tb, x,y);
int r=int(((color>>16)&0xff) * tr);
int g=int(((color>> 8)&0xff) * tg);
int b=int(((color>> 0)&0xff) * tb);
fp->write_32((r<<16)|(g<<8)|b);
}
// save vert hights and normals
g1_map_vertex_class *v=g1_verts;
for (y=0; y<=h; y++)
for (x=0; x<=w; x++, v++)
{
i4_3d_vector normal;
v->get_normal(normal, x,y);
fp->write_float(normal.x);
fp->write_float(normal.y);
fp->write_float(normal.z);
fp->write_float(v->get_height());
float r,g,b;
v->get_rgb(r,g,b, x,y);
fp->write_float(r);
fp->write_float(g);
fp->write_float(b);
}
i4_array mlist(0,32);
// save cell texture names
c=g1_cells;
for (i=0; itype);
char *tname=g1_render.r_api->get_tmanager()->get_texture_name(type);
int len=strlen(tname)+1;
fp->write_16(len);
fp->write(tname,len);
int flags=c->get_rotation();
if (c->mirrored())
flags|=4;
fp->write_8(flags);
}
list=&mlist;
int x1=0,y1=0, x2=g1_map_width, y2=g1_map_height;
split_gather(x1,y1,x2,y2,0 );
for (i=2; i<6; i++)
{
int x1=mlist[i]->x1, y1=mlist[i]->y1, x2=mlist[i]->x2, y2=mlist[i]->y2;
printf("%d %d %d %d\n",x1,y1,x2,y2);
i4_image_class *to;
if (to = render_map_section(x1,y1,x2,y2, 256,256))
{
char fn[100];
sprintf(fn,"x:/jc/lod_test/%d.tga", i-2);
i4_file_class *fp=i4_open(fn, I4_WRITE);
i4_tga_write(to, fp, 0);
delete to;
}
}
for (i=0; i