diff --git a/src/rencache.c b/src/rencache.c index 143ae477..5523a30e 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -8,7 +8,7 @@ #define CELL_SIZE 96 #define COMMAND_BARE_SIZE offsetof(Command, text) -enum { SET_CLIP, DRAW_TEXT, DRAW_RECT, DRAW_TEXT_SUBPIXEL }; +enum { SET_CLIP, DRAW_TEXT, DRAW_RECT, DRAW_TEXT_SUBPIXEL, DRAW_IMAGE }; typedef struct { int8_t type; @@ -21,6 +21,7 @@ typedef struct { FontDesc *font_desc; CPReplaceTable *replacements; RenColor replace_color; + uint32_t image_id; /* FIXME: do not add a new field but use unions or alias another field. */ char text[0]; } Command; @@ -148,6 +149,20 @@ void rencache_draw_rect(RenCache *rc, RenRect rect, RenColor color) { } } + +void rencache_draw_image(RenCache *rc, int image_id, int x, int y, RenRect image_rect) { + RenRect rect = {x, y, image_rect.width, image_rect.height}; + if (!rects_overlap(rc->screen_rect, rect)) { return; } + Command *cmd = push_command(rc, DRAW_IMAGE, COMMAND_BARE_SIZE + 2 * sizeof(int)); + int *img_coord = (int *) cmd->text; + if (cmd) { + cmd->rect = rect; + cmd->image_id = image_id; + img_coord[0] = image_rect.x; + img_coord[1] = image_rect.y; + } +} + int rencache_draw_text(RenCache *rc, lua_State *L, FontDesc *font_desc, int font_index, const char *text, int x, int y, RenColor color, bool draw_subpixel, CPReplaceTable *replacements, RenColor replace_color) @@ -268,6 +283,7 @@ void rencache_end_frame(RenCache *rc, lua_State *L) { /* redraw updated regions */ for (int i = 0; i < rect_count; i++) { + const int *image_coord; /* draw */ RenRect r = rc->rect_buf[i]; ren_set_clip_rect(rc->ren_surface, r); @@ -292,6 +308,10 @@ void rencache_end_frame(RenCache *rc, lua_State *L) { cmd->subpixel_scale * cmd->rect.x + cmd->x_subpixel_offset, cmd->rect.y, cmd->color, cmd->replacements, cmd->replace_color); break; + case DRAW_IMAGE: + image_coord = (const int *) cmd->text; + ren_draw_image(rc->ren_surface, cmd->image_id, image_coord[0], image_coord[1], cmd->rect); + break; } } diff --git a/src/renderer.c b/src/renderer.c index 12042f55..15fd2258 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -127,14 +127,28 @@ void ren_resize_window() { renwin_resize_surface(&window_renderer); } +/* FIXME: all this stuff. */ +#define IMAGE_CELL_SIZE 96 +#define IMAGE_CELL_X 80 + +static inline int image_cell_idx(int x, int y) { + return x + y * IMAGE_CELLS_X; +} void ren_update_rects(RenSurface *ren, RenRect *rects, int count) { if (ren->type == SurfaceTexture) { - // FIXME: this is now a NOP because we don't present the rectangles into - // the screen neither we upload them into a texture. - // The problem is that the information about the update rects is lost for - // later when the rendering commands are sent to the window. - // rentex_update_rects((RenTexture *) ren->data, rects, count); + RenTexture *rentex = (RenTexture *) ren->data; + for (int i = 0; i < count; i++) { + RenRect irect = image_rect_to_index(rects[i]); + /* Increment the revision number for all cells that needs to be updated, + i.e. those that overlaps with one of the update rectangles. */ + for (int x = irect.x; x < irect.x + irect.width; x++) { + for (int y = irect.y; y < irect.y + irect.height; y++) { + int idx = image_cell_idx(x, y); + rentex->revisions[idx] += 1: + } + } + } } else { RenWindow *renwin = (RenWindow *) ren->data; if (renwin->initial_frame) { @@ -438,3 +452,12 @@ int ren_get_font_subpixel_scale(RenSurface *ren, FontDesc *font_desc) { RenFont *font = font_desc_get_font_at_scale(font_desc, surface_scale); return FR_Subpixel_Scale(font->renderer) * surface_scale; } + +void ren_draw_image(RenSurface *ren, uint32_t image_id, int image_x, int image_y, RenRect rect) { + SDL_Rect image_rect; + SDL_Surface *image_surf = image_get(image_id, &image_rect, image_x, image_y); + SDL_Surface *surface = ren_surface_get_surface(ren); + SDL_Rect dst_rect = {rect.x, rect.y, 0, 0}; + SDL_BlitSurface(image_surf,image_rect, surface, &dst_rect); +} + diff --git a/src/renderer.h b/src/renderer.h index c671005b..b8e4a3bd 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -21,10 +21,13 @@ enum { typedef struct { uint8_t b, g, r, a; } RenColor; typedef struct { int x, y, width, height; } RenRect; +// FIXME: ensure this Max is okay or use dynamic allocation. +#define TEXTURE_REVS_MAX 256 struct RenTexture { SDL_Surface *surface; int surface_scale; RenRect clip; /* Clipping rect in pixel coordinates. */ + int revisions[TEXTURE_REVS_MAX]; }; typedef struct RenTexture RenTexture; @@ -73,6 +76,7 @@ int ren_font_subpixel_round(int width, int subpixel_scale, int orientation); void ren_draw_rect(RenSurface *ren, RenRect rect, RenColor color); void ren_draw_text(RenSurface *ren, FontDesc *font_desc, const char *text, int x, int y, RenColor color, CPReplaceTable *replacements, RenColor replace_color); void ren_draw_text_subpixel(RenSurface *ren, FontDesc *font_desc, const char *text, int x_subpixel, int y, RenColor color, CPReplaceTable *replacements, RenColor replace_color); +void ren_draw_image(RenSurface *ren, uint32_t image_id, int image_x, int image_y, RenRect rect); void ren_cp_replace_init(CPReplaceTable *rep_table); void ren_cp_replace_free(CPReplaceTable *rep_table);