# HG changeset patch # User John Tsiombikas # Date 1403403370 -10800 # Node ID b0ed38f13261ce6da063c0100fd90d0586101d04 # Parent fb0a0d6a8b5271c28e58f7a4918bf95f444ff26f working on the rasterizer diff -r fb0a0d6a8b52 -r b0ed38f13261 Makefile.sdl --- a/Makefile.sdl Thu Jun 19 05:53:46 2014 +0300 +++ b/Makefile.sdl Sun Jun 22 05:16:10 2014 +0300 @@ -4,7 +4,9 @@ dep = $(obj:.o=.d) bin = trycatch -CFLAGS = -pedantic -Wall -g `pkg-config sdl --cflags` -Isrc -Isrc/sdlsys +warn = -Wall -Wno-unused-function + +CFLAGS = -pedantic $(warn) -g `pkg-config sdl --cflags` -Isrc -Isrc/sdlsys LDFLAGS = `pkg-config sdl --libs` -lm $(bin): $(obj) @@ -13,6 +15,11 @@ %.x86.o: %.c $(CC) $(CFLAGS) -o $@ -c $< +-include $(dep) + +%.x86.d: %.c + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ + .PHONY: clean clean: rm -f $(obj) $(bin) diff -r fb0a0d6a8b52 -r b0ed38f13261 src/config.h --- a/src/config.h Thu Jun 19 05:53:46 2014 +0300 +++ b/src/config.h Sun Jun 22 05:16:10 2014 +0300 @@ -1,8 +1,24 @@ #ifndef CONFIG_H_ #define CONFIG_H_ -#define GFX_MODE VMODE_LFB_160x128_16 +#include "gbasys.h" + +/* 3: 240x160:16 + * 4: 240x160:8 + * 5: 160x128:16 + */ +#define GFX_MODE 5 + +#if (GFX_MODE == 3) || (GFX_MODE == 4) +#define WIDTH 240 +#define HEIGHT 160 +#else #define WIDTH 160 #define HEIGHT 128 +#endif + +#if (GFX_MODE == 4) +#define PALMODE +#endif #endif /* CONFIG_H_ */ diff -r fb0a0d6a8b52 -r b0ed38f13261 src/game.c --- a/src/game.c Thu Jun 19 05:53:46 2014 +0300 +++ b/src/game.c Sun Jun 22 05:16:10 2014 +0300 @@ -4,23 +4,32 @@ #include "x3d.h" #include "sincos.h" #include "fixed.h" +#include "palman.h" + +static void draw_rect(int x, int y, int w, int h, uint16_t color); #define X16INT(x) ((x) << 16) static const int32_t poly[] = { - X16INT(80), X16INT(10), 0, - X16INT(140), X16INT(100), 0, - X16INT(40), X16INT(80), 0 + X16INT(120), X16INT(20), 0, + X16INT(200), X16INT(130), 0, + X16INT(40), X16INT(100), 0 }; static const short vcount = sizeof poly / sizeof *poly / 3; int game_init(void) { sincos_init(); +#ifdef PALMODE + palman_init(); +#endif return 0; } +static short keyrot; +static int autorot = 1; + void game_draw(void) { unsigned long msec = get_millisec(); @@ -29,22 +38,119 @@ x3d_load_identity(); x3d_translate(-itox16(WIDTH / 2), -itox16(HEIGHT / 2), 0); - x3d_rotate((msec / 64) << 16, 0, 0, 65536); + if(autorot) { + x3d_rotate((msec / 64) << 16, 0, 0, 65536); + } else { + x3d_rotate(keyrot << 16, 0, 0, 65536); + } x3d_translate(itox16(WIDTH / 2), itox16(HEIGHT / 2), 0); x3d_vertex_array(vcount, poly); +#ifdef PALMODE + x3d_color_index(255); +#else x3d_color(65536, 65536, 65536); +#endif x3d_draw_arrays(X3D_TRIANGLES, vcount); +#ifdef PALMODE + x3d_color_index(RGBPAL(0, 255, 0)); +#else x3d_color(0, 65536, 0); +#endif x3d_draw_arrays(X3D_POINTS, vcount); + x3d_vertex_array(0, 0); - x3d_vertex_array(0, 0); + draw_rect(0, 0, WIDTH, HEIGHT, RGBPAL(255, 0, 0)); + draw_rect(1, 1, WIDTH - 2, HEIGHT - 2, RGBPAL(0, 255, 0)); + draw_rect(2, 2, WIDTH - 4, HEIGHT - 4, RGBPAL(32, 64, 255)); flip(); } void game_keyb(int key, int pressed) { + if(!pressed) return; + + switch(key) { + case KEY_LEFT: + keyrot--; + break; + + case KEY_RIGHT: + keyrot++; + break; + + case KEY_A: + autorot = !autorot; + break; + + default: + break; + } } + +#ifdef PALMODE +#define ROWADV (WIDTH / 2) +#else +#define ROWADV WIDTH +#endif + +static void draw_rect(int x, int y, int w, int h, uint16_t color) +{ + int i, xsz = w, ysz = h; + uint16_t *pixels = back_buffer->pixels; + uint16_t *topleft, *topright, *botleft; + +#ifdef PALMODE + pixels += (y * WIDTH + x) / 2; + topleft = pixels; + topright = (uint16_t*)back_buffer->pixels + (y * WIDTH + x + w - 1) / 2; + + color |= color << 8; + xsz /= 2; +#else + pixels += y * WIDTH + x; + topleft = pixels; + topright = topleft + w - 1; +#endif + botleft = topleft + (ysz - 1) * ROWADV; + +#ifdef PALMODE + if(x & 1) { + *topleft = (*topleft & 0xff) | (color & 0xff00); + *botleft = (*topleft & 0xff) | (color & 0xff00); + ++topleft; + ++botleft; + xsz -= 1; + } +#endif + for(i=0; ix * pbuf->y; unsigned short *pixels = pbuf->pixels; - for(i=0; ix * pbuf->y; i++) { +#ifdef PALMODE + color |= color << 8; + sz /= 2; +#endif + + for(i=0; itype) { case SDL_KEYDOWN: case SDL_KEYUP: - handle_keyboard(ev->key.keysym.sym, ev->key.state == SDL_KEYDOWN); + handle_keyboard(ev->key.keysym.sym, ev->key.state); break; case SDL_QUIT: @@ -173,6 +203,7 @@ break; case '\n': + case '\r': gba_key = KEY_A; break; case '\b': diff -r fb0a0d6a8b52 -r b0ed38f13261 src/palman.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/palman.c Sun Jun 22 05:16:10 2014 +0300 @@ -0,0 +1,16 @@ +#include "gbasys.h" +#include "palman.h" + +void palman_init(void) +{ + int i; + + for(i=0; i<255; i++) { + int r = GET_R_PAL(i); + int g = GET_G_PAL(i); + int b = GET_B_PAL(i); + + set_palette(i, r, g, b); + } + set_palette(255, 255, 255, 255); +} diff -r fb0a0d6a8b52 -r b0ed38f13261 src/palman.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/palman.h Sun Jun 22 05:16:10 2014 +0300 @@ -0,0 +1,13 @@ +#ifndef PALMAN_H_ +#define PALMAN_H_ + +#define RGBPAL(r, g, b) \ + (((r) & 0xe0) | (((g) >> 3) & 0x1c) | (((b) >> 6) & 0x3)) + +#define GET_R_PAL(c) ((c) & 0xe0) +#define GET_G_PAL(c) (((c) & 0x1c) << 3) +#define GET_B_PAL(c) (((c) & 0x3) << 6) + +void palman_init(void); + +#endif /* PALMAN_H_ */ diff -r fb0a0d6a8b52 -r b0ed38f13261 src/polyfill.c --- a/src/polyfill.c Thu Jun 19 05:53:46 2014 +0300 +++ b/src/polyfill.c Sun Jun 22 05:16:10 2014 +0300 @@ -5,14 +5,18 @@ #include "fixed.h" #include "gbasys.h" -static void fill_scanline(int y, int x0, int x1, uint16_t color); +#define VNEXT(x, n) (((x) + 1) % (n)) +#define VPREV(x, n) ((x) > 0 ? (x) - 1 : (n) - 1) + +static void fill_scanline_pal(int y, int x0, int x1, uint8_t color); +static void fill_scanline_rgb(int y, int x0, int x1, uint16_t color); void draw_poly(int num, const pvec3 *verts, uint16_t color) { int i, topidx = 0, botidx = 0; - int lidx[2], ridx[2]; + int lidx[2] = {-1, -1}, ridx[2] = {-1, -1}; int32_t y, topy, boty; - int32_t ldy, rdy, ldxdy, rdxdy; + int32_t ldy = 0, rdy = 0, ldxdy, rdxdy; int32_t lx, rx; int start, end; @@ -30,22 +34,46 @@ } lidx[0] = ridx[0] = topidx; - lidx[1] = topidx ? topidx - 1 : num - 1; - ridx[1] = (topidx + 1) % num; + + /* find starting left edge */ + lidx[1] = VPREV(lidx[0], num); + ldy = verts[lidx[1]].y - verts[lidx[0]].y; + + while(ldy == 0) { + lidx[0] = lidx[1]; + lidx[1] = VPREV(lidx[1], num); + + if(lidx[1] == topidx) { + return; /* degenerate */ + } + + ldy = verts[lidx[1]].y - verts[lidx[0]].y; + } + lx = verts[lidx[0]].x; + ldxdy = x16div(verts[lidx[1]].x - lx, ldy); + + /* find starting right edge */ + ridx[1] = VNEXT(ridx[0], num); + rdy = verts[ridx[1]].y - verts[ridx[0]].y; + + while(rdy == 0) { + ridx[0] = ridx[1]; + ridx[1] = VNEXT(ridx[1], num); + + if(ridx[1] == topidx) { + return; /* degenerate */ + } + + rdy = verts[ridx[1]].y - verts[ridx[0]].y; + } + rx = verts[ridx[0]].x; + rdxdy = x16div(verts[ridx[1]].x - rx, rdy); + if(verts[ridx[1]].x < verts[lidx[1]].x) { - return; /* backface (CCW) */ + return; /* backface (CCW) */ } - lx = rx = verts[lidx[0]].x; - - /* TODO handle ldy == 0 or rdy == 0 */ - ldy = verts[lidx[1]].y - verts[lidx[0]].y; - ldxdy = x16div(verts[lidx[1]].x - lx, ldy); - - rdy = verts[ridx[1]].y - verts[ridx[0]].y; - rdxdy = x16div(verts[ridx[1]].x - rx, rdy); - start = topy >> 16; end = boty >> 16; @@ -53,18 +81,12 @@ y = topy; for(i=start; i> 16); - x1 = (rx >> 16) >= WIDTH ? WIDTH - 1 : (rx >> 16); - - if(i >= 0 && x1 > x0) { - fill_scanline(i, x0, x1, color); - } + short x0, x1; if(y >= verts[lidx[1]].y) { + lx = verts[lidx[1]].x; lidx[0] = lidx[1]; - lidx[1] = lidx[1] ? lidx[1] - 1 : num - 1; + lidx[1] = VPREV(lidx[1], num); ldy = verts[lidx[1]].y - verts[lidx[0]].y; if(ldy < 0) { break; @@ -72,8 +94,9 @@ ldxdy = x16div(verts[lidx[1]].x - lx, ldy); } if(y >= verts[ridx[1]].y) { + rx = verts[ridx[1]].x; ridx[0] = ridx[1]; - ridx[1] = (ridx[1] + 1) % num; + ridx[1] = VNEXT(ridx[1], num); rdy = verts[ridx[1]].y - verts[ridx[0]].y; if(rdy < 0) { break; @@ -81,13 +104,58 @@ rdxdy = x16div(verts[ridx[1]].x - rx, rdy); } + x0 = lx < 0 ? 0 : (lx >> 16); + x1 = (rx >> 16) >= WIDTH ? WIDTH - 1 : (rx >> 16); + + if(i >= 0 && x1 > x0) { +#ifdef PALMODE + fill_scanline_pal(i, x0, x1, (uint8_t)color); +#else + fill_scanline_rgb(i, x0, x1, color); +#endif + } + lx += ldxdy; rx += rdxdy; y += 65536; } } -static void fill_scanline(int y, int x0, int x1, uint16_t color) + +static void fill_scanline_pal(int y, int x0, int x1, uint8_t color) +{ +#if 1 + int i, num_pairs, num_pix = x1 - x0; + uint16_t *pixels = (uint16_t*)back_buffer->pixels + (y * WIDTH + x0) / 2; + uint16_t colpair = (uint16_t)color | ((uint16_t)color << 8); + + if(x0 & 1) { + uint16_t pix = *pixels & 0xff; + *pixels++ = pix | ((uint16_t)color << 8); + --num_pix; + } + + num_pairs = (num_pix & 0xfffe) / 2; + + for(i=0; ipixels + y * WIDTH + x0; + + for(i=x0; ipixels + y * WIDTH + x0; @@ -108,5 +176,14 @@ return; } +#ifdef PALMODE + pixels += (y * WIDTH + x) / 2; + if(x & 1) { + *pixels = (*pixels & 0xff) | (color << 8); + } else { + *pixels = (*pixels & 0xff00) | color; + } +#else pixels[y * WIDTH + x] = color; +#endif } diff -r fb0a0d6a8b52 -r b0ed38f13261 src/sdlsys/gbasys.h --- a/src/sdlsys/gbasys.h Thu Jun 19 05:53:46 2014 +0300 +++ b/src/sdlsys/gbasys.h Sun Jun 22 05:16:10 2014 +0300 @@ -22,6 +22,7 @@ /* defined in main_sdl.c */ void flip(void); void clear_buffer(struct pixel_buffer *pbuf, unsigned short color); +void set_palette(int idx, int r, int g, int b); /* ---- fake gbasys/input.h ---- */ enum { diff -r fb0a0d6a8b52 -r b0ed38f13261 src/x3d.c --- a/src/x3d.c Thu Jun 19 05:53:46 2014 +0300 +++ b/src/x3d.c Sun Jun 22 05:16:10 2014 +0300 @@ -1,3 +1,4 @@ +#include "config.h" #include #include "x3d.h" #include "fixed.h" @@ -33,6 +34,7 @@ static unsigned short color_count; static int32_t im_color[3]; +static uint8_t im_color_index; void x3d_projection(int32_t fov, int32_t aspect, int32_t nearz, int32_t farz) { @@ -155,7 +157,10 @@ int i, j, pverts = prim; const int32_t *vptr = vertex_array; const int32_t *cptr = color_array; +#ifndef PALMODE short cr, cg, cb; +#endif + uint16_t color; if(!vertex_array) return -1; @@ -181,6 +186,9 @@ if(cptr) cptr += 3; } +#ifdef PALMODE + color = im_color_index; +#else cr = col[0].x >> 8; cg = col[0].y >> 8; cb = col[0].z >> 8; @@ -189,9 +197,12 @@ if(cg > 255) cg = 255; if(cb > 255) cb = 255; + color = RGB(cr, cg, cb); +#endif + switch(pverts) { case X3D_POINTS: - draw_point(vpos, RGB(cr, cg, cb)); + draw_point(vpos, color); break; case X3D_LINES: @@ -199,7 +210,7 @@ case X3D_TRIANGLES: case X3D_QUADS: - draw_poly(pverts, vpos, RGB(cr, cg, cb)); + draw_poly(pverts, vpos, color); break; } } @@ -239,6 +250,11 @@ } } +void x3d_color_index(int cidx) +{ + im_color_index = cidx; +} + void x3d_color(int32_t r, int32_t g, int32_t b) { im_color[0] = r; diff -r fb0a0d6a8b52 -r b0ed38f13261 src/x3d.h --- a/src/x3d.h Thu Jun 19 05:53:46 2014 +0300 +++ b/src/x3d.h Sun Jun 22 05:16:10 2014 +0300 @@ -25,6 +25,7 @@ void x3d_color_array(int count, const int32_t *ptr); int x3d_draw_arrays(int prim, int vnum); +void x3d_color_index(int cidx); void x3d_color(int32_t r, int32_t g, int32_t b); #endif /* X3D_H_ */