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