crt shader moved to the COnfig
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@@ -251,7 +251,7 @@ bin/menu.o: src/menu.c $(TIC80_H) $(TIC_H)
 | 
				
			|||||||
bin/surf.o: src/surf.c $(TIC80_H) $(TIC_H)
 | 
					bin/surf.o: src/surf.c $(TIC80_H) $(TIC_H)
 | 
				
			||||||
	$(CC) $< $(OPT) $(INCLUDES) -c -o $@
 | 
						$(CC) $< $(OPT) $(INCLUDES) -c -o $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bin/system.o: src/system.c src/keycodes.c src/ext/shader/* $(TIC80_H) $(TIC_H)
 | 
					bin/system.o: src/system.c src/keycodes.c $(TIC80_H) $(TIC_H)
 | 
				
			||||||
	$(CC) $< $(OPT) $(INCLUDES) -c -o $@
 | 
						$(CC) $< $(OPT) $(INCLUDES) -c -o $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bin/chip.o: src/system/chip.c src/keycodes.c $(TIC80_H) $(TIC_H)
 | 
					bin/chip.o: src/system/chip.c src/keycodes.c $(TIC80_H) $(TIC_H)
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								config.tic
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								config.tic
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										31
									
								
								src/config.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								src/config.c
									
									
									
									
									
								
							@@ -76,6 +76,31 @@ static void readConfigShowSync(Config* config, lua_State* lua)
 | 
				
			|||||||
	lua_pop(lua, 1);
 | 
						lua_pop(lua, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void readConfigCrtMonitor(Config* config, lua_State* lua)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						lua_getglobal(lua, "CRT_MONITOR");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(lua_isboolean(lua, -1))
 | 
				
			||||||
 | 
							config->data.crtMonitor = lua_toboolean(lua, -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lua_pop(lua, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void readConfigCrtShader(Config* config, lua_State* lua)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						lua_getglobal(lua, "CRT_SHADER");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(lua_isstring(lua, -1))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if(!config->data.crtShader)
 | 
				
			||||||
 | 
								config->data.crtShader = calloc(1, sizeof(tic_code));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							strcpy((char*)config->data.crtShader, lua_tostring(lua, -1));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lua_pop(lua, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void readCursorTheme(Config* config, lua_State* lua)
 | 
					static void readCursorTheme(Config* config, lua_State* lua)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	lua_getfield(lua, -1, "CURSOR");
 | 
						lua_getfield(lua, -1, "CURSOR");
 | 
				
			||||||
@@ -222,9 +247,15 @@ static void readConfig(Config* config)
 | 
				
			|||||||
			readConfigCheckNewVersion(config, lua);
 | 
								readConfigCheckNewVersion(config, lua);
 | 
				
			||||||
			readConfigNoSound(config, lua);
 | 
								readConfigNoSound(config, lua);
 | 
				
			||||||
			readConfigShowSync(config, lua);
 | 
								readConfigShowSync(config, lua);
 | 
				
			||||||
 | 
								readConfigCrtMonitor(config, lua);
 | 
				
			||||||
			readTheme(config, lua);
 | 
								readTheme(config, lua);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(luaL_loadstring(lua, config->tic->config.bank1.code.data) == LUA_OK && lua_pcall(lua, 0, LUA_MULTRET, 0) == LUA_OK)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								readConfigCrtShader(config, lua);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		lua_close(lua);
 | 
							lua_close(lua);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -277,9 +277,9 @@ static bool AddLoop(GifFileType *gif)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static const u8* toColor(const u8* ptr, gif_color* color)
 | 
					static const u8* toColor(const u8* ptr, gif_color* color)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	color->b = *ptr++;
 | 
					 | 
				
			||||||
	color->g = *ptr++;
 | 
					 | 
				
			||||||
	color->r = *ptr++;
 | 
						color->r = *ptr++;
 | 
				
			||||||
 | 
						color->g = *ptr++;
 | 
				
			||||||
 | 
						color->b = *ptr++;
 | 
				
			||||||
	ptr++;
 | 
						ptr++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ptr;
 | 
						return ptr;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,133 +0,0 @@
 | 
				
			|||||||
SHADER(#version 100\n
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
precision highp float;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
varying vec2 texCoord;
 | 
					 | 
				
			||||||
uniform sampler2D source;
 | 
					 | 
				
			||||||
uniform float trg_x;
 | 
					 | 
				
			||||||
uniform float trg_y;
 | 
					 | 
				
			||||||
uniform float trg_w;
 | 
					 | 
				
			||||||
uniform float trg_h;
 | 
					 | 
				
			||||||
uniform float scr_w;
 | 
					 | 
				
			||||||
uniform float scr_h;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Emulated input resolution.
 | 
					 | 
				
			||||||
vec2 res=vec2(256.0,144.0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Hardness of scanline.
 | 
					 | 
				
			||||||
//  -8.0 = soft
 | 
					 | 
				
			||||||
// -16.0 = medium
 | 
					 | 
				
			||||||
float hardScan=-8.0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Hardness of pixels in scanline.
 | 
					 | 
				
			||||||
// -2.0 = soft
 | 
					 | 
				
			||||||
// -4.0 = hard
 | 
					 | 
				
			||||||
float hardPix=-3.0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Display warp.
 | 
					 | 
				
			||||||
// 0.0 = none
 | 
					 | 
				
			||||||
// 1.0/8.0 = extreme
 | 
					 | 
				
			||||||
vec2 warp=vec2(1.0/32.0,1.0/24.0); 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Amount of shadow mask.
 | 
					 | 
				
			||||||
float maskDark=0.5;
 | 
					 | 
				
			||||||
float maskLight=1.5;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// sRGB to Linear.
 | 
					 | 
				
			||||||
// Assuing using sRGB typed textures this should not be needed.
 | 
					 | 
				
			||||||
float ToLinear1(float c){return(c<=0.04045)?c/12.92:pow((c+0.055)/1.055,2.4);}
 | 
					 | 
				
			||||||
vec3 ToLinear(vec3 c){return vec3(ToLinear1(c.r),ToLinear1(c.g),ToLinear1(c.b));}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Linear to sRGB.
 | 
					 | 
				
			||||||
// Assuing using sRGB typed textures this should not be needed.
 | 
					 | 
				
			||||||
float ToSrgb1(float c){return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);}
 | 
					 | 
				
			||||||
vec3 ToSrgb(vec3 c){return vec3(ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Nearest emulated sample given floating point position and texel offset.
 | 
					 | 
				
			||||||
// Also zero's off screen.
 | 
					 | 
				
			||||||
vec3 Fetch(vec2 pos,vec2 off){
 | 
					 | 
				
			||||||
	pos=(floor(pos*res+off)+vec2(0.5,0.5))/res;
 | 
					 | 
				
			||||||
	return ToLinear(1.2 * texture2D(source,pos.xy,-16.0).rgb);}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Distance in emulated pixels to nearest texel.
 | 
					 | 
				
			||||||
vec2 Dist(vec2 pos){pos=pos*res;return -((pos-floor(pos))-vec2(0.5));}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
// 1D Gaussian.
 | 
					 | 
				
			||||||
float Gaus(float pos,float scale){return exp2(scale*pos*pos);}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 3-tap Gaussian filter along horz line.
 | 
					 | 
				
			||||||
vec3 Horz3(vec2 pos,float off){
 | 
					 | 
				
			||||||
	vec3 b=Fetch(pos,vec2(-1.0,off));
 | 
					 | 
				
			||||||
	vec3 c=Fetch(pos,vec2( 0.0,off));
 | 
					 | 
				
			||||||
	vec3 d=Fetch(pos,vec2( 1.0,off));
 | 
					 | 
				
			||||||
	float dst=Dist(pos).x;
 | 
					 | 
				
			||||||
	// Convert distance to weight.
 | 
					 | 
				
			||||||
	float scale=hardPix;
 | 
					 | 
				
			||||||
	float wb=Gaus(dst-1.0,scale);
 | 
					 | 
				
			||||||
	float wc=Gaus(dst+0.0,scale);
 | 
					 | 
				
			||||||
	float wd=Gaus(dst+1.0,scale);
 | 
					 | 
				
			||||||
	// Return filtered sample.
 | 
					 | 
				
			||||||
	return (b*wb+c*wc+d*wd)/(wb+wc+wd);}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 5-tap Gaussian filter along horz line.
 | 
					 | 
				
			||||||
vec3 Horz5(vec2 pos,float off){
 | 
					 | 
				
			||||||
	vec3 a=Fetch(pos,vec2(-2.0,off));
 | 
					 | 
				
			||||||
	vec3 b=Fetch(pos,vec2(-1.0,off));
 | 
					 | 
				
			||||||
	vec3 c=Fetch(pos,vec2( 0.0,off));
 | 
					 | 
				
			||||||
	vec3 d=Fetch(pos,vec2( 1.0,off));
 | 
					 | 
				
			||||||
	vec3 e=Fetch(pos,vec2( 2.0,off));
 | 
					 | 
				
			||||||
	float dst=Dist(pos).x;
 | 
					 | 
				
			||||||
	// Convert distance to weight.
 | 
					 | 
				
			||||||
	float scale=hardPix;
 | 
					 | 
				
			||||||
	float wa=Gaus(dst-2.0,scale);
 | 
					 | 
				
			||||||
	float wb=Gaus(dst-1.0,scale);
 | 
					 | 
				
			||||||
	float wc=Gaus(dst+0.0,scale);
 | 
					 | 
				
			||||||
	float wd=Gaus(dst+1.0,scale);
 | 
					 | 
				
			||||||
	float we=Gaus(dst+2.0,scale);
 | 
					 | 
				
			||||||
	// Return filtered sample.
 | 
					 | 
				
			||||||
	return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Return scanline weight.
 | 
					 | 
				
			||||||
float Scan(vec2 pos,float off){
 | 
					 | 
				
			||||||
	float dst=Dist(pos).y;
 | 
					 | 
				
			||||||
	return Gaus(dst+off,hardScan);}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Allow nearest three lines to effect pixel.
 | 
					 | 
				
			||||||
vec3 Tri(vec2 pos){
 | 
					 | 
				
			||||||
	vec3 a=Horz3(pos,-1.0);
 | 
					 | 
				
			||||||
	vec3 b=Horz5(pos, 0.0);
 | 
					 | 
				
			||||||
	vec3 c=Horz3(pos, 1.0);
 | 
					 | 
				
			||||||
	float wa=Scan(pos,-1.0);
 | 
					 | 
				
			||||||
	float wb=Scan(pos, 0.0);
 | 
					 | 
				
			||||||
	float wc=Scan(pos, 1.0);
 | 
					 | 
				
			||||||
	return a*wa+b*wb+c*wc;}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Distortion of scanlines, and end of screen alpha.
 | 
					 | 
				
			||||||
vec2 Warp(vec2 pos){
 | 
					 | 
				
			||||||
	pos=pos*2.0-1.0;    
 | 
					 | 
				
			||||||
	pos*=vec2(1.0+(pos.y*pos.y)*warp.x,1.0+(pos.x*pos.x)*warp.y);
 | 
					 | 
				
			||||||
	return pos*0.5+0.5;}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Shadow mask.
 | 
					 | 
				
			||||||
vec3 Mask(vec2 pos){
 | 
					 | 
				
			||||||
	pos.x+=pos.y*3.0;
 | 
					 | 
				
			||||||
	vec3 mask=vec3(maskDark,maskDark,maskDark);
 | 
					 | 
				
			||||||
	pos.x=fract(pos.x/6.0);
 | 
					 | 
				
			||||||
	if(pos.x<0.333)mask.r=maskLight;
 | 
					 | 
				
			||||||
	else if(pos.x<0.666)mask.g=maskLight;
 | 
					 | 
				
			||||||
	else mask.b=maskLight;
 | 
					 | 
				
			||||||
	return mask;}    
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void main() {
 | 
					 | 
				
			||||||
	hardScan=-12.0;
 | 
					 | 
				
			||||||
//  maskDark=maskLight;
 | 
					 | 
				
			||||||
	vec2 start=gl_FragCoord.xy-vec2(trg_x, trg_y);
 | 
					 | 
				
			||||||
	start.y=scr_h-start.y;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	vec2 pos=Warp(start/vec2(trg_w, trg_h));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	gl_FragColor.rgb=Tri(pos)*Mask(gl_FragCoord.xy);
 | 
					 | 
				
			||||||
	gl_FragColor = vec4(ToSrgb(gl_FragColor.rgb), 1.0);
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
@@ -1637,8 +1637,9 @@ void studioConfigChanged()
 | 
				
			|||||||
	if(code->update)
 | 
						if(code->update)
 | 
				
			||||||
		code->update(code);
 | 
							code->update(code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// initTouchGamepad();
 | 
					 | 
				
			||||||
	updateSystemFont();
 | 
						updateSystemFont();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						getSystem()->updateConfig();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u32 unzip(u8** dest, const u8* source, size_t size)
 | 
					u32 unzip(u8** dest, const u8* source, size_t size)
 | 
				
			||||||
@@ -1764,6 +1765,8 @@ static void studioTick()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void studioClose()
 | 
					static void studioClose()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						free((void*)getConfig()->crtShader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for(s32 i = 0; i < TIC_EDITOR_BANKS; i++)
 | 
							for(s32 i = 0; i < TIC_EDITOR_BANKS; i++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										135
									
								
								src/system.c
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								src/system.c
									
									
									
									
									
								
							@@ -12,7 +12,7 @@
 | 
				
			|||||||
#include <emscripten.h>
 | 
					#include <emscripten.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STUDIO_UI_SCALE 4
 | 
					#define STUDIO_UI_SCALE 3
 | 
				
			||||||
#define STUDIO_PIXEL_FORMAT GPU_FORMAT_RGBA
 | 
					#define STUDIO_PIXEL_FORMAT GPU_FORMAT_RGBA
 | 
				
			||||||
#define TEXTURE_SIZE (TIC80_FULLWIDTH)
 | 
					#define TEXTURE_SIZE (TIC80_FULLWIDTH)
 | 
				
			||||||
#define OFFSET_LEFT ((TIC80_FULLWIDTH-TIC80_WIDTH)/2)
 | 
					#define OFFSET_LEFT ((TIC80_FULLWIDTH-TIC80_WIDTH)/2)
 | 
				
			||||||
@@ -30,7 +30,6 @@ static struct
 | 
				
			|||||||
		GPU_Image* texture;
 | 
							GPU_Image* texture;
 | 
				
			||||||
		u32 shader;
 | 
							u32 shader;
 | 
				
			||||||
		GPU_ShaderBlock block;
 | 
							GPU_ShaderBlock block;
 | 
				
			||||||
		bool useShader;
 | 
					 | 
				
			||||||
	} gpu;
 | 
						} gpu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct
 | 
						struct
 | 
				
			||||||
@@ -212,7 +211,7 @@ static void calcTextureRect(SDL_Rect* rect)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	SDL_GetWindowSize(platform.window, &rect->w, &rect->h);
 | 
						SDL_GetWindowSize(platform.window, &rect->w, &rect->h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(platform.gpu.useShader)
 | 
						if(platform.studio->config()->crtMonitor)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		enum{Width = TIC80_FULLWIDTH, Height = TIC80_FULLHEIGHT};
 | 
							enum{Width = TIC80_FULLWIDTH, Height = TIC80_FULLHEIGHT};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -279,7 +278,7 @@ static void processMouse()
 | 
				
			|||||||
		SDL_Rect rect = {0, 0, 0, 0};
 | 
							SDL_Rect rect = {0, 0, 0, 0};
 | 
				
			||||||
		calcTextureRect(&rect);
 | 
							calcTextureRect(&rect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if(platform.gpu.useShader)
 | 
							if(platform.studio->config()->crtMonitor)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if(rect.w) input->mouse.x = (mx - rect.x) * TIC80_FULLWIDTH / rect.w - OFFSET_LEFT;
 | 
								if(rect.w) input->mouse.x = (mx - rect.x) * TIC80_FULLWIDTH / rect.w - OFFSET_LEFT;
 | 
				
			||||||
			if(rect.h) input->mouse.y = (my - rect.y) * TIC80_FULLHEIGHT / rect.h - OFFSET_TOP;
 | 
								if(rect.h) input->mouse.y = (my - rect.y) * TIC80_FULLHEIGHT / rect.h - OFFSET_TOP;
 | 
				
			||||||
@@ -946,6 +945,73 @@ static void preseed()
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void loadCrtShader()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static const char* VertexShader = "#version 100\n\
 | 
				
			||||||
 | 
							precision highp float;\n\
 | 
				
			||||||
 | 
							precision mediump int;\n\
 | 
				
			||||||
 | 
							attribute vec2 gpu_Vertex;\n\
 | 
				
			||||||
 | 
							attribute vec2 gpu_TexCoord;\n\
 | 
				
			||||||
 | 
							attribute mediump vec4 gpu_Color;\n\
 | 
				
			||||||
 | 
							uniform mat4 gpu_ModelViewProjectionMatrix;\n\
 | 
				
			||||||
 | 
							varying mediump vec4 color;\n\
 | 
				
			||||||
 | 
							varying vec2 texCoord;\n\
 | 
				
			||||||
 | 
							void main(void)\n\
 | 
				
			||||||
 | 
							{\n\
 | 
				
			||||||
 | 
								color = gpu_Color;\n\
 | 
				
			||||||
 | 
								texCoord = vec2(gpu_TexCoord);\n\
 | 
				
			||||||
 | 
								gl_Position = gpu_ModelViewProjectionMatrix * vec4(gpu_Vertex, 0.0, 1.0);\n\
 | 
				
			||||||
 | 
							}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 vertex = GPU_CompileShader(GPU_VERTEX_SHADER, VertexShader);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if(!vertex)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char msg[1024];
 | 
				
			||||||
 | 
							sprintf(msg, "Failed to load vertex shader: %s\n", GPU_GetShaderMessage());
 | 
				
			||||||
 | 
							showMessageBox("Error", msg);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 fragment = GPU_CompileShader(GPU_PIXEL_SHADER, platform.studio->config()->crtShader);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if(!fragment)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char msg[1024];
 | 
				
			||||||
 | 
							sprintf(msg, "Failed to load fragment shader: %s\n", GPU_GetShaderMessage());
 | 
				
			||||||
 | 
							showMessageBox("Error", msg);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if(platform.gpu.shader)
 | 
				
			||||||
 | 
							GPU_FreeShaderProgram(platform.gpu.shader);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						platform.gpu.shader = GPU_LinkShaders(vertex, fragment);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if(platform.gpu.shader)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							platform.gpu.block = GPU_LoadShaderBlock(platform.gpu.shader, "gpu_Vertex", "gpu_TexCoord", "gpu_Color", "gpu_ModelViewProjectionMatrix");
 | 
				
			||||||
 | 
							GPU_ActivateShaderProgram(platform.gpu.shader, &platform.gpu.block);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char msg[1024];
 | 
				
			||||||
 | 
							sprintf(msg, "Failed to link shader program: %s\n", GPU_GetShaderMessage());
 | 
				
			||||||
 | 
							showMessageBox("Error", msg);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void updateConfig()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if(platform.gpu.screen)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							initTouchGamepad();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(platform.studio->config()->crtMonitor)
 | 
				
			||||||
 | 
								loadCrtShader();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static System systemInterface = 
 | 
					static System systemInterface = 
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	.setClipboardText = setClipboardText,
 | 
						.setClipboardText = setClipboardText,
 | 
				
			||||||
@@ -966,6 +1032,7 @@ static System systemInterface =
 | 
				
			|||||||
	.openSystemPath = openSystemPath,
 | 
						.openSystemPath = openSystemPath,
 | 
				
			||||||
	.preseed = preseed,
 | 
						.preseed = preseed,
 | 
				
			||||||
	.poll = pollEvent,
 | 
						.poll = pollEvent,
 | 
				
			||||||
 | 
						.updateConfig = updateConfig,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void gpuTick()
 | 
					static void gpuTick()
 | 
				
			||||||
@@ -990,7 +1057,7 @@ static void gpuTick()
 | 
				
			|||||||
		GPU_UpdateImageBytes(platform.gpu.texture, NULL, (const u8*)tic->screen, TIC80_FULLWIDTH * sizeof(u32));
 | 
							GPU_UpdateImageBytes(platform.gpu.texture, NULL, (const u8*)tic->screen, TIC80_FULLWIDTH * sizeof(u32));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if(platform.gpu.useShader)
 | 
								if(platform.studio->config()->crtMonitor && platform.gpu.shader)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				SDL_Rect rect = {0, 0, 0, 0};
 | 
									SDL_Rect rect = {0, 0, 0, 0};
 | 
				
			||||||
				calcTextureRect(&rect);
 | 
									calcTextureRect(&rect);
 | 
				
			||||||
@@ -1012,10 +1079,11 @@ static void gpuTick()
 | 
				
			|||||||
				GPU_BlitScale(platform.gpu.texture, NULL, platform.gpu.screen, rect.x, rect.y, 
 | 
									GPU_BlitScale(platform.gpu.texture, NULL, platform.gpu.screen, rect.x, rect.y, 
 | 
				
			||||||
					(float)rect.w / TIC80_FULLWIDTH, (float)rect.h / TIC80_FULLHEIGHT);
 | 
										(float)rect.w / TIC80_FULLWIDTH, (float)rect.h / TIC80_FULLHEIGHT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				GPU_ActivateShaderProgram(0, NULL);
 | 
									GPU_DeactivateShaderProgram();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 | 
									GPU_DeactivateShaderProgram();
 | 
				
			||||||
				blitGpuTexture(platform.gpu.screen, platform.gpu.texture);
 | 
									blitGpuTexture(platform.gpu.screen, platform.gpu.texture);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -1077,57 +1145,6 @@ static void emsGpuTick()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SHADER(...) #__VA_ARGS__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void loadCrtShader()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	static const char* VertexShader = "#version 100\n\
 | 
					 | 
				
			||||||
		precision highp float;\n\
 | 
					 | 
				
			||||||
		precision mediump int;\n\
 | 
					 | 
				
			||||||
		attribute vec2 gpu_Vertex;\n\
 | 
					 | 
				
			||||||
		attribute vec2 gpu_TexCoord;\n\
 | 
					 | 
				
			||||||
		attribute mediump vec4 gpu_Color;\n\
 | 
					 | 
				
			||||||
		uniform mat4 gpu_ModelViewProjectionMatrix;\n\
 | 
					 | 
				
			||||||
		varying mediump vec4 color;\n\
 | 
					 | 
				
			||||||
		varying vec2 texCoord;\n\
 | 
					 | 
				
			||||||
		void main(void)\n\
 | 
					 | 
				
			||||||
		{\n\
 | 
					 | 
				
			||||||
			color = gpu_Color;\n\
 | 
					 | 
				
			||||||
			texCoord = vec2(gpu_TexCoord);\n\
 | 
					 | 
				
			||||||
			gl_Position = gpu_ModelViewProjectionMatrix * vec4(gpu_Vertex, 0.0, 1.0);\n\
 | 
					 | 
				
			||||||
		}";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u32 vertex = GPU_CompileShader(GPU_VERTEX_SHADER, VertexShader);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	if(!vertex)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		GPU_LogError("Failed to load vertex shader: %s\n", GPU_GetShaderMessage());
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	static const char* PixelShader = 
 | 
					 | 
				
			||||||
		#include "ext/shader/crt-lottes.frag"
 | 
					 | 
				
			||||||
	;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u32 fragment = GPU_CompileShader(GPU_PIXEL_SHADER, PixelShader);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	if(!fragment)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		GPU_LogError("Failed to load fragment shader: %s\n", GPU_GetShaderMessage());
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	platform.gpu.shader = GPU_LinkShaders(vertex, fragment);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	if(platform.gpu.shader)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		platform.gpu.block = GPU_LoadShaderBlock(platform.gpu.shader, "gpu_Vertex", "gpu_TexCoord", "gpu_Color", "gpu_ModelViewProjectionMatrix");
 | 
					 | 
				
			||||||
		GPU_ActivateShaderProgram(platform.gpu.shader, &platform.gpu.block);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		GPU_LogError("Failed to link shader program: %s\n", GPU_GetShaderMessage());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static s32 start(s32 argc, char **argv, const char* folder)
 | 
					static s32 start(s32 argc, char **argv, const char* folder)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
 | 
						SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
 | 
				
			||||||
@@ -1155,9 +1172,7 @@ static s32 start(s32 argc, char **argv, const char* folder)
 | 
				
			|||||||
	GPU_SetAnchor(platform.gpu.texture, 0, 0);
 | 
						GPU_SetAnchor(platform.gpu.texture, 0, 0);
 | 
				
			||||||
	GPU_SetImageFilter(platform.gpu.texture, GPU_FILTER_NEAREST);
 | 
						GPU_SetImageFilter(platform.gpu.texture, GPU_FILTER_NEAREST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	platform.gpu.useShader = true;
 | 
						if(platform.studio->config()->crtMonitor)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if(platform.gpu.useShader)
 | 
					 | 
				
			||||||
		loadCrtShader();
 | 
							loadCrtShader();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__EMSCRIPTEN__)
 | 
					#if defined(__EMSCRIPTEN__)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,8 @@ typedef struct
 | 
				
			|||||||
	void (*preseed)();
 | 
						void (*preseed)();
 | 
				
			||||||
	void (*poll)();
 | 
						void (*poll)();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void (*updateConfig)();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} System;
 | 
					} System;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct
 | 
					typedef struct
 | 
				
			||||||
@@ -67,6 +69,9 @@ typedef struct
 | 
				
			|||||||
	bool checkNewVersion;
 | 
						bool checkNewVersion;
 | 
				
			||||||
	bool noSound;
 | 
						bool noSound;
 | 
				
			||||||
	bool showSync;
 | 
						bool showSync;
 | 
				
			||||||
 | 
						bool crtMonitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const char* crtShader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} StudioConfig;
 | 
					} StudioConfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user