2012-01-30 03:05:42 +04:00
|
|
|
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
|
|
|
*
|
|
|
|
* Graphics library
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <syscall.h>
|
|
|
|
#include <stdint.h>
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
#include <math.h>
|
2012-01-30 03:05:42 +04:00
|
|
|
#include "graphics.h"
|
2012-02-20 08:35:20 +04:00
|
|
|
#include "window.h"
|
2012-01-30 03:05:42 +04:00
|
|
|
|
|
|
|
/* Pointer to graphics memory */
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
void flip(gfx_context_t * ctx) {
|
|
|
|
memcpy(ctx->buffer, ctx->backbuffer, ctx->size);
|
|
|
|
}
|
2012-02-04 05:47:36 +04:00
|
|
|
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
void clearbuffer(gfx_context_t * ctx) {
|
|
|
|
memset(ctx->backbuffer, 0, ctx->size);
|
2012-02-04 05:47:36 +04:00
|
|
|
}
|
2012-01-30 03:05:42 +04:00
|
|
|
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
/* Deprecated */
|
|
|
|
gfx_context_t * init_graphics_fullscreen() {
|
|
|
|
gfx_context_t * out = malloc(sizeof(gfx_context_t));
|
|
|
|
out->width = syscall_getgraphicswidth();
|
|
|
|
out->height = syscall_getgraphicsheight();
|
|
|
|
out->depth = syscall_getgraphicsdepth();
|
|
|
|
out->size = GFX_H(out) * GFX_W(out) * GFX_B(out);
|
|
|
|
out->buffer = (void *)syscall_getgraphicsaddress();
|
|
|
|
out->backbuffer = out->buffer;
|
|
|
|
return out;
|
2012-02-04 05:47:36 +04:00
|
|
|
}
|
|
|
|
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
gfx_context_t * init_graphics_fullscreen_double_buffer() {
|
|
|
|
gfx_context_t * out = init_graphics_fullscreen();
|
|
|
|
out->backbuffer = malloc(sizeof(uint32_t) * GFX_W(out) * GFX_H(out));
|
|
|
|
return out;
|
2012-01-30 03:05:42 +04:00
|
|
|
}
|
|
|
|
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
gfx_context_t * init_graphics_window(window_t * window) {
|
|
|
|
gfx_context_t * out = malloc(sizeof(gfx_context_t));
|
|
|
|
out->width = window->width;
|
|
|
|
out->height = window->height;
|
|
|
|
out->depth = 32;
|
|
|
|
out->size = GFX_H(out) * GFX_W(out) * GFX_B(out);
|
|
|
|
out->buffer = window->buffer;
|
|
|
|
out->backbuffer = out->buffer;
|
|
|
|
return out;
|
2012-02-20 08:35:20 +04:00
|
|
|
}
|
|
|
|
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
gfx_context_t * init_graphics_window_double_buffer(window_t * window) {
|
|
|
|
gfx_context_t * out = init_graphics_window(window);
|
|
|
|
out->backbuffer = malloc(sizeof(uint32_t) * GFX_W(out) * GFX_H(out));
|
|
|
|
return out;
|
2012-02-20 08:35:20 +04:00
|
|
|
}
|
|
|
|
|
2012-01-30 03:05:42 +04:00
|
|
|
uint32_t rgb(uint8_t r, uint8_t g, uint8_t b) {
|
|
|
|
return 0xFF000000 + (r * 0x10000) + (g * 0x100) + (b * 0x1);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t alpha_blend(uint32_t bottom, uint32_t top, uint32_t mask) {
|
2012-04-18 00:34:34 +04:00
|
|
|
uint8_t a = _RED(mask);
|
2012-04-18 03:36:29 +04:00
|
|
|
uint8_t red = (_RED(bottom) * (256 - a) + _RED(top) * a) / 256;
|
|
|
|
uint8_t gre = (_GRE(bottom) * (256 - a) + _GRE(top) * a) / 256;
|
|
|
|
uint8_t blu = (_BLU(bottom) * (256 - a) + _BLU(top) * a) / 256;
|
2012-01-30 03:05:42 +04:00
|
|
|
return rgb(red,gre,blu);
|
|
|
|
}
|
|
|
|
|
2012-02-04 05:47:36 +04:00
|
|
|
void load_sprite(sprite_t * sprite, char * filename) {
|
|
|
|
/* Open the requested binary */
|
|
|
|
FILE * image = fopen(filename, "r");
|
|
|
|
size_t image_size= 0;
|
|
|
|
|
|
|
|
fseek(image, 0, SEEK_END);
|
|
|
|
image_size = ftell(image);
|
|
|
|
fseek(image, 0, SEEK_SET);
|
|
|
|
|
|
|
|
/* Alright, we have the length */
|
|
|
|
char * bufferb = malloc(image_size);
|
|
|
|
fread(bufferb, image_size, 1, image);
|
|
|
|
uint16_t x = 0; /* -> 212 */
|
|
|
|
uint16_t y = 0; /* -> 68 */
|
|
|
|
/* Get the width / height of the image */
|
|
|
|
signed int *bufferi = (signed int *)((uintptr_t)bufferb + 2);
|
|
|
|
uint32_t width = bufferi[4];
|
|
|
|
uint32_t height = bufferi[5];
|
|
|
|
uint16_t bpp = bufferi[6] / 0x10000;
|
|
|
|
uint32_t row_width = (bpp * width + 31) / 32 * 4;
|
|
|
|
/* Skip right to the important part */
|
|
|
|
size_t i = bufferi[2];
|
|
|
|
|
|
|
|
sprite->width = width;
|
|
|
|
sprite->height = height;
|
|
|
|
sprite->bitmap = malloc(sizeof(uint32_t) * width * height);
|
|
|
|
|
|
|
|
for (y = 0; y < height; ++y) {
|
|
|
|
for (x = 0; x < width; ++x) {
|
|
|
|
if (i > image_size) return;
|
|
|
|
/* Extract the color */
|
|
|
|
uint32_t color;
|
|
|
|
if (bpp == 24) {
|
2012-02-20 07:43:13 +04:00
|
|
|
color = (bufferb[i + 3 * x] & 0xFF) +
|
|
|
|
(bufferb[i+1 + 3 * x] & 0xFF) * 0x100 +
|
|
|
|
(bufferb[i+2 + 3 * x] & 0xFF) * 0x10000;
|
2012-02-04 05:47:36 +04:00
|
|
|
} else if (bpp == 32) {
|
2012-02-20 07:43:13 +04:00
|
|
|
color = (bufferb[i + 4 * x] & 0xFF) * 0x1000000 +
|
|
|
|
(bufferb[i+1 + 4 * x] & 0xFF) * 0x100 +
|
|
|
|
(bufferb[i+2 + 4 * x] & 0xFF) * 0x10000 +
|
|
|
|
(bufferb[i+3 + 4 * x] & 0xFF) * 0x1;
|
2012-02-04 05:47:36 +04:00
|
|
|
}
|
|
|
|
/* Set our point */
|
|
|
|
sprite->bitmap[(height - y - 1) * width + x] = color;
|
|
|
|
}
|
|
|
|
i += row_width;
|
|
|
|
}
|
|
|
|
free(bufferb);
|
|
|
|
}
|
|
|
|
|
2012-02-16 06:50:31 +04:00
|
|
|
static inline int32_t min(int32_t a, int32_t b) {
|
|
|
|
return (a < b) ? a : b;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int32_t max(int32_t a, int32_t b) {
|
|
|
|
return (a > b) ? a : b;
|
|
|
|
}
|
|
|
|
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
void draw_sprite(gfx_context_t * ctx, sprite_t * sprite, int32_t x, int32_t y) {
|
2012-02-16 06:50:31 +04:00
|
|
|
int32_t _left = max(x, 0);
|
|
|
|
int32_t _top = max(y, 0);
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
int32_t _right = min(x + sprite->width, ctx->width - 1);
|
|
|
|
int32_t _bottom = min(y + sprite->height, ctx->height - 1);
|
2012-02-04 05:47:36 +04:00
|
|
|
for (uint16_t _y = 0; _y < sprite->height; ++_y) {
|
|
|
|
for (uint16_t _x = 0; _x < sprite->width; ++_x) {
|
2012-02-16 06:50:31 +04:00
|
|
|
if (x + _x < _left || x + _x > _right || y + _y < _top || y + _y > _bottom)
|
|
|
|
continue;
|
2012-02-04 05:47:36 +04:00
|
|
|
if (sprite->alpha) {
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
GFX(ctx, x + _x, y + _y) = alpha_blend(GFX(ctx, x + _x, y + _y), SPRITE(sprite, _x, _y), SMASKS(sprite, _x, _y));
|
2012-02-04 05:47:36 +04:00
|
|
|
} else {
|
|
|
|
if (SPRITE(sprite,_x,_y) != sprite->blank) {
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
GFX(ctx, x + _x, y + _y) = SPRITE(sprite, _x, _y);
|
2012-02-04 05:47:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-17 23:25:03 +04:00
|
|
|
void draw_line(gfx_context_t * ctx, int32_t x0, int32_t x1, int32_t y0, int32_t y1, uint32_t color) {
|
2012-02-04 05:47:36 +04:00
|
|
|
int deltax = abs(x1 - x0);
|
|
|
|
int deltay = abs(y1 - y0);
|
|
|
|
int sx = (x0 < x1) ? 1 : -1;
|
|
|
|
int sy = (y0 < y1) ? 1 : -1;
|
|
|
|
int error = deltax - deltay;
|
|
|
|
while (1) {
|
2012-04-17 23:25:03 +04:00
|
|
|
if (x0 >= 0 && y0 >= 0 && x0 < ctx->width && y0 < ctx->height) {
|
|
|
|
GFX(ctx, x0, y0) = color;
|
|
|
|
}
|
|
|
|
if (x0 == x1 && y0 == y1) break;
|
|
|
|
int e2 = 2 * error;
|
|
|
|
if (e2 > -deltay) {
|
|
|
|
error -= deltay;
|
|
|
|
x0 += sx;
|
|
|
|
}
|
|
|
|
if (e2 < deltax) {
|
|
|
|
error += deltax;
|
|
|
|
y0 += sy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void draw_line_thick(gfx_context_t * ctx, int32_t x0, int32_t x1, int32_t y0, int32_t y1, uint32_t color, char thickness) {
|
|
|
|
int deltax = abs(x1 - x0);
|
|
|
|
int deltay = abs(y1 - y0);
|
|
|
|
int sx = (x0 < x1) ? 1 : -1;
|
|
|
|
int sy = (y0 < y1) ? 1 : -1;
|
|
|
|
int error = deltax - deltay;
|
|
|
|
while (1) {
|
|
|
|
for (char j = -thickness; j <= thickness; ++j) {
|
|
|
|
for (char i = -thickness; i <= thickness; ++i) {
|
|
|
|
if (x0 + i >= 0 && x0 + i < ctx->width && y0 + j >= 0 && y0 + j < ctx->height) {
|
|
|
|
GFX(ctx, x0 + i, y0 + j) = color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-02-04 05:47:36 +04:00
|
|
|
if (x0 == x1 && y0 == y1) break;
|
|
|
|
int e2 = 2 * error;
|
|
|
|
if (e2 > -deltay) {
|
|
|
|
error -= deltay;
|
|
|
|
x0 += sx;
|
|
|
|
}
|
|
|
|
if (e2 < deltax) {
|
|
|
|
error += deltax;
|
|
|
|
y0 += sy;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-17 23:25:03 +04:00
|
|
|
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 22:21:34 +04:00
|
|
|
void draw_fill(gfx_context_t * ctx, uint32_t color) {
|
|
|
|
for (uint16_t y = 0; y < ctx->height; ++y) {
|
|
|
|
for (uint16_t x = 0; x < ctx->width; ++x) {
|
|
|
|
GFX(ctx, x, y) = color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Bilinear filtering from Wikipedia */
|
|
|
|
uint32_t getBilinearFilteredPixelColor(sprite_t * tex, double u, double v) {
|
|
|
|
u *= tex->width;
|
|
|
|
v *= tex->height;
|
|
|
|
int x = floor(u);
|
|
|
|
int y = floor(v);
|
|
|
|
if (x >= tex->width) return 0;
|
|
|
|
if (y >= tex->height) return 0;
|
|
|
|
double u_ratio = u - x;
|
|
|
|
double v_ratio = v - y;
|
|
|
|
double u_o = 1 - u_ratio;
|
|
|
|
double v_o = 1 - v_ratio;
|
|
|
|
double r_ALP = 256;
|
|
|
|
if (tex->alpha) {
|
|
|
|
if (x == tex->width - 1 || y == tex->height - 1) return (SPRITE(tex,x,y) | 0xFF000000) & (0xFFFFFF + _RED(SMASKS(tex,x,y)) * 0x1000000);
|
|
|
|
r_ALP = (_RED(SMASKS(tex,x,y)) * u_o + _RED(SMASKS(tex,x+1,y)) * u_ratio) * v_o + (_RED(SMASKS(tex,x,y+1)) * u_o + _RED(SMASKS(tex,x+1,y+1)) * u_ratio) * v_ratio;
|
|
|
|
}
|
|
|
|
if (x == tex->width - 1 || y == tex->height - 1) return SPRITE(tex,x,y);
|
|
|
|
double r_RED = (_RED(SPRITE(tex,x,y)) * u_o + _RED(SPRITE(tex,x+1,y)) * u_ratio) * v_o + (_RED(SPRITE(tex,x,y+1)) * u_o + _RED(SPRITE(tex,x+1,y+1)) * u_ratio) * v_ratio;
|
|
|
|
double r_BLU = (_BLU(SPRITE(tex,x,y)) * u_o + _BLU(SPRITE(tex,x+1,y)) * u_ratio) * v_o + (_BLU(SPRITE(tex,x,y+1)) * u_o + _BLU(SPRITE(tex,x+1,y+1)) * u_ratio) * v_ratio;
|
|
|
|
double r_GRE = (_GRE(SPRITE(tex,x,y)) * u_o + _GRE(SPRITE(tex,x+1,y)) * u_ratio) * v_o + (_GRE(SPRITE(tex,x,y+1)) * u_o + _GRE(SPRITE(tex,x+1,y+1)) * u_ratio) * v_ratio;
|
|
|
|
|
|
|
|
return rgb(r_RED,r_GRE,r_BLU) & (0xFFFFFF + (int)r_ALP * 0x1000000);
|
|
|
|
}
|
|
|
|
|
|
|
|
void draw_sprite_scaled(gfx_context_t * ctx, sprite_t * sprite, uint16_t x, uint16_t y, uint16_t width, uint16_t height) {
|
|
|
|
int32_t _left = max(x, 0);
|
|
|
|
int32_t _top = max(y, 0);
|
|
|
|
int32_t _right = min(x + width, ctx->width - 1);
|
|
|
|
int32_t _bottom = min(y + height, ctx->height - 1);
|
|
|
|
for (uint16_t _y = 0; _y < height; ++_y) {
|
|
|
|
for (uint16_t _x = 0; _x < width; ++_x) {
|
|
|
|
if (x + _x < _left || x + _x > _right || y + _y < _top || y + _y > _bottom)
|
|
|
|
continue;
|
|
|
|
if (sprite->alpha) {
|
|
|
|
uint32_t n_color = getBilinearFilteredPixelColor(sprite, (double)_x / (double)width, (double)_y/(double)height);
|
|
|
|
uint32_t f_color = rgb(_ALP(n_color), 0, 0);
|
|
|
|
GFX(ctx, x + _x, y + _y) = alpha_blend(GFX(ctx, x + _x, y + _y), n_color, f_color);
|
|
|
|
} else {
|
|
|
|
GFX(ctx, x + _x, y + _y) = getBilinearFilteredPixelColor(sprite, (double)_x / (double)width, (double)_y/(double)height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|