2 // ===========================================================================================================
4 vg_tex2d tex_tile_data
= { .path
= "textures/tileset.qoi" };
5 vg_tex2d tex_tile_detail
= { .path
= "textures/tile_overlays.qoi" };
6 vg_tex2d tex_wood
= { .path
= "textures/wood.qoi" };
7 vg_tex2d tex_background
= { .path
= "textures/background.qoi" };
8 vg_tex2d tex_ball_noise
= { .path
= "textures/bnoise.qoi" };
9 vg_tex2d tex_monofur
= { .path
= "textures/ascii.qoi", .flags
= VG_TEXTURE_NO_MIP
};
11 vg_tex2d
*texture_list
[] = { &tex_tile_detail
, &tex_tile_data
, &tex_wood
, &tex_background
, &tex_ball_noise
, &tex_monofur
};
14 // ===========================================================================================================
16 sfx_vol_control audio_volume_sfx
= { .val
= 1.0f
, .name
= "Sound effects" };
17 sfx_vol_control audio_volume_music
= { .val
= 1.0f
, .name
= "Music" };
19 sfx_system audio_system_sfx
=
23 .vol_src
= &audio_volume_sfx
,
27 sfx_set audio_tile_mod
=
39 sfx_set audio_splitter
=
42 sound/splitter_01.ogg\0"
48 sound/rolling_01.ogg\0\
49 sound/rolling_02.ogg\0"
52 sfx_set audio_random
=
55 sound/random_01.ogg\0\
56 sound/random_02.ogg\0\
57 sound/random_03.ogg\0\
58 sound/random_04.ogg\0\
59 sound/random_05.ogg\0\
60 sound/random_06.ogg\0\
61 sound/random_07.ogg\0\
62 sound/random_08.ogg\0"
65 // One two or three layers of rolling noise
66 sfx_system audio_system_balls_rolling
=
68 .vol
= 1.f
, .ch
= 1, .vol_src
= &audio_volume_sfx
,
69 .name
= "Balls Rolling", .flags
= SFX_FLAG_REPEAT
73 sfx_system audio_system_balls_switching
=
75 .vol
= 1.f
, .ch
= 1, .vol_src
= &audio_volume_sfx
,
76 .name
= "Balls Switching"
79 // Gameplay critical sounds eg. splitter sound rocking
80 sfx_system audio_system_balls_important
=
82 .vol
= 1.f
, .ch
= 1, .vol_src
= &audio_volume_sfx
,
83 .name
= "Balls Gameplay"
87 sfx_system audio_system_balls_extra
=
89 .vol
= 1.f
, .ch
= 1, .vol_src
= &audio_volume_sfx
,
93 static void resource_load_main(void)
96 vg_tex2d_init( texture_list
, vg_list_size( texture_list
) );
98 ui_override_font( tex_monofur
.name
, 7 );
101 sfx_set_init( &audio_tile_mod
, NULL
);
102 sfx_set_init( &audio_splitter
, NULL
);
103 sfx_set_init( &audio_rolls
, NULL
);
104 sfx_set_init( &audio_random
, NULL
);
107 static void resource_free_main(void)
109 vg_tex2d_free( texture_list
, vg_list_size( texture_list
) );
111 sfx_set_free( &audio_tile_mod
);
112 sfx_set_free( &audio_splitter
);
113 sfx_set_free( &audio_rolls
);
114 sfx_set_free( &audio_random
);
118 // ===========================================================================================================
120 SHADER_DEFINE( shader_tile_colour
,
123 "layout (location=0) in vec2 a_co;"
125 "uniform vec3 uOffset;"
129 "gl_Position = vec4( uPv * vec3( a_co * uOffset.z + uOffset.xy, 1.0 ), 1.0 );"
133 "out vec4 FragColor;"
134 "uniform vec4 uColour;"
138 "FragColor = uColour;"
141 UNIFORMS({ "uPv", "uOffset", "uColour" })
144 SHADER_DEFINE( shader_ball
,
146 "layout (location=0) in vec2 a_co;"
147 "uniform vec2 uOffset;"
150 "out vec4 aTexCoords;"
155 "vec3 worldpos = vec3( a_co * 0.5 - 0.25 + uOffset, 1.0 );"
156 "gl_Position = vec4( uPv * worldpos, 1.0 );"
158 // Create texture coords
159 "aTexCoords = vec4( a_co, worldpos.xy );"
163 "out vec4 FragColor;"
165 "uniform sampler2D uTexMain;"
166 "uniform vec3 uColour;"
167 "uniform vec2 uTexOffset;"
169 "in vec4 aTexCoords;"
173 "vec2 center_coords = aTexCoords.xy - 0.5;"
174 "vec2 center_coords_sqr = center_coords*center_coords;"
175 "float circle_factor = smoothstep( 0.07, 0.0625, center_coords_sqr.x+center_coords_sqr.y );"
177 "float bulge_amt = center_coords_sqr.x+center_coords_sqr.y;"
178 "vec2 warped_coords = aTexCoords.zw+uTexOffset - center_coords;"
179 "vec4 noise_sample = texture( uTexMain, warped_coords );"
181 "float rim_light = (center_coords_sqr.x+center_coords_sqr.y)*15.0;"
183 "vec2 shadow_coords = center_coords + vec2(0.02,0.07);"
184 "vec2 shadow_coords_sqr = shadow_coords*shadow_coords;"
185 "float shadow = exp(-((shadow_coords_sqr.x+shadow_coords_sqr.y)-0.0125)*15.0);"
187 "vec3 marble_comp = uColour*0.9 + (noise_sample.x*0.7+pow(rim_light,3.0)*2.0) * 0.1;"
188 "vec4 colour_comp = mix( vec4(0.74,0.53,0.34,shadow), vec4(marble_comp,1.0), circle_factor );"
190 "FragColor = colour_comp;"
193 UNIFORMS({ "uTexMain", "uColour", "uOffset", "uPv", "uTexOffset" })
196 SHADER_DEFINE( shader_tile_main
,
198 "layout (location=0) in vec2 a_co;"
199 "uniform vec4 uOffset;" // Tile x/y, uv x/y
201 "uniform mat2 uSubTransform;"
203 "out vec4 aTexCoords;"
204 "out vec2 aWorldCoords;"
206 "vec2 hash22(vec2 p)"
208 "vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));"
209 "p3 += dot(p3, p3.yzx+33.33);"
210 "return fract((p3.xx+p3.yz)*p3.zy);"
216 "vec2 subtransform = uSubTransform * (a_co-0.5) + 0.5;"
217 "vec3 worldpos = vec3( subtransform + uOffset.xy, 1.0 );"
218 "gl_Position = vec4( uPv * worldpos, 1.0 );"
220 // Create texture coords
221 "vec2 random_offset = floor(hash22(uOffset.xy) * 4.0) * 0.25;"
222 "vec2 edge_safe_coords = a_co * 0.98 + 0.01;"
223 "aTexCoords = vec4((edge_safe_coords + uOffset.zw) * 0.25, edge_safe_coords * 0.25 + random_offset );"
224 "aWorldCoords = worldpos.xy;"
228 "out vec4 FragColor;"
230 "uniform sampler2D uTexGlyphs;"
231 "uniform sampler2D uTexWood;"
232 "uniform float uGhost;"
233 "uniform float uForeground;"
234 "uniform vec2 uMousePos;"
235 "uniform vec4 uColour;"
237 "in vec4 aTexCoords;"
238 "in vec2 aWorldCoords;"
242 "vec3 shadowing_colour = vec3( 0.93, 0.88536, 0.8184 );"
243 "vec4 glyph = texture( uTexGlyphs, aTexCoords.xy );"
244 "vec4 wood = texture( uTexWood, aTexCoords.zw );"
245 "vec4 wood_secondary = texture( uTexWood, aTexCoords.zw + 0.25 );"
246 "vec3 wood_comp = mix( wood_secondary.rgb * shadowing_colour, wood.rgb, clamp( glyph.b * 2.0 - 1.0, 0.0, 1.0 ) );"
248 "vec3 shadows = mix( vec3( 0.85, 0.7344, 0.561 ), vec3(1.0,1.0,1.0), glyph.r );"
250 "vec4 output_regular = vec4( wood_comp * shadows, mix( glyph.a, glyph.b, uForeground ) );"
252 "float ghost_dist = clamp( 1.5 - distance(uMousePos, aWorldCoords), 0.0, 1.0 );"
253 "vec4 output_ghost = vec4( 1.0, 1.0, 1.0, glyph.g * ghost_dist );"
255 "FragColor = mix( output_regular, output_ghost, uGhost ) * uColour;"
258 UNIFORMS({ "uPv", "uOffset", "uTexGlyphs", "uTexWood", "uSubTransform", "uGhost", "uMousePos", "uColour", "uForeground" })
261 SHADER_DEFINE( shader_background
,
263 "layout (location=0) in vec2 a_co;"
265 "uniform vec3 uOffset;"
267 "out vec2 aTexCoords;"
271 "vec2 world_pos = a_co * uOffset.z + uOffset.xy;"
272 "gl_Position = vec4( uPv * vec3( world_pos, 1.0 ), 1.0 );"
277 "out vec4 FragColor;"
279 "uniform sampler2D uTexMain;"
280 "uniform sampler2D uSamplerNoise;"
281 "uniform float uVariance;"
283 "in vec2 aTexCoords;"
287 "float ao_accum = 0.0;"
288 "for( int i=0; i<10; ++i )"
290 "vec2 random_noise = (texture( uSamplerNoise, aTexCoords * 20.0 + float(i) * 0.2 ).xy - vec2( 0.5, 0.5 )) * uVariance;"
291 "vec4 background = texture( uTexMain, aTexCoords + random_noise );"
292 "ao_accum += background.r * clamp((1.0 - length( random_noise )), 0.0, 1.0);"
296 "vec4 data_this_tile = texture( uTexMain, aTexCoords );"
298 "ao_accum -= data_this_tile.r;"
300 "vec3 colour_main = vec3( 0.369768, 0.3654, 0.42 );"
302 "vec2 square_coords = fract( aTexCoords * 64.0 );"
303 "vec2 grid_coords = abs( square_coords - 0.5 );"
304 "float edge_contrast = (1.0-ao_accum*0.2);"
306 "float gridline = step( 0.49, max(grid_coords.x,grid_coords.y) );"
307 "float gridline_fadeout = min(max(edge_contrast-1.0, 0.0)*40.0 + data_this_tile.g,10.0);"
309 "FragColor = vec4( colour_main * edge_contrast + gridline * 0.02 * gridline_fadeout, 1.0 );"
312 UNIFORMS({ "uPv", "uOffset", "uTexMain", "uVariance", "uSamplerNoise" })
315 SHADER_DEFINE( shader_wire
,
317 "layout (location=0) in vec2 a_co;"
318 "uniform vec3 uStart;"
321 "uniform float uCurve;"
323 "out vec2 aTexCoords;"
325 "vec3 sample_curve_time( float t )"
327 "vec3 line_coord = mix( uStart, uEnd, t );"
329 "float curve_amt = 1.0-(pow((t*2.0-1.0),2.0));"
330 "return vec3( line_coord.x, line_coord.y - curve_amt*uCurve, line_coord.z );"
336 "vec3 p0 = sample_curve_time( a_co.x );"
337 "vec3 p1 = sample_curve_time( a_co.x + 0.025 );"
339 "vec2 line_tangent = normalize(p1.xy-p0.xy);"
340 "vec2 line_normal = vec2( -line_tangent.y, line_tangent.x );"
342 "vec2 worldfinal = p0.xy + line_normal*a_co.y*p0.z;"
344 "gl_Position = vec4( uPv * vec3(worldfinal, 1.0), 1.0 );"
346 // Create texture coords (todo: include stretch adjusted coords?)
347 "aTexCoords = vec2( a_co.x, a_co.y + 0.5 );"
351 "out vec4 FragColor;"
353 "uniform sampler2D uTexMain;"
354 "uniform vec4 uColour;"
356 "in vec2 aTexCoords;"
360 "FragColor = uColour;"
363 UNIFORMS({ "uPv", "uColour", "uTexMain", "uStart", "uEnd", "uCurve" })
367 void vg_register(void)
369 SHADER_INIT( shader_tile_colour
);
370 SHADER_INIT( shader_tile_main
);
371 SHADER_INIT( shader_ball
);
372 SHADER_INIT( shader_background
);
373 SHADER_INIT( shader_wire
);
377 0000 0 | 0001 1 | 0010 2 | 0011 3
381 0100 4 | 0101 5 | 0110 6 | 0111 7
385 1000 8 | 1001 9 | 1010 10 | 1011 11
389 1100 12 | 1101 13 | 1110 14 | 1111 15
395 float const MESH_NUMBER_0
[] = {
396 #include "fonts/numbers/n0.h"
399 float const MESH_NUMBER_1
[] = {
400 #include "fonts/numbers/n1.h"
403 float const MESH_NUMBER_2
[] = {
404 #include "fonts/numbers/n2.h"
407 float const MESH_NUMBER_3
[] = {
408 #include "fonts/numbers/n3.h"
411 float const MESH_NUMBER_4
[] = {
412 #include "fonts/numbers/n4.h"
415 float const MESH_NUMBER_5
[] = {
416 #include "fonts/numbers/n5.h"
419 float const MESH_NUMBER_6
[] = {
420 #include "fonts/numbers/n6.h"
423 float const MESH_NUMBER_7
[] = {
424 #include "fonts/numbers/n7.h"
427 float const MESH_NUMBER_8
[] = {
428 #include "fonts/numbers/n8.h"
431 float const MESH_NUMBER_9
[] = {
432 #include "fonts/numbers/n9.h"
435 float const MESH_NUMBERS_BUFFER
[] =
437 #include "fonts/numbers/n0.h"
438 #include "fonts/numbers/n1.h"
439 #include "fonts/numbers/n2.h"
440 #include "fonts/numbers/n3.h"
441 #include "fonts/numbers/n4.h"
442 #include "fonts/numbers/n5.h"
443 #include "fonts/numbers/n6.h"
444 #include "fonts/numbers/n7.h"
445 #include "fonts/numbers/n8.h"
446 #include "fonts/numbers/n9.h"
449 #define MESH_NUMBER_DIVISOR 6
451 u32
const MESH_NUMBERS_OFFSETS
[][2] =
455 vg_list_size( MESH_NUMBER_0
) / MESH_NUMBER_DIVISOR
458 vg_list_size( MESH_NUMBER_0
) / MESH_NUMBER_DIVISOR
,
459 vg_list_size( MESH_NUMBER_1
) / MESH_NUMBER_DIVISOR
463 vg_list_size( MESH_NUMBER_0
) +
464 vg_list_size( MESH_NUMBER_1
)
465 ) / MESH_NUMBER_DIVISOR
,
466 vg_list_size( MESH_NUMBER_2
) / MESH_NUMBER_DIVISOR
470 vg_list_size( MESH_NUMBER_0
) +
471 vg_list_size( MESH_NUMBER_1
) +
472 vg_list_size( MESH_NUMBER_2
)
473 ) / MESH_NUMBER_DIVISOR
,
474 vg_list_size( MESH_NUMBER_3
) / MESH_NUMBER_DIVISOR
478 vg_list_size( MESH_NUMBER_0
) +
479 vg_list_size( MESH_NUMBER_1
) +
480 vg_list_size( MESH_NUMBER_2
) +
481 vg_list_size( MESH_NUMBER_3
)
482 ) / MESH_NUMBER_DIVISOR
,
483 vg_list_size( MESH_NUMBER_4
) / MESH_NUMBER_DIVISOR
487 vg_list_size( MESH_NUMBER_0
) +
488 vg_list_size( MESH_NUMBER_1
) +
489 vg_list_size( MESH_NUMBER_2
) +
490 vg_list_size( MESH_NUMBER_3
) +
491 vg_list_size( MESH_NUMBER_4
)
492 ) / MESH_NUMBER_DIVISOR
,
493 vg_list_size( MESH_NUMBER_5
) / MESH_NUMBER_DIVISOR
497 vg_list_size( MESH_NUMBER_0
) +
498 vg_list_size( MESH_NUMBER_1
) +
499 vg_list_size( MESH_NUMBER_2
) +
500 vg_list_size( MESH_NUMBER_3
) +
501 vg_list_size( MESH_NUMBER_4
) +
502 vg_list_size( MESH_NUMBER_5
)
503 ) / MESH_NUMBER_DIVISOR
,
504 vg_list_size( MESH_NUMBER_6
) / MESH_NUMBER_DIVISOR
508 vg_list_size( MESH_NUMBER_0
) +
509 vg_list_size( MESH_NUMBER_1
) +
510 vg_list_size( MESH_NUMBER_2
) +
511 vg_list_size( MESH_NUMBER_3
) +
512 vg_list_size( MESH_NUMBER_4
) +
513 vg_list_size( MESH_NUMBER_5
) +
514 vg_list_size( MESH_NUMBER_6
)
515 ) / MESH_NUMBER_DIVISOR
,
516 vg_list_size( MESH_NUMBER_7
) / MESH_NUMBER_DIVISOR
520 vg_list_size( MESH_NUMBER_0
) +
521 vg_list_size( MESH_NUMBER_1
) +
522 vg_list_size( MESH_NUMBER_2
) +
523 vg_list_size( MESH_NUMBER_3
) +
524 vg_list_size( MESH_NUMBER_4
) +
525 vg_list_size( MESH_NUMBER_5
) +
526 vg_list_size( MESH_NUMBER_6
) +
527 vg_list_size( MESH_NUMBER_7
)
528 ) / MESH_NUMBER_DIVISOR
,
529 vg_list_size( MESH_NUMBER_8
) / MESH_NUMBER_DIVISOR
533 vg_list_size( MESH_NUMBER_0
) +
534 vg_list_size( MESH_NUMBER_1
) +
535 vg_list_size( MESH_NUMBER_2
) +
536 vg_list_size( MESH_NUMBER_3
) +
537 vg_list_size( MESH_NUMBER_4
) +
538 vg_list_size( MESH_NUMBER_5
) +
539 vg_list_size( MESH_NUMBER_6
) +
540 vg_list_size( MESH_NUMBER_7
) +
541 vg_list_size( MESH_NUMBER_8
)
542 ) / MESH_NUMBER_DIVISOR
,
543 vg_list_size( MESH_NUMBER_9
) / MESH_NUMBER_DIVISOR
549 const char *map_name
;
551 const char *description
;
556 struct cmp_level cmp_levels_tutorials
[] =
559 .title
= "PRINCIPLE 1",
560 .map_name
= "cmp_t01",
561 .description
= "Utilize basic transport methods",
566 .title
= "PRINCIPLE 2",
567 .map_name
= "cmp_t02",
568 .description
= "Utilize the twisty turny(TM) piece",
573 .title
= "PRINCIPLE 3",
574 .map_name
= "cmp_t03",
575 .description
= "Merge transport into one",
580 .title
= "PRINCIPLE 4",
581 .map_name
= "cmp_t04",
582 .description
= "Some stages require multiple runs to succeed in order to pass",
588 struct cmp_level cmp_levels_basic
[] =
591 .title
= "SUBDIVISION 1",
592 .map_name
= "cmp_b01",
593 .description
= "Simple maths, branching required.",
598 .title
= "SUBDIVISION 2",
599 .map_name
= "cmp_b02",
600 .description
= "Simple maths. Futher.",
605 .title
= "RESTRUCTURE",
606 .map_name
= "cmp_b03",
607 .description
= "Not so simple swap",
612 .title
= "SERIALIZE",
613 .map_name
= "cmp_b04",
614 .description
= "Merge and sort",
619 .title
= "PATTERNS 1",
620 .map_name
= "cmp_b05",
621 .description
= "Replicate",
626 .title
= "PATTERNS 2",
627 .map_name
= "cmp_b06",
628 .description
= "Replicate MORE",
633 .title
= "MIGHTY CONSUMER",
634 .map_name
= "cmp_b07",
635 .description
= "Build a greedy system",
640 .title
= "ENCRYPTED 1",
641 .map_name
= "cmp_b08",
642 .description
= "Some configurations may not be valid",
648 .map_name
= "cmp_b09",
649 .description
= "Reverse the incoming order. Always length 4",
654 .title
= "PRINCIPLE 5",
655 .map_name
= "cmp_b10",
657 "The competent engineers among you may have already\n"
658 "spotted and utilized these parts of the system\n"
660 "We forgot to include the relevant principle tasks\n"
661 "as part of your training package, you will now be\n"
662 "tasked to complete them",
667 .title
= "ROUTING PROBLEM",
668 .map_name
= "cmp_routing",
670 "Things can get a little chaotic on tight boards,\n"
671 "Do your best to utilize principle 5 to get the job\n"
677 .title
= "PRINCIPLE 6",
678 .map_name
= "cmp_b11",
680 "While hovering over a simple tile peice, right click\n"
681 "and drag to start creating a wire. These can be\n"
682 "connected to the left, or right recieving pins of a\n"
683 "Twisty Turny(TM) peice.\n"
685 "Once connected, the Twisty Turny(TM) will no longer\n"
686 "'flip flop' as marbles run through them, but instead\n"
687 "be set to left or right rotating only. As indicated\n"
688 "by the status arrow beneath them\n"
690 "When the left or right slot is triggered, the Twisty\n"
691 "Turny(TM) will switch modes according to that input.\n"
693 "Trigger wires apply instantaneously, however if both\n"
694 "the left and right inputs are recieved at the same\n"
695 "time, this results in no operation being performed,\n"
696 "and no state changes take place in the Twisty Turny(TM)\n",
702 .map_name
= "cmp_not",
704 "Test your knowledge of triggers, build an 'NOT GATE'\n"
705 "emulated by marble logic.",
711 .map_name
= "cmp_and",
713 "A slightly more complicated gate, but shouldn't be\n"
714 "too difficult for your skillset.",
719 .title
= "QUALIFICATION PROJECT",
720 .map_name
= "cmp_grad",
722 "There's no instructions here, resolve and complete this\n"
723 "task to qualify yourself as an official marble engineer",
728 struct cmp_level cmp_levels_grad
[] =
732 .map_name
= "cmp_i01",
734 "Device a scheme to filter and sort the inputs. If you\n"
735 "believe you lack the tools required to solve this one,\n"
736 "take a harder look at the inputs.",
742 .map_name
= "cmp_i02",
744 "Spit your inputs up into a third of its value\n"
745 "Is this possible? -HG",
751 .map_name
= "cmp_xor",
753 "Significantly more complicated than an AND or NOT gate,\n"
758 .title
= "SECRET CODE",
759 .map_name
= "cmp_secret",
761 "Only one input should send an unlock signal marble to\n"