int block_next_lin(struct map_rect_priv *mr) { for (;;) { block_lin_count++; block_mem+=sizeof(struct block *); mr->b.block_num++; if (! mr->b.block_num) mr->b.p=mr->file->begin+0x2000; else mr->b.p=mr->b.block_start+mr->b.b->blocks*512; if (mr->b.p >= mr->file->end) return 0; mr->b.block_start=mr->b.p; mr->b.b=block_get(&mr->b.p); mr->b.p_start=mr->b.p; mr->b.end=mr->b.block_start+mr->b.b->size; if (mr->b.b->count == -1) return 0; if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->rect, &mr->b.b->r)) { block_active_count++; block_active_mem+=mr->b.b->blocks*512-sizeof(struct block *); return 1; } } }
int block_next_lin(struct map_rect_priv *mr) { struct coord_rect r; for (;;) { block_lin_count++; block_mem+=sizeof(struct block *); mr->b.block_num++; if (! mr->b.block_num) mr->b.p=mr->file->begin+0x2000; else mr->b.p=mr->b.block_start+block_get_blocks(mr->b.b)*512; if (mr->b.p >= mr->file->end) { dbg(lvl_debug,"end of blocks %p vs %p\n", mr->b.p, mr->file->end); return 0; } mr->b.block_start=mr->b.p; mr->b.b=block_get(&mr->b.p); mr->b.p_start=mr->b.p; mr->b.end=mr->b.block_start+block_get_size(mr->b.b); if (block_get_count(mr->b.b) == -1) { dbg(lvl_warning,"empty blocks\n"); return 0; } block_get_r(mr->b.b, &r); if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->u.c_rect, &r)) { block_active_count++; block_active_mem+=block_get_blocks(mr->b.b)*512-sizeof(struct block *); dbg(lvl_debug,"block ok\n"); return 1; } dbg(lvl_info,"block not in cur_sel\n"); } }
int block_init(struct map_rect_priv *mr) { mr->b.block_num=-1; mr->b.bt.b=NULL; mr->b.bt.next=0; block_setup_tags(mr); if (mr->b.binarytree) { mr->b.bt.next=mr->b.binarytree; mr->b.bt.p=NULL; mr->b.bt.block_count=0; } if (mr->cur_sel && !coord_rect_overlap(&mr->cur_sel->rect, &mr->b.b_rect)) return 0; return block_next(mr); }
static int selection_contains(struct map_selection *sel, struct coord_rect *r, struct minmax *mima) { int order; if (! sel) return 1; while (sel) { if (coord_rect_overlap(r, &sel->u.c_rect)) { order=sel->order[0]; if (sel->order[1] > order) order=sel->order[1]; if (sel->order[2] > order) order=sel->order[2]; dbg(1,"min %d max %d order %d\n", mima->min, mima->max, order); if (!mima->min && !mima->max) return 1; if (order >= mima->min && order <= mima->max) return 1; } sel=sel->next; } return 0; }
int block_next(struct map_rect_priv *mr) { int blk_num,coord,r_h,r_w; struct block_bt_priv *bt=&mr->b.bt; if (!mr->b.binarytree || ! mr->cur_sel) return block_next_lin(mr); for (;;) { if (! bt->p) { dbg(1,"block 0x%x\n", bt->next); if (bt->next == -1) return 0; bt->b=block_get_byid(mr->file, bt->next, &bt->p); bt->end=(unsigned char *)mr->b.bt.b+mr->b.bt.b->size; bt->next=bt->b->next; bt->order=0; dbg(1,"size 0x%x next 0x%x\n", bt->b->size, bt->b->next); if (! mr->b.bt.block_count) { #if 0 if (debug) { printf("idx rect "); block_rect_print(&mr->b.bt.b->r); } #endif bt->r=bt->b->r; bt->r_curr=bt->r; coord=get_u32(&mr->b.bt.p); } else { bt->p=(unsigned char *)bt->b+0xc; } bt->block_count++; } while (mr->b.bt.p < mr->b.bt.end) { block_idx_count++; blk_num=get_u32(&mr->b.bt.p); coord=get_u32(&mr->b.bt.p); block_mem+=8; dbg(1,"%p vs %p coord 0x%x ", mr->b.bt.end, mr->b.bt.p, coord); dbg(1,"block 0x%x", blk_num); r_w=bt->r_curr.rl.x-bt->r_curr.lu.x; r_h=bt->r_curr.lu.y-bt->r_curr.rl.y; #if 0 if (debug) { printf(" rect1 "); block_rect_print(&bt->r_curr); printf(" %dx%d", r_w, r_h); } #endif mr->b.b=NULL; if (blk_num != -1) { block_mem+=8; if (coord_rect_overlap(&mr->cur_sel->rect, &bt->r_curr)) { mr->b.b=block_get_byid(mr->file, blk_num, &mr->b.p); mr->b.block_num=blk_num; g_assert(mr->b.b != NULL); mr->b.block_start=(unsigned char *)(mr->b.b); mr->b.p_start=mr->b.p; mr->b.end=mr->b.block_start+mr->b.b->size; block_rect_same(&mr->b.b->r, &bt->r_curr); } } if (coord != -1) { bt->stack[bt->stackp]=bt->r_curr; if (r_w > r_h) { bt->r_curr.rl.x=coord; bt->stack[bt->stackp].lu.x=coord+1; } else { bt->r_curr.lu.y=coord; bt->stack[bt->stackp].rl.y=coord+1; } bt->stackp++; g_assert(bt->stackp < BT_STACK_SIZE); } else { if (bt->stackp) { bt->stackp--; bt->r_curr=bt->stack[bt->stackp]; } else { bt->r_curr=bt->r; bt->order++; if (bt->order > 100) return 0; } } if (mr->b.b) { block_active_count++; block_active_mem+=mr->b.b->blocks*512; return 1; } } bt->p=NULL; } return 0; }
int poly_get(struct map_rect_priv *mr, struct poly_priv *poly, struct item *item) { struct coord_rect r; for (;;) { if (mr->b.p >= mr->b.end) return 0; if (mr->b.p == mr->b.p_start) { poly->poly_num=0; poly->subpoly_num=0; poly->subpoly_num_all=0; poly->poly_next=mr->b.p; item->meth=&poly_meth; } if (poly->poly_num >= block_get_count(mr->b.b)) return 0; if (!poly->subpoly_num) { mr->b.p=poly->poly_next; item->id_lo=mr->b.p-mr->file->begin; poly_get_data(poly, &mr->b.p); poly->poly_next=mr->b.p+poly->count_sum*sizeof(struct coord); poly->poly_num++; r.lu=poly->c[0]; r.rl=poly->c[1]; if (mr->cur_sel && (poly->order > mr->cur_sel->order*3 || !coord_rect_overlap(&mr->cur_sel->u.c_rect, &r))) { poly->subpoly_num_all+=poly->polys; mr->b.p=poly->poly_next; continue; } switch(poly->type) { case 0x13: item->type=type_poly_wood; break; case 0x14: item->type=type_poly_town; break; case 0x15: item->type=type_poly_cemetery; break; case 0x16: item->type=type_poly_building; break; case 0x17: item->type=type_poly_museum; break; case 0x19: item->type=type_poly_place; break; case 0x1b: item->type=type_poly_commercial_center; break; case 0x1e: item->type=type_poly_industry; break; case 0x23: /* FIXME: what is this ?*/ item->type=type_poly_place; break; case 0x24: item->type=type_poly_car_parking; break; case 0x28: item->type=type_poly_airport; break; case 0x29: item->type=type_poly_station; break; case 0x2d: item->type=type_poly_hospital; break; case 0x2e: item->type=type_poly_hospital; break; case 0x2f: item->type=type_poly_university; break; case 0x30: item->type=type_poly_university; break; case 0x32: item->type=type_poly_park; break; case 0x34: item->type=type_poly_sport; break; case 0x35: item->type=type_poly_sport; break; case 0x37: item->type=type_poly_golf_course; break; case 0x38: item->type=type_poly_national_park; break; case 0x39: item->type=type_poly_nature_park; break; case 0x3c: item->type=type_poly_water; break; case 0xbc: item->type=type_water_line; break; case 0xc3: /* FIXME: what is this ?*/ item->type=type_border_state; break; case 0xc6: item->type=type_border_country; break; case 0xc7: item->type=type_border_state; break; case 0xd0: item->type=type_rail; break; default: dbg(0,"Unknown poly type 0x%x '%s' 0x%x,0x%x\n", poly->type,poly->name,r.lu.x,r.lu.y); item->type=type_street_unkn; } if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) { poly->subpoly_num_all+=poly->polys; mr->b.p=poly->poly_next; continue; } } else mr->b.p=poly->subpoly_next; dbg(1,"%d %d %s\n", poly->subpoly_num_all, mr->b.block_num, poly->name); item->id_lo=poly->subpoly_num_all | (mr->b.block_num << 16); item->id_hi=(mr->current_file << 16); dbg(1,"0x%x 0x%x\n", item->id_lo, item->id_hi); poly->subpoly_next=mr->b.p+L(poly->count[poly->subpoly_num])*sizeof(struct coord); poly->subpoly_num++; poly->subpoly_num_all++; if (poly->subpoly_num >= poly->polys) poly->subpoly_num=0; poly->subpoly_start=poly->p=mr->b.p; item->priv_data=poly; poly->attr_next=attr_label; return 1; } }