cmp_plot3x3
[fishladder.git] / fishladder_resources.h
1 // FONTS
2
3 struct sdf_char
4 {
5 u16 uvx, uvy, originX, originY, w, h, advance;
6 };
7
8 struct sdf_font
9 {
10 const char *name;
11 int size, width, height;
12 struct sdf_char *characters;
13 };
14
15 static struct sdf_char characters_Ubuntu[] = {
16 {655, 167, 9, 9, 18, 18, 11},
17 {561, 64, 6, 42, 25, 52, 13},
18 {435, 167, 6, 45, 32, 30, 20},
19 {797, 64, 7, 42, 46, 51, 32},
20 {362, 0, 6, 46, 39, 60, 27},
21 {918, 0, 7, 43, 55, 52, 41},
22 {973, 0, 7, 43, 47, 52, 32},
23 {467, 167, 6, 45, 23, 30, 11},
24 {142, 0, 5, 46, 30, 64, 15},
25 {172, 0, 9, 46, 30, 64, 15},
26 {291, 167, 7, 42, 38, 37, 23},
27 {171, 167, 6, 35, 40, 42, 27},
28 {410, 167, 7, 14, 25, 31, 12},
29 {625, 167, 8, 26, 30, 22, 14},
30 {558, 167, 6, 15, 25, 24, 12},
31 {0, 0, 10, 46, 39, 64, 18},
32 {88, 64, 7, 43, 41, 52, 27},
33 {532, 116, 5, 42, 32, 51, 27},
34 {370, 64, 6, 43, 39, 52, 27},
35 {409, 64, 6, 43, 39, 52, 27},
36 {176, 116, 7, 42, 42, 51, 27},
37 {448, 64, 6, 42, 39, 52, 27},
38 {170, 64, 6, 42, 40, 52, 27},
39 {343, 116, 6, 42, 40, 51, 27},
40 {854, 0, 6, 43, 40, 53, 27},
41 {210, 64, 7, 43, 40, 52, 27},
42 {146, 167, 6, 34, 25, 43, 12},
43 {564, 116, 7, 34, 26, 51, 12},
44 {211, 167, 6, 34, 40, 39, 27},
45 {370, 167, 6, 30, 40, 32, 27},
46 {251, 167, 6, 34, 40, 39, 27},
47 {525, 64, 8, 43, 36, 52, 19},
48 {401, 0, 6, 43, 57, 59, 45},
49 {700, 64, 9, 42, 49, 51, 32},
50 {218, 116, 5, 42, 42, 51, 31},
51 {769, 0, 6, 43, 44, 53, 30},
52 {935, 64, 5, 42, 45, 51, 34},
53 {383, 116, 5, 42, 40, 51, 27},
54 {423, 116, 5, 42, 38, 51, 26},
55 {724, 0, 6, 43, 45, 53, 32},
56 {45, 116, 5, 42, 44, 51, 34},
57 {590, 116, 5, 42, 23, 51, 13},
58 {487, 64, 9, 42, 38, 52, 24},
59 {89, 116, 5, 42, 44, 51, 30},
60 {461, 116, 5, 42, 38, 51, 25},
61 {646, 64, 6, 42, 54, 51, 42},
62 {0, 116, 5, 42, 45, 51, 35},
63 {674, 0, 6, 43, 50, 53, 37},
64 {302, 116, 5, 42, 41, 51, 29},
65 {312, 0, 6, 43, 50, 61, 37},
66 {133, 116, 5, 42, 43, 51, 30},
67 {813, 0, 7, 43, 41, 53, 25},
68 {0, 64, 8, 42, 44, 52, 27},
69 {44, 64, 5, 42, 44, 52, 33},
70 {749, 64, 8, 42, 48, 51, 31},
71 {586, 64, 8, 42, 60, 51, 44},
72 {843, 64, 8, 42, 46, 51, 30},
73 {889, 64, 9, 42, 46, 51, 28},
74 {260, 116, 7, 42, 42, 51, 27},
75 {202, 0, 4, 46, 29, 64, 16},
76 {39, 0, 10, 46, 39, 64, 18},
77 {231, 0, 9, 46, 29, 64, 16},
78 {329, 167, 7, 42, 41, 36, 27},
79 {583, 167, 9, 4, 42, 22, 23},
80 {490, 167, 6, 46, 27, 28, 18},
81 {695, 116, 7, 34, 38, 44, 25},
82 {458, 0, 5, 46, 40, 56, 28},
83 {733, 116, 7, 34, 37, 44, 22},
84 {498, 0, 7, 46, 40, 56, 28},
85 {655, 116, 7, 34, 40, 44, 27},
86 {641, 0, 5, 46, 33, 55, 18},
87 {250, 64, 7, 34, 40, 52, 27},
88 {603, 0, 5, 46, 38, 55, 27},
89 {894, 0, 6, 44, 24, 53, 12},
90 {282, 0, 12, 44, 30, 62, 12},
91 {564, 0, 5, 46, 39, 55, 25},
92 {538, 0, 5, 46, 26, 56, 13},
93 {860, 116, 5, 34, 52, 43, 41},
94 {0, 167, 5, 34, 38, 43, 27},
95 {613, 116, 7, 34, 42, 44, 28},
96 {290, 64, 5, 34, 40, 52, 28},
97 {330, 64, 7, 34, 40, 52, 28},
98 {113, 167, 5, 34, 33, 43, 18},
99 {770, 116, 7, 34, 36, 44, 21},
100 {499, 116, 5, 42, 33, 51, 19},
101 {38, 167, 5, 34, 38, 43, 27},
102 {912, 116, 8, 34, 41, 43, 24},
103 {806, 116, 8, 34, 54, 43, 37},
104 {953, 116, 8, 34, 41, 43, 24},
105 {129, 64, 9, 34, 41, 52, 24},
106 {76, 167, 7, 34, 37, 43, 22},
107 {78, 0, 7, 46, 32, 64, 16},
108 {260, 0, 4, 46, 22, 64, 13},
109 {110, 0, 9, 46, 32, 64, 16},
110 {517, 167, 7, 27, 41, 26, 27},
111 };
112
113 static struct sdf_font font_Ubuntu = {"Ubuntu", 48, 1024, 256, characters_Ubuntu};
114
115 vg_tex2d tex_ubuntu = { .path = "textures/ubuntu.qoi" };
116
117 // TEXTURES
118 // ===========================================================================================================
119
120 vg_tex2d tex_tile_data = { .path = "textures/tileset.qoi" };
121 vg_tex2d tex_tile_detail = { .path = "textures/tile_overlays.qoi" };
122 vg_tex2d tex_wood = { .path = "textures/wood.qoi" };
123 vg_tex2d tex_ball_noise = { .path = "textures/bnoise.qoi" };
124 vg_tex2d tex_monofur = { .path = "textures/ascii.qoi", .flags = VG_TEXTURE_NO_MIP };
125 vg_tex2d tex_unkown = { .path = "textures/unkown.qoi" };
126 vg_tex2d tex_buttons = { .path = "textures/buttons.qoi" };
127
128 vg_tex2d *texture_list[] = { &tex_tile_detail, &tex_tile_data, &tex_wood, &tex_ball_noise, &tex_monofur, &tex_unkown, &tex_buttons, &tex_ubuntu };
129
130 // AUDIO
131 // ===========================================================================================================
132
133 sfx_vol_control audio_volume_sfx = { .val = 1.0f, .name = "Sound effects" };
134 sfx_vol_control audio_volume_music = { .val = 1.0f, .name = "Music" };
135
136 sfx_system audio_system_sfx =
137 {
138 .vol = 1.f,
139 .ch = 1,
140 .vol_src = &audio_volume_sfx,
141 .name = "sfx"
142 };
143
144 sfx_set audio_tile_mod =
145 {
146 .sources = "\
147 sound/mod_01.ogg\0\
148 sound/mod_02.ogg\0\
149 sound/mod_03.ogg\0\
150 sound/mod_04.ogg\0\
151 sound/mod_05.ogg\0\
152 sound/mod_06.ogg\0",
153 .flags = 0
154 };
155
156 sfx_set audio_splitter =
157 {
158 .sources = "\
159 sound/splitter_01.ogg\0"
160 };
161
162 sfx_set audio_rolls =
163 {
164 .sources = "\
165 sound/rolling_01.ogg\0\
166 sound/rolling_02.ogg\0"
167 };
168
169 sfx_set audio_random =
170 {
171 .sources = "\
172 sound/random_01.ogg\0\
173 sound/random_02.ogg\0\
174 sound/random_03.ogg\0\
175 sound/random_04.ogg\0\
176 sound/random_05.ogg\0\
177 sound/random_06.ogg\0\
178 sound/random_07.ogg\0\
179 sound/random_08.ogg\0"
180 };
181
182 sfx_set audio_clicks =
183 {
184 .sources = "\
185 sound/click_a.ogg\0\
186 sound/click_b.ogg\0\
187 sound/click_c.ogg\0"
188 };
189
190 sfx_set audio_tones =
191 {
192 .sources = "\
193 sound/y0.ogg\0\
194 sound/y1.ogg\0\
195 sound/y2.ogg\0\
196 sound/y3.ogg\0\
197 sound/y4.ogg\0\
198 sound/y5.ogg\0\
199 sound/y6.ogg\0\
200 sound/y7.ogg\0\
201 sound/y8.ogg\0\
202 sound/win.ogg\0"
203 };
204
205 // One two or three layers of rolling noise
206 sfx_system audio_system_balls_rolling =
207 {
208 .vol = 0.7f, .ch = 1, .vol_src = &audio_volume_sfx,
209 .name = "Balls Rolling", .flags = SFX_FLAG_REPEAT | SFX_FLAG_PERSISTENT
210 };
211
212 // Various oneshots
213 sfx_system audio_system_balls_switching =
214 {
215 .vol = 0.2f, .ch = 1, .vol_src = &audio_volume_sfx,
216 .name = "Balls Switching"
217 };
218
219 // Gameplay critical sounds eg. splitter sound rocking
220 sfx_system audio_system_balls_important =
221 {
222 .vol = 1.f, .ch = 1, .vol_src = &audio_volume_sfx,
223 .name = "Balls Gameplay"
224 };
225
226 // Suplemental sounds
227 sfx_system audio_system_balls_extra =
228 {
229 .vol = 0.27f, .ch = 1, .vol_src = &audio_volume_sfx,
230 .name = "Balls Extra"
231 };
232
233 sfx_system audio_system_ui =
234 {
235 .vol = 1.f, .ch = 1, .vol_src = &audio_volume_sfx,
236 .name = "UI"
237 };
238
239 ui_colourset ui_fl_colours = {
240 .main = 0xff807373,
241 .hover = 0xff918484,
242 .active = 0xffad9f9e
243 };
244
245 ui_colourset ui_fl_colours_inactive = {
246 .main = 0xff655958,
247 .hover = 0xff655958,
248 .active = 0xff655958
249 };
250
251 static void resource_load_main(void)
252 {
253 // Textures // UI
254 vg_tex2d_init( texture_list, vg_list_size( texture_list ) );
255 ui_global_ctx.colours_main = &ui_fl_colours;
256 gui_reset_colours();
257
258 // Audio
259 sfx_set_init( &audio_tile_mod, NULL );
260 sfx_set_init( &audio_splitter, NULL );
261 sfx_set_init( &audio_rolls, NULL );
262 sfx_set_init( &audio_random, NULL );
263 sfx_set_init( &audio_clicks, NULL );
264 sfx_set_init( &audio_tones, NULL );
265 }
266
267 static void resource_free_main(void)
268 {
269 vg_tex2d_free( texture_list, vg_list_size( texture_list ) );
270
271 sfx_set_free( &audio_tile_mod );
272 sfx_set_free( &audio_splitter );
273 sfx_set_free( &audio_rolls );
274 sfx_set_free( &audio_random );
275 sfx_set_free( &audio_clicks );
276 sfx_set_free( &audio_tones );
277 }
278
279 // SHADERS
280 // ===========================================================================================================
281
282 SHADER_DEFINE( shader_tile_colour,
283
284 // VERTEX
285 "layout (location=0) in vec2 a_co;"
286 "uniform mat3 uPv;"
287 "uniform vec3 uOffset;"
288 ""
289 "void main()"
290 "{"
291 "gl_Position = vec4( uPv * vec3( a_co * uOffset.z + uOffset.xy, 1.0 ), 1.0 );"
292 "}",
293
294 // FRAGMENT
295 "out vec4 FragColor;"
296 "uniform vec4 uColour;"
297 ""
298 "void main()"
299 "{"
300 "FragColor = uColour;"
301 "}"
302 ,
303 UNIFORMS({ "uPv", "uOffset", "uColour" })
304 )
305
306 SHADER_DEFINE( shader_ball,
307 // VERTEX
308 "layout (location=0) in vec2 a_co;"
309 "uniform vec3 uOffset;"
310 "uniform mat3 uPv;"
311 ""
312 "out vec4 aTexCoords;"
313 ""
314 "void main()"
315 "{"
316 // Vertex transform
317 "vec3 worldpos = vec3( (a_co * 0.5 - 0.25) * uOffset.z + uOffset.xy, 1.0 );"
318 "gl_Position = vec4( uPv * worldpos, 1.0 );"
319
320 // Create texture coords
321 "aTexCoords = vec4( a_co, worldpos.xy );"
322 "}",
323
324 // FRAGMENT
325 "out vec4 FragColor;"
326 ""
327 "uniform sampler2D uTexMain;"
328 "uniform vec3 uColour;"
329 "uniform vec2 uTexOffset;"
330 ""
331 "in vec4 aTexCoords;"
332 ""
333 "void main()"
334 "{"
335 "vec2 center_coords = aTexCoords.xy - 0.5;"
336 "vec2 center_coords_sqr = center_coords*center_coords;"
337 "float circle_factor = smoothstep( 0.07, 0.0625, center_coords_sqr.x+center_coords_sqr.y );"
338
339 "float bulge_amt = center_coords_sqr.x+center_coords_sqr.y;"
340 "vec2 warped_coords = aTexCoords.zw+uTexOffset - center_coords;"
341 "vec4 noise_sample = texture( uTexMain, warped_coords );"
342
343 "float rim_light = (center_coords_sqr.x+center_coords_sqr.y)*15.0;"
344
345 "vec2 shadow_coords = center_coords + vec2(0.02,0.07);"
346 "vec2 shadow_coords_sqr = shadow_coords*shadow_coords;"
347 "float shadow = exp(-((shadow_coords_sqr.x+shadow_coords_sqr.y)-0.0125)*15.0);"
348
349 "vec3 marble_comp = uColour*0.9 + (noise_sample.x*0.7+pow(rim_light,3.0)*2.0) * 0.1;"
350 "vec4 colour_comp = mix( vec4(0.74,0.53,0.34,shadow), vec4(marble_comp,1.0), circle_factor );"
351
352 "FragColor = colour_comp;"
353 "}"
354 ,
355 UNIFORMS({ "uTexMain", "uColour", "uOffset", "uPv", "uTexOffset" })
356 )
357
358 SHADER_DEFINE( shader_tile_main,
359 // VERTEX
360 "layout (location=0) in vec2 a_co;"
361 "uniform vec4 uOffset;" // Tile x/y, uv x/y
362 "uniform mat3 uPv;"
363 "uniform mat2 uSubTransform;"
364 "uniform float uVisibility;"
365 ""
366 "out vec4 aTexCoords;"
367 "out vec2 aWorldCoords;"
368 ""
369 "vec2 hash22(vec2 p)"
370 "{"
371 "vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));"
372 "p3 += dot(p3, p3.yzx+33.33);"
373 "return fract((p3.xx+p3.yz)*p3.zy);"
374 "}"
375 ""
376 "void main()"
377 "{"
378 "vec2 hash_val = hash22(uOffset.xy);"
379 "float scaling_factor = smoothstep( hash_val.x, hash_val.x+1.0, uVisibility );"
380
381 // Vertex transform
382 "vec2 subtransform = uSubTransform * (a_co-0.5) * scaling_factor + 0.5;"
383 "vec3 worldpos = vec3( subtransform + uOffset.xy, 1.0 );"
384 "gl_Position = vec4( uPv * worldpos, 1.0 );"
385
386 // Create texture coords
387 "vec2 random_offset = floor(hash_val * 4.0) * 0.25;"
388 "vec2 edge_safe_coords = a_co * 0.98 + 0.01;"
389 "aTexCoords = vec4((edge_safe_coords + uOffset.zw) * 0.25, edge_safe_coords * 0.25 + random_offset );"
390 "aWorldCoords = worldpos.xy;"
391 "}",
392
393 // FRAGMENT
394 "out vec4 FragColor;"
395 ""
396 "uniform sampler2D uTexGlyphs;"
397 "uniform sampler2D uTexWood;"
398 "uniform float uGhost;"
399 "uniform float uForeground;"
400 "uniform vec2 uMousePos;"
401 "uniform vec4 uColour;"
402 ""
403 "in vec4 aTexCoords;"
404 "in vec2 aWorldCoords;"
405 ""
406 "void main()"
407 "{"
408 "vec3 shadowing_colour = vec3( 0.93, 0.88536, 0.8184 ) * 0.97;"
409 "vec4 glyph = texture( uTexGlyphs, aTexCoords.xy );"
410 "vec4 wood = texture( uTexWood, aTexCoords.zw );"
411 "vec4 wood_secondary = texture( uTexWood, aTexCoords.zw + 0.25 );"
412 "vec3 wood_comp = mix( wood_secondary.rgb * shadowing_colour, wood.rgb, clamp( glyph.b * 2.0 - 1.0, 0.0, 1.0 ) );"
413
414 "vec3 shadows = mix( vec3( 0.85, 0.7344, 0.561 ), vec3(1.0,1.0,1.0), glyph.r );"
415
416 "vec4 output_regular = vec4( wood_comp * shadows, mix( glyph.a, glyph.b, uForeground ) );"
417
418 "float ghost_dist = clamp( 1.5 - distance(uMousePos, aWorldCoords), 0.0, 1.0 );"
419 "vec4 output_ghost = vec4( 1.0, 1.0, 1.0, glyph.g * ghost_dist );"
420
421 "FragColor = mix( output_regular, output_ghost, uGhost ) * uColour;"
422 "}"
423 ,
424 UNIFORMS({ "uPv", "uOffset", "uTexGlyphs", "uTexWood", "uSubTransform", "uGhost", "uMousePos", "uColour", "uForeground", "uVisibility" })
425 )
426
427 SHADER_DEFINE( shader_background,
428 // VERTEX
429 "layout (location=0) in vec2 a_co;"
430 "uniform mat3 uPv;"
431 "uniform vec3 uOffset;"
432 ""
433 "out vec2 aTexCoords;"
434 ""
435 "void main()"
436 "{"
437 "vec2 world_pos = a_co * uOffset.z + uOffset.xy;"
438 "gl_Position = vec4( uPv * vec3( world_pos, 1.0 ), 1.0 );"
439 "aTexCoords = a_co;"
440 "}",
441
442 // FRAGMENT
443 "out vec4 FragColor;"
444 ""
445 "uniform sampler2D uTexMain;"
446 "uniform sampler2D uSamplerNoise;"
447 "uniform float uVariance;"
448 "uniform float uVisibility;"
449 ""
450 "in vec2 aTexCoords;"
451 ""
452 "void main()"
453 "{"
454 "float ao_accum = 0.0;"
455 "for( int i=0; i<10; ++i )"
456 "{"
457 "vec2 random_noise = (texture( uSamplerNoise, aTexCoords * 20.0 + float(i) * 0.2 ).xy - vec2( 0.5, 0.5 )) * uVariance;"
458 "vec4 background = texture( uTexMain, aTexCoords + random_noise );"
459 "ao_accum += background.r * clamp((1.0 - length( random_noise )), 0.0, 1.0);"
460 "}"
461 "ao_accum *= 0.15;"
462
463 "vec4 data_this_tile = texture( uTexMain, aTexCoords );"
464
465 "ao_accum -= data_this_tile.r;"
466 "ao_accum *= uVisibility;"
467
468 "vec3 colour_main = mix( vec3( 0.369768, 0.3654, 0.42 ), vec3( 0.275, 0.388, 0.553 ), data_this_tile.g * uVisibility );"
469
470 "vec2 square_coords = fract( aTexCoords * 64.0 );"
471 "vec2 grid_coords = abs( square_coords - 0.5 );"
472 "float edge_contrast = (1.0-ao_accum*0.2);"
473
474 "float gridline = step( 0.49, max(grid_coords.x,grid_coords.y) );"
475 "float gridline_fadeout = min(max(edge_contrast-1.0, 0.0)*40.0 + data_this_tile.g,10.0);"
476
477 "FragColor = vec4( colour_main * edge_contrast + gridline * 0.02 * gridline_fadeout, 1.0 );"
478 "}"
479 ,
480 UNIFORMS({ "uPv", "uOffset", "uTexMain", "uVariance", "uSamplerNoise", "uVisibility" })
481 )
482
483 SHADER_DEFINE( shader_wire,
484 // VERTEX
485 "layout (location=0) in vec2 a_co;"
486 "uniform vec3 uStart;"
487 "uniform vec3 uEnd;"
488 "uniform mat3 uPv;"
489 "uniform float uCurve;"
490 ""
491 "out vec2 aTexCoords;"
492 ""
493 "vec3 sample_curve_time( float t )"
494 "{"
495 "vec3 line_coord = mix( uStart, uEnd, t );"
496
497 "float curve_amt = 1.0-(pow((t*2.0-1.0),2.0));"
498 "return vec3( line_coord.x, line_coord.y - curve_amt*uCurve, line_coord.z );"
499 "}"
500 ""
501 "void main()"
502 "{"
503 // Vertex transform
504 "vec3 p0 = sample_curve_time( a_co.x );"
505 "vec3 p1 = sample_curve_time( a_co.x + 0.025 );"
506
507 "vec2 line_tangent = normalize(p1.xy-p0.xy);"
508 "vec2 line_normal = vec2( -line_tangent.y, line_tangent.x );"
509
510 "vec2 worldfinal = p0.xy + line_normal*a_co.y*p0.z;"
511
512 "gl_Position = vec4( uPv * vec3(worldfinal, 1.0), 1.0 );"
513
514 // Create texture coords (todo: include stretch adjusted coords?)
515 "aTexCoords = vec2( a_co.x, a_co.y + 0.5 );"
516 "}",
517
518 // FRAGMENT
519 "out vec4 FragColor;"
520 ""
521 "uniform sampler2D uTexMain;"
522 "uniform vec4 uColour;"
523 "uniform float uTime;"
524 "uniform float uGlow;"
525 ""
526 "in vec2 aTexCoords;"
527 ""
528 "void main()"
529 "{"
530 // Compute shadowing
531 "float shadow = 1.0 - abs(aTexCoords.y - 0.5) * 2.0;"
532 "float masking = smoothstep( 0.5, 0.8, shadow );"
533
534 "vec3 colour_comp = mix( vec3(0.0,0.0,0.0), uColour.rgb, masking );"
535
536 "float flow_thing = fract( aTexCoords.x + uTime );"
537 "vec3 final_comp = colour_comp + flow_thing * uGlow;"
538
539 "FragColor = vec4( final_comp, max( shadow* 0.2, masking ) * uColour.a );"
540 "}"
541 ,
542 UNIFORMS({ "uPv", "uColour", "uTexMain", "uStart", "uEnd", "uCurve", "uTime", "uGlow" })
543 )
544
545 SHADER_DEFINE( shader_buttons,
546 // VERTEX
547 "layout (location=0) in vec2 a_co;"
548 "uniform vec4 uOffset;" // Tile x/y, uv x/y
549 "uniform mat3 uPv;"
550 ""
551 "out vec2 aTexCoords;"
552 ""
553 "void main()"
554 "{"
555 // Vertex transform
556 "vec3 worldpos = vec3( a_co + uOffset.xy, 1.0 );"
557 "gl_Position = vec4( uPv * worldpos, 1.0 );"
558
559 // Create texture coords
560 "vec2 edge_safe_coords = a_co * 0.98 + 0.01;"
561 "aTexCoords = (edge_safe_coords + uOffset.zw) * 0.25;"
562 "}",
563
564 // FRAGMENT
565 "out vec4 FragColor;"
566 ""
567 "uniform sampler2D uTexMain;"
568 "uniform vec4 uColour;" // rgb, light amount
569 ""
570 "in vec2 aTexCoords;"
571 ""
572 "void main()"
573 "{"
574 "vec4 glyph = texture( uTexMain, aTexCoords.xy );"
575
576 "FragColor = vec4( uColour.rgb * (mix(glyph.r, glyph.g, uColour.a)+0.02)*2.6 + glyph.b * 0.4, glyph.a );"
577 "}"
578 ,
579 UNIFORMS({ "uPv", "uOffset", "uTexMain", "uColour" })
580 )
581
582 SHADER_DEFINE( shader_sdf,
583
584 // VERTEX
585 "layout (location=0) in vec2 a_co;"
586 "layout (location=1) in vec2 a_uv;"
587 "uniform mat3 uPv;"
588 ""
589 "out vec2 aTexCoords;"
590 ""
591 "void main()"
592 "{"
593 "gl_Position = vec4( uPv * vec3( a_co, 1.0 ), 1.0 );"
594 "aTexCoords = a_uv;"
595 "}",
596
597 // FRAGMENT
598 "uniform sampler2D uTexGlyphs;"
599 "uniform vec4 uColour;"
600 "out vec4 FragColor;"
601 ""
602 "in vec2 aTexCoords;"
603 "in vec4 aColour;"
604 ""
605 "void main()"
606 "{"
607 "vec4 glyph = texture( uTexGlyphs, aTexCoords );"
608 "FragColor = vec4( uColour.rgb, smoothstep( 0.46, 0.54, glyph.r ) * uColour.a );"
609 //"FragColor = glyph;"
610 "}"
611 ,
612 UNIFORMS({ "uPv", "uTexGlyphs", "uColour" })
613 )
614
615 void vg_register(void)
616 {
617 SHADER_INIT( shader_tile_colour );
618 SHADER_INIT( shader_tile_main );
619 SHADER_INIT( shader_ball );
620 SHADER_INIT( shader_background );
621 SHADER_INIT( shader_wire );
622 SHADER_INIT( shader_buttons );
623 SHADER_INIT( shader_sdf );
624 }
625
626 /*
627 0000 0 | 0001 1 | 0010 2 | 0011 3
628 | | | | |
629 X | X= | X | X=
630 | | |
631 0100 4 | 0101 5 | 0110 6 | 0111 7
632 | | | | |
633 =X | =X= | =X | =X=
634 | | |
635 1000 8 | 1001 9 | 1010 10 | 1011 11
636 | | | | |
637 X | X= | X | X=
638 | | | | | | |
639 1100 12 | 1101 13 | 1110 14 | 1111 15
640 | | | | |
641 =X | =X= | =X | =X=
642 | | | | | | |
643 */
644
645 struct cmp_level
646 {
647 const char *map_name;
648 const char *title;
649 const char *description;
650 const char *achievement;
651
652 int unlocked;
653 int completed_score;
654
655 int _unlock, _linked; // When completed, unlock this level
656 struct cmp_level *unlock, *linked;
657
658 int serial_id;
659 int is_tutorial;
660
661 struct world_button btn;
662
663 #ifdef VG_STEAM
664 SteamLeaderboard_t steam_leaderboard;
665 #endif
666 };
667
668 static struct cmp_level cmp_levels_tutorials[] =
669 {
670 // r1
671 {
672 .serial_id = 0,
673 .title = "PRINCIPLE 1",
674 .map_name = "cmp_t01",
675 .description =
676 "",
677
678 ._unlock = 1,
679 .is_tutorial = 1
680 },
681 // r1
682 {
683 .serial_id = 1,
684 .title = "PRINCIPLE 2",
685 .map_name = "cmp_t02",
686 .description =
687 "",
688
689 ._unlock = 2,
690 .is_tutorial = 1,
691 },
692 // r1
693 {
694 .serial_id = 2,
695 .title = "PRINCIPLE 3",
696 .map_name = "cmp_t03",
697 .description =
698 "",
699
700 ._unlock = 12,
701 .is_tutorial = 1
702 },
703 // r1
704 {
705 .serial_id = 12,
706 .title = "PRINCIPLE 4",
707 .map_name = "cmp_t04",
708 .description =
709 "",
710
711 ._unlock = 6,
712 .is_tutorial = 1,
713 .achievement = "TUTORIALS"
714 }
715 };
716
717 static struct cmp_level cmp_levels_basic[] =
718 {
719 // r2 GM
720 {
721 .serial_id = 6,
722 .title = "PATCH",
723 .map_name = "cmp_b04",
724 .description =
725 "",
726
727 ._unlock = 7,
728 ._linked = 3
729 },
730 // r1 GM
731 {
732 .serial_id = 3,
733 .title = "SUBDIVISION 1",
734 .map_name = "cmp_b01",
735 .description =
736 "",
737
738 ._linked = 4,
739 ._unlock = 5
740 },
741 // r1 GM
742 {
743 .serial_id = 4,
744 .title = "SUBDIVISION 2",
745 .map_name = "cmp_b02",
746 .description =
747 "",
748
749 ._unlock = 7
750 },
751 // r1 GM
752 {
753 .serial_id = 5,
754 .title = "RESTRUCTURE",
755 .map_name = "cmp_b03",
756 .description =
757 "",
758
759 ._unlock = 8
760 },
761 // r2 GM
762 {
763 .serial_id = 7,
764 .title = "PATTERNS 1",
765 .map_name = "cmp_b05",
766 .description =
767 "",
768
769 ._unlock = 15,
770 ._linked = 8
771 },
772 // r2 GM
773 {
774 .serial_id = 8,
775 .title = "PATTERNS 2",
776 .map_name = "cmp_b06",
777 .description =
778 "",
779
780 ._unlock = 15
781 },
782 // r2 GM
783 {
784 .serial_id = 15,
785 .title = "PRINCIPLE 5",
786 .map_name = "cmp_b10",
787 .description =
788 "",
789
790 ._unlock = 16,
791 .is_tutorial = 1
792 },
793 // r2 GM
794 {
795 .serial_id = 16,
796 .title = "ROUTING PROBLEM",
797 .map_name = "cmp_routing",
798 .description =
799 "",
800
801 ._linked = 9
802 },
803 // r2 GM
804 {
805 .serial_id = 9,
806 .title = "MIGHTY CONSUMER",
807 .map_name = "cmp_b07",
808 .description =
809 "",
810
811 ._linked = 10,
812 ._unlock = 11,
813 .achievement = "MIGHTY_CONSUMER"
814 },
815 {
816 .serial_id = 10,
817 .title = "SHIFT",
818 .map_name = "cmp_b08",
819 .description =
820 "",
821
822 ._unlock = 17
823 },
824 // r2 GM
825 {
826 .serial_id = 11,
827 .title = "REVERSE",
828 .map_name = "cmp_b09",
829 .description =
830 "",
831
832 ._unlock = 17
833 },
834 // r2 GM
835 {
836 .serial_id = 17,
837 .title = "PRINCIPLE 6",
838 .map_name = "cmp_b11",
839 .description =
840 "(Right click)",
841
842 ._unlock = 18,
843 .is_tutorial = 1
844 },
845 // r2 GM
846 {
847 .serial_id = 18,
848 .title = "NOT GATE",
849 .map_name = "cmp_not",
850 .description = "",
851
852 ._linked = 19,
853 ._unlock = 20
854 },
855 // r2 GM
856 {
857 .serial_id = 19,
858 .title = "AND GATE",
859 .map_name = "cmp_and",
860 .description = "",
861
862 ._unlock = 20
863 },
864 // r2 GM
865 {
866 .serial_id = 20,
867 .title = "QUALIFICATION PROJECT",
868 .map_name = "cmp_xor",
869 .description = "",
870
871 ._unlock = 13,
872 .achievement = "GRADUATE"
873 }
874 };
875
876 static struct cmp_level cmp_levels_grad[] =
877 {
878 // r2
879 {
880 .serial_id = 13,
881 .title = "SORT",
882 .map_name = "cmp_i01",
883 .description = "",
884 ._linked = 14
885
886 },
887 // r2
888 {
889 .serial_id = 14,
890 .title = "THIRDS",
891 .map_name = "cmp_i02",
892 .description = "",
893 ._linked = 21
894
895 },
896 // r2 GM
897 {
898 .serial_id = 21,
899 .title = "SIMPLE ADDITION",
900 .map_name = "cmp_grad",
901 .description = "",
902
903 ._linked = 22,
904 ._unlock = 23
905 },
906 // r2 GM
907 {
908 .serial_id = 22,
909 .title = "SECRET CODE",
910 .map_name = "cmp_secret",
911 .description = "",
912
913 ._unlock = 23
914 }
915 };
916
917 static struct cmp_level cmp_levels_computer[] =
918 {
919 {
920 .serial_id = 23,
921 .title = "3 BIT BINARY",
922 .map_name = "cmp_binary",
923 .description = "",
924
925 ._unlock = 24
926 },
927 {
928 .serial_id = 24,
929 .title = "3 BIT ADDITION",
930 .map_name = "cmp_add3b",
931 .description = "",
932
933 ._unlock = 25
934 },
935 {
936 .serial_id = 25,
937 .title = "3x3 PLOT",
938 .map_name = "cmp_plot3x3",
939 .description = ""
940 }
941 };
942
943 #define NUM_CAMPAIGN_LEVELS (vg_list_size( cmp_levels_tutorials ) + vg_list_size( cmp_levels_basic ) + vg_list_size( cmp_levels_grad ) + vg_list_size( cmp_levels_computer ) )
944
945 static struct career_level_pack
946 {
947 struct cmp_level *pack;
948 int count;
949
950 v3f primary_colour;
951 v2i origin;
952 v2i dims;
953 }
954 career_packs[] =
955 {
956 {
957 .pack = cmp_levels_tutorials,
958 .count = vg_list_size( cmp_levels_tutorials ),
959 .primary_colour = { 0.204f, 0.345f, 0.553f },
960 .origin = { -5, 0 },
961 .dims = { 1, 4 }
962 },
963 {
964 .pack = cmp_levels_basic,
965 .count = vg_list_size( cmp_levels_basic ),
966 .primary_colour = { 0.304f, 0.245f, 0.553f },
967 .origin = { -3, 0 },
968 .dims = { 3, 5 }
969 },
970 {
971 .pack = cmp_levels_grad,
972 .count = vg_list_size( cmp_levels_grad ),
973 .primary_colour = { 0.553f, 0.345f, 0.204f },
974 .origin = { -5, 6 },
975 .dims = { 4, 1 }
976 },
977 {
978 .pack = cmp_levels_computer,
979 .count = vg_list_size( cmp_levels_computer ),
980 .primary_colour = { 0.75f, 0.23f, 0.39f },
981 .origin = { -5, 8 },
982 .dims = { 5, 1 }
983 }
984 };
985
986 // Setup pointers and that
987 static void career_local_data_init(void)
988 {
989 struct cmp_level *level_ptrs[ NUM_CAMPAIGN_LEVELS ];
990
991 // COllect pointers
992 for( int i = 0; i < vg_list_size( career_packs ); i ++ )
993 {
994 struct career_level_pack *set = &career_packs[i];
995
996 for( int j = 0; j < set->count; j ++ )
997 level_ptrs[ set->pack[j].serial_id ] = &set->pack[j];
998 }
999
1000 // Apply
1001 for( int i = 0; i < vg_list_size( career_packs ); i ++ )
1002 {
1003 struct career_level_pack *set = &career_packs[i];
1004
1005 for( int j = 0; j < set->count; j ++ )
1006 {
1007 struct cmp_level *lvl = &set->pack[j];
1008 lvl->unlock = lvl->_unlock? level_ptrs[ lvl->_unlock ]: NULL;
1009 lvl->linked = lvl->_linked? level_ptrs[ lvl->_linked ]: NULL;
1010 }
1011 }
1012 }