#include "render.h" static struct { Colour pixels[renderer_w * renderer_h]; } renderer; Colour make_colour(unsigned rgb, unsigned char a) { Colour r; r.r = (unsigned char)(rgb >> 16); r.g = (unsigned char)(rgb >> 8); r.b = (unsigned char)rgb; r.a = a; return r; } Colour make_black() { Colour r = { 0, 0, 0, 255 }; return r; } Colour make_white() { return make_colour(0xffffff, 255); } void init_bitmap( Bitmap* bitmap, Colour* pixels, int w, int h ) { bitmap->pixels = pixels; bitmap->w = w; bitmap->h = h; } void init_renderer() { } void renderer_begin_frame() { int i; for (i = 0; i < renderer_w * renderer_h; i++) { renderer.pixels[i] = make_black(); } } Colour* get_render_pixels() { return renderer.pixels; } Colour blend(Colour dst, Colour src) { int ima; ima = 0xff - src.a; dst.r = (unsigned char)(((src.r * src.a) + (dst.r * ima)) >> 8); dst.g = (unsigned char)(((src.g * src.a) + (dst.g * ima)) >> 8); dst.b = (unsigned char)(((src.b * src.a) + (dst.b * ima)) >> 8); return dst; } Colour blend_mod(Colour dst, Colour src, Colour mod) { int ima; src.a = (src.a * mod.a) >> 8; ima = 0xff - src.a; dst.r = (unsigned char)(((src.r * mod.r * src.a) >> 16) + ((dst.r * ima) >> 8)); dst.g = (unsigned char)(((src.g * mod.g * src.a) >> 16) + ((dst.g * ima) >> 8)); dst.b = (unsigned char)(((src.b * mod.b * src.a) >> 16) + ((dst.b * ima) >> 8)); return dst; } void init_font( BM_Font* font, const Bitmap* bmp, int char_w, int char_h, int chars_across ) { font->bmp = bmp; font->char_w = char_w; font->char_h = char_h; font->chars_across = chars_across; } void rfont_char(const BM_Font* font, int x, int y, char c) { Rectangle rect; c -= ' '; rect.x = (c % font->chars_across) * font->char_w; rect.y = (c / font->chars_across) * font->char_h; rect.w = font->char_w; rect.h = font->char_h; render_bitmap(font->bmp, x, y, &rect); } void rfont_char_col( const BM_Font* font, int x, int y, char c, Colour colour ) { Rectangle rect; c -= ' '; rect.x = (c % font->chars_across) * font->char_w; rect.y = (c / font->chars_across) * font->char_h; rect.w = font->char_w; rect.h = font->char_h; render_bitmap_col(font->bmp, x, y, &rect, colour); } void rfont_text( const BM_Font* font, int x, int y, const char* text ) { const char* c; for (c = text; *c; c++) { rfont_char(font, x, y, *c); x += font->char_w; } } void rfont_text_col( const BM_Font* font, int x, int y, const char* text, Colour colour ) { const char* c; for (c = text; *c; c++) { rfont_char_col(font, x, y, *c, colour); x += font->char_w; } } void render_bitmap( const Bitmap* bitmap, int x, int y, const Rectangle* rect ) { int i, j, stride, sstride, n; Colour* dst; const Colour* src; Rectangle sub; sub = *rect; if (sub.w <= 0) { return; } if (sub.h <= 0) { return; } if (sub.w > bitmap->w) { return; } if (sub.h > bitmap->h) { return; } if ((n = -x) > 0) { sub.w -= n; sub.x += n; x += n; } if ((n = -y) > 0) { sub.h -= n; sub.y += n; y += n; } if ((n = x + sub.w - renderer_w) > 0) { sub.w -= n; } if ((n = y + sub.h - renderer_h) > 0) { sub.h -= n; } if (sub.w <= 0) { return; } if (sub.h <= 0) { return; } dst = renderer.pixels + (x + y * renderer_w); src = bitmap->pixels + (sub.x + sub.y * bitmap->w); stride = renderer_w - sub.w; sstride = bitmap->w - sub.w; for (i = 0; i < sub.h; i++) { for (j = 0; j < sub.w; j++) { *dst = blend(*dst, *src); dst++; src++; } dst += stride; src += sstride; } } void render_bitmap_col( const Bitmap* bitmap, int x, int y, const Rectangle* rect, Colour colour ) { int i, j, stride, sstride, n; Colour* dst; const Colour* src; Rectangle sub; sub = *rect; if (sub.w <= 0) { return; } if (sub.h <= 0) { return; } if (sub.w > bitmap->w) { return; } if (sub.h > bitmap->h) { return; } if ((n = -x) > 0) { sub.w -= n; sub.x += n; x += n; } if ((n = -y) > 0) { sub.h -= n; sub.y += n; y += n; } if ((n = x + sub.w - renderer_w) > 0) { sub.w -= n; } if ((n = y + sub.h - renderer_h) > 0) { sub.h -= n; } if (sub.w <= 0) { return; } if (sub.h <= 0) { return; } dst = renderer.pixels + (x + y * renderer_w); src = bitmap->pixels + (sub.x + sub.y * bitmap->w); stride = renderer_w - sub.w; sstride = bitmap->w - sub.w; for (i = 0; i < sub.h; i++) { for (j = 0; j < sub.w; j++) { *dst = blend_mod(*dst, *src, colour); dst++; src++; } dst += stride; src += sstride; } } void blit( Bitmap* to, const Bitmap* from, int x, int y, const Rectangle* rect ) { int i, j, stride, sstride, n; Colour* dst; const Colour* src; Rectangle sub; sub = *rect; if (sub.w <= 0) { return; } if (sub.h <= 0) { return; } if (sub.w > from->w) { return; } if (sub.h > from->h) { return; } if ((n = -x) > 0) { sub.w -= n; sub.x += n; x += n; } if ((n = -y) > 0) { sub.h -= n; sub.y += n; y += n; } if ((n = x + sub.w - to->w) > 0) { sub.w -= n; } if ((n = y + sub.h - to->h) > 0) { sub.h -= n; } if (sub.w <= 0) { return; } if (sub.h <= 0) { return; } dst = to->pixels + (x + y * to->w); src = from->pixels + (sub.x + sub.y * from->w); stride = to->w - sub.w; sstride = from->w - sub.w; for (i = 0; i < sub.h; i++) { for (j = 0; j < sub.w; j++) { *dst = blend(*dst, *src); dst++; src++; } dst += stride; src += sstride; } } void blit_col( Bitmap* to, const Bitmap* from, int x, int y, const Rectangle* rect, Colour colour ) { int i, j, stride, sstride, n; Colour* dst; const Colour* src; Rectangle sub; sub = *rect; if (sub.w <= 0) { return; } if (sub.h <= 0) { return; } if (sub.w > from->w) { return; } if (sub.h > from->h) { return; } if ((n = -x) > 0) { sub.w -= n; sub.x += n; x += n; } if ((n = -y) > 0) { sub.h -= n; sub.y += n; y += n; } if ((n = x + sub.w - to->w) > 0) { sub.w -= n; } if ((n = y + sub.h - to->h) > 0) { sub.h -= n; } if (sub.w <= 0) { return; } if (sub.h <= 0) { return; } dst = to->pixels + (x + y * to->w); src = from->pixels + (sub.x + sub.y * from->w); stride = to->w - sub.w; sstride = from->w - sub.w; for (i = 0; i < sub.h; i++) { for (j = 0; j < sub.w; j++) { *dst = blend_mod(*dst, *src, colour); dst++; src++; } dst += stride; src += sstride; } }