#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(xblock_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=0); ASSERT(xx) { 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<0) { dz=(dz<<16)/count; while(count) { insert_point((z>>16)>>ELE_SHIFT,x1<>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<=0); wall=storey_list[storey].WallHead; while(wall) { SLONG z; z=wall_list[wall].DZ; /* if(z>(max_z<edge_min_z&&z(%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<>ELE_SHIFT)<>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<>ELE_SHIFT,((pz+edge_min_z)>>ELE_SHIFT))<>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(xmax_x) max_x=x; if(zmax_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>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>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<Points[p]].Z-(mz<>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<Points[p]].Z-(mz<>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;c0Points[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>8),min_x-256+128); for(x=min_x-256+128;xedge_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(xlmax_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))<maxy) maxy=y+dy; add_point(x-128,y+dy,(z<>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))<maxy) maxy=y+dy; add_point(x-128+ELE_SIZE,y+dy,(z<>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))<maxy) maxy=y+dy; add_point(x-128,y+dy,(z<>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))<maxy) maxy=y+dy; add_point(x-128+256,y+dy,(z<>ELE_SHIFT)+1+(z+1)*MAX_BOUND_SIZE]=next_prim_point-1; br=next_prim_point-1; } if(dyThingIndex=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;z0) { 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||mxt_max_x||mz=lmax_z+oz) { } else { if(flag_blocks[mx+(mz-oz)*MAX_BOUND_SIZE]>0) { bits|=1<>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>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>ELE_SHIFT)][storey_list[storey].DZ>>ELE_SHIFT].Y<>ELE_SHIFT),storey_list[storey].DZ>>ELE_SHIFT)<>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>ELE_SHIFT),z+(edge_min_z>>ELE_SHIFT))<>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))<>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>ELE_SHIFT;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<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)); // 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)); // 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<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)); // 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)); // 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<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)); // 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)); // 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)<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)); // 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)); // 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<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)<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)<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<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<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)<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)<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)<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<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)<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)<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)<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)); // 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)); 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)); 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)); // 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> 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>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>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(count0) { //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>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;c0ThingIndex=-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;c0ThingIndex=-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;c0DrawFlags=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(%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;c0ThingIndex=-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;c0ThingIndex=-wall; if(ptexture1 && (c0ThingIndex=-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 && (c0ThingIndex=-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;c0ThingIndex=-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=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 && (countThingIndex=-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 && (countThingIndex=-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;c0ThingIndex=-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;c0ThingIndex=-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>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)>8)>0&&(pz>>8)>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>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;c0StartPoint=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>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>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>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>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;c0ThingIndex=-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;c0ThingIndex=-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;c0ThingIndex=-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(ybuild_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(ybuild_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)<>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>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;c0UV[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;x0) { 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>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;c0EndFace4;c0++) { } if(p_facet->EndFace3) for(c0=p_facet->StartFace3;c0EndFace3;c0++) { } sp=p_facet->StartPoint; ep=p_facet->EndPoint; for(c0=sp;c01) { if(data[c1]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;c0Class) { 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;c0StartPoint; ep=p_obj->EndPoint; engine.X-=x<<8; engine.Y-=y<<8; engine.Z-=z<<8; for(c0=sp;c0max_x) max_x=global_res[c0-sp].X; if(global_res[c0-sp].Ymax_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;c0max_x) max_x=global_res[c0-sp].X; if(global_res[c0-sp].Ymax_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;c0global_res[c0-sp].Z) min_z=global_res[c0-sp].Z; if(max_zglobal_res[c0-sp].Z) // best_z=global_res[c0-sp].Z; } for(c0=mp;c0StartFace4>=0); if(p_facet->EndFace4) for(c0=p_facet->StartFace4;c0EndFace4;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->ThingIndexThingIndex].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(azFaceFlags); 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;c0EndFace3;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