void push_clipping_rectangle (ALLEGRO_BITMAP *bitmap, int x, int y, int w, int h) { assert (clipping_rectangle_stack_nmemb < CLIPPING_RECTANGLE_STACK_NMEMB_MAX); set_target_bitmap (bitmap); /* save current */ int cx, cy, cw, ch; al_get_clipping_rectangle (&cx, &cy, &cw, &ch); size_t i = clipping_rectangle_stack_nmemb; clipping_rectangle_stack[i].bitmap = bitmap; clipping_rectangle_stack[i].x = cx; clipping_rectangle_stack[i].y = cy; clipping_rectangle_stack[i].w = cw; clipping_rectangle_stack[i].h = ch; clipping_rectangle_stack_nmemb++; /* intersection */ if (! ignore_clipping_rectangle_intersection) intersection_rectangle (x, y, w, h, cx, cy, cw, ch, &x, &y, &w, &h); /* set new */ al_set_clipping_rectangle (x, y, w, h); }
void draw_filled_rectangle (ALLEGRO_BITMAP *to, float x1, float y1, float x2, float y2, ALLEGRO_COLOR color) { set_target_bitmap (to); al_draw_filled_rectangle (x1, y1, x2 + 1, y2 + 1, color); }
ALLEGRO_BITMAP * apply_palette (ALLEGRO_BITMAP *bitmap, palette p) { if (! bitmap) return NULL; ALLEGRO_BITMAP *cached = get_cached_palette (bitmap, p); if (cached) return cached; int x, y; ALLEGRO_BITMAP *rbitmap = clone_bitmap (bitmap); int w = al_get_bitmap_width (bitmap); int h = al_get_bitmap_height (bitmap); al_lock_bitmap (rbitmap, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE); set_target_bitmap (rbitmap); for (y = 0; y < h; y++) for (x = 0; x < w; x++) al_put_pixel (x, y, p (al_get_pixel (rbitmap, x, y))); al_unlock_bitmap (rbitmap); struct palette_cache pc; pc.ib = bitmap; pc.pal = p; pc.ob = rbitmap; palette_cache = add_to_array (&pc, 1, palette_cache, &palette_cache_nmemb, palette_cache_nmemb, sizeof (pc)); qsort (palette_cache, palette_cache_nmemb, sizeof (pc), compare_palette_caches); return rbitmap; }
void draw_rectangle (ALLEGRO_BITMAP *to, float x1, float y1, float x2, float y2, ALLEGRO_COLOR color, float thickness) { set_target_bitmap (to); al_draw_rectangle (x1 + 1, y1, x2 + 1, y2, color, thickness); }
void draw_star (struct stars *stars, int i, enum vm vm) { al_lock_bitmap (stars->b, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE); set_target_bitmap (stars->b); al_put_pixel (stars->s[i].x - stars->c.x, stars->s[i].y - stars->c.y, get_star_color (stars->s[i].color, vm)); al_unlock_bitmap (stars->b); }
void draw_door_top (ALLEGRO_BITMAP *bitmap, struct pos *p, enum em em, enum vm vm) { set_target_bitmap (bitmap); al_set_clipping_rectangle (PLACE_WIDTH * (p->place + 1), PLACE_HEIGHT * p->floor - 12, 25, 15); draw_door_right (bitmap, p, em, vm); al_reset_clipping_rectangle (); }
void draw_pattern (ALLEGRO_BITMAP *bitmap, int ox, int oy, int w, int h, ALLEGRO_COLOR color_0, ALLEGRO_COLOR color_1) { int x, y; set_target_bitmap (bitmap); al_lock_bitmap (bitmap, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE); for (y = oy; y < oy + h; y++) for (x = ox; x < ox + w; x++) al_put_pixel (x, y, (x % 2 != y % 2) ? color_0 : color_1); al_unlock_bitmap (bitmap); }
void pop_clipping_rectangle (void) { assert (clipping_rectangle_stack_nmemb > 0); size_t i = clipping_rectangle_stack_nmemb - 1; ALLEGRO_BITMAP *bitmap = clipping_rectangle_stack[i].bitmap; int x = clipping_rectangle_stack[i].x; int y = clipping_rectangle_stack[i].y; int w = clipping_rectangle_stack[i].w; int h = clipping_rectangle_stack[i].h; set_target_bitmap (bitmap); al_set_clipping_rectangle (x, y, w, h); clipping_rectangle_stack_nmemb--; }
void draw_bitmap_region (ALLEGRO_BITMAP *from, ALLEGRO_BITMAP *to, float sx, float sy, float sw, float sh, float dx, float dy, int flags) { merge_drawn_rectangle (to, dx, dy, sw, sh); set_target_bitmap (to); int cx, cy, cw, ch; al_get_clipping_rectangle (&cx, &cy, &cw, &ch); if (cw <= 0 || ch <= 0) return; al_draw_bitmap_region (from, sx, sy, sw, sh, dx, dy, flags); }
bool merge_clipping_rectangle (ALLEGRO_BITMAP *bitmap, int x, int y, int w, int h) { assert (clipping_rectangle_stack_nmemb > 0); int i; for (i = clipping_rectangle_stack_nmemb - 1; i >= 0 && clipping_rectangle_stack[i].bitmap != bitmap; i--); if (i < 0) return false; set_target_bitmap (clipping_rectangle_stack[i].bitmap); /* get current */ int cx, cy, cw, ch; al_get_clipping_rectangle (&cx, &cy, &cw, &ch); /* union */ int xr, yr, wr, hr; union_rectangle (x, y, w, h, cx, cy, cw, ch, &xr, &yr, &wr, &hr); /* intersection */ if (! ignore_clipping_rectangle_intersection) { int xs = clipping_rectangle_stack[i].x; int ys = clipping_rectangle_stack[i].y; int ws = clipping_rectangle_stack[i].w; int hs = clipping_rectangle_stack[i].h; intersection_rectangle (xr, yr, wr, hr, xs, ys, ws, hs, &xr, &yr, &wr, &hr); } /* set new */ al_set_clipping_rectangle (xr, yr, wr, hr); return true; }
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_bottom_text (ALLEGRO_BITMAP *bitmap, char *text, int priority) { static char *current_text = NULL; static int cur_priority = INT_MIN; static int text_offset = 0; static int dir = 0; static uint64_t cycle = 0; if (bitmap == NULL && priority < cur_priority && bottom_text_timer < BOTTOM_TEXT_DURATION) return; if (text) { if (current_text) { if (strcmp (text, current_text)) { text_offset = 0; dir = 0; cycle = 0; } al_free (current_text); } xasprintf (¤t_text, "%s", text); bottom_text_timer = 1; cur_priority = priority; } else if (bottom_text_timer > BOTTOM_TEXT_DURATION || ! bitmap) { bottom_text_timer = 0; cur_priority = INT_MIN; } else if (bottom_text_timer) { ALLEGRO_COLOR bg_color; switch (vm) { case CGA: bg_color = C_MSG_LINE_COLOR; break; case EGA: bg_color = E_MSG_LINE_COLOR; break; case VGA: bg_color = V_MSG_LINE_COLOR; break; } if (strlen (current_text) > BOTTOM_TEXT_MAX_LENGTH) { if (cycle++ % 2) { if (dir % 2) { if (strlen (current_text + text_offset) > BOTTOM_TEXT_MAX_LENGTH) text_offset++; else dir = (dir + 1) % 2; } else { if (text_offset > 0) text_offset--; else dir = (dir + 1) % 2; } } } char str[BOTTOM_TEXT_MAX_LENGTH + 1]; strncpy (str, current_text + text_offset, BOTTOM_TEXT_MAX_LENGTH); str[BOTTOM_TEXT_MAX_LENGTH] = '\0'; set_target_bitmap (bitmap); al_draw_filled_rectangle (0, CUTSCENE_HEIGHT - 8, CUTSCENE_WIDTH, CUTSCENE_HEIGHT, bg_color); draw_text (bitmap, str, CUTSCENE_WIDTH / 2.0, CUTSCENE_HEIGHT - 7, ALLEGRO_ALIGN_CENTRE); } }
void draw_text (ALLEGRO_BITMAP *bitmap, char const *text, float x, float y, int flags) { set_target_bitmap (bitmap); al_draw_text (builtin_font, WHITE, x, y, flags, text); }
void clear_bitmap (ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR color) { set_target_bitmap (bitmap); al_clear_to_color (color); }
void set_target_backbuffer (ALLEGRO_DISPLAY *display) { set_target_bitmap (al_get_backbuffer (display)); }