struct pos * npos (struct pos *p, struct pos *np) { /* assert (is_valid_pos (p)); */ if (np != p) *np = *p; bool m; np->room = room_val (np->room); do { m = false; if (np->floor < 0) { np->floor += FLOORS; np->room = roomd (np->l, np->room, ABOVE); m = true; } else if (np->floor >= FLOORS) { np->floor -= FLOORS; np->room = roomd (np->l, np->room, BELOW); m = true; } else if (np->place < 0) { np->place += PLACES; np->room = roomd (np->l, np->room, LEFT); m = true; } else if (np->place >= PLACES) { np->place -= PLACES; np->room = roomd (np->l, np->room, RIGHT); m = true; } } while (m); return np; }
void mirror_link (struct level *l, int room, enum dir dir0, enum dir dir1) { int r0 = roomd (l, room, dir0); int r1 = roomd (l, room, dir1); link_room (l, room, r0, dir1); link_room (l, room, r1, dir0); }
struct pos * pos2room (struct pos *p, int room, struct pos *pv) { *pv = *p; /* npos (pv, pv); */ if (pv->room == room) return pv; struct pos pb, pa, pl, pr; pb = pa = pl = pr = *pv; int mpb, mpa, mpr, mpl; mpb = mpa = mpr = mpl = INT_MAX; int ra, rb, rl, rr; ra = roomd (pv->l, room, ABOVE); rb = roomd (pv->l, room, BELOW); rl = roomd (pv->l, room, LEFT); rr = roomd (pv->l, room, RIGHT); if (rb == pv->room) { pb.floor += FLOORS; pb.room = room; mpb = pos_mod (&pb, p); } if (ra == pv->room) { pa.floor -= FLOORS; pa.room = room; mpa = pos_mod (&pa, p); } if (rr == pv->room) { pr.place += PLACES; pr.room = room; mpr = pos_mod (&pr, p); } if (rl == pv->room) { pl.place -= PLACES; pl.room = room; mpl = pos_mod (&pl, p); } int lm = mpb; lm = min_int (lm, mpa); lm = min_int (lm, mpr); lm = min_int (lm, mpl); if (lm == mpb) *pv = pb; else if (lm == mpa) *pv = pa; else if (lm == mpr) *pv = pr; else if (lm == mpl) *pv = pl; return pv; }
bool is_room_adjacent (struct level *l, int room0, int room1) { return room0 == room1 || roomd (l, room0, LEFT) == room1 || roomd (l, room0, RIGHT) == room1 || roomd (l, room0, ABOVE) == room1 || roomd (l, room0, BELOW) == room1; }
void mr_map_room_adj (int r, int x, int y) { int rl = roomd (r, LEFT); int rr = roomd (r, RIGHT); int ra = roomd (r, ABOVE); int rb = roomd (r, BELOW); mr.cell[x][y].room = r; mr.cell[x][y].done = true; if (x > 0) mr.cell[x - 1][y].room = rl; if (x < mr.w - 1) mr.cell[x + 1][y].room = rr; if (y > 0) mr.cell[x][y - 1].room = ra; if (y < mr.h - 1) mr.cell[x][y + 1].room = rb; }
void mr_view_trans (enum dir d) { int x, y, dx = +0, dy = +0; mr.select_cycles = 0; for (y = mr.h - 1; y >= 0; y--) for (x = 0; x < mr.w; x++) { int r = mr.cell[x][y].room; if (r <= 0) continue; r = roomd (r, d); if (r) { mr.room = r; mr.x = x; mr.y = y; return; } } switch (d) { case RIGHT: if (mr.x > 0) dx = -1; break; case LEFT: if (mr.x < mr.w - 1) dx = +1; break; case BELOW: if (mr.y > 0) dy = -1; break; case ABOVE: if (mr.y < mr.h - 1) dy = +1; break; } mr.x += dx; mr.y += dy; }
void mr_map_room (int r, int x, int y) { int rl = roomd (&global_level, r, LEFT); int rr = roomd (&global_level, r, RIGHT); int ra = roomd (&global_level, r, ABOVE); int rb = roomd (&global_level, r, BELOW); mr.cell[x][y].room = r; mr.cell[x][y].done = true; if (x > 0 && mr.cell[x - 1][y].room == -1) mr.cell[x - 1][y].room = rl; if (x < mr.w - 1 && mr.cell[x + 1][y].room == -1) mr.cell[x + 1][y].room = rr; if (y > 0 && mr.cell[x][y - 1].room == -1) mr.cell[x][y - 1].room = ra; if (y < mr.h - 1 && mr.cell[x][y + 1].room == -1) mr.cell[x][y + 1].room = rb; }
bool coord4draw (struct coord *c, int room, struct coord *cv) { if (cv != c) *cv = *c; ncoord (cv, cv); bool m = false; if (cv->y < 11 && roomd (cv->l, room, BELOW) == cv->room && room != cv->room) { cv->y += PLACE_HEIGHT * FLOORS; cv->room = room; m = true; } else if (cv->y >= PLACE_HEIGHT * FLOORS && roomd (cv->l, room, ABOVE) == cv->room && room != cv->room) { cv->y -= PLACE_HEIGHT * FLOORS; cv->room = room; m = true; } return m; }
int room_dist (struct level *lv, int r0, int r1, int max) { struct room_dist room[ROOMS]; /* begin optimization block */ if (r0 == r1) return 0; if (roomd (lv, r0, LEFT) == r1 || roomd (lv, r0, RIGHT) == r1 || roomd (lv, r0, BELOW) == r1 || roomd (lv, r0, ABOVE) == r1) return 1; /* end optimization block */ int i; for (i = 0; i < ROOMS; i++) { room[i].dist = INT_MAX; room[i].visited = false; } room[r0].dist = 0; int dmax = 0; int u; while ((u = min_room_dist (room, &dmax)) != -1 && dmax <= max) { if (u == r1) break; room[u].visited = true; int l = roomd (lv, u, LEFT); int r = roomd (lv, u, RIGHT); int b = roomd (lv, u, BELOW); int a = roomd (lv, u, ABOVE); room[l].dist = min_int (room[l].dist, room[u].dist + 1); room[r].dist = min_int (room[r].dist, room[u].dist + 1); room[b].dist = min_int (room[b].dist, room[u].dist + 1); room[a].dist = min_int (room[a].dist, room[u].dist + 1); } return room[r1].dist; }
void mr_select_trans (enum dir d) { int dx = +0, dy = +0; switch (d) { case LEFT: dx = -1; break; case RIGHT: dx = +1; break; case ABOVE: dy = -1; break; case BELOW: dy = +1; break; } int r = roomd (mr.room, d); if (r) { mr.room = r; nmr_coord (mr.x + dx, mr.y + dy, &mr.x, &mr.y); } mr.select_cycles = SELECT_CYCLES; }
void mr_view_trans (enum dir d) { int x, y, dx = +0, dy = +0; mr.select_cycles = SELECT_CYCLES; struct mr_origin o; mr_save_origin (&o); for (y = mr.h - 1; y >= 0; y--) for (x = 0; x < mr.w; x++) { int r = mr.cell[x][y].room; if (r <= 0) continue; r = roomd (&global_level, r, d); if (r) { mr_set_origin (r, x, y); mr_stabilize_origin (&o, d); return; } } switch (d) { case RIGHT: if (mr.x > 0) dx = -1; break; case LEFT: if (mr.x < mr.w - 1) dx = +1; break; case BELOW: if (mr.y > 0) dy = -1; break; case ABOVE: if (mr.y < mr.h - 1) dy = +1; break; } mr_set_origin (mr.room, mr.x + dx, mr.y + dy); mr_stabilize_origin (&o, d); return; }
int roomd_n0 (struct level *l, int room, enum dir dir) { int r = roomd (l, room, dir); return r ? r : room; }
void draw_room_anim_fg (ALLEGRO_BITMAP *bitmap, enum em em, enum vm vm, struct anim *a0) { draw_room_anim_fg_sub (bitmap, em, vm, a0); int x = a0->f.c.x; int y = a0->f.c.y; int room = a0->f.c.room; int w = al_get_bitmap_width (a0->f.b); int h = al_get_bitmap_height (a0->f.b); struct anim a = *a0; if (room == roomd (a.f.c.l, room, LEFT) && x < 0) { a.f.c = a0->f.c; a.f.c.x += PLACE_WIDTH * PLACES; draw_room_anim_fg_sub (bitmap, em, vm, &a); } if (room == roomd (a.f.c.l, room, RIGHT) && x + w - 1 >= PLACE_WIDTH * PLACES) { a.f.c = a0->f.c; a.f.c.x -= PLACE_WIDTH * PLACES; draw_room_anim_fg_sub (bitmap, em, vm, &a); } if (room == roomd (a.f.c.l, room, ABOVE) && y < 3) { a.f.c = a0->f.c; a.f.c.y += PLACE_HEIGHT * FLOORS; draw_room_anim_fg_sub (bitmap, em, vm, &a); } if (room == roomd (a.f.c.l, room, BELOW) && y + h - 1 >= PLACE_HEIGHT * FLOORS) { a.f.c = a0->f.c; a.f.c.y -= PLACE_HEIGHT * FLOORS; draw_room_anim_fg_sub (bitmap, em, vm, &a); } if (room == roomd (a.f.c.l, room, LEFT) && x < 0 && room == roomd (a.f.c.l, room, ABOVE) && y < 3) { a.f.c = a0->f.c; a.f.c.x += PLACE_WIDTH * PLACES; a.f.c.y += PLACE_HEIGHT * FLOORS; draw_room_anim_fg_sub (bitmap, em, vm, &a); } if (room == roomd (a.f.c.l, room, RIGHT) && x + w - 1 >= PLACE_WIDTH * PLACES && room == roomd (a.f.c.l, room, ABOVE) && y < 3) { a.f.c = a0->f.c; a.f.c.x -= PLACE_WIDTH * PLACES; a.f.c.y += PLACE_HEIGHT * FLOORS; draw_room_anim_fg_sub (bitmap, em, vm, &a); } if (room == roomd (a.f.c.l, room, LEFT) && x < 0 && room == roomd (a.f.c.l, room, BELOW) && y + h - 1 >= PLACE_HEIGHT * FLOORS) { a.f.c = a0->f.c; a.f.c.x += PLACE_WIDTH * PLACES; a.f.c.y -= PLACE_HEIGHT * FLOORS; draw_room_anim_fg_sub (bitmap, em, vm, &a); } if (room == roomd (a.f.c.l, room, RIGHT) && x + w - 1 >= PLACE_WIDTH * PLACES && room == roomd (a.f.c.l, room, BELOW) && y + h - 1 >= PLACE_HEIGHT * FLOORS) { a.f.c = a0->f.c; a.f.c.x -= PLACE_WIDTH * PLACES; a.f.c.y -= PLACE_HEIGHT * FLOORS; draw_room_anim_fg_sub (bitmap, em, vm, &a); } }
struct coord * coord2room (struct coord *c, int room, struct coord *cv) { *cv = *c; ncoord (cv, cv); if (cv->room == room) return cv; struct coord cb, ca, cl, cr; cb = ca = cl = cr = *cv; int mcb, mca, mcr, mcl; mcb = mca = mcr = mcl = INT_MAX; int ra, rb, rl, rr; int rab, rba, rlr, rrl; ra = roomd (cv->l, room, ABOVE); rb = roomd (cv->l, room, BELOW); rl = roomd (cv->l, room, LEFT); rr = roomd (cv->l, room, RIGHT); rab = roomd (cv->l, ra, BELOW); rba = roomd (cv->l, rb, ABOVE); rlr = roomd (cv->l, rl, RIGHT); rrl = roomd (cv->l, rr, LEFT); if (rb == cv->room && rba == room) { cb.y += PLACE_HEIGHT * FLOORS; cb.room = room; mcb = coord_mod (&cb); } if (ra == cv->room && rab == room) { ca.y -= PLACE_HEIGHT * FLOORS; ca.room = room; mca = coord_mod (&ca); } if (rr == cv->room && rrl == room) { cr.x += PLACE_WIDTH * PLACES; cr.room = room; mcr = coord_mod (&cr); } if (rl == cv->room && rlr == room) { cl.x -= PLACE_WIDTH * PLACES; cl.room = room; mcl = coord_mod (&cl); } int lm = mcb; lm = min_int (lm, mca); lm = min_int (lm, mcr); lm = min_int (lm, mcl); if (lm == mcb) *cv = cb; else if (lm == mca) *cv = ca; else if (lm == mcr) *cv = cr; else if (lm == mcl) *cv = cl; return cv; }
struct coord * ncoord (struct coord *c, struct coord *nc) { /* assert (is_valid_coord (c)); */ if (nc != c) *nc = *c; bool m, allow_weak, allow_zero; do { bool nl = nc->x < 0; bool nr = nc->x >= PLACE_WIDTH * PLACES; bool na = nc->y < 0; bool nb = nc->y >= PLACE_HEIGHT * FLOORS + 11; if (! nl && ! nr && ! na && ! nb) break; m = allow_weak = allow_zero = false; int ra, rb, rl, rr; ra = roomd (nc->l, nc->room, ABOVE); rb = roomd (nc->l, nc->room, BELOW); rl = roomd (nc->l, nc->room, LEFT); rr = roomd (nc->l, nc->room, RIGHT); int rab, rba, rlr, rrl; rab = roomd (nc->l, ra, BELOW); rba = roomd (nc->l, rb, ABOVE); rlr = roomd (nc->l, rl, RIGHT); rrl = roomd (nc->l, rr, LEFT); retry: if (nl && (rlr == nc->room || allow_weak) && (rl != 0 || allow_zero)) { nc->x += PLACE_WIDTH * PLACES; nc->prev_room = nc->room; nc->room = rl; nc->xd = LEFT; m = true; } else if (nr && (rrl == nc->room || allow_weak) && (rr != 0 || allow_zero)) { nc->x -= PLACE_WIDTH * PLACES; nc->prev_room = nc->room; nc->room = rr; nc->xd = RIGHT; m = true; } else if (na && (rab == nc->room || allow_weak) && (ra != 0 || allow_zero)) { nc->y += PLACE_HEIGHT * FLOORS; nc->prev_room = nc->room; nc->room = ra; nc->xd = ABOVE; m = true; } else if (nb && (rba == nc->room || allow_weak) && (rb != 0 || allow_zero)) { nc->y -= PLACE_HEIGHT * FLOORS; nc->prev_room = nc->room; nc->room = rb; nc->xd = BELOW; m = true; } if (! m && ! allow_weak) { allow_weak = true; goto retry; } if (! m && ! allow_zero) { allow_zero = true; goto retry; } } while (m); return nc; }
void update_cache_pos (struct pos *p, enum changed_pos_reason reason, enum em em, enum vm vm) { static bool recursive = false, recursive_01 = false; int x, y; struct pos p0; p0 = *p; struct pos pbl; prel (p, &pbl, +1, -1); struct pos pb; prel (p, &pb, +1, +0); struct pos pbr; prel (p, &pbr, +1, +1); struct pos pl; prel (p, &pl, +0, -1); struct pos pr; prel (p, &pr, +0, +1); struct pos par; prel (p, &par, -1, +1); /* if (! recursive) */ /* printf ("%i,%i,%i,%i\n", p->room, p->floor, p->place, reason); */ for (y = mr.h - 1; y >= 0; y--) for (x = 0; x < mr.w; x++) if (p->room && mr.cell[x][y].room == p->room) { room_view = p->room; mr.dx = x; mr.dy = y; con_caching = true; struct rect r; struct door *d; switch (reason) { case CHPOS_NONE: break; case CHPOS_UNHIDE_FLOOR: case CHPOS_MOUSE_SELECT: case CHPOS_MOUSE_DESELECT: case CHPOS_CLOSE_LEVEL_DOOR: case CHPOS_CARPET_DESIGN: case CHPOS_WALL: draw_conbg (mr.cell[x][y].cache, p, em, vm, true); break; case CHPOS_SHAKE_LOOSE_FLOOR: case CHPOS_RELEASE_LOOSE_FLOOR: case CHPOS_PRESS_OPENER_FLOOR: case CHPOS_UNPRESS_OPENER_FLOOR: case CHPOS_PRESS_CLOSER_FLOOR: case CHPOS_UNPRESS_CLOSER_FLOOR: new_rect (&r, p->room, PLACE_WIDTH * p->place, PLACE_HEIGHT * p->floor + 49, 58, 17); clear_rect_to_color (mr.cell[x][y].cache, &r, TRANSPARENT_COLOR); if (con (&pbl)->fg == LEVEL_DOOR || con (&pbl)->bg == BALCONY) draw_conbg (mr.cell[x][y].cache, &pbl, em, vm, true); if (con (&pb)->fg == LEVEL_DOOR || con (&pb)->bg == BALCONY) draw_conbg (mr.cell[x][y].cache, &pb, em, vm, true); if (con (&pbr)->fg == LEVEL_DOOR || con (&pbr)->bg == BALCONY) draw_conbg (mr.cell[x][y].cache, &pbr, em, vm, true); draw_confg_top (mr.cell[x][y].cache, &pb, em, vm, true); draw_conbg (mr.cell[x][y].cache, &pl, em, vm, true); draw_conbg (mr.cell[x][y].cache, p, em, vm, true); break; case CHPOS_LOOSE_FLOOR_FALL: case CHPOS_CHAIN_RELEASE_LOOSE_FLOOR: new_rect (&r, p->room, PLACE_WIDTH * p->place, PLACE_HEIGHT * p->floor + 49, 58, 17); clear_rect_to_color (mr.cell[x][y].cache, &r, TRANSPARENT_COLOR); if (con (&pbl)->fg == LEVEL_DOOR || con (&pbl)->bg == BALCONY) draw_conbg (mr.cell[x][y].cache, &pbl, em, vm, true); if (con (&pb)->fg == LEVEL_DOOR || con (&pb)->bg == BALCONY) draw_conbg (mr.cell[x][y].cache, &pb, em, vm, true); if (con (&pbr)->fg == LEVEL_DOOR || con (&pbr)->bg == BALCONY) draw_conbg (mr.cell[x][y].cache, &pbr, em, vm, true); draw_confg_top (mr.cell[x][y].cache, &pbl, em, vm, true); draw_confg_top (mr.cell[x][y].cache, &pb, em, vm, true); draw_conbg (mr.cell[x][y].cache, &pl, em, vm, true); draw_conbg (mr.cell[x][y].cache, p, em, vm, true); draw_confg_base (mr.cell[x][y].cache, &pr, em, vm); draw_confg_left (mr.cell[x][y].cache, &pr, em, vm, true); break; case CHPOS_BREAK_LOOSE_FLOOR: case CHPOS_BREAK_OPENER_FLOOR: case CHPOS_BREAK_CLOSER_FLOOR: case CHPOS_BREAK_LEVEL_DOOR: new_rect (&r, p->room, PLACE_WIDTH * p->place, PLACE_HEIGHT * p->floor + 35, 57, 31); clear_rect_to_color (mr.cell[x][y].cache, &r, TRANSPARENT_COLOR); if (con (&pbl)->fg == LEVEL_DOOR || con (&pbl)->bg == BALCONY) draw_conbg (mr.cell[x][y].cache, &pbl, em, vm, true); if (con (&pb)->fg == LEVEL_DOOR || con (&pb)->bg == BALCONY) draw_conbg (mr.cell[x][y].cache, &pb, em, vm, true); if (con (&pbr)->fg == LEVEL_DOOR || con (&pbr)->bg == BALCONY) draw_conbg (mr.cell[x][y].cache, &pbr, em, vm, true); draw_confg_top (mr.cell[x][y].cache, &pb, em, vm, true); draw_conbg (mr.cell[x][y].cache, &pl, em, vm, true); draw_conbg (mr.cell[x][y].cache, p, em, vm, true); break; case CHPOS_OPEN_DOOR: case CHPOS_CLOSE_DOOR: case CHPOS_ABRUPTLY_CLOSE_DOOR: d = door_at_pos (p); int ch = 18 + d->i + 1; new_rect (&r, p->room, PLACE_WIDTH * (p->place + 1), PLACE_HEIGHT * p->floor - 6, 24, ch); clear_rect_to_color (mr.cell[x][y].cache, &r, TRANSPARENT_COLOR); draw_conbg (mr.cell[x][y].cache, p, em, vm, true); if (ch > PLACE_HEIGHT - 3) draw_confg_top (mr.cell[x][y].cache, &pb, em, vm, true); break; case CHPOS_OPEN_LEVEL_DOOR: new_rect (&r, p->room, PLACE_WIDTH * p->place + 7, PLACE_HEIGHT * p->floor - 1, 48, 51); clear_rect_to_color (mr.cell[x][y].cache, &r, TRANSPARENT_COLOR); draw_conbg (mr.cell[x][y].cache, p, em, vm, true); break; case CHPOS_SPIKES: new_rect (&r, p->room, PLACE_WIDTH * p->place + 7, PLACE_HEIGHT * p->floor + 34, 40, 24); clear_rect_to_color (mr.cell[x][y].cache, &r, TRANSPARENT_COLOR); draw_conbg (mr.cell[x][y].cache, &pl, em, vm, true); draw_conbg (mr.cell[x][y].cache, p, em, vm, true); break; case CHPOS_CHOPPER: new_rect (&r, p->room, PLACE_WIDTH * p->place, PLACE_HEIGHT * p->floor + 3, 27, 60); clear_rect_to_color (mr.cell[x][y].cache, &r, TRANSPARENT_COLOR); draw_conbg (mr.cell[x][y].cache, &pl, em, vm, true); draw_conbg (mr.cell[x][y].cache, p, em, vm, true); break; default: new_rect (&r, p->room, PLACE_WIDTH * p->place - 1, PLACE_HEIGHT * p->floor - 17, 2 * PLACE_WIDTH + 1, PLACE_HEIGHT + 3 + 17); clear_rect_to_color (mr.cell[x][y].cache, &r, TRANSPARENT_COLOR); for (p0.floor = p->floor + 1; p0.floor >= p->floor - 1; p0.floor--) for (p0.place = p->place - 2; p0.place <= p->place + 1; p0.place++) draw_conbg (mr.cell[x][y].cache, &p0, em, vm, true); break; } con_caching = false; goto end; } end:; /* if (is_room_visible (p->room)) printf ("%i,%i,%i\n", p->room, p->floor, p->place); */ bool depedv = ((em == DUNGEON && vm == VGA) || (em == DUNGEON && vm == EGA) || (em == PALACE && vm == EGA)); if (! recursive_01 && depedv && con (&pl)->fg == WALL) { recursive_01 = true; update_cache_pos (&pl, CHPOS_WALL, em, vm); recursive_01 = false; } if (! recursive && p->place == -1) { p0.room = roomd (&global_level, p->room, LEFT); p0.floor = p->floor; p0.place = PLACES - 1; recursive = true; update_cache_pos (&p0, reason, em, vm); recursive = false; } if (! recursive && p->floor == -1) { p0.room = roomd (&global_level, p->room, ABOVE); p0.floor = FLOORS - 1; p0.place = p->place; recursive = true; update_cache_pos (&p0, reason, em, vm); recursive = false; } if (! recursive && p->floor == 0) { p0.room = roomd (&global_level, p->room, ABOVE); p0.floor = FLOORS; p0.place = p->place; recursive = true; update_cache_pos (&p0, reason, em, vm); recursive = false; } if (! recursive && p->place == PLACES - 1) { p0.room = roomd (&global_level, p->room, RIGHT); p0.floor = p->floor; p0.place = -1; recursive = true; update_cache_pos (&p0, reason, em, vm); recursive = false; } if (! recursive && p->floor == FLOORS - 1) { p0.room = roomd (&global_level, p->room, BELOW); p0.floor = -1; p0.place = p->place; recursive = true; update_cache_pos (&p0, reason, em, vm); recursive = false; } if (! recursive && p->floor == -1 && p->place == -1) { p0.room = roomd (&global_level, p->room, ABOVE); p0.room = roomd (&global_level, p0.room, LEFT); p0.floor = FLOORS - 1; p0.place = PLACES - 1; recursive = true; update_cache_pos (&p0, reason, em, vm); recursive = false; } if (! recursive && p->floor == 0 && p->place == PLACES - 1) { p0.room = roomd (&global_level, p->room, ABOVE); p0.room = roomd (&global_level, p0.room, RIGHT); p0.floor = FLOORS; p0.place = -1; recursive = true; update_cache_pos (&p0, reason, em, vm); recursive = false; } if (! recursive && p->floor == -1 && p->place == PLACES - 1) { p0.room = roomd (&global_level, p->room, ABOVE); p0.room = roomd (&global_level, p0.room, RIGHT); p0.floor = FLOORS - 1; p0.place = -1; recursive = true; update_cache_pos (&p0, reason, em, vm); recursive = false; } if (! recursive && p->floor == FLOORS - 1 && p->place == -1) { p0.room = roomd (&global_level, p->room, LEFT); p0.room = roomd (&global_level, p0.room, BELOW); p0.floor = -1; p0.place = PLACES - 1; recursive = true; update_cache_pos (&p0, reason, em, vm); recursive = false; } if (! recursive && p->floor == FLOORS - 1 && p->place == PLACES - 1) { p0.room = roomd (&global_level, p->room, BELOW); p0.room = roomd (&global_level, p0.room, RIGHT); p0.floor = -1; p0.place = -1; recursive = true; update_cache_pos (&p0, reason, em, vm); recursive = false; } /* if (is_room_visible (p->room) && ! recursive) printf ("----------------------------\n"); */ }
void update_cache_pos (struct pos *p, enum em em, enum vm vm) { static bool recursive = false; int x, y; int room_view_bkp = room_view; struct pos pbl; prel (p, &pbl, +1, -1); struct pos pb; prel (p, &pb, +1, +0); struct pos pbr; prel (p, &pbr, +1, +1); struct pos pl; prel (p, &pl, +0, -1); struct pos pr; prel (p, &pr, +0, +1); struct pos pa; prel (p, &pa, -1, +0); struct pos pal; prel (p, &pal, -1, -1); struct pos par; prel (p, &par, -1, +1); for (y = mr.h - 1; y >= 0; y--) for (x = 0; x < mr.w; x++) if (p->room && mr.cell[x][y].room == p->room) { room_view = p->room; mr.dx = x; mr.dy = y; int cx, cy, cw, ch; switch (con (p)->fg) { default: cx = PLACE_WIDTH * p->place; cy = PLACE_HEIGHT * p->floor - 10; cw = 2 * PLACE_WIDTH; ch = PLACE_HEIGHT + 3 + 10; break; } set_target_bitmap (mr.cell[x][y].cache); al_set_clipping_rectangle (cx, cy, cw, ch); al_clear_to_color (TRANSPARENT_COLOR); con_caching = true; draw_conbg (mr.cell[x][y].cache, &pbl, em, vm); draw_conbg (mr.cell[x][y].cache, &pb, em, vm); draw_conbg (mr.cell[x][y].cache, &pbr, em, vm); draw_conbg (mr.cell[x][y].cache, &pl, em, vm); draw_conbg (mr.cell[x][y].cache, p, em, vm); draw_conbg (mr.cell[x][y].cache, &pr, em, vm); draw_conbg (mr.cell[x][y].cache, &pal, em, vm); draw_conbg (mr.cell[x][y].cache, &pa, em, vm); draw_conbg (mr.cell[x][y].cache, &par, em, vm); draw_confg_right (mr.cell[x][y].cache, &pbl, em, vm, true); draw_confg_right (mr.cell[x][y].cache, &pb, em, vm, true); draw_confg_right (mr.cell[x][y].cache, &pl, em, vm, false); draw_confg (mr.cell[x][y].cache, p, em, vm, true); draw_confg_right (mr.cell[x][y].cache, &pal, em, vm, true); draw_confg (mr.cell[x][y].cache, &pa, em, vm, true); draw_confg_base (mr.cell[x][y].cache, &par, em, vm); draw_confg_left (mr.cell[x][y].cache, &par, em, vm, false); al_reset_clipping_rectangle (); al_hold_bitmap_drawing (false); con_caching = false; } /* printf ("%i,%i,%i\n", p->room, p->floor, p->place); */ if (! recursive && p->place == -1) { struct pos p0; p0.room = roomd (p->room, LEFT); p0.floor = p->floor; p0.place = PLACES - 1; recursive = true; update_cache_pos (&p0, em, vm); recursive = false; } if (! recursive && p->floor == -1) { struct pos p0; p0.room = roomd (p->room, ABOVE); p0.floor = FLOORS - 1; p0.place = p->place; recursive = true; update_cache_pos (&p0, em, vm); recursive = false; } if (! recursive && p->place == PLACES - 1) { struct pos p0; p0.room = roomd (p->room, RIGHT); p0.floor = p->floor; p0.place = -1; recursive = true; update_cache_pos (&p0, em, vm); recursive = false; } if (! recursive && p->floor == FLOORS - 1) { struct pos p0; p0.room = roomd (p->room, BELOW); p0.floor = -1; p0.place = p->place; recursive = true; update_cache_pos (&p0, em, vm); recursive = false; } if (! recursive && p->floor == -1 && p->place == -1) { struct pos p0; p0.room = roomd (p->room, ABOVE); p0.room = roomd (p0.room, LEFT); p0.floor = FLOORS - 1; p0.place = PLACES - 1; recursive = true; update_cache_pos (&p0, em, vm); recursive = false; } if (! recursive && p->floor == -1 && p->place == PLACES - 1) { struct pos p0; p0.room = roomd (p->room, ABOVE); p0.room = roomd (p0.room, RIGHT); p0.floor = FLOORS - 1; p0.place = -1; recursive = true; update_cache_pos (&p0, em, vm); recursive = false; } if (! recursive && p->floor == FLOORS - 1 && p->place == -1) { struct pos p0; p0.room = roomd (p->room, LEFT); p0.room = roomd (p0.room, BELOW); p0.floor = -1; p0.place = PLACES - 1; recursive = true; update_cache_pos (&p0, em, vm); recursive = false; } if (! recursive && p->floor == FLOORS - 1 && p->place == PLACES - 1) { struct pos p0; p0.room = roomd (p->room, BELOW); p0.room = roomd (p0.room, RIGHT); p0.floor = -1; p0.place = -1; recursive = true; update_cache_pos (&p0, em, vm); recursive = false; } /* if (! recursive) printf ("----------------------------\n"); */ room_view = room_view_bkp; }
void draw_bitmap_regionc (ALLEGRO_BITMAP *from, ALLEGRO_BITMAP *to, float sx, float sy, float sw, float sh, struct coord *c, int flags) { if (! from) return; struct coord nc = *c; if (! cutscene && nc.room != room_view) { struct frame f; f.b = from; f.c = *c; frame2room (&f, room_view, &nc); if (nc.room != room_view) return; } draw_bitmap_region (from, to, sx, sy, sw, sh, nc.x, nc.y, flags); if (cutscene || con_caching || no_recursive_links_continuity) return; int x = nc.x; int y = nc.y; int room = nc.room; int w = sw; int h = sh; struct coord mc; push_reset_clipping_rectangle (to); if (room == roomd (nc.l, room, LEFT) && x < 0) { mc = nc; mc.x += PLACE_WIDTH * PLACES; draw_bitmap_region (from, to, sx, sy, sw, sh, mc.x, mc.y, flags); } if (room == roomd (nc.l, room, RIGHT) && x + w - 1 >= PLACE_WIDTH * PLACES) { mc = nc; mc.x -= PLACE_WIDTH * PLACES; draw_bitmap_region (from, to, sx, sy, sw, sh, mc.x, mc.y, flags); } if (room == roomd (nc.l, room, ABOVE) && y < 3) { mc = nc; mc.y += PLACE_HEIGHT * FLOORS; draw_bitmap_region (from, to, sx, sy, sw, sh, mc.x, mc.y, flags); } if (room == roomd (nc.l, room, BELOW) && y + h - 1 >= PLACE_HEIGHT * FLOORS) { mc = nc; mc.y -= PLACE_HEIGHT * FLOORS; draw_bitmap_region (from, to, sx, sy, sw, sh, mc.x, mc.y, flags); } if (room == roomd (nc.l, room, LEFT) && x < 0 && room == roomd (nc.l, room, ABOVE) && y < 3) { mc = nc; mc.x += PLACE_WIDTH * PLACES; mc.y += PLACE_HEIGHT * FLOORS; draw_bitmap_region (from, to, sx, sy, sw, sh, mc.x, mc.y, flags); } if (room == roomd (nc.l, room, RIGHT) && x + w - 1 >= PLACE_WIDTH * PLACES && room == roomd (nc.l, room, ABOVE) && y < 3) { mc = nc; mc.x -= PLACE_WIDTH * PLACES; mc.y += PLACE_HEIGHT * FLOORS; draw_bitmap_region (from, to, sx, sy, sw, sh, mc.x, mc.y, flags); } if (room == roomd (nc.l, room, LEFT) && x < 0 && room == roomd (nc.l, room, BELOW) && y + h - 1 >= PLACE_HEIGHT * FLOORS) { mc = nc; mc.x += PLACE_WIDTH * PLACES; mc.y -= PLACE_HEIGHT * FLOORS; draw_bitmap_region (from, to, sx, sy, sw, sh, mc.x, mc.y, flags); } if (room == roomd (nc.l, room, RIGHT) && x + w - 1 >= PLACE_WIDTH * PLACES && room == roomd (nc.l, room, BELOW) && y + h - 1 >= PLACE_HEIGHT * FLOORS) { mc = nc; mc.x -= PLACE_WIDTH * PLACES; mc.y -= PLACE_HEIGHT * FLOORS; draw_bitmap_region (from, to, sx, sy, sw, sh, mc.x, mc.y, flags); } pop_clipping_rectangle (); }