summaryrefslogtreecommitdiff
path: root/libwinnie/src/gfx.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libwinnie/src/gfx.cc')
-rw-r--r--libwinnie/src/gfx.cc566
1 files changed, 296 insertions, 270 deletions
diff --git a/libwinnie/src/gfx.cc b/libwinnie/src/gfx.cc
index e35f080..a054e4c 100644
--- a/libwinnie/src/gfx.cc
+++ b/libwinnie/src/gfx.cc
@@ -18,299 +18,325 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
Author: Eleni Maria Stea <elene.mst@gmail.com>
*/
+#include <algorithm>
+#include <inttypes.h>
#include <stdio.h>
#include <string.h>
-#include <inttypes.h>
-#include <algorithm>
#include "geom.h"
#include "sdl/gfx.h"
// used by the polygon rasterizer
-#define MAX_SCANLINES 2048
+#define MAX_SCANLINES 2048
static int32_t left_fx[MAX_SCANLINES], right_fx[MAX_SCANLINES];
-
-void clear_screen(int r, int g, int b)
+void
+clear_screen(int r, int g, int b)
{
- Rect screen_rect = get_screen_size();
- fill_rect(screen_rect, r, g, b);
+ Rect screen_rect = get_screen_size();
+ fill_rect(screen_rect, r, g, b);
}
-void fill_rect(const Rect &rect, int r, int g, int b)
+void
+fill_rect(const Rect &rect, int r, int g, int b)
{
- Rect drect = rect;
- Rect screen_rect = get_screen_size();
- Rect clipping_rect = get_clipping_rect();
-
- if(drect.x < clipping_rect.x) {
- drect.width -= clipping_rect.x - drect.x;
- drect.x = clipping_rect.x;
- }
-
- if(drect.y < clipping_rect.y) {
- drect.height -= clipping_rect.y - drect.y;
- drect.y = clipping_rect.y;
- }
-
- if(drect.x + drect.width >= clipping_rect.x + clipping_rect.width) {
- drect.width = clipping_rect.width + clipping_rect.x - drect.x;
- }
-
- if(drect.y + drect.height >= clipping_rect.y + clipping_rect.height) {
- drect.height = clipping_rect.height + clipping_rect.y - drect.y;
- }
-
- unsigned char *fb = get_framebuffer() + (drect.x + screen_rect.width * drect.y) * 4;
- for(int i=0; i<drect.height; i++) {
- for(int j=0; j<drect.width; j++) {
- fb[j * 4] = b;
- fb[j * 4 + 1] = g;
- fb[j * 4 + 2] = r;
- }
- fb += screen_rect.width * 4;
- }
+ Rect drect = rect;
+ Rect screen_rect = get_screen_size();
+ Rect clipping_rect = get_clipping_rect();
+
+ if (drect.x < clipping_rect.x) {
+ drect.width -= clipping_rect.x - drect.x;
+ drect.x = clipping_rect.x;
+ }
+
+ if (drect.y < clipping_rect.y) {
+ drect.height -= clipping_rect.y - drect.y;
+ drect.y = clipping_rect.y;
+ }
+
+ if (drect.x + drect.width >= clipping_rect.x + clipping_rect.width) {
+ drect.width = clipping_rect.width + clipping_rect.x - drect.x;
+ }
+
+ if (drect.y + drect.height >= clipping_rect.y + clipping_rect.height) {
+ drect.height = clipping_rect.height + clipping_rect.y - drect.y;
+ }
+
+ unsigned char *fb
+ = get_framebuffer() + (drect.x + screen_rect.width * drect.y) * 4;
+ for (int i = 0; i < drect.height; i++) {
+ for (int j = 0; j < drect.width; j++) {
+ fb[j * 4] = b;
+ fb[j * 4 + 1] = g;
+ fb[j * 4 + 2] = r;
+ }
+ fb += screen_rect.width * 4;
+ }
}
-void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
- const Rect &dest_rect, int dest_x, int dest_y)
+void
+blit(unsigned char *src_img,
+ const Rect &src_rect,
+ unsigned char *dest_img,
+ const Rect &dest_rect,
+ int dest_x,
+ int dest_y)
{
- int red_offs, green_offs, blue_offs;
- get_rgb_order(&red_offs, &green_offs, &blue_offs);
-
- Rect irect = rect_intersection(get_clipping_rect(), dest_rect);
-
- int src_xoffs = 0;
- int src_yoffs = 0;
- int width = src_rect.width;
- int height = src_rect.height;
-
- int xoffs = dest_x - irect.x;
- if(xoffs < 0) {
- dest_x = irect.x;
- width += xoffs;
- src_xoffs = -xoffs;
- }
-
- int yoffs = dest_y - irect.y;
- if(yoffs < 0) {
- dest_y = irect.y;
- height += yoffs;
- src_yoffs = -yoffs;
- }
-
- int xend = dest_x + width;
- if(xend >= irect.x + irect.width) {
- width -= xend - (irect.x + irect.width);
- }
-
- int yend = dest_y + height;
- if(yend >= irect.y + irect.height) {
- height -= yend - (irect.y + irect.height);
- }
-
- if(width <= 0 || height <= 0) {
- return;
- }
-
- unsigned char *sptr = src_img + ((src_rect.y + src_yoffs) * src_rect.width + src_rect.x + src_xoffs) * 4;
- unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
-
- for(int i=0; i<height; i++) {
- for(int j=0; j<width; j++) {
- dptr[j * 4 + red_offs] = sptr[j * 4];
- dptr[j * 4 + green_offs] = sptr[j * 4 + 1];
- dptr[j * 4 + blue_offs] = sptr[j * 4 + 2];
- }
- sptr += src_rect.width * 4;
- dptr += dest_rect.width * 4;
- }
+ int red_offs, green_offs, blue_offs;
+ get_rgb_order(&red_offs, &green_offs, &blue_offs);
+
+ Rect irect = rect_intersection(get_clipping_rect(), dest_rect);
+
+ int src_xoffs = 0;
+ int src_yoffs = 0;
+ int width = src_rect.width;
+ int height = src_rect.height;
+
+ int xoffs = dest_x - irect.x;
+ if (xoffs < 0) {
+ dest_x = irect.x;
+ width += xoffs;
+ src_xoffs = -xoffs;
+ }
+
+ int yoffs = dest_y - irect.y;
+ if (yoffs < 0) {
+ dest_y = irect.y;
+ height += yoffs;
+ src_yoffs = -yoffs;
+ }
+
+ int xend = dest_x + width;
+ if (xend >= irect.x + irect.width) {
+ width -= xend - (irect.x + irect.width);
+ }
+
+ int yend = dest_y + height;
+ if (yend >= irect.y + irect.height) {
+ height -= yend - (irect.y + irect.height);
+ }
+
+ if (width <= 0 || height <= 0) {
+ return;
+ }
+
+ unsigned char *sptr
+ = src_img
+ + ((src_rect.y + src_yoffs) * src_rect.width + src_rect.x + src_xoffs)
+ * 4;
+ unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ dptr[j * 4 + red_offs] = sptr[j * 4];
+ dptr[j * 4 + green_offs] = sptr[j * 4 + 1];
+ dptr[j * 4 + blue_offs] = sptr[j * 4 + 2];
+ }
+ sptr += src_rect.width * 4;
+ dptr += dest_rect.width * 4;
+ }
}
-void blit_key(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
- const Rect &dest_rect, int dest_x, int dest_y, int key_r, int key_g, int key_b)
+void
+blit_key(unsigned char *src_img,
+ const Rect &src_rect,
+ unsigned char *dest_img,
+ const Rect &dest_rect,
+ int dest_x,
+ int dest_y,
+ int key_r,
+ int key_g,
+ int key_b)
{
- int red_offs, green_offs, blue_offs;
- get_rgb_order(&red_offs, &green_offs, &blue_offs);
-
- Rect irect = rect_intersection(get_clipping_rect(), dest_rect);
-
- int src_xoffs = 0;
- int src_yoffs = 0;
- int width = src_rect.width;
- int height = src_rect.height;
-
- int xoffs = dest_x - irect.x;
- if(xoffs < 0) {
- dest_x = irect.x;
- width += xoffs;
- src_xoffs = -xoffs;
- }
-
- int yoffs = dest_y - irect.y;
- if(yoffs < 0) {
- dest_y = irect.y;
- height += yoffs;
- src_yoffs = -yoffs;
- }
-
- int xend = dest_x + width;
- if(xend >= irect.x + irect.width) {
- width -= xend - (irect.x + irect.width);
- }
-
- int yend = dest_y + height;
- if(yend >= irect.y + irect.height) {
- height -= yend - (irect.y + irect.height);
- }
-
- if(width <= 0 || height <= 0) {
- return;
- }
-
- unsigned char *sptr = src_img + ((src_rect.y + src_yoffs) * src_rect.width + src_rect.x + src_xoffs) * 4;
- unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
-
- for(int i=0; i<height; i++) {
- for(int j=0; j<width; j++) {
- int r = sptr[j * 4];
- int g = sptr[j * 4 + 1];
- int b = sptr[j * 4 + 2];
-
- if(r != key_r || g != key_g || b != key_b) {
- dptr[j * 4 + red_offs] = r;
- dptr[j * 4 + green_offs] = g;
- dptr[j * 4 + blue_offs] = b;
- }
- }
-
- sptr += src_rect.width * 4;
- dptr += dest_rect.width * 4;
- }
+ int red_offs, green_offs, blue_offs;
+ get_rgb_order(&red_offs, &green_offs, &blue_offs);
+
+ Rect irect = rect_intersection(get_clipping_rect(), dest_rect);
+
+ int src_xoffs = 0;
+ int src_yoffs = 0;
+ int width = src_rect.width;
+ int height = src_rect.height;
+
+ int xoffs = dest_x - irect.x;
+ if (xoffs < 0) {
+ dest_x = irect.x;
+ width += xoffs;
+ src_xoffs = -xoffs;
+ }
+
+ int yoffs = dest_y - irect.y;
+ if (yoffs < 0) {
+ dest_y = irect.y;
+ height += yoffs;
+ src_yoffs = -yoffs;
+ }
+
+ int xend = dest_x + width;
+ if (xend >= irect.x + irect.width) {
+ width -= xend - (irect.x + irect.width);
+ }
+
+ int yend = dest_y + height;
+ if (yend >= irect.y + irect.height) {
+ height -= yend - (irect.y + irect.height);
+ }
+
+ if (width <= 0 || height <= 0) {
+ return;
+ }
+
+ unsigned char *sptr
+ = src_img
+ + ((src_rect.y + src_yoffs) * src_rect.width + src_rect.x + src_xoffs)
+ * 4;
+ unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ int r = sptr[j * 4];
+ int g = sptr[j * 4 + 1];
+ int b = sptr[j * 4 + 2];
+
+ if (r != key_r || g != key_g || b != key_b) {
+ dptr[j * 4 + red_offs] = r;
+ dptr[j * 4 + green_offs] = g;
+ dptr[j * 4 + blue_offs] = b;
+ }
+ }
+
+ sptr += src_rect.width * 4;
+ dptr += dest_rect.width * 4;
+ }
}
-void draw_line(Pixmap *pixmap, int x0, int y0, int x1, int y1, int r, int g, int b)
+void
+draw_line(Pixmap *pixmap, int x0, int y0, int x1, int y1, int r, int g, int b)
{
- int red_offs = 0, green_offs = 1, blue_offs = 2;
- if(pixmap == get_framebuffer_pixmap()) {
- get_rgb_order(&red_offs, &green_offs, &blue_offs);
- }
-
- unsigned char *ptr = pixmap->pixels + (y0 * pixmap->width + x0) * 4;
-
- int dx = x1 - x0;
- int dy = y1 - y0;
-
- int x_inc = 4;
- int y_inc = pixmap->width * 4;
-
- if(dx < 0) {
- x_inc = -x_inc;
- dx = -dx;
- }
- if(dy < 0) {
- y_inc = -y_inc;
- dy = -dy;
- }
-
- if(dx > dy) {
- int error = (dy << 1) - dx;
- for(int i=0; i<=dx; i++) {
- ptr[red_offs] = r;
- ptr[green_offs] = g;
- ptr[blue_offs] = b;
- if(error >= 0) {
- error -= dx << 1;
- ptr += y_inc;
- }
- error += dy << 1;
- ptr += x_inc;
- }
- } else {
- int error = (dx << 1) - dy;
- for(int i=0; i<=dy; i++) {
- ptr[red_offs] = r;
- ptr[green_offs] = g;
- ptr[blue_offs] = b;
- if(error >= 0) {
- error -= dy << 1;
- ptr += x_inc;
- }
- error += dx << 1;
- ptr += y_inc;
- }
- }
+ int red_offs = 0, green_offs = 1, blue_offs = 2;
+ if (pixmap == get_framebuffer_pixmap()) {
+ get_rgb_order(&red_offs, &green_offs, &blue_offs);
+ }
+
+ unsigned char *ptr = pixmap->pixels + (y0 * pixmap->width + x0) * 4;
+
+ int dx = x1 - x0;
+ int dy = y1 - y0;
+
+ int x_inc = 4;
+ int y_inc = pixmap->width * 4;
+
+ if (dx < 0) {
+ x_inc = -x_inc;
+ dx = -dx;
+ }
+ if (dy < 0) {
+ y_inc = -y_inc;
+ dy = -dy;
+ }
+
+ if (dx > dy) {
+ int error = (dy << 1) - dx;
+ for (int i = 0; i <= dx; i++) {
+ ptr[red_offs] = r;
+ ptr[green_offs] = g;
+ ptr[blue_offs] = b;
+ if (error >= 0) {
+ error -= dx << 1;
+ ptr += y_inc;
+ }
+ error += dy << 1;
+ ptr += x_inc;
+ }
+ } else {
+ int error = (dx << 1) - dy;
+ for (int i = 0; i <= dy; i++) {
+ ptr[red_offs] = r;
+ ptr[green_offs] = g;
+ ptr[blue_offs] = b;
+ if (error >= 0) {
+ error -= dy << 1;
+ ptr += x_inc;
+ }
+ error += dx << 1;
+ ptr += y_inc;
+ }
+ }
}
-void draw_polygon(Pixmap *pixmap, int *vpos, int *vtex, int num_verts, int r, int g, int b)
+void
+draw_polygon(
+ Pixmap *pixmap, int *vpos, int *vtex, int num_verts, int r, int g, int b)
{
- int roffs = 0, goffs = 1, boffs = 2;
- if(pixmap == get_framebuffer_pixmap()) {
- get_rgb_order(&roffs, &goffs, &boffs);
- }
-
- int ystart = pixmap->height, yend = 0;
-
- for(int i=0; i<num_verts; i++) {
- int next = (i + 1) % num_verts;
- int x0 = vpos[i * 2];
- int y0 = vpos[i * 2 + 1];
- int x1 = vpos[next * 2];
- int y1 = vpos[next * 2 + 1];
-
- int dx = x1 - x0;
- int dy = y1 - y0;
-
- if(dy == 0)
- continue;
-
- /* continue in 24.8 fixed point */
- int32_t fslope = ((int32_t)dx << 8) / (int32_t)abs(dy);
- int32_t fx = x0 << 8;
-
- if(dy >= 0) {
- for(int j=y0; j<=y1; j++) {
- right_fx[j] = fx;
- fx += fslope;
- }
- } else {
- for(int j=y0; j>=y1; j--) {
- left_fx[j] = fx;
- fx += fslope;
- }
- }
-
- ystart = std::min(ystart, std::min(y0, y1));
- yend = std::max(yend, std::max(y0, y1));
- }
-
- if(ystart < 0) ystart = 0;
- if(yend > pixmap->height) yend = pixmap->height;
-
- for(int i=ystart; i<yend; i++) {
- int x = (left_fx[i] + (1 << 7)) >> 8;
- int dx = (right_fx[i] - left_fx[i]) >> 8;
-
- // accept polygons of either order
- if(dx < 0) {
- x = (right_fx[i] + (1 << 7)) >> 8;
- dx = -dx;
- }
-
- if(x < 0) {
- dx += x;
- x = 0;
- }
- if(x + dx >= pixmap->width) {
- dx = pixmap->width - x;
- }
- unsigned char *pixptr = pixmap->pixels + (i * pixmap->width + x) * 4;
-
- for(int j=0; j<=dx; j++) {
- pixptr[roffs] = r;
- pixptr[goffs] = g;
- pixptr[boffs] = b;
- pixptr += 4;
- }
- }
+ int roffs = 0, goffs = 1, boffs = 2;
+ if (pixmap == get_framebuffer_pixmap()) {
+ get_rgb_order(&roffs, &goffs, &boffs);
+ }
+
+ int ystart = pixmap->height, yend = 0;
+
+ for (int i = 0; i < num_verts; i++) {
+ int next = (i + 1) % num_verts;
+ int x0 = vpos[i * 2];
+ int y0 = vpos[i * 2 + 1];
+ int x1 = vpos[next * 2];
+ int y1 = vpos[next * 2 + 1];
+
+ int dx = x1 - x0;
+ int dy = y1 - y0;
+
+ if (dy == 0)
+ continue;
+
+ /* continue in 24.8 fixed point */
+ int32_t fslope = ((int32_t) dx << 8) / (int32_t) abs(dy);
+ int32_t fx = x0 << 8;
+
+ if (dy >= 0) {
+ for (int j = y0; j <= y1; j++) {
+ right_fx[j] = fx;
+ fx += fslope;
+ }
+ } else {
+ for (int j = y0; j >= y1; j--) {
+ left_fx[j] = fx;
+ fx += fslope;
+ }
+ }
+
+ ystart = std::min(ystart, std::min(y0, y1));
+ yend = std::max(yend, std::max(y0, y1));
+ }
+
+ if (ystart < 0)
+ ystart = 0;
+ if (yend > pixmap->height)
+ yend = pixmap->height;
+
+ for (int i = ystart; i < yend; i++) {
+ int x = (left_fx[i] + (1 << 7)) >> 8;
+ int dx = (right_fx[i] - left_fx[i]) >> 8;
+
+ // accept polygons of either order
+ if (dx < 0) {
+ x = (right_fx[i] + (1 << 7)) >> 8;
+ dx = -dx;
+ }
+
+ if (x < 0) {
+ dx += x;
+ x = 0;
+ }
+ if (x + dx >= pixmap->width) {
+ dx = pixmap->width - x;
+ }
+ unsigned char *pixptr = pixmap->pixels + (i * pixmap->width + x) * 4;
+
+ for (int j = 0; j <= dx; j++) {
+ pixptr[roffs] = r;
+ pixptr[goffs] = g;
+ pixptr[boffs] = b;
+ pixptr += 4;
+ }
+ }
}