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