11655 lines
238 KiB
C++
11655 lines
238 KiB
C++
|
|
#include "game.h"
|
|
#include "shadow.h"
|
|
#include "c:\fallen\headers\animtmap.h"
|
|
#include "pap.h"
|
|
#include "supermap.h"
|
|
#include "io.h"
|
|
#include "memory.h"
|
|
|
|
#ifndef PSX
|
|
#ifdef EDITOR
|
|
#include "c:\fallen\editor\headers\Editor.hpp"
|
|
#else
|
|
#define PSX
|
|
|
|
//bits that #defining PSX removes: bring them back:
|
|
struct TXTY textures_xy[200][5];
|
|
struct DXTXTY dx_textures_xy[200][5];
|
|
UBYTE textures_flags[200][5];
|
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
extern UWORD page_remap[];
|
|
|
|
extern SLONG build_psx;
|
|
|
|
|
|
SLONG insert_collision_vect(SLONG x1,SLONG y1,SLONG z1,SLONG x2,SLONG y2,SLONG z2,UBYTE prim_type,UBYTE prim_extra,SWORD face)
|
|
{
|
|
return 0;
|
|
}
|
|
//psx#include "c:\fallen\editor\headers\Editor.hpp"
|
|
//#include "c:\fallen\editor\headers\engine.h"
|
|
//#include "engine.h"
|
|
//#include "math.h"
|
|
//#include "thing.h"
|
|
|
|
#pragma warning( disable : 4244)
|
|
#define ALT_SHIFT (3)
|
|
|
|
#ifdef PSX
|
|
#define EDIT_MAP_WIDTH 128
|
|
#define EDIT_MAP_DEPTH 128
|
|
#endif
|
|
|
|
#ifndef PSX
|
|
SLONG start_point[200];
|
|
#endif
|
|
|
|
UWORD next_roof_bound=1;
|
|
|
|
|
|
|
|
UWORD background_prim=0;
|
|
|
|
|
|
void set_floor_hidden(SLONG storey,UWORD lower,UWORD flags);
|
|
|
|
|
|
UWORD end_prim_point=MAX_PRIM_POINTS-2;
|
|
UWORD end_prim_face4=MAX_PRIM_FACES4-2;
|
|
UWORD end_prim_face3=MAX_PRIM_FACES3-2;
|
|
UWORD end_prim_object=MAX_PRIM_OBJECTS-2;
|
|
UWORD end_prim_multi_object=MAX_PRIM_MOBJECTS-2;
|
|
|
|
#ifndef PSX
|
|
struct TXTY texture_xy2[]=
|
|
{
|
|
{0,0,0}, //0
|
|
{0,32,0}, //1
|
|
{0,64,0}, //2
|
|
{0,0,32}, //3
|
|
{0,32,32}, //4
|
|
{0,64,32}, //5
|
|
{0,96,32}, //6
|
|
{0,128,32}, //7
|
|
{0,0,64}, //8
|
|
{0,32,64}, //9
|
|
{0,64,64}, //10
|
|
{0,96,64}, //11
|
|
{0,128,64}, //12
|
|
{0,0,96}, //13
|
|
{0,32,96}, //14
|
|
{0,64,96}, //15
|
|
{0,96,96}, //16
|
|
{0,128,96}, //17
|
|
{0,0,128}, //18
|
|
{0,32,128}, //19
|
|
{0,64,128}, //20
|
|
{0,96,128}, //21
|
|
{0,128,128}, //22
|
|
{0,0,160}, //23
|
|
{0,32,160}, //24
|
|
{0,64,160}, //25
|
|
{0,96,160}, //26
|
|
{0,128,160}, //27
|
|
{3,4*32,6*32}, //28
|
|
{0,0}
|
|
|
|
};
|
|
#endif
|
|
|
|
// textures[piece][style]
|
|
/*
|
|
=
|
|
{// TL TM TR ML MM MR MM1 MM2
|
|
{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
|
|
|
|
{{0,0,0,0},{0,1,0,0},{0,2,0,0},{0,0,1,0},{0,1,1,0},{0,2,1,0},{0,3,1,0},{0,4,1,0}}, //BROWN_BRICK1
|
|
{{0,0,2,0},{0,1,2,0},{0,2,2,0},{0,0,3,0},{0,1,3,0},{0,2,3,0},{0,3,3,0},{0,4,3,0}}, //BROWN_BRICK2
|
|
{{0,6,5,0},{0,6,5,0},{0,6,5,0},{0,6,5,0},{0,6,5,0},{0,6,5,0},{0,6,5,0},{0,6,5,0}}, //GREY_RIM2
|
|
{{0,0,4,0},{0,0,4,0},{0,0,4,0},{0,0,4,0},{0,0,4,0},{0,0,4,0},{0,1,4,0},{0,2,4,0}}, //GREY_RIM1
|
|
{{0,3,7,0},{0,3,7,0},{0,3,7,0},{0,3,7,0},{0,3,7,0},{0,3,7,0},{0,3,7,0},{0,3,7,0}}, //RED_WINDOW
|
|
{{0,4,7,0},{0,4,7,0},{0,4,7,0},{0,4,7,0},{0,4,7,0},{0,4,7,0},{0,5,7,0},{0,5,7,0}}, //GREY_CORIGATED
|
|
{{0,7,7,0},{0,7,7,0},{0,7,7,0},{0,7,7,0},{0,7,7,0},{0,7,7,0},{0,7,7,0},{0,7,7,0}}, //CRATES_SMALL_BROWN
|
|
{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, //GREY_POSH
|
|
{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, //HOTEL_SIGN1
|
|
{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, //HOTEL_SIGN2
|
|
{{0,5,5,0},{0,5,5,0},{0,5,5,0},{0,5,5,0},{0,5,5,0},{0,5,5,0},{0,5,5,0},{0,5,5,0}}, //Fence
|
|
|
|
};
|
|
*/
|
|
#ifndef PSX
|
|
struct TXTY textures_xy[200][5];
|
|
struct DXTXTY dx_textures_xy[200][5];
|
|
UBYTE textures_flags[200][5];
|
|
#endif
|
|
|
|
|
|
/*
|
|
struct TextureInfo texture_info[]=
|
|
{ // 0 1 2 3 4 5 6 7
|
|
{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0}, //0
|
|
{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0},{1,0}, //1
|
|
{2,0},{2,0},{2,0},{2,0},{2,0},{0,0},{9,0},{9,0}, //2
|
|
{2,0},{2,0},{2,0},{2,0},{2,0},{0,0},{9,0},{9,0}, //3
|
|
{4,0},{4,0},{4,0},{0,0},{0,0},{0,0},{10,0},{10,0}, //4
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{11,0},{3,0},{8,0}, //5
|
|
{0,0},{0,0},{0,0},{8,0},{8,0},{8,0},{8,0},{8,0}, //6
|
|
{0,0},{0,0},{0,0},{5,0},{6,0},{6,0},{6,0},{7,0}, //7
|
|
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
|
|
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}
|
|
|
|
};
|
|
*/
|
|
|
|
#ifndef PSX
|
|
|
|
|
|
static SLONG build_x,build_y,build_z,build_min_y,build_max_y;
|
|
|
|
extern void do_quad_clip_list(SWORD face,SLONG p0,SLONG p1,SLONG p2,SLONG p3); //prim.cpp
|
|
extern void do_tri_clip_list(SWORD face,SLONG p0,SLONG p1,SLONG p2); //prim.cpp
|
|
extern UWORD calc_lights(SLONG x,SLONG y,SLONG z,struct SVector *p_vect);
|
|
|
|
extern struct SVector global_res[]; //max points per object?
|
|
extern SLONG global_flags[];
|
|
extern UWORD global_bright[];
|
|
extern float global_light[];
|
|
|
|
#define SORT_LEVEL_LONG_LEDGE 1
|
|
#define SORT_LEVEL_FIRE_ESCAPE 3
|
|
|
|
extern SLONG calc_height_at(SLONG x,SLONG z);
|
|
extern SLONG dist_between_vertex_and_vector(SLONG x1,SLONG y1,SLONG x2,SLONG y2,SLONG px,SLONG py);
|
|
|
|
struct PrimFace4* create_a_quad(UWORD p1,UWORD p0,UWORD p3,UWORD p2,SWORD texture_style,SWORD texture_piece,SLONG flipx=0);
|
|
void build_face_texture_info(struct PrimFace4* p_f4,UWORD texture);
|
|
struct PrimFace3* create_a_tri(UWORD p2,UWORD p1,UWORD p0,SWORD texture_id,SWORD texture_piece);
|
|
void build_ledge(SLONG x,SLONG y,SLONG z,SLONG wall,SLONG storey,SLONG height);
|
|
SLONG build_ledge2(SLONG y,SLONG storey,SLONG out,SLONG height,SLONG dip);
|
|
SLONG create_strip_points(SLONG x1,SLONG y1,SLONG z1,SLONG x2,SLONG y2,SLONG z2,SLONG len,SLONG numb,SLONG end_flag);
|
|
SLONG build_outline(SLONG *sx,SLONG *sz,SLONG storey,SLONG wall,SLONG y,SLONG out);
|
|
void calc_building_normals(void);
|
|
|
|
|
|
UWORD next_building_object=1;
|
|
UWORD end_building_object=MAX_BUILDING_OBJECTS-2;
|
|
|
|
UWORD next_building_facet=1;
|
|
UWORD end_building_facet=MAX_BUILDING_FACETS-2;
|
|
|
|
void fn_building_normal(Thing *b_thing);
|
|
|
|
//data
|
|
|
|
|
|
UWORD diff_page_count1=0;
|
|
UWORD diff_page_count2=0;
|
|
UWORD page_count[64*8];
|
|
struct FWindow window_list[MAX_WINDOWS];
|
|
struct FWall wall_list[MAX_WALLS];
|
|
struct FStorey storey_list[MAX_STOREYS];
|
|
struct FBuilding building_list[MAX_BUILDINGS];
|
|
|
|
struct BuildingFacet building_facets[MAX_BUILDING_FACETS];
|
|
struct BuildingObject building_objects[MAX_BUILDING_OBJECTS];
|
|
|
|
SLONG build_mode=1;
|
|
|
|
struct RoomID room_ids[MAX_INSIDE_STOREYS];
|
|
SLONG next_inside=1;
|
|
|
|
UWORD floor_texture_sizes[]=
|
|
{
|
|
16,32,64,128
|
|
};
|
|
|
|
#define FLOOR_LADDER (1<<6)
|
|
|
|
/*
|
|
|
|
**************************
|
|
Create city code
|
|
----------------
|
|
**************************
|
|
|
|
*/
|
|
|
|
|
|
void add_page_countxy(SLONG tx,SLONG ty,SLONG page)
|
|
{
|
|
|
|
page=page*64+tx+ty*8;
|
|
page_count[page]++;
|
|
if(page_count[page]==1)
|
|
{
|
|
if(page<4*64)
|
|
diff_page_count1++;
|
|
else
|
|
diff_page_count2++;
|
|
}
|
|
}
|
|
//******************************************************
|
|
// Data Abstraction layer for map references
|
|
//******************************************************
|
|
|
|
SLONG add_bound_box(UBYTE minx,UBYTE maxx,UBYTE minz,UBYTE maxz,SWORD y)
|
|
{
|
|
if(next_roof_bound>MAX_ROOF_BOUND-2)
|
|
return(0);
|
|
roof_bounds[next_roof_bound].MinX=minx;
|
|
roof_bounds[next_roof_bound].MaxX=maxx;
|
|
roof_bounds[next_roof_bound].MinZ=minz;
|
|
roof_bounds[next_roof_bound].MaxZ=maxz;
|
|
roof_bounds[next_roof_bound].Y=y;
|
|
next_roof_bound++;
|
|
return(next_roof_bound-1);
|
|
}
|
|
|
|
SLONG get_map_walkable(SLONG x,SLONG z)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
// return(edit_map[x][z].Walkable);
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
return(MAP2(x,z).Walkable);
|
|
break;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
void set_map_walkable(SLONG x,SLONG z,SLONG walkable)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
// edit_map[x][z].Walkable=walkable;
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
MAP2(x,z).Walkable=walkable;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
SLONG get_map_texture(SLONG x,SLONG z)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
if(tex_map[x][z]&0x3ff)
|
|
return(tex_map[x][z]);
|
|
else
|
|
return(edit_map[x][z].Texture);
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
|
|
return PAP_2HI(x,z).Texture;
|
|
break;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
void set_map_texture(SLONG x,SLONG z,SLONG texture)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
edit_map[x][z].Texture=(UWORD)texture;
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
PAP_2HI(x,z).Texture = texture;
|
|
break;
|
|
}
|
|
}
|
|
|
|
SLONG get_map_height(SLONG x,SLONG z)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
return(edit_map[x][z].Y);
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
return PAP_2HI(x,z).Alt;
|
|
break;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
SLONG get_roof_height(SLONG x,SLONG z)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
return(edit_map_roof_height[x][z]);
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
return 0; //PAP_2HI(x,z).Alt;
|
|
break;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
SLONG set_map_flag(SLONG x,SLONG z,SLONG flag)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
edit_map[x][z].Flags|=flag;
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
PAP_2HI(x,z).Flags |= flag;
|
|
break;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
SLONG mask_map_flag(SLONG x,SLONG z,SLONG flag)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
edit_map[x][z].Flags&=~flag;
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
PAP_2HI(x,z).Flags &= ~flag;
|
|
break;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
SLONG get_map_flags(SLONG x,SLONG z)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
return(edit_map[x][z].Flags);
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
return PAP_2HI(x,z).Flags;
|
|
break;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
void set_map_height(SLONG x,SLONG z,SLONG y)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
edit_map[x][z].Y=(SBYTE)y;
|
|
PAP_2HI(x,z).Alt = y;
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
PAP_2HI(x,z).Alt = y;
|
|
break;
|
|
}
|
|
}
|
|
|
|
SLONG in_map_range(SLONG x,SLONG z)
|
|
{
|
|
if(x<0||z<0)
|
|
return(0);
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
if(x>EDIT_MAP_WIDTH||z>EDIT_MAP_DEPTH)
|
|
return(0);
|
|
else
|
|
return(1);
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
if(x>MAP_WIDTH||z>MAP_HEIGHT)
|
|
return(0);
|
|
else
|
|
return(1);
|
|
break;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
void place_thing_on_map(SLONG x,SLONG z,SLONG thing)
|
|
{
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
add_thing_to_edit_map(x>>ELE_SHIFT,z>>ELE_SHIFT,thing);
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
add_thing_to_map(TO_THING(thing));
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
void set_vect_floor_height(SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG y)
|
|
{
|
|
SLONG step_x,step_z;
|
|
SLONG len,count;
|
|
|
|
|
|
|
|
step_x=x2-x1;
|
|
step_z=z2-z1;
|
|
len=Root(step_x*step_x+step_z*step_z);
|
|
|
|
step_x=(step_x<<16)/len;
|
|
step_z=(step_z<<16)/len;
|
|
|
|
count=len>>8;
|
|
|
|
x1<<=8;
|
|
z1<<=8;
|
|
set_map_height(x1>>16,z1>>16,y);
|
|
while(count)
|
|
{
|
|
|
|
x1+=step_x;
|
|
z1+=step_z;
|
|
set_map_height(x1>>16,z1>>16,y);
|
|
|
|
count--;
|
|
}
|
|
}
|
|
|
|
|
|
static SLONG build_seed=0x12345678;
|
|
|
|
SLONG build_rand(void)
|
|
{
|
|
build_seed=(build_seed*12345678)+12345678;
|
|
// LogText(" build_seed %x \n",build_seed);
|
|
return(build_seed>>16);
|
|
}
|
|
|
|
void set_build_seed(SLONG seed)
|
|
{
|
|
build_seed=seed;
|
|
}
|
|
|
|
|
|
void add_walk_face_to_map(SWORD face,SLONG x,SLONG z)
|
|
{
|
|
#ifdef TARGET_DC
|
|
// Shouldn't be using this, apparently.
|
|
ASSERT ( FALSE );
|
|
#endif
|
|
|
|
if(next_walk_link>=(MAX_WALK_POOL-4))
|
|
{
|
|
LogText(" failed out of walk mem \n");
|
|
ASSERT(0);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// If this face is already in the walkable list for this square,
|
|
// then don't add it again!
|
|
//
|
|
|
|
{
|
|
SLONG index = MAP[MAP_INDEX(x,z)].Walkable;
|
|
|
|
while(index)
|
|
{
|
|
if (walk_links[index].Face == face)
|
|
{
|
|
return;
|
|
}
|
|
|
|
index = walk_links[index].Next;
|
|
}
|
|
}
|
|
|
|
walk_links[next_walk_link].Face=face;
|
|
walk_links[next_walk_link].Next=get_map_walkable(x,z);
|
|
set_map_walkable(x,z,next_walk_link);
|
|
next_walk_link++;
|
|
}
|
|
|
|
|
|
void scan_walk_triangle(SLONG x0, SLONG y0, SLONG z0,SLONG x1, SLONG y1, SLONG z1,SLONG x2, SLONG y2, SLONG z2,SLONG face)
|
|
{
|
|
|
|
SLONG px,py,pz;
|
|
SLONG face_x,face_y,face_z;
|
|
SLONG c0;
|
|
SLONG s,t,step_s,step_t;
|
|
SLONG vx,vy,vz,wx,wy,wz;
|
|
struct DepthStrip *me;
|
|
SLONG prev_x,prev_z;
|
|
SLONG quad;
|
|
SLONG len;
|
|
// CBYTE str[100];
|
|
UBYTE info=0;
|
|
|
|
face_x = x0;
|
|
face_y = y0;
|
|
face_z = z0;
|
|
|
|
vx = x1 - x0;
|
|
vy = y1 - y0; //vector from point 0 to point 1
|
|
vz = z1 - z0;
|
|
|
|
wx = x2 - x0; //vector from point 1 to point 2
|
|
wy = y2 - y0;
|
|
wz = z2 - z0;
|
|
|
|
len=(Root(vx*vx+vy*vy+vz*vz)>>7);
|
|
if(len<2)
|
|
len=2;
|
|
step_s=(1<<7)/len;
|
|
len=(Root(wx*wx+wy*wy+wz*wz)>>7);
|
|
if(len<2)
|
|
len=2;
|
|
step_t=(1<<7)/len;
|
|
|
|
if(step_s==0)
|
|
step_s=256;
|
|
if(step_t==0)
|
|
step_t=256;
|
|
|
|
prev_x=-1;
|
|
prev_z=-1;
|
|
for(s=5; s<(255) ; s+=step_s)
|
|
for(t=5; t<(255) && ((s+t)<(256)); t+=step_t)
|
|
{
|
|
px=face_x+((s*vx)>>8)+((t*wx)>>8);
|
|
pz=face_z+((s*vz)>>8)+((t*wz)>>8);
|
|
if((px>>8)!=prev_x||(pz>>8)!=prev_z)
|
|
{
|
|
py=face_y+((s*vy)>>8)+((t*wy)>>8);
|
|
|
|
if (WITHIN(px >> ELE_SHIFT, 0, MAP_WIDTH - 1) &&
|
|
WITHIN(pz >> ELE_SHIFT, 0, MAP_HEIGHT - 1))
|
|
{
|
|
// LogText(" add walkable face to %d %d \n",px>>8,pz>>8);
|
|
add_walk_face_to_map(face,px>>8,pz>>8);
|
|
}
|
|
prev_x=px>>8;
|
|
prev_z=pz>>8;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// 0 1
|
|
//
|
|
// 2 3
|
|
void add_quad_to_walkable_list(SWORD face)
|
|
{
|
|
SLONG x[4],y[4],z[4];
|
|
SLONG c0,p0;
|
|
struct PrimFace4 *p_f4;
|
|
p_f4=&prim_faces4[face];
|
|
|
|
for(c0=0;c0<4;c0++)
|
|
{
|
|
p0=p_f4->Points[c0];
|
|
x[c0]=prim_points[p0].X;
|
|
y[c0]=prim_points[p0].Y;
|
|
z[c0]=prim_points[p0].Z;
|
|
}
|
|
scan_walk_triangle(x[0],y[0],z[0],x[1],y[1],z[1],x[2],y[2],z[2],face);
|
|
scan_walk_triangle(x[1],y[1],z[1],x[3],y[3],z[3],x[2],y[2],z[2],face);
|
|
|
|
//
|
|
// Mark the face as walkable.
|
|
//
|
|
|
|
prim_faces4[face].FaceFlags |= FACE_FLAG_WALKABLE;
|
|
}
|
|
|
|
void add_tri_to_walkable_list(SWORD face)
|
|
{
|
|
/* wrong wrong wrong
|
|
SLONG x,z;
|
|
SLONG p0;
|
|
struct PrimFace3 *p_f3;
|
|
|
|
p_f3=&prim_faces3[face];
|
|
//for now just take one corner and add it to map at that corner
|
|
p0=p_f3->Points[0];
|
|
x=prim_points[p0].X>>ELE_SHIFT;
|
|
z=prim_points[p0].Z>>ELE_SHIFT;
|
|
add_walk_face_to_map(-face,x,z);
|
|
*/
|
|
}
|
|
|
|
SLONG place_building_at(UWORD building,UWORD prim,SLONG x,SLONG y,SLONG z)
|
|
{
|
|
UWORD map_thing;
|
|
|
|
//y=0;
|
|
//LogText(" place building prim %d x %d y %d z %d \n",prim,x,y,z);
|
|
switch(build_mode)
|
|
{
|
|
case BUILD_MODE_EDITOR:
|
|
#ifdef EDITOR
|
|
{
|
|
struct MapThing *p_mthing;
|
|
map_thing=find_empty_map_thing();
|
|
if(!map_thing)
|
|
return(0);
|
|
//add_thing_to_edit_map(x>>ELE_SHIFT,z>>ELE_SHIFT,map_thing);
|
|
p_mthing=TO_MTHING(map_thing);
|
|
p_mthing->X=0; //x;
|
|
p_mthing->Y=y;
|
|
p_mthing->Z=0; //z;
|
|
|
|
p_mthing->Type=MAP_THING_TYPE_BUILDING;
|
|
p_mthing->IndexOther=prim;
|
|
p_mthing->IndexOrig=prim;
|
|
p_mthing->BuildingList = building;
|
|
p_mthing->EditorFlags = 0;
|
|
p_mthing->EditorData = 0;
|
|
place_thing_on_map(x,z,map_thing);
|
|
|
|
//
|
|
// Link the building to the editor MapThing.
|
|
//
|
|
|
|
building_list[building].ThingIndex = map_thing;
|
|
|
|
return(map_thing);
|
|
}
|
|
#endif
|
|
break;
|
|
case BUILD_MODE_DX:
|
|
{
|
|
Thing *p_thing;
|
|
SLONG new_thing;
|
|
|
|
new_thing = alloc_primary_thing(CLASS_BUILDING);
|
|
if(new_thing)
|
|
{
|
|
p_thing = TO_THING(new_thing);
|
|
|
|
p_thing->WorldPos.X=x<<8;
|
|
p_thing->WorldPos.Y=y<<8;
|
|
p_thing->WorldPos.Z=z<<8;
|
|
p_thing->StateFn = fn_building_normal; // Guy.
|
|
// p_thing->StateFn = NULL;
|
|
p_thing->DrawType = DT_NONE;
|
|
p_thing->Flags = 0;
|
|
|
|
p_thing->Index = prim;
|
|
p_thing->DrawType = DT_BUILDING;
|
|
p_thing->Class = CLASS_BUILDING;
|
|
// p_thing->BuildingList = building;
|
|
MSG_add(" create building prim %d at %d %d %d building %d \n",prim,x,y,z,building);
|
|
add_thing_to_map(p_thing);
|
|
|
|
//
|
|
// Link the building to the thing.
|
|
//
|
|
|
|
building_list[building].ThingIndex = new_thing;
|
|
|
|
return new_thing;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
void add_point(SLONG x,SLONG y,SLONG z)
|
|
{
|
|
AENG_dx_prim_points[next_prim_point].X=(float)x;
|
|
AENG_dx_prim_points[next_prim_point].Y=(float)y;
|
|
AENG_dx_prim_points[next_prim_point].Z=(float)z;
|
|
|
|
prim_points[next_prim_point].X=x;
|
|
prim_points[next_prim_point].Y=y;
|
|
prim_points[next_prim_point++].Z=z;
|
|
}
|
|
|
|
|
|
SLONG WindowCount;
|
|
|
|
SLONG build_row_wall_points_at_y(SLONG y,SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG wall)
|
|
{
|
|
SLONG wcount,wwidth,wallwidth,dx,dz,dist;
|
|
|
|
SLONG start_point;
|
|
|
|
start_point=next_prim_point;
|
|
|
|
wwidth=BLOCK_SIZE;
|
|
|
|
dx=abs(x2-x1);
|
|
dz=abs(z2-z1);
|
|
|
|
dist=Root(SDIST2(dx,dz));
|
|
if(dist==0)
|
|
return(0);
|
|
|
|
if(wall_list[wall].WallFlags&FLAG_WALL_AUTO_WINDOWS)
|
|
{
|
|
wcount=dist/(BLOCK_SIZE*4);
|
|
wwidth=dist/(wcount*2+1);
|
|
// wall_list[wall].WindowCount=wcount;
|
|
WindowCount=wcount;
|
|
|
|
}
|
|
else
|
|
{
|
|
wcount=0; //wall_list[wall].WindowCount;
|
|
wwidth=BLOCK_SIZE;
|
|
}
|
|
|
|
dx=(x2-x1);
|
|
dz=(z2-z1);
|
|
|
|
if(wcount<0)
|
|
return(0);
|
|
|
|
wallwidth=(dist-(wcount*wwidth))/(wcount+1);
|
|
|
|
dx=(dx<<10)/dist;
|
|
dz=(dz<<10)/dist;
|
|
|
|
|
|
add_point(x1,y,z1);
|
|
|
|
while(wcount)
|
|
{
|
|
x1=x1+((dx*wallwidth)>>10);
|
|
z1=z1+((dz*wallwidth)>>10);
|
|
add_point(x1,y,z1);
|
|
|
|
|
|
x1=x1+((dx*wwidth)>>10);
|
|
z1=z1+((dz*wwidth)>>10);
|
|
add_point(x1,y,z1);
|
|
|
|
wcount--;
|
|
}
|
|
x1=x1+((dx*wallwidth)>>10);
|
|
z1=z1+((dz*wallwidth)>>10);
|
|
add_point(x1,y,z1);
|
|
|
|
return(start_point);
|
|
|
|
}
|
|
|
|
SLONG build_row_wall_points_at_floor_alt(SLONG y,SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG wall)
|
|
{
|
|
SLONG wcount,wwidth,wallwidth,dx,dz,dist;
|
|
|
|
SLONG start_point;
|
|
SLONG ny;
|
|
|
|
start_point=next_prim_point;
|
|
|
|
wwidth=BLOCK_SIZE;
|
|
|
|
dx=abs(x2-x1);
|
|
dz=abs(z2-z1);
|
|
|
|
dist=Root(SDIST2(dx,dz));
|
|
if(dist==0)
|
|
return(0);
|
|
|
|
if(wall_list[wall].WallFlags&FLAG_WALL_AUTO_WINDOWS)
|
|
{
|
|
wcount=dist/(BLOCK_SIZE*4);
|
|
wwidth=dist/(wcount*2+1);
|
|
// wall_list[wall].WindowCount=wcount;
|
|
WindowCount=wcount;
|
|
|
|
}
|
|
else
|
|
{
|
|
wcount=0; //wall_list[wall].WindowCount;
|
|
wwidth=BLOCK_SIZE;
|
|
}
|
|
|
|
dx=(x2-x1);
|
|
dz=(z2-z1);
|
|
|
|
if(wcount<0)
|
|
return(0);
|
|
|
|
wallwidth=(dist-(wcount*wwidth))/(wcount+1);
|
|
|
|
dx=(dx<<10)/dist;
|
|
dz=(dz<<10)/dist;
|
|
|
|
y=PAP_calc_height_at(x1,z1);
|
|
|
|
add_point(x1,y,z1);
|
|
|
|
while(wcount)
|
|
{
|
|
x1=x1+((dx*wallwidth)>>10);
|
|
z1=z1+((dz*wallwidth)>>10);
|
|
y=PAP_calc_height_at(x1,z1);
|
|
add_point(x1,y,z1);
|
|
|
|
|
|
x1=x1+((dx*wwidth)>>10);
|
|
z1=z1+((dz*wwidth)>>10);
|
|
y=PAP_calc_height_at(x1,z1);
|
|
add_point(x1,y,z1);
|
|
|
|
wcount--;
|
|
|
|
}
|
|
x1=x1+((dx*wallwidth)>>10);
|
|
z1=z1+((dz*wallwidth)>>10);
|
|
y=PAP_calc_height_at(x1,z1);
|
|
add_point(x1,y,z1);
|
|
|
|
return(start_point);
|
|
|
|
}
|
|
|
|
SLONG build_row_wall_only_points_at_y(SLONG y,SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG wall)
|
|
{
|
|
SLONG wcount,wwidth,dx,dz,dist;
|
|
|
|
SLONG start_point;
|
|
|
|
start_point=next_prim_point;
|
|
|
|
dx=abs(x2-x1);
|
|
dz=abs(z2-z1);
|
|
|
|
dist=Root(SDIST2(dx,dz));
|
|
if(dist==0)
|
|
return(0);
|
|
|
|
wcount=(dist/(BLOCK_SIZE*4));
|
|
if(wcount==0)
|
|
wcount=1;
|
|
wwidth=dist/(wcount);
|
|
// wall_list[wall].WindowCount=wcount;
|
|
WindowCount=wcount;
|
|
|
|
dx=(x2-x1);
|
|
dz=(z2-z1);
|
|
|
|
|
|
dx=(dx<<10)/dist;
|
|
dz=(dz<<10)/dist;
|
|
|
|
add_point(x1,y,z1);
|
|
wcount--;
|
|
|
|
while(wcount)
|
|
{
|
|
|
|
x1=x1+((dx*wwidth)>>10);
|
|
z1=z1+((dz*wwidth)>>10);
|
|
add_point(x1,y,z1);
|
|
|
|
wcount--;
|
|
}
|
|
add_point(x2,y,z2); //make sure last point is spot on.
|
|
|
|
return(start_point);
|
|
|
|
}
|
|
|
|
SLONG build_row_wall_only_points_at_floor_alt(SLONG dy,SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG wall)
|
|
{
|
|
SLONG wcount,wwidth,dx,dz,dist;
|
|
|
|
SLONG start_point;
|
|
|
|
SLONG y;
|
|
|
|
start_point=next_prim_point;
|
|
|
|
dx=abs(x2-x1);
|
|
dz=abs(z2-z1);
|
|
|
|
dist=Root(SDIST2(dx,dz));
|
|
if(dist==0)
|
|
return(0);
|
|
|
|
wcount=(dist/(BLOCK_SIZE*4));
|
|
if(wcount==0)
|
|
wcount=1;
|
|
wwidth=dist/(wcount);
|
|
//wall_list[wall].WindowCount=wcount;
|
|
WindowCount=wcount;
|
|
|
|
dx=(x2-x1);
|
|
dz=(z2-z1);
|
|
|
|
|
|
dx=(dx<<10)/dist;
|
|
dz=(dz<<10)/dist;
|
|
|
|
y=PAP_calc_height_at(x1,z1);
|
|
|
|
y+=dy;
|
|
add_point(x1,y,z1);
|
|
wcount--;
|
|
|
|
while(wcount)
|
|
{
|
|
|
|
x1=x1+((dx*wwidth)>>10);
|
|
z1=z1+((dz*wwidth)>>10);
|
|
y=PAP_calc_height_at(x1,z1);
|
|
|
|
y+=dy;
|
|
add_point(x1,y,z1);
|
|
|
|
wcount--;
|
|
}
|
|
y=PAP_calc_height_at(x2,z2);
|
|
|
|
y+=dy;
|
|
add_point(x2,y,z2); //make sure last point is spot on.
|
|
|
|
return(start_point);
|
|
|
|
}
|
|
|
|
SLONG build_row_window_depth_points_at_y(SLONG y,SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG wall)
|
|
{
|
|
|
|
SLONG wcount,wwidth,wallwidth,dx,dz,dist;
|
|
SLONG pdx,pdz;
|
|
|
|
SLONG start_point;
|
|
|
|
start_point=next_prim_point;
|
|
|
|
|
|
|
|
dx=abs(x2-x1);
|
|
dz=abs(z2-z1);
|
|
|
|
dist=Root(SDIST2(dx,dz));
|
|
if(dist==0)
|
|
return(0);
|
|
|
|
if(wall_list[wall].WallFlags&FLAG_WALL_AUTO_WINDOWS)
|
|
{
|
|
wcount=dist/(BLOCK_SIZE*4);
|
|
wwidth=dist/(wcount*2+1);
|
|
//wall_list[wall].WindowCount=wcount;
|
|
WindowCount=wcount;
|
|
|
|
}
|
|
else
|
|
{
|
|
wcount=0; //wall_list[wall].WindowCount;
|
|
wwidth=BLOCK_SIZE;
|
|
}
|
|
|
|
dx=(x2-x1);
|
|
dz=(z2-z1);
|
|
|
|
if(wcount<0)
|
|
return(0);
|
|
|
|
wallwidth=(dist-(wcount*wwidth))/(wcount+1);
|
|
|
|
dx=(dx<<10)/dist;
|
|
dz=(dz<<10)/dist;
|
|
|
|
pdx=-dz;
|
|
pdz=dx;
|
|
|
|
pdx=(pdx*20)>>10;
|
|
pdz=(pdz*20)>>10;
|
|
|
|
x1+=pdx;
|
|
z1+=pdz;
|
|
|
|
|
|
// add_point(x1,y,z1);
|
|
|
|
while(wcount)
|
|
{
|
|
x1=x1+((dx*wallwidth)>>10);
|
|
z1=z1+((dz*wallwidth)>>10);
|
|
add_point(x1,y,z1);
|
|
|
|
|
|
x1=x1+((dx*wwidth)>>10);
|
|
z1=z1+((dz*wwidth)>>10);
|
|
add_point(x1,y,z1);
|
|
|
|
wcount--;
|
|
|
|
}
|
|
x1=x1+((dx*wallwidth)>>10);
|
|
z1=z1+((dz*wallwidth)>>10);
|
|
// add_point(x1,y,z1);
|
|
|
|
return(start_point);
|
|
|
|
}
|
|
|
|
struct Edge
|
|
{
|
|
SWORD X;
|
|
UBYTE Type;
|
|
UBYTE Count;
|
|
SWORD Next;
|
|
SWORD Prev;
|
|
};
|
|
|
|
struct Edge *edge_pool_ptr=0;
|
|
static UWORD *edge_heads_ptr=0;
|
|
static ULONG next_edge;
|
|
static ULONG edge_min_z;
|
|
static SLONG *flag_blocks=0;
|
|
static SLONG *flag_blocks2=0;
|
|
static UWORD *cut_blocks=0;
|
|
static SLONG global_y;
|
|
SLONG block_min_x,block_max_x;
|
|
#define MAX_BOUND_SIZE (200)
|
|
|
|
|
|
void insert_point(SLONG z,SLONG x,SWORD type)
|
|
{
|
|
SLONG edge;
|
|
|
|
// LogText(" insert point (%x,%x) \n",x,z);
|
|
|
|
if(x<block_min_x||x>block_max_x)
|
|
return;
|
|
|
|
edge_pool_ptr[next_edge].X=x;
|
|
edge_pool_ptr[next_edge].Count=1;
|
|
edge_pool_ptr[next_edge].Type=type;
|
|
ASSERT(z>=0);
|
|
ASSERT(z<MAX_BOUND_SIZE);
|
|
ASSERT(x>=0);
|
|
ASSERT(x<MAP_WIDTH*256);
|
|
|
|
edge=edge_heads_ptr[z];
|
|
if(edge)
|
|
{
|
|
while(edge)
|
|
{
|
|
if(edge_pool_ptr[edge].X>x)
|
|
{
|
|
SLONG prev;
|
|
prev=edge_pool_ptr[edge].Prev;
|
|
|
|
if(prev)
|
|
{
|
|
// insert between current one and previous
|
|
edge_pool_ptr[prev].Next=next_edge;
|
|
edge_pool_ptr[edge].Prev=next_edge;
|
|
edge_pool_ptr[next_edge].Next=edge;
|
|
edge_pool_ptr[next_edge].Prev=prev;
|
|
next_edge++;
|
|
}
|
|
else
|
|
{
|
|
// insert before current one and head of list
|
|
edge_heads_ptr[z]=next_edge;
|
|
edge_pool_ptr[edge].Prev=next_edge;
|
|
edge_pool_ptr[next_edge].Next=edge;
|
|
edge_pool_ptr[next_edge].Prev=0;
|
|
next_edge++;
|
|
|
|
}
|
|
return;
|
|
}
|
|
else
|
|
if(edge_pool_ptr[edge].X==x)
|
|
{
|
|
edge_pool_ptr[edge].Count++;
|
|
// LogText(" allready exists cancel \n");
|
|
return;
|
|
}
|
|
|
|
if(edge_pool_ptr[edge].Next==0)
|
|
{
|
|
//append after current
|
|
edge_pool_ptr[edge].Next=next_edge;
|
|
edge_pool_ptr[next_edge].Next=0;
|
|
edge_pool_ptr[next_edge].Prev=edge;
|
|
next_edge++;
|
|
return;
|
|
|
|
}
|
|
edge=edge_pool_ptr[edge].Next;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
edge_heads_ptr[z]=next_edge;
|
|
edge_pool_ptr[next_edge].Prev=0;
|
|
edge_pool_ptr[next_edge].Next=0;
|
|
next_edge++;
|
|
}
|
|
}
|
|
|
|
#define SIDEWAY_EDGE (1)
|
|
#define NORMAL_EDGE (2)
|
|
|
|
#define CUT_BLOCK_TOP (0)
|
|
#define CUT_BLOCK_BOTTOM (1)
|
|
#define CUT_BLOCK_LEFT (2)
|
|
#define CUT_BLOCK_RIGHT (3)
|
|
|
|
void set_cut_blocks(SLONG x,SLONG z) // x is in pixels // zis in blocks
|
|
{
|
|
|
|
LogText(" cut block [%d][%d] top x %d x %x\n",x>>ELE_SHIFT,z+1,x,x);
|
|
LogText(" cut block [%d][%d] bottom x %d x %x\n",x>>ELE_SHIFT,z,x,x);
|
|
// z=z-(edge_min_z>>ELE_SHIFT);
|
|
cut_blocks[(x>>ELE_SHIFT)*4+((z)*MAX_BOUND_SIZE*4+CUT_BLOCK_TOP)]=x;
|
|
cut_blocks[(x>>ELE_SHIFT)*4+((z-1)*MAX_BOUND_SIZE*4+CUT_BLOCK_BOTTOM)]=x;
|
|
}
|
|
|
|
void set_cut_blocks_z(SLONG x,SLONG z) // x is in blocks z is in pixels
|
|
{
|
|
|
|
LogText(" cut block [%d][%d] left z %d z %x\n",x,z>>ELE_SHIFT,z,z);
|
|
LogText(" cut block [%d][%d] right z %d z %x\n",x-1,z>>ELE_SHIFT,z,z);
|
|
cut_blocks[(x)*4+(((z>>ELE_SHIFT)-0)*MAX_BOUND_SIZE*4+CUT_BLOCK_LEFT)]=z;
|
|
cut_blocks[(x-1)*4+(((z>>ELE_SHIFT)-0)*MAX_BOUND_SIZE*4+CUT_BLOCK_RIGHT)]=z;
|
|
}
|
|
|
|
void scan_line_z(SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG flag)
|
|
{
|
|
SLONG dx,dz,count;
|
|
SLONG x,z;
|
|
SWORD type;
|
|
// LogText(" scan line z x1 %d z1 %d x2 %d z2 %d \n",x1,z1,x2,z2);
|
|
// LogText(" scan lineZ (%x,%x)->(%x,%x) \n",x1,(z1>>ELE_SHIFT),x2,(z2>>ELE_SHIFT));
|
|
|
|
|
|
dz=z2-z1;
|
|
dx=x2-x1;
|
|
// LogText(" dx %d dz %d \n",dx,dz);
|
|
{
|
|
x1>>=ELE_SHIFT;
|
|
x2>>=ELE_SHIFT;
|
|
dx=x2-x1;
|
|
|
|
z=z1<<16;
|
|
count=dx;
|
|
// LogText(" x1 %d x2 %d dx %d \n",x1,x2,dx);
|
|
|
|
if(count<0)
|
|
{
|
|
// LogText(" neg count %d z1 %d z2 %d \n",count,z1,z2);
|
|
dz=-(dz<<16)/count;
|
|
x1--;
|
|
z+=dz;
|
|
// else
|
|
// count--;
|
|
|
|
// LogText("A x1 %d x2 %d dx %d dz %x count %d\n",x1,x2,dx,dz,count);
|
|
while(count)
|
|
{
|
|
if(dz)
|
|
{
|
|
// LogText(" mid scan z %d z %x\n",(z>>16)&0xff,z);
|
|
if((z>>16)&0xff)
|
|
{
|
|
set_cut_blocks_z(x1,z>>16);
|
|
}
|
|
|
|
}
|
|
|
|
z+=dz;
|
|
x1--;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(count>0)
|
|
{
|
|
dz=(dz<<16)/count;
|
|
// if(flag)
|
|
// count++;
|
|
|
|
//LogText("B x1 %d x2 %d dx %d count %d\n",x1,x2,dx,count);
|
|
while(count)
|
|
{
|
|
if(dz)
|
|
{
|
|
//LogText(" mid scan z %d z %x\n",(z>>16)&0xff,z);
|
|
if((z>>16)&0xff)
|
|
{
|
|
set_cut_blocks_z(x1,z>>16);
|
|
}
|
|
}
|
|
z+=dz;
|
|
x1++;
|
|
count--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
UBYTE scan_line(SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG flag)
|
|
{
|
|
SLONG dx,dz,count;
|
|
SLONG x,z;
|
|
SWORD type;
|
|
// LogText(" scan line (%x,%x)->(%x,%x) \n",x1,(z1>>ELE_SHIFT),x2,(z2>>ELE_SHIFT));
|
|
|
|
|
|
if(z1==z2)
|
|
type=SIDEWAY_EDGE;
|
|
else
|
|
type=NORMAL_EDGE;
|
|
|
|
dz=z2-z1;
|
|
dx=x2-x1;
|
|
//if(abs(dz)>abs(dx))
|
|
{
|
|
//LogText(" dz longest \n");
|
|
z1>>=ELE_SHIFT;
|
|
z2>>=ELE_SHIFT;
|
|
dz=z2-z1;
|
|
|
|
x=x1<<16;
|
|
count=dz;
|
|
|
|
if(count<0)
|
|
{
|
|
// LogText(" neg count %d z1 %d z2 %d \n",count,z1,z2);
|
|
dx=-(dx<<16)/count;
|
|
//z1--;
|
|
//count++;
|
|
//x+=dx;
|
|
// if(!flag)
|
|
z1--;
|
|
x+=dx;
|
|
// else
|
|
// count--;
|
|
|
|
while(count)
|
|
{
|
|
insert_point(z1,x>>16,type);
|
|
if(dx)
|
|
{
|
|
LogText(" scan x %d \n",(x>>16)&0xff);
|
|
if((x>>16)&0xff)
|
|
{
|
|
set_cut_blocks(x>>16,z1);
|
|
}
|
|
|
|
}
|
|
|
|
x+=dx;
|
|
z1--;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(count>0)
|
|
{
|
|
dx=(dx<<16)/count;
|
|
// if(flag)
|
|
// count++;
|
|
|
|
while(count)
|
|
{
|
|
insert_point(z1,x>>16,type);
|
|
if(dx)
|
|
{
|
|
LogText(" scan x2 %d \n",(x>>16)&0xff);
|
|
if((x>>16)&0xff)
|
|
{
|
|
set_cut_blocks(x>>16,z1);
|
|
}
|
|
}
|
|
x+=dx;
|
|
z1++;
|
|
count--;
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
else
|
|
{
|
|
LogText(" dx longest \n");
|
|
x1>>=ELE_SHIFT;
|
|
x2>>=ELE_SHIFT;
|
|
dx=x2-x1;
|
|
|
|
z=z1<<16;
|
|
count=dx;
|
|
|
|
if(count<0)
|
|
{
|
|
LogText(" neg count %d z1 %d z2 %d \n",count,z1,z2);
|
|
dz=-(dz<<16)/count;
|
|
while(count<0)
|
|
{
|
|
insert_point((z>>16)>>ELE_SHIFT,x1<<ELE_SHIFT,type);
|
|
z+=dz;
|
|
x1--;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(count>0)
|
|
{
|
|
dz=(dz<<16)/count;
|
|
|
|
while(count)
|
|
{
|
|
insert_point((z>>16)>>ELE_SHIFT,x1<<ELE_SHIFT,type);
|
|
z+=dz;
|
|
x1++;
|
|
count--;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
if(dx&&dz)
|
|
return(1);
|
|
else
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
SLONG build_edge_list(SLONG storey,SLONG flag)
|
|
{
|
|
UWORD wall;
|
|
SLONG px,pz;
|
|
SLONG angles=0;
|
|
// if(storey==211)
|
|
// ASSERT(0);
|
|
|
|
next_edge=1;
|
|
|
|
if(edge_pool_ptr)
|
|
{
|
|
MemFree((UBYTE*)edge_pool_ptr);
|
|
edge_pool_ptr=0;
|
|
}
|
|
if(edge_heads_ptr)
|
|
{
|
|
MemFree((UBYTE*)edge_heads_ptr);
|
|
edge_heads_ptr=0;
|
|
}
|
|
if(flag_blocks)
|
|
{
|
|
MemFree((UBYTE*)flag_blocks);
|
|
flag_blocks=0;
|
|
}
|
|
if(flag_blocks2)
|
|
{
|
|
// MemFree((UBYTE*)flag_blocks2);
|
|
flag_blocks2=0;
|
|
}
|
|
if(cut_blocks)
|
|
{
|
|
MemFree((UBYTE*)cut_blocks);
|
|
cut_blocks=0;
|
|
}
|
|
edge_pool_ptr=(struct Edge*)MemAlloc(sizeof(struct Edge)*MAX_BOUND_SIZE*5);
|
|
edge_heads_ptr=(UWORD*)MemAlloc(sizeof(UWORD)*MAX_BOUND_SIZE);
|
|
flag_blocks=(SLONG*)MemAlloc(sizeof(SLONG)*MAX_BOUND_SIZE*MAX_BOUND_SIZE);
|
|
// flag_blocks2=(UWORD*)MemAlloc((sizeof(SLONG)*MAX_BOUND_SIZE*MAX_BOUND_SIZE)>>8);
|
|
cut_blocks=(UWORD*)MemAlloc(sizeof(UWORD)*MAX_BOUND_SIZE*MAX_BOUND_SIZE*4);
|
|
|
|
memset((UBYTE*)edge_heads_ptr,0,sizeof(UWORD)*MAX_BOUND_SIZE);
|
|
memset((UBYTE*)flag_blocks,0,sizeof(SLONG)*MAX_BOUND_SIZE*MAX_BOUND_SIZE);
|
|
// memset((UBYTE*)flag_blocks2,0,(sizeof(UWORD)*MAX_BOUND_SIZE*MAX_BOUND_SIZE)>>8);
|
|
memset((UBYTE*)cut_blocks,0,sizeof(UWORD)*MAX_BOUND_SIZE*MAX_BOUND_SIZE*4);
|
|
|
|
px=storey_list[storey].DX;
|
|
pz=storey_list[storey].DZ-edge_min_z;
|
|
wall=storey_list[storey].WallHead;
|
|
|
|
while(wall)
|
|
{
|
|
if(scan_line(px,pz,wall_list[wall].DX,wall_list[wall].DZ-edge_min_z,flag))
|
|
{
|
|
scan_line_z(px,pz,wall_list[wall].DX,wall_list[wall].DZ-edge_min_z,flag);
|
|
angles=1;
|
|
}
|
|
px=wall_list[wall].DX;
|
|
pz=wall_list[wall].DZ-edge_min_z;
|
|
|
|
wall=wall_list[wall].Next;
|
|
|
|
}
|
|
return(angles);
|
|
}
|
|
|
|
void build_more_edge_list(SLONG min_z,SLONG max_z,SLONG storey,SLONG flag)
|
|
{
|
|
UWORD wall;
|
|
SLONG px,pz;
|
|
|
|
|
|
px=storey_list[storey].DX;
|
|
pz=storey_list[storey].DZ;
|
|
if(pz>(max_z<<ELE_SHIFT))
|
|
{
|
|
pz=(max_z<<ELE_SHIFT);
|
|
}
|
|
|
|
pz-=edge_min_z;
|
|
|
|
ASSERT(pz>=0);
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
|
|
while(wall)
|
|
{
|
|
SLONG z;
|
|
z=wall_list[wall].DZ;
|
|
/*
|
|
if(z>(max_z<<ELE_SHIFT))
|
|
{
|
|
z=(max_z<<ELE_SHIFT);
|
|
}
|
|
*/
|
|
|
|
if(z>edge_min_z&&z<max_z)
|
|
{
|
|
|
|
if(scan_line(px,pz,wall_list[wall].DX,z-edge_min_z,flag))
|
|
{
|
|
scan_line_z(px,pz,wall_list[wall].DX,z-edge_min_z,flag);
|
|
|
|
}
|
|
}
|
|
px=wall_list[wall].DX;
|
|
pz=z-edge_min_z;
|
|
wall=wall_list[wall].Next;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void scan_bottom_line(SLONG x,SLONG z,SLONG x2,SLONG y)
|
|
{
|
|
SLONG dy;
|
|
//LogText(" scan bottom line (%x,%x)->(%x) \n",x1,(z1>>ELE_SIZE),x2);
|
|
|
|
//LogText(" scan bottom before x %d x2 %d z %d\n",x,x2,z);
|
|
|
|
x2=x2>>ELE_SHIFT;
|
|
x=(x>>ELE_SHIFT);
|
|
if(x>x2)
|
|
{
|
|
SLONG temp;
|
|
temp=x;
|
|
x=x2;
|
|
x2=temp;
|
|
}
|
|
//LogText(" scan bottom x %d x2 %d z %d\n",x,x2,z);
|
|
|
|
for(;x<=x2;x++)
|
|
{
|
|
if(flag_blocks[(x)+(z>>ELE_SHIFT)*MAX_BOUND_SIZE]==0)
|
|
{
|
|
//dy=edit_map[x][((z+edge_min_z)>>ELE_SHIFT)].Y<<FLOOR_HEIGHT_SHIFT;
|
|
dy=get_map_height(x,(z+edge_min_z)>>ELE_SHIFT)<<FLOOR_HEIGHT_SHIFT;
|
|
add_point(x<<ELE_SHIFT,y+dy,(z)+edge_min_z);
|
|
//LogText(" scan bottom (%d,%d)\n",x,z>>ELE_SIZE);
|
|
flag_blocks[(x)+(z>>ELE_SHIFT)*MAX_BOUND_SIZE]=next_prim_point-1;
|
|
}
|
|
//else
|
|
//LogText(" x %d z %d contains %d \n",x,z>>ELE_SHIFT,flag_blocks[(x)+(z>>ELE_SHIFT)*MAX_BOUND_SIZE]);
|
|
}
|
|
}
|
|
|
|
|
|
// scan horizontal edges
|
|
void build_bottom_edge_list(SLONG storey,SLONG y)
|
|
{
|
|
UWORD wall;
|
|
SLONG px,pz;
|
|
|
|
px=storey_list[storey].DX;
|
|
pz=storey_list[storey].DZ-edge_min_z;
|
|
wall=storey_list[storey].WallHead;
|
|
|
|
while(wall)
|
|
{
|
|
//add end points to the fray, incase we missed any
|
|
if(flag_blocks[(px>>ELE_SHIFT)+(pz>>ELE_SHIFT)*MAX_BOUND_SIZE]==0)
|
|
{
|
|
SLONG dy;
|
|
// dy=edit_map[px>>ELE_SHIFT][((pz+edge_min_z)>>ELE_SHIFT)].Y<<FLOOR_HEIGHT_SHIFT;
|
|
dy=get_map_height(px>>ELE_SHIFT,((pz+edge_min_z)>>ELE_SHIFT))<<FLOOR_HEIGHT_SHIFT;
|
|
add_point(px,y+dy,(pz)+edge_min_z);
|
|
flag_blocks[(px>>ELE_SHIFT)+(pz>>ELE_SHIFT)*MAX_BOUND_SIZE]=next_prim_point-1;
|
|
}
|
|
// LogText(" find bottom edge wall %d \n",wall);
|
|
if(pz==wall_list[wall].DZ-edge_min_z)
|
|
scan_bottom_line(px,pz,wall_list[wall].DX,y);
|
|
px=wall_list[wall].DX;
|
|
pz=wall_list[wall].DZ-edge_min_z;
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void bin_edge_list(void)
|
|
{
|
|
if(edge_pool_ptr)
|
|
{
|
|
MemFree((UBYTE*)edge_pool_ptr);
|
|
edge_pool_ptr=0;
|
|
}
|
|
if(edge_heads_ptr)
|
|
{
|
|
MemFree((UBYTE*)edge_heads_ptr);
|
|
edge_heads_ptr=0;
|
|
}
|
|
if(flag_blocks)
|
|
{
|
|
MemFree((UBYTE*)flag_blocks);
|
|
flag_blocks=0;
|
|
}
|
|
if(flag_blocks2)
|
|
{
|
|
// MemFree((UBYTE*)flag_blocks2);
|
|
flag_blocks=0;
|
|
}
|
|
if(cut_blocks)
|
|
{
|
|
MemFree((UBYTE*)cut_blocks);
|
|
cut_blocks=0;
|
|
}
|
|
// MemFree((UBYTE*)edge_pool_ptr);
|
|
// MemFree((UBYTE*)edge_heads_ptr);
|
|
// MemFree((UBYTE*)flag_blocks);
|
|
// MemFree((UBYTE*)cut_blocks);
|
|
}
|
|
|
|
|
|
|
|
#define BOUNDS(x,z) if(x<min_x) min_x=x;if (x>max_x) max_x=x; if(z<min_z) min_z=z; if(z>max_z) max_z=z;
|
|
|
|
#define INSIDE (0)
|
|
#define ON_EDGE (1)
|
|
#define OUTSIDE (2)
|
|
|
|
|
|
void dump_edge_list(UWORD size)
|
|
{
|
|
SLONG c0;
|
|
SLONG edge;
|
|
//return;
|
|
|
|
for(c0=0;c0<size;c0++)
|
|
{
|
|
edge=edge_heads_ptr[c0];
|
|
DebugText(" Z %d---",c0);
|
|
while(edge)
|
|
{
|
|
DebugText(" %x(%d) ",edge_pool_ptr[edge].X,edge_pool_ptr[edge].Count);
|
|
edge=edge_pool_ptr[edge].Next;
|
|
}
|
|
DebugText(" \n");
|
|
}
|
|
}
|
|
|
|
#define MYX(x) (((x-min_x)*box_width)+10)
|
|
#define MYY(x) (((x)*box_depth)+10)
|
|
|
|
#define MYFX(x) (( ((x-(min_x<<ELE_SHIFT))*(box_width>>3))>>(ELE_SHIFT-3))+10 )
|
|
#define MYFY(x) ( (((x)*(box_depth>>3))>>(ELE_SHIFT-3))+10)
|
|
/*
|
|
void show_grid(SLONG width,SLONG depth,SLONG min_x)
|
|
{
|
|
SLONG xt,xb,zl,zr;
|
|
SLONG x,z;
|
|
SLONG box_width,box_depth;
|
|
SetWorkWindowBounds(0,0,800,600);
|
|
DrawBox(0,0,800,600,0xfff);
|
|
|
|
box_depth=(580/depth);
|
|
box_width=(780/width);
|
|
|
|
|
|
LogText(" show grid width %d depth %d min_x %d \n",width,depth,min_x);
|
|
|
|
|
|
|
|
for(z=0;z<depth;z++)
|
|
{
|
|
for(x=min_x;x<min_x+width;x++)
|
|
{
|
|
SLONG x1,z1;
|
|
CBYTE xt_s[10],xb_s[10],zl_s[10],zr_s[10];
|
|
|
|
x1=((x-min_x)*box_width)+10;
|
|
z1=(z*box_depth)+10;
|
|
|
|
xt=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_TOP];
|
|
xb=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_BOTTOM];
|
|
zl=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_LEFT];
|
|
zr=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_RIGHT];
|
|
|
|
DrawLineC(x1,z1,x1+box_width,z1,0x8);
|
|
DrawLineC(x1+box_width,z1,x1+box_width,z1+box_depth,0x8);
|
|
DrawLineC(x1,z1+box_depth,x1+box_width,z1+box_depth,0x8);
|
|
DrawLineC(x1,z1,x1,z1+box_depth,0x8);
|
|
if(flag_blocks[x+z*MAX_BOUND_SIZE])
|
|
{
|
|
x1-=4;
|
|
z1-=4;
|
|
DrawLineC(x1,z1,x1+8,z1,0x8);
|
|
DrawLineC(x1+8,z1,x1+8,z1+8,0x8);
|
|
DrawLineC(x1,z1+8,x1+8,z1+8,0x8);
|
|
DrawLineC(x1,z1,x1,z1+8,0x8);
|
|
x1+=4;
|
|
z1+=4;
|
|
|
|
}
|
|
|
|
sprintf(xt_s,"%d",xt);
|
|
sprintf(xb_s,"%d",xb);
|
|
sprintf(zl_s,"%d",zl);
|
|
sprintf(zr_s,"%d",zr);
|
|
|
|
//QuickTextC(x1+((box_width)>>1)-7,z1+2,xt_s,0);
|
|
//QuickTextC(x1+((box_width)>>1)-7,z1+box_depth-12,xb_s,0);
|
|
//QuickTextC(x1+2,z1+(box_depth>>1)-6,zl_s,0);
|
|
//QuickTextC(x1+box_width-30,z1+(box_depth>>1)-6,zr_s,0);
|
|
#ifdef POO
|
|
|
|
if(xt)
|
|
DrawLineC(x1+(box_width>>1),z1+(box_depth>>1),MYFX(xt),z1,0x1f);
|
|
|
|
//DrawLineC(x1+(box_width>>1),z1+(box_depth>>1),MYFX(xt),z1,0x1f);
|
|
if(xb)
|
|
DrawLineC(x1+(box_width>>1),z1+(box_depth>>1),MYFX(xb),z1+box_depth,0x1f0);
|
|
|
|
if(zl)
|
|
DrawLineC(x1+(box_width>>1),z1+(box_depth>>1),x1,MYFY(zl),0x1f);
|
|
|
|
if(zr)
|
|
DrawLineC(x1+(box_width>>1),z1+(box_depth>>1),x1+box_width,MYFY(zr),0x1f0);
|
|
#endif
|
|
|
|
}
|
|
}
|
|
ShowWorkScreen(0);
|
|
while(!RightButton)
|
|
{
|
|
}
|
|
while(RightButton);
|
|
}
|
|
*/
|
|
|
|
|
|
#define set_UV4(x0,y0,x1,y1,x2,y2,x3,y3) UV[0][0]=(x0);UV[0][1]=(y0);UV[1][0]=(x1);UV[1][1]=(y1);UV[2][0]=(x3);UV[2][1]=(y3);UV[3][0]=(x2);UV[3][1]=(y2);
|
|
|
|
// mx,mz are map co_ords 0..MAP_WIDTH
|
|
void build_free_tri_texture_info(struct PrimFace3 *p_f3,SLONG mx,SLONG mz)
|
|
{
|
|
UBYTE tx,ty,page;
|
|
SLONG tsize;
|
|
SLONG rot;
|
|
UBYTE UV[4][2];
|
|
UWORD texture,p;
|
|
|
|
SLONG dtx_down,dty_down;
|
|
SLONG dtx_down_r,dty_down_r;
|
|
//SLONG dtx_across,dty_across;
|
|
|
|
// texture=edit_map[mx][mz].Texture;
|
|
texture=get_map_texture(mx,mz);
|
|
|
|
tx=((struct MiniTextureBits*)(&texture))->X<<5;
|
|
ty=((struct MiniTextureBits*)(&texture))->Y<<5;
|
|
page=(UBYTE)(((struct MiniTextureBits*)(&texture))->Page);
|
|
tsize=31;//floor_texture_sizes[((struct MiniTextureBits*)(&texture))->Size]-1;
|
|
rot=((struct MiniTextureBits*)(&texture))->Rot;
|
|
// rot=(rot3)&3;
|
|
switch(rot)
|
|
{
|
|
case 0:
|
|
set_UV4( tx,ty,tx+tsize,ty,tx,ty+tsize,tx+tsize,ty+tsize);
|
|
break;
|
|
case 1:
|
|
set_UV4( tx+tsize,ty,tx+tsize,ty+tsize,tx,ty,tx,ty+tsize);
|
|
break;
|
|
case 2:
|
|
set_UV4( tx+tsize,ty+tsize,tx,ty+tsize,tx+tsize,ty,tx,ty);
|
|
break;
|
|
case 3:
|
|
set_UV4( tx,ty+tsize,tx,ty,tx+tsize,ty+tsize,tx+tsize,ty);
|
|
break;
|
|
}
|
|
|
|
dtx_down=UV[3][0]-UV[0][0];
|
|
dty_down=UV[3][1]-UV[0][1];
|
|
|
|
dtx_down_r=UV[2][0]-UV[1][0];
|
|
dty_down_r=UV[2][1]-UV[1][1];
|
|
|
|
p_f3->TexturePage=page;
|
|
|
|
LogText(" U[0].X %d U[0].Y %d\n",UV[0][0],UV[0][1]);
|
|
LogText(" U[1].X %d U[1].Y %d\n",UV[1][0],UV[1][1]);
|
|
LogText(" U[2].X %d U[2].Y %d\n",UV[2][0],UV[2][1]);
|
|
LogText(" U[3].X %d U[3].Y %d\n",UV[3][0],UV[3][1]);
|
|
|
|
for(p=0;p<3;p++)
|
|
{
|
|
SLONG x1,z1;
|
|
SLONG lx,ly;
|
|
SLONG rx,ry;
|
|
|
|
|
|
x1=prim_points[p_f3->Points[p]].X-(mx<<ELE_SHIFT);
|
|
z1=prim_points[p_f3->Points[p]].Z-(mz<<ELE_SHIFT);
|
|
|
|
|
|
LogText(" free tri p %d x1 %d z1 %d \n",p,x1,z1);
|
|
|
|
|
|
lx=(z1*dtx_down)>>8;
|
|
ly=(z1*dty_down)>>8;
|
|
lx+=UV[0][0];
|
|
ly+=UV[0][1];
|
|
|
|
rx=(z1*dtx_down_r)>>8;
|
|
ry=(z1*dty_down_r)>>8;
|
|
|
|
rx+=UV[1][0];
|
|
ry+=UV[1][1];
|
|
|
|
LogText("left (%d,%d) right (%d,%d)\n",lx,ly,rx,ry);
|
|
|
|
p_f3->UV[p][0]=lx+(((rx-lx)*x1)>>8);
|
|
p_f3->UV[p][1]=ly+(((ry-ly)*x1)>>8);
|
|
|
|
LogText("result (%d,%d) \n",lx+(((rx-lx)*x1)>>8),ly+(((ry-ly)*x1)>>8));
|
|
}
|
|
}
|
|
|
|
void build_free_quad_texture_info(struct PrimFace4 *p_f4,SLONG mx,SLONG mz)
|
|
{
|
|
UBYTE tx,ty,page;
|
|
SLONG tsize;
|
|
SLONG rot;
|
|
UBYTE UV[4][2];
|
|
UWORD texture,p;
|
|
|
|
SLONG dtx_down,dty_down;
|
|
SLONG dtx_down_r,dty_down_r;
|
|
SLONG dtx_across,dty_across;
|
|
|
|
// texture=edit_map[mx][mz].Texture;
|
|
texture=get_map_texture(mx,mz);
|
|
|
|
tx=((struct MiniTextureBits*)(&texture))->X<<5;
|
|
ty=((struct MiniTextureBits*)(&texture))->Y<<5;
|
|
page=(UBYTE)(((struct MiniTextureBits*)(&texture))->Page);
|
|
tsize=31;//floor_texture_sizes[((struct MiniTextureBits*)(&texture))->Size]-1;
|
|
rot=((struct MiniTextureBits*)(&texture))->Rot;
|
|
// rot=(rot3)&3;
|
|
switch(rot)
|
|
{
|
|
case 0:
|
|
set_UV4( tx,ty,tx+tsize,ty,tx,ty+tsize,tx+tsize,ty+tsize);
|
|
break;
|
|
case 1:
|
|
set_UV4( tx+tsize,ty,tx+tsize,ty+tsize,tx,ty,tx,ty+tsize);
|
|
break;
|
|
case 2:
|
|
set_UV4( tx+tsize,ty+tsize,tx,ty+tsize,tx+tsize,ty,tx,ty);
|
|
break;
|
|
case 3:
|
|
set_UV4( tx,ty+tsize,tx,ty,tx+tsize,ty+tsize,tx+tsize,ty);
|
|
break;
|
|
}
|
|
|
|
dtx_down=UV[3][0]-UV[0][0];
|
|
dty_down=UV[3][1]-UV[0][1];
|
|
|
|
dtx_down_r=UV[2][0]-UV[1][0];
|
|
dty_down_r=UV[2][1]-UV[1][1];
|
|
|
|
p_f4->TexturePage=page;
|
|
|
|
LogText(" U[0].X %d U[0].Y %d\n",UV[0][0],UV[0][1]);
|
|
LogText(" U[1].X %d U[1].Y %d\n",UV[1][0],UV[1][1]);
|
|
LogText(" U[2].X %d U[2].Y %d\n",UV[2][0],UV[2][1]);
|
|
LogText(" U[3].X %d U[3].Y %d\n",UV[3][0],UV[3][1]);
|
|
|
|
for(p=0;p<4;p++)
|
|
{
|
|
SLONG x1,z1;
|
|
SLONG lx,ly;
|
|
SLONG rx,ry;
|
|
|
|
|
|
x1=prim_points[p_f4->Points[p]].X-(mx<<ELE_SHIFT);
|
|
z1=prim_points[p_f4->Points[p]].Z-(mz<<ELE_SHIFT);
|
|
|
|
|
|
LogText(" free tri p %d x1 %d z1 %d \n",p,x1,z1);
|
|
|
|
|
|
lx=(z1*dtx_down)>>8;
|
|
ly=(z1*dty_down)>>8;
|
|
lx+=UV[0][0];
|
|
ly+=UV[0][1];
|
|
|
|
rx=(z1*dtx_down_r)>>8;
|
|
ry=(z1*dty_down_r)>>8;
|
|
|
|
rx+=UV[1][0];
|
|
ry+=UV[1][1];
|
|
|
|
LogText(" left (%d,%d) right (%d,%d)\n",lx,ly,rx,ry);
|
|
|
|
p_f4->UV[p][0]=lx+(((rx-lx)*x1)>>8);
|
|
p_f4->UV[p][1]=ly+(((ry-ly)*x1)>>8);
|
|
|
|
LogText(" result (%d,%d) \n",lx+(((rx-lx)*x1)>>8),ly+(((ry-ly)*x1)>>8));
|
|
}
|
|
}
|
|
|
|
//edge_min_z subtracted from z's
|
|
//x's are in world co-ords
|
|
|
|
|
|
void scan_45(SLONG x1,SLONG z1,SLONG dx,SLONG dz)
|
|
{
|
|
UBYTE type=0;
|
|
SLONG count;
|
|
SLONG pp,p0,p1,p2,p3;
|
|
struct PrimFace3 *p_f3;
|
|
|
|
count=abs(dx)>>ELE_SHIFT;
|
|
x1=x1>>ELE_SHIFT;
|
|
z1=z1>>ELE_SHIFT;
|
|
|
|
if(dx<0)
|
|
{
|
|
dx=-1;
|
|
type|=1;
|
|
}
|
|
else
|
|
{
|
|
dx=1;
|
|
}
|
|
|
|
if(dz<0)
|
|
{
|
|
type|=2;
|
|
dz=-1;
|
|
}
|
|
else
|
|
{
|
|
dz=1;
|
|
}
|
|
|
|
pp=flag_blocks[(x1)+z1*MAX_BOUND_SIZE];
|
|
while(count)
|
|
{
|
|
x1+=dx;
|
|
z1+=dz;
|
|
|
|
p1=flag_blocks[(x1)+z1*MAX_BOUND_SIZE];
|
|
p2=flag_blocks[(x1-dx)+z1*MAX_BOUND_SIZE];
|
|
p3=flag_blocks[(x1)+(z1-dz)*MAX_BOUND_SIZE];
|
|
switch(type)
|
|
{ //(vector goes from pp to p1)
|
|
case 0: //SE
|
|
// pp p3
|
|
//
|
|
// p2 p1
|
|
p_f3=create_a_tri(p2,p1,pp,0,0);
|
|
build_free_tri_texture_info(p_f3,x1-dx,z1-dz+(edge_min_z>>ELE_SHIFT));
|
|
break;
|
|
case 1: //SW
|
|
// p3 pp
|
|
//
|
|
// p1 p2
|
|
p_f3=create_a_tri(p1,pp,p3,0,0);
|
|
build_free_tri_texture_info(p_f3,x1,z1-dz+(edge_min_z>>ELE_SHIFT));
|
|
break;
|
|
case 2: //NE
|
|
// p2 p1
|
|
//
|
|
// pp p3
|
|
p_f3=create_a_tri(pp,p3,p1,0,0);
|
|
build_free_tri_texture_info(p_f3,x1-dx,z1+(edge_min_z>>ELE_SHIFT));
|
|
break;
|
|
case 3: //NW
|
|
// p1 p2
|
|
//
|
|
// p3 pp
|
|
p_f3=create_a_tri(p1,pp,p2,0,0);
|
|
build_free_tri_texture_info(p_f3,x1,z1+(edge_min_z>>ELE_SHIFT));
|
|
break;
|
|
}
|
|
|
|
pp=p1;
|
|
count--;
|
|
}
|
|
}
|
|
|
|
SLONG build_storey_lip(SLONG storey,SLONG y)
|
|
{
|
|
SLONG flag=0;
|
|
SLONG out,height,dip;
|
|
|
|
if(storey_list[storey].StoreyFlags&(FLAG_STOREY_ROOF_RIM))
|
|
flag|=1;
|
|
if(storey_list[storey].StoreyFlags&(FLAG_STOREY_ROOF_RIM2))
|
|
flag|=2;
|
|
|
|
switch(flag)
|
|
{
|
|
case 0: //cant have 0
|
|
|
|
break;
|
|
case 1:
|
|
out=BLOCK_SIZE;
|
|
height=BLOCK_SIZE+(BLOCK_SIZE>>1);
|
|
dip=20;
|
|
break;
|
|
case 2:
|
|
out=BLOCK_SIZE>>1;
|
|
height=(BLOCK_SIZE>>1);
|
|
dip=0;
|
|
break;
|
|
case 3:
|
|
out=BLOCK_SIZE;
|
|
height=(BLOCK_SIZE);
|
|
dip=0; //BLOCK_SIZE>>2;
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
y=build_ledge2(y,storey,out,height,dip);
|
|
|
|
return(y);
|
|
}
|
|
|
|
SLONG current_building;
|
|
void create_walkable_structure(SLONG left,SLONG right,SLONG top,SLONG bottom,SLONG y,SLONG sp,SLONG sf4,SLONG dy)
|
|
{
|
|
struct DWalkable *p_w;
|
|
|
|
if(next_dwalkable>MAX_DWALKABLES-5)
|
|
ASSERT(0);
|
|
// return;
|
|
|
|
p_w=&dwalkables[next_dwalkable];
|
|
|
|
p_w->X1=left;
|
|
p_w->X2=right;
|
|
p_w->Z1=top;
|
|
p_w->Z2=bottom;
|
|
|
|
if(y<0)
|
|
y=0;
|
|
|
|
p_w->Y=y>>5;
|
|
ASSERT(p_w->Y!=255);
|
|
p_w->StoreyY=dy;
|
|
|
|
p_w->StartPoint=sp;
|
|
p_w->EndPoint=next_prim_point;
|
|
|
|
p_w->StartFace4=sf4;
|
|
p_w->EndFace4=next_prim_face4;
|
|
|
|
p_w->Next=building_list[current_building].Walkable;
|
|
p_w->Building=current_building;
|
|
building_list[current_building].Walkable=next_dwalkable;
|
|
|
|
{
|
|
SLONG c0;
|
|
for(c0=sf4;c0<next_prim_face4;c0++)
|
|
{
|
|
LogText(" face %d p0 %d p1 %d p2 %d p3 %d SP %d EP %d \n",c0,prim_faces4[c0].Points[0],prim_faces4[c0].Points[1],prim_faces4[c0].Points[2],prim_faces4[c0].Points[3],sp,next_prim_point);
|
|
}
|
|
}
|
|
|
|
|
|
next_dwalkable++;
|
|
|
|
}
|
|
|
|
// 0 1
|
|
//
|
|
// 2 3
|
|
|
|
void calc_face_split(struct PrimFace4 *p_f4)
|
|
{
|
|
SLONG y0,y1,y2,y3;
|
|
|
|
y0=prim_points[p_f4->Points[0]].Y;
|
|
y1=prim_points[p_f4->Points[1]].Y;
|
|
y2=prim_points[p_f4->Points[2]].Y;
|
|
y3=prim_points[p_f4->Points[3]].Y;
|
|
|
|
if(y1==y2 && y2==y3 && y0!=y1)
|
|
{
|
|
p_f4->FaceFlags|=FACE_FLAG_OTHER_SPLIT;
|
|
return;
|
|
}
|
|
if(y0==y1 && y1==y2 && y3!=y1)
|
|
{
|
|
p_f4->FaceFlags|=FACE_FLAG_OTHER_SPLIT;
|
|
return;
|
|
}
|
|
}
|
|
|
|
#define ROT1 (3<<8)
|
|
#define ROT2 (2<<8)
|
|
#define ROT3 (1<<8)
|
|
UWORD lookup_roof[]=
|
|
{
|
|
// ->>>0
|
|
//000
|
|
//0X0
|
|
//000
|
|
62,
|
|
// ->>>1
|
|
//100
|
|
//0X0
|
|
//000
|
|
62,
|
|
// ->>>2
|
|
//010
|
|
//0X0
|
|
//000
|
|
58,
|
|
// ->>>3
|
|
//110
|
|
//0X0
|
|
//000
|
|
58,
|
|
// ->>>4
|
|
//001
|
|
//0X0
|
|
//000
|
|
62,
|
|
// ->>>5
|
|
//101
|
|
//0X0
|
|
//000
|
|
62,
|
|
// ->>>6
|
|
//011
|
|
//0X0
|
|
//000
|
|
58,
|
|
// ->>>7
|
|
//111
|
|
//0X0
|
|
//000
|
|
58,
|
|
// ->>>8
|
|
//000
|
|
//1X0
|
|
//000
|
|
58+ROT3,
|
|
// ->>>9
|
|
//100
|
|
//1X0
|
|
//000
|
|
58+ROT3,
|
|
// ->>>10
|
|
//010
|
|
//1X0
|
|
//000
|
|
63,
|
|
// ->>>11
|
|
//110
|
|
//1X0
|
|
//000
|
|
55,
|
|
// ->>>12
|
|
//001
|
|
//1X0
|
|
//000
|
|
58+ROT3,
|
|
// ->>>13
|
|
//101
|
|
//1X0
|
|
//000
|
|
58+ROT3,
|
|
// ->>>14
|
|
//011
|
|
//1X0
|
|
//000
|
|
63,
|
|
// ->>>15
|
|
//111
|
|
//1X0
|
|
//000
|
|
55,
|
|
// ->>>16
|
|
//000
|
|
//0X1
|
|
//000
|
|
58+ROT1,
|
|
// ->>>17
|
|
//100
|
|
//0X1
|
|
//000
|
|
58+ROT1,
|
|
// ->>>18
|
|
//010
|
|
//0X1
|
|
//000
|
|
63+ROT1,
|
|
// ->>>19
|
|
//110
|
|
//0X1
|
|
//000
|
|
63+ROT1,
|
|
// ->>>20
|
|
//001
|
|
//0X1
|
|
//000
|
|
58+ROT1,
|
|
// ->>>21
|
|
//101
|
|
//0X1
|
|
//000
|
|
58+ROT1,
|
|
// ->>>22
|
|
//011
|
|
//0X1
|
|
//000
|
|
55+ROT1,
|
|
// ->>>23
|
|
//111
|
|
//0X1
|
|
//000
|
|
55+ROT1,
|
|
// ->>>24
|
|
//000
|
|
//1X1
|
|
//000
|
|
57,
|
|
// ->>>25
|
|
//100
|
|
//1X1
|
|
//000
|
|
57,
|
|
// ->>>26
|
|
//010
|
|
//1X1
|
|
//000
|
|
65,
|
|
// ->>>27
|
|
//110
|
|
//1X1
|
|
//000
|
|
61,
|
|
// ->>>28
|
|
//001
|
|
//1X1
|
|
//000
|
|
57,
|
|
// ->>>29
|
|
//101
|
|
//1X1
|
|
//000
|
|
57,
|
|
// ->>>30
|
|
//011
|
|
//1X1
|
|
//000
|
|
60,
|
|
// ->>>31
|
|
//111
|
|
//1X1
|
|
//000
|
|
54,
|
|
// ->>>32
|
|
//000
|
|
//0X0
|
|
//100
|
|
62,
|
|
// ->>>33
|
|
//100
|
|
//0X0
|
|
//100
|
|
62,
|
|
// ->>>34
|
|
//010
|
|
//0X0
|
|
//100
|
|
58,
|
|
// ->>>35
|
|
//110
|
|
//0X0
|
|
//100
|
|
58,
|
|
// ->>>36
|
|
//001
|
|
//0X0
|
|
//100
|
|
62,
|
|
// ->>>37
|
|
//101
|
|
//0X0
|
|
//100
|
|
62,
|
|
// ->>>38
|
|
//011
|
|
//0X0
|
|
//100
|
|
58,
|
|
// ->>>39
|
|
//111
|
|
//0X0
|
|
//100
|
|
58,
|
|
// ->>>40
|
|
//000
|
|
//1X0
|
|
//100
|
|
58+ROT3,
|
|
// ->>>41
|
|
//100
|
|
//1X0
|
|
//100
|
|
58+ROT3,
|
|
// ->>>42
|
|
//010
|
|
//1X0
|
|
//100
|
|
63,
|
|
// ->>>43
|
|
//110
|
|
//1X0
|
|
//100
|
|
55,
|
|
// ->>>44
|
|
//001
|
|
//1X0
|
|
//100
|
|
58+ROT3,
|
|
// ->>>45
|
|
//101
|
|
//1X0
|
|
//100
|
|
58+ROT3,
|
|
// ->>>46
|
|
//011
|
|
//1X0
|
|
//100
|
|
63,
|
|
// ->>>47
|
|
//111
|
|
//1X0
|
|
//100
|
|
55,
|
|
// ->>>48
|
|
//000
|
|
//0X1
|
|
//100
|
|
58+ROT1,
|
|
// ->>>49
|
|
//100
|
|
//0X1
|
|
//100
|
|
58+ROT1,
|
|
// ->>>50
|
|
//010
|
|
//0X1
|
|
//100
|
|
63+ROT1,
|
|
// ->>>51
|
|
//110
|
|
//0X1
|
|
//100
|
|
63+ROT1,
|
|
// ->>>52
|
|
//001
|
|
//0X1
|
|
//100
|
|
58+ROT1,
|
|
// ->>>53
|
|
//101
|
|
//0X1
|
|
//100
|
|
58+ROT1,
|
|
// ->>>54
|
|
//011
|
|
//0X1
|
|
//100
|
|
55+ROT1,
|
|
// ->>>55
|
|
//111
|
|
//0X1
|
|
//100
|
|
55+ROT1,
|
|
// ->>>56
|
|
//000
|
|
//1X1
|
|
//100
|
|
57,
|
|
// ->>>57
|
|
//100
|
|
//1X1
|
|
//100
|
|
57,
|
|
// ->>>58
|
|
//010
|
|
//1X1
|
|
//100
|
|
60,
|
|
// ->>>59
|
|
//110
|
|
//1X1
|
|
//100
|
|
61,
|
|
// ->>>60
|
|
//001
|
|
//1X1
|
|
//100
|
|
57,
|
|
// ->>>61
|
|
//101
|
|
//1X1
|
|
//100
|
|
57,
|
|
// ->>>62
|
|
//011
|
|
//1X1
|
|
//100
|
|
60,
|
|
// ->>>63
|
|
//111
|
|
//1X1
|
|
//100
|
|
54,
|
|
// ->>>64
|
|
//000
|
|
//0X0
|
|
//010
|
|
58+ROT2,
|
|
// ->>>65
|
|
//100
|
|
//0X0
|
|
//010
|
|
58+ROT2,
|
|
// ->>>66
|
|
//010
|
|
//0X0
|
|
//010
|
|
57+ROT1,
|
|
// ->>>67
|
|
//110
|
|
//0X0
|
|
//010
|
|
57+ROT1,
|
|
// ->>>68
|
|
//001
|
|
//0X0
|
|
//010
|
|
58+ROT2,
|
|
// ->>>69
|
|
//101
|
|
//0X0
|
|
//010
|
|
58+ROT2,
|
|
// ->>>70
|
|
//011
|
|
//0X0
|
|
//010
|
|
57+ROT1,
|
|
// ->>>71
|
|
//111
|
|
//0X0
|
|
//010
|
|
57+ROT1,
|
|
// ->>>72
|
|
//000
|
|
//1X0
|
|
//010
|
|
63+ROT3,
|
|
// ->>>73
|
|
//100
|
|
//1X0
|
|
//010
|
|
63+ROT3,
|
|
// ->>>74
|
|
//010
|
|
//1X0
|
|
//010
|
|
0,
|
|
// ->>>75
|
|
//110
|
|
//1X0
|
|
//010
|
|
60+ROT3,
|
|
// ->>>76
|
|
//001
|
|
//1X0
|
|
//010
|
|
63+ROT3,
|
|
// ->>>77
|
|
//101
|
|
//1X0
|
|
//010
|
|
63+ROT3,
|
|
// ->>>78
|
|
//011
|
|
//1X0
|
|
//010
|
|
0,
|
|
// ->>>79
|
|
//111
|
|
//1X0
|
|
//010
|
|
60+ROT3,
|
|
// ->>>80
|
|
//000
|
|
//0X1
|
|
//010
|
|
63+ROT2,
|
|
// ->>>81
|
|
//100
|
|
//0X1
|
|
//010
|
|
63+ROT2,
|
|
// ->>>82
|
|
//010
|
|
//0X1
|
|
//010
|
|
0,
|
|
// ->>>83
|
|
//110
|
|
//0X1
|
|
//010
|
|
0,
|
|
// ->>>84
|
|
//001
|
|
//0X1
|
|
//010
|
|
63+ROT2,
|
|
// ->>>85
|
|
//101
|
|
//0X1
|
|
//010
|
|
63+ROT2,
|
|
// ->>>86
|
|
//011
|
|
//0X1
|
|
//010
|
|
61+ROT1,
|
|
// ->>>87
|
|
//111
|
|
//0X1
|
|
//010
|
|
61+ROT1,
|
|
// ->>>88
|
|
//000
|
|
//1X1
|
|
//010
|
|
65+ROT2,
|
|
// ->>>89
|
|
//100
|
|
//1X1
|
|
//010
|
|
65+ROT2,
|
|
// ->>>90
|
|
//010
|
|
//1X1
|
|
//010
|
|
0,
|
|
// ->>>91
|
|
//110
|
|
//1X1
|
|
//010
|
|
0,
|
|
// ->>>92
|
|
//001
|
|
//1X1
|
|
//010
|
|
65+ROT2,
|
|
// ->>>93
|
|
//101
|
|
//1X1
|
|
//010
|
|
65+ROT2,
|
|
// ->>>94
|
|
//011
|
|
//1X1
|
|
//010
|
|
0,
|
|
// ->>>95
|
|
//111
|
|
//1X1
|
|
//010
|
|
59,
|
|
// ->>>96
|
|
//000
|
|
//0X0
|
|
//110
|
|
58+ROT2,
|
|
// ->>>97
|
|
//100
|
|
//0X0
|
|
//110
|
|
58+ROT2,
|
|
// ->>>98
|
|
//010
|
|
//0X0
|
|
//110
|
|
57+ROT1,
|
|
// ->>>99
|
|
//110
|
|
//0X0
|
|
//110
|
|
57+ROT1,
|
|
// ->>>100
|
|
//001
|
|
//0X0
|
|
//110
|
|
58+ROT2,
|
|
// ->>>101
|
|
//101
|
|
//0X0
|
|
//110
|
|
58+ROT2,
|
|
// ->>>102
|
|
//011
|
|
//0X0
|
|
//110
|
|
57+ROT1,
|
|
// ->>>103
|
|
//111
|
|
//0X0
|
|
//110
|
|
57+ROT1,
|
|
// ->>>104
|
|
//000
|
|
//1X0
|
|
//110
|
|
55+ROT3,
|
|
// ->>>105
|
|
//100
|
|
//1X0
|
|
//110
|
|
55+ROT3,
|
|
// ->>>106
|
|
//010
|
|
//1X0
|
|
//110
|
|
61+ROT3,
|
|
// ->>>107
|
|
//110
|
|
//1X0
|
|
//110
|
|
54+ROT3,
|
|
// ->>>108
|
|
//001
|
|
//1X0
|
|
//110
|
|
55+ROT3,
|
|
// ->>>109
|
|
//101
|
|
//1X0
|
|
//110
|
|
55+ROT3,
|
|
// ->>>110
|
|
//011
|
|
//1X0
|
|
//110
|
|
61+ROT3,
|
|
// ->>>111
|
|
//111
|
|
//1X0
|
|
//110
|
|
54+ROT3,
|
|
// ->>>112
|
|
//000
|
|
//0X1
|
|
//110
|
|
63+ROT2,
|
|
// ->>>113
|
|
//100
|
|
//0X1
|
|
//110
|
|
63+ROT2,
|
|
// ->>>114
|
|
//010
|
|
//0X1
|
|
//110
|
|
65+ROT1,
|
|
// ->>>115
|
|
//110
|
|
//0X1
|
|
//110
|
|
65+ROT1,
|
|
// ->>>116
|
|
//001
|
|
//0X1
|
|
//110
|
|
63+ROT2,
|
|
// ->>>117
|
|
//101
|
|
//0X1
|
|
//110
|
|
63+ROT2,
|
|
// ->>>118
|
|
//011
|
|
//0X1
|
|
//110
|
|
61+ROT1,
|
|
// ->>>119
|
|
//111
|
|
//0X1
|
|
//110
|
|
61+ROT1,
|
|
// ->>>120
|
|
//000
|
|
//1X1
|
|
//110
|
|
60+ROT2,
|
|
// ->>>121
|
|
//100
|
|
//1X1
|
|
//110
|
|
60+ROT2,
|
|
// ->>>122
|
|
//010
|
|
//1X1
|
|
//110
|
|
0,
|
|
// ->>>123
|
|
//110
|
|
//1X1
|
|
//110
|
|
59+ROT3,
|
|
// ->>>124
|
|
//001
|
|
//1X1
|
|
//110
|
|
60+ROT2,
|
|
// ->>>125
|
|
//101
|
|
//1X1
|
|
//110
|
|
60+ROT2,
|
|
// ->>>126
|
|
//011
|
|
//1X1
|
|
//110
|
|
64,
|
|
// ->>>127
|
|
//111
|
|
//1X1
|
|
//110
|
|
56,
|
|
// ->>>128
|
|
//000
|
|
//0X0
|
|
//001
|
|
62,
|
|
// ->>>129
|
|
//100
|
|
//0X0
|
|
//001
|
|
62,
|
|
// ->>>130
|
|
//010
|
|
//0X0
|
|
//001
|
|
58,
|
|
// ->>>131
|
|
//110
|
|
//0X0
|
|
//001
|
|
58,
|
|
// ->>>132
|
|
//001
|
|
//0X0
|
|
//001
|
|
62,
|
|
// ->>>133
|
|
//101
|
|
//0X0
|
|
//001
|
|
62,
|
|
// ->>>134
|
|
//011
|
|
//0X0
|
|
//001
|
|
58,
|
|
// ->>>135
|
|
//111
|
|
//0X0
|
|
//001
|
|
58,
|
|
// ->>>136
|
|
//000
|
|
//1X0
|
|
//001
|
|
58+ROT3,
|
|
// ->>>137
|
|
//100
|
|
//1X0
|
|
//001
|
|
58+ROT2,
|
|
// ->>>138
|
|
//010
|
|
//1X0
|
|
//001
|
|
63,
|
|
// ->>>139
|
|
//110
|
|
//1X0
|
|
//001
|
|
55,
|
|
// ->>>140
|
|
//001
|
|
//1X0
|
|
//001
|
|
58+ROT3,
|
|
// ->>>141
|
|
//101
|
|
//1X0
|
|
//001
|
|
58,
|
|
// ->>>142
|
|
//011
|
|
//1X0
|
|
//001
|
|
63,
|
|
// ->>>143
|
|
//111
|
|
//1X0
|
|
//001
|
|
55,
|
|
// ->>>144
|
|
//000
|
|
//0X1
|
|
//001
|
|
58+ROT1,
|
|
// ->>>145
|
|
//100
|
|
//0X1
|
|
//001
|
|
58+ROT1,
|
|
// ->>>146
|
|
//010
|
|
//0X1
|
|
//001
|
|
63+ROT1,
|
|
// ->>>147
|
|
//110
|
|
//0X1
|
|
//001
|
|
63+ROT1,
|
|
// ->>>148
|
|
//001
|
|
//0X1
|
|
//001
|
|
58+ROT1,
|
|
// ->>>149
|
|
//101
|
|
//0X1
|
|
//001
|
|
58+ROT1,
|
|
// ->>>150
|
|
//011
|
|
//0X1
|
|
//001
|
|
55+ROT1,
|
|
// ->>>151
|
|
//111
|
|
//0X1
|
|
//001
|
|
55+ROT1,
|
|
// ->>>152
|
|
//000
|
|
//1X1
|
|
//001
|
|
57,
|
|
// ->>>153
|
|
//100
|
|
//1X1
|
|
//001
|
|
57,
|
|
// ->>>154
|
|
//010
|
|
//1X1
|
|
//001
|
|
65,
|
|
// ->>>155
|
|
//110
|
|
//1X1
|
|
//001
|
|
61,
|
|
// ->>>156
|
|
//001
|
|
//1X1
|
|
//001
|
|
57,
|
|
// ->>>157
|
|
//101
|
|
//1X1
|
|
//001
|
|
57,
|
|
// ->>>158
|
|
//011
|
|
//1X1
|
|
//001
|
|
60,
|
|
// ->>>159
|
|
//111
|
|
//1X1
|
|
//001
|
|
54,
|
|
// ->>>160
|
|
//000
|
|
//0X0
|
|
//101
|
|
62,
|
|
// ->>>161
|
|
//100
|
|
//0X0
|
|
//101
|
|
62,
|
|
// ->>>162
|
|
//010
|
|
//0X0
|
|
//101
|
|
58,
|
|
// ->>>163
|
|
//110
|
|
//0X0
|
|
//101
|
|
58,
|
|
// ->>>164
|
|
//001
|
|
//0X0
|
|
//101
|
|
62,
|
|
// ->>>165
|
|
//101
|
|
//0X0
|
|
//101
|
|
62,
|
|
// ->>>166
|
|
//011
|
|
//0X0
|
|
//101
|
|
58,
|
|
// ->>>167
|
|
//111
|
|
//0X0
|
|
//101
|
|
58,
|
|
// ->>>168
|
|
//000
|
|
//1X0
|
|
//101
|
|
58+ROT3,
|
|
// ->>>169
|
|
//100
|
|
//1X0
|
|
//101
|
|
58+ROT3,
|
|
// ->>>170
|
|
//010
|
|
//1X0
|
|
//101
|
|
63,
|
|
// ->>>171
|
|
//110
|
|
//1X0
|
|
//101
|
|
55,
|
|
// ->>>172
|
|
//001
|
|
//1X0
|
|
//101
|
|
58+ROT3,
|
|
// ->>>173
|
|
//101
|
|
//1X0
|
|
//101
|
|
58+ROT3,
|
|
// ->>>174
|
|
//011
|
|
//1X0
|
|
//101
|
|
63,
|
|
// ->>>175
|
|
//111
|
|
//1X0
|
|
//101
|
|
55,
|
|
// ->>>176
|
|
//000
|
|
//0X1
|
|
//101
|
|
58+ROT1,
|
|
// ->>>177
|
|
//100
|
|
//0X1
|
|
//101
|
|
58+ROT1,
|
|
// ->>>178
|
|
//010
|
|
//0X1
|
|
//101
|
|
63+ROT1,
|
|
// ->>>179
|
|
//110
|
|
//0X1
|
|
//101
|
|
63+ROT1,
|
|
// ->>>180
|
|
//001
|
|
//0X1
|
|
//101
|
|
58+ROT1,
|
|
// ->>>181
|
|
//101
|
|
//0X1
|
|
//101
|
|
58+ROT1,
|
|
// ->>>182
|
|
//011
|
|
//0X1
|
|
//101
|
|
55+ROT1,
|
|
// ->>>183
|
|
//111
|
|
//0X1
|
|
//101
|
|
55+ROT1,
|
|
// ->>>184
|
|
//000
|
|
//1X1
|
|
//101
|
|
57,
|
|
// ->>>185
|
|
//100
|
|
//1X1
|
|
//101
|
|
57,
|
|
// ->>>186
|
|
//010
|
|
//1X1
|
|
//101
|
|
65,
|
|
// ->>>187
|
|
//110
|
|
//1X1
|
|
//101
|
|
61,
|
|
// ->>>188
|
|
//001
|
|
//1X1
|
|
//101
|
|
57,
|
|
// ->>>189
|
|
//101
|
|
//1X1
|
|
//101
|
|
57,
|
|
// ->>>190
|
|
//011
|
|
//1X1
|
|
//101
|
|
60,
|
|
// ->>>191
|
|
//111
|
|
//1X1
|
|
//101
|
|
54,
|
|
// ->>>192
|
|
//000
|
|
//0X0
|
|
//011
|
|
58+ROT2,
|
|
// ->>>193
|
|
//100
|
|
//0X0
|
|
//011
|
|
58+ROT2,
|
|
// ->>>194
|
|
//010
|
|
//0X0
|
|
//011
|
|
57+ROT1,
|
|
// ->>>195
|
|
//110
|
|
//0X0
|
|
//011
|
|
57+ROT1,
|
|
// ->>>196
|
|
//001
|
|
//0X0
|
|
//011
|
|
58+ROT2,
|
|
// ->>>197
|
|
//101
|
|
//0X0
|
|
//011
|
|
58+ROT2,
|
|
// ->>>198
|
|
//011
|
|
//0X0
|
|
//011
|
|
57+ROT1,
|
|
// ->>>199
|
|
//111
|
|
//0X0
|
|
//011
|
|
57+ROT1,
|
|
// ->>>200
|
|
//000
|
|
//1X0
|
|
//011
|
|
63+ROT3,
|
|
// ->>>201
|
|
//100
|
|
//1X0
|
|
//011
|
|
63+ROT3,
|
|
// ->>>202
|
|
//010
|
|
//1X0
|
|
//011
|
|
61+ROT3,
|
|
// ->>>203
|
|
//110
|
|
//1X0
|
|
//011
|
|
60+ROT3,
|
|
// ->>>204
|
|
//001
|
|
//1X0
|
|
//011
|
|
63+ROT3,
|
|
// ->>>205
|
|
//101
|
|
//1X0
|
|
//011
|
|
63+ROT3,
|
|
// ->>>206
|
|
//011
|
|
//1X0
|
|
//011
|
|
65+ROT3,
|
|
// ->>>207
|
|
//111
|
|
//1X0
|
|
//011
|
|
60+ROT3,
|
|
// ->>>208
|
|
//000
|
|
//0X1
|
|
//011
|
|
55+ROT2,
|
|
// ->>>209
|
|
//100
|
|
//0X1
|
|
//011
|
|
55+ROT2,
|
|
// ->>>210
|
|
//010
|
|
//0X1
|
|
//011
|
|
60+ROT1,
|
|
// ->>>211
|
|
//110
|
|
//0X1
|
|
//011
|
|
60+ROT1,
|
|
// ->>>212
|
|
//001
|
|
//0X1
|
|
//011
|
|
55+ROT2,
|
|
// ->>>213
|
|
//101
|
|
//0X1
|
|
//011
|
|
55+ROT2,
|
|
// ->>>214
|
|
//011
|
|
//0X1
|
|
//011
|
|
54+ROT1,
|
|
// ->>>215
|
|
//111
|
|
//0X1
|
|
//011
|
|
54+ROT1,
|
|
// ->>>216
|
|
//000
|
|
//1X1
|
|
//011
|
|
61+ROT2,
|
|
// ->>>217
|
|
//100
|
|
//1X1
|
|
//011
|
|
61+ROT2,
|
|
// ->>>218
|
|
//010
|
|
//1X1
|
|
//011
|
|
0,
|
|
// ->>>219
|
|
//110
|
|
//1X1
|
|
//011
|
|
64+ROT1,
|
|
// ->>>220
|
|
//001
|
|
//1X1
|
|
//011
|
|
61+ROT2,
|
|
// ->>>221
|
|
//101
|
|
//1X1
|
|
//011
|
|
61+ROT2,
|
|
// ->>>222
|
|
//011
|
|
//1X1
|
|
//011
|
|
58+ROT1,
|
|
// ->>>223
|
|
//111
|
|
//1X1
|
|
//011
|
|
56+ROT1,
|
|
// ->>>224
|
|
//000
|
|
//0X0
|
|
//111
|
|
58+ROT2,
|
|
// ->>>225
|
|
//100
|
|
//0X0
|
|
//111
|
|
58+ROT2,
|
|
// ->>>226
|
|
//010
|
|
//0X0
|
|
//111
|
|
57+ROT1,
|
|
// ->>>227
|
|
//110
|
|
//0X0
|
|
//111
|
|
57+ROT1,
|
|
// ->>>228
|
|
//001
|
|
//0X0
|
|
//111
|
|
58+ROT2,
|
|
// ->>>229
|
|
//101
|
|
//0X0
|
|
//111
|
|
58+ROT2,
|
|
// ->>>230
|
|
//011
|
|
//0X0
|
|
//111
|
|
57+ROT1,
|
|
// ->>>231
|
|
//111
|
|
//0X0
|
|
//111
|
|
57+ROT1,
|
|
// ->>>232
|
|
//000
|
|
//1X0
|
|
//111
|
|
55+ROT3,
|
|
// ->>>233
|
|
//100
|
|
//1X0
|
|
//111
|
|
55+ROT3,
|
|
// ->>>234
|
|
//010
|
|
//1X0
|
|
//111
|
|
61+ROT3,
|
|
// ->>>235
|
|
//110
|
|
//1X0
|
|
//111
|
|
54+ROT3,
|
|
// ->>>236
|
|
//001
|
|
//1X0
|
|
//111
|
|
55+ROT3,
|
|
// ->>>237
|
|
//101
|
|
//1X0
|
|
//111
|
|
55+ROT3,
|
|
// ->>>238
|
|
//011
|
|
//1X0
|
|
//111
|
|
61+ROT3,
|
|
// ->>>239
|
|
//111
|
|
//1X0
|
|
//111
|
|
54+ROT3,
|
|
// ->>>240
|
|
//000
|
|
//0X1
|
|
//111
|
|
55+ROT2,
|
|
// ->>>241
|
|
//100
|
|
//0X1
|
|
//111
|
|
55+ROT2,
|
|
// ->>>242
|
|
//010
|
|
//0X1
|
|
//111
|
|
60+ROT1,
|
|
// ->>>243
|
|
//110
|
|
//0X1
|
|
//111
|
|
60+ROT1,
|
|
// ->>>244
|
|
//001
|
|
//0X1
|
|
//111
|
|
55+ROT2,
|
|
// ->>>245
|
|
//101
|
|
//0X1
|
|
//111
|
|
55+ROT2,
|
|
// ->>>246
|
|
//011
|
|
//0X1
|
|
//111
|
|
54+ROT1,
|
|
// ->>>247
|
|
//111
|
|
//0X1
|
|
//111
|
|
54+ROT1,
|
|
// ->>>248
|
|
//000
|
|
//1X1
|
|
//111
|
|
54+ROT2,
|
|
// ->>>249
|
|
//100
|
|
//1X1
|
|
//111
|
|
54+ROT2,
|
|
// ->>>250
|
|
//010
|
|
//1X1
|
|
//111
|
|
59+ROT2,
|
|
// ->>>251
|
|
//110
|
|
//1X1
|
|
//111
|
|
56+ROT3,
|
|
// ->>>252
|
|
//001
|
|
//1X1
|
|
//111
|
|
54+ROT2,
|
|
// ->>>253
|
|
//101
|
|
//1X1
|
|
//111
|
|
54+ROT2,
|
|
// ->>>254
|
|
//011
|
|
//1X1
|
|
//111
|
|
56+ROT2,
|
|
// ->>>255
|
|
//111
|
|
//1X1
|
|
//111
|
|
37,
|
|
};
|
|
|
|
SLONG build_easy_roof(SLONG min_x,SLONG edge_min_z,SLONG max_x,SLONG depth,SLONG y,SLONG face_wall,SLONG flag)
|
|
{
|
|
SLONG x,z;
|
|
SLONG valid_roof=0;
|
|
struct PrimFace4 *p_f4;
|
|
SLONG small_dy=9999999;
|
|
SLONG lmin_x=9999999,lmax_x=-9999999,lmin_z=9999999,lmax_z=-9999999;
|
|
SLONG flatten=0;
|
|
SLONG maxy=-9999;
|
|
|
|
SLONG sp,ep,sf4,ef4;
|
|
if(edit_info.HideMap&4)
|
|
return(0);
|
|
|
|
sp=next_prim_point;
|
|
sf4=next_prim_face4;
|
|
|
|
// y+=build_max_y;
|
|
|
|
// if(ShiftFlag)
|
|
// flatten=1;
|
|
|
|
for(z=0;z<depth;z++)
|
|
{
|
|
SLONG polarity=0;
|
|
SLONG edge;
|
|
SLONG dy=0;
|
|
SLONG prev_x_in=0;
|
|
edge=edge_heads_ptr[z];
|
|
DebugText("\n roof polys z=%d x %x",z+(edge_min_z>>8),min_x-256+128);
|
|
|
|
for(x=min_x-256+128;x<max_x+256 && edge;x+=ELE_SIZE)
|
|
{
|
|
|
|
//
|
|
// we are greater then we have crossed an edge
|
|
//
|
|
if((x)>edge_pool_ptr[edge].X)
|
|
{
|
|
//
|
|
// crossed an edge so flip the priority
|
|
//
|
|
DebugText("%d",edge_pool_ptr[edge].Count);
|
|
|
|
polarity+=edge_pool_ptr[edge].Count;
|
|
edge=edge_pool_ptr[edge].Next;
|
|
}
|
|
// else
|
|
// DebugText("0");
|
|
|
|
if(polarity&1)
|
|
// if(edit_map[(x>>ELE_SHIFT)][z+(edge_min_z>>ELE_SHIFT)].Flags&PAP_FLAG_REFLECTIVE)
|
|
{
|
|
SLONG tl,tr,bl,br;
|
|
SLONG texture;
|
|
|
|
DebugText("[]");
|
|
|
|
if(x<lmin_x)
|
|
lmin_x=x;
|
|
|
|
if(z<lmin_z)
|
|
lmin_z=z;
|
|
|
|
if(x>lmax_x)
|
|
lmax_x=x;
|
|
|
|
if(z>lmax_z)
|
|
lmax_z=z;
|
|
valid_roof=1;
|
|
/*
|
|
if(flatten)
|
|
{
|
|
|
|
if(z&&x)
|
|
if(flag_blocks[(x>>ELE_SHIFT)+(z-1)*MAX_BOUND_SIZE])
|
|
if(flag_blocks[(x>>ELE_SHIFT)-1+(z)*MAX_BOUND_SIZE])
|
|
set_map_height((x>>ELE_SHIFT),z+(edge_min_z>>ELE_SHIFT),build_max_y>>FLOOR_HEIGHT_SHIFT);
|
|
}
|
|
*/
|
|
|
|
tl=flag_blocks[(x>>ELE_SHIFT)+z*MAX_BOUND_SIZE];
|
|
if(!tl)
|
|
{
|
|
if(flag==0)
|
|
dy=(get_roof_height((x>>ELE_SHIFT),z+(edge_min_z>>ELE_SHIFT))<<FLOOR_HEIGHT_SHIFT); //-build_max_y;
|
|
|
|
if(y+dy>maxy)
|
|
maxy=y+dy;
|
|
|
|
add_point(x-128,y+dy,(z<<ELE_SHIFT)+edge_min_z);
|
|
// DebugText(" roof point a %d %d %d next prim point %d\n",x-128,y+dy,(z<<ELE_SHIFT)+edge_min_z,next_prim_point);
|
|
flag_blocks[(x>>ELE_SHIFT)+z*MAX_BOUND_SIZE]=next_prim_point-1;
|
|
tl=next_prim_point-1;
|
|
}
|
|
|
|
tr=flag_blocks[(x>>ELE_SHIFT)+1+z*MAX_BOUND_SIZE];
|
|
if(!tr)
|
|
{
|
|
if(flag==0)
|
|
dy=(get_roof_height((x>>ELE_SHIFT)+1,z+(edge_min_z>>ELE_SHIFT))<<FLOOR_HEIGHT_SHIFT); //-build_max_y;
|
|
|
|
if(y+dy>maxy)
|
|
maxy=y+dy;
|
|
|
|
add_point(x-128+ELE_SIZE,y+dy,(z<<ELE_SHIFT)+edge_min_z);
|
|
// DebugText(" roof point b %d %d %d next prim point %d\n",x-128+ELE_SIZE,y+dy,(z<<ELE_SHIFT)+edge_min_z,next_prim_point);
|
|
flag_blocks[(x>>ELE_SHIFT)+1+z*MAX_BOUND_SIZE]=next_prim_point-1;
|
|
tr=next_prim_point-1;
|
|
}
|
|
|
|
bl=flag_blocks[(x>>ELE_SHIFT)+(z+1)*MAX_BOUND_SIZE];
|
|
if(!bl)
|
|
{
|
|
if(flag==0)
|
|
dy=(get_roof_height((x>>ELE_SHIFT),z+1+(edge_min_z>>ELE_SHIFT))<<FLOOR_HEIGHT_SHIFT); //-build_max_y;
|
|
|
|
if(y+dy>maxy)
|
|
maxy=y+dy;
|
|
add_point(x-128,y+dy,(z<<ELE_SHIFT)+edge_min_z+ELE_SIZE);
|
|
// DebugText(" roof point c %d %d %d next prim point %d\n",x-128,y+dy,(z<<ELE_SHIFT)+edge_min_z+ELE_SIZE,next_prim_point);
|
|
flag_blocks[(x>>ELE_SHIFT)+(z+1)*MAX_BOUND_SIZE]=next_prim_point-1;
|
|
bl=next_prim_point-1;
|
|
}
|
|
br=flag_blocks[(x>>ELE_SHIFT)+1+(z+1)*MAX_BOUND_SIZE];
|
|
if(!br)
|
|
{
|
|
if(flag==0)
|
|
dy=(get_roof_height((x>>ELE_SHIFT)+1,z+1+(edge_min_z>>ELE_SHIFT))<<FLOOR_HEIGHT_SHIFT); //-build_max_y;
|
|
if(y+dy>maxy)
|
|
maxy=y+dy;
|
|
|
|
add_point(x-128+256,y+dy,(z<<ELE_SHIFT)+edge_min_z+ELE_SIZE);
|
|
// DebugText(" roof point d %d %d %d next prim point %d\n",x-128+256,y+dy,(z<<ELE_SHIFT)+edge_min_z+ELE_SIZE,next_prim_point);
|
|
flag_blocks[(x>>ELE_SHIFT)+1+(z+1)*MAX_BOUND_SIZE]=next_prim_point-1;
|
|
br=next_prim_point-1;
|
|
}
|
|
if(dy<small_dy)
|
|
small_dy=dy;
|
|
|
|
|
|
if(bl<0)
|
|
bl=-bl;
|
|
|
|
if(tl<0)
|
|
tl=-tl;
|
|
|
|
if(br<0)
|
|
br=-br;
|
|
|
|
if(tr<0)
|
|
tr=-tr;
|
|
|
|
//p_f4=create_a_quad(tl,bl,tr,br,0,0); //p0,p3,p1,p2,0,0);
|
|
p_f4=create_a_quad(tr,tl,br,bl,0,0); //p0,p3,p1,p2,0,0);
|
|
// p_f4=create_a_quad(br,tr,bl,tl,0,0); //p0,p3,p1,p2,0,0);
|
|
// p_f4=create_a_quad(tl,bl,tr,br,0,0); //p0,p3,p1,p2,0,0);
|
|
|
|
|
|
// ASSERT((next_prim_face4-1)!=7717);
|
|
if(p_f4)
|
|
{
|
|
p_f4->ThingIndex=face_wall;
|
|
if(p_f4->FaceFlags&FACE_FLAG_NON_PLANAR)
|
|
calc_face_split(p_f4);
|
|
LogText(" add walkable quad %d \n",next_prim_face4-1);
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
|
|
//void attach_walkable_to_map(SLONG face);
|
|
// attach_walkable_to_map(next_prim_face4-1);
|
|
|
|
|
|
|
|
texture=get_map_texture(x>>ELE_SHIFT,z+(edge_min_z>>ELE_SHIFT));
|
|
((struct MiniTextureBits*)(&texture))->Rot+=1;
|
|
build_face_texture_info(p_f4,texture);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
DebugText("..");
|
|
//
|
|
// this block should not be filled
|
|
//
|
|
if(flag_blocks[(x>>ELE_SHIFT)+z*MAX_BOUND_SIZE])
|
|
flag_blocks[(x>>ELE_SHIFT)+z*MAX_BOUND_SIZE]=-flag_blocks[(x>>ELE_SHIFT)+z*MAX_BOUND_SIZE];
|
|
|
|
//skip x on to next edge
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
lmax_x+=256;
|
|
lmax_z++;
|
|
|
|
if(valid_roof)
|
|
{
|
|
SLONG t_min_x,t_max_x;
|
|
SLONG dx,dz;
|
|
SLONG oz=(edge_min_z>>ELE_SHIFT);
|
|
|
|
t_min_x=lmin_x>>8;
|
|
t_max_x=lmax_x>>8;
|
|
|
|
for(z=lmin_z;z<lmax_z;z++)
|
|
{
|
|
LogText("\n");
|
|
for(x=t_min_x;x<=t_max_x;x++)
|
|
{
|
|
SLONG point;
|
|
|
|
point=flag_blocks[x+z*MAX_BOUND_SIZE];
|
|
if(point>0)
|
|
{
|
|
SLONG bits=0;
|
|
SLONG count=0,data;
|
|
|
|
|
|
|
|
if( (edit_map[x][z+oz].Texture&0x3ff)==0)
|
|
{
|
|
for(dz=-1;dz<2;dz++)
|
|
for(dx=-1;dx<2;dx++)
|
|
{
|
|
if(dx||dz)
|
|
{
|
|
SLONG mx,mz;
|
|
mx=x+dx;
|
|
mz=z+dz+oz;
|
|
|
|
if(mx<0||mx>=128||mz<0||mz>128||mx<t_min_x||mx>t_max_x||mz<oz||mz>=lmax_z+oz)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
if(flag_blocks[mx+(mz-oz)*MAX_BOUND_SIZE]>0)
|
|
{
|
|
bits|=1<<count;
|
|
}
|
|
}
|
|
count++;
|
|
}
|
|
|
|
}
|
|
ASSERT(bits<256);
|
|
|
|
if(data=lookup_roof[bits])
|
|
{
|
|
DebugText(" %d(%d,%d) ",bits,data&0xff,data>>8);
|
|
if(data)
|
|
{
|
|
edit_map[x][z+oz].Texture=(data&0xff)+6*64;
|
|
edit_map[x][z+oz].Texture|=(data>>8)<<0xa;
|
|
edit_map[x][z+oz].Texture|=1<<0xe;
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
LogText("..");
|
|
|
|
|
|
}
|
|
DebugText("\n");
|
|
}
|
|
|
|
DebugText("\n");
|
|
|
|
{
|
|
SLONG left,top,right,bottom;
|
|
|
|
left=lmin_x>>8;
|
|
right=lmax_x>>8;
|
|
top=lmin_z+(edge_min_z>>8);
|
|
bottom=lmax_z+(edge_min_z>>8);
|
|
// if(next_dwalkable==19 ||next_dwalkable==26)
|
|
// ASSERT(0);
|
|
// ASSERT((storey_list[wall_list[-face_wall].StoreyHead].DY>>8)>0);
|
|
// ASSERT(maxy<storey_list[wall_list[-face_wall].StoreyHead].DY+512);
|
|
// ASSERT((y+small_dy)>>5<100);
|
|
create_walkable_structure(left,right,top,bottom,y+small_dy,sp,sf4,storey_list[wall_list[-face_wall].StoreyHead].DY>>6);
|
|
|
|
return(add_bound_box(left,right,top,bottom,y+small_dy));
|
|
}
|
|
}
|
|
else
|
|
return(0);
|
|
|
|
}
|
|
|
|
void clear_reflective_flag(SLONG min_x,SLONG min_z,SLONG max_x,SLONG max_z)
|
|
{
|
|
SLONG minx,maxx,minz,maxz;
|
|
SLONG x,z;
|
|
|
|
minx=min_x>>ELE_SHIFT;
|
|
maxx=max_x>>ELE_SHIFT;
|
|
|
|
minz=min_z>>ELE_SHIFT;
|
|
maxz=max_z>>ELE_SHIFT;
|
|
|
|
SATURATE(minx,0,127);
|
|
SATURATE(maxx,0,127);
|
|
SATURATE(minz,0,127);
|
|
SATURATE(maxz,0,127);
|
|
|
|
for(x=minx;x<maxx;x++)
|
|
for(z=minz;z<maxz;z++)
|
|
{
|
|
#ifdef EDITOR
|
|
edit_map[x][z].Flags&=~PAP_FLAG_REFLECTIVE;
|
|
#endif
|
|
}
|
|
|
|
|
|
}
|
|
|
|
SLONG build_roof_grid(SLONG storey,SLONG y,SLONG flat_flag)
|
|
{
|
|
SLONG min_x=9999999,max_x=0,min_z=9999999,max_z=0;
|
|
SLONG width,depth;
|
|
SLONG x,z;
|
|
|
|
SLONG wall;
|
|
struct PrimFace4 *p_f4;
|
|
struct PrimFace3 *p_f3;
|
|
SLONG face_wall;
|
|
SLONG angles,sstorey;
|
|
SLONG building;
|
|
|
|
|
|
building=storey_list[storey].BuildingHead;
|
|
//return;
|
|
if(storey_list[storey].StoreyFlags&(FLAG_STOREY_ROOF_RIM|FLAG_STOREY_ROOF_RIM2))
|
|
y=build_storey_lip(storey,y);
|
|
face_wall=-storey_list[storey].WallHead;
|
|
|
|
// LogText(" build roof grid for storey %d at y %d \n",storey,y);
|
|
|
|
// global_y=edit_map[(storey_list[storey].DX>>ELE_SHIFT)][storey_list[storey].DZ>>ELE_SHIFT].Y<<FLOOR_HEIGHT_SHIFT;
|
|
global_y=get_map_height((storey_list[storey].DX>>ELE_SHIFT),storey_list[storey].DZ>>ELE_SHIFT)<<FLOOR_HEIGHT_SHIFT;
|
|
|
|
BOUNDS(storey_list[storey].DX,storey_list[storey].DZ);
|
|
|
|
|
|
|
|
sstorey=building_list[building].StoreyHead;
|
|
while(sstorey)
|
|
{
|
|
wall=storey_list[sstorey].WallHead;
|
|
BOUNDS(storey_list[sstorey].DX,storey_list[sstorey].DZ);
|
|
while(wall)
|
|
{
|
|
BOUNDS(wall_list[wall].DX,wall_list[wall].DZ);
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
sstorey=storey_list[sstorey].Next;
|
|
}
|
|
|
|
block_min_x=min_x;
|
|
block_max_x=max_x;
|
|
|
|
min_x-=ELE_SIZE;
|
|
min_z-=ELE_SIZE;
|
|
max_x+=ELE_SIZE;
|
|
max_z+=ELE_SIZE;
|
|
|
|
|
|
// bounds shound now be set, + bagginess
|
|
width=(max_x-min_x)>>ELE_SHIFT;
|
|
depth=(max_z-min_z)>>ELE_SHIFT;
|
|
|
|
edge_min_z=min_z;
|
|
|
|
clear_reflective_flag(min_x,min_z,max_x,max_z);
|
|
set_floor_hidden(storey,0,PAP_FLAG_REFLECTIVE);
|
|
|
|
//now step over whole rect, flagging points as either inside or outside or on the edge of the building
|
|
LogText(" BUILD FIRST EDGE LIST for storey %d \n",storey);
|
|
angles=build_edge_list(storey,0);
|
|
|
|
// ASSERT(storey!=5);
|
|
|
|
//
|
|
// set floor reflective just under this storey
|
|
//
|
|
|
|
|
|
dump_edge_list(depth);
|
|
if(storey_list[storey].Next)
|
|
{
|
|
SLONG s;
|
|
SLONG storey_height;
|
|
storey_height=storey_list[storey].Height;
|
|
|
|
s=building_list[building].StoreyHead;
|
|
while(s)
|
|
{
|
|
SLONG do_storeys_overlap(SLONG s1,SLONG s2);
|
|
|
|
if(do_storeys_overlap(s,storey) && (storey_list[s].DY==storey_list[storey].DY+storey_height) && (storey_list[s].StoreyType==STOREY_TYPE_SKYLIGHT||storey_list[s].StoreyType==STOREY_TYPE_NORMAL) )
|
|
{
|
|
LogText(" storey %d height %d is 1 above %d so edge it\n",s,storey_list[s].DY,storey);
|
|
build_more_edge_list(min_z,max_z,s,0);
|
|
|
|
|
|
}
|
|
else
|
|
LogText(" failed storey %d height %d is NOT 1 above %d \n",s,storey_list[s].DY,storey);
|
|
|
|
s=storey_list[s].Next;
|
|
}
|
|
}
|
|
|
|
|
|
if(storey==3)
|
|
{
|
|
LogText(" about to build faulty roof \n");
|
|
}
|
|
|
|
if(!angles)
|
|
{
|
|
SLONG bound;
|
|
LogText(" EASY ROOF building %d storey %d \n",storey_list[storey].BuildingHead,storey);
|
|
// if(storey==214)
|
|
// ASSERT(0);
|
|
LogText(" final edge list \n");
|
|
dump_edge_list(depth);
|
|
bound=build_easy_roof(min_x,edge_min_z,max_x,depth,y,face_wall,flat_flag); //0 changed to 1 for flat rooves
|
|
bin_edge_list();
|
|
clear_reflective_flag(min_x,min_z,max_x,max_z);
|
|
return(bound);
|
|
}
|
|
LogText(" COMPLEX ROOF building %d storey %d \n",storey_list[storey].BuildingHead,storey);
|
|
|
|
|
|
|
|
for(z=0;z<depth;z++)
|
|
{
|
|
SLONG polarity=0;
|
|
SLONG edge;
|
|
SLONG dy;
|
|
SLONG prev_x_in=0;
|
|
edge=edge_heads_ptr[z];
|
|
|
|
for(x=min_x-256;x<max_x;x+=ELE_SIZE)
|
|
{
|
|
SLONG done=0;
|
|
while(!done&&edge)
|
|
{
|
|
if(x<edge_pool_ptr[edge].X)
|
|
{
|
|
if(polarity&1)
|
|
{
|
|
//struct DepthStrip *me;
|
|
|
|
dy=get_map_height((x>>ELE_SHIFT),z+(edge_min_z>>ELE_SHIFT))<<FLOOR_HEIGHT_SHIFT;
|
|
add_point(x,y+dy,(z<<ELE_SHIFT)+edge_min_z);
|
|
|
|
flag_blocks[(x>>ELE_SHIFT)+z*MAX_BOUND_SIZE]=next_prim_point-1;
|
|
// LogText(" write flag %d at %d,%d \n",next_prim_point-1,x>>ELE_SHIFT,z);
|
|
}
|
|
done=1;
|
|
}
|
|
else
|
|
if(x==edge_pool_ptr[edge].X)
|
|
{
|
|
//grid[][]
|
|
polarity++;
|
|
//if(polarity&1)
|
|
{
|
|
struct DepthStrip *me;
|
|
|
|
dy=get_map_height((x>>ELE_SHIFT),z+(edge_min_z>>ELE_SHIFT))<<FLOOR_HEIGHT_SHIFT-global_y;
|
|
add_point(x,y,(z<<ELE_SHIFT)+edge_min_z);
|
|
flag_blocks[(x>>ELE_SHIFT)+z*MAX_BOUND_SIZE]=next_prim_point-1;
|
|
|
|
}
|
|
|
|
edge = edge_pool_ptr[ edge ].Next;
|
|
done=1;
|
|
}
|
|
else
|
|
if(x>edge_pool_ptr[edge].X)
|
|
{
|
|
//
|
|
// we have just crossed an edge
|
|
//
|
|
|
|
polarity++;
|
|
edge=edge_pool_ptr[edge].Next;
|
|
if(edge==0)
|
|
{
|
|
//if(polarity&1)
|
|
//flag_blocks[(x>>ELE_SHIFT)+z*MAX_BOUND_SIZE]=INSIDE;
|
|
//else
|
|
//flag_blocks[(x>>ELE_SHIFT)+z*MAX_BOUND_SIZE]=OUTSIDE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LogText(" \n");
|
|
}
|
|
// ASSERT(0);
|
|
build_bottom_edge_list(storey,y);
|
|
|
|
{
|
|
SLONG wall;
|
|
SLONG px,pz;
|
|
px=storey_list[storey].DX;
|
|
pz=storey_list[storey].DZ-edge_min_z;
|
|
wall=storey_list[storey].WallHead;
|
|
while(wall)
|
|
{
|
|
SLONG x,z;
|
|
SLONG dx,dz;
|
|
x=wall_list[wall].DX;
|
|
z=wall_list[wall].DZ-edge_min_z;
|
|
|
|
dx=x-px;
|
|
dz=z-pz;
|
|
if(abs(dx)==abs(dz)&&dx)
|
|
{
|
|
// 45 degree wall
|
|
scan_45(px,pz,dx,dz);
|
|
}
|
|
px=x;
|
|
pz=z;
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
|
|
}
|
|
|
|
// show_grid((max_x>>ELE_SHIFT)-(min_x>>ELE_SHIFT),depth,min_x>>ELE_SHIFT);
|
|
for(z=0;z<depth;z++)
|
|
{
|
|
SLONG polarity=0;
|
|
SLONG edge;
|
|
edge=edge_heads_ptr[z];
|
|
for(x=min_x>>ELE_SHIFT;x<max_x>>ELE_SHIFT;x++)
|
|
{
|
|
SLONG p0,p1,p2,p3;
|
|
//
|
|
// Build faces by finding quads with defined points
|
|
//
|
|
// p0 p1
|
|
//
|
|
// p3 p2
|
|
p0=flag_blocks[x+z*MAX_BOUND_SIZE];
|
|
p1=flag_blocks[x+1+z*MAX_BOUND_SIZE];
|
|
p2=flag_blocks[x+1+(z+1)*MAX_BOUND_SIZE];
|
|
p3=flag_blocks[x+(z+1)*MAX_BOUND_SIZE];
|
|
// LogText(" x %d z %d p01234 %d %d %d %d \n",x,z,p0,p1,p2,p3);
|
|
if(p0&&p1&&p2&&p3)
|
|
{
|
|
SLONG texture;
|
|
// LogText(" use poly %d %d \n",x,z);
|
|
//UWORD p1,UWORD p0,UWORD p3,UWORD p2,SWORD texture_style,SWORD texture_piece)
|
|
p_f4=create_a_quad(p0,p3,p1,p2,0,0);
|
|
if(p_f4)
|
|
{
|
|
p_f4->ThingIndex=face_wall;
|
|
// LogText(" roof grid quad for map %d %d \n",x,z+(edge_min_z>>ELE_SHIFT));
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
texture=get_map_texture(x,z+(edge_min_z>>ELE_SHIFT));
|
|
build_face_texture_info(p_f4,texture);
|
|
}
|
|
// LogText(" add grid roof face to walkable \n");
|
|
}
|
|
else
|
|
if(p0||p1||p2||p3)
|
|
{ //the following code is shit, sorry
|
|
UBYTE exist_flags=0;
|
|
|
|
#define TL (1)
|
|
#define TR (2)
|
|
#define BL (4)
|
|
#define BR (8)
|
|
if(p0)
|
|
exist_flags|=TL;
|
|
if(p1)
|
|
exist_flags|=TR;
|
|
if(p2)
|
|
exist_flags|=BR;
|
|
if(p3)
|
|
exist_flags|=BL;
|
|
|
|
switch(exist_flags)
|
|
{
|
|
SLONG xt,xb;
|
|
SLONG zl,zr;
|
|
SLONG pa,pb;
|
|
|
|
case (TR+BR):
|
|
xt=cut_blocks[x*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_TOP];
|
|
xb=cut_blocks[x*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_BOTTOM];
|
|
|
|
if(xt&&xb)
|
|
{
|
|
// pa p1
|
|
//
|
|
// pb p2
|
|
pa=next_prim_point;
|
|
add_point(xt,y,(z<<ELE_SHIFT)+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point(xb,y,((z+1)<<ELE_SHIFT)+edge_min_z);
|
|
p_f4=create_a_quad(pa,pb,p1,p2,0,0);
|
|
if(p_f4)
|
|
{
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
}
|
|
// LogText(" done tr+br 1 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(xt)
|
|
{
|
|
// pa p1
|
|
//
|
|
// p2
|
|
pa=next_prim_point;
|
|
add_point(xt,y,(z<<ELE_SHIFT)+edge_min_z);
|
|
p_f3=create_a_tri(p2,p1,pa,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tr+br 2 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(xb)
|
|
{
|
|
// p1
|
|
//
|
|
// pa p2
|
|
pa=next_prim_point;
|
|
add_point(xb,y,((z+1)<<ELE_SHIFT)+edge_min_z);
|
|
p_f3=create_a_tri(p2,p1,pa,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tr+br 3 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
LogText(" pooerror1\n");
|
|
|
|
break;
|
|
case (BL+BR):
|
|
zl=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_LEFT];
|
|
zr=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_RIGHT];
|
|
LogText(" zl %x zr %x \n",zl,zr);
|
|
|
|
if(zl&&zr)
|
|
{
|
|
// pa pb
|
|
//
|
|
// p3 p2
|
|
pa=next_prim_point;
|
|
add_point(x<<ELE_SHIFT,y,zl+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
p_f4=create_a_quad(pa,p3,pb,p2,0,0);
|
|
if(p_f4)
|
|
{
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
}
|
|
// LogText(" done bl+br 1 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(zl)
|
|
{
|
|
//
|
|
// pa
|
|
// p3 p2
|
|
pa=next_prim_point;
|
|
add_point(x<<ELE_SHIFT,y,zl+edge_min_z);
|
|
p_f3=create_a_tri(p3,p2,pa,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done bl+br 2 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(zr)
|
|
{
|
|
//
|
|
// pa
|
|
// p3 p2
|
|
pa=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
p_f3=create_a_tri(p3,p2,pa,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done bl+br 3 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
LogText(" pooerror2\n");
|
|
break;
|
|
case (TL+BL):
|
|
xt=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_TOP];
|
|
xb=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_BOTTOM];
|
|
|
|
if(xt&&xb)
|
|
{
|
|
// p0 pa
|
|
//
|
|
// p3 pb
|
|
pa=next_prim_point;
|
|
add_point(xt,y,(z<<ELE_SHIFT)+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point(xb,y,((z+1)<<ELE_SHIFT)+edge_min_z);
|
|
p_f4=create_a_quad(p0,p3,pa,pb,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tl+bl 1 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(xt)
|
|
{
|
|
// p0 pa
|
|
//
|
|
// p3
|
|
pa=next_prim_point;
|
|
add_point(xt,y,(z<<ELE_SHIFT)+edge_min_z);
|
|
p_f3=create_a_tri(p3,pa,p0,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tl+bl 2 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(xb)
|
|
{
|
|
// p0
|
|
//
|
|
// p3 pa
|
|
pa=next_prim_point;
|
|
add_point(xb,y,((z+1)<<ELE_SHIFT)+edge_min_z);
|
|
p_f3=create_a_tri(p3,pa,p0,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tl+bl 3 at [%d][%d]\n",x,z);
|
|
}
|
|
/* can not be surely
|
|
else
|
|
{
|
|
zr=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_RIGHT];
|
|
if(zr)
|
|
{
|
|
// p0
|
|
// pa
|
|
// p3
|
|
pa=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
create_a_tri(p3,pa,p0,0,0);
|
|
|
|
}
|
|
|
|
}
|
|
*/
|
|
//LogText(" pooerror3\n");
|
|
break;
|
|
case (TL+TR):
|
|
zl=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_LEFT];
|
|
zr=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_RIGHT];
|
|
// LogText(" zl %x zr %x \n",zl,zr);
|
|
|
|
if(zl&&zr)
|
|
{
|
|
// p0 p1
|
|
//
|
|
// pa pb
|
|
pa=next_prim_point;
|
|
add_point(x<<ELE_SHIFT,y,zl+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
p_f4=create_a_quad(p0,pa,p1,pb,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tl+tr 1 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(zl)
|
|
{
|
|
// p0 p1
|
|
// pa
|
|
//
|
|
pa=next_prim_point;
|
|
add_point(x<<ELE_SHIFT,y,zl+edge_min_z);
|
|
p_f3=create_a_tri(pa,p1,p0,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tl+tr 2 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(zr)
|
|
{
|
|
// p0 p1
|
|
// pa
|
|
//
|
|
pa=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
p_f3=create_a_tri(pa,p1,p0,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tl+tr 3 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
LogText(" pooerror4\n");
|
|
break;
|
|
|
|
case (TR+BR+BL):
|
|
xt=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_TOP];
|
|
zl=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_LEFT];
|
|
// LogText("POO1 xt %x zl %x \n",xt,zl);
|
|
// LogText(" [%d][%d] \n",x,z);
|
|
if(xt&&zl)
|
|
{
|
|
// pa p1
|
|
// pb
|
|
// p3 p2
|
|
pa=next_prim_point;
|
|
add_point(xt,y,(z<<ELE_SHIFT)+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point((x)<<ELE_SHIFT,y,zl+edge_min_z);
|
|
|
|
p_f4=create_a_quad(pa,pb,p1,p3,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
p_f3=create_a_tri(p3,p2,p1,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tr+br+bl 1 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(xt||zl)
|
|
{
|
|
if(xt==(x+1)<<ELE_SHIFT||xt==0)
|
|
{
|
|
// pa
|
|
// pb
|
|
// p3 p2
|
|
LogText("special 1b \n");
|
|
pb=next_prim_point;
|
|
add_point((x)<<ELE_SHIFT,y,zl+edge_min_z);
|
|
p_f4=create_a_quad(pb,p3,p1,p2,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tr+br+bl 2 at [%d][%d]\n",x,z);
|
|
|
|
}
|
|
else
|
|
if(zl==(z+1)<<ELE_SHIFT||zl==0)
|
|
{
|
|
// pa p1
|
|
//
|
|
// p3 p2
|
|
// LogText("special 1b \n");
|
|
pa=next_prim_point;
|
|
add_point(xt,y,(z<<ELE_SHIFT)+edge_min_z);
|
|
p_f4=create_a_quad(pa,p3,p1,p2,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tr+br+bl 3 at [%d][%d]\n",x,z);
|
|
|
|
}
|
|
}
|
|
// else
|
|
// create_a_tri(p3,p2,p1,0,0);
|
|
|
|
|
|
|
|
break;
|
|
case (TL+BR+BL):
|
|
xt=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_TOP];
|
|
zr=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_RIGHT];
|
|
// LogText("POO2 xt %x zr %x \n",xt,zr);
|
|
// LogText(" [%d][%d] \n",x,z);
|
|
// LogText(" p0 (%d,%d,%d) p2 (%d,%d,%d) p3 (%d,%d,%d) \n",prim_points[p0].X,prim_points[p0].Y,prim_points[p0].Z,prim_points[p2].X,prim_points[p2].Y,prim_points[p2].Z,prim_points[p3].X,prim_points[p3].Y,prim_points[p3].Z);
|
|
|
|
if(xt&&zr)
|
|
{
|
|
// p0 pa
|
|
// pb
|
|
// p3 p2
|
|
pa=next_prim_point;
|
|
add_point(xt,y,(z<<ELE_SHIFT)+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
|
|
p_f4=create_a_quad(pb,pa,p2,p0,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
p_f3=create_a_tri(p3,p2,p0,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tl+br+bl 1 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(xt||zr)
|
|
{
|
|
if(xt==x<<ELE_SHIFT||xt==0)
|
|
{
|
|
// pa
|
|
// pb
|
|
// p3 p2
|
|
LogText("special 2 \n");
|
|
pb=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
p_f4=create_a_quad(p0,p3,pb,p2,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
LogText(" done tl+br+bl 2 at [%d][%d]\n",x,z);
|
|
|
|
}
|
|
else
|
|
if(zr==((z+1)<<ELE_SHIFT)||zr==0)
|
|
{
|
|
// p0 pa
|
|
//
|
|
// p3 p2
|
|
LogText("special 2b \n");
|
|
pb=next_prim_point;
|
|
add_point((xt),y,(z<<ELE_SHIFT)+edge_min_z);
|
|
p_f4=create_a_quad(p0,p3,pa,p2,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
LogText(" done tl+br+bl 3 at [%d][%d]\n",x,z);
|
|
|
|
}
|
|
}
|
|
// else
|
|
// create_a_tri(p3,p2,p0,0,0);
|
|
|
|
break;
|
|
case (TL+TR+BL):
|
|
xb=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_BOTTOM];
|
|
zr=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_RIGHT];
|
|
LogText("POO3 xb %x zr %x \n",xb,zr);
|
|
LogText(" [%d][%d] \n",x,z);
|
|
LogText(" p0 (%d,%d,%d) p1 (%d,%d,%d) p3 (%d,%d,%d) \n",prim_points[p0].X,prim_points[p0].Y,prim_points[p0].Z,prim_points[p1].X,prim_points[p1].Y,prim_points[p1].Z,prim_points[p3].X,prim_points[p3].Y,prim_points[p3].Z);
|
|
|
|
if(xb&&zr)
|
|
{
|
|
// p0 p1
|
|
// pb
|
|
// p3 pa
|
|
pa=next_prim_point;
|
|
add_point(xb,y,((z+1)<<ELE_SHIFT)+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
|
|
p_f4=create_a_quad(pa,pb,p3,p1,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
p_f3=create_a_tri(p3,p1,p0,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
LogText(" done tl+tr+bl 1 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(xb||zr)
|
|
{
|
|
if(zr==((z+1)<<ELE_SHIFT)||zr==0)
|
|
{
|
|
// p0 p1
|
|
//
|
|
// p3 pa
|
|
LogText("special 3 \n");
|
|
pa=next_prim_point;
|
|
add_point((xb),y,((z+1)<<ELE_SHIFT)+edge_min_z);
|
|
p_f4=create_a_quad(p0,p3,p1,pa,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
LogText(" done tl+tr+bl 2 at [%d][%d]\n",x,z);
|
|
|
|
}
|
|
else
|
|
if(xb==(x<<ELE_SHIFT) || xb==0)
|
|
{
|
|
// p0 p1
|
|
// pb
|
|
// pa3
|
|
LogText("special 3b \n");
|
|
pb=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
p_f4=create_a_quad(p0,p3,p1,pb,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
LogText(" done tl+tr+bl 3 at [%d][%d]\n",x,z);
|
|
}
|
|
}
|
|
// else
|
|
// create_a_tri(p3,p1,p0,0,0);
|
|
|
|
break;
|
|
|
|
case (TL+TR+BR):
|
|
xb=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_BOTTOM];
|
|
zl=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_LEFT];
|
|
LogText("POO444 xb %x zl %x \n",xb,zl);
|
|
LogText(" [%d][%d] \n",x,z);
|
|
|
|
if(xb&&zl)
|
|
{
|
|
// p0 p1
|
|
// pb
|
|
// pa p2
|
|
pa=next_prim_point;
|
|
add_point(xb,y,((z+1)<<ELE_SHIFT)+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point((x)<<ELE_SHIFT,y,zl+edge_min_z);
|
|
LogText(" p0 (%d,%d,%d) p1 (%d,%d,%d) p2 (%d,%d,%d) \n",prim_points[p0].X,prim_points[p0].Y,prim_points[p0].Z,prim_points[p1].X,prim_points[p1].Y,prim_points[p1].Z,prim_points[p2].X,prim_points[p2].Y,prim_points[p2].Z);
|
|
LogText(" pa (%d,%d,%d) pb (%d,%d,%d) \n",prim_points[pa].X,prim_points[pa].Y,prim_points[pa].Z,prim_points[pb].X,prim_points[pb].Y,prim_points[pb].Z);
|
|
|
|
p_f4=create_a_quad(pb,pa,p0,p2,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
p_f3=create_a_tri(p0,p2,p1,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
LogText(" done tl+tr+br 1 at [%d][%d]\n",x,z);
|
|
}
|
|
else
|
|
if(xb||zl)
|
|
{
|
|
if(xb==(x+1)<<ELE_SHIFT||xb==0)
|
|
{
|
|
// p0 p1
|
|
// pb
|
|
// p2a
|
|
LogText("special 4 \n");
|
|
pb=next_prim_point;
|
|
add_point((x)<<ELE_SHIFT,y,zl+edge_min_z);
|
|
p_f4=create_a_quad(p0,pb,p1,p2,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
LogText(" done tl+tr+br 2 at [%d][%d]\n",x,z);
|
|
|
|
}
|
|
else
|
|
if(zl==(z)<<ELE_SHIFT||zl==0)
|
|
{
|
|
// pb p1
|
|
//
|
|
// pa p2
|
|
LogText("special 4b \n");
|
|
pa=next_prim_point;
|
|
add_point((xb),y,((z+1)<<ELE_SHIFT)+edge_min_z);
|
|
p_f4=create_a_quad(p0,pb,p1,p2,0,0);
|
|
p_f4->ThingIndex=face_wall;
|
|
build_free_quad_texture_info(p_f4,x,z+(edge_min_z>>ELE_SHIFT));
|
|
LogText(" done tl+tr+br 3 at [%d][%d]\n",x,z);
|
|
|
|
}
|
|
}
|
|
// else
|
|
// create_a_tri(p2,p1,p0,0,0);
|
|
break;
|
|
case (TL):
|
|
xt=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_TOP];
|
|
zl=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_LEFT];
|
|
// LogText("SINGLE1 xt %x zl %x \n",xt,zl);
|
|
// LogText(" [%d][%d] \n",x,z);
|
|
|
|
if(xt&&zl)
|
|
{
|
|
// p0 pa
|
|
// pb
|
|
|
|
pa=next_prim_point;
|
|
add_point(xt,y,((z)<<ELE_SHIFT)+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point((x)<<ELE_SHIFT,y,zl+edge_min_z);
|
|
|
|
p_f3=create_a_tri(pb,pa,p0,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done tl 1 at [%d][%d]\n",x,z);
|
|
}
|
|
break;
|
|
case (TR):
|
|
xt=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_TOP];
|
|
zr=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_RIGHT];
|
|
// LogText("SINGLE2 xt %x zr %x \n",xt,zr);
|
|
// LogText(" [%d][%d] \n",x,z);
|
|
|
|
if(xt&&zr)
|
|
{
|
|
// pa p1
|
|
// pb
|
|
|
|
pa=next_prim_point;
|
|
add_point(xt,y,((z)<<ELE_SHIFT)+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
|
|
p_f3=create_a_tri(pa,pb,p1,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
LogText(" done tr 1 at [%d][%d]\n",x,z);
|
|
}
|
|
break;
|
|
case (BR):
|
|
xb=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_BOTTOM];
|
|
zr=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_RIGHT];
|
|
// LogText("SINGLE3 xb %x zr %x \n",xb,zr);
|
|
// LogText(" [%d][%d] \n",x,z);
|
|
|
|
if(xb&&zr)
|
|
{
|
|
// pb
|
|
// pa p2
|
|
|
|
pa=next_prim_point;
|
|
add_point(xb,y,((z+1)<<ELE_SHIFT)+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point((x+1)<<ELE_SHIFT,y,zr+edge_min_z);
|
|
|
|
p_f3=create_a_tri(pb,pa,p2,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
LogText(" done br 1 at [%d][%d]\n",x,z);
|
|
}
|
|
break;
|
|
case (BL):
|
|
xb=cut_blocks[(x)*4+z*MAX_BOUND_SIZE*4+CUT_BLOCK_BOTTOM];
|
|
zl=cut_blocks[(x)*4+(z)*MAX_BOUND_SIZE*4+CUT_BLOCK_LEFT];
|
|
// LogText("SINGLE4 xb %x zl %x \n",xb,zl);
|
|
// LogText(" [%d][%d] \n",x,z);
|
|
|
|
if(xb&&zl)
|
|
{
|
|
// pb
|
|
// p3 pa
|
|
|
|
pa=next_prim_point;
|
|
add_point(xb,y,((z+1)<<ELE_SHIFT)+edge_min_z);
|
|
pb=next_prim_point;
|
|
add_point((x)<<ELE_SHIFT,y,zl+edge_min_z);
|
|
|
|
p_f3=create_a_tri(p3,pa,pb,0,0);
|
|
build_free_tri_texture_info(p_f3,x,z+(edge_min_z>>ELE_SHIFT));
|
|
// LogText(" done bl 1 at [%d][%d]\n",x,z);
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
LogText(" un supported p0... (%d,%d,%d,%d)\n",p0,p1,p2,p3);
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
bin_edge_list();
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
|
|
SLONG is_storey_circular(SLONG storey)
|
|
{
|
|
SLONG sx,sz,wall;
|
|
sx=storey_list[storey].DX;
|
|
sz=storey_list[storey].DZ;
|
|
wall=storey_list[storey].WallHead;
|
|
|
|
while(wall)
|
|
{
|
|
if(sx==wall_list[wall].DX && sz==wall_list[wall].DZ)
|
|
{
|
|
return(1);
|
|
}
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
void set_floor_hidden(SLONG storey,UWORD lower,UWORD flags)
|
|
{
|
|
SLONG min_x=9999999,max_x=0,min_z=9999999,max_z=0;
|
|
SLONG width,depth;
|
|
SLONG x,z;
|
|
|
|
SLONG wall;
|
|
// LogText(" set floor hidden storey %d \n",storey);
|
|
if(!is_storey_circular(storey))
|
|
{
|
|
// LogText(" not circular \n");
|
|
return;
|
|
}
|
|
|
|
BOUNDS(storey_list[storey].DX,storey_list[storey].DZ);
|
|
wall=storey_list[storey].WallHead;
|
|
while(wall)
|
|
{
|
|
BOUNDS(wall_list[wall].DX,wall_list[wall].DZ);
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
|
|
block_min_x=min_x;
|
|
block_max_x=max_x;
|
|
|
|
min_x-=ELE_SIZE;
|
|
min_z-=ELE_SIZE;
|
|
max_x+=ELE_SIZE;
|
|
max_z+=ELE_SIZE;
|
|
|
|
// bounds shound now be set, + bagginess
|
|
width=(max_x-min_x)>>ELE_SHIFT;
|
|
depth=(max_z-min_z)>>ELE_SHIFT;
|
|
|
|
edge_min_z=min_z;
|
|
|
|
//now step over whole rect, flagging poins as either inside or outside or on the edge of the building
|
|
build_edge_list(storey,0);
|
|
// dump_edge_list(depth);
|
|
|
|
|
|
|
|
for(z=0;z<depth;z++)
|
|
{
|
|
SLONG polarity=0;
|
|
SLONG edge;
|
|
edge=edge_heads_ptr[z];
|
|
for(x=min_x;x<max_x;x+=ELE_SIZE)
|
|
{
|
|
SLONG done=0;
|
|
while(!done&&edge)
|
|
{
|
|
if(x<edge_pool_ptr[edge].X)
|
|
{
|
|
if(polarity&1)
|
|
{
|
|
struct DepthStrip *me;
|
|
|
|
set_map_flag(
|
|
x >> PAP_SHIFT_HI,
|
|
z + (edge_min_z >> PAP_SHIFT_HI),
|
|
flags);
|
|
|
|
//hidden
|
|
}
|
|
done=1;
|
|
}
|
|
else
|
|
if(x==edge_pool_ptr[edge].X)
|
|
{
|
|
//grid[][]
|
|
polarity+=edge_pool_ptr[edge].Count;
|
|
if(polarity&1)
|
|
{
|
|
struct DepthStrip *me;
|
|
|
|
set_map_flag(
|
|
x >> PAP_SHIFT_HI,
|
|
z + (edge_min_z >> PAP_SHIFT_HI),
|
|
flags);
|
|
|
|
}
|
|
|
|
edge = edge_pool_ptr[ edge ].Next;
|
|
done=1;
|
|
}
|
|
else
|
|
if(x>edge_pool_ptr[edge].X)
|
|
{
|
|
polarity+=edge_pool_ptr[edge].Count;
|
|
edge=edge_pool_ptr[edge].Next;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(0) //lower)
|
|
{
|
|
for(z=0;z<depth;z++)
|
|
{
|
|
UWORD pfu,pfl;
|
|
pfu=get_map_flags(min_x>>PAP_SHIFT_HI,z+(edge_min_z>>PAP_SHIFT_HI));
|
|
pfl=get_map_flags(min_x>>PAP_SHIFT_HI,z+(edge_min_z>>PAP_SHIFT_HI)+1);
|
|
|
|
for(x=min_x+(1 << PAP_SHIFT_HI);x<max_x-(1 << PAP_SHIFT_HI);x+=(1 << PAP_SHIFT_HI))
|
|
{
|
|
UWORD fu,fl;
|
|
fu=get_map_flags(x>>PAP_SHIFT_HI,z+(edge_min_z>>PAP_SHIFT_HI));
|
|
fl=get_map_flags(x>>PAP_SHIFT_HI,z+(edge_min_z>>PAP_SHIFT_HI)+1);
|
|
if((fu&fl&pfu&pfl&PAP_FLAG_HIDDEN))
|
|
{
|
|
set_map_height((x>>PAP_SHIFT_HI)+1,z+(edge_min_z>>PAP_SHIFT_HI)+1,-256>>2);
|
|
|
|
}
|
|
|
|
pfu=fu;
|
|
pfl=fl;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
bin_edge_list();
|
|
}
|
|
|
|
|
|
|
|
|
|
void build_fe_mid_points(SLONG y,SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG flag)
|
|
{
|
|
SLONG dx,dz,dist;
|
|
|
|
dx=abs(x2-x1);
|
|
dz=abs(z2-z1);
|
|
|
|
dist=Root(SDIST2(dx,dz));
|
|
|
|
if(dist==0)
|
|
return;
|
|
|
|
dx=(dx*BLOCK_SIZE)/dist;
|
|
dz=(dz*BLOCK_SIZE)/dist;
|
|
|
|
add_point(x1+dx,y,z1+dz);
|
|
if(flag==0)
|
|
add_point(x2-dx,y,z2-dz);
|
|
}
|
|
|
|
void build_fire_escape_points(UWORD storey,SLONG y,SLONG flag)
|
|
{
|
|
SLONG walls[3],count=0,wall;
|
|
SLONG mx,mz,mx2,mz2;
|
|
SLONG p0=0;
|
|
if(flag==0)
|
|
{
|
|
add_point(storey_list[storey].DX,y,storey_list[storey].DZ);
|
|
//LogText(" point %d is storey \n",p0++);
|
|
|
|
}
|
|
wall=storey_list[storey].WallHead;
|
|
while(wall&&count<3)
|
|
{
|
|
walls[count++]=wall;
|
|
if(flag==0)
|
|
{
|
|
|
|
add_point(wall_list[wall].DX,y,wall_list[wall].DZ);
|
|
// LogText(" point %d is rest of wall \n",p0++);
|
|
}
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
|
|
mx=(storey_list[storey].DX+wall_list[walls[2]].DX)>>1;
|
|
mz=(storey_list[storey].DZ+wall_list[walls[2]].DZ)>>1;
|
|
|
|
mx2=(wall_list[walls[0]].DX+wall_list[walls[1]].DX)>>1;
|
|
mz2=(wall_list[walls[0]].DZ+wall_list[walls[1]].DZ)>>1;
|
|
|
|
if(flag==0)
|
|
{
|
|
add_point(mx,y,mz);
|
|
// LogText(" point %d is middle left \n",p0++);
|
|
add_point(mx2,y,mz2);
|
|
// LogText(" point %d is middle right \n",p0++);
|
|
|
|
}
|
|
build_fe_mid_points(y,mx,mz,mx2,mz2,flag);
|
|
// LogText(" point %d is middle mid left \n",p0++);
|
|
// LogText(" point %d is middle mid right \n",p0++);
|
|
build_fe_mid_points(y,wall_list[walls[2]].DX,wall_list[walls[2]].DZ,wall_list[walls[1]].DX,wall_list[walls[1]].DZ,flag);
|
|
// LogText(" point %d is front mid left \n",p0++);
|
|
// LogText(" point %d is front mid right \n",p0++);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define PsetUV4(p_f4,x0,y0,x1,y1,x2,y2,x3,y3,page) p_f4->UV[0][0]=(x0);p_f4->UV[0][1]=(y0);p_f4->UV[1][0]=(x1);p_f4->UV[1][1]=(y1);p_f4->UV[2][0]=(x2);p_f4->UV[2][1]=(y2);p_f4->UV[3][0]=(x3);p_f4->UV[3][1]=(y3);p_f4->TexturePage=page;
|
|
|
|
void build_face_texture_info(struct PrimFace4 *p_f4,UWORD texture)
|
|
{
|
|
UBYTE tx,ty,page;
|
|
SLONG tsize;
|
|
SLONG rot;
|
|
|
|
tx=((struct MiniTextureBits*)(&texture))->X<<5;
|
|
ty=((struct MiniTextureBits*)(&texture))->Y<<5;
|
|
page=(UBYTE)(((struct MiniTextureBits*)(&texture))->Page);
|
|
tsize=31;//floor_texture_sizes[((struct MiniTextureBits*)(&texture))->Size]-1;
|
|
rot=((struct MiniTextureBits*)(&texture))->Rot;
|
|
rot=(rot+3)&3;
|
|
switch(rot)
|
|
{
|
|
case 0:
|
|
|
|
PsetUV4( p_f4,tx,ty,tx+tsize,ty,tx,ty+tsize,tx+tsize,ty+tsize,page);
|
|
break;
|
|
case 1:
|
|
PsetUV4( p_f4,tx+tsize,ty,tx+tsize,ty+tsize,tx,ty,tx,ty+tsize,page);
|
|
break;
|
|
case 2:
|
|
PsetUV4( p_f4,tx+tsize,ty+tsize,tx,ty+tsize,tx+tsize,ty,tx,ty,page);
|
|
break;
|
|
case 3:
|
|
PsetUV4( p_f4,tx,ty+tsize,tx,ty,tx+tsize,ty+tsize,tx+tsize,ty,page);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 0 1
|
|
//
|
|
// 2 3
|
|
void set_quad_planar_flag(struct PrimFace4 *pf4)
|
|
{
|
|
SLONG p0,p1,p2,p3;
|
|
SLONG nx,ny,nz,mx,my,mz;
|
|
SLONG vx,vy,vz,wx,wy,wz;
|
|
|
|
p0=pf4->Points[0];
|
|
p1=pf4->Points[1];
|
|
p2=pf4->Points[2];
|
|
p3=pf4->Points[3];
|
|
|
|
vx=prim_points[p0].X-prim_points[p2].X;
|
|
vy=prim_points[p0].Y-prim_points[p2].Y;
|
|
vz=prim_points[p0].Z-prim_points[p2].Z;
|
|
|
|
wx=prim_points[p1].X-prim_points[p0].X;
|
|
wy=prim_points[p1].Y-prim_points[p0].Y;
|
|
wz=prim_points[p1].Z-prim_points[p0].Z;
|
|
|
|
nx=vy*wz-vz*wy;
|
|
ny=vz*wx-vx*wz;
|
|
nz=vx*wy-vy*wx;
|
|
|
|
{
|
|
SLONG len;
|
|
|
|
len=Root(nx*nx+ny*ny+nz*nz);
|
|
if(len==0)
|
|
len=1;
|
|
nx=(nx*64)/len;
|
|
ny=(ny*64)/len;
|
|
nz=(nz*64)/len;
|
|
}
|
|
|
|
vx=prim_points[p3].X-prim_points[p1].X;
|
|
vy=prim_points[p3].Y-prim_points[p1].Y;
|
|
vz=prim_points[p3].Z-prim_points[p1].Z;
|
|
|
|
wx=prim_points[p2].X-prim_points[p3].X;
|
|
wy=prim_points[p2].Y-prim_points[p3].Y;
|
|
wz=prim_points[p2].Z-prim_points[p3].Z;
|
|
|
|
mx=vy*wz-vz*wy;
|
|
my=vz*wx-vx*wz;
|
|
mz=vx*wy-vy*wx;
|
|
|
|
{
|
|
SLONG len;
|
|
|
|
len=Root(mx*mx+my*my+mz*mz);
|
|
if(len==0)
|
|
len=1;
|
|
mx=(mx*64)/len;
|
|
my=(my*64)/len;
|
|
mz=(mz*64)/len;
|
|
}
|
|
|
|
if( (nx!=mx) || (ny!=my) || (nz!=mz) )
|
|
{
|
|
pf4->FaceFlags|=FACE_FLAG_NON_PLANAR;
|
|
}
|
|
}
|
|
|
|
struct PrimFace4* create_a_quad(UWORD p1,UWORD p0,UWORD p3,UWORD p2,SWORD texture_style,SWORD texture_piece,SLONG flipx)
|
|
{
|
|
struct PrimFace4 *p4;
|
|
SLONG tx,ty;
|
|
SLONG theight=31;
|
|
SLONG add_page=1;
|
|
SLONG page_to;
|
|
SLONG flip;
|
|
|
|
if(texture_style==0)
|
|
add_page=0;
|
|
|
|
|
|
p4=&prim_faces4[next_prim_face4];
|
|
next_prim_face4++;
|
|
|
|
p4->Points[0]=p0;
|
|
p4->Points[1]=p1;
|
|
p4->Points[2]=p2;
|
|
p4->Points[3]=p3;
|
|
/*
|
|
p4->Bright[0]=128;
|
|
p4->Bright[1]=128;
|
|
p4->Bright[2]=128;
|
|
p4->Bright[3]=128;
|
|
*/
|
|
p4->DrawFlags=POLY_GT;
|
|
p4->FaceFlags=0;
|
|
|
|
set_quad_planar_flag(p4);
|
|
|
|
if(texture_style)
|
|
{
|
|
if(texture_piece==TEXTURE_PIECE_MIDDLE)
|
|
{
|
|
if( (build_rand()&3)==0)
|
|
{
|
|
if(build_rand()&1)
|
|
texture_piece=TEXTURE_PIECE_MIDDLE1;
|
|
else
|
|
texture_piece=TEXTURE_PIECE_MIDDLE2;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tx=textures_xy[texture_style][texture_piece].Tx<<5;
|
|
ty=textures_xy[texture_style][texture_piece].Ty<<5;
|
|
p4->TexturePage=textures_xy[texture_style][texture_piece].Page;
|
|
flip=textures_xy[texture_style][texture_piece].Flip;
|
|
|
|
if(add_page)
|
|
add_page_countxy(tx>>5,ty>>5,p4->TexturePage);
|
|
if(build_psx)
|
|
{
|
|
page_to=(p4->TexturePage<<6)+(tx>>5)+((ty>>5)<<3);
|
|
|
|
if(page_remap[page_to])
|
|
{
|
|
page_to=page_remap[page_to]+25*64-1;
|
|
|
|
flip^=page_to>>14;
|
|
|
|
tx=(page_to&7)<<5;
|
|
ty=((page_to>>3)&7)<<5;
|
|
p4->TexturePage=(page_to>>6)&31;
|
|
}
|
|
else
|
|
{
|
|
page_to=0;
|
|
tx=(page_to&7)<<5;
|
|
ty=((page_to>>3)&7)<<5;
|
|
p4->TexturePage=(page_to>>6)&31;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// LogText(" USE texture_style tx %d ty %d page %d \n",tx,ty,p4->TexturePage);
|
|
p4->DrawFlags=textures_flags[texture_style][texture_piece];
|
|
}
|
|
else
|
|
{
|
|
// ASSERT(0);
|
|
tx=texture_xy2[texture_piece].Tx;
|
|
ty=texture_xy2[texture_piece].Ty;
|
|
p4->TexturePage=texture_xy2[texture_piece].Page;
|
|
flip=textures_xy[texture_style][texture_piece].Flip;
|
|
if(add_page)
|
|
add_page_countxy(tx>>5,ty>>5,p4->TexturePage);
|
|
ASSERT(p4->TexturePage<15);
|
|
|
|
if(build_psx)
|
|
{
|
|
page_to=(p4->TexturePage<<6)+(tx>>5)+((ty>>5)<<3);
|
|
|
|
if(page_remap[page_to])
|
|
{
|
|
page_to=page_remap[page_to]+25*64-1;
|
|
tx=(page_to&7)<<5;
|
|
ty=((page_to>>3)&7)<<5;
|
|
p4->TexturePage=(page_to>>6)&31;
|
|
}
|
|
else
|
|
{
|
|
page_to=0;
|
|
tx=(page_to&7)<<5;
|
|
ty=((page_to>>3)&7)<<5;
|
|
p4->TexturePage=(page_to>>6)&31;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// ASSERT(p4->TexturePage<15);
|
|
if(flipx)
|
|
flip^=1;
|
|
|
|
switch(flip) //textures_xy[texture_style][texture_piece].Flip)
|
|
{
|
|
case 0:
|
|
p4->UV[0][0]=tx;
|
|
p4->UV[0][1]=ty;
|
|
p4->UV[1][0]=tx+31;
|
|
p4->UV[1][1]=ty;
|
|
p4->UV[2][0]=tx;
|
|
p4->UV[2][1]=ty+theight;
|
|
p4->UV[3][0]=tx+31;
|
|
p4->UV[3][1]=ty+31;
|
|
break;
|
|
case 1: //flip x
|
|
p4->UV[0][0]=tx+31;
|
|
p4->UV[0][1]=ty;
|
|
p4->UV[1][0]=tx;
|
|
p4->UV[1][1]=ty;
|
|
p4->UV[2][0]=tx+31;
|
|
p4->UV[2][1]=ty+theight;
|
|
p4->UV[3][0]=tx;
|
|
p4->UV[3][1]=ty+theight;
|
|
break;
|
|
case 2: //flip y
|
|
p4->UV[0][0]=tx;
|
|
p4->UV[0][1]=ty+31;
|
|
p4->UV[1][0]=tx+31;
|
|
p4->UV[1][1]=ty+theight;
|
|
p4->UV[2][0]=tx;
|
|
p4->UV[2][1]=ty;
|
|
p4->UV[3][0]=tx+31;
|
|
p4->UV[3][1]=ty;
|
|
break;
|
|
case 3: //flip x+y
|
|
p4->UV[0][0]=tx+31;
|
|
p4->UV[0][1]=ty+31;
|
|
p4->UV[1][0]=tx;
|
|
p4->UV[1][1]=ty+31;
|
|
p4->UV[2][0]=tx+theight;
|
|
p4->UV[2][1]=ty;
|
|
p4->UV[3][0]=tx;
|
|
p4->UV[3][1]=ty;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
p4->UV[0][0]=tx;
|
|
p4->UV[0][1]=ty;
|
|
p4->UV[1][0]=tx+31;
|
|
p4->UV[1][1]=ty;
|
|
p4->UV[2][0]=tx;
|
|
p4->UV[2][1]=ty+31;
|
|
p4->UV[3][0]=tx+31;
|
|
p4->UV[3][1]=ty+31;
|
|
*/
|
|
/*
|
|
if(global_overflow)
|
|
{
|
|
p4=0;
|
|
next_prim_face4--;
|
|
}
|
|
*/
|
|
return(p4);
|
|
}
|
|
|
|
struct PrimFace4* create_a_quad_tex(UWORD p1,UWORD p0,UWORD p3,UWORD p2,UWORD texture,SLONG flipx=0)
|
|
{
|
|
struct PrimFace4 *p4;
|
|
SLONG tx,ty;
|
|
SLONG flip;
|
|
SLONG page_to;
|
|
|
|
p4=&prim_faces4[next_prim_face4];
|
|
next_prim_face4++;
|
|
|
|
p4->Points[0]=p0;
|
|
p4->Points[1]=p1;
|
|
p4->Points[2]=p2;
|
|
p4->Points[3]=p3;
|
|
|
|
p4->DrawFlags=POLY_GT;
|
|
p4->FaceFlags=0;
|
|
|
|
tx=(texture&7)<<5;
|
|
ty=((texture>>3)&7)<<5;
|
|
flip=(texture&0x80)>>7;
|
|
p4->TexturePage=(texture&0x7f)>>6;
|
|
add_page_countxy(tx>>5,ty>>5,p4->TexturePage);
|
|
|
|
if(build_psx)
|
|
{
|
|
page_to=(p4->TexturePage<<6)+(tx>>5)+((ty>>5)<<3);
|
|
|
|
if(page_remap[page_to])
|
|
{
|
|
page_to=page_remap[page_to]+25*64-1;
|
|
}
|
|
else
|
|
page_to=0;
|
|
// page_to=page_remap[page_to]+25*64;
|
|
tx=(page_to&7)<<5;
|
|
ty=((page_to>>3)&7)<<5;
|
|
p4->TexturePage=(page_to>>6)&31;
|
|
flip^=((page_to>>14)&1);
|
|
}
|
|
|
|
|
|
p4->DrawFlags=POLY_GT;
|
|
if(flipx)
|
|
flip^=1;
|
|
|
|
if(flip)
|
|
{
|
|
p4->UV[1][0]=tx;
|
|
p4->UV[1][1]=ty;
|
|
p4->UV[0][0]=tx+31;
|
|
p4->UV[0][1]=ty;
|
|
p4->UV[3][0]=tx;
|
|
p4->UV[3][1]=ty+31;
|
|
p4->UV[2][0]=tx+31;
|
|
p4->UV[2][1]=ty+31;
|
|
|
|
}
|
|
else
|
|
{
|
|
p4->UV[0][0]=tx;
|
|
p4->UV[0][1]=ty;
|
|
p4->UV[1][0]=tx+31;
|
|
p4->UV[1][1]=ty;
|
|
p4->UV[2][0]=tx;
|
|
p4->UV[2][1]=ty+31;
|
|
p4->UV[3][0]=tx+31;
|
|
p4->UV[3][1]=ty+31;
|
|
}
|
|
/*
|
|
if(global_overflow)
|
|
{
|
|
p4=0;
|
|
next_prim_face4--;
|
|
}
|
|
*/
|
|
return(p4);
|
|
}
|
|
|
|
struct PrimFace3* create_a_tri(UWORD p2,UWORD p1,UWORD p0,SWORD texture_id,SWORD texture_piece)
|
|
{
|
|
struct PrimFace3 *p3;
|
|
SLONG tx,ty;
|
|
texture_id=texture_id;
|
|
p3=&prim_faces3[next_prim_face3];
|
|
next_prim_face3++;
|
|
|
|
p3->Points[0]=p0;
|
|
p3->Points[1]=p1;
|
|
p3->Points[2]=p2;
|
|
/*
|
|
p3->Bright[0]=128;
|
|
p3->Bright[1]=128;
|
|
p3->Bright[2]=128;
|
|
*/
|
|
|
|
p3->DrawFlags=POLY_GT;
|
|
|
|
tx=texture_xy2[texture_piece].Tx;
|
|
ty=texture_xy2[texture_piece].Ty;
|
|
p3->UV[0][0]=tx;
|
|
p3->UV[0][1]=ty;
|
|
p3->UV[1][0]=tx+31;
|
|
p3->UV[1][1]=ty;
|
|
p3->UV[2][0]=tx;
|
|
p3->UV[2][1]=ty+31;
|
|
|
|
p3->TexturePage=texture_xy2[texture_piece].Page;
|
|
ASSERT(p3->TexturePage<15);
|
|
/*
|
|
if(global_overflow)
|
|
{
|
|
p3=0;
|
|
next_prim_face3--;
|
|
}
|
|
*/
|
|
return(p3);
|
|
|
|
}
|
|
|
|
void set_texture_fe(struct PrimFace4 *p4,SLONG xw,SLONG xh,SLONG type)
|
|
{
|
|
SLONG tx,ty;
|
|
switch(type)
|
|
{
|
|
case 0:
|
|
tx=0;
|
|
ty=6*32;
|
|
break;
|
|
case 1:
|
|
tx=5*32;
|
|
ty=4*32;
|
|
break;
|
|
}
|
|
|
|
xw=1;
|
|
xh=1;
|
|
|
|
p4->UV[0][0]=tx;
|
|
p4->UV[0][1]=ty;
|
|
p4->UV[1][0]=tx+32*xw;
|
|
p4->UV[1][1]=ty;
|
|
p4->UV[2][0]=tx;
|
|
p4->UV[2][1]=ty+32*xh;
|
|
p4->UV[3][0]=tx+32*xw;
|
|
p4->UV[3][1]=ty+32*xh;
|
|
p4->TexturePage=1;
|
|
|
|
}
|
|
|
|
// 0--------------------------1
|
|
//
|
|
//
|
|
// 4 6 7 5
|
|
//
|
|
//
|
|
// 3 8 9 2
|
|
//
|
|
|
|
#ifdef OLD_DOG_POO_OF_A_SYSTEM_OR_IS_IT
|
|
/*
|
|
UWORD next_face_type=1;
|
|
UWORD next_face_link=1;
|
|
UWORD next_face_connection=1;
|
|
|
|
struct FaceLink
|
|
{
|
|
UWORD Index;
|
|
UBYTE Count;
|
|
};
|
|
|
|
UWORD face_type_index[50]; // for face type %1 returns index into face_links which you add your ID to , to pull out an inde and number of faces connected to
|
|
struct FaceLink face_links[50*20]; //
|
|
UWORD face_connection_pool[2000];
|
|
|
|
|
|
|
|
//each type has a variable number of ID's
|
|
|
|
|
|
void add_connection_for_current_id(SLONG offset)
|
|
{
|
|
face_connection_pool[next_face_connection++]=offset;
|
|
face_links[next_face_link-1].Count++;
|
|
}
|
|
|
|
SLONG advance_face_id_number(void)
|
|
{
|
|
face_links[next_face_link].Count=0;
|
|
face_links[next_face_link].Index=next_face_connection;
|
|
|
|
next_face_link++;
|
|
return(next_face_link-1);
|
|
|
|
|
|
}
|
|
|
|
SLONG advance_face_type_number(void)
|
|
{
|
|
face_type_index[next_face_type]=next_face_link;
|
|
face_links[next_face_link].Count=0;
|
|
next_face_type++;
|
|
|
|
return(next_face_type-1);
|
|
}
|
|
*/
|
|
#endif
|
|
|
|
|
|
|
|
#define FE_FIRST_SLOPE 1
|
|
#define FE_PLINTH1 2
|
|
#define FE_WALKWAY1 3
|
|
#define FE_PLINTH2 4
|
|
#define FE_SLOPE2 5
|
|
|
|
#define FE_FIRST_SLOPE_RAIL -6
|
|
#define FE_PLINTH1_RAIL_A -7
|
|
#define FE_PLINTH1_RAIL_B -8
|
|
#define FE_WALKWAY1_RAIL -9
|
|
#define FE_PLINTH2_RAIL_A -10
|
|
#define FE_PLINTH2_RAIL_B -11
|
|
#define FE_SLOPE2_RAIL -12
|
|
|
|
|
|
SWORD face_offsets[]=
|
|
{
|
|
0,
|
|
-1,0, //1
|
|
1,-2,0, //3
|
|
2,1,0, //6
|
|
-1,12,0, //9
|
|
-12,-1,0 //12
|
|
|
|
};
|
|
|
|
UWORD id_offset[]=
|
|
{
|
|
0,1,3,6,9,12
|
|
};
|
|
#define FACE_TYPE_FIRE_ESCAPE (1<<0)
|
|
|
|
SLONG next_connected_face(SLONG type,SLONG id,SLONG count)
|
|
{
|
|
switch(type)
|
|
{
|
|
case FACE_TYPE_FIRE_ESCAPE:
|
|
SLONG start;
|
|
|
|
start=id_offset[id];
|
|
// LogText(" id %d start %d count %d \n",id,start,count);
|
|
return(face_offsets[start+count]);
|
|
break;
|
|
}
|
|
return(0);
|
|
}
|
|
void build_firescape(SLONG storey)
|
|
{
|
|
SLONG y=0;
|
|
SLONG count=0;
|
|
// SLONG sp[120];
|
|
struct PrimFace4 *p4;
|
|
SLONG wall;
|
|
|
|
|
|
wall=-storey_list[storey].WallHead;
|
|
|
|
while(count<storey_list[storey].Height)
|
|
{
|
|
|
|
start_point[count]=next_prim_point;
|
|
if(count==0)
|
|
{
|
|
build_fire_escape_points(storey,y,1);
|
|
build_fire_escape_points(storey,y+BLOCK_SIZE,1);
|
|
}
|
|
else
|
|
{
|
|
build_fire_escape_points(storey,y,0);
|
|
build_fire_escape_points(storey,y+BLOCK_SIZE,0);
|
|
}
|
|
|
|
|
|
if(count>0)
|
|
{
|
|
//banisters
|
|
p4=create_a_quad(start_point[count]+3+10,start_point[count]+0+10,start_point[count]+3,start_point[count]+4,0,0);
|
|
set_texture_fe(p4,1,1,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
|
|
p4=create_a_quad(start_point[count]+8+10,start_point[count]+3+10,start_point[count]+8,start_point[count]+3,0,0);
|
|
set_texture_fe(p4,1,1,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
|
|
p4=create_a_quad(start_point[count]+2+10,start_point[count]+9+10,start_point[count]+2,start_point[count]+9,0,0);
|
|
set_texture_fe(p4,1,1,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
|
|
p4=create_a_quad(start_point[count]+1+10,start_point[count]+2+10,start_point[count]+1,start_point[count]+2,0,0);
|
|
set_texture_fe(p4,1,1,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
|
|
p4=create_a_quad(start_point[count]+7+10,start_point[count]+6+10,start_point[count]+7,start_point[count]+6,0,0);
|
|
set_texture_fe(p4,1,1,1);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
|
|
|
|
// floors
|
|
p4=create_a_quad(start_point[count],start_point[count]+1,start_point[count]+4,start_point[count]+5,0,0);
|
|
set_texture_fe(p4,1,1,1);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4->Type=FACE_TYPE_FIRE_ESCAPE;
|
|
p4->ID=FE_WALKWAY1;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
|
|
p4=create_a_quad(start_point[count]+4,start_point[count]+6,start_point[count]+3,start_point[count]+8,0,0);
|
|
set_texture_fe(p4,1,1,1);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4->Type=FACE_TYPE_FIRE_ESCAPE;
|
|
p4->ID=FE_PLINTH2;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
|
|
p4=create_a_quad(start_point[count]+7,start_point[count]+5,start_point[count]+9,start_point[count]+2,0,0);
|
|
set_texture_fe(p4,1,1,1);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4->Type=FACE_TYPE_FIRE_ESCAPE;
|
|
p4->ID=FE_PLINTH1;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
}
|
|
|
|
if(count==1)
|
|
{
|
|
//first slope
|
|
//floor
|
|
insert_collision_vect(prim_points[start_point[count-1]].X,prim_points[start_point[count-1]].Y,prim_points[start_point[count-1]].Z,
|
|
prim_points[start_point[count-1]+1].X,prim_points[start_point[count-1]+1].Y,prim_points[start_point[count-1]+1].Z,0,0,next_prim_face4);
|
|
|
|
p4=create_a_quad(start_point[count-1],start_point[count]+7,start_point[count-1]+1,start_point[count]+9,0,0);
|
|
set_texture_fe(p4,1,1,1);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4->ThingIndex=wall;
|
|
p4->FaceFlags|=FACE_FLAG_WALKABLE;
|
|
p4->Type=FACE_TYPE_FIRE_ESCAPE;
|
|
p4->ID=FE_FIRST_SLOPE;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
|
|
|
|
//bannister
|
|
p4=create_a_quad(start_point[count]+9+10,start_point[count-1]+3,start_point[count]+9,start_point[count-1]+1,0,0);
|
|
set_texture_fe(p4,1,1,1);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
p4->Type=FACE_TYPE_FIRE_ESCAPE;
|
|
p4->ID=FE_FIRST_SLOPE_RAIL;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
}
|
|
else
|
|
if(count>1)
|
|
{
|
|
//continue slope
|
|
p4=create_a_quad(start_point[count-1]+6,start_point[count]+7,start_point[count-1]+8,start_point[count]+9,0,0);
|
|
set_texture_fe(p4,1,1,1);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED; //|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4->Type=FACE_TYPE_FIRE_ESCAPE;
|
|
p4->ID=FE_SLOPE2;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
|
|
//rail
|
|
p4=create_a_quad(start_point[count]+9+10,start_point[count-1]+8+10,start_point[count]+9,start_point[count-1]+8,0,0);
|
|
set_texture_fe(p4,1,1,1);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4->Type=FACE_TYPE_FIRE_ESCAPE;
|
|
p4->ID=FE_SLOPE2_RAIL;
|
|
|
|
}
|
|
|
|
count++;
|
|
y+=BLOCK_SIZE*4;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
|
|
#define LADDER_SPINE_WIDTH 12
|
|
void build_ladder_points(SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG y,SLONG flag)
|
|
{
|
|
SLONG dx,dz;
|
|
|
|
dx=x2-x1;
|
|
dz=z2-z1;
|
|
|
|
if(dx>0)
|
|
dx=LADDER_SPINE_WIDTH;
|
|
else
|
|
if(dx<0)
|
|
dx=-LADDER_SPINE_WIDTH;
|
|
|
|
if(dz>0)
|
|
dz=LADDER_SPINE_WIDTH;
|
|
else
|
|
if(dz<0)
|
|
dz=-LADDER_SPINE_WIDTH;
|
|
|
|
|
|
if(flag==1)
|
|
{
|
|
add_point(x1-dz,y,z1+dx);
|
|
add_point(x1,y,z1);
|
|
add_point(x1+dx,y,z1+dz);
|
|
add_point(x2-dx,y,z2-dz);
|
|
add_point(x2,y,z2);
|
|
add_point(x2-dz,y,z2+dx);
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
dx=(dx*3)>>2;
|
|
dz=(dz*3)>>2;
|
|
add_point(x1+dx,y,z1+dz);
|
|
add_point(x2-dx,y,z2-dz);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
void calc_ladder_ends(SLONG *x1,SLONG *z1,SLONG *x2,SLONG *z2);
|
|
|
|
void calc_ladder_pos(SLONG *x1,SLONG *z1,SLONG *x2,SLONG *z2,SLONG *y,SLONG *extra_height)
|
|
{
|
|
SLONG dx,dz;
|
|
*extra_height=0;
|
|
|
|
calc_ladder_ends(x1,z1,x2,z2);
|
|
|
|
if(*y==0)
|
|
{
|
|
SLONG min_y,ty;
|
|
|
|
min_y=PAP_calc_height_at(*x1,*z1);
|
|
ty=PAP_calc_height_at(*x2,*z2);
|
|
|
|
if(ty<min_y)
|
|
min_y=ty;
|
|
|
|
*y=min_y;
|
|
*extra_height = abs(min_y)>>6;
|
|
}
|
|
else
|
|
*y+=build_max_y;
|
|
|
|
// *y+=calc_height_at(*x1,*z1);
|
|
}
|
|
|
|
|
|
// 0 1 2 3
|
|
//
|
|
// 9 4
|
|
//
|
|
// 8 7 6 5
|
|
|
|
// w=4 h=3
|
|
|
|
|
|
#define MAX_SIZE 20
|
|
SLONG sp[MAX_SIZE][MAX_SIZE];
|
|
SLONG xp[MAX_SIZE],zp[MAX_SIZE];
|
|
|
|
SLONG flat_fill_a_quad_of_points(SLONG start_point,SLONG w,SLONG h,SLONG texture_style,SLONG wall)
|
|
{
|
|
SLONG ax,az;
|
|
SLONG y;
|
|
SLONG c0;
|
|
SLONG texture=TEXTURE_PIECE_RIGHT;
|
|
struct PrimFace4 *p_f4;
|
|
|
|
|
|
y=prim_points[start_point].Y;
|
|
|
|
for(c0=0;c0<w;c0++)
|
|
{
|
|
sp[c0][0]=start_point+c0;
|
|
sp[c0][h-1]=start_point+w+h-2+w-c0-1;
|
|
|
|
xp[c0]=prim_points[start_point+c0].X;
|
|
// LogText(" fill edge top[%d]=%d bot[]=%d \n",c0,c0,w+h-2+w-c0-1);
|
|
}
|
|
|
|
zp[0]=prim_points[start_point].Z;
|
|
for(c0=1;c0<h-1;c0++)
|
|
{
|
|
sp[w-1][c0]=start_point+w+c0-1; //rhs
|
|
sp[0][c0]=start_point+w+w+h-2+h-c0-2; //lhs
|
|
|
|
zp[c0]=prim_points[start_point+w-1+c0].Z;
|
|
// LogText(" fill edge left[%d]=%d right[]=%d \n",c0,w+w+h-2+h-c0-2,w+c0-1);
|
|
}
|
|
|
|
for(ax=1;ax<w-1;ax++)
|
|
for(az=1;az<h-1;az++)
|
|
{
|
|
sp[ax][az]=next_prim_point;
|
|
add_point(xp[ax],y,zp[az]);
|
|
// LogText(" mid point at %d %d \n",ax,az);
|
|
}
|
|
|
|
for(az=0;az<h-1;az++)
|
|
{
|
|
for(ax=0;ax<w-1;ax++)
|
|
{
|
|
// create_a_quad(sp[ax][az],sp[ax+1][az],sp[ax][az+1],sp[ax+1][az+1],0,18);
|
|
p_f4=create_a_quad(sp[ax][az+1],sp[ax+1][az+1],sp[ax][az],sp[ax+1][az],texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4->Type=FACE_TYPE_SKYLIGHT;
|
|
p_f4->ID=0;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
}
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
|
|
SLONG sx[200],sz[200];
|
|
SLONG numb[200];
|
|
|
|
SLONG build_skylight(SLONG storey)
|
|
{
|
|
SLONG count=0;
|
|
SLONG index,c0;
|
|
SLONG dx,dz;
|
|
SLONG px,pz,rx,rz;
|
|
SLONG x,y,z,wall;
|
|
SLONG ox,oz;
|
|
SLONG pcount;
|
|
SLONG in=-50;
|
|
SLONG up=50;
|
|
SLONG texture,texture_style;
|
|
struct PrimFace4 *p_f4;
|
|
|
|
|
|
|
|
//
|
|
// Create the same number of points inside but raised then polygonize the outside
|
|
//
|
|
|
|
// need to fill in strange shape inside
|
|
// or can I assume its a quad
|
|
|
|
x=storey_list[storey].DX;
|
|
y=storey_list[storey].DY;
|
|
z=storey_list[storey].DZ;
|
|
|
|
y+=build_max_y;
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
if(texture_style==0)
|
|
texture_style=1;
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
|
|
|
|
|
|
//
|
|
// Build points at roof height
|
|
//
|
|
LogText(" build outer rim \n");
|
|
start_point[0]=next_prim_point;
|
|
ox=x;
|
|
oz=z;
|
|
index=wall;
|
|
count=0;
|
|
while(index)
|
|
{
|
|
dx=wall_list[index].DX;
|
|
dz=wall_list[index].DZ;
|
|
numb[count]=create_strip_points(ox,y,oz,dx,y,dz,256,0,0); //no end point
|
|
count++;
|
|
index=wall_list[index].Next;
|
|
ox=dx;
|
|
oz=dz;
|
|
}
|
|
|
|
//
|
|
// Build points above roof and in a bit
|
|
//
|
|
LogText(" build up and in \n");
|
|
|
|
pcount=build_outline(&sx[0],&sz[0],storey,wall,y+up,in);
|
|
|
|
start_point[1]=next_prim_point;
|
|
count=0;
|
|
for(c0=0;c0<pcount;c0++)
|
|
{
|
|
create_strip_points(sx[c0],y+up,sz[c0],sx[c0+1],y+up,sz[c0+1],256,numb[count],0);
|
|
count++;
|
|
}
|
|
count=start_point[1]-start_point[0];
|
|
|
|
for(c0=0;c0<count-1;c0++)
|
|
{
|
|
p_f4=create_a_quad(start_point[1]+c0,start_point[1]+c0+1,start_point[0]+c0,start_point[0]+c0+1,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4->Type=FACE_TYPE_SKYLIGHT;
|
|
p_f4->ID=0;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
}
|
|
p_f4=create_a_quad(start_point[1]+c0,start_point[1],start_point[0]+c0,start_point[0],texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4->Type=FACE_TYPE_SKYLIGHT;
|
|
p_f4->ID=0;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
|
|
flat_fill_a_quad_of_points(start_point[1],numb[0]+1,numb[1]+1,texture_style,wall);
|
|
|
|
return(y+up);
|
|
}
|
|
|
|
void build_ladder(SLONG storey)
|
|
{
|
|
SLONG y=0,c0;
|
|
SLONG count=0;
|
|
// UWORD sp[120]; //,spr[10];
|
|
struct PrimFace4 *p4;
|
|
SLONG wall;
|
|
SLONG extra_height;
|
|
|
|
SLONG x1,z1,x2,z2;
|
|
SLONG wx1,wz1,wx2,wz2;
|
|
SLONG texture_style;
|
|
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
|
|
wx1=x1=storey_list[storey].DX;
|
|
wz1=z1=storey_list[storey].DZ;
|
|
|
|
wx2=x2=wall_list[wall].DX;
|
|
wz2=z2=wall_list[wall].DZ;
|
|
|
|
wall=-wall;
|
|
y=storey_list[storey].DY;
|
|
calc_ladder_pos(&x1,&z1,&x2,&z2,&y,&extra_height);
|
|
|
|
insert_collision_vect(x1,y,z1,x2,y,z2,STOREY_TYPE_LADDER,storey_list[storey].Height,wall);
|
|
|
|
//
|
|
// These extra colvects stop the player from squeezing between the
|
|
// wall and the ladder.
|
|
//
|
|
|
|
insert_collision_vect(
|
|
wx1, y, wz1,
|
|
x1, y, z1,
|
|
STOREY_TYPE_LADDER,
|
|
storey_list[storey].Height ,
|
|
wall);
|
|
|
|
insert_collision_vect(
|
|
x2, y, z2,
|
|
wx2, y, wz2,
|
|
STOREY_TYPE_LADDER,
|
|
storey_list[storey].Height ,
|
|
wall);
|
|
|
|
//
|
|
// These extra colvects stop the player from squeezing between the
|
|
// wall and the ladder.
|
|
//
|
|
|
|
insert_collision_vect(
|
|
wx1, y, wz1,
|
|
x1, y, z1,
|
|
STOREY_TYPE_LADDER,
|
|
0,
|
|
wall);
|
|
|
|
insert_collision_vect(
|
|
x2, y, z2,
|
|
wx2, y, wz2,
|
|
STOREY_TYPE_LADDER,
|
|
0,
|
|
wall);
|
|
|
|
//
|
|
// build edges
|
|
//
|
|
|
|
// plan view
|
|
//
|
|
// 0 5
|
|
// 1 2 3 4
|
|
{
|
|
SLONG height,size,count;
|
|
|
|
// height=(storey_list[storey].Height+extra_height)*64;
|
|
height=(storey_list[storey].Height)*64;
|
|
|
|
count=height>>8;
|
|
if (count == 0)
|
|
{
|
|
count += 1;
|
|
}
|
|
size=height/count;
|
|
|
|
start_point[0]=next_prim_point;
|
|
build_ladder_points(x1,z1,x2,z2,y,1);
|
|
|
|
for(c0=1;c0<=count;c0++)
|
|
{
|
|
start_point[c0]=next_prim_point;
|
|
build_ladder_points(x1,z1,x2,z2,y+size*c0,1);
|
|
|
|
p4=create_a_quad(start_point[c0]+0,start_point[c0]+1,start_point[c0-1]+0+0,start_point[c0-1]+1+0,texture_style,TEXTURE_PIECE_MIDDLE);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4=create_a_quad(start_point[c0]+1,start_point[c0]+2,start_point[c0-1]+1+0,start_point[c0-1]+2+0,texture_style,TEXTURE_PIECE_MIDDLE);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4=create_a_quad(start_point[c0]+3,start_point[c0]+4,start_point[c0-1]+3+0,start_point[c0-1]+4+0,texture_style,TEXTURE_PIECE_MIDDLE);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4=create_a_quad(start_point[c0]+4,start_point[c0]+5,start_point[c0-1]+4+0,start_point[c0-1]+5+0,texture_style,TEXTURE_PIECE_MIDDLE);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// now create rungs
|
|
//
|
|
|
|
|
|
for(c0=0;c0<storey_list[storey].Height;c0++)
|
|
{
|
|
SLONG spr;
|
|
spr=next_prim_point;
|
|
|
|
build_ladder_points(x1,z1,x2,z2,y+BLOCK_SIZE*(c0+1)-8,0);
|
|
build_ladder_points(x1,z1,x2,z2,y+BLOCK_SIZE*(c0+1),0);
|
|
|
|
p4=create_a_quad(spr+2,spr+2+1,spr+0,spr+1,texture_style,TEXTURE_PIECE_LEFT);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
void build_ladder_old(SLONG storey)
|
|
{
|
|
SLONG y=0,c0;
|
|
SLONG count=0;
|
|
// UWORD sp[120]; //,spr[10];
|
|
struct PrimFace4 *p4;
|
|
SLONG wall;
|
|
SLONG extra_height;
|
|
|
|
SLONG x1,z1,x2,z2;
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
|
|
x1=storey_list[storey].DX;
|
|
z1=storey_list[storey].DZ;
|
|
|
|
x2=wall_list[wall].DX;
|
|
z2=wall_list[wall].DZ;
|
|
|
|
wall=-wall;
|
|
y=storey_list[storey].DY;
|
|
calc_ladder_pos(&x1,&z1,&x2,&z2,&y,&extra_height);
|
|
|
|
insert_collision_vect(x1,y,z1,x2,y,z2,STOREY_TYPE_LADDER,0,wall);
|
|
// prim_points[start_point[count-1]].X,prim_points[start_point[count-1]].Y,prim_points[start_point[count-1]].Z,
|
|
// prim_points[start_point[count-1]+1].X,prim_points[start_point[count-1]+1].Y,prim_points[start_point[count-1]+1].Z,0,0,next_prim_face4);
|
|
|
|
while(count<(storey_list[storey].Height))
|
|
{
|
|
|
|
start_point[count]=next_prim_point;
|
|
if(count==0)
|
|
{
|
|
// plan view
|
|
//
|
|
// 0 5
|
|
// 1 2 3 4
|
|
build_ladder_points(x1,z1,x2,z2,y,1);
|
|
build_ladder_points(x1,z1,x2,z2,y+BLOCK_SIZE*4,1);
|
|
}
|
|
else
|
|
{
|
|
build_ladder_points(x1,z1,x2,z2,y+BLOCK_SIZE*4,1);
|
|
}
|
|
|
|
if(count==0)
|
|
{
|
|
p4=create_a_quad(start_point[count]+0+6,start_point[count]+1+6,start_point[count]+0+0,start_point[count]+1+0,0,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4=create_a_quad(start_point[count]+1+6,start_point[count]+2+6,start_point[count]+1+0,start_point[count]+2+0,0,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4=create_a_quad(start_point[count]+3+6,start_point[count]+4+6,start_point[count]+3+0,start_point[count]+4+0,0,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4=create_a_quad(start_point[count]+4+6,start_point[count]+5+6,start_point[count]+4+0,start_point[count]+5+0,0,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
}
|
|
if(count)
|
|
{
|
|
p4=create_a_quad(start_point[count]+0,start_point[count]+1,start_point[count-1]+0,start_point[count-1]+1,0,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4=create_a_quad(start_point[count]+1,start_point[count]+2,start_point[count-1]+1,start_point[count-1]+2,0,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4=create_a_quad(start_point[count]+3,start_point[count]+4,start_point[count-1]+3,start_point[count-1]+4,0,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4=create_a_quad(start_point[count]+4,start_point[count]+5,start_point[count-1]+4,start_point[count-1]+5,0,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
}
|
|
|
|
//
|
|
// now create rungs
|
|
//
|
|
|
|
|
|
for(c0=0;c0<4;c0++)
|
|
{
|
|
SLONG spr;
|
|
spr=next_prim_point;
|
|
|
|
build_ladder_points(x1,z1,x2,z2,y+BLOCK_SIZE*(c0+1)-8,0);
|
|
build_ladder_points(x1,z1,x2,z2,y+BLOCK_SIZE*(c0+1),0);
|
|
|
|
p4=create_a_quad(spr+2,spr+2+1,spr+0,spr+1,0,0);
|
|
p4->DrawFlags=POLY_T|POLY_FLAG_DOUBLESIDED;
|
|
p4->ThingIndex=wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
|
|
}
|
|
|
|
|
|
|
|
//floor
|
|
// insert_collision_vect(prim_points[start_point[count-1]].X,prim_points[start_point[count-1]].Y,prim_points[start_point[count-1]].Z,
|
|
// prim_points[start_point[count-1]+1].X,prim_points[start_point[count-1]+1].Y,prim_points[start_point[count-1]+1].Z,0,0,next_prim_face4);
|
|
|
|
|
|
count++;
|
|
y+=BLOCK_SIZE*4;
|
|
}
|
|
}
|
|
|
|
// x1->x2->x3
|
|
|
|
//see diag 5.2 page 164 of van dam 1
|
|
|
|
|
|
SLONG calc_sin_from_cos(SLONG sin)
|
|
{
|
|
SLONG cos;
|
|
|
|
cos=(Root((1<<14)-((sin*sin)>>14)));
|
|
cos=cos<<7;
|
|
return(cos);
|
|
|
|
}
|
|
|
|
void calc_new_corner_point(SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG x3,SLONG z3,SLONG width,SLONG *res_x,SLONG *res_z)
|
|
{
|
|
|
|
SLONG vx,vz,dist;
|
|
SLONG wx,wz;
|
|
SLONG ax,az;
|
|
SLONG angle;
|
|
|
|
SLONG z;
|
|
|
|
|
|
// LogText(" x1 %d z1 %d x2 %d z2 %d x3 %d z3 %d \n",x1,z1,x2,z2,x3,z3);
|
|
|
|
vx=x2-x1;
|
|
vz=z2-z1;
|
|
|
|
wx=-(x3-x2);
|
|
wz=-(z3-z2);
|
|
|
|
|
|
|
|
z=vx*wz-vz*wx;
|
|
// LogText(" z= %d \n",z);
|
|
|
|
dist=Root(SDIST2(vx,vz));
|
|
// LogText(" V (%d,%d) dist %d \n",vx,vz,dist);
|
|
if(dist==0)
|
|
return;
|
|
|
|
vx=(vx<<14)/dist;
|
|
vz=(vz<<14)/dist;
|
|
|
|
dist=Root(SDIST2(wx,wz));
|
|
// LogText(" W (%d,%d) dist %d \n",wx,wz,dist);
|
|
if(dist==0)
|
|
return;
|
|
|
|
wx=(wx<<14)/dist;
|
|
wz=(wz<<14)/dist;
|
|
|
|
ax=(vx+wx);
|
|
az=(vz+wz);
|
|
|
|
dist=Root(SDIST2(ax,az));
|
|
// LogText(" A (%d,%d) dist %d\n",ax,az,dist);
|
|
if(dist==0)
|
|
{
|
|
//u & V cancel each other out
|
|
*res_x = ((vz*width)>>14)+x2;
|
|
*res_z = -((vx*width)>>14)+z2;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
ax=(ax<<14)/dist;
|
|
az=(az<<14)/dist;
|
|
|
|
// LogText(" normalised vectors V(%d,%d) W(%d,%d) A(%d,%d)\n",vx,vz,wx,wz,ax,az);
|
|
|
|
angle=(vx*ax+vz*az)>>14;
|
|
// LogText(" cos angle = %d \n",angle);
|
|
//we now have the cos of the angle
|
|
angle=calc_sin_from_cos(angle); //<<2;
|
|
//LogText(" sin angle(<<14) = %d \n",angle);
|
|
|
|
//we now have the sin of the angle
|
|
|
|
// sin@=o/h
|
|
|
|
if(angle==0)
|
|
dist=width;
|
|
else
|
|
{
|
|
dist=(width<<14)/angle;
|
|
}
|
|
// LogText(" dist= %d \n",dist);
|
|
|
|
if(z>0)
|
|
{
|
|
dist=-dist;
|
|
|
|
}
|
|
|
|
|
|
*res_x=((ax*dist)>>14)+x2;
|
|
*res_z=((az*dist)>>14)+z2;
|
|
|
|
// LogText(" resx %d resz %d \n",(ax*dist)>>14,(az*dist)>>14);
|
|
|
|
}
|
|
|
|
|
|
void build_ledge(SLONG x,SLONG y,SLONG z,SLONG wall,SLONG storey,SLONG height)
|
|
{
|
|
// SLONG sp[10];
|
|
SLONG count=0;
|
|
SLONG index,c0;
|
|
SLONG dx,dz;
|
|
SLONG px,pz,rx,rz;
|
|
|
|
storey=storey;
|
|
start_point[0]=next_prim_point;
|
|
add_point(x,y,z);
|
|
index=wall;
|
|
while(index)
|
|
{
|
|
dx=wall_list[index].DX;
|
|
dz=wall_list[index].DZ;
|
|
add_point(dx,y,dz);
|
|
index=wall_list[index].Next;
|
|
count++;
|
|
}
|
|
start_point[1]=next_prim_point;
|
|
add_point(x,y,z);
|
|
|
|
px=x;
|
|
pz=z;
|
|
index=wall;
|
|
while(index)
|
|
{
|
|
SLONG next;
|
|
// LogText(" calc corner %d \n",index);
|
|
dx=wall_list[index].DX;
|
|
dz=wall_list[index].DZ;
|
|
next=wall_list[index].Next;
|
|
if(next)
|
|
{
|
|
calc_new_corner_point(px,pz,dx,dz,wall_list[next].DX,wall_list[next].DZ,BLOCK_SIZE,&rx,&rz);
|
|
add_point(rx,y,rz);
|
|
}
|
|
else
|
|
{
|
|
calc_new_corner_point(px,pz,dx,dz,wall_list[wall].DX,wall_list[wall].DZ,BLOCK_SIZE,&rx,&rz);
|
|
add_point(rx,y,rz);
|
|
prim_points[start_point[1]].X=rx;
|
|
prim_points[start_point[1]].Z=rz;
|
|
}
|
|
|
|
px=dx;
|
|
pz=dz;
|
|
index=wall_list[index].Next;
|
|
}
|
|
// add_point(prim_points[start_point[1]].X,y,prim_points[start_point[1]].Z);
|
|
|
|
y+=height;
|
|
start_point[2]=next_prim_point;
|
|
for(c0=start_point[1];c0<start_point[2];c0++)
|
|
{
|
|
prim_points[next_prim_point].X=prim_points[c0].X;
|
|
prim_points[next_prim_point].Y=y+2;
|
|
prim_points[next_prim_point].Z=prim_points[c0].Z;
|
|
next_prim_point++;
|
|
|
|
}
|
|
|
|
start_point[3]=next_prim_point;
|
|
add_point(x,y,z);
|
|
index=wall;
|
|
while(index)
|
|
{
|
|
dx=wall_list[index].DX;
|
|
dz=wall_list[index].DZ;
|
|
add_point(dx,y+2,dz);
|
|
index=wall_list[index].Next;
|
|
}
|
|
|
|
// LogText("ledge start_point %d %d %d %d next p point %d count %d \n",start_point[0],start_point[1],start_point[2],start_point[3],next_prim_point,count);
|
|
for(c0=0;c0<=count;c0++)
|
|
{
|
|
create_a_quad(start_point[1]+c0,start_point[1]+c0+1,start_point[0]+c0,start_point[0]+c0+1,0,18);
|
|
// LogText(" create a face with points %d %d %d %d \n",start_point[1]+c0,start_point[1]+c0+1,start_point[0]+c0,start_point[0]+c0+1);
|
|
create_a_quad(start_point[2]+c0,start_point[2]+c0+1,start_point[1]+c0,start_point[1]+c0+1,0,18);
|
|
create_a_quad(start_point[3]+c0,start_point[3]+c0+1,start_point[2]+c0,start_point[2]+c0+1,0,18);
|
|
}
|
|
}
|
|
|
|
SLONG create_strip_points(SLONG x1,SLONG y1,SLONG z1,SLONG x2,SLONG y2,SLONG z2,SLONG len,SLONG numb,SLONG end_flag)
|
|
{
|
|
SLONG count;
|
|
SLONG dist;
|
|
SLONG dx,dy,dz;
|
|
SLONG wwidth,wcount;
|
|
|
|
|
|
dx=x2-x1;
|
|
dz=z2-z1;
|
|
|
|
dist=Root(dx*dx+dz*dz);
|
|
|
|
if(dist==0)
|
|
dist=1;
|
|
|
|
if(numb)
|
|
count=numb;
|
|
else
|
|
count=dist/len;
|
|
|
|
wcount=count;
|
|
|
|
wwidth=dist/(wcount);
|
|
|
|
dx=(x2-x1);
|
|
dz=(z2-z1);
|
|
|
|
|
|
dx=(dx<<10)/dist;
|
|
dz=(dz<<10)/dist;
|
|
|
|
add_point(x1,y1,z1);
|
|
count--;
|
|
|
|
// LogText(" create strip points y %d (%d,%d)->(%d,%d) count %d \n",y1,x1,z1,x2,z2,count+1);
|
|
|
|
while(count)
|
|
{
|
|
|
|
x1=x1+((dx*wwidth)>>10);
|
|
z1=z1+((dz*wwidth)>>10);
|
|
add_point(x1,y1,z1);
|
|
|
|
count--;
|
|
}
|
|
if(end_flag)
|
|
add_point(x2,y1,z2); //make sure last point is spot on.
|
|
return(wcount);
|
|
}
|
|
|
|
|
|
|
|
SLONG build_outline(SLONG *sx,SLONG *sz,SLONG storey,SLONG wall,SLONG y,SLONG out)
|
|
{
|
|
SLONG offset;
|
|
SLONG px;
|
|
SLONG pz;
|
|
SLONG index;
|
|
SLONG dx,dz;
|
|
SLONG rx,rz;
|
|
|
|
offset=1;
|
|
|
|
px=storey_list[storey].DX;
|
|
pz=storey_list[storey].DZ;
|
|
|
|
index=wall;
|
|
while(index)
|
|
{
|
|
SLONG next;
|
|
dx=wall_list[index].DX;
|
|
dz=wall_list[index].DZ;
|
|
next=wall_list[index].Next;
|
|
if(next)
|
|
{
|
|
calc_new_corner_point(px,pz,dx,dz,wall_list[next].DX,wall_list[next].DZ,out,&rx,&rz);
|
|
sx[offset]=rx;
|
|
sz[offset]=rz;
|
|
}
|
|
else
|
|
{
|
|
calc_new_corner_point(px,pz,dx,dz,wall_list[wall].DX,wall_list[wall].DZ,out,&rx,&rz);
|
|
sx[0]=rx;
|
|
sz[0]=rz;
|
|
sx[offset]=rx;
|
|
sz[offset]=rz;
|
|
}
|
|
// LogText("build outline offset %d xz %d %d \n",offset,sx[offset],sz[offset]);
|
|
|
|
px=dx;
|
|
pz=dz;
|
|
index=wall_list[index].Next;
|
|
// index=0;
|
|
offset++;
|
|
}
|
|
return(offset-1);
|
|
}
|
|
|
|
|
|
SLONG ladder_on_block(SLONG p0,SLONG p1,SLONG p2,SLONG p3)
|
|
{
|
|
SLONG ax,az;
|
|
SLONG flags;
|
|
|
|
ax=prim_points[p0].X;
|
|
ax+=prim_points[p1].X;
|
|
ax+=prim_points[p2].X;
|
|
ax+=prim_points[p3].X;
|
|
|
|
az=prim_points[p0].Z;
|
|
az+=prim_points[p1].Z;
|
|
az+=prim_points[p2].Z;
|
|
az+=prim_points[p3].Z;
|
|
|
|
ax>>=2;
|
|
az>>=2;
|
|
|
|
flags=get_map_flags(ax>>PAP_SHIFT_HI,az>>PAP_SHIFT_HI);
|
|
|
|
if(flags&FLOOR_LADDER)
|
|
return(1);
|
|
else
|
|
return(0);
|
|
|
|
}
|
|
|
|
// p2 p3
|
|
//
|
|
//
|
|
// p0 p1
|
|
/*
|
|
void build_ledge_around_ladder(SLONG p0,SLONG p1,SLONG p2,SLONG p3)
|
|
{
|
|
SLONG x1,z1,x2,z2,dx,dz;
|
|
|
|
x1=prim_points[p0].X;
|
|
z1=prim_points[p0].Z;
|
|
|
|
x2=prim_points[p1].X;
|
|
z2=prim_points[p1].Z;
|
|
|
|
dx=x2-x1;
|
|
dz=z2-z1;
|
|
|
|
|
|
x1+=dx/3;
|
|
z1+=dz/3;
|
|
|
|
x2-=dx/3;
|
|
z2-=dz/3;
|
|
|
|
x1+=dz>>3;
|
|
x2+=dz>>3;
|
|
|
|
z1-=dx>>3;
|
|
z2-=dx>>3;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
*/
|
|
SLONG sx_l2[30],sz_l2[30];
|
|
SLONG build_ledge2(SLONG y,SLONG storey,SLONG out,SLONG height,SLONG dip)
|
|
{
|
|
//SLONG sp[10];
|
|
SLONG count=0;
|
|
SLONG index,c0;
|
|
SLONG dx,dz;
|
|
SLONG px,pz,rx,rz;
|
|
SLONG x,z,wall;
|
|
SLONG ox,oz;
|
|
SLONG pcount;
|
|
// SLONG numb[200];
|
|
|
|
x=storey_list[storey].DX;
|
|
z=storey_list[storey].DZ;
|
|
wall=storey_list[storey].WallHead;
|
|
|
|
storey=storey;
|
|
|
|
//
|
|
// Build points round top of building
|
|
//
|
|
LogText(" build down & in \n");
|
|
start_point[0]=next_prim_point;
|
|
ox=x;
|
|
oz=z;
|
|
index=wall;
|
|
count=0;
|
|
while(index)
|
|
{
|
|
dx=wall_list[index].DX;
|
|
dz=wall_list[index].DZ;
|
|
numb[count]=create_strip_points(ox,y,oz,dx,y,dz,256,0,1);
|
|
count++;
|
|
// add_point(dx,y,dz);
|
|
index=wall_list[index].Next;
|
|
ox=dx;
|
|
oz=dz;
|
|
}
|
|
|
|
//
|
|
// Build points at top of building height that stick out
|
|
//
|
|
LogText(" build down & out \n");
|
|
|
|
pcount=build_outline(&sx_l2[0],&sz_l2[0],storey,wall,y,out);
|
|
|
|
start_point[1]=next_prim_point;
|
|
count=0;
|
|
for(c0=0;c0<pcount;c0++)
|
|
{
|
|
create_strip_points(sx_l2[c0],y,sz_l2[c0],sx_l2[c0+1],y,sz_l2[c0+1],256,numb[count],1);
|
|
count++;
|
|
}
|
|
//create_strip_points(sx_l2[c0],y,sz_l2[c0],sx_l2[0],y,sz_l2[0],256);
|
|
|
|
//
|
|
// sticky out and up
|
|
//
|
|
LogText(" build up & out \n");
|
|
start_point[2]=next_prim_point;
|
|
|
|
pcount=build_outline(&sx_l2[0],&sz_l2[0],storey,wall,y+height,out);
|
|
|
|
count=0;
|
|
for(c0=0;c0<pcount;c0++)
|
|
{
|
|
create_strip_points(sx_l2[c0],y+height,sz_l2[c0],sx_l2[c0+1],y+height,sz_l2[c0+1],256,numb[count],1);
|
|
count++;
|
|
}
|
|
// create_strip_points(sx_l2[c0],y+height,sz_l2[c0],sx_l2[0],y+height,sz_l2[0],256);
|
|
|
|
//
|
|
// not sticky out but up
|
|
//
|
|
// LogText(" build up & in \n");
|
|
start_point[3]=next_prim_point;
|
|
|
|
ox=x;
|
|
oz=z;
|
|
index=wall;
|
|
count=0;
|
|
while(index)
|
|
{
|
|
dx=wall_list[index].DX;
|
|
dz=wall_list[index].DZ;
|
|
create_strip_points(ox,y+height,oz,dx,y+height,dz,256,numb[count],1);
|
|
count++;
|
|
index=wall_list[index].Next;
|
|
ox=dx;
|
|
oz=dz;
|
|
}
|
|
|
|
// LogText(" build half up & in \n");
|
|
start_point[4]=next_prim_point;
|
|
|
|
ox=x;
|
|
oz=z;
|
|
index=wall;
|
|
count=0;
|
|
while(index)
|
|
{
|
|
dx=wall_list[index].DX;
|
|
dz=wall_list[index].DZ;
|
|
create_strip_points(ox,y+height-dip,oz,dx,y+height-dip,dz,256,numb[count],1);
|
|
count++;
|
|
index=wall_list[index].Next;
|
|
ox=dx;
|
|
oz=dz;
|
|
}
|
|
|
|
|
|
count=start_point[1]-start_point[0];
|
|
// LogText("ledge start_point %d %d %d %d next p point %d count %d \n",start_point[0],start_point[1],start_point[2],start_point[3],next_prim_point,count);
|
|
for(c0=0;c0<count-1;c0++)
|
|
{
|
|
SLONG p0,p1,p2,p3,p4;
|
|
p0=start_point[0]+c0;
|
|
p1=start_point[1]+c0;
|
|
p2=start_point[2]+c0;
|
|
p3=start_point[3]+c0;
|
|
p4=start_point[4]+c0;
|
|
|
|
if(!ladder_on_block(p1,p1+1,p0,p0+1))
|
|
{
|
|
create_a_quad(p1,p1+1,p0,p0+1,0,18);
|
|
create_a_quad(p2,p2+1,p1,p1+1,0,18);
|
|
create_a_quad(p3,p3+1,p2,p2+1,0,18);
|
|
create_a_quad(p3+1,p3,p4+1,p4,0,18);
|
|
}
|
|
else
|
|
{
|
|
create_a_quad(p2,p3,p1,p0,0,18);
|
|
create_a_quad(p3+1,p2+1,p0+1,p1+1,0,18);
|
|
create_a_quad(p4,p4+1,p0,p0+1,0,18);
|
|
// build_ledge_around_ladder(p3,p3+1,p2,p2+1);
|
|
}
|
|
}
|
|
return(y+height-dip);
|
|
}
|
|
|
|
#define RECESS_SIZE (32)
|
|
void append_recessed_wall_prim(SLONG x,SLONG y,SLONG z,SLONG wall,SLONG storey,SLONG height)
|
|
{
|
|
SLONG x2,y2,z2;
|
|
SLONG dx,dz,len;
|
|
// SLONG sp[10];
|
|
SLONG texture,texture_style;
|
|
SLONG texture_style2;
|
|
struct PrimFace4 *p_f4;
|
|
SLONG c0;
|
|
UBYTE *ptexture1;
|
|
SLONG tcount1;
|
|
UBYTE *ptexture2;
|
|
SLONG tcount2;
|
|
|
|
ptexture1=wall_list[wall].Textures;
|
|
tcount1=wall_list[wall].Tcount;
|
|
ptexture2=wall_list[wall].Textures2;
|
|
tcount2=wall_list[wall].Tcount2;
|
|
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
texture_style2=wall_list[wall].TextureStyle2;
|
|
if(texture_style==0)
|
|
texture_style=1;
|
|
if(texture_style2==0)
|
|
texture_style2=1;
|
|
|
|
|
|
x2=wall_list[wall].DX;
|
|
z2=wall_list[wall].DZ;
|
|
|
|
dx=x2-x;
|
|
dz=z2-z;
|
|
|
|
len=Root(dx*dx+dz*dz);
|
|
if(len==0)
|
|
len=1;
|
|
|
|
dx = (dx*RECESS_SIZE)/len;
|
|
dz = (dz*RECESS_SIZE)/len;
|
|
|
|
start_point[0]=next_prim_point;
|
|
add_point(x,y,z);
|
|
add_point(x,y+height,z);
|
|
|
|
add_point(x+dz,y,z-dx);
|
|
add_point(x+dz,y+height,z-dx);
|
|
|
|
start_point[1]=next_prim_point;
|
|
add_point(x2,y,z2);
|
|
add_point(x2,y+height,z2);
|
|
|
|
add_point(x2+dz,y,z2-dx);
|
|
add_point(x2+dz,y+height,z2-dx);
|
|
|
|
texture=TEXTURE_PIECE_LEFT;
|
|
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
|
|
if(texture_style==0)
|
|
texture_style=1;
|
|
|
|
p_f4=create_a_quad(start_point[0]+1,start_point[0]+3,start_point[0]+0,start_point[0]+2,texture_style,texture); //left
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
texture=TEXTURE_PIECE_RIGHT;
|
|
p_f4=create_a_quad(start_point[1]+3,start_point[1]+1,start_point[1]+2,start_point[1]+0,texture_style,texture); //right
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
texture=TEXTURE_PIECE_MIDDLE2;
|
|
p_f4=create_a_quad(start_point[0],start_point[0]+2,start_point[1]+0,start_point[1]+2,texture_style,texture); // floor
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
texture=TEXTURE_PIECE_MIDDLE1;
|
|
p_f4=create_a_quad(start_point[0]+3,start_point[0]+1,start_point[1]+3,start_point[1]+1,texture_style,texture); //roof
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
x+=dz;
|
|
z+=-dx;
|
|
|
|
x2+=dz;
|
|
z2+=-dx;
|
|
|
|
start_point[0]=build_row_wall_only_points_at_y(y+height+2,x,z,x2,z2,wall);
|
|
start_point[1]=build_row_wall_only_points_at_y(y ,x,z,x2,z2,wall);
|
|
// for(c0=0;c0<wall_list[wall].WindowCount;c0++)
|
|
for(c0=0;c0<WindowCount;c0++)
|
|
{
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
if(c0==0)
|
|
{
|
|
texture=TEXTURE_PIECE_RIGHT;
|
|
}
|
|
else
|
|
if(c0==WindowCount-1)
|
|
{
|
|
|
|
texture=TEXTURE_PIECE_LEFT;
|
|
}
|
|
else
|
|
{
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
}
|
|
// p_f4=create_a_quad(start_point[0]+c0,start_point[0]+c0+1,start_point[1]+c0,start_point[1]+c0+1,texture_style,texture);
|
|
|
|
|
|
// p_f4->ThingIndex=-wall;
|
|
|
|
if(ptexture1 && (c0<WindowCount) && ptexture1[c0])
|
|
{
|
|
p_f4=create_a_quad_tex(start_point[0]+c0,start_point[0]+c0+1,start_point[1]+c0,start_point[1]+c0+1,ptexture1[c0]);
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
else
|
|
{
|
|
// if(ControlFlag)
|
|
{
|
|
p_f4=create_a_quad(start_point[0]+c0,start_point[0]+c0+1,start_point[1]+c0,start_point[1]+c0+1,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
}
|
|
// if(storey_list[storey].InsideIDIndex||storey_list[storey].InsideStorey||storey_list[storey].StoreyType==STOREY_TYPE_PARTITION)
|
|
{
|
|
if(ptexture2 && (c0<tcount2) && ptexture2[c0])
|
|
{
|
|
p_f4=create_a_quad_tex(start_point[0]+c0+1,start_point[0]+c0,start_point[1]+c0+1,start_point[1]+c0,ptexture2[c0]);
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
else
|
|
{
|
|
p_f4=create_a_quad(start_point[0]+c0+1,start_point[0]+c0,start_point[1]+c0+1,start_point[1]+c0,texture_style2,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
p_f4->FaceFlags|=FACE_FLAG_TEX2;
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void append_foundation_wall(SLONG x,SLONG y,SLONG z,SLONG wall,SLONG storey,SLONG height)
|
|
{
|
|
SLONG c0;
|
|
SLONG start_point[10];
|
|
// SLONG sf4[10];
|
|
SLONG texture,texture_style;
|
|
struct PrimFace4 *p_f4;
|
|
UBYTE *ptexture;
|
|
SLONG tcount,count;
|
|
|
|
/*
|
|
if(wall_list[wall].WallFlags&FLAG_WALL_RECESSED)
|
|
{
|
|
append_recessed_wall_prim(x,y,z, wall,storey,height);
|
|
return;
|
|
|
|
}
|
|
*/
|
|
ptexture=wall_list[wall].Textures;
|
|
tcount=wall_list[wall].Tcount;
|
|
|
|
// set_build_seed(x*z*storey*wall+x+z+y);
|
|
set_build_seed(x*z+y);
|
|
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
if(texture_style==0)
|
|
texture_style=1;
|
|
|
|
if(!(wall_list[wall].WallFlags&FLAG_WALL_AUTO_WINDOWS)&& WindowCount==0)
|
|
{
|
|
start_point[0]=build_row_wall_only_points_at_y(y+2,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
start_point[1]=build_row_wall_only_points_at_floor_alt(0 ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
count=0;
|
|
for(c0=0;c0<WindowCount;c0++)
|
|
{
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
if(c0==0)
|
|
{
|
|
// if(storey_list[storey].Next==0)
|
|
// texture=TEXTURE_PIECE_TOP_RIGHT;
|
|
// else
|
|
texture=TEXTURE_PIECE_RIGHT;
|
|
}
|
|
else
|
|
if(c0==WindowCount-1)
|
|
{
|
|
|
|
// if(storey_list[storey].Next==0)
|
|
// texture=TEXTURE_PIECE_TOP_LEFT;
|
|
// else
|
|
texture=TEXTURE_PIECE_LEFT;
|
|
}
|
|
else
|
|
{
|
|
// if(storey_list[storey].Next==0)
|
|
// texture=TEXTURE_PIECE_TOP_MIDDLE;
|
|
// else
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
|
|
}
|
|
if(ptexture && (count<tcount) && ptexture[count])
|
|
{
|
|
p_f4=create_a_quad_tex(start_point[0]+c0,start_point[0]+c0+1,start_point[1]+c0,start_point[1]+c0+1,ptexture[count]);
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
else
|
|
{
|
|
p_f4=create_a_quad(start_point[0]+c0,start_point[0]+c0+1,start_point[1]+c0,start_point[1]+c0+1,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
//
|
|
// fix texture sizes
|
|
//
|
|
{
|
|
SLONG dy;
|
|
dy=prim_points[start_point[0]+c0+1].Y-prim_points[start_point[1]+c0+1].Y;
|
|
if(dy>256)
|
|
dy=256;
|
|
dy=(31*dy)>>8;
|
|
p_f4->UV[2][1]=p_f4->UV[0][1]+dy;
|
|
|
|
dy=prim_points[start_point[0]+c0].Y-prim_points[start_point[1]+c0].Y;
|
|
if(dy>256)
|
|
dy=256;
|
|
dy=(31*dy)>>8;
|
|
p_f4->UV[3][1]=p_f4->UV[1][1]+dy;
|
|
}
|
|
count++;
|
|
}
|
|
WindowCount=0;
|
|
}
|
|
}
|
|
|
|
void append_wall_prim(SLONG x,SLONG y,SLONG z,SLONG wall,SLONG storey,SLONG height) //,UBYTE *ptexture,UWORD tcount)
|
|
{
|
|
SLONG c0;
|
|
SLONG start_point[10];
|
|
// SLONG sf4[10];
|
|
SLONG texture,texture_style,texture_style2;
|
|
SLONG count;
|
|
struct PrimFace4 *p_f4;
|
|
UBYTE *ptexture1;
|
|
SLONG tcount1;
|
|
UBYTE *ptexture2;
|
|
SLONG tcount2;
|
|
SLONG no_draw=0;
|
|
SLONG circular;
|
|
|
|
circular=is_storey_circular(storey);
|
|
|
|
if(next_prim_point>50000)
|
|
no_draw=1;
|
|
// return;
|
|
if((edit_info.HideMap&1)&& x<16384)
|
|
no_draw=1;
|
|
// return;
|
|
if((edit_info.HideMap&2)&& x>16384)
|
|
no_draw=1;
|
|
// return;
|
|
|
|
|
|
|
|
if(wall_list[wall].WallFlags&FLAG_WALL_RECESSED)
|
|
{
|
|
append_recessed_wall_prim(x,y,z, wall,storey,height);
|
|
return;
|
|
}
|
|
WindowCount=0;
|
|
|
|
ptexture1=wall_list[wall].Textures;
|
|
tcount1=wall_list[wall].Tcount;
|
|
ptexture2=wall_list[wall].Textures2;
|
|
tcount2=wall_list[wall].Tcount2;
|
|
|
|
// set_build_seed(x*z*storey*wall+x+z+y);
|
|
set_build_seed(x*z+y);
|
|
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
texture_style2=wall_list[wall].TextureStyle2;
|
|
if(texture_style==0)
|
|
texture_style=1;
|
|
if(texture_style2==0)
|
|
texture_style2=1;
|
|
|
|
|
|
if(!(wall_list[wall].WallFlags&FLAG_WALL_AUTO_WINDOWS)&& WindowCount==0)
|
|
{
|
|
// if(next_prim_point>50000)
|
|
if(!no_draw)
|
|
{
|
|
if(!circular)
|
|
{
|
|
start_point[0]=build_row_wall_only_points_at_floor_alt(y+height+2 ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
start_point[1]=build_row_wall_only_points_at_floor_alt(y ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
}
|
|
else
|
|
{
|
|
start_point[0]=build_row_wall_only_points_at_y(y+height+2 ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
start_point[1]=build_row_wall_only_points_at_y(y ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
start_point[0]=0;
|
|
start_point[1]=0;
|
|
|
|
}
|
|
count=0;
|
|
for(c0=0;c0<WindowCount;c0++)
|
|
{
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
if(c0==0)
|
|
{
|
|
// if(storey_list[storey].Next==0)
|
|
// texture=TEXTURE_PIECE_TOP_RIGHT;
|
|
// else
|
|
texture=TEXTURE_PIECE_RIGHT;
|
|
}
|
|
else
|
|
if(c0==WindowCount-1)
|
|
{
|
|
|
|
// if(storey_list[storey].Next==0)
|
|
// texture=TEXTURE_PIECE_TOP_LEFT;
|
|
// else
|
|
texture=TEXTURE_PIECE_LEFT;
|
|
}
|
|
else
|
|
{
|
|
// if(storey_list[storey].Next==0)
|
|
// texture=TEXTURE_PIECE_TOP_MIDDLE;
|
|
// else
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
|
|
}
|
|
|
|
|
|
// if((edit_info.HideMap&1) && prim_points[start_point[0]+c0].X>=16384 || (edit_info.HideMap&2) && prim_points[start_point[0]+c0].X<=16384 ||(edit_info.HideMap&3)==0)
|
|
{
|
|
|
|
// LogText(" face %d texture %d \n",c0,texture);
|
|
if(ptexture1 && (count<tcount1) && ptexture1[count])
|
|
{
|
|
p_f4=create_a_quad_tex(start_point[0]+c0,start_point[0]+c0+1,start_point[1]+c0,start_point[1]+c0+1,ptexture1[count]);
|
|
if(p_f4)
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
else
|
|
{
|
|
p_f4=create_a_quad(start_point[0]+c0,start_point[0]+c0+1,start_point[1]+c0,start_point[1]+c0+1,texture_style,texture);
|
|
if(p_f4)
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
if(no_draw)
|
|
next_prim_face4--;
|
|
|
|
if(!circular)
|
|
{
|
|
p_f4->DrawFlags|=POLY_FLAG_DOUBLESIDED;
|
|
}
|
|
|
|
//
|
|
// All warehouses have two-sided walls.
|
|
//
|
|
|
|
if (building_list[storey_list[storey].BuildingHead].BuildingType == BUILDING_TYPE_WAREHOUSE ||
|
|
storey_list[storey].InsideIDIndex ||
|
|
storey_list[storey].InsideStorey ||
|
|
storey_list[storey].StoreyType == STOREY_TYPE_PARTITION)
|
|
{
|
|
if(ptexture2 && (count<tcount2) && ptexture2[count])
|
|
{
|
|
p_f4=create_a_quad_tex(start_point[0]+c0+1,start_point[0]+c0,start_point[1]+c0+1,start_point[1]+c0,ptexture2[count]);
|
|
if(p_f4)
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
else
|
|
{
|
|
p_f4=create_a_quad(start_point[0]+c0+1,start_point[0]+c0,start_point[1]+c0+1,start_point[1]+c0,texture_style2,texture,1);
|
|
if(p_f4)
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
if(p_f4)
|
|
p_f4->FaceFlags|=FACE_FLAG_TEX2;
|
|
if(no_draw)
|
|
next_prim_face4--;
|
|
|
|
}
|
|
|
|
if(p_f4)
|
|
if(height<256)
|
|
{
|
|
if(height==64)
|
|
{
|
|
p_f4->UV[2][1]-=24;
|
|
p_f4->UV[3][1]-=24;
|
|
}
|
|
else
|
|
if(height==128)
|
|
{
|
|
p_f4->UV[2][1]-=16;
|
|
p_f4->UV[3][1]-=16;
|
|
}
|
|
else
|
|
if(height==128+64)
|
|
{
|
|
p_f4->UV[2][1]-=8;
|
|
p_f4->UV[3][1]-=8;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
count++;
|
|
}
|
|
WindowCount=0;
|
|
}
|
|
else
|
|
{
|
|
|
|
/*
|
|
start_point[0]=build_row_wall_points_at_y(y+height ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
start_point[1]=build_row_wall_points_at_y(y+(height*2)/3,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
start_point[2]=build_row_wall_points_at_y(y+(height*1)/3,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
start_point[3]=build_row_wall_points_at_y(y ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
|
|
start_point[4]=build_row_window_depth_points_at_y(y+(height*2)/3,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
start_point[5]=build_row_window_depth_points_at_y(y+(height*1)/3,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
|
|
for(c0=0;c0<WindowCount*2+1;c0++)
|
|
{
|
|
p_f4=create_a_quad(start_point[0]+c0,start_point[0]+c0+1,start_point[1]+c0,start_point[1]+c0+1,0,0);
|
|
if(p_f4)
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4=create_a_quad(start_point[2]+c0,start_point[2]+c0+1,start_point[3]+c0,start_point[3]+c0+1,0,0);
|
|
if(p_f4)
|
|
p_f4->ThingIndex=-wall;
|
|
if(!(c0&1))
|
|
{
|
|
p_f4=create_a_quad(start_point[1]+c0,start_point[1]+c0+1,start_point[2]+c0,start_point[2]+c0+1,0,0);
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
|
|
}
|
|
for(c0=0;c0<WindowCount;c0++)
|
|
{
|
|
p_f4=create_a_quad(start_point[1]+c0*2+1,start_point[1]+c0*2+2,start_point[4]+c0*2,start_point[4]+c0*2+1,0,0); //lid
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4=create_a_quad(start_point[1]+c0*2+1,start_point[4]+c0*2,start_point[2]+c0*2+1,start_point[5]+c0*2,0,0); //side1
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4=create_a_quad(start_point[4]+c0*2+1,start_point[1]+c0*2+2,start_point[5]+c0*2+1,start_point[2]+c0*2+2,0,0); //side2
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4=create_a_quad(start_point[5]+c0*2,start_point[5]+c0*2+1,start_point[2]+c0*2+1,start_point[2]+c0*2+2,0,0); //base
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
SLONG find_near_prim_point(SLONG x,SLONG z,SLONG sp,SLONG ep)
|
|
{
|
|
SLONG best,best_dist=0x7fffffff,dx,dz,dist,c0;
|
|
|
|
for(c0=sp;c0<ep;c0++)
|
|
{
|
|
dx=(prim_points[c0].X-x);
|
|
dz=(prim_points[c0].Z-z);
|
|
dist=SDIST2(dx,dz);
|
|
if(dist<best_dist)
|
|
{
|
|
best_dist=dist;
|
|
best=c0;
|
|
}
|
|
}
|
|
|
|
return(best);
|
|
}
|
|
|
|
|
|
void create_recessed_storey_points(SLONG y,SLONG storey,SLONG count,SLONG size)
|
|
{
|
|
|
|
SLONG px,pz,index,dx,dz;
|
|
SLONG rx,rz;
|
|
SLONG wall;
|
|
SLONG sp;
|
|
|
|
count=count;
|
|
sp=next_prim_point;
|
|
|
|
px=storey_list[storey].DX;
|
|
pz=storey_list[storey].DZ;
|
|
add_point(px,y,pz); //this gets replaced later
|
|
index=storey_list[storey].WallHead;
|
|
wall=index;
|
|
|
|
while(index)
|
|
{
|
|
SLONG next;
|
|
// LogText(" calc corner %d \n",index);
|
|
dx=wall_list[index].DX;
|
|
dz=wall_list[index].DZ;
|
|
next=wall_list[index].Next;
|
|
if(next)
|
|
{
|
|
calc_new_corner_point(px,pz,dx,dz,wall_list[next].DX,wall_list[next].DZ,size,&rx,&rz);
|
|
add_point(rx,y,rz);
|
|
}
|
|
else
|
|
{
|
|
calc_new_corner_point(px,pz,dx,dz,wall_list[wall].DX,wall_list[wall].DZ,size,&rx,&rz);
|
|
add_point(rx,y,rz);
|
|
prim_points[sp].X=rx;
|
|
prim_points[sp].Z=rz;
|
|
}
|
|
|
|
px=dx;
|
|
pz=dz;
|
|
index=wall_list[index].Next;
|
|
}
|
|
}
|
|
|
|
void scan_triangle(SLONG x0, SLONG y0, SLONG z0,SLONG x1, SLONG y1, SLONG z1,SLONG x2, SLONG y2, SLONG z2,SLONG flag)
|
|
{
|
|
|
|
SLONG px,py,pz;
|
|
SLONG face_x,face_y,face_z;
|
|
SLONG c0;
|
|
SLONG s,t,step_s,step_t;
|
|
SLONG vx,vy,vz,wx,wy,wz;
|
|
struct DepthStrip *me;
|
|
SLONG quad;
|
|
SLONG len;
|
|
// CBYTE str[100];
|
|
UBYTE info=0;
|
|
|
|
face_x = x0;
|
|
face_y = y0;
|
|
face_z = z0;
|
|
|
|
vx = x1 - x0;
|
|
vy = y1 - y0; //vector from point 0 to point 1
|
|
vz = z1 - z0;
|
|
|
|
wx = x2 - x0; //vector from point 1 to point 2
|
|
wy = y2 - y0;
|
|
wz = z2 - z0;
|
|
|
|
len=(Root(vx*vx+vy*vy+vz*vz)>>7);
|
|
if(len<2)
|
|
len=2;
|
|
step_s=(1<<7)/len;
|
|
len=(Root(wx*wx+wy*wy+wz*wz)>>7);
|
|
if(len<2)
|
|
len=2;
|
|
step_t=(1<<7)/len;
|
|
|
|
if(step_s==0)
|
|
step_s=256;
|
|
if(step_t==0)
|
|
step_t=256;
|
|
|
|
for(s=5; s<(245) ; s+=step_s)
|
|
for(t=5; t<(245) && ((s+t)<(245)); t+=step_t)
|
|
{
|
|
px=face_x+((s*vx)>>8)+((t*wx)>>8);
|
|
py=face_y+((s*vy)>>8)+((t*wy)>>8);
|
|
pz=face_z+((s*vz)>>8)+((t*wz)>>8);
|
|
|
|
|
|
if (PAP_on_map_hi(px >> PAP_SHIFT_HI, pz >> PAP_SHIFT_HI))
|
|
{
|
|
set_map_flag(
|
|
px >> PAP_SHIFT_HI,
|
|
pz >> PAP_SHIFT_HI,
|
|
PAP_FLAG_HIDDEN);
|
|
}
|
|
|
|
|
|
|
|
|
|
// if((px>>8)>0&&(px>>8)<EDIT_MAP_WIDTH&&(pz>>8)>0&&(pz>>8)<EDIT_MAP_DEPTH)
|
|
// if(in_map_range((px>>ELE_SHIFT),(pz>>ELE_SHIFT)))
|
|
// {
|
|
// me=&edit_map[(px>>ELE_SHIFT)][(pz>>ELE_SHIFT)];
|
|
// me->Flags|=FLOOR_HIDDEN;
|
|
// set_map_flag(px>>ELE_SHIFT,(pz>>ELE_SHIFT),FLOOR_HIDDEN);
|
|
//LogText(" dx %d dz %d hidden \n",px>>ELE_SHIFT,pz>>ELE_SHIFT);
|
|
// me->Texture|=TS_TEXT_SORT;
|
|
// }
|
|
}
|
|
}
|
|
|
|
|
|
void flag_floor_tiles_for_quad(SLONG p0,SLONG p1,SLONG p2,SLONG p3)
|
|
{
|
|
SLONG x0,y0,z0,x1,y1,z1,x2,y2,z2,x3,y3,z3;
|
|
|
|
|
|
x0=prim_points[p0].X;
|
|
y0=prim_points[p0].Y;
|
|
z0=prim_points[p0].Z;
|
|
|
|
x1=prim_points[p1].X;
|
|
y1=prim_points[p1].Y;
|
|
z1=prim_points[p1].Z;
|
|
|
|
x2=prim_points[p2].X;
|
|
y2=prim_points[p2].Y;
|
|
z2=prim_points[p2].Z;
|
|
|
|
x3=prim_points[p3].X;
|
|
y3=prim_points[p3].Y;
|
|
z3=prim_points[p3].Z;
|
|
|
|
|
|
scan_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,0);
|
|
scan_triangle(x1,y1,z1,x3,y3,z3,x2,y2,z2,0);
|
|
|
|
}
|
|
|
|
void flag_floor_tiles_for_tri(SLONG p0,SLONG p1,SLONG p2)
|
|
{
|
|
SLONG x0,y0,z0,x1,y1,z1,x2,y2,z2;
|
|
|
|
|
|
x0=prim_points[p0].X;
|
|
y0=prim_points[p0].Y;
|
|
z0=prim_points[p0].Z;
|
|
|
|
x1=prim_points[p1].X;
|
|
y1=prim_points[p1].Y;
|
|
z1=prim_points[p1].Z;
|
|
|
|
x2=prim_points[p2].X;
|
|
y2=prim_points[p2].Y;
|
|
z2=prim_points[p2].Z;
|
|
|
|
|
|
|
|
scan_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,0);
|
|
|
|
}
|
|
|
|
|
|
SLONG build_roof(UWORD storey,SLONG y,SLONG flat_flag)
|
|
{
|
|
// SLONG x1,z1,x2,z2,x3,z3;
|
|
SLONG wall;
|
|
// ,prev_wall,prev_prev_wall;
|
|
// SLONG sp[10];
|
|
SLONG roof;
|
|
SLONG p0,p1,p2,p3;
|
|
// SLONG rx,rz;
|
|
SLONG count;
|
|
SLONG roof_height=BLOCK_SIZE*3;
|
|
SLONG c0;
|
|
SLONG overlap;
|
|
|
|
SLONG roof_flags;
|
|
SLONG roof_rim;
|
|
SLONG overlap_height=BLOCK_SIZE>>1;
|
|
|
|
SLONG poox,pooz;
|
|
|
|
//calc_new_corner_point(0,0,0,50,0,100,12,&poox,&pooz);
|
|
overlap=BLOCK_SIZE>>1;
|
|
/*
|
|
roof=storey_list[storey].Roof;
|
|
roof_flags=storey_list[roof].StoreyFlags;
|
|
|
|
if(roof_flags&FLAG_ROOF_WALLED)
|
|
overlap_height=BLOCK_SIZE;
|
|
|
|
if(roof_flags&FLAG_ROOF_FLAT)
|
|
roof_height=0;
|
|
|
|
overlap=BLOCK_SIZE>>1;
|
|
|
|
if(roof_flags&FLAG_ROOF_OVERLAP_SMALL)
|
|
overlap=BLOCK_SIZE>>1;
|
|
else
|
|
if(roof_flags&FLAG_ROOF_OVERLAP_MEDIUM)
|
|
overlap=BLOCK_SIZE;
|
|
*/
|
|
|
|
if((storey_list[storey].StoreyFlags&FLAG_STOREY_ROOF_RIM)&&0)
|
|
{
|
|
|
|
if(storey_list[storey].WallHead)// && storey_list[storey].Roof)
|
|
{
|
|
|
|
//
|
|
// Roof points arround top of wall
|
|
//
|
|
|
|
start_point[0]=next_prim_point;
|
|
add_point(storey_list[storey].DX,y+2,storey_list[storey].DZ);
|
|
wall=storey_list[storey].WallHead;
|
|
count=0;
|
|
while(wall)
|
|
{
|
|
|
|
add_point(wall_list[wall].DX,y+2,wall_list[wall].DZ);
|
|
wall=wall_list[wall].Next;
|
|
count++;
|
|
}
|
|
|
|
//
|
|
// Roof points jutting out at wall height
|
|
//
|
|
start_point[1]=next_prim_point;
|
|
create_recessed_storey_points(y,storey,count,overlap);
|
|
|
|
//
|
|
// Roof point jutting out at raised height (overlap_height)
|
|
//
|
|
|
|
start_point[2]=next_prim_point;
|
|
roof_rim=next_prim_point;
|
|
for(c0=0;c0<start_point[2]-start_point[1];c0++)
|
|
{
|
|
SLONG x,z;
|
|
x=prim_points[c0+start_point[1]].X;
|
|
z=prim_points[c0+start_point[1]].Z;
|
|
|
|
add_point(x,y+(overlap_height),z);
|
|
|
|
}
|
|
|
|
// BUILD RAISED/CENTER POINTS FOR ANGLED/FLAT ROOF
|
|
// now unused
|
|
|
|
/*
|
|
sp[3]=next_prim_point;
|
|
wall=storey_list[roof].WallHead;
|
|
add_point(storey_list[roof].DX,y+roof_height,storey_list[roof].DZ);
|
|
while(wall)
|
|
{
|
|
add_point(wall_list[wall].DX,y+roof_height,wall_list[wall].DZ);
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
*/
|
|
start_point[4]=next_prim_point;
|
|
/*
|
|
for(c0=0;c0<=count;c0++)
|
|
{
|
|
p0=start_point[0]+c0+1;
|
|
p1=start_point[0]+c0;
|
|
|
|
p2=find_near_prim_point(prim_points[p1].X,prim_points[p1].Z,start_point[3],start_point[4]);
|
|
p3=find_near_prim_point(prim_points[p0].X,prim_points[p0].Z,start_point[3],start_point[4]);
|
|
if(p2&&p3)
|
|
{
|
|
if(p2!=p3)
|
|
{
|
|
flag_floor_tiles_for_quad(p0,p1,p3,p2);
|
|
}
|
|
else
|
|
{
|
|
flag_floor_tiles_for_tri(p0,p1,p3);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
//cancel walled
|
|
/*
|
|
if(roof_flags&FLAG_ROOF_WALLED)
|
|
{
|
|
//
|
|
// raised and overlap inwards
|
|
//
|
|
|
|
create_recessed_storey_points(y+overlap_height,storey,count,-overlap);
|
|
start_point[5]=next_prim_point;
|
|
|
|
//
|
|
// overlap inwards but back to wall height
|
|
//
|
|
roof_rim=next_prim_point;
|
|
for(c0=0;c0<start_point[5]-start_point[4];c0++)
|
|
{
|
|
SLONG x,z;
|
|
x=prim_points[c0+start_point[4]].X;
|
|
z=prim_points[c0+start_point[4]].Z;
|
|
|
|
add_point(x,y,z);
|
|
|
|
}
|
|
}
|
|
|
|
if( (roof_flags&(FLAG_ROOF_WALLED|FLAG_ROOF_FLAT)) ==(FLAG_ROOF_WALLED)) //ANGLED ROOF WITH WALL
|
|
{
|
|
//
|
|
// overlap inwards even further but back to wall height //only for non flat walled buildings
|
|
//
|
|
start_point[6]=next_prim_point;
|
|
roof_rim=next_prim_point;
|
|
create_recessed_storey_points(y,storey,count,-overlap*2);
|
|
|
|
}
|
|
*/
|
|
|
|
|
|
//
|
|
// Brind overlap back to storey position and a bit more
|
|
//
|
|
start_point[5]=next_prim_point;
|
|
roof_rim=next_prim_point;
|
|
//
|
|
// overlap inwards slightly and raised
|
|
//
|
|
create_recessed_storey_points(y+overlap_height,storey,count,-3);
|
|
|
|
|
|
// if(storey_list[storey].StoreyFlags&FLAG_ROOF_WALLED)
|
|
|
|
for(c0=0;c0<=count;c0++)
|
|
{
|
|
create_a_quad(start_point[1]+c0,start_point[1]+c0+1,start_point[0]+c0,start_point[0]+c0+1,0,23);
|
|
create_a_quad(start_point[2]+c0,start_point[2]+c0+1,start_point[1]+c0,start_point[1]+c0+1,0,23);
|
|
create_a_quad(start_point[5]+c0,start_point[5]+c0+1,start_point[2]+c0,start_point[2]+c0+1,0,23);
|
|
}
|
|
|
|
|
|
/* //forget walled for now
|
|
if(roof_flags&FLAG_ROOF_WALLED)
|
|
{
|
|
for(c0=0;c0<=count;c0++)
|
|
{
|
|
create_a_quad(start_point[4]+c0,start_point[4]+c0+1,start_point[2]+c0,start_point[2]+c0+1,0,23);
|
|
create_a_quad(start_point[5]+c0,start_point[5]+c0+1,start_point[4]+c0,start_point[4]+c0+1,0,23);
|
|
}
|
|
|
|
}
|
|
if( (roof_flags&(FLAG_ROOF_WALLED|FLAG_ROOF_FLAT)) ==(FLAG_ROOF_WALLED)) //ANGLED ROOF WITH WALL
|
|
{
|
|
for(c0=0;c0<=count;c0++)
|
|
create_a_quad(start_point[6]+c0,start_point[6]+c0+1,start_point[5]+c0,start_point[5]+c0+1,0,23);
|
|
}
|
|
*/
|
|
|
|
/* //old filling to roof points raised or flat
|
|
wall=storey_list[storey].WallHead;
|
|
count=0;
|
|
while(wall)
|
|
{
|
|
SLONG q0,q1;
|
|
|
|
p0=roof_rim+count+1;
|
|
p1=roof_rim+count;
|
|
|
|
q0=start_point[0]+count+1;
|
|
q1=start_point[0]+count;
|
|
|
|
p2=find_near_prim_point(prim_points[p1].X,prim_points[p1].Z,start_point[3],start_point[4]);
|
|
p3=find_near_prim_point(prim_points[p0].X,prim_points[p0].Z,start_point[3],start_point[4]);
|
|
|
|
if(p2!=p3)
|
|
{
|
|
create_a_quad(p0,p1,p3,p2,0,23); //p2,p3,p1,p0);
|
|
//no more flag_floor_tiles_for_quad(q0,q1,p3,p2);
|
|
|
|
}
|
|
else
|
|
{
|
|
create_a_tri(p0,p1,p2,0,23);
|
|
//no more flag_floor_tiles_for_tri(q0,q1,p3);
|
|
}
|
|
wall=wall_list[wall].Next;
|
|
count++;
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
else
|
|
overlap_height=0;
|
|
return(build_roof_grid(storey,y+overlap_height,flat_flag));
|
|
|
|
}
|
|
|
|
SLONG area_of_quad(SLONG p0,SLONG p1,SLONG p2,SLONG p3)
|
|
{
|
|
|
|
SLONG dx,dz;
|
|
dx=abs(prim_points[p0].X-prim_points[p1].X);
|
|
dz=abs(prim_points[p0].Z-prim_points[p2].Z);
|
|
return(dx*dz);
|
|
}
|
|
|
|
|
|
// p0 p01 p1
|
|
|
|
|
|
// p20 p03 p13
|
|
|
|
|
|
// p2 p32 p3
|
|
|
|
|
|
void create_split_quad_into_4(SLONG p0,SLONG p1,SLONG p2,SLONG p3,SLONG wall,SLONG y)
|
|
{
|
|
|
|
SLONG p01,p13,p32,p20,p03;
|
|
SLONG x,z;
|
|
struct PrimFace4 *p_f4;
|
|
|
|
SWORD texture_style;
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
|
|
p01=next_prim_point;
|
|
x=(prim_points[p1].X+prim_points[p0].X)>>1;
|
|
z=(prim_points[p1].Z+prim_points[p0].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
p13=next_prim_point;
|
|
x=(prim_points[p1].X+prim_points[p3].X)>>1;
|
|
z=(prim_points[p1].Z+prim_points[p3].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
p32=next_prim_point;
|
|
x=(prim_points[p3].X+prim_points[p2].X)>>1;
|
|
z=(prim_points[p3].Z+prim_points[p2].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
p20=next_prim_point;
|
|
x=(prim_points[p0].X+prim_points[p2].X)>>1;
|
|
z=(prim_points[p0].Z+prim_points[p2].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
p03=next_prim_point;
|
|
x=(prim_points[p0].X+prim_points[p1].X+prim_points[p2].X+prim_points[p3].X)>>2;
|
|
z=(prim_points[p0].Z+prim_points[p1].Z+prim_points[p2].Z+prim_points[p3].Z)>>2;
|
|
add_point(x,y,z);
|
|
|
|
p_f4=create_a_quad(p0,p01,p20,p03,texture_style,0); //p2,p3,p1,p0);
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(p20,p03,p2,p32,texture_style,0); //p2,p3,p1,p0);
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
|
|
p_f4=create_a_quad(p01,p1,p03,p13,texture_style,0); //p2,p3,p1,p0);
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(p03,p13,p32,p3,texture_style,0); //p2,p3,p1,p0);
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
}
|
|
|
|
void create_split_quad_into_16(SLONG p0,SLONG p1,SLONG p2,SLONG p3,SLONG wall,SLONG y)
|
|
{
|
|
SLONG p01,p13,p32,p20,p03;
|
|
SLONG x,z;
|
|
struct PrimFace4 *p_f4;
|
|
|
|
|
|
p01=next_prim_point;
|
|
x=(prim_points[p1].X+prim_points[p0].X)>>1;
|
|
z=(prim_points[p1].Z+prim_points[p0].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
|
|
p13=next_prim_point;
|
|
x=(prim_points[p1].X+prim_points[p3].X)>>1;
|
|
z=(prim_points[p1].Z+prim_points[p3].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
p32=next_prim_point;
|
|
x=(prim_points[p3].X+prim_points[p2].X)>>1;
|
|
z=(prim_points[p3].Z+prim_points[p2].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
p20=next_prim_point;
|
|
x=(prim_points[p0].X+prim_points[p2].X)>>1;
|
|
z=(prim_points[p0].Z+prim_points[p2].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
p03=next_prim_point;
|
|
x=(prim_points[p0].X+prim_points[p1].X+prim_points[p2].X+prim_points[p3].X)>>2;
|
|
z=(prim_points[p0].Z+prim_points[p1].Z+prim_points[p2].Z+prim_points[p3].Z)>>2;
|
|
add_point(x,y,z);
|
|
|
|
create_split_quad_into_4(p0,p01,p20,p03,wall,y); //p2,p3,p1,p0);
|
|
create_split_quad_into_4(p20,p03,p2,p32,wall,y); //p2,p3,p1,p0);
|
|
create_split_quad_into_4(p01,p1,p03,p13,wall,y); //p2,p3,p1,p0);
|
|
create_split_quad_into_4(p03,p13,p32,p3,wall,y); //p2,p3,p1,p0);
|
|
|
|
}
|
|
|
|
void create_split_quad_into_48(SLONG p0,SLONG p1,SLONG p2,SLONG p3,SLONG wall,SLONG y)
|
|
{
|
|
SLONG p01,p13,p32,p20,p03;
|
|
SLONG x,z;
|
|
struct PrimFace4 *p_f4;
|
|
|
|
|
|
p01=next_prim_point;
|
|
x=(prim_points[p1].X+prim_points[p0].X)>>1;
|
|
z=(prim_points[p1].Z+prim_points[p0].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
|
|
p13=next_prim_point;
|
|
x=(prim_points[p1].X+prim_points[p3].X)>>1;
|
|
z=(prim_points[p1].Z+prim_points[p3].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
p32=next_prim_point;
|
|
x=(prim_points[p3].X+prim_points[p2].X)>>1;
|
|
z=(prim_points[p3].Z+prim_points[p2].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
p20=next_prim_point;
|
|
x=(prim_points[p0].X+prim_points[p2].X)>>1;
|
|
z=(prim_points[p0].Z+prim_points[p2].Z)>>1;
|
|
add_point(x,y,z);
|
|
|
|
p03=next_prim_point;
|
|
x=(prim_points[p0].X+prim_points[p1].X+prim_points[p2].X+prim_points[p3].X)>>2;
|
|
z=(prim_points[p0].Z+prim_points[p1].Z+prim_points[p2].Z+prim_points[p3].Z)>>2;
|
|
add_point(x,y,z);
|
|
|
|
create_split_quad_into_16(p0,p01,p20,p03,wall,y); //p2,p3,p1,p0);
|
|
create_split_quad_into_16(p20,p03,p2,p32,wall,y); //p2,p3,p1,p0);
|
|
create_split_quad_into_16(p01,p1,p03,p13,wall,y); //p2,p3,p1,p0);
|
|
create_split_quad_into_16(p03,p13,p32,p3,wall,y); //p2,p3,p1,p0);
|
|
|
|
}
|
|
|
|
|
|
void build_roof_quad(UWORD storey,SLONG y)
|
|
{
|
|
// SLONG x1,z1,x2,z2,x3,z3;
|
|
SLONG wall;
|
|
// ,prev_wall,prev_prev_wall;
|
|
// SLONG start_point[10];
|
|
SLONG roof;
|
|
SLONG p0,p1,p2,p3;
|
|
// SLONG rx,rz;
|
|
SLONG count=0;
|
|
SLONG roof_height=0; //BLOCK_SIZE*3;
|
|
struct PrimFace4 *p_f4;
|
|
SWORD texture_style;
|
|
|
|
//build_storey_lip(storey,y);
|
|
|
|
|
|
if(storey_list[storey].WallHead && 0); //storey_list[storey].Roof)
|
|
{
|
|
SLONG area;
|
|
SLONG npp;
|
|
|
|
npp=next_prim_point;
|
|
|
|
roof=0; //storey_list[storey].Roof;
|
|
start_point[0]=next_prim_point;
|
|
wall=storey_list[roof].WallHead;
|
|
if(wall_list[wall].WallFlags&FLAG_ROOF_FLAT)
|
|
roof_height=0;
|
|
|
|
if(wall)
|
|
add_point(storey_list[roof].DX,y-roof_height,storey_list[roof].DZ);
|
|
while(wall&&count<3)
|
|
{
|
|
|
|
add_point(wall_list[wall].DX,y-roof_height,wall_list[wall].DZ);
|
|
wall=wall_list[wall].Next;
|
|
count++;
|
|
}
|
|
|
|
if(count<3)
|
|
{
|
|
//
|
|
// A quad roof has been found that has less than 4 walls
|
|
//
|
|
|
|
LogText(" storey %d is a roof quad with <4 walls\n",storey);
|
|
next_prim_point=npp;
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
wall=storey_list[roof].WallHead;
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
p0=start_point[0]+3;
|
|
p1=start_point[0]+2;
|
|
p2=start_point[0]+0;
|
|
p3=start_point[0]+1;
|
|
area=area_of_quad(p0,p1,p2,p3);
|
|
if(area>8*256*8*256)
|
|
create_split_quad_into_48(p0,p1,p2,p3,wall,y+roof_height);
|
|
else
|
|
if(area>4*256*4*256)
|
|
create_split_quad_into_16(p0,p1,p2,p3,wall,y+roof_height);
|
|
else
|
|
if(area>2*256*2*256)
|
|
create_split_quad_into_4(p0,p1,p2,p3,wall,y+roof_height);
|
|
else
|
|
{
|
|
p_f4=create_a_quad(p0,p1,p2,p3,texture_style,0); //p2,p3,p1,p0);
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
//no more flag_floor_tiles_for_quad(p0,p1,p2,p3);
|
|
p_f4->ThingIndex=-wall;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void center_object(SLONG sp,SLONG ep)
|
|
{
|
|
SLONG c0;
|
|
// ,count;
|
|
SLONG az=0,ax=0;
|
|
if(ep-sp<0)
|
|
{
|
|
LogText(" sp %d ep %d \n",sp,ep);
|
|
ERROR_MSG(0," center object has negative points");
|
|
return;
|
|
}
|
|
if((ep-sp)==0)
|
|
{
|
|
LogText("CENTER OBJECT Error sp %d ep %d \n",sp,ep);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
*/
|
|
for(c0=sp;c0<ep;c0++)
|
|
{
|
|
ax+=prim_points[c0].X;
|
|
az+=prim_points[c0].Z;
|
|
}
|
|
|
|
ax/=(ep-sp);
|
|
az/=(ep-sp);
|
|
build_x=ax;//+(64<<ELE_SHIFT);
|
|
build_z=az;//+(64<<ELE_SHIFT);
|
|
build_y=0;
|
|
|
|
/*
|
|
for(c0=sp;c0<ep;c0++)
|
|
{
|
|
prim_points[c0].X-=ax;
|
|
prim_points[c0].Z-=az;
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
}
|
|
|
|
void center_object_about_xz(SLONG sp,SLONG ep,SLONG x,SLONG z)
|
|
{
|
|
SLONG c0;
|
|
// ,count;
|
|
if(ep-sp<0)
|
|
{
|
|
LogText(" sp %d ep %d \n",sp,ep);
|
|
ERROR_MSG(0," center object has negative points");
|
|
return;
|
|
}
|
|
if((ep-sp)==0)
|
|
{
|
|
LogText("CENTER OBJECT Error sp %d ep %d \n",sp,ep);
|
|
return;
|
|
}
|
|
|
|
build_x=x;//+(64<<ELE_SHIFT);
|
|
build_z=z;//+(64<<ELE_SHIFT);
|
|
build_y=0;
|
|
/*
|
|
for(c0=sp;c0<ep;c0++)
|
|
{
|
|
prim_points[c0].X-=x;
|
|
prim_points[c0].Z-=z;
|
|
}
|
|
*/
|
|
}
|
|
|
|
|
|
|
|
SLONG build_facet(SLONG sp,SLONG mp,SLONG sf3,SLONG sf4,SLONG mf4,SLONG prev_facet,UWORD flags,UWORD col_vect)
|
|
{
|
|
struct BuildingFacet *p_obj;
|
|
p_obj=&building_facets[next_building_facet];
|
|
// LogText(" add facet %d to building %d \n",next_building_facet,next_building_object);
|
|
DebugText(" build facet sp %d mp %d ep %d sf4 %d ef4 %d\n",sp,mp,next_prim_point,sf4,next_prim_face4);
|
|
next_building_facet++;
|
|
|
|
SLONG c0;
|
|
for(c0=sf4;c0<next_prim_face4;c0++)
|
|
{
|
|
ASSERT(prim_faces4[c0].Points[0]<next_prim_point);
|
|
ASSERT(prim_faces4[c0].Points[1]<next_prim_point);
|
|
ASSERT(prim_faces4[c0].Points[2]<next_prim_point);
|
|
ASSERT(prim_faces4[c0].Points[3]<next_prim_point);
|
|
}
|
|
|
|
|
|
p_obj->StartPoint=sp;
|
|
p_obj->MidPoint=mp;
|
|
p_obj->EndPoint=next_prim_point;
|
|
|
|
ASSERT(sf4>=0);
|
|
ASSERT(sf4<=65535);
|
|
p_obj->StartFace4=sf4;
|
|
p_obj->MidFace4=mf4;
|
|
p_obj->EndFace4=next_prim_face4;
|
|
p_obj->StartFace3=sf3;
|
|
p_obj->EndFace3=next_prim_face3;
|
|
p_obj->NextFacet=prev_facet;
|
|
p_obj->FacetFlags=flags;
|
|
p_obj->ColVect=col_vect;
|
|
|
|
ASSERT(p_obj->StartFace4>=0);
|
|
ASSERT(p_obj->StartFace3>=0);
|
|
ASSERT(p_obj->EndFace4>=0);
|
|
ASSERT(p_obj->EndFace3>=0);
|
|
|
|
// center_object(p_obj);
|
|
return(next_building_facet-1);
|
|
}
|
|
|
|
SLONG build_building(SLONG sp,SLONG sf3,SLONG sf4,SLONG prev_facet)
|
|
{
|
|
struct BuildingObject *p_bobj;
|
|
p_bobj=&building_objects[next_building_object];
|
|
next_building_object++;
|
|
|
|
p_bobj->StartPoint=sp;
|
|
p_bobj->EndPoint=next_prim_point;
|
|
|
|
p_bobj->StartFace4=sf4;
|
|
p_bobj->EndFace4=next_prim_face4;
|
|
|
|
p_bobj->StartFace3=sf3;
|
|
p_bobj->EndFace3=next_prim_face3;
|
|
p_bobj->FacetHead=prev_facet;
|
|
// LogText(" center object %d->%d \n",p_bobj->StartPoint,p_bobj->EndPoint);
|
|
center_object(p_bobj->StartPoint,p_bobj->EndPoint);
|
|
#ifdef FUNNY_FANNY
|
|
p_bobj->X=build_x;
|
|
p_bobj->Y=build_y;
|
|
p_bobj->Z=build_z;
|
|
#endif
|
|
|
|
// center_object(p_bobj);
|
|
return(next_building_object-1);
|
|
}
|
|
|
|
SLONG build_building2(SLONG sp,SLONG sf3,SLONG sf4,SLONG prev_facet,SLONG cx,SLONG cz)
|
|
{
|
|
struct BuildingObject *p_bobj;
|
|
p_bobj=&building_objects[next_building_object];
|
|
next_building_object++;
|
|
|
|
p_bobj->StartPoint=sp;
|
|
p_bobj->EndPoint=next_prim_point;
|
|
|
|
p_bobj->StartFace4=sf4;
|
|
p_bobj->EndFace4=next_prim_face4;
|
|
|
|
p_bobj->StartFace3=sf3;
|
|
p_bobj->EndFace3=next_prim_face3;
|
|
p_bobj->FacetHead=prev_facet;
|
|
// LogText(" center object %d->%d \n",p_bobj->StartPoint,p_bobj->EndPoint);
|
|
center_object_about_xz(p_bobj->StartPoint,p_bobj->EndPoint,cx,cz);
|
|
|
|
// center_object(p_bobj);
|
|
return(next_building_object-1);
|
|
}
|
|
|
|
SLONG build_prim_object(SLONG sp,SLONG sf3,SLONG sf4)
|
|
{
|
|
struct PrimObject *p_obj;
|
|
p_obj=&prim_objects[next_prim_object];
|
|
next_prim_object++;
|
|
|
|
p_obj->StartPoint=sp;
|
|
p_obj->EndPoint=next_prim_point;
|
|
|
|
p_obj->StartFace4=sf4;
|
|
p_obj->EndFace4=next_prim_face4;
|
|
|
|
p_obj->StartFace3=sf3;
|
|
p_obj->EndFace3=next_prim_face3;
|
|
center_object(p_obj->StartPoint,p_obj->EndPoint);
|
|
return(next_prim_object-1);
|
|
}
|
|
|
|
|
|
void find_next_last_coord(SWORD wall,SLONG *x,SLONG *z)
|
|
{
|
|
SLONG next_wall;
|
|
LogText(" find next to last wall %d ",wall);
|
|
while(wall)
|
|
{
|
|
next_wall=wall_list[wall].Next;
|
|
// LogText(" wall %d ",wall);
|
|
if(wall_list[next_wall].Next==0)
|
|
{
|
|
// LogText(" next to last wall is %d xz (%d,%d)",wall,wall_list[wall].DX,wall_list[wall].DZ);
|
|
*x=wall_list[wall].DX;
|
|
*z=wall_list[wall].DZ;
|
|
return;
|
|
}
|
|
wall=next_wall;
|
|
}
|
|
}
|
|
|
|
struct LedgeInfo
|
|
{
|
|
SWORD Storey,Wall;
|
|
SWORD Y;
|
|
SLONG X1,Z1,X2,Z2,X3,Z3,X4,Z4;
|
|
|
|
};
|
|
|
|
|
|
void build_single_ledge(struct LedgeInfo *p_ledge)
|
|
{
|
|
|
|
SLONG sp[4],count=0;
|
|
SLONG rx,rz,rx2,rz2;
|
|
|
|
SLONG y,height;
|
|
struct PrimFace4 *p4;
|
|
|
|
// LogText(" build ledge (%d,%d) (%d,%d) (%d,%d) (%d,%d) storey %d wall %d \n",p_ledge->X1,p_ledge->Z1,p_ledge->X2,p_ledge->Z2,p_ledge->X3,p_ledge->Z3,p_ledge->X4,p_ledge->Z4,p_ledge->Storey,p_ledge->Wall);
|
|
|
|
height=BLOCK_SIZE>>1;
|
|
y=p_ledge->Y;
|
|
|
|
sp[0]=next_prim_point;
|
|
add_point(p_ledge->X2,y+2,p_ledge->Z2);
|
|
add_point(p_ledge->X3,y+2,p_ledge->Z3);
|
|
calc_new_corner_point(p_ledge->X1,p_ledge->Z1,p_ledge->X2,p_ledge->Z2,p_ledge->X3,p_ledge->Z3,BLOCK_SIZE,&rx,&rz);
|
|
calc_new_corner_point(p_ledge->X2,p_ledge->Z2,p_ledge->X3,p_ledge->Z3,p_ledge->X4,p_ledge->Z4,BLOCK_SIZE,&rx2,&rz2);
|
|
sp[1]=next_prim_point;
|
|
add_point(rx,y+2,rz);
|
|
add_point(rx2,y+2,rz2);
|
|
|
|
y+=height;
|
|
sp[2]=next_prim_point;
|
|
add_point(rx,y+2,rz);
|
|
add_point(rx2,y+2,rz2);
|
|
|
|
sp[3]=next_prim_point;
|
|
add_point(p_ledge->X2,y+2,p_ledge->Z2);
|
|
add_point(p_ledge->X3,y+2,p_ledge->Z3);
|
|
|
|
p4=create_a_quad(sp[1],sp[1]+1,sp[0],sp[0]+1,0,18);
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_LONG_LEDGE);
|
|
p4=create_a_quad(sp[2],sp[2]+1,sp[1],sp[1]+1,0,18);
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_LONG_LEDGE);
|
|
p4=create_a_quad(sp[3],sp[3]+1,sp[2],sp[2]+1,0,18);
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_LONG_LEDGE);
|
|
|
|
}
|
|
|
|
SLONG dist_between_vertex_and_vector(SLONG x1,SLONG y1,SLONG x2,SLONG y2,SLONG px,SLONG py)
|
|
{
|
|
SLONG dist,dx,dy;
|
|
|
|
x1=(x1+x2)>>1;
|
|
y1=(y1+y2)>>1;
|
|
|
|
dx=abs(x1-px);
|
|
dy=abs(y1-py);
|
|
|
|
|
|
dist=QDIST2(dx,dy);
|
|
return(dist);
|
|
|
|
}
|
|
|
|
SLONG find_wall_for_fe(SLONG fe_x,SLONG fe_y,SLONG storey)
|
|
{
|
|
SLONG wall=0;
|
|
SLONG px,pz,x1,z1;
|
|
SLONG best_wall=-1,best_dist=0x7fffffff,dist;
|
|
SLONG wall_count=0;
|
|
|
|
while(storey_list[storey].StoreyType==STOREY_TYPE_LADDER ||
|
|
storey_list[storey].StoreyType==STOREY_TYPE_FIRE_ESCAPE ||
|
|
storey_list[storey].StoreyType==STOREY_TYPE_STAIRCASE ||
|
|
storey_list[storey].StoreyType==STOREY_TYPE_FENCE_BRICK ||
|
|
storey_list[storey].StoreyType==STOREY_TYPE_FENCE_FLAT ||
|
|
storey_list[storey].StoreyType==STOREY_TYPE_OUTSIDE_DOOR ||
|
|
storey_list[storey].StoreyType==STOREY_TYPE_FENCE)
|
|
{
|
|
storey=storey_list[storey].Next;
|
|
}
|
|
if(storey==0)
|
|
LogText(" error \n");
|
|
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
if(wall==0)
|
|
LogText(" error \n");
|
|
px=storey_list[storey].DX;
|
|
pz=storey_list[storey].DZ;
|
|
while(wall)
|
|
{
|
|
x1=wall_list[wall].DX;
|
|
z1=wall_list[wall].DZ;
|
|
|
|
dist=dist_between_vertex_and_vector(px,pz,x1,z1,fe_x,fe_y);
|
|
if(dist<best_dist)
|
|
{
|
|
best_wall=wall_count;
|
|
best_dist=dist;
|
|
|
|
}
|
|
|
|
wall_count++;
|
|
wall=wall_list[wall].Next;
|
|
px=x1;
|
|
pz=z1;
|
|
}
|
|
if(best_wall==-1)
|
|
LogText(" best wall=-1\n");
|
|
return(best_wall);
|
|
|
|
}
|
|
|
|
SLONG sp_stairs[300];
|
|
void build_staircase(SLONG storey)
|
|
{
|
|
SLONG wall;
|
|
SLONG wall_count=0;
|
|
SLONG count;
|
|
SLONG step_count,step_size,step_height,len,step_y,step_pos,step_length;
|
|
SLONG row=0;
|
|
SLONG c0,c1;
|
|
SLONG y,start_y=0;
|
|
struct PrimFace4 *p4;
|
|
SLONG step_pos_old;
|
|
SLONG last;
|
|
SLONG x1,z1;
|
|
|
|
struct StairVect
|
|
{
|
|
SLONG X1,Z1,X2,Z2;
|
|
|
|
};
|
|
|
|
struct StairVect s_vects[50];
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
x1=storey_list[storey].DX;
|
|
z1=storey_list[storey].DZ;
|
|
while(wall)
|
|
{
|
|
SLONG x2,z2;
|
|
wall_count++;
|
|
x2=wall_list[wall].DX;
|
|
z2=wall_list[wall].DZ;
|
|
insert_collision_vect(x1,start_y,z1,x2,start_y,z2,STOREY_TYPE_STAIRCASE,0,-wall);
|
|
set_vect_floor_height(x1,z1,x2,z2,(start_y+build_min_y)>>ALT_SHIFT);
|
|
wall=wall_list[wall].Next;
|
|
x1=x2;
|
|
z1=z2;
|
|
}
|
|
|
|
start_y+=build_min_y;
|
|
|
|
if((wall_count<4)||(wall_count&1))
|
|
return;
|
|
|
|
count=1;
|
|
wall=storey_list[storey].WallHead;
|
|
// vects[0].X1=storey_list[storey].DX;
|
|
// vects[0].Z1=storey_list[storey].DZ;
|
|
while(wall)
|
|
{
|
|
if(count<=(wall_count>>1))
|
|
{
|
|
s_vects[count-1].X1 = wall_list[wall].DX;
|
|
s_vects[count-1].Z1 = wall_list[wall].DZ;
|
|
|
|
}
|
|
else
|
|
{
|
|
SLONG pos;
|
|
pos=(wall_count)-(count)+1;
|
|
|
|
s_vects[pos-1].X2=wall_list[wall].DX;
|
|
s_vects[pos-1].Z2=wall_list[wall].DZ;
|
|
|
|
}
|
|
|
|
count++;
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
|
|
/* We now have a load of vects to travel along */
|
|
|
|
{
|
|
SLONG dx,dz;
|
|
|
|
dx=abs(s_vects[0].X1-s_vects[0].X2);
|
|
dz=abs(s_vects[0].Z1-s_vects[0].Z2);
|
|
len=QDIST2(dx,dz);
|
|
}
|
|
|
|
if(len==0)
|
|
return;
|
|
|
|
step_height=BLOCK_SIZE>>1;
|
|
step_length=BLOCK_SIZE>>1;
|
|
step_count=len/step_length;
|
|
if(step_count==0)
|
|
return;
|
|
step_size=(len<<8)/step_count;
|
|
step_y=storey_list[storey].DY;
|
|
|
|
step_pos=len<<8;
|
|
y=start_y;
|
|
|
|
|
|
step_pos_old=step_pos;
|
|
sp_stairs[99]=next_prim_point;
|
|
while(step_pos>=0)
|
|
{
|
|
SLONG x,z;
|
|
if(storey_list[storey].Info1&&step_pos<storey_list[storey].Info1*step_size)
|
|
{
|
|
step_pos=0;
|
|
}
|
|
last=(wall_count>>1)-1;
|
|
x=s_vects[0].X1+((s_vects[0].X2-s_vects[0].X1)*step_pos)/(len<<8);
|
|
z=s_vects[0].Z1+((s_vects[0].Z2-s_vects[0].Z1)*step_pos)/(len<<8);
|
|
add_point(x,start_y,z);
|
|
x=s_vects[last].X1+((s_vects[last].X2-s_vects[last].X1)*step_pos)/(len<<8);
|
|
z=s_vects[last].Z1+((s_vects[last].Z2-s_vects[last].Z1)*step_pos)/(len<<8);
|
|
add_point(x,start_y,z);
|
|
step_pos-=step_size;
|
|
}
|
|
step_pos=step_pos_old;
|
|
|
|
|
|
while(step_pos>=0)
|
|
{
|
|
|
|
if(storey_list[storey].Info1&&step_pos<storey_list[storey].Info1*step_size)
|
|
{
|
|
step_pos=0;
|
|
/*
|
|
sp_stairs[row]=next_prim_point;
|
|
for(c0=0;c0<(wall_count>>1);c0++)
|
|
{
|
|
SLONG x,z;
|
|
|
|
x=s_vects[c0].X1;
|
|
z=s_vects[c0].Z1;
|
|
|
|
add_point(x,y,z);
|
|
}
|
|
row++;
|
|
step_pos=-1;
|
|
*/
|
|
|
|
|
|
}
|
|
// else
|
|
{
|
|
|
|
sp_stairs[row]=next_prim_point;
|
|
for(c0=0;c0<(wall_count>>1);c0++)
|
|
{
|
|
SLONG x,z;
|
|
x=s_vects[c0].X1+((s_vects[c0].X2-s_vects[c0].X1)*step_pos)/(len<<8);
|
|
z=s_vects[c0].Z1+((s_vects[c0].Z2-s_vects[c0].Z1)*step_pos)/(len<<8);
|
|
add_point(x,y,z);
|
|
}
|
|
sp_stairs[row+1]=next_prim_point;
|
|
step_pos-=step_size;
|
|
if(step_pos>=0)
|
|
{
|
|
//we dont need a riser on the last one
|
|
for(c0=sp_stairs[row];c0<sp_stairs[row]+(wall_count>>1);c0++)
|
|
{
|
|
add_point(prim_points[c0].X,y+step_height,prim_points[c0].Z);
|
|
}
|
|
|
|
y+=step_height;
|
|
row+=2;
|
|
}
|
|
else
|
|
{
|
|
|
|
y+=step_height;
|
|
row+=1;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
|
|
for(c1=0; c1<(row-1) ;c1++)
|
|
{
|
|
for(c0=0;c0 < ((wall_count>>1)-1);c0++)
|
|
{
|
|
//
|
|
// Do the risers and the steps
|
|
//
|
|
p4=create_a_quad(sp_stairs[c1+1]+1+c0,sp_stairs[c1+1]+c0,sp_stairs[c1]+1+c0,sp_stairs[c1]+c0,0,18+((c1&1)?5:0));
|
|
p4->ThingIndex=-wall;
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
// if(c1&1) //only steps are walkable
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
}
|
|
if(c1&1)
|
|
{
|
|
//
|
|
// do the sides
|
|
//
|
|
|
|
p4=create_a_quad(sp_stairs[c1],sp_stairs[c1+1],sp_stairs[99]+((c1-1)&0xfffe),sp_stairs[99]+2+((c1-1)&0xfffe),0,23);
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
p4=create_a_quad(sp_stairs[c1+1]+last,sp_stairs[c1]+last,sp_stairs[99]+3+((c1-1)&0xfffe),sp_stairs[99]+1+((c1-1)&0xfffe),0,23);
|
|
OR_SORT_LEVEL(p4->FaceFlags,SORT_LEVEL_FIRE_ESCAPE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void get_wall_start_and_end(
|
|
SLONG want_wall,
|
|
|
|
//
|
|
// These are 16-bit map coordinates...
|
|
//
|
|
|
|
SLONG *x1, SLONG *z1,
|
|
SLONG *x2, SLONG *z2)
|
|
{
|
|
SLONG wall;
|
|
|
|
FWall *p_wall;
|
|
FStorey *p_storey;
|
|
|
|
p_storey = &storey_list[wall_list[want_wall].StoreyHead];
|
|
|
|
*x1 = p_storey->DX;
|
|
*z1 = p_storey->DZ;
|
|
|
|
wall = p_storey->WallHead;
|
|
|
|
while(wall)
|
|
{
|
|
p_wall = &wall_list[wall];
|
|
|
|
*x2 = p_wall->DX;
|
|
*z2 = p_wall->DZ;
|
|
|
|
if (wall == want_wall)
|
|
{
|
|
return;
|
|
}
|
|
|
|
*x1 = *x2;
|
|
*z1 = *z2;
|
|
|
|
|
|
wall = p_wall->Next;
|
|
}
|
|
|
|
//
|
|
// The wall wasn't part of its storey!
|
|
//
|
|
|
|
ASSERT(0);
|
|
}
|
|
|
|
|
|
|
|
|
|
// THING_INDEX cable_thing,
|
|
void make_cable_taut_along( SLONG along,SLONG building,SLONG *x_middle,SLONG *y_middle,SLONG *z_middle)
|
|
{
|
|
SLONG i;
|
|
|
|
SLONG x;
|
|
SLONG y;
|
|
SLONG z;
|
|
|
|
SLONG dx;
|
|
SLONG dy;
|
|
SLONG dz;
|
|
|
|
SLONG h;
|
|
|
|
SLONG V;
|
|
SLONG v1;
|
|
SLONG v2;
|
|
|
|
SLONG L;
|
|
SLONG l1;
|
|
SLONG l2;
|
|
|
|
SLONG x1;
|
|
SLONG y1;
|
|
SLONG z1;
|
|
|
|
SLONG x2;
|
|
SLONG y2;
|
|
SLONG z2;
|
|
|
|
SLONG xm;
|
|
SLONG ym;
|
|
SLONG zm;
|
|
|
|
SLONG middle;
|
|
|
|
SLONG num_points;
|
|
|
|
SLONG pstart;
|
|
SLONG pend;
|
|
|
|
SLONG p1;
|
|
SLONG p2;
|
|
|
|
BuildingFacet *bf;
|
|
|
|
// Thing *p_thing = TO_THING(cable_thing);
|
|
|
|
//
|
|
// Make sure this is a building.
|
|
//
|
|
|
|
// ASSERT(p_thing->Class == CLASS_BUILDING);
|
|
|
|
//
|
|
// It should only have one facet.
|
|
//
|
|
|
|
bf = &building_facets[building_objects[building].FacetHead];
|
|
|
|
//
|
|
// Make sure that this facet is a cable.
|
|
//
|
|
|
|
if(!(bf->FacetFlags & FACET_FLAG_CABLE))
|
|
return;
|
|
|
|
pstart = bf->StartPoint;
|
|
pend = bf->EndPoint - 2;
|
|
|
|
x1 = prim_points[pstart].X;
|
|
y1 = prim_points[pstart].Y;
|
|
z1 = prim_points[pstart].Z;
|
|
|
|
x2 = prim_points[pend].X;
|
|
y2 = prim_points[pend].Y;
|
|
z2 = prim_points[pend].Z;
|
|
|
|
//
|
|
// Work out the length of the cable, L.
|
|
//
|
|
|
|
L = 0;
|
|
|
|
for (i = bf->StartPoint; i + 2 < bf->EndPoint; i += 2)
|
|
{
|
|
p1 = i;
|
|
p2 = i + 2;
|
|
|
|
dx = abs(prim_points[p2].X - prim_points[p1].X);
|
|
dy = abs(prim_points[p2].Y - prim_points[p1].Y);
|
|
dz = abs(prim_points[p2].Z - prim_points[p1].Z);
|
|
|
|
L += QDIST3(dx,dy,dz);
|
|
}
|
|
L-=L>>2;
|
|
|
|
ASSERT(L > 0);
|
|
|
|
//
|
|
// Straight line distance between the ends of the cable, V.
|
|
//
|
|
|
|
dx = abs(x2 - x1);
|
|
dy = abs(y2 - y1);
|
|
dz = abs(z2 - z1);
|
|
|
|
V = QDIST3(dx,dy,dz);
|
|
|
|
L=V+50;
|
|
|
|
//
|
|
// Work out v1 and v2, the lengths along the line broken up
|
|
// by where you are hanging.
|
|
//
|
|
|
|
v1 = V * along >> 8;
|
|
v2 = V - v1;
|
|
|
|
//
|
|
// Find l1, the length of the cable upto where you are
|
|
// hanging.
|
|
//
|
|
|
|
l1 = (L*L + v1*v1 - v2*v2) / (2*L);
|
|
|
|
//
|
|
// Now work out h, the distance to hang down by.
|
|
//
|
|
|
|
h = Root(l1*l1 - v1*v1);
|
|
|
|
//
|
|
// We have to move the cable points so they form a triangle shape.
|
|
//
|
|
|
|
num_points = bf->EndPoint - bf->StartPoint >> 1;
|
|
|
|
ASSERT(num_points >= 3);
|
|
|
|
//
|
|
// The bottom of the triangle shape.
|
|
//
|
|
|
|
xm = x1 + ((x2 - x1) * along >> 8);
|
|
ym = y1 + ((y2 - y1) * along >> 8);
|
|
zm = z1 + ((z2 - z1) * along >> 8);
|
|
|
|
ym -= h;
|
|
|
|
//
|
|
// The point to use as the middle point.
|
|
//
|
|
|
|
middle = num_points * along >> 8;
|
|
|
|
if (middle == 0)
|
|
{
|
|
middle = 1;
|
|
}
|
|
|
|
if (middle == num_points - 1)
|
|
{
|
|
middle -= 1;
|
|
}
|
|
|
|
dx = (xm - x1) / middle;
|
|
dy = (ym - y1) / middle;
|
|
dz = (zm - z1) / middle;
|
|
|
|
x = x1;
|
|
y = y1;
|
|
z = z1;
|
|
|
|
for (i = 0; i < num_points; i++)
|
|
{
|
|
if (i == middle)
|
|
{
|
|
//
|
|
// Recalculate (dx,dy,dz)
|
|
//
|
|
|
|
dx = (x2 - xm) / (num_points - middle - 1);
|
|
dy = (y2 - ym) / (num_points - middle - 1);
|
|
dz = (z2 - zm) / (num_points - middle - 1);
|
|
|
|
x = xm;
|
|
y = ym;
|
|
z = zm;
|
|
}
|
|
|
|
AENG_dx_prim_points[bf->StartPoint + (i * 2) + 0].X = x;
|
|
AENG_dx_prim_points[bf->StartPoint + (i * 2) + 0].Y = y;
|
|
AENG_dx_prim_points[bf->StartPoint + (i * 2) + 0].Z = z;
|
|
|
|
AENG_dx_prim_points[bf->StartPoint + (i * 2) + 1].X = x;
|
|
AENG_dx_prim_points[bf->StartPoint + (i * 2) + 1].Y = y + 8;
|
|
AENG_dx_prim_points[bf->StartPoint + (i * 2) + 1].Z = z;
|
|
|
|
x += dx;
|
|
y += dy;
|
|
z += dz;
|
|
}
|
|
|
|
*x_middle = xm;
|
|
*y_middle = ym;
|
|
*z_middle = zm;
|
|
}
|
|
|
|
void make_cable_flabby(SLONG building)
|
|
{
|
|
SLONG i;
|
|
|
|
BuildingFacet *bf = &building_facets[building_objects[building].FacetHead];
|
|
|
|
//
|
|
// Easy!
|
|
//
|
|
|
|
for (i = bf->StartPoint; i < bf->EndPoint; i++)
|
|
{
|
|
AENG_dx_prim_points[i].X = float(prim_points[i].X);
|
|
AENG_dx_prim_points[i].Y = float(prim_points[i].Y);
|
|
AENG_dx_prim_points[i].Z = float(prim_points[i].Z);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#define LIGHT_SIZE BLOCK_SIZE
|
|
#define CONE_MULT 5
|
|
SLONG create_suspended_light(SLONG x,SLONG y,SLONG z,SLONG flags)
|
|
{
|
|
SLONG p1,p2;
|
|
struct PrimFace3 *p_f3;
|
|
|
|
flags=flags;
|
|
p1=next_prim_point;
|
|
add_point(x,y,z);
|
|
add_point(x-LIGHT_SIZE,y-LIGHT_SIZE,z-LIGHT_SIZE);
|
|
add_point(x+LIGHT_SIZE,y-LIGHT_SIZE,z-LIGHT_SIZE);
|
|
add_point(x+LIGHT_SIZE,y-LIGHT_SIZE,z+LIGHT_SIZE);
|
|
add_point(x-LIGHT_SIZE,y-LIGHT_SIZE,z+LIGHT_SIZE);
|
|
|
|
|
|
/*
|
|
p2=next_prim_point-1;
|
|
add_point(x-LIGHT_SIZE*CONE_MULT,y-LIGHT_SIZE*6,z-LIGHT_SIZE*CONE_MULT);
|
|
add_point(x+LIGHT_SIZE*CONE_MULT,y-LIGHT_SIZE*6,z-LIGHT_SIZE*CONE_MULT);
|
|
add_point(x+LIGHT_SIZE*CONE_MULT,y-LIGHT_SIZE*6,z+LIGHT_SIZE*CONE_MULT);
|
|
add_point(x-LIGHT_SIZE*CONE_MULT,y-LIGHT_SIZE*6,z+LIGHT_SIZE*CONE_MULT);
|
|
*/
|
|
|
|
|
|
p_f3=create_a_tri(p1+2,p1+1,p1+0,0,0);
|
|
p_f3->DrawFlags=0; //POLY_50T;
|
|
p_f3=create_a_tri(p1+3,p1+2,p1+0,0,0);
|
|
p_f3->DrawFlags=0; //POLY_50T;
|
|
p_f3=create_a_tri(p1+4,p1+3,p1+0,0,0);
|
|
p_f3->DrawFlags=0; //POLY_50T;
|
|
p_f3=create_a_tri(p1+1,p1+4,p1+0,0,0);
|
|
p_f3->DrawFlags=0; //POLY_50T;
|
|
/*
|
|
p_f3=create_a_tri(p2+2,p2+1,p1+0,0,28);
|
|
p_f3->DrawFlags=POLY_50T;
|
|
p_f3=create_a_tri(p2+3,p2+2,p1+0,0,28);
|
|
p_f3->DrawFlags=POLY_50T;
|
|
p_f3=create_a_tri(p2+4,p2+3,p1+0,0,28);
|
|
p_f3->DrawFlags=POLY_50T;
|
|
p_f3=create_a_tri(p2+1,p2+4,p1+0,0,28);
|
|
p_f3->DrawFlags=POLY_50T;
|
|
*/
|
|
//conv apply_light_to_map(x,50,z,150);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void build_cable(SLONG x1,SLONG y1,SLONG z1,SLONG x2,SLONG y2,SLONG z2,SWORD wall,SWORD type,SLONG saggysize)
|
|
{
|
|
SLONG p1;
|
|
UWORD start_point;
|
|
UWORD start_face3,start_face4;
|
|
struct PrimFace4 *p_f4;
|
|
SLONG prim;
|
|
SLONG len,dx,dy,dz,count;
|
|
SLONG px,py,pz;
|
|
SLONG c0;
|
|
SLONG light_x,light_y,light_z;
|
|
SLONG step_angle1,step_angle2,angle;
|
|
|
|
wall=wall;
|
|
type=type;
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
dx=abs(x2-x1);
|
|
dy=abs(y2-y1);
|
|
dz=abs(z2-z1);
|
|
|
|
len=QDIST3(dx,dy,dz);
|
|
count=(len<<1)/ELE_SIZE;
|
|
dx=(x2-x1);
|
|
dy=(y2-y1);
|
|
dz=(z2-z1);
|
|
|
|
|
|
px=x1;
|
|
py=y1;
|
|
pz=z1;
|
|
add_point(px,py,pz);
|
|
add_point(px,py+8,pz);
|
|
|
|
if(dy==0)
|
|
{
|
|
step_angle1=1024/count;
|
|
step_angle2=-step_angle1;
|
|
}
|
|
else
|
|
{
|
|
SLONG c1,c2;
|
|
SLONG m;
|
|
SLONG d1,d2;
|
|
if(len==0)
|
|
len=1;
|
|
m=(abs(dy)*190)/len;
|
|
|
|
c1=128; //== 0.5 along
|
|
c2=128; //=0.5
|
|
|
|
|
|
if(dy<0)
|
|
{
|
|
|
|
//
|
|
// its going down hill so slow stepangle1 and fast step angle2
|
|
//
|
|
c1=c1+m;
|
|
c2=c2-m;
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
c1=c1-m;
|
|
c2=c2+m;
|
|
}
|
|
if(c1<0)
|
|
c1=0;
|
|
if(c1>256)
|
|
c1=256;
|
|
if(c2<0)
|
|
c2=0;
|
|
if(c2>256)
|
|
c2=256;
|
|
|
|
d1=((count*c1)>>8);
|
|
d2=((count*c2)>>8);
|
|
|
|
if(d1==0)
|
|
d1=1;
|
|
|
|
if(d2==0)
|
|
d2=1;
|
|
|
|
step_angle1=512/d1;
|
|
step_angle2=-512/d2;
|
|
|
|
}
|
|
angle=-512;
|
|
for(c0=1;c0<=count;c0++)
|
|
{
|
|
SLONG ex,ey,ez;
|
|
|
|
angle+=step_angle1;
|
|
if(angle>=-30)
|
|
{
|
|
step_angle1=step_angle2;
|
|
}
|
|
|
|
|
|
ex=x1+(c0*dx)/count;
|
|
ey=y1+(c0*dy)/count;
|
|
|
|
// angle=((c0-(count>>1))*1024)/count;
|
|
// angle=(angle+2048)&2047;
|
|
ey-=(COS((angle+2048)&2047)*saggysize)>>16;
|
|
ez=z1+(c0*dz)/count;
|
|
if(c0==(count>>1))
|
|
{
|
|
light_x=ex;
|
|
light_y=ey;
|
|
light_z=ez;
|
|
|
|
}
|
|
p1=next_prim_point;
|
|
add_point(ex,ey,ez);
|
|
add_point(ex,ey+8,ez);
|
|
p_f4=create_a_quad(p1-1,p1+1,p1-2,p1,0,0);
|
|
p_f4->DrawFlags=POLY_FLAG_DOUBLESIDED;
|
|
p_f4->Type=FACE_TYPE_CABLE;
|
|
p_f4->ThingIndex=-wall;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
p_f4->FaceFlags &= ~FACE_FLAG_WALKABLE;
|
|
|
|
px=ex;
|
|
py=ey;
|
|
pz=ez;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
void build_cable_old(SLONG x1,SLONG y1,SLONG z1,SLONG x2,SLONG y2,SLONG z2,SWORD wall,SWORD type)
|
|
{
|
|
SLONG p1;
|
|
UWORD start_point;
|
|
UWORD start_face3,start_face4;
|
|
struct PrimFace4 *p_f4;
|
|
SLONG prim;
|
|
SLONG len,dx,dy,dz,count;
|
|
SLONG px,py,pz;
|
|
SLONG c0;
|
|
SLONG light_x,light_y,light_z;
|
|
|
|
wall=wall;
|
|
type=type;
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
dx=abs(x2-x1);
|
|
dy=abs(y2-y1);
|
|
dz=abs(z2-z1);
|
|
|
|
len=QDIST3(dx,dy,dz);
|
|
count=(len<<1)/ELE_SIZE;
|
|
dx=(x2-x1);
|
|
dy=(y2-y1);
|
|
dz=(z2-z1);
|
|
|
|
|
|
px=x1;
|
|
py=y1;
|
|
pz=z1;
|
|
add_point(px,py,pz);
|
|
add_point(px,py+8,pz);
|
|
// LogText(" cable len %d count %d dx %d dy %d dz %d \n",len,count,dx,dy,dz);
|
|
|
|
for(c0=1;c0<=count;c0++)
|
|
{
|
|
SLONG ex,ey,ez;
|
|
SLONG angle;
|
|
|
|
ex=x1+(c0*dx)/count;
|
|
ey=y1+(c0*dy)/count;
|
|
|
|
angle=((c0-(count>>1))*1024)/count;
|
|
angle=(angle+2048)&2047;
|
|
ey-=COS(angle)>>9;
|
|
ez=z1+(c0*dz)/count;
|
|
if(c0==(count>>1))
|
|
{
|
|
light_x=ex;
|
|
light_y=ey;
|
|
light_z=ez;
|
|
|
|
}
|
|
p1=next_prim_point;
|
|
add_point(ex,ey,ez);
|
|
add_point(ex,ey+8,ez);
|
|
p_f4=create_a_quad(p1-1,p1+1,p1-2,p1,0,0);
|
|
p_f4->DrawFlags=POLY_FLAG_DOUBLESIDED;
|
|
p_f4->Type=FACE_TYPE_CABLE;
|
|
p_f4->ThingIndex=-wall;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
|
|
px=ex;
|
|
py=ey;
|
|
pz=ez;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if(px&1)
|
|
// create_suspended_light(light_x,light_y,light_z,1);
|
|
|
|
/*
|
|
p1=next_prim_point;
|
|
add_point(x1,y1,z1);
|
|
add_point(x2,y2,z2);
|
|
add_point(x1,y1-10,z1);
|
|
add_point(x2,y2-10,z2);
|
|
|
|
p_f4=create_a_quad(p1+2,p1+3,p1,p1+1,0,0);
|
|
|
|
p_f4->DrawFlags|= POLY_FLAG_DOUBLESIDED;
|
|
*/
|
|
//prim=build_prim_object(start_point,start_face3,start_face4);
|
|
|
|
//place_prim_at(prim,build_x,0,build_z);
|
|
|
|
}
|
|
|
|
SLONG build_cables(SWORD storey,SLONG prev_facet)
|
|
{
|
|
SLONG wall;
|
|
SLONG x1,y1,z1,x2,y2,z2;
|
|
SLONG start_point,start_face3,start_face4;
|
|
SLONG prim;
|
|
SLONG building;
|
|
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
x1=storey_list[storey].DX;
|
|
y1=storey_list[storey].DY;
|
|
|
|
// y1=BLOCK_SIZE*8;
|
|
z1=storey_list[storey].DZ;
|
|
y1+=PAP_calc_height_at(x1,z1);
|
|
// if(y1==0)
|
|
// y1=BLOCK_SIZE*8;
|
|
while(wall)
|
|
{
|
|
|
|
x2=wall_list[wall].DX;
|
|
y2=wall_list[wall].DY;
|
|
z2=wall_list[wall].DZ;
|
|
y2+=PAP_calc_height_at(x2,z2);
|
|
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
build_cable(x1,y1,z1,x2,y2,z2,wall,0,wall_list[wall].TextureStyle2*64);
|
|
#ifdef PSX
|
|
// printf(" build cable\n");
|
|
#endif
|
|
prev_facet=build_facet(start_point,next_prim_point,start_face3,start_face4,next_prim_face4,0,FACET_FLAG_CABLE,0);
|
|
|
|
// prim=build_building(start_point,start_face3,start_face4,prev_facet);
|
|
prim=build_building2(start_point,start_face3,start_face4,prev_facet,storey_list[storey].DX,storey_list[storey].DZ);
|
|
building=storey_list[storey].BuildingHead;
|
|
|
|
|
|
/*
|
|
|
|
//
|
|
// Buildings dont have an (x,y,z) anymore... they have a thing index instead.
|
|
//
|
|
|
|
building_list[building].X=build_x;
|
|
building_list[building].Y=0; //y1;
|
|
building_list[building].Z=build_z;
|
|
|
|
*/
|
|
|
|
storey_list[storey].Info1=prim;
|
|
// LogText(" cable wall %d storey %d building %d xz %d %d \n",wall,storey,building,build_x,build_z);
|
|
THING_INDEX new_thing = place_building_at(building,prim,build_x,0,build_z);
|
|
insert_collision_vect(x1,y1+5000,z1,x2,y2+5000,z2,STOREY_TYPE_CABLE,1,new_thing);
|
|
|
|
if (new_thing)
|
|
{
|
|
TO_THING(new_thing)->Flags |= FLAGS_CABLE_BUILDING;
|
|
}
|
|
|
|
wall=wall_list[wall].Next;
|
|
|
|
x1=x2;
|
|
y1=y2;
|
|
z1=z2;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
void build_fence_points_and_faces(SLONG y1,SLONG y2,SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG wall,UBYTE posts)
|
|
{
|
|
SLONG wcount,wwidth,dx,dz,dist;
|
|
SLONG start_point;
|
|
SLONG texture,texture_style;
|
|
struct PrimFace4 *p_f4;
|
|
SLONG px,pz;
|
|
SLONG ya,yb;
|
|
|
|
ya=PAP_calc_height_at(x1,z1);
|
|
yb=PAP_calc_height_at(x2,z2);
|
|
|
|
insert_collision_vect(x1,ya,z1,x2,yb,z2,STOREY_TYPE_FENCE,4,-wall);
|
|
insert_collision_vect(x2,yb,z2,x1,ya,z1,STOREY_TYPE_FENCE,4,-wall);
|
|
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
|
|
start_point=next_prim_point;
|
|
|
|
dx=abs(x2-x1);
|
|
dz=abs(z2-z1);
|
|
|
|
dist=Root(SDIST2(dx,dz));
|
|
if(dist==0)
|
|
return;
|
|
|
|
wcount=(dist/(BLOCK_SIZE*4));
|
|
if(wcount==0)
|
|
wcount=1;
|
|
wwidth=dist/(wcount);
|
|
|
|
dx=(x2-x1);
|
|
dz=(z2-z1);
|
|
|
|
|
|
dx=(dx<<10)/dist;
|
|
dz=(dz<<10)/dist;
|
|
|
|
px=((dz*(10))>>10);
|
|
pz=-((dx*(10))>>10);
|
|
|
|
while(wcount)
|
|
{
|
|
SLONG p,p1,p2;
|
|
SLONG floor_1,floor_2;
|
|
p=next_prim_point;
|
|
|
|
|
|
floor_1=PAP_calc_height_at(x1,z1);
|
|
|
|
add_point(x1,y2+floor_1,z1);
|
|
add_point(x1,y1+floor_1,z1);
|
|
|
|
add_point(x1+px*5,y2+45+floor_1,z1+pz*5);
|
|
add_point(x1+px*1,y2+10+floor_1,z1+pz*1);
|
|
|
|
|
|
x1=x1+((dx*(wwidth-20))>>10);
|
|
z1=z1+((dz*(wwidth-20))>>10);
|
|
floor_2=PAP_calc_height_at(x1,z1);
|
|
|
|
p1=next_prim_point;
|
|
|
|
add_point(x1,y2+floor_2,z1);
|
|
add_point(x1,y1+floor_2,z1);
|
|
|
|
add_point(x1+px*4,y2+45+floor_2,z1+pz*4);
|
|
add_point(x1+px*1,y2+10+floor_2,z1+pz*1);
|
|
|
|
p_f4=create_a_quad(p,p1+0,p+1,p1+1,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4->DrawFlags|=(POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED);
|
|
|
|
p_f4=create_a_quad(p+2,p1+2,p+3,p1+3,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4->DrawFlags|=(POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED);
|
|
|
|
#ifndef PSX
|
|
p=next_prim_point;
|
|
add_point(x1+px,y2+floor_2,z1+pz);
|
|
add_point(x1+px,y1+floor_2,z1+pz);
|
|
add_point(x1-px,y2+floor_2,z1-pz);
|
|
add_point(x1-px,y1+floor_2,z1-pz);
|
|
|
|
add_point(x1+px*6,y2+50+floor_2,z1+pz*6);
|
|
add_point(x1+px*4,y2+50+floor_2,z1+pz*4);
|
|
|
|
x1=x1+((dx*(20))>>10);
|
|
z1=z1+((dz*(20))>>10);
|
|
|
|
p1=next_prim_point;
|
|
add_point(x1+px,y2+floor_2,z1+pz);
|
|
add_point(x1+px,y1+floor_2,z1+pz);
|
|
add_point(x1-px,y2+floor_2,z1-pz);
|
|
add_point(x1-px,y1+floor_2,z1-pz);
|
|
|
|
add_point(x1+px*6,y2+50+floor_2,z1+pz*6);
|
|
add_point(x1+px*4,y2+50+floor_2,z1+pz*4);
|
|
|
|
p_f4=create_a_quad(p,p1,p+1,p1+1,texture_style,TEXTURE_PIECE_LEFT);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(p1+2,p+2,p1+3,p+3,texture_style,TEXTURE_PIECE_LEFT);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(p+2,p+0,p+3,p+1,texture_style,TEXTURE_PIECE_LEFT);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(p1,p1+2,p1+1,p1+3,texture_style,TEXTURE_PIECE_LEFT);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
|
|
p_f4=create_a_quad(p+4,p1+4,p,p1,texture_style,TEXTURE_PIECE_LEFT);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(p1+5,p+5,p1+2,p+2,texture_style,TEXTURE_PIECE_LEFT);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(p1+4,p1+5,p1,p1+2,texture_style,TEXTURE_PIECE_LEFT);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(p+5,p+4,p+2,p,texture_style,TEXTURE_PIECE_LEFT);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(p+4,p+5,p1+4,p1+5,texture_style,TEXTURE_PIECE_LEFT);
|
|
p_f4->ThingIndex=-wall;
|
|
#endif
|
|
// p_f4=create_a_quad(p+0,p+2,p1,p1+2,texture_style,TEXTURE_PIECE_LEFT);
|
|
// p_f4->ThingIndex=-wall;
|
|
|
|
|
|
wcount--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void build_high_chain_fence(SLONG x,SLONG y,SLONG z,SLONG wall,SLONG storey,SLONG height,UBYTE alt_mode)
|
|
{
|
|
SLONG c0;
|
|
SLONG sp[10];
|
|
// SLONG sf4[10];
|
|
SLONG texture,texture_style;
|
|
struct PrimFace4 *p_f4;
|
|
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
if(texture_style==0)
|
|
texture_style=1;
|
|
|
|
if(alt_mode==1)
|
|
{
|
|
sp[0]=build_row_wall_only_points_at_floor_alt(height*2 ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
sp[1]=build_row_wall_only_points_at_floor_alt(height ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
sp[2]=build_row_wall_only_points_at_floor_alt(0 ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
}
|
|
else
|
|
{
|
|
sp[0]=build_row_wall_only_points_at_y(y+height*2 ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
sp[1]=build_row_wall_only_points_at_y(y+height ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
sp[2]=build_row_wall_only_points_at_y(y ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
}
|
|
|
|
for(c0=0;c0<WindowCount;c0++)
|
|
{
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
if(c0==0)
|
|
{
|
|
texture=TEXTURE_PIECE_RIGHT;
|
|
}
|
|
else
|
|
if(c0==WindowCount-1)
|
|
{
|
|
texture=TEXTURE_PIECE_LEFT;
|
|
}
|
|
else
|
|
{
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
}
|
|
|
|
p_f4=create_a_quad(sp[0]+c0,sp[0]+c0+1,sp[1]+c0,sp[1]+c0+1,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4->DrawFlags|=(POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED);
|
|
p_f4->Type=FACE_TYPE_FENCE;
|
|
|
|
p_f4=create_a_quad(sp[1]+c0,sp[1]+c0+1,sp[2]+c0,sp[2]+c0+1,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4->DrawFlags|=(POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED);
|
|
p_f4->Type=FACE_TYPE_FENCE;
|
|
}
|
|
{
|
|
SLONG ya,yb;
|
|
ya=PAP_calc_height_at(x,z);
|
|
yb=PAP_calc_height_at(wall_list[wall].DX,wall_list[wall].DZ);
|
|
insert_collision_vect(x,ya,z,wall_list[wall].DX,yb,wall_list[wall].DZ,STOREY_TYPE_FENCE_FLAT,8,-wall);
|
|
insert_collision_vect(wall_list[wall].DX,yb,wall_list[wall].DZ,x,ya,z,STOREY_TYPE_FENCE_FLAT,8,-wall);
|
|
}
|
|
}
|
|
|
|
void build_height_fence(SLONG x,SLONG y,SLONG z,SLONG wall,SLONG storey,SLONG height,SLONG alt_mode)
|
|
{
|
|
SLONG c0;
|
|
SLONG sp[10];
|
|
SLONG texture,texture_style;
|
|
struct PrimFace4 *p_f4;
|
|
UBYTE *ptexture1;
|
|
SLONG tcount1;
|
|
UBYTE *ptexture2;
|
|
SLONG tcount2;
|
|
SLONG count;
|
|
|
|
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
if(texture_style==0)
|
|
texture_style=1;
|
|
|
|
ptexture1=wall_list[wall].Textures;
|
|
tcount1=wall_list[wall].Tcount;
|
|
|
|
ptexture2=wall_list[wall].Textures2;
|
|
tcount2=wall_list[wall].Tcount2;
|
|
|
|
|
|
if(alt_mode==1)
|
|
{
|
|
sp[0]=build_row_wall_only_points_at_floor_alt(height ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
sp[1]=build_row_wall_only_points_at_floor_alt(0 ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
}
|
|
else
|
|
{
|
|
sp[0]=build_row_wall_only_points_at_y(y+height ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
sp[1]=build_row_wall_only_points_at_y(y ,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall);
|
|
}
|
|
|
|
count=0;
|
|
for(c0=0;c0<WindowCount;c0++)
|
|
{
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
if(c0==0)
|
|
{
|
|
texture=TEXTURE_PIECE_RIGHT;
|
|
}
|
|
else
|
|
if(c0==WindowCount-1)
|
|
{
|
|
texture=TEXTURE_PIECE_LEFT;
|
|
}
|
|
else
|
|
{
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
}
|
|
if(ptexture1 && (count<tcount1) && ptexture1[count])
|
|
{
|
|
p_f4=create_a_quad_tex(sp[0]+c0,sp[0]+c0+1,sp[1]+c0,sp[1]+c0+1,ptexture1[count]);
|
|
|
|
}
|
|
else
|
|
{
|
|
p_f4=create_a_quad(sp[0]+c0,sp[0]+c0+1,sp[1]+c0,sp[1]+c0+1,texture_style,texture);
|
|
}
|
|
p_f4->ThingIndex=-wall;
|
|
p_f4->DrawFlags|=(POLY_FLAG_DOUBLESIDED|POLY_FLAG_MASKED);
|
|
p_f4->Type=FACE_TYPE_FENCE;
|
|
count++;
|
|
|
|
}
|
|
{
|
|
SLONG ya,yb;
|
|
ya=PAP_calc_height_at(x,z);
|
|
yb=PAP_calc_height_at(wall_list[wall].DX,wall_list[wall].DZ);
|
|
insert_collision_vect(x,ya,z,wall_list[wall].DX,yb,wall_list[wall].DZ,STOREY_TYPE_FENCE_FLAT,height/64,-wall);
|
|
insert_collision_vect(wall_list[wall].DX,yb,wall_list[wall].DZ,x,ya,z,STOREY_TYPE_FENCE_FLAT,height/64,-wall);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// p1 ..
|
|
// ..p2
|
|
// .
|
|
// .
|
|
// .p3
|
|
//
|
|
|
|
/*
|
|
SLONG find_previous_wall(SLONG storey,SLONG wall)
|
|
{
|
|
SLONG w,next;
|
|
w=storey_list[storey].WallHead;
|
|
if(w==wall)
|
|
return(0);
|
|
while(w)
|
|
{
|
|
next=wall_list[w].Next;
|
|
if(next==wall)
|
|
return(w);
|
|
w=next;
|
|
}
|
|
return(0);
|
|
}
|
|
*/
|
|
|
|
|
|
#define WALL_WIDTH (60)
|
|
|
|
void build_thick_wall_polys(SLONG *x,SLONG *z,SLONG y,SLONG height,SLONG flag,SLONG storey,SLONG wall)
|
|
{
|
|
SLONG sp[8];
|
|
SLONG c0;
|
|
struct PrimFace4 *p_f4;
|
|
SLONG texture,texture_style;
|
|
|
|
insert_collision_vect(x[1],y,z[1],x[0],y,z[0],STOREY_TYPE_NORMAL,1,-wall);
|
|
insert_collision_vect(x[2],y,z[2],x[3],y,z[3],STOREY_TYPE_NORMAL,1,-wall);
|
|
|
|
|
|
texture_style=wall_list[wall].TextureStyle;
|
|
if(texture_style==0)
|
|
texture_style=1;
|
|
|
|
sp[0]=build_row_wall_only_points_at_y(y+height ,x[0],z[0],x[1],z[1],wall);
|
|
sp[1]=build_row_wall_only_points_at_y(y ,x[0],z[0],x[1],z[1],wall);
|
|
|
|
sp[2]=build_row_wall_only_points_at_y(y+height ,x[2],z[2],x[3],z[3],wall);
|
|
sp[3]=build_row_wall_only_points_at_y(y ,x[2],z[2],x[3],z[3],wall);
|
|
sp[4]=next_prim_point;
|
|
|
|
for(c0=0;c0<WindowCount;c0++)
|
|
{
|
|
|
|
texture=TEXTURE_PIECE_MIDDLE;
|
|
p_f4=create_a_quad(sp[0]+c0+1,sp[0]+c0,sp[1]+c0+1,sp[1]+c0,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(sp[2]+c0,sp[2]+c0+1,sp[3]+c0,sp[3]+c0+1,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
|
|
p_f4=create_a_quad(sp[0]+c0,sp[0]+c0+1,sp[2]+c0,sp[2]+c0+1,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
add_quad_to_walkable_list(next_prim_face4-1);
|
|
|
|
}
|
|
if(flag==1)
|
|
{
|
|
p_f4=create_a_quad(sp[0],sp[2],sp[1],sp[3],texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
insert_collision_vect(x[0],y,z[0],x[2],y,z[2],STOREY_TYPE_FENCE_BRICK,4,-wall);
|
|
|
|
}
|
|
if(flag==2)
|
|
{
|
|
p_f4=create_a_quad(sp[3]-1,sp[1]-1,sp[4]-1,sp[2]-1,texture_style,texture);
|
|
p_f4->ThingIndex=-wall;
|
|
insert_collision_vect(x[1],y,z[1],x[3],y,z[3],STOREY_TYPE_FENCE_BRICK,4,-wall);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 2 3
|
|
//
|
|
// 0 1
|
|
SLONG build_brick_wall(SLONG storey)
|
|
{
|
|
SLONG x[4],z[4];
|
|
SLONG wall,nwall;
|
|
SLONG dx,dz,len;
|
|
SLONG y,height;
|
|
SLONG start_point,start_face3,start_face4;
|
|
SLONG prev_facet;
|
|
SLONG prim;
|
|
SLONG building;
|
|
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
y = storey_list[storey].DY;
|
|
height = storey_list[storey].Height;
|
|
|
|
x[0]=storey_list[storey].DX;
|
|
z[0]=storey_list[storey].DZ;
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
nwall=wall_list[wall].Next;
|
|
|
|
x[1]=wall_list[wall].DX;
|
|
z[1]=wall_list[wall].DZ;
|
|
|
|
dz=-(x[1]-x[0]);
|
|
dx=(z[1]-z[0]);
|
|
|
|
len=Root(dx*dx+dz*dz);
|
|
if(len==0)
|
|
len=1;
|
|
|
|
dx=(dx*WALL_WIDTH)/len;
|
|
dz=(dz*WALL_WIDTH)/len;
|
|
|
|
x[2]=x[0]+dx;
|
|
z[2]=z[0]+dz;
|
|
|
|
calc_new_corner_point(x[0],z[0],x[1],z[1],wall_list[nwall].DX,wall_list[nwall].DZ,WALL_WIDTH,&x[3],&z[3]);
|
|
|
|
build_thick_wall_polys(&x[0],&z[0],y,height,1,storey,wall);
|
|
wall=nwall;
|
|
nwall=wall_list[wall].Next;
|
|
|
|
while(wall&&nwall)
|
|
{
|
|
x[0]=x[1];
|
|
x[2]=x[3];
|
|
z[0]=z[1];
|
|
z[2]=z[3];
|
|
|
|
x[1]=wall_list[wall].DX;
|
|
z[1]=wall_list[wall].DZ;
|
|
|
|
|
|
calc_new_corner_point(x[0],z[0],x[1],z[1],wall_list[nwall].DX,wall_list[nwall].DZ,WALL_WIDTH,&x[3],&z[3]);
|
|
|
|
build_thick_wall_polys(&x[0],&z[0],y,height,0,storey,wall);
|
|
wall=nwall;
|
|
nwall=wall_list[wall].Next;
|
|
}
|
|
|
|
//
|
|
// last bit
|
|
//
|
|
x[0]=x[1];
|
|
x[2]=x[3];
|
|
z[0]=z[1];
|
|
z[2]=z[3];
|
|
|
|
x[1]=wall_list[wall].DX;
|
|
z[1]=wall_list[wall].DZ;
|
|
dz=-(x[1]-x[0]);
|
|
dx=(z[1]-z[0]);
|
|
|
|
len=Root(dx*dx+dz*dz);
|
|
if(len==0)
|
|
len=1;
|
|
|
|
dx=(dx*WALL_WIDTH)/len;
|
|
dz=(dz*WALL_WIDTH)/len;
|
|
|
|
x[3]=x[1]+dx;
|
|
z[3]=z[1]+dz;
|
|
build_thick_wall_polys(&x[0],&z[0],y,height,2,storey,wall);
|
|
|
|
|
|
#ifdef PSX
|
|
// printf(" build brick wall\n");
|
|
#endif
|
|
|
|
prev_facet=build_facet(start_point,next_prim_point,start_face3,start_face4,next_prim_face4,0,FACET_FLAG_NON_SORT,0);
|
|
|
|
prim=build_building(start_point,start_face3,start_face4,prev_facet);
|
|
building=storey_list[storey].BuildingHead;
|
|
|
|
/*
|
|
|
|
//
|
|
// No (x,y,z), buildings have a ThingIndex instead... it is
|
|
// set in place_building_at()
|
|
//
|
|
|
|
building_list[building].X=build_x;
|
|
building_list[building].Y=y;
|
|
building_list[building].Z=build_z;
|
|
|
|
*/
|
|
|
|
place_building_at(building,prim,build_x,0,build_z);
|
|
|
|
return(prev_facet);
|
|
}
|
|
|
|
void build_fence(SLONG x,SLONG y,SLONG z,SLONG wall,SLONG storey,SLONG height)
|
|
{
|
|
SLONG alt_mode = 1; // Stick to floor by default.
|
|
|
|
if (storey_list[storey].ExtraFlags & FLAG_STOREY_EXTRA_ONBUILDING)
|
|
{
|
|
//
|
|
// Dont stick on the floor.
|
|
//
|
|
|
|
alt_mode = 0;
|
|
}
|
|
|
|
switch(storey_list[storey].StoreyType)
|
|
{
|
|
case STOREY_TYPE_FENCE: // 3/4
|
|
build_fence_points_and_faces(y,y+((height*3)>>2)+2,x,z,wall_list[wall].DX,wall_list[wall].DZ,wall,1);
|
|
break;
|
|
case STOREY_TYPE_FENCE_BRICK:
|
|
build_height_fence(x,y,z,wall,storey,height,alt_mode);
|
|
break;
|
|
case STOREY_TYPE_FENCE_FLAT:
|
|
case STOREY_TYPE_OUTSIDE_DOOR:
|
|
if(height==512)
|
|
build_high_chain_fence(x,y,z,wall,storey,BLOCK_SIZE*4,alt_mode);
|
|
else
|
|
build_height_fence(x,y,z,wall,storey,height,alt_mode);
|
|
break;
|
|
|
|
}
|
|
WindowCount=0;
|
|
}
|
|
|
|
/*
|
|
Go Through fence building all the pieces and slap them into a single facet
|
|
the facet being a special one that sorts normally
|
|
*/
|
|
|
|
SLONG build_whole_fence(SLONG storey)
|
|
{
|
|
SLONG wall,px,pz;
|
|
SLONG height,y;
|
|
UWORD start_point_123=99,start_face3_123=99,start_face4_123=99;
|
|
SLONG prev_facet;
|
|
SLONG prim;
|
|
SLONG building;
|
|
SLONG start_point,start_face3,start_face4;
|
|
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
height=storey_list[storey].Height;
|
|
y=storey_list[storey].DY;
|
|
// y+=build_min_y;
|
|
|
|
px=storey_list[storey].DX;
|
|
pz=storey_list[storey].DZ;
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
while(wall)
|
|
{
|
|
build_fence(px,y,pz,wall,storey,height);
|
|
px=wall_list[wall].DX;
|
|
pz=wall_list[wall].DZ;
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
|
|
prev_facet=build_facet(start_point,next_prim_point,start_face3,start_face4,next_prim_face4,0,FACET_FLAG_NON_SORT,0);
|
|
|
|
prim=build_building(start_point,start_face3,start_face4,prev_facet);
|
|
building=storey_list[storey].BuildingHead;
|
|
|
|
|
|
/*
|
|
|
|
//
|
|
// No (x,y,z), buildings have a ThingIndex instead... it is
|
|
// set in place_building_at()
|
|
//
|
|
|
|
building_list[building].X=build_x;
|
|
building_list[building].Y=y;
|
|
building_list[building].Z=build_z;
|
|
|
|
*/
|
|
|
|
place_building_at(building,prim,build_x,0,build_z);
|
|
return(prev_facet);
|
|
}
|
|
|
|
SLONG process_external_pieces(UWORD building)
|
|
{
|
|
SLONG storey,c0=0;
|
|
SLONG prev_facet=0;
|
|
|
|
storey=building_list[building].StoreyHead;
|
|
LogText(" storey type START %d \n",storey_list[storey].StoreyType);
|
|
while(storey&&c0<400)
|
|
{
|
|
switch(storey_list[storey].StoreyType)
|
|
{
|
|
case STOREY_TYPE_CABLE:
|
|
prev_facet=build_cables(storey,prev_facet);
|
|
break;
|
|
case STOREY_TYPE_FENCE:
|
|
case STOREY_TYPE_FENCE_FLAT:
|
|
case STOREY_TYPE_OUTSIDE_DOOR:
|
|
if(storey_list[storey].DY==0)
|
|
prev_facet=build_whole_fence(storey);
|
|
LogText(" storey type1 %d facet %d\n",storey_list[storey].StoreyType,prev_facet);
|
|
break;
|
|
case STOREY_TYPE_FENCE_BRICK:
|
|
if(storey_list[storey].DY==0)
|
|
prev_facet=build_whole_fence(storey);
|
|
// prev_facet=build_brick_wall(storey);
|
|
LogText(" storey type2 %d \n",storey_list[storey].StoreyType);
|
|
break;
|
|
case STOREY_TYPE_NORMAL:
|
|
if(storey_list[storey].DY==0)
|
|
{
|
|
SLONG wall;
|
|
SLONG x,y,z;
|
|
wall=storey_list[storey].WallHead;
|
|
x=storey_list[storey].DX;
|
|
z=storey_list[storey].DZ;
|
|
y=PAP_calc_height_at(x,z);
|
|
if(y<build_min_y)
|
|
build_min_y=y;
|
|
|
|
if(y>build_max_y)
|
|
build_max_y=y;
|
|
|
|
while(wall)
|
|
{
|
|
x=wall_list[wall].DX;
|
|
z=wall_list[wall].DZ;
|
|
y=PAP_calc_height_at(x,z);
|
|
if(y<build_min_y)
|
|
build_min_y=y;
|
|
if(y>build_max_y)
|
|
build_max_y=y;
|
|
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
storey=storey_list[storey].Next;
|
|
c0++;
|
|
}
|
|
if(build_max_y!=build_min_y)
|
|
{
|
|
build_max_y+=(ELE_SIZE>>2)-1;
|
|
build_max_y&=~63;
|
|
}
|
|
|
|
// LogText(" fence facet %d \n",prev_facet);
|
|
return(prev_facet);
|
|
}
|
|
|
|
/* //pre store face wall/storey links
|
|
struct StoreyLink
|
|
{
|
|
SWORD Face; //storey or wall
|
|
UWORD Link;
|
|
};
|
|
|
|
struct StoreyLink storey_link_pool[2000];
|
|
UWORD next_storey_link=1;
|
|
|
|
UWORD storey_heads[100];
|
|
|
|
|
|
void build_link_table(UWORD building)
|
|
{
|
|
UWORD storey;
|
|
|
|
next_storey_link=1;
|
|
|
|
storey=building_list[building].StoreyHead;
|
|
while(storey)
|
|
{
|
|
switch(storey_list[storey].StoreyType)
|
|
{
|
|
case STOREY_TYPE_NORMAL:
|
|
wall=storey_list[storey].WallHead;
|
|
while(wall)
|
|
{
|
|
find_
|
|
}
|
|
|
|
break;
|
|
}
|
|
storey=storey_list[storey].Next;
|
|
}
|
|
}
|
|
*/
|
|
|
|
void mark_map_with_ladder(SLONG storey)
|
|
{
|
|
SLONG x1,z1,x2,z2;
|
|
SLONG dx,dz;
|
|
SLONG wall;
|
|
|
|
x1=storey_list[storey].DX;
|
|
z1=storey_list[storey].DZ;
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
|
|
x2=wall_list[wall].DX;
|
|
z2=wall_list[wall].DZ;
|
|
|
|
dx=x2-x1;
|
|
dz=z2-z1;
|
|
|
|
|
|
x1+=dx/3;
|
|
z1+=dz/3;
|
|
|
|
x1+=dz>>3;
|
|
z1-=dx>>3;
|
|
|
|
set_map_flag(x1>>ELE_SHIFT,z1>>ELE_SHIFT,FLOOR_LADDER);
|
|
|
|
}
|
|
|
|
void setup_storey_data(UWORD building,SWORD *wall_for_ladder)
|
|
{
|
|
SLONG wall,storey;
|
|
|
|
storey=building_list[building].StoreyHead;
|
|
while(storey)
|
|
{
|
|
storey_list[storey].StoreyFlags&=~FLAG_STOREY_FACET_LINKED;
|
|
|
|
switch(storey_list[storey].StoreyType)
|
|
{
|
|
case STOREY_TYPE_NORMAL:
|
|
case STOREY_TYPE_FENCE:
|
|
case STOREY_TYPE_FENCE_FLAT:
|
|
case STOREY_TYPE_FENCE_BRICK:
|
|
case STOREY_TYPE_OUTSIDE_DOOR:
|
|
wall=storey_list[storey].WallHead;
|
|
while(wall)
|
|
{
|
|
wall_list[wall].WallFlags&=~FLAG_WALL_FACET_LINKED;
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
|
|
break;
|
|
case STOREY_TYPE_LADDER:
|
|
|
|
wall=find_wall_for_fe(storey_list[storey].DX,storey_list[storey].DZ,building_list[building].StoreyHead);
|
|
if(wall>=0)
|
|
wall_for_ladder[wall]=storey;
|
|
mark_map_with_ladder(storey);
|
|
break;
|
|
}
|
|
storey=storey_list[storey].Next;
|
|
}
|
|
|
|
}
|
|
|
|
SLONG find_connect_wall(SLONG x1,SLONG z1,SLONG x2,SLONG z2,SLONG *connect_storey,SLONG storey,UBYTE **ret_tex,UWORD *ret_tcount)
|
|
{
|
|
SLONG found=0;
|
|
SLONG wall;
|
|
SLONG fx1,fz1,fx2,fz2;
|
|
|
|
storey=storey_list[storey].Next;
|
|
|
|
while(storey&&!found)
|
|
{
|
|
switch(storey_list[storey].StoreyType)
|
|
{
|
|
case STOREY_TYPE_NORMAL:
|
|
// case STOREY_TYPE_FENCE:
|
|
// case STOREY_TYPE_FENCE_BRICK:
|
|
// case STOREY_TYPE_FENCE_FLAT:
|
|
found=1;
|
|
break;
|
|
default:
|
|
storey=storey_list[storey].Next;
|
|
}
|
|
}
|
|
if(found)
|
|
{
|
|
fx1=storey_list[storey].DX;
|
|
fz1=storey_list[storey].DZ;
|
|
wall=storey_list[storey].WallHead;
|
|
|
|
while(wall)
|
|
{
|
|
fx2=wall_list[wall].DX;
|
|
fz2=wall_list[wall].DZ;
|
|
if(fx1==x1&&fz1==z1&&fx2==x2&&fz2==z2)
|
|
{
|
|
*connect_storey=storey;
|
|
*ret_tex=wall_list[wall].Textures;
|
|
*ret_tcount=wall_list[wall].Tcount;
|
|
return(wall);
|
|
}
|
|
fx1=fx2;
|
|
fz1=fz2;
|
|
|
|
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
}
|
|
else
|
|
return(0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
//
|
|
// Add colvects around the recess...
|
|
//
|
|
|
|
void insert_recessed_wall_vect(
|
|
SLONG x1, SLONG y1, SLONG z1,
|
|
SLONG x2, SLONG y2, SLONG z2,
|
|
UBYTE storey_type,
|
|
UBYTE height,
|
|
SLONG wall)
|
|
{
|
|
SLONG x1o;
|
|
SLONG z1o;
|
|
|
|
SLONG x2o;
|
|
SLONG z2o;
|
|
|
|
SLONG dx;
|
|
SLONG dz;
|
|
|
|
SLONG len;
|
|
|
|
dx = x2 - x1;
|
|
dz = z2 - z1;
|
|
|
|
len = Root(dx*dx + dz*dz);
|
|
|
|
if (len == 0)
|
|
{
|
|
len = 1;
|
|
}
|
|
|
|
dx = (dx * RECESS_SIZE) / len;
|
|
dz = (dz * RECESS_SIZE) / len;
|
|
|
|
x1o = x1 + dz + (dx >> 1);
|
|
z1o = z1 - dx + (dz >> 1);
|
|
|
|
x2o = x2 + dz - (dx >> 1);
|
|
z2o = z2 - dx - (dz >> 1);
|
|
|
|
insert_collision_vect(
|
|
x1, y1, z1,
|
|
x2, y2, z2,
|
|
storey_type,
|
|
height*4,
|
|
wall);
|
|
|
|
insert_collision_vect(
|
|
x1, y1, z1,
|
|
x1o, y1, z1o,
|
|
storey_type,
|
|
height*4,
|
|
wall);
|
|
|
|
insert_collision_vect(
|
|
x1o, y1, z1o,
|
|
x2o, y2, z2o,
|
|
storey_type,
|
|
height*4,
|
|
wall);
|
|
|
|
insert_collision_vect(
|
|
x2o, y2, z2o,
|
|
x2, y2, z2,
|
|
storey_type,
|
|
height*4,
|
|
wall);
|
|
}
|
|
|
|
|
|
|
|
SLONG build_storey_floor(SLONG storey,SLONG y,SLONG flag)
|
|
{
|
|
SLONG min_x=9999999,max_x=0,min_z=9999999,max_z=0;
|
|
SLONG width,depth;
|
|
SLONG x,z;
|
|
|
|
SLONG wall;
|
|
struct PrimFace4 *p_f4;
|
|
struct PrimFace3 *p_f3;
|
|
SLONG face_wall;
|
|
SLONG angles;
|
|
SLONG building;
|
|
|
|
|
|
building=storey_list[storey].BuildingHead;
|
|
face_wall=-storey_list[storey].WallHead;
|
|
|
|
global_y=get_map_height((storey_list[storey].DX>>ELE_SHIFT),storey_list[storey].DZ>>ELE_SHIFT)<<FLOOR_HEIGHT_SHIFT;
|
|
|
|
BOUNDS(storey_list[storey].DX,storey_list[storey].DZ);
|
|
wall=storey_list[storey].WallHead;
|
|
while(wall)
|
|
{
|
|
BOUNDS(wall_list[wall].DX,wall_list[wall].DZ);
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
|
|
block_min_x=min_x;
|
|
block_max_x=max_x;
|
|
|
|
min_x-=ELE_SIZE;
|
|
min_z-=ELE_SIZE;
|
|
max_x+=ELE_SIZE;
|
|
max_z+=ELE_SIZE;
|
|
|
|
|
|
// bounds shound now be set, + bagginess
|
|
width=(max_x-min_x)>>ELE_SHIFT;
|
|
depth=(max_z-min_z)>>ELE_SHIFT;
|
|
|
|
edge_min_z=min_z;
|
|
|
|
//now step over whole rect, flagging points as either inside or outside or on the edge of the building
|
|
LogText(" BUILD FIRST EDGE LIST for storey %d \n",storey);
|
|
angles=build_edge_list(storey,0);
|
|
dump_edge_list(depth);
|
|
|
|
if(!angles)
|
|
{
|
|
SLONG bound;
|
|
LogText(" EASY ROOF building %d storey %d \n",storey_list[storey].BuildingHead,storey);
|
|
LogText(" final edge list \n");
|
|
dump_edge_list(depth);
|
|
bound=build_easy_roof(min_x,edge_min_z,max_x,depth,y,face_wall,flag);
|
|
bin_edge_list();
|
|
return(bound);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
SLONG build_trench(SLONG prev_facet,SLONG storey)
|
|
{
|
|
SLONG start_point,start_face3,start_face4;
|
|
SLONG wall;
|
|
SLONG px,pz;
|
|
SLONG col_vect;
|
|
SLONG bound;
|
|
SLONG min_y;
|
|
// UBYTE *textures;
|
|
// UWORD tcount;
|
|
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
wall=storey_list[storey].WallHead;
|
|
px=storey_list[storey].DX;
|
|
pz=storey_list[storey].DZ;
|
|
min_y=PAP_calc_height_at(px,pz);
|
|
while(wall)
|
|
{
|
|
SLONG y;
|
|
px=wall_list[wall].DX;
|
|
pz=wall_list[wall].DZ;
|
|
y=PAP_calc_height_at(px,pz);
|
|
if(y<min_y)
|
|
min_y=y;
|
|
wall=wall_list[wall].Next;
|
|
}
|
|
|
|
// min_y<<=ALT_SHIFT;
|
|
|
|
set_floor_hidden(storey,1,FLOOR_TRENCH|PAP_FLAG_HIDDEN);
|
|
wall=storey_list[storey].WallHead;
|
|
px=storey_list[storey].DX;
|
|
pz=storey_list[storey].DZ;
|
|
// textures=storey_list[storey].Textures;
|
|
// tcount=storey_list[storey].Tcount;
|
|
while(wall)
|
|
{
|
|
SLONG x2,z2;
|
|
|
|
x2=wall_list[wall].DX;
|
|
z2=wall_list[wall].DZ;
|
|
append_wall_prim(px,min_y,pz,wall,storey,-256); //,textures,tcount);
|
|
set_vect_floor_height(px,pz,x2,z2,min_y>>ALT_SHIFT);
|
|
|
|
//
|
|
// Insert col vect backwards for trenches, so we can enter it but not leave it
|
|
//
|
|
col_vect=insert_collision_vect(x2,min_y-256,z2,px,min_y-256, pz,STOREY_TYPE_TRENCH,0,-wall);
|
|
prev_facet=build_facet(start_point,next_prim_point,start_face3,start_face4,next_prim_face4,prev_facet,0,col_vect);
|
|
|
|
// LogText(" create building prim4 next prim_point %d \n",next_prim_point);
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
// textures=wall_list[wall].Textures;
|
|
// tcount=wall_list[wall].Tcount;
|
|
|
|
wall=wall_list[wall].Next;
|
|
px=x2;
|
|
pz=z2;
|
|
|
|
}
|
|
bound=build_storey_floor(storey,min_y-256+2,1);
|
|
prev_facet=build_facet(start_point,next_prim_point,start_face3,start_face4,next_prim_face4,prev_facet,FACET_FLAG_ROOF,-bound);
|
|
|
|
// LogText(" create building prim4 next prim_point %d \n",next_prim_point);
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
return(prev_facet);
|
|
}
|
|
|
|
/*
|
|
|
|
A facet is used for sorting and quick back face culling (but not yet)
|
|
For Each piece of wall on the bottom storey find vertically identical pieces to become
|
|
a facet.
|
|
|
|
*/
|
|
SWORD wall_for_fe[100];
|
|
SWORD wall_for_ladder[100];
|
|
|
|
SLONG create_building_prim(UWORD building,SLONG *small_y)
|
|
{
|
|
UBYTE pass2=0;
|
|
SLONG storey;
|
|
SLONG wall;
|
|
|
|
SLONG start_point,start_face3,start_face4;
|
|
SLONG mid_point,mid_face4;
|
|
SLONG y=0,offset_y=0;
|
|
|
|
ULONG obj_start_point;
|
|
ULONG obj_start_face3,obj_start_face4;
|
|
ULONG prev_facet=0;
|
|
SLONG wall_count=0;
|
|
SWORD fire_escape_count=0;
|
|
SWORD ladder_count=0;
|
|
SLONG first=0;
|
|
SLONG valid=0;
|
|
SLONG col_vect;
|
|
UBYTE *textures,tcount;
|
|
|
|
SLONG circular;
|
|
|
|
if(storey_list[building_list[building].StoreyHead].StoreyType!=STOREY_TYPE_NORMAL)
|
|
{
|
|
circular=1;
|
|
}
|
|
else
|
|
{
|
|
circular=is_storey_circular(building_list[building].StoreyHead);
|
|
}
|
|
|
|
build_min_y=999999;
|
|
build_max_y=-999999;
|
|
|
|
// LogText(" create building prim next prim_point %d \n",next_prim_point);
|
|
|
|
current_building=building;
|
|
*small_y=99999;
|
|
|
|
building_list[building].Walkable=0;
|
|
memset((UBYTE*)wall_for_fe,0,200);
|
|
memset((UBYTE*)wall_for_ladder,0,200);
|
|
|
|
if(building==3)
|
|
LogText(" build external bits\n");
|
|
|
|
process_external_pieces(building); //makes seperate buildings
|
|
// LogText(" create building prim2 next prim_point %d \n",next_prim_point);
|
|
|
|
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
obj_start_point=start_point;
|
|
obj_start_face3=start_face3;
|
|
obj_start_face4=start_face4;
|
|
|
|
setup_storey_data(building,&wall_for_ladder[0]); //clear connection flags
|
|
storey=building_list[building].StoreyHead;
|
|
|
|
if(circular)
|
|
{
|
|
// build_max_y=0;
|
|
if(build_min_y!=build_max_y)
|
|
build_max_y-=256;
|
|
|
|
//
|
|
// build_max_y is maximum fllor height the building overlaps rounded up to nearest quarter block -256
|
|
//
|
|
|
|
offset_y=build_max_y;
|
|
}
|
|
else
|
|
{
|
|
offset_y=0;
|
|
build_min_y=0;
|
|
build_max_y=0;
|
|
}
|
|
|
|
|
|
|
|
building_list[building].OffsetY=build_max_y;
|
|
while(storey)
|
|
{
|
|
LogText("storey %d \n",storey);
|
|
SLONG x1,z1,x2,z2;
|
|
// LogText("MCD build storey %d \n",storey);
|
|
|
|
switch(storey_list[storey].StoreyType)
|
|
{
|
|
case STOREY_TYPE_FENCE_FLAT:
|
|
case STOREY_TYPE_OUTSIDE_DOOR:
|
|
case STOREY_TYPE_FENCE:
|
|
case STOREY_TYPE_FENCE_BRICK:
|
|
if(storey_list[storey].DY)
|
|
{
|
|
x1=storey_list[storey].DX;
|
|
z1=storey_list[storey].DZ;
|
|
y=storey_list[storey].DY;
|
|
wall=storey_list[storey].WallHead;
|
|
while(wall)
|
|
{
|
|
|
|
build_fence(x1,y+offset_y,z1,wall,storey,storey_list[storey].Height);
|
|
|
|
|
|
x1=wall_list[wall].DX;
|
|
z1=wall_list[wall].DZ;
|
|
|
|
wall=wall_list[wall].Next;
|
|
|
|
prev_facet=build_facet(start_point,mid_point,start_face3,start_face4,mid_face4,prev_facet,0,col_vect);
|
|
|
|
// LogText(" create building prim4 next prim_point %d \n",next_prim_point);
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
}
|
|
}
|
|
|
|
break;
|
|
case STOREY_TYPE_NORMAL:
|
|
valid=1;
|
|
if(first==0)
|
|
{
|
|
set_floor_hidden(storey,0,PAP_FLAG_HIDDEN);
|
|
first=1;
|
|
}
|
|
|
|
x1=storey_list[storey].DX;
|
|
z1=storey_list[storey].DZ;
|
|
|
|
wall_count=0;
|
|
wall=storey_list[storey].WallHead;
|
|
while(wall)
|
|
{
|
|
SLONG connect_wall,connect_storey,connect_count=0;
|
|
|
|
x2=wall_list[wall].DX;
|
|
z2=wall_list[wall].DZ;
|
|
if(!(wall_list[wall].WallFlags&FLAG_WALL_FACET_LINKED))
|
|
{
|
|
y=storey_list[storey].DY;
|
|
|
|
if(y==0)
|
|
{
|
|
SLONG temp_y;
|
|
temp_y=PAP_calc_height_at(x1,z1);
|
|
if(temp_y<*small_y)
|
|
*small_y=temp_y;
|
|
|
|
}
|
|
// LogText("MCD normal storey wall append%d at y %d \n",wall,y+offset_y);
|
|
|
|
wall_list[wall].WallFlags|=FLAG_WALL_FACET_LINKED;
|
|
if( (y) ==0&& (build_min_y!=build_max_y) && circular)
|
|
append_foundation_wall(x1,y+offset_y+256,z1,wall,storey,storey_list[storey].Height); //this wants the top of the wall
|
|
else
|
|
append_wall_prim(x1,y+offset_y,z1,wall,storey,storey_list[storey].Height); //,textures,tcount); //this wants the base of the wall
|
|
|
|
|
|
{
|
|
UBYTE *tex=0;
|
|
UWORD tcount=0;
|
|
connect_wall=find_connect_wall(x1,z1,x2,z2,&connect_storey,storey,&tex,&tcount);
|
|
connect_count=1;
|
|
if(connect_wall)
|
|
{
|
|
// LogText(" found a connect wall %d\n",connect_wall);
|
|
|
|
while(connect_wall)
|
|
{
|
|
SLONG ty;
|
|
connect_count++;
|
|
ty=storey_list[connect_storey].DY;
|
|
wall_list[connect_wall].WallFlags|=FLAG_WALL_FACET_LINKED;
|
|
append_wall_prim(x1,ty+offset_y,z1,connect_wall,connect_storey,storey_list[connect_storey].Height); //,tex,tcount);
|
|
connect_wall=find_connect_wall(x1,z1,x2,z2,&connect_storey,connect_storey,&tex,&tcount);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
//
|
|
//
|
|
}
|
|
}
|
|
|
|
if (wall_list[wall].WallFlags & FLAG_WALL_RECESSED)
|
|
{
|
|
//
|
|
// Add colvects around the recess...
|
|
//
|
|
|
|
insert_recessed_wall_vect(
|
|
x1, y + offset_y, z1,
|
|
x2, y + offset_y, z2,
|
|
STOREY_TYPE_NORMAL,
|
|
connect_count,
|
|
-wall);
|
|
if(building==3)
|
|
LogText(" building 3 recessed wall \n");
|
|
}
|
|
else
|
|
{
|
|
if(y==0)
|
|
{
|
|
col_vect=insert_collision_vect(x1,y+offset_y,z1,x2,y+offset_y,z2,STOREY_TYPE_NORMAL_FOUNDATION,connect_count*4,-wall);
|
|
}
|
|
else
|
|
col_vect=insert_collision_vect(x1,y+offset_y,z1,x2,y+offset_y,z2,STOREY_TYPE_NORMAL,connect_count*4,-wall);
|
|
}
|
|
|
|
mid_point=next_prim_point;
|
|
// LogText(" create building prim3 next prim_point %d \n",next_prim_point);
|
|
mid_face4=next_prim_face4;
|
|
if(wall_for_fe[wall_count]&&pass2==0)
|
|
{
|
|
build_firescape(wall_for_fe[wall_count]);
|
|
}
|
|
// if(wall_for_ladder[wall_count]&&pass2==0)
|
|
// {
|
|
// build_ladder(wall_for_ladder[wall_count]);
|
|
// }
|
|
#ifdef PSX
|
|
// printf(" build 1\n");
|
|
#endif
|
|
|
|
prev_facet=build_facet(start_point,mid_point,start_face3,start_face4,mid_face4,prev_facet,0,col_vect);
|
|
|
|
// LogText(" create building prim4 next prim_point %d \n",next_prim_point);
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
}
|
|
// else
|
|
// LogText(" allready done through connection \n");
|
|
|
|
x1=x2;
|
|
z1=z2;
|
|
textures=wall_list[wall].Textures;
|
|
tcount=wall_list[wall].Tcount;
|
|
|
|
wall=wall_list[wall].Next;
|
|
wall_count++;
|
|
}
|
|
pass2=1;
|
|
|
|
break;
|
|
case STOREY_TYPE_LADDER:
|
|
// build_ladder(storey);
|
|
break;
|
|
case STOREY_TYPE_FIRE_ESCAPE:
|
|
wall=find_wall_for_fe(storey_list[storey].DX,storey_list[storey].DZ,building_list[building].StoreyHead);
|
|
if(wall>=0)
|
|
wall_for_fe[wall]=storey;
|
|
fire_escape_count++;
|
|
break;
|
|
case STOREY_TYPE_TRENCH:
|
|
prev_facet=build_trench(prev_facet,storey);
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
break;
|
|
case STOREY_TYPE_STAIRCASE:
|
|
build_staircase(storey);
|
|
prev_facet=build_facet(start_point,next_prim_point,start_face3,start_face4,next_prim_face4,prev_facet,0,0);
|
|
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
break;
|
|
|
|
/* moved to setup_storey_data
|
|
case STOREY_TYPE_LADDER:
|
|
wall=find_wall_for_fe(storey_list[storey].DX,storey_list[storey].DZ,building_list[building].StoreyHead);
|
|
if(wall>=0)
|
|
wall_for_ladder[wall]=storey;
|
|
ladder_count++;
|
|
break;
|
|
*/
|
|
|
|
default:
|
|
break;
|
|
}
|
|
// if(storey_list[storey].StoreyFlags&FLAG_STOREY_ROOF_RIM)
|
|
// offset_y+=BLOCK_SIZE+(BLOCK_SIZE>>1)-20;
|
|
|
|
storey=storey_list[storey].Next;
|
|
}
|
|
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
storey=building_list[building].StoreyHead;
|
|
while(storey)
|
|
{
|
|
SLONG bound;
|
|
LogText("storeyb %d \n",storey);
|
|
|
|
if((storey_list[storey].StoreyFlags&(FLAG_STOREY_TILED_ROOF|FLAG_STOREY_FLAT_TILED_ROOF)) && (storey_list[storey].StoreyType==STOREY_TYPE_NORMAL))
|
|
{
|
|
SLONG flat=0;
|
|
if(storey_list[storey].StoreyFlags&(FLAG_STOREY_FLAT_TILED_ROOF))
|
|
{
|
|
flat=1;
|
|
}
|
|
bound=build_roof(storey,storey_list[storey].DY+offset_y+storey_list[storey].Height,flat);
|
|
}
|
|
|
|
|
|
|
|
if(0) //storey_list[storey].Roof)
|
|
{
|
|
/*
|
|
switch(storey_list[storey_list[storey].Roof].StoreyType)
|
|
{
|
|
case STOREY_TYPE_ROOF:
|
|
if(building==3)
|
|
LogText(" building 3 build roof \n");
|
|
build_roof(storey,storey_list[storey_list[storey].Roof].DY+offset_y);
|
|
break;
|
|
case STOREY_TYPE_ROOF_QUAD:
|
|
if(building==3)
|
|
LogText(" building 3 build roof quad\n");
|
|
build_roof_quad(storey,storey_list[storey_list[storey].Roof].DY+offset_y);
|
|
break;
|
|
case STOREY_TYPE_LADDER:
|
|
if(building==3)
|
|
LogText(" building 3 build ladder\n");
|
|
build_ladder(storey);
|
|
break;
|
|
|
|
}
|
|
*/
|
|
}
|
|
else
|
|
{
|
|
switch(storey_list[storey].StoreyType)
|
|
{
|
|
case STOREY_TYPE_LADDER:
|
|
if(building==3)
|
|
LogText(" building 3 build ladder\n");
|
|
build_ladder(storey);
|
|
break;
|
|
case STOREY_TYPE_SKYLIGHT: //where should a skylight be processed?
|
|
if(building==3)
|
|
LogText(" building 3 build skylight\n");
|
|
build_skylight(storey);
|
|
break;
|
|
}
|
|
}
|
|
|
|
prev_facet=build_facet(start_point,next_prim_point,start_face3,start_face4,next_prim_face4,prev_facet,FACET_FLAG_ROOF,0);
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
if(storey_list[storey].InsideStorey)
|
|
{
|
|
SLONG istorey,iwall;
|
|
SLONG added_wall=0;
|
|
|
|
istorey=storey_list[storey].InsideStorey;
|
|
while(istorey)
|
|
{
|
|
SLONG x1,y1,z1;
|
|
|
|
iwall=storey_list[istorey].WallHead;
|
|
x1=storey_list[istorey].DX;
|
|
y1=storey_list[istorey].DY;
|
|
z1=storey_list[istorey].DZ;
|
|
|
|
while(iwall)
|
|
{
|
|
added_wall=1;
|
|
append_wall_prim(x1,y1+offset_y,z1,iwall,istorey,256); //,tex,tcount);
|
|
x1=wall_list[iwall].DX;
|
|
z1=wall_list[iwall].DZ;
|
|
iwall=wall_list[iwall].Next;
|
|
}
|
|
istorey=storey_list[istorey].Next;
|
|
}
|
|
|
|
if(added_wall)
|
|
{
|
|
SLONG c0;
|
|
/*
|
|
for(c0=start_face4;c0<next_prim_face4;c0++)
|
|
{
|
|
prim_faces4[c0].DrawFlags|=POLY_FLAG_DOUBLESIDED;
|
|
}
|
|
*/
|
|
|
|
prev_facet=build_facet(start_point,next_prim_point,start_face3,start_face4,next_prim_face4,prev_facet,FACET_FLAG_INSIDE,-bound);
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
}
|
|
}
|
|
storey=storey_list[storey].Next;
|
|
}
|
|
|
|
// LogText(" create building prim5 next prim_point %d \n",next_prim_point);
|
|
if(valid)
|
|
{
|
|
if(building==3)
|
|
LogText(" building 3 build last facet\n");
|
|
#ifdef PSX
|
|
// printf(" build 2\n");
|
|
#endif
|
|
prev_facet=build_facet(start_point,next_prim_point,start_face3,start_face4,next_prim_face4,prev_facet,FACET_FLAG_ROOF,0);
|
|
}
|
|
start_point=next_prim_point;
|
|
start_face3=next_prim_face3;
|
|
start_face4=next_prim_face4;
|
|
|
|
if(valid)
|
|
{
|
|
//
|
|
// We want crates to always have the 'crate' texture.
|
|
//
|
|
|
|
if(0)
|
|
if (building_list[building].BuildingType == BUILDING_TYPE_CRATE_IN ||
|
|
building_list[building].BuildingType == BUILDING_TYPE_CRATE_OUT)
|
|
{
|
|
//
|
|
// Retexture the quads...
|
|
//
|
|
|
|
SLONG i;
|
|
|
|
PrimFace4 *p_f4;
|
|
|
|
for (i = obj_start_face4; i < next_prim_face4; i++)
|
|
{
|
|
p_f4 = &prim_faces4[i];
|
|
|
|
p_f4->UV[0][0] = 7 * 32 + 0;
|
|
p_f4->UV[0][1] = 7 * 32 + 0;
|
|
|
|
p_f4->UV[1][0] = 7 * 32 + 31;
|
|
p_f4->UV[1][1] = 7 * 32 + 0;
|
|
|
|
p_f4->UV[2][0] = 7 * 32 + 0;
|
|
p_f4->UV[2][1] = 7 * 32 + 31;
|
|
|
|
p_f4->UV[3][0] = 7 * 32 + 31;
|
|
p_f4->UV[3][1] = 7 * 32 + 31;
|
|
|
|
p_f4->TexturePage = 0;
|
|
}
|
|
}
|
|
|
|
return(build_building(obj_start_point,obj_start_face3,obj_start_face4,prev_facet));
|
|
}
|
|
else
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void copy_to_game_map(void)
|
|
{
|
|
SLONG x,z,c0;
|
|
|
|
#ifdef EDITOR
|
|
for(x=0;x<EDIT_MAP_WIDTH;x++)
|
|
for(z=0;z<EDIT_MAP_DEPTH;z++)
|
|
{
|
|
//MAP2(x,z).Alt=edit_map[x][z].Y;
|
|
PAP_2HI(x,z).Alt=edit_map[x][z].Y;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
void clear_map2(void)
|
|
{
|
|
SLONG x,z,c0;
|
|
|
|
//
|
|
// clear pap lo
|
|
//
|
|
memset((UBYTE*) &PAP_lo[0][0],0,sizeof(PAP_Lo)*PAP_SIZE_LO*PAP_SIZE_LO);
|
|
|
|
|
|
for(x=0;x<EDIT_MAP_WIDTH;x++)
|
|
for(z=0;z<EDIT_MAP_DEPTH;z++)
|
|
{
|
|
mask_map_flag(x,z,(FLOOR_HIDDEN|FLOOR_LADDER|FLOOR_TRENCH));
|
|
}
|
|
#ifdef EDITOR
|
|
for(x=0;x<EDIT_MAP_WIDTH;x++)
|
|
for(z=0;z<EDIT_MAP_DEPTH;z++)
|
|
{
|
|
SLONG index;
|
|
index=edit_map[x][z].MapThingIndex;
|
|
while(index)
|
|
{
|
|
switch(map_things[index].Type)
|
|
{
|
|
case MAP_THING_TYPE_ANIM_PRIM:
|
|
case MAP_THING_TYPE_PRIM:
|
|
case MAP_THING_TYPE_LIGHT:
|
|
/*
|
|
if(map_things[index].MapChild>0)
|
|
{
|
|
switch(map_things[map_things[index].MapChild].Type)
|
|
{
|
|
|
|
case MAP_THING_TYPE_ANIM_PRIM:
|
|
case MAP_THING_TYPE_PRIM:
|
|
case MAP_THING_TYPE_LIGHT:
|
|
break;
|
|
default:
|
|
map_things[index].MapChild=0;
|
|
break;
|
|
}
|
|
}
|
|
*/
|
|
index=map_things[index].MapChild;
|
|
break;
|
|
default:
|
|
delete_thing_from_edit_map(x,z,index);
|
|
index=edit_map[x][z].MapThingIndex;
|
|
|
|
// edit_map[x][z].MapThingIndex=0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
edit_map[x][z].ColVectHead=0;
|
|
edit_map[x][z].Walkable=0;
|
|
MAP2(x,z).ColVectHead=0;
|
|
MAP2(x,z).Walkable=0;
|
|
//edit_map[x][z].Flags&=~(FLOOR_HIDDEN|FLOOR_LADDER);
|
|
|
|
}
|
|
|
|
// memset(edit_map,0,sizeof(struct DepthStrip)*EDIT_MAP_WIDTH*EDIT_MAP_DEPTH);
|
|
//memset((UBYTE*)&map_things[0],0,sizeof(struct MapThing)*MAX_MAP_THINGS);
|
|
for(c0=0;c0<MAX_MAP_THINGS;c0++)
|
|
{
|
|
switch(map_things[c0].Type)
|
|
{
|
|
case MAP_THING_TYPE_ANIM_PRIM:
|
|
case MAP_THING_TYPE_PRIM:
|
|
case MAP_THING_TYPE_LIGHT:
|
|
break;
|
|
default:
|
|
memset((UBYTE*)&map_things[c0],0,sizeof(struct MapThing));
|
|
break;
|
|
}
|
|
}
|
|
|
|
clear_prims();
|
|
#endif
|
|
|
|
next_building_object=1;
|
|
next_building_facet=1;
|
|
next_col_vect=1;
|
|
next_col_vect_link=1;
|
|
next_walk_link=1;
|
|
|
|
next_dbuilding=1;
|
|
next_dwalkable=1;
|
|
next_dfacet=1;
|
|
next_dstyle=1;
|
|
next_facet_link=1;
|
|
facet_link_count=0;
|
|
|
|
memset((UBYTE*)prim_points,0,sizeof(struct PrimPoint)*MAX_PRIM_POINTS);
|
|
memset((UBYTE*)prim_faces3,0,sizeof(struct PrimFace3)*MAX_PRIM_FACES3);
|
|
memset((UBYTE*)prim_faces4,0,sizeof(struct PrimFace4)*MAX_PRIM_FACES4);
|
|
memset((UBYTE*)prim_objects,0,sizeof(struct PrimObject)*MAX_PRIM_OBJECTS);
|
|
memset((UBYTE*)prim_multi_objects,0,sizeof(struct PrimMultiObject)*MAX_PRIM_MOBJECTS);
|
|
}
|
|
|
|
void clear_floor_ladder(void)
|
|
{
|
|
SLONG x,z;
|
|
#ifdef EDITOR
|
|
for(x=0;x<EDIT_MAP_WIDTH;x++)
|
|
for(z=0;z<EDIT_MAP_DEPTH;z++)
|
|
{
|
|
edit_map[x][z].Flags&=~(FLOOR_LADDER);
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
void wibble_floor(void)
|
|
{
|
|
SLONG dx,dz;
|
|
return;
|
|
//#ifdef EDITOR
|
|
for(dx=0;dx<EDIT_MAP_WIDTH;dx++)
|
|
for(dz=0;dz<EDIT_MAP_DEPTH;dz++)
|
|
{
|
|
// edit_map[dx][dz].Y=(COS((dx*15)&2047)+SIN((dz*15)&2047))>>12;
|
|
set_map_height(dx,dz,(COS((dx*15)&2047)+SIN((dz*15)&2047))>>10);
|
|
}
|
|
//#endif
|
|
}
|
|
|
|
|
|
|
|
void clip_building_prim(SLONG prim,SLONG x,SLONG y,SLONG z)
|
|
{
|
|
SLONG index;
|
|
SLONG best_z=-999999,az;
|
|
struct BuildingFacet *p_facet;
|
|
SLONG sp,ep;
|
|
struct PrimFace4 *p_f4;
|
|
struct PrimFace3 *p_f3;
|
|
SLONG c0;
|
|
|
|
// LogText(" draw a building %d at %d %d %d\n",building,x,y,z);
|
|
index=building_objects[prim].FacetHead;
|
|
while(index)
|
|
{
|
|
p_facet = &building_facets[index];
|
|
|
|
if(p_facet->EndFace4)
|
|
for(c0=p_facet->StartFace4;c0<p_facet->EndFace4;c0++)
|
|
{
|
|
}
|
|
|
|
if(p_facet->EndFace3)
|
|
for(c0=p_facet->StartFace3;c0<p_facet->EndFace3;c0++)
|
|
{
|
|
}
|
|
|
|
sp=p_facet->StartPoint;
|
|
ep=p_facet->EndPoint;
|
|
for(c0=sp;c0<ep;c0++)
|
|
{
|
|
SLONG px,py,pz;
|
|
SLONG fy;
|
|
|
|
px=prim_points[c0].X+x;
|
|
py=prim_points[c0].Y+y;
|
|
pz=prim_points[c0].Z+z;
|
|
|
|
fy=PAP_calc_height_at(px,pz);
|
|
|
|
if(py<fy)
|
|
{
|
|
prim_points[c0].Y+=fy-py;
|
|
}
|
|
|
|
}
|
|
|
|
index=building_facets[index].NextFacet;
|
|
}
|
|
|
|
}
|
|
|
|
SLONG calc_win(UWORD *attack,SLONG c1,UWORD *def,SLONG c2)
|
|
{
|
|
SLONG b1=0,b2=0;
|
|
UWORD data[10];
|
|
SLONG a1,a2,d1,d2;
|
|
SLONG wins=0;
|
|
|
|
memcpy((UBYTE*)data,(UBYTE*)def,10);
|
|
|
|
if(data[0]<data[1])
|
|
{
|
|
SWAP(data[0],data[1]);
|
|
}
|
|
if(data[1]<data[2])
|
|
{
|
|
SWAP(data[1],data[2]);
|
|
}
|
|
if(data[0]<data[1])
|
|
{
|
|
SWAP(data[0],data[1]);
|
|
}
|
|
|
|
|
|
if(c2>1)
|
|
{
|
|
if(data[c1]<data[c1+1])
|
|
SWAP(data[c1],data[c1+1]);
|
|
|
|
if(data[1]>data[c1+1])
|
|
{
|
|
wins--;
|
|
}
|
|
else
|
|
{
|
|
wins++;
|
|
}
|
|
}
|
|
if(data[0]>data[c1])
|
|
{
|
|
wins--;
|
|
}
|
|
else
|
|
{
|
|
wins++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(wins);
|
|
|
|
}
|
|
|
|
void calc_prob(void)
|
|
{
|
|
UWORD c[6];
|
|
SLONG total=0,total_win1=0,total_win2=0;
|
|
|
|
for(c[0]=1;c[0]<7;c[0]++)
|
|
for(c[1]=1;c[1]<7;c[1]++)
|
|
for(c[2]=1;c[2]<7;c[2]++)
|
|
for(c[3]=1;c[3]<7;c[3]++)
|
|
for(c[4]=1;c[4]<7;c[4]++)
|
|
{
|
|
SLONG win;
|
|
win=calc_win(&c[0],3,&c[3],2);
|
|
total_win2+=win;
|
|
win=calc_win(&c[0],3,&c[3],1);
|
|
total_win1+=win;
|
|
total++;
|
|
}
|
|
LogText(" total %d win2 %d win1 %d P2 %f p1 %f \n",total,total_win2,total_win1,(float)(((float)total_win2)/((float)total)),(float)(((float)total_win1)/((float)total)));
|
|
|
|
}
|
|
|
|
void fix_furniture(void)
|
|
{
|
|
Thing *p_thing;
|
|
SLONG c0;
|
|
p_thing=TO_THING(0);
|
|
for(c0=1;c0<MAX_THINGS;c0++)
|
|
{
|
|
switch(p_thing->Class)
|
|
{
|
|
case CLASS_FURNITURE:
|
|
// if(abs(p_thing->WorldPos.Y)<(10<<8))
|
|
p_thing->WorldPos.Y=PAP_calc_height_at(p_thing->WorldPos.X>>8,p_thing->WorldPos.Z>>8)<<8;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void count_floor(void)
|
|
{
|
|
SLONG x,z;
|
|
SLONG page,tx,ty;
|
|
UWORD texture;
|
|
for(x=0;x<128;x++)
|
|
for(z=0;z<128;z++)
|
|
{
|
|
texture=get_map_texture(x,z);
|
|
|
|
tx=((struct MiniTextureBits*)(&texture))->X;
|
|
ty=((struct MiniTextureBits*)(&texture))->Y;
|
|
page=(UBYTE)(((struct MiniTextureBits*)(&texture))->Page);
|
|
add_page_countxy(tx,ty,page);
|
|
}
|
|
|
|
}
|
|
|
|
void create_city(UBYTE mode)
|
|
{
|
|
SLONG c0;
|
|
SLONG bcount=0;
|
|
#ifndef PSX
|
|
SLONG temp_next_prim;
|
|
SLONG temp_next_face3;
|
|
SLONG temp_next_face4;
|
|
SLONG temp_next_point;
|
|
SLONG temp_next_building_object;
|
|
SLONG temp_next_building_facet;
|
|
#endif
|
|
|
|
diff_page_count1=0;
|
|
diff_page_count2=0;
|
|
memset(page_count,0,8*64);
|
|
count_floor();
|
|
//calc_prob();
|
|
|
|
build_mode=mode;
|
|
// save_all_prims("temp.sav");
|
|
if(mode==BUILD_MODE_EDITOR)
|
|
{
|
|
copy_to_game_map();
|
|
clear_map2();
|
|
load_all_individual_prims();
|
|
}
|
|
|
|
// Stuck in by Guy.
|
|
next_building_object=1;
|
|
next_building_facet=1;
|
|
next_col_vect=1;
|
|
next_col_vect_link=1;
|
|
next_walk_link=1;
|
|
//
|
|
|
|
// REMOVED FOR E3 DEMO
|
|
// load_all_prims("allprim.sav");
|
|
|
|
#ifndef PSX
|
|
temp_next_prim =next_prim_object;
|
|
temp_next_face3 =next_prim_face3;
|
|
temp_next_face4 =next_prim_face4;
|
|
temp_next_point =next_prim_point;
|
|
temp_next_building_object=next_building_object;
|
|
temp_next_building_facet =next_building_facet;
|
|
#endif
|
|
|
|
|
|
/*
|
|
LogText("*************\n");
|
|
LogText("*create city*\n");
|
|
LogText("*************\n");
|
|
LogText(" obj %d face3 %d face4 %d point %d build %d facet %d \n",next_prim_object,next_prim_face3,next_prim_face4,next_prim_point,next_building_object,next_building_facet);
|
|
LogText(" col vect %d link %d \n",next_col_vect,next_col_vect_link);
|
|
*/
|
|
|
|
LogText(" next prim point %d \n",next_prim_point);
|
|
// wibble_floor();
|
|
for(c0=1;c0<MAX_BUILDINGS;c0++)
|
|
{
|
|
SLONG prim;
|
|
if(building_list[c0].BuildingFlags)
|
|
{
|
|
SLONG y;
|
|
// printf(" about to create build %d \n",c0);
|
|
prim=create_building_prim(c0,&y);
|
|
y=0; //build_min_y;
|
|
// printf(" DONE create prim \n");
|
|
if(prim)
|
|
{
|
|
/*
|
|
|
|
//
|
|
// No (x,y,z), buildings have a ThingIndex instead... it is
|
|
// set in place_building_at()
|
|
//
|
|
|
|
building_list[c0].X=build_x;
|
|
building_list[c0].Y=y;
|
|
building_list[c0].Z=build_z;
|
|
|
|
*/
|
|
|
|
//y=calc_height_at(build_x,build_z);
|
|
// LogText(" place building y %d \n",y);
|
|
place_building_at(c0,prim,build_x,y,build_z);
|
|
|
|
extern void save_asc(UWORD building,UWORD version);
|
|
// save_asc(c0,1);
|
|
|
|
//clip_building_prim(prim,build_x,y,build_z);
|
|
// LogText(" after building %d, nextprimpoint %d \n",bcount,next_prim_point);
|
|
bcount++;
|
|
}
|
|
}
|
|
// LogText(" next walk link %d \n",next_walk_link);
|
|
}
|
|
extern void apply_global_amb_to_map(void);
|
|
// printf(" about to light map \n");
|
|
#ifndef PSX
|
|
// apply_global_amb_to_map();
|
|
#endif
|
|
|
|
// printf(" done light map \n");
|
|
/*
|
|
next_prim_object =temp_next_prim;
|
|
next_prim_face3 =temp_next_face3;
|
|
next_prim_face4 =temp_next_face4;
|
|
next_prim_point =temp_next_point;
|
|
next_building_object= temp_next_building_object;
|
|
next_building_facet = temp_next_building_facet;
|
|
*/
|
|
//
|
|
// Calculate the normals of all the buildings.
|
|
//
|
|
|
|
// printf(" about to norm \n");
|
|
calc_building_normals();
|
|
// printf(" about to clear ladder\n");
|
|
clear_floor_ladder();
|
|
// printf(" about to shadow\n");
|
|
// SHADOW_do();
|
|
// printf(" done shadow\n");
|
|
|
|
LogText(" Structures (PSX1)\n");
|
|
LogText(" next_prim_point %d \n",next_prim_point);
|
|
LogText(" next_prim_face3 %d \n",next_prim_face3);
|
|
LogText(" next_prim_face4 %d \n",next_prim_face4);
|
|
LogText(" next_prim_object %d \n",next_prim_object);
|
|
LogText(" next_building_object %d \n",next_building_object);
|
|
LogText(" next_building_facet %d \n",next_building_facet);
|
|
LogText(" next_col_vect %d \n",next_col_vect);
|
|
LogText(" next_col_vect_link %d \n",next_col_vect_link);
|
|
LogText(" next_walk_link %d \n",next_walk_link);
|
|
{
|
|
SLONG high=0;
|
|
for(c0=0;c0<MAX_WALLS;c0++)
|
|
{
|
|
LogText(" wallflag[%d]=%d \n",c0,wall_list[c0].WallFlags);
|
|
if(wall_list[c0].WallFlags)
|
|
high=c0;
|
|
}
|
|
LogText(" max wall list %d \n",high);
|
|
}
|
|
{
|
|
SLONG high=0;
|
|
for(c0=0;c0<MAX_STOREYS;c0++)
|
|
{
|
|
if(storey_list[c0].StoreyFlags)
|
|
high=c0;
|
|
}
|
|
LogText(" max storey list %d \n",high);
|
|
}
|
|
{
|
|
SLONG high=0;
|
|
for(c0=0;c0<MAX_BUILDINGS;c0++)
|
|
{
|
|
if(building_list[c0].BuildingFlags)
|
|
high=c0;
|
|
}
|
|
LogText(" max building list %d \n",high);
|
|
}
|
|
|
|
for(c0=1;c0<next_dwalkable;c0++)
|
|
{
|
|
SLONG face;
|
|
|
|
for(face=dwalkables[c0].StartFace4;face<dwalkables[c0].EndFace4;face++)
|
|
{
|
|
prim_faces4[face].ThingIndex=c0; //dwalkables[c0].Building;
|
|
void attach_walkable_to_map(SLONG face);
|
|
LogText(" walkable face %d \n",face);
|
|
|
|
{
|
|
SLONG point,c0;
|
|
for(c0=0;c0<4;c0++)
|
|
{
|
|
point=prim_faces4[face].Points[c0];
|
|
LogText(" point %d (%d,%d,%d) \n",point,prim_points[point].X,prim_points[point].Y,prim_points[point].Z);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
attach_walkable_to_map(face);
|
|
prim_faces4[face].FaceFlags|=FACE_FLAG_WALKABLE;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
// fix_furniture();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//**************************************8
|
|
|
|
void offset_buildings(SLONG x,SLONG y,SLONG z)
|
|
{
|
|
SLONG c0;
|
|
for (c0=1;c0<MAX_STOREYS;c0++ )
|
|
{
|
|
if(storey_list[c0].StoreyFlags)
|
|
{
|
|
storey_list[c0].DX+=(SWORD)x;
|
|
storey_list[c0].DY+=(SWORD)y;
|
|
// storey_list[c0].DY=-storey_list[c0].DY+(SWORD)y;
|
|
storey_list[c0].DZ+=(SWORD)z;
|
|
}
|
|
|
|
}
|
|
for (c0=1;c0<MAX_WALLS;c0++ )
|
|
{
|
|
if(wall_list[c0].WallFlags)
|
|
{
|
|
wall_list[c0].DX+=(SWORD)x;
|
|
wall_list[c0].DY+=(SWORD)y;//-wall_list[c0].DY+(SWORD)y;
|
|
wall_list[c0].DZ+=(SWORD)z;
|
|
}
|
|
}
|
|
/*
|
|
*/
|
|
}
|
|
|
|
/*
|
|
void calc_buildings_screen_box(UWORD prim,SLONG x,SLONG y,SLONG z,EdRect *rect)
|
|
{
|
|
SLONG c0,flags;
|
|
struct PrimObject *p_obj;
|
|
SLONG sp,ep;
|
|
SLONG min_x=999999,max_x=-999999,min_y=999999,max_y=-999999;
|
|
|
|
p_obj =&prim_objects[prim];
|
|
|
|
sp=p_obj->StartPoint;
|
|
ep=p_obj->EndPoint;
|
|
|
|
engine.X-=x<<8;
|
|
engine.Y-=y<<8;
|
|
engine.Z-=z<<8;
|
|
|
|
for(c0=sp;c0<ep;c0++)
|
|
{
|
|
//transform all points for this Object
|
|
flags=rotate_point_gte((struct SVector*)&prim_points[c0],&global_res[c0-sp]);
|
|
// if(!(flags & EF_CLIPFLAGS))
|
|
{
|
|
if(global_res[c0-sp].X<min_x)
|
|
min_x=global_res[c0-sp].X;
|
|
|
|
if(global_res[c0-sp].X>max_x)
|
|
max_x=global_res[c0-sp].X;
|
|
|
|
if(global_res[c0-sp].Y<min_y)
|
|
min_y=global_res[c0-sp].Y;
|
|
|
|
if(global_res[c0-sp].Y>max_y)
|
|
max_y=global_res[c0-sp].Y;
|
|
}
|
|
|
|
}
|
|
|
|
engine.X+=x<<8;
|
|
engine.Y+=y<<8;
|
|
engine.Z+=z<<8;
|
|
if(min_x<0)
|
|
min_x=0;
|
|
if(min_y<0)
|
|
min_y=0;
|
|
|
|
rect->SetRect(min_x-2,min_y-2,max_x-min_x+4,max_y-min_y+4);
|
|
}
|
|
|
|
void calc_buildings_world_box(UWORD prim,SLONG x,SLONG y,SLONG z,EdRect *rect)
|
|
{
|
|
SLONG c0;
|
|
struct PrimObject *p_obj;
|
|
SLONG sp,ep;
|
|
SLONG min_x=999999,max_x=-999999,min_y=999999,max_y=-999999;
|
|
|
|
p_obj =&prim_objects[prim];
|
|
|
|
sp=p_obj->StartPoint;
|
|
ep=p_obj->EndPoint;
|
|
|
|
|
|
for(c0=sp;c0<ep;c0++)
|
|
{
|
|
global_res[c0-sp].X=prim_points[c0].X+x;
|
|
global_res[c0-sp].Y=prim_points[c0].Y+y;
|
|
global_res[c0-sp].Z=prim_points[c0].Z+z;
|
|
{
|
|
if(global_res[c0-sp].X<min_x)
|
|
min_x=global_res[c0-sp].X;
|
|
|
|
if(global_res[c0-sp].X>max_x)
|
|
max_x=global_res[c0-sp].X;
|
|
|
|
if(global_res[c0-sp].Y<min_y)
|
|
min_y=global_res[c0-sp].Y;
|
|
|
|
if(global_res[c0-sp].Y>max_y)
|
|
max_y=global_res[c0-sp].Y;
|
|
}
|
|
|
|
}
|
|
|
|
if(min_x<0)
|
|
min_x=0;
|
|
if(min_y<0)
|
|
min_y=0;
|
|
|
|
rect->SetRect(min_x,min_y,max_x-min_x,max_y-min_y);
|
|
}
|
|
*/
|
|
UWORD is_it_clockwise(SLONG p0,SLONG p1,SLONG p2)
|
|
{
|
|
SLONG z;
|
|
SLONG vx,vy,wx,wy;
|
|
|
|
vx=global_res[p1].X-global_res[p0].X;
|
|
wx=global_res[p2].X-global_res[p1].X;
|
|
vy=global_res[p1].Y-global_res[p0].Y;
|
|
wy=global_res[p2].Y-global_res[p1].Y;
|
|
|
|
z=vx*wy-vy*wx;
|
|
|
|
if(z>0)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Calculates the normals of the points in all the buildings.
|
|
//
|
|
#define MAX_POINTS_PER_BUILDING 12560
|
|
|
|
extern UBYTE each_point[]; //MAX_POINTS_PER_BUILDING];
|
|
|
|
void calc_building_normals(void)
|
|
{
|
|
SLONG i;
|
|
SLONG j;
|
|
SLONG k;
|
|
SLONG dx;
|
|
SLONG dy;
|
|
SLONG dz;
|
|
SLONG dist;
|
|
SLONG num_points;
|
|
SVector fnormal;
|
|
SLONG p_index;
|
|
|
|
|
|
BuildingObject *p_obj;
|
|
PrimFace3 *p_f3;
|
|
PrimFace4 *p_f4;
|
|
PrimPoint *p_pt;
|
|
|
|
for (i = 1; i < next_building_object; i++)
|
|
{
|
|
p_obj = &building_objects[i];
|
|
|
|
num_points = p_obj->EndPoint - p_obj->StartPoint;
|
|
|
|
ASSERT(num_points <= MAX_POINTS_PER_BUILDING);
|
|
|
|
//
|
|
// Mark all the points as having zero faces using them.
|
|
//
|
|
|
|
memset(each_point, 0, sizeof(UBYTE) * num_points);
|
|
|
|
//
|
|
// Work out the normal for each point by going through
|
|
// all the faces.
|
|
//
|
|
|
|
for (j = p_obj->StartFace3; j < p_obj->EndFace3; j++)
|
|
{
|
|
p_f3 = &prim_faces3[j];
|
|
|
|
//
|
|
// What is the normal of this face?
|
|
//
|
|
|
|
calc_normal(-j, &fnormal);
|
|
|
|
//
|
|
// Use this normal to work out the normal of each point that
|
|
// makes up the face.
|
|
//
|
|
|
|
for (k = 0; k < 3; k++)
|
|
{
|
|
p_index = p_f3->Points[k] - p_obj->StartPoint;
|
|
|
|
ASSERT(WITHIN(p_index, 0, MAX_POINTS_PER_BUILDING - 1));
|
|
|
|
if (each_point[p_index] == 0)
|
|
{
|
|
//
|
|
// This is the only face that we know uses the point,
|
|
// so make the normal of the point equal to the normal
|
|
// of the face.
|
|
//
|
|
|
|
prim_normal[p_f3->Points[k]].X = fnormal.X;
|
|
prim_normal[p_f3->Points[k]].Y = fnormal.Y;
|
|
prim_normal[p_f3->Points[k]].Z = fnormal.Z;
|
|
|
|
each_point[p_index] = 1;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Average this faces' normal with the current normal.
|
|
//
|
|
|
|
prim_normal[p_f3->Points[k]].X *= each_point[p_index];
|
|
prim_normal[p_f3->Points[k]].Y *= each_point[p_index];
|
|
prim_normal[p_f3->Points[k]].Z *= each_point[p_index];
|
|
|
|
prim_normal[p_f3->Points[k]].X += fnormal.X;
|
|
prim_normal[p_f3->Points[k]].Y += fnormal.Y;
|
|
prim_normal[p_f3->Points[k]].Z += fnormal.Z;
|
|
|
|
each_point[p_index] += 1;
|
|
|
|
prim_normal[p_f3->Points[k]].X /= each_point[p_index];
|
|
prim_normal[p_f3->Points[k]].Y /= each_point[p_index];
|
|
prim_normal[p_f3->Points[k]].Z /= each_point[p_index];
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
for (j = p_obj->StartFace4; j < p_obj->EndFace4; j++)
|
|
{
|
|
p_f4 = &prim_faces4[j];
|
|
|
|
//
|
|
// What is the normal of this face?
|
|
//
|
|
|
|
calc_normal(j, &fnormal);
|
|
|
|
//
|
|
// Use this normal to work out the normal of each point that
|
|
// makes up the face.
|
|
//
|
|
|
|
for (k = 0; k < 4; k++)
|
|
{
|
|
p_index = p_f4->Points[k] - p_obj->StartPoint;
|
|
|
|
ASSERT(WITHIN(p_index, 0, MAX_POINTS_PER_BUILDING - 1));
|
|
|
|
if (each_point[p_index] == 0)
|
|
{
|
|
//
|
|
// This is the only face that we know uses the point,
|
|
// so make the normal of the point equal to the normal
|
|
// of the face.
|
|
//
|
|
|
|
prim_normal[p_f4->Points[k]].X = fnormal.X;
|
|
prim_normal[p_f4->Points[k]].Y = fnormal.Y;
|
|
prim_normal[p_f4->Points[k]].Z = fnormal.Z;
|
|
|
|
each_point[p_index] = 1;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Average this faces' normal with the current normal.
|
|
//
|
|
|
|
prim_normal[p_f4->Points[k]].X *= each_point[p_index];
|
|
prim_normal[p_f4->Points[k]].Y *= each_point[p_index];
|
|
prim_normal[p_f4->Points[k]].Z *= each_point[p_index];
|
|
|
|
prim_normal[p_f4->Points[k]].X += fnormal.X;
|
|
prim_normal[p_f4->Points[k]].Y += fnormal.Y;
|
|
prim_normal[p_f4->Points[k]].Z += fnormal.Z;
|
|
|
|
each_point[p_index] += 1;
|
|
|
|
prim_normal[p_f4->Points[k]].X /= each_point[p_index];
|
|
prim_normal[p_f4->Points[k]].Y /= each_point[p_index];
|
|
prim_normal[p_f4->Points[k]].Z /= each_point[p_index];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Normalise the length of each normal to be 256.
|
|
//
|
|
|
|
SLONG old_nx;
|
|
SLONG old_ny;
|
|
SLONG old_nz;
|
|
|
|
for (j = p_obj->StartPoint; j < p_obj->EndPoint; j++)
|
|
{
|
|
old_nx = prim_normal[j].X;
|
|
old_ny = prim_normal[j].Y;
|
|
old_nz = prim_normal[j].Z;
|
|
|
|
dx = abs(prim_normal[j].X);
|
|
dy = abs(prim_normal[j].Y);
|
|
dz = abs(prim_normal[j].Z);
|
|
|
|
dist = dx*dx + dy*dy + dz*dz;
|
|
dist = Root(dist);
|
|
dist += 1;
|
|
|
|
prim_normal[j].X <<= 8;
|
|
prim_normal[j].Y <<= 8;
|
|
prim_normal[j].Z <<= 8;
|
|
|
|
prim_normal[j].X /= dist;
|
|
prim_normal[j].Y /= dist;
|
|
prim_normal[j].Z /= dist;
|
|
|
|
if ((prim_normal[j].X * prim_normal[j].X +
|
|
prim_normal[j].Y * prim_normal[j].Y +
|
|
prim_normal[j].Z * prim_normal[j].Z) > 67536)
|
|
{
|
|
ASSERT(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
|
|
void fn_building_normal(Thing *b_thing)
|
|
{
|
|
Switch *the_switch;
|
|
|
|
/*
|
|
if(b_thing->SwitchThing)
|
|
{
|
|
the_switch = TO_THING(b_thing->SwitchThing)->Genus.Switch;
|
|
if(the_switch->Flags&SWITCH_FLAGS_TRIGGERED)
|
|
{
|
|
b_thing->Flags &= ~FLAGS_LOCKED;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
#ifdef EDITOR
|
|
// problems getting the top face under the fires escape to be a facet member
|
|
extern SLONG calc_shadow_co_ord(struct SVector *input,struct SVector *output,SLONG l_x,SLONG l_y,SLONG l_z);
|
|
|
|
SLONG draw_a_facet_at(UWORD facet,SLONG x,SLONG y,SLONG z)
|
|
{
|
|
struct PrimFace4 *p_f4;
|
|
struct PrimFace3 *p_f3;
|
|
ULONG flag_and,flag_or;
|
|
SLONG c0;
|
|
struct BuildingFacet *p_facet;
|
|
SLONG sp,mp,ep;
|
|
SLONG az;
|
|
SLONG col=0,cor=0,cob=0,cot=0,total=0;
|
|
SLONG best_z=9999999;
|
|
SLONG min_z=9999999,max_z=-9999999;
|
|
SLONG first_face=1;
|
|
|
|
SLONG facet_flags;
|
|
SLONG offset_z=0;
|
|
|
|
struct SVector res_shadow[1560],temp_shadow; //max points per object?
|
|
SLONG flags_shadow[1560];
|
|
SLONG shadow=0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p_facet = &building_facets[facet];
|
|
facet_flags = p_facet->FacetFlags;
|
|
p_f4 = &prim_faces4[p_facet->StartFace4];
|
|
p_f3 = &prim_faces3[p_facet->StartFace3];
|
|
if(facet_flags&FACET_FLAG_ROOF)
|
|
{
|
|
first_face=0;
|
|
offset_z=-50;
|
|
}
|
|
|
|
sp=p_facet->StartPoint;
|
|
mp=p_facet->MidPoint;
|
|
ep=p_facet->EndPoint;
|
|
|
|
// LogText(" draw a facet %d at %d %d %d, sp %d ep %d sf4 %d ef4 %d \n",facet,x,y,z,sp,ep,p_facet->StartFace4,p_facet->EndFace4);
|
|
|
|
engine.X-=x<<8;
|
|
engine.Y-=y<<8;
|
|
engine.Z-=z<<8;
|
|
|
|
for(c0=sp;c0<mp;c0++)
|
|
{
|
|
struct SVector pp;
|
|
pp.X=prim_points[c0].X;
|
|
pp.Y=prim_points[c0].Y;
|
|
pp.Z=prim_points[c0].Z;
|
|
|
|
//transform all points for this Object
|
|
/*
|
|
if(shadow)
|
|
{
|
|
calc_shadow_co_ord((struct SVector*)&prim_points[c0],&temp_shadow,9000*2,4000,8000*2);//light co_ord
|
|
flags_shadow[c0-sp]=rotate_point_gte((struct SVector*)&temp_shadow,&res_shadow[c0-sp]);
|
|
}
|
|
*/
|
|
global_flags[c0-sp]=rotate_point_gte(&pp,&global_res[c0-sp]);
|
|
global_bright[c0-sp]=calc_lights(x,y,z,&pp);
|
|
if(ControlFlag)
|
|
{
|
|
CBYTE str[100];
|
|
//sprintf(str,"%d",global_res[c0-sp].Z);
|
|
//QuickTextC(global_res[c0-sp].X+1,global_res[c0-sp].Y+1,str,0);
|
|
//QuickTextC(global_res[c0-sp].X,global_res[c0-sp].Y,str,1);
|
|
}
|
|
if(min_z>global_res[c0-sp].Z)
|
|
min_z=global_res[c0-sp].Z;
|
|
if(max_z<global_res[c0-sp].Z)
|
|
max_z=global_res[c0-sp].Z;
|
|
|
|
//if(best_z>global_res[c0-sp].Z)
|
|
// best_z=global_res[c0-sp].Z;
|
|
|
|
}
|
|
for(c0=mp;c0<ep;c0++)
|
|
{
|
|
struct SVector pp;
|
|
pp.X=prim_points[c0].X;
|
|
pp.Y=prim_points[c0].Y;
|
|
pp.Z=prim_points[c0].Z;
|
|
|
|
//transform all points for this Object
|
|
|
|
global_flags[c0-sp]=rotate_point_gte(&pp,&global_res[c0-sp]);
|
|
global_bright[c0-sp]=calc_lights(x,y,z,&pp);
|
|
|
|
}
|
|
engine.X+=x<<8;
|
|
engine.Y+=y<<8;
|
|
engine.Z+=z<<8;
|
|
best_z=min_z;
|
|
|
|
|
|
|
|
ASSERT(p_facet->StartFace4>=0);
|
|
|
|
if(p_facet->EndFace4)
|
|
for(c0=p_facet->StartFace4;c0<p_facet->EndFace4;c0++)
|
|
{
|
|
SLONG p0,p1,p2,p3;
|
|
SLONG height_ok=1;
|
|
|
|
if(current_bucket_pool>=end_bucket_pool)
|
|
goto exit;
|
|
|
|
|
|
if(p_f4->FaceFlags&FACE_FLAG_WALKABLE)
|
|
{
|
|
if(p_f4->ThingIndex>0)
|
|
{
|
|
SLONG dy;
|
|
dy=((dwalkables[p_f4->ThingIndex].Y)>>3)+1;
|
|
|
|
ASSERT(p_f4->ThingIndex<next_dwalkable);
|
|
// ASSERT(dwalkables[p_f4->ThingIndex].StoreyY>0);
|
|
if(dy>=edit_info.TileScale)
|
|
height_ok=0;
|
|
else
|
|
{
|
|
//DebugText(" no height walkable y %d edity %d\n",dy,edit_info.TileScale);
|
|
//SLONG my;
|
|
//my=prim_points[p_f4->Points[0]].Y;
|
|
//ASSERT(my<(edit_info.TileScale<<8));
|
|
}
|
|
// else
|
|
// ASSERT(0);
|
|
}
|
|
else
|
|
ASSERT(0);
|
|
|
|
}
|
|
// else
|
|
// ASSERT(facet_flags&FACET_FLAG_ROOF);
|
|
if(p_f4->ThingIndex<0)
|
|
{
|
|
SLONG wall;
|
|
SLONG dy;
|
|
wall=-p_f4->ThingIndex;
|
|
//dy=storey_list[wall_list[wall].StoreyHead].DY>>8;
|
|
dy=prim_points[p_f4->Points[0]].Y>>8;
|
|
|
|
if(dy>=edit_info.TileScale)
|
|
height_ok=0;
|
|
|
|
|
|
}
|
|
|
|
if(height_ok)
|
|
{
|
|
p0=p_f4->Points[0]-sp;
|
|
p1=p_f4->Points[1]-sp;
|
|
p2=p_f4->Points[2]-sp;
|
|
p3=p_f4->Points[3]-sp;
|
|
/*
|
|
if(shadow)
|
|
{
|
|
flag_and = flags_shadow[p0]&flags_shadow[p1]&flags_shadow[p2]&flags_shadow[p3];
|
|
flag_or = flags_shadow[p0]|flags_shadow[p1]|flags_shadow[p2]|flags_shadow[p3];
|
|
|
|
if((flag_or&EF_BEHIND_YOU)==0)
|
|
if(!(flag_and & EF_CLIPFLAGS))
|
|
{
|
|
az=(res_shadow[p0].Z+res_shadow[p1].Z+res_shadow[p2].Z+res_shadow[p3].Z)>>2;
|
|
az-=150;
|
|
|
|
setPolyType4(
|
|
current_bucket_pool,
|
|
POLY_F
|
|
);
|
|
|
|
setCol4 (
|
|
(struct BucketQuad*)current_bucket_pool,
|
|
0
|
|
);
|
|
|
|
setXY4 (
|
|
(struct BucketQuad*)current_bucket_pool,
|
|
res_shadow[p0].X,res_shadow[p0].Y,
|
|
res_shadow[p1].X,res_shadow[p1].Y,
|
|
res_shadow[p2].X,res_shadow[p2].Y,
|
|
res_shadow[p3].X,res_shadow[p3].Y
|
|
);
|
|
|
|
|
|
setZ4((struct BucketQuad*)current_bucket_pool,-res_shadow[p0].Z,-res_shadow[p1].Z,-res_shadow[p2].Z,-res_shadow[p3].Z);
|
|
((struct BucketQuad*)current_bucket_pool)->DebugInfo=c0;
|
|
((struct BucketQuad*)current_bucket_pool)->DebugFlags=0;
|
|
|
|
add_bucket((void *)current_bucket_pool,az);
|
|
|
|
current_bucket_pool+=sizeof(struct BucketQuad);
|
|
|
|
}
|
|
}
|
|
*/
|
|
|
|
{
|
|
|
|
|
|
flag_and = global_flags[p0]&global_flags[p1]&global_flags[p2]&global_flags[p3];
|
|
flag_or = global_flags[p0]|global_flags[p1]|global_flags[p2]|global_flags[p3];
|
|
|
|
if((p_f4->FaceFlags&FACE_FLAG_SMOOTH)&&ShiftFlag)
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
|
|
if( (!(flag_and & EF_CLIPFLAGS))&&((flag_or&EF_BEHIND_YOU)==0))
|
|
{
|
|
SLONG wid,height;
|
|
SLONG sort_level;
|
|
/*
|
|
if(first_face)
|
|
{
|
|
first_face=0;
|
|
|
|
if(!(p_f4->DrawFlags&POLY_FLAG_DOUBLESIDED))
|
|
if(!is_it_clockwise(p0,p1,p2))
|
|
{
|
|
c0=p_facet->MidFace4;
|
|
p_f4 = &prim_faces4[p_facet->MidFace4];
|
|
best_z=max_z;
|
|
goto skip_wall;
|
|
}
|
|
}
|
|
*/
|
|
total++;
|
|
/*
|
|
if(!AltFlag)
|
|
{
|
|
|
|
az=global_res[p0].Z+1000;
|
|
|
|
if(az<global_res[p1].Z)
|
|
az=global_res[p1].Z+1000;
|
|
|
|
if(az<global_res[p2].Z)
|
|
az=global_res[p2].Z+1000;
|
|
|
|
if(az<global_res[p3].Z)
|
|
az=global_res[p3].Z+1000;
|
|
az-=1000;
|
|
|
|
}
|
|
else
|
|
{
|
|
sort_level=GET_SORT_LEVEL(p_f4->FaceFlags);
|
|
if(sort_level==0)
|
|
{
|
|
az=best_z;
|
|
}
|
|
else
|
|
{
|
|
az=best_z-(sort_level<<2);
|
|
|
|
}
|
|
|
|
}
|
|
*/
|
|
sort_level=GET_SORT_LEVEL(p_f4->FaceFlags);
|
|
if(sort_level==0)
|
|
{
|
|
//if(best_z>az)
|
|
// best_z=az;
|
|
az=global_res[p0].Z;
|
|
|
|
if(az>global_res[p1].Z)
|
|
az=global_res[p1].Z;
|
|
|
|
if(az>global_res[p2].Z)
|
|
az=global_res[p2].Z;
|
|
|
|
if(az>global_res[p3].Z)
|
|
az=global_res[p3].Z;
|
|
}
|
|
else
|
|
{
|
|
az=best_z-(sort_level<<2);
|
|
//return(best_z);
|
|
}
|
|
//LogText(" facet %d sort_level %d best_z %d az %d face %d \n",facet,sort_level,best_z,az,c0);
|
|
|
|
wid=WorkWindowWidth;
|
|
|
|
height=WorkWindowHeight;
|
|
|
|
setPolyType4(
|
|
current_bucket_pool,
|
|
p_f4->DrawFlags
|
|
);
|
|
|
|
|
|
setCol4 (
|
|
(struct BucketQuad*)current_bucket_pool,
|
|
((UBYTE)p_f4->Col2)
|
|
);
|
|
|
|
|
|
setXY4 (
|
|
(struct BucketQuad*)current_bucket_pool,
|
|
global_res[p0].X,global_res[p0].Y,
|
|
global_res[p1].X,global_res[p1].Y,
|
|
global_res[p2].X,global_res[p2].Y,
|
|
global_res[p3].X,global_res[p3].Y
|
|
);
|
|
|
|
if(SelectFlag)
|
|
do_quad_clip_list((SWORD)c0,p0,p1,p2,p3);
|
|
|
|
//RUD
|
|
if(p_f4->DrawFlags&POLY_FLAG_TEXTURED)
|
|
{
|
|
if(p_f4->TexturePage<0)
|
|
{
|
|
struct AnimTmap *p_a;
|
|
SLONG cur;
|
|
|
|
p_a=&anim_tmaps[-p_f4->TexturePage];
|
|
cur=p_a->Current;
|
|
setUV4 (
|
|
(struct BucketQuad*)current_bucket_pool,
|
|
p_a->UV[cur][0][0],p_a->UV[cur][0][1],
|
|
p_a->UV[cur][1][0],p_a->UV[cur][1][1],
|
|
p_a->UV[cur][2][0],p_a->UV[cur][2][1],
|
|
p_a->UV[cur][3][0],p_a->UV[cur][3][1],
|
|
(UBYTE)p_a->Page[cur]
|
|
);
|
|
ASSERT(p_a->Page[cur]<15);
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
// ASSERT(p_f4->TexturePage<15);
|
|
setUV4 (
|
|
(struct BucketQuad*)current_bucket_pool,
|
|
p_f4->UV[0][0],p_f4->UV[0][1],
|
|
p_f4->UV[1][0],p_f4->UV[1][1],
|
|
p_f4->UV[2][0],p_f4->UV[2][1],
|
|
p_f4->UV[3][0],p_f4->UV[3][1],
|
|
(UBYTE)p_f4->TexturePage
|
|
);
|
|
// ASSERT(p_f4->TexturePage<15);
|
|
}
|
|
}
|
|
|
|
setZ4((struct BucketQuad*)current_bucket_pool,global_res[p0].Z,global_res[p1].Z,global_res[p2].Z,global_res[p3].Z);
|
|
|
|
|
|
setShade4((struct BucketQuad*)current_bucket_pool,
|
|
CLIP256(p_f4->Bright[0]+global_bright[p0]),
|
|
CLIP256(p_f4->Bright[1]+global_bright[p1]),
|
|
CLIP256(p_f4->Bright[2]+global_bright[p2]),
|
|
CLIP256(p_f4->Bright[3]+global_bright[p3]));
|
|
((struct BucketQuad*)current_bucket_pool)->DebugInfo=az; //c0;
|
|
((struct BucketQuad*)current_bucket_pool)->DebugFlags=p_f4->FaceFlags;
|
|
|
|
add_bucket((void *)current_bucket_pool,az);
|
|
|
|
if(check_mouse_over_prim_quad(global_res,p0,p1,p2,p3,c0))
|
|
{
|
|
selected_prim_xyz.X = x;
|
|
selected_prim_xyz.Y = y;
|
|
selected_prim_xyz.Z = z;
|
|
}
|
|
if(p_f4->DrawFlags&POLY_FLAG_DOUBLESIDED)
|
|
{
|
|
if(check_mouse_over_prim_quad(global_res,p1,p0,p3,p2,c0))
|
|
{
|
|
selected_prim_xyz.X = x;
|
|
selected_prim_xyz.Y = y;
|
|
selected_prim_xyz.Z = z;
|
|
}
|
|
|
|
}
|
|
|
|
current_bucket_pool += sizeof(struct BucketQuad);
|
|
}
|
|
else
|
|
{
|
|
if(flag_and&EF_OFF_LEFT)
|
|
col++;
|
|
if(flag_and&EF_OFF_RIGHT)
|
|
cor++;
|
|
if(flag_and&EF_OFF_TOP)
|
|
cot++;
|
|
if(flag_and&EF_OFF_BOTTOM)
|
|
cob++;
|
|
}
|
|
// LogText(" clipped face %d \n",c0);
|
|
}
|
|
}
|
|
}
|
|
|
|
p_f4++;
|
|
skip_wall:;
|
|
}
|
|
|
|
if(p_facet->EndFace3)
|
|
for(c0=p_facet->StartFace3;c0<p_facet->EndFace3;c0++)
|
|
{
|
|
SLONG p0,p1,p2;
|
|
|
|
if(current_bucket_pool>=end_bucket_pool)
|
|
goto exit;
|
|
|
|
|
|
p0=p_f3->Points[0]-sp;
|
|
p1=p_f3->Points[1]-sp;
|
|
p2=p_f3->Points[2]-sp;
|
|
|
|
flag_and = global_flags[p0]&global_flags[p1]&global_flags[p2];
|
|
flag_or = global_flags[p0]|global_flags[p1]|global_flags[p2];
|
|
|
|
if((flag_or&EF_BEHIND_YOU)==0)
|
|
if(!(flag_and & EF_CLIPFLAGS))
|
|
{
|
|
// az=(global_res[p0].Z+global_res[p1].Z+global_res[p2].Z)/3;
|
|
az=global_res[p0].Z;
|
|
|
|
if(az>global_res[p1].Z)
|
|
az=global_res[p1].Z;
|
|
|
|
if(az>global_res[p2].Z)
|
|
az=global_res[p2].Z;
|
|
|
|
setPolyType3(
|
|
current_bucket_pool,
|
|
p_f3->DrawFlags
|
|
);
|
|
|
|
setCol3 (
|
|
(struct BucketTri*)current_bucket_pool,
|
|
p_f3->Col2
|
|
);
|
|
|
|
setXY3 (
|
|
(struct BucketTri*)current_bucket_pool,
|
|
global_res[p0].X,global_res[p0].Y,
|
|
global_res[p1].X,global_res[p1].Y,
|
|
global_res[p2].X,global_res[p2].Y
|
|
);
|
|
|
|
if(SelectFlag)
|
|
do_tri_clip_list(-c0,p0,p1,p2);
|
|
|
|
//RUD
|
|
if(p_f3->DrawFlags&POLY_FLAG_TEXTURED)
|
|
{
|
|
ASSERT(p_f3->TexturePage<15);
|
|
setUV3 (
|
|
(struct BucketTri*)current_bucket_pool,
|
|
p_f3->UV[0][0],p_f3->UV[0][1],
|
|
p_f3->UV[1][0],p_f3->UV[1][1],
|
|
p_f3->UV[2][0],p_f3->UV[2][1],
|
|
p_f3->TexturePage
|
|
);
|
|
// ASSERT(p_f3->TexturePage<15);
|
|
}
|
|
|
|
setShade3((struct BucketTri*)current_bucket_pool,
|
|
CLIP256(p_f3->Bright[0]+global_bright[p0]),
|
|
CLIP256(p_f3->Bright[1]+global_bright[p1]),
|
|
CLIP256(p_f3->Bright[2]+global_bright[p2]));
|
|
|
|
setZ3((struct BucketQuad*)current_bucket_pool,global_res[p0].Z,global_res[p1].Z,global_res[p2].Z);
|
|
|
|
((struct BucketTri*)current_bucket_pool)->DebugInfo=c0;
|
|
((struct BucketTri*)current_bucket_pool)->DebugFlags=p_f3->FaceFlags;
|
|
|
|
add_bucket((void *)current_bucket_pool,az);
|
|
|
|
if(check_mouse_over_prim_tri(global_res,p0,p1,p2,c0))
|
|
{
|
|
selected_prim_xyz.X = x;
|
|
selected_prim_xyz.Y = y;
|
|
selected_prim_xyz.Z = z;
|
|
}
|
|
|
|
current_bucket_pool += sizeof(struct BucketQuad);
|
|
}
|
|
p_f3++;
|
|
}
|
|
exit:;
|
|
|
|
// LogText(" draw a prim left %d right %d top %d bot %d ok %d \n",col,cor,cot,cob,total);
|
|
|
|
return(best_z);
|
|
}
|
|
|
|
void draw_a_building_at(UWORD building,SLONG x,SLONG y,SLONG z)
|
|
{
|
|
UWORD index;
|
|
SLONG best_z=-999999,az;
|
|
//LogText(" draw a building %d at %d %d %d\n",building,x,y,z);
|
|
index=building_objects[building].FacetHead;
|
|
while(index)
|
|
{
|
|
//LogText(" draw facet %d \n",index);
|
|
az=draw_a_facet_at(index,x,y,z);
|
|
if(best_z<az)
|
|
best_z=az;
|
|
index=building_facets[index].NextFacet;
|
|
}
|
|
|
|
}
|
|
#endif
|
|
#endif
|