textri command
added to js & lua supports use_map ( i.e. render like a map ) supports chroma ( i.e. ignore color )
This commit is contained in:
		
							
								
								
									
										24
									
								
								src/jsapi.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								src/jsapi.c
									
									
									
									
									
								
							@@ -644,6 +644,29 @@ static duk_ret_t duk_tri(duk_context* duk)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static duk_ret_t duk_textri(duk_context* duk)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						s32 pt[12];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (s32 i = 0; i < COUNT_OF(pt); i++)
 | 
				
			||||||
 | 
							pt[i] = duk_to_int(duk, i);
 | 
				
			||||||
 | 
						tic_mem* memory = (tic_mem*)getDukMachine(duk);
 | 
				
			||||||
 | 
						bool use_map = duk_is_null_or_undefined(duk, 12) ? false : duk_to_boolean(duk, 12);
 | 
				
			||||||
 | 
						u8 chroma = duk_is_null_or_undefined(duk, 13) ? 0xff : duk_to_int(duk, 13);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memory->api.textri(memory, pt[0], pt[1],	//	xy 1
 | 
				
			||||||
 | 
											pt[2], pt[3],	//	xy 2
 | 
				
			||||||
 | 
											pt[4], pt[5],	//  xy 3
 | 
				
			||||||
 | 
											pt[6], pt[7],	//	uv 1
 | 
				
			||||||
 | 
											pt[8], pt[9],	//	uv 2
 | 
				
			||||||
 | 
											pt[10], pt[11],//  uv 3
 | 
				
			||||||
 | 
											use_map, // usemap
 | 
				
			||||||
 | 
											chroma);	//	chroma
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static duk_ret_t duk_clip(duk_context* duk)
 | 
					static duk_ret_t duk_clip(duk_context* duk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	s32 x = duk_to_int(duk, 0);
 | 
						s32 x = duk_to_int(duk, 0);
 | 
				
			||||||
@@ -724,6 +747,7 @@ static const struct{duk_c_function func; s32 params;} ApiFunc[] =
 | 
				
			|||||||
	{duk_circ, 4},
 | 
						{duk_circ, 4},
 | 
				
			||||||
	{duk_circb, 4},
 | 
						{duk_circb, 4},
 | 
				
			||||||
	{duk_tri, 7},
 | 
						{duk_tri, 7},
 | 
				
			||||||
 | 
						{duk_textri,12},
 | 
				
			||||||
	{duk_clip, 4},
 | 
						{duk_clip, 4},
 | 
				
			||||||
	{duk_music, 4},
 | 
						{duk_music, 4},
 | 
				
			||||||
	{duk_sync, 0},
 | 
						{duk_sync, 0},
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										38
									
								
								src/luaapi.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								src/luaapi.c
									
									
									
									
									
								
							@@ -290,6 +290,42 @@ static s32 lua_tri(lua_State* lua)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static s32 lua_textri(lua_State* lua)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						s32 top = lua_gettop(lua);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (top >= 12)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							float pt[12];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (s32 i = 0; i < COUNT_OF(pt); i++)
 | 
				
			||||||
 | 
								pt[i] = getLuaNumber(lua, i + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tic_mem* memory = (tic_mem*)getLuaMachine(lua);
 | 
				
			||||||
 | 
							u8 chroma = 0xff;
 | 
				
			||||||
 | 
							bool use_map = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//	check for use map 
 | 
				
			||||||
 | 
							if (top >= 13)
 | 
				
			||||||
 | 
								use_map = lua_toboolean(lua, 13);
 | 
				
			||||||
 | 
							//	check for chroma 
 | 
				
			||||||
 | 
							if (top >= 14)
 | 
				
			||||||
 | 
								chroma = (u8)getLuaNumber(lua, 14);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							memory->api.textri(memory, pt[0], pt[1],	//	xy 1
 | 
				
			||||||
 | 
														pt[2], pt[3],	//	xy 2
 | 
				
			||||||
 | 
														pt[4], pt[5],	//  xy 3
 | 
				
			||||||
 | 
														pt[6], pt[7],	//	uv 1
 | 
				
			||||||
 | 
														pt[8], pt[9],	//	uv 2
 | 
				
			||||||
 | 
														pt[10], pt[11], //  uv 3
 | 
				
			||||||
 | 
														use_map,		// use map
 | 
				
			||||||
 | 
														chroma);		// chroma
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else luaL_error(lua, "invalid parameters, textri(x1,y1,x2,y2,x3,y3,u1,v1,u2,v2,u3,v3,[use_map=false],[chroma=off])\n");
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static s32 lua_clip(lua_State* lua)
 | 
					static s32 lua_clip(lua_State* lua)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	s32 top = lua_gettop(lua);
 | 
						s32 top = lua_gettop(lua);
 | 
				
			||||||
@@ -1013,7 +1049,7 @@ static const lua_CFunction ApiFunc[] =
 | 
				
			|||||||
	lua_rectb, lua_spr, lua_btn, lua_btnp, lua_sfx, lua_map, lua_mget, 
 | 
						lua_rectb, lua_spr, lua_btn, lua_btnp, lua_sfx, lua_map, lua_mget, 
 | 
				
			||||||
	lua_mset, lua_peek, lua_poke, lua_peek4, lua_poke4, lua_memcpy, 
 | 
						lua_mset, lua_peek, lua_poke, lua_peek4, lua_poke4, lua_memcpy, 
 | 
				
			||||||
	lua_memset, lua_trace, lua_pmem, lua_time, lua_exit, lua_font, lua_mouse, 
 | 
						lua_memset, lua_trace, lua_pmem, lua_time, lua_exit, lua_font, lua_mouse, 
 | 
				
			||||||
	lua_circ, lua_circb, lua_tri, lua_clip, lua_music, lua_sync
 | 
						lua_circ, lua_circb, lua_tri, lua_textri, lua_clip, lua_music, lua_sync
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STATIC_ASSERT(api_func, COUNT_OF(ApiKeywords) == COUNT_OF(ApiFunc));
 | 
					STATIC_ASSERT(api_func, COUNT_OF(ApiKeywords) == COUNT_OF(ApiFunc));
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										124
									
								
								src/tic.c
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								src/tic.c
									
									
									
									
									
								
							@@ -711,6 +711,10 @@ static struct
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	s16 Left[TIC80_HEIGHT];
 | 
						s16 Left[TIC80_HEIGHT];
 | 
				
			||||||
	s16 Right[TIC80_HEIGHT];	
 | 
						s16 Right[TIC80_HEIGHT];	
 | 
				
			||||||
 | 
						float ULeft[TIC80_HEIGHT];
 | 
				
			||||||
 | 
						float VLeft[TIC80_HEIGHT];
 | 
				
			||||||
 | 
						float URight[TIC80_HEIGHT];
 | 
				
			||||||
 | 
						float VRight[TIC80_HEIGHT];
 | 
				
			||||||
} SidesBuffer;
 | 
					} SidesBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void initSidesBuffer()
 | 
					static void initSidesBuffer()
 | 
				
			||||||
@@ -728,6 +732,26 @@ static void setSidePixel(s32 x, s32 y)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void setSideTexPixel(s32 x, s32 y, float u, float v)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int yy = (int)y;
 | 
				
			||||||
 | 
						if (yy >= 0 && yy < TIC80_HEIGHT)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (x < SidesBuffer.Left[yy])
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								SidesBuffer.Left[yy] = x;
 | 
				
			||||||
 | 
								SidesBuffer.ULeft[yy] = u;
 | 
				
			||||||
 | 
								SidesBuffer.VLeft[yy] = v;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (x > SidesBuffer.Right[yy])
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								SidesBuffer.Right[yy] = x;
 | 
				
			||||||
 | 
								SidesBuffer.URight[yy] = u;
 | 
				
			||||||
 | 
								SidesBuffer.VRight[yy] = v;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void api_circle(tic_mem* memory, s32 xm, s32 ym, u32 radius, u8 color)
 | 
					static void api_circle(tic_mem* memory, s32 xm, s32 ym, u32 radius, u8 color)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	tic_machine* machine = (tic_machine*)memory;
 | 
						tic_machine* machine = (tic_machine*)memory;
 | 
				
			||||||
@@ -805,6 +829,105 @@ static void api_tri(tic_mem* memory, s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32
 | 
				
			|||||||
			setPixel(machine, x, y, color);
 | 
								setPixel(machine, x, y, color);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						float x, y, u, v;
 | 
				
			||||||
 | 
					} TexVert;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void ticTexLine(tic_mem* memory, TexVert *v0, TexVert *v1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int iy;
 | 
				
			||||||
 | 
						TexVert *top = v0;
 | 
				
			||||||
 | 
						TexVert *bot = v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bot->y < top->y)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							top = v1;
 | 
				
			||||||
 | 
							bot = v0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						float dy = bot->y - top->y;
 | 
				
			||||||
 | 
						if ((int)dy == 0)	return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						float step_x = (bot->x - top->x) / dy;
 | 
				
			||||||
 | 
						float step_u = (bot->u - top->u) / dy;
 | 
				
			||||||
 | 
						float step_v = (bot->v - top->v) / dy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						float x = top->x;
 | 
				
			||||||
 | 
						float y = top->y;
 | 
				
			||||||
 | 
						float u = top->u;
 | 
				
			||||||
 | 
						float v = top->v;
 | 
				
			||||||
 | 
						for (; y < (int)bot->y; y++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							setSideTexPixel(x, y, u, v);
 | 
				
			||||||
 | 
							x += step_x;
 | 
				
			||||||
 | 
							u += step_u;
 | 
				
			||||||
 | 
							v += step_v;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void api_textri(tic_mem* memory, s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32 y3, s32 u1, s32 v1, s32 u2, s32 v2, s32 u3, s32 v3,bool use_map,u8 chroma)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						tic_machine* machine = (tic_machine*)memory;
 | 
				
			||||||
 | 
						TexVert V0, V1, V2;
 | 
				
			||||||
 | 
						const u8* ptr = memory->ram.gfx.tiles[0].data;
 | 
				
			||||||
 | 
						const u8* map = memory->ram.gfx.map.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						V0.x = (float)x1; 	V0.y = (float)y1; 	V0.u = (float)u1; 	V0.v = (float)v1;
 | 
				
			||||||
 | 
						V1.x = (float)x2; 	V1.y = (float)y2; 	V1.u = (float)u2; 	V1.v = (float)v2;
 | 
				
			||||||
 | 
						V2.x = (float)x3; 	V2.y = (float)y3; 	V2.u = (float)u3; 	V2.v = (float)v3;
 | 
				
			||||||
 | 
						initSidesBuffer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ticTexLine(memory, &V0, &V1);
 | 
				
			||||||
 | 
						ticTexLine(memory, &V1, &V2);
 | 
				
			||||||
 | 
						ticTexLine(memory, &V2, &V0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (s32 y = 0; y < TIC80_HEIGHT; y++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								float width = SidesBuffer.Right[y] - SidesBuffer.Left[y];
 | 
				
			||||||
 | 
								if (width > 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									float du = (SidesBuffer.URight[y] - SidesBuffer.ULeft[y]) / width;
 | 
				
			||||||
 | 
									float dv = (SidesBuffer.VRight[y] - SidesBuffer.VLeft[y]) / width;
 | 
				
			||||||
 | 
									float u = SidesBuffer.ULeft[y];
 | 
				
			||||||
 | 
									float v = SidesBuffer.VLeft[y];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									for (s32 x = (int)SidesBuffer.Left[y]; x <= (int)SidesBuffer.Right[y]; ++x)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										if ((x >= 0) && (x < TIC80_WIDTH))
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											if (use_map == true)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												int iu = (int)u % 1920;
 | 
				
			||||||
 | 
												int iv = (int)v % 1088;
 | 
				
			||||||
 | 
												u8 tile = map[(iv>>3) * TIC_MAP_WIDTH + (iu>>3)];
 | 
				
			||||||
 | 
												u8 *buffer = &ptr[tile << 5];
 | 
				
			||||||
 | 
												u8 color = tic_tool_peek4(buffer, (iu & 7) + ((iv & 7) << 3));
 | 
				
			||||||
 | 
												if (color != chroma)
 | 
				
			||||||
 | 
													setPixel(machine, x, y, color);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											else
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												int iu = (int)(u) & 127;
 | 
				
			||||||
 | 
												int iv = (int)(v) & 255;
 | 
				
			||||||
 | 
												u8 *buffer = &ptr[((iu >> 3) + ((iv >> 3) << 4)) << 5];
 | 
				
			||||||
 | 
												u8 color = tic_tool_peek4(buffer, (iu & 7) + ((iv & 7) << 3));
 | 
				
			||||||
 | 
												if (color != chroma)
 | 
				
			||||||
 | 
													setPixel(machine, x, y, color);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										u += du;
 | 
				
			||||||
 | 
										v += dv;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void api_sprite(tic_mem* memory, const tic_gfx* src, s32 index, s32 x, s32 y, u8* colors, s32 count)
 | 
					static void api_sprite(tic_mem* memory, const tic_gfx* src, s32 index, s32 x, s32 y, u8* colors, s32 count)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	drawSprite(memory, src, index, x, y, colors, count, 1, tic_no_flip, tic_no_rotate);
 | 
						drawSprite(memory, src, index, x, y, colors, count, 1, tic_no_flip, tic_no_rotate);
 | 
				
			||||||
@@ -1536,6 +1659,7 @@ static void initApi(tic_api* api)
 | 
				
			|||||||
	INIT_API(circle);
 | 
						INIT_API(circle);
 | 
				
			||||||
	INIT_API(circle_border);
 | 
						INIT_API(circle_border);
 | 
				
			||||||
	INIT_API(tri);
 | 
						INIT_API(tri);
 | 
				
			||||||
 | 
						INIT_API(textri);
 | 
				
			||||||
	INIT_API(clip);
 | 
						INIT_API(clip);
 | 
				
			||||||
	INIT_API(sfx);
 | 
						INIT_API(sfx);
 | 
				
			||||||
	INIT_API(sfx_stop);
 | 
						INIT_API(sfx_stop);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -104,7 +104,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define API_KEYWORDS {"TIC", "scanline", "print", "cls", "pix", "line", "rect", "rectb", \
 | 
					#define API_KEYWORDS {"TIC", "scanline", "print", "cls", "pix", "line", "rect", "rectb", \
 | 
				
			||||||
	"spr", "btn", "btnp", "sfx", "map", "mget", "mset", "peek", "poke", "peek4", "poke4", \
 | 
						"spr", "btn", "btnp", "sfx", "map", "mget", "mset", "peek", "poke", "peek4", "poke4", \
 | 
				
			||||||
	"memcpy", "memset", "trace", "pmem", "time", "exit", "font", "mouse", "circ", "circb", "tri", \
 | 
						"memcpy", "memset", "trace", "pmem", "time", "exit", "font", "mouse", "circ", "circb", "tri", "textri", \
 | 
				
			||||||
	"clip", "music", "sync"}
 | 
						"clip", "music", "sync"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TIC_FONT_CHARS 128
 | 
					#define TIC_FONT_CHARS 128
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -82,6 +82,7 @@ typedef struct
 | 
				
			|||||||
	void (*circle)				(tic_mem* memory, s32 x, s32 y, u32 radius, u8 color);
 | 
						void (*circle)				(tic_mem* memory, s32 x, s32 y, u32 radius, u8 color);
 | 
				
			||||||
	void (*circle_border)		(tic_mem* memory, s32 x, s32 y, u32 radius, u8 color);
 | 
						void (*circle_border)		(tic_mem* memory, s32 x, s32 y, u32 radius, u8 color);
 | 
				
			||||||
	void (*tri)					(tic_mem* memory, s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32 y3, u8 color);
 | 
						void (*tri)					(tic_mem* memory, s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32 y3, u8 color);
 | 
				
			||||||
 | 
						void (*textri)				(tic_mem* memory, s32 x1, s32 y1, s32 x2, s32 y2, s32 x3, s32 y3, s32 u1, s32 v1, s32 u2, s32 v2, s32 u3, s32 v3 ,bool use_map,u8 chroma);
 | 
				
			||||||
	void (*clip)				(tic_mem* memory, s32 x, s32 y, s32 width, s32 height);
 | 
						void (*clip)				(tic_mem* memory, s32 x, s32 y, s32 width, s32 height);
 | 
				
			||||||
	void (*sfx)					(tic_mem* memory, s32 index, s32 note, s32 octave, s32 duration, s32 channel);
 | 
						void (*sfx)					(tic_mem* memory, s32 index, s32 note, s32 octave, s32 duration, s32 channel);
 | 
				
			||||||
	void (*sfx_stop)			(tic_mem* memory, s32 channel);
 | 
						void (*sfx_stop)			(tic_mem* memory, s32 channel);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user