honey

very old unfinished project. tracking so i dont lose it
git clone git://moonbender.net/honey
Log | Files | Refs | README

render.c (3982B)


      1 #include <math.h>
      2 
      3 #include "xdraw.h"
      4 #include "common.h"
      5 #define PI 3.141592654
      6 
      7 //Our rendered pixel layout, to be processed by the front end
      8 uint8_t PixBuffer[XREZ * YREZ];
      9 
     10 extern uint32_t Palette[16];
     11 
     12 extern uint8_t spritedata[504];
     13 extern uint8_t frame_honey_run_1[1444];
     14 
     15 typedef struct
     16 {
     17 	uint8_t width, height;
     18 	uint8_t *pixels;
     19 } frame;
     20 
     21 //TODO: Need to initialize these in a way that uses the enum
     22 frame Frames[F_TOTAL] = {
     23 	{28, 18, spritedata},
     24 	{28, 18, spritedata},
     25 };
     26 
     27 uint32_t camX, camY, camZ;
     28 
     29 typedef struct
     30 {
     31 	double x, y;
     32 } vec2;
     33 
     34 typedef struct
     35 {
     36 	//relative to actor origin
     37 	vec2 loc;
     38 	uint32_t u, v;
     39 } vert;
     40 
     41 uint32_t *GetPalette()
     42 {
     43 	return Palette;
     44 }
     45 
     46 uint8_t *GetPixBuf()
     47 {
     48 	return PixBuffer;
     49 }
     50 
     51 void InitRender()
     52 {
     53 	camZ = 1;
     54 }
     55 
     56 void ClearScreen()
     57 {
     58 	for (int i = 0; i < XREZ * YREZ; i++)
     59 	{
     60 		PixBuffer[i] = 1;
     61 	}
     62 }
     63 
     64 void PlotPix(int x, int y, uint8_t color)
     65 {
     66 	PixBuffer[XREZ * y + x] = color;
     67 }
     68 
     69 //cross product
     70 float EdgeFunc( vec2 v1, vec2 v2, vec2 v3)
     71 {
     72 	return 	(v3.x - v1.x) * 
     73 			(v2.y - v1.y) - 
     74 			(v3.y - v1.y) * 
     75 			(v2.x - v1.x);
     76 }
     77 
     78 uint8_t GetColor(uint32_t sp_in, uint32_t u, uint32_t v)
     79 {
     80 	uint8_t *sppixels = Frames[sp_in].pixels;
     81 	uint32_t spritewidth = Frames[sp_in].width;
     82 	return *(sppixels + ( v * spritewidth + u));
     83 }
     84 
     85 void DrawTri (	uint32_t sp_in,
     86 		vert p1,
     87 		vert p2,
     88 		vert p3	)
     89 {
     90 	for (int y = 0; y < YREZ; ++y)
     91 	{
     92 		for (int x = 0; x < XREZ; ++x)
     93 		{
     94 			int u, v;
     95 			vec2 point;
     96 			point.x = x;
     97 			point.y = y;
     98 			float area = EdgeFunc(p1.loc, p2.loc, p3.loc);
     99 			float w1 = EdgeFunc(p2.loc, p3.loc, point);
    100 			float w2 = EdgeFunc(p3.loc, p1.loc, point);
    101 			float w3 = EdgeFunc(p1.loc, p2.loc, point);
    102 			if (w1 >= 0 && w2 >= 0 && w3 >= 0)
    103 			{
    104 				// barycentric coordinates
    105 				w1 /= area;
    106 				w2 /= area;
    107 				w3 /= area;
    108 				//calculate UV data from them
    109 				u = w1 * p1.u + w2 * p2.u + w3 * p3.u;
    110 				v = w1 * p1.v + w2 * p2.v + w3 * p3.v;
    111 				uint8_t color = GetColor(sp_in, u, v);
    112 				if (color) //0 is transparency
    113 				{
    114 					PlotPix(x, y, GetColor(sp_in, u, v));
    115 				}
    116 			}
    117 		}
    118 	}	
    119 
    120 }
    121 
    122 vec2 RotateVec(vec2 in, double angle)
    123 {
    124 	vec2 out;
    125 	out.x = cos(angle) * in.x - sin(angle) * in.y;
    126 	out.y = sin(angle) * in.x + cos(angle) * in.y;
    127 	return out;
    128 }
    129 
    130 void DrawSprite(	uint32_t sp_in, 
    131 			double posx, 	
    132 			double posy, 
    133 			double angle, 
    134 			uint8_t distance	)
    135 {
    136 	uint8_t spritewidth = Frames[sp_in].width;
    137 	uint8_t spriteheight = Frames[sp_in].height;
    138 
    139 	vert p1, p2, p3;
    140 	p1.loc.x = -(float)(spritewidth / 2) 	/ 	distance;
    141 	p1.loc.y = -(float)(spriteheight / 2) 	/ 	distance;
    142 
    143 	p2.loc.x = -(float)(spritewidth / 2) 	/ 	distance;
    144 	p2.loc.y = (float)(spriteheight / 2) 	/ 	distance;
    145 
    146 	p3.loc.x = (float)(spritewidth / 2) 	/ 	distance;
    147 	p3.loc.y = -(float)(spriteheight / 2) 	/ 	distance;
    148 
    149 	//WINDING ORDER IS IMPORTANT!
    150 	//Tris must be wound counter-clackwise
    151 	p1.u = 0;
    152 	p1.v = 0;
    153 
    154 	p2.u = 0;
    155 	p2.v = spriteheight;
    156 
    157 	p3.u = spritewidth;
    158 	p3.v = 0;
    159 
    160 	vert z1, z2, z3;
    161 	z1.loc.x = (float)(spritewidth / 2)	/	distance;
    162 	z1.loc.y = (float)(spriteheight / 2) 	/	distance;
    163 	z2.loc.x = (float)(spritewidth / 2) 	/	distance;
    164 	z2.loc.y = -(float)(spriteheight / 2) 	/ 	distance;
    165 	z3.loc.x = -(float)(spritewidth / 2) 	/ 	distance;
    166 	z3.loc.y = (float)(spriteheight / 2) 	/ 	distance;
    167 
    168 	z1.u = spritewidth;
    169 	z1.v = spriteheight;
    170 
    171 	z2.u = spritewidth;
    172 	z2.v = 0;
    173 
    174 	z3.u = 0;
    175 	z3.v = spriteheight;
    176 
    177 	p1.loc = RotateVec(p1.loc, angle);
    178 	p2.loc = RotateVec(p2.loc, angle);
    179 	p3.loc = RotateVec(p3.loc, angle);
    180 	z1.loc = RotateVec(z1.loc, angle);
    181 	z2.loc = RotateVec(z2.loc, angle);
    182 	z3.loc = RotateVec(z3.loc, angle);
    183 
    184 	p1.loc.x += posx;
    185 	p1.loc.y += posy;
    186 	p2.loc.x += posx;
    187 	p2.loc.y += posy;
    188 	p3.loc.x += posx;
    189 	p3.loc.y += posy;
    190 
    191 	z1.loc.x += posx;
    192 	z1.loc.y += posy;
    193 	z2.loc.x += posx;
    194 	z2.loc.y += posy;
    195 	z3.loc.x += posx;
    196 	z3.loc.y += posy;
    197 
    198 	DrawTri(sp_in, z1, z2, z3);
    199 	DrawTri(sp_in, p1, p2, p3);
    200 }
    201 
    202 void DrawFrame(uint32_t frameno, double angle)
    203 {
    204 	ClearScreen();
    205 	DrawSprite(frameno, XREZ / 2, YREZ / 2, angle, camZ);
    206 }