leaderboard have picture
[fishladder.git] / fishladder_resources.h
1 // TEXTURES
2 // ===========================================================================================================
3
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 };
10 vg_tex2d tex_unkown = { .path = "textures/unkown.qoi" };
11
12 vg_tex2d *texture_list[] = { &tex_tile_detail, &tex_tile_data, &tex_wood, &tex_background, &tex_ball_noise, &tex_monofur, &tex_unkown };
13
14 // AUDIO
15 // ===========================================================================================================
16
17 sfx_vol_control audio_volume_sfx = { .val = 1.0f, .name = "Sound effects" };
18 sfx_vol_control audio_volume_music = { .val = 1.0f, .name = "Music" };
19
20 sfx_system audio_system_sfx =
21 {
22 .vol = 1.f,
23 .ch = 1,
24 .vol_src = &audio_volume_sfx,
25 .name = "sfx"
26 };
27
28 sfx_set audio_tile_mod =
29 {
30 .sources = "\
31 sound/mod_01.ogg\0\
32 sound/mod_02.ogg\0\
33 sound/mod_03.ogg\0\
34 sound/mod_04.ogg\0\
35 sound/mod_05.ogg\0\
36 sound/mod_06.ogg\0",
37 .flags = 0
38 };
39
40 sfx_set audio_splitter =
41 {
42 .sources = "\
43 sound/splitter_01.ogg\0"
44 };
45
46 sfx_set audio_rolls =
47 {
48 .sources = "\
49 sound/rolling_01.ogg\0\
50 sound/rolling_02.ogg\0"
51 };
52
53 sfx_set audio_random =
54 {
55 .sources = "\
56 sound/random_01.ogg\0\
57 sound/random_02.ogg\0\
58 sound/random_03.ogg\0\
59 sound/random_04.ogg\0\
60 sound/random_05.ogg\0\
61 sound/random_06.ogg\0\
62 sound/random_07.ogg\0\
63 sound/random_08.ogg\0"
64 };
65
66 // One two or three layers of rolling noise
67 sfx_system audio_system_balls_rolling =
68 {
69 .vol = 1.f, .ch = 1, .vol_src = &audio_volume_sfx,
70 .name = "Balls Rolling", .flags = SFX_FLAG_REPEAT
71 };
72
73 // Various oneshots
74 sfx_system audio_system_balls_switching =
75 {
76 .vol = 1.f, .ch = 1, .vol_src = &audio_volume_sfx,
77 .name = "Balls Switching"
78 };
79
80 // Gameplay critical sounds eg. splitter sound rocking
81 sfx_system audio_system_balls_important =
82 {
83 .vol = 1.f, .ch = 1, .vol_src = &audio_volume_sfx,
84 .name = "Balls Gameplay"
85 };
86
87 // Suplemental sounds
88 sfx_system audio_system_balls_extra =
89 {
90 .vol = 1.f, .ch = 1, .vol_src = &audio_volume_sfx,
91 .name = "Balls Extra"
92 };
93
94 ui_colourset ui_fl_colours = {
95 .main = 0xff807373,
96 .hover = 0xff918484,
97 .active = 0xffad9f9e
98 };
99
100 ui_colourset ui_fl_colours_inactive = {
101 .main = 0xff655958,
102 .hover = 0xff655958,
103 .active = 0xff655958
104 };
105
106 static void resource_load_main(void)
107 {
108 // Textures
109 vg_tex2d_init( texture_list, vg_list_size( texture_list ) );
110
111 ui_override_font( tex_monofur.name, 7 );
112
113 ui_global_ctx.colours_main = &ui_fl_colours;
114 gui_reset_colours();
115
116 // Audio
117 sfx_set_init( &audio_tile_mod, NULL );
118 sfx_set_init( &audio_splitter, NULL );
119 sfx_set_init( &audio_rolls, NULL );
120 sfx_set_init( &audio_random, NULL );
121 }
122
123 static void resource_free_main(void)
124 {
125 vg_tex2d_free( texture_list, vg_list_size( texture_list ) );
126
127 sfx_set_free( &audio_tile_mod );
128 sfx_set_free( &audio_splitter );
129 sfx_set_free( &audio_rolls );
130 sfx_set_free( &audio_random );
131 }
132
133 // SHADERS
134 // ===========================================================================================================
135
136 SHADER_DEFINE( shader_tile_colour,
137
138 // VERTEX
139 "layout (location=0) in vec2 a_co;"
140 "uniform mat3 uPv;"
141 "uniform vec3 uOffset;"
142 ""
143 "void main()"
144 "{"
145 "gl_Position = vec4( uPv * vec3( a_co * uOffset.z + uOffset.xy, 1.0 ), 1.0 );"
146 "}",
147
148 // FRAGMENT
149 "out vec4 FragColor;"
150 "uniform vec4 uColour;"
151 ""
152 "void main()"
153 "{"
154 "FragColor = uColour;"
155 "}"
156 ,
157 UNIFORMS({ "uPv", "uOffset", "uColour" })
158 )
159
160 SHADER_DEFINE( shader_ball,
161 // VERTEX
162 "layout (location=0) in vec2 a_co;"
163 "uniform vec2 uOffset;"
164 "uniform mat3 uPv;"
165 ""
166 "out vec4 aTexCoords;"
167 ""
168 "void main()"
169 "{"
170 // Vertex transform
171 "vec3 worldpos = vec3( a_co * 0.5 - 0.25 + uOffset, 1.0 );"
172 "gl_Position = vec4( uPv * worldpos, 1.0 );"
173
174 // Create texture coords
175 "aTexCoords = vec4( a_co, worldpos.xy );"
176 "}",
177
178 // FRAGMENT
179 "out vec4 FragColor;"
180 ""
181 "uniform sampler2D uTexMain;"
182 "uniform vec3 uColour;"
183 "uniform vec2 uTexOffset;"
184 ""
185 "in vec4 aTexCoords;"
186 ""
187 "void main()"
188 "{"
189 "vec2 center_coords = aTexCoords.xy - 0.5;"
190 "vec2 center_coords_sqr = center_coords*center_coords;"
191 "float circle_factor = smoothstep( 0.07, 0.0625, center_coords_sqr.x+center_coords_sqr.y );"
192
193 "float bulge_amt = center_coords_sqr.x+center_coords_sqr.y;"
194 "vec2 warped_coords = aTexCoords.zw+uTexOffset - center_coords;"
195 "vec4 noise_sample = texture( uTexMain, warped_coords );"
196
197 "float rim_light = (center_coords_sqr.x+center_coords_sqr.y)*15.0;"
198
199 "vec2 shadow_coords = center_coords + vec2(0.02,0.07);"
200 "vec2 shadow_coords_sqr = shadow_coords*shadow_coords;"
201 "float shadow = exp(-((shadow_coords_sqr.x+shadow_coords_sqr.y)-0.0125)*15.0);"
202
203 "vec3 marble_comp = uColour*0.9 + (noise_sample.x*0.7+pow(rim_light,3.0)*2.0) * 0.1;"
204 "vec4 colour_comp = mix( vec4(0.74,0.53,0.34,shadow), vec4(marble_comp,1.0), circle_factor );"
205
206 "FragColor = colour_comp;"
207 "}"
208 ,
209 UNIFORMS({ "uTexMain", "uColour", "uOffset", "uPv", "uTexOffset" })
210 )
211
212 SHADER_DEFINE( shader_tile_main,
213 // VERTEX
214 "layout (location=0) in vec2 a_co;"
215 "uniform vec4 uOffset;" // Tile x/y, uv x/y
216 "uniform mat3 uPv;"
217 "uniform mat2 uSubTransform;"
218 ""
219 "out vec4 aTexCoords;"
220 "out vec2 aWorldCoords;"
221 ""
222 "vec2 hash22(vec2 p)"
223 "{"
224 "vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));"
225 "p3 += dot(p3, p3.yzx+33.33);"
226 "return fract((p3.xx+p3.yz)*p3.zy);"
227 "}"
228 ""
229 "void main()"
230 "{"
231 // Vertex transform
232 "vec2 subtransform = uSubTransform * (a_co-0.5) + 0.5;"
233 "vec3 worldpos = vec3( subtransform + uOffset.xy, 1.0 );"
234 "gl_Position = vec4( uPv * worldpos, 1.0 );"
235
236 // Create texture coords
237 "vec2 random_offset = floor(hash22(uOffset.xy) * 4.0) * 0.25;"
238 "vec2 edge_safe_coords = a_co * 0.98 + 0.01;"
239 "aTexCoords = vec4((edge_safe_coords + uOffset.zw) * 0.25, edge_safe_coords * 0.25 + random_offset );"
240 "aWorldCoords = worldpos.xy;"
241 "}",
242
243 // FRAGMENT
244 "out vec4 FragColor;"
245 ""
246 "uniform sampler2D uTexGlyphs;"
247 "uniform sampler2D uTexWood;"
248 "uniform float uGhost;"
249 "uniform float uForeground;"
250 "uniform vec2 uMousePos;"
251 "uniform vec4 uColour;"
252 ""
253 "in vec4 aTexCoords;"
254 "in vec2 aWorldCoords;"
255 ""
256 "void main()"
257 "{"
258 "vec3 shadowing_colour = vec3( 0.93, 0.88536, 0.8184 );"
259 "vec4 glyph = texture( uTexGlyphs, aTexCoords.xy );"
260 "vec4 wood = texture( uTexWood, aTexCoords.zw );"
261 "vec4 wood_secondary = texture( uTexWood, aTexCoords.zw + 0.25 );"
262 "vec3 wood_comp = mix( wood_secondary.rgb * shadowing_colour, wood.rgb, clamp( glyph.b * 2.0 - 1.0, 0.0, 1.0 ) );"
263
264 "vec3 shadows = mix( vec3( 0.85, 0.7344, 0.561 ), vec3(1.0,1.0,1.0), glyph.r );"
265
266 "vec4 output_regular = vec4( wood_comp * shadows, mix( glyph.a, glyph.b, uForeground ) );"
267
268 "float ghost_dist = clamp( 1.5 - distance(uMousePos, aWorldCoords), 0.0, 1.0 );"
269 "vec4 output_ghost = vec4( 1.0, 1.0, 1.0, glyph.g * ghost_dist );"
270
271 "FragColor = mix( output_regular, output_ghost, uGhost ) * uColour;"
272 "}"
273 ,
274 UNIFORMS({ "uPv", "uOffset", "uTexGlyphs", "uTexWood", "uSubTransform", "uGhost", "uMousePos", "uColour", "uForeground" })
275 )
276
277 SHADER_DEFINE( shader_background,
278 // VERTEX
279 "layout (location=0) in vec2 a_co;"
280 "uniform mat3 uPv;"
281 "uniform vec3 uOffset;"
282 ""
283 "out vec2 aTexCoords;"
284 ""
285 "void main()"
286 "{"
287 "vec2 world_pos = a_co * uOffset.z + uOffset.xy;"
288 "gl_Position = vec4( uPv * vec3( world_pos, 1.0 ), 1.0 );"
289 "aTexCoords = a_co;"
290 "}",
291
292 // FRAGMENT
293 "out vec4 FragColor;"
294 ""
295 "uniform sampler2D uTexMain;"
296 "uniform sampler2D uSamplerNoise;"
297 "uniform float uVariance;"
298 ""
299 "in vec2 aTexCoords;"
300 ""
301 "void main()"
302 "{"
303 "float ao_accum = 0.0;"
304 "for( int i=0; i<10; ++i )"
305 "{"
306 "vec2 random_noise = (texture( uSamplerNoise, aTexCoords * 20.0 + float(i) * 0.2 ).xy - vec2( 0.5, 0.5 )) * uVariance;"
307 "vec4 background = texture( uTexMain, aTexCoords + random_noise );"
308 "ao_accum += background.r * clamp((1.0 - length( random_noise )), 0.0, 1.0);"
309 "}"
310 "ao_accum *= 0.15;"
311
312 "vec4 data_this_tile = texture( uTexMain, aTexCoords );"
313
314 "ao_accum -= data_this_tile.r;"
315
316 "vec3 colour_main = vec3( 0.369768, 0.3654, 0.42 );"
317
318 "vec2 square_coords = fract( aTexCoords * 64.0 );"
319 "vec2 grid_coords = abs( square_coords - 0.5 );"
320 "float edge_contrast = (1.0-ao_accum*0.2);"
321
322 "float gridline = step( 0.49, max(grid_coords.x,grid_coords.y) );"
323 "float gridline_fadeout = min(max(edge_contrast-1.0, 0.0)*40.0 + data_this_tile.g,10.0);"
324
325 "FragColor = vec4( colour_main * edge_contrast + gridline * 0.02 * gridline_fadeout, 1.0 );"
326 "}"
327 ,
328 UNIFORMS({ "uPv", "uOffset", "uTexMain", "uVariance", "uSamplerNoise" })
329 )
330
331 SHADER_DEFINE( shader_wire,
332 // VERTEX
333 "layout (location=0) in vec2 a_co;"
334 "uniform vec3 uStart;"
335 "uniform vec3 uEnd;"
336 "uniform mat3 uPv;"
337 "uniform float uCurve;"
338 ""
339 "out vec2 aTexCoords;"
340 ""
341 "vec3 sample_curve_time( float t )"
342 "{"
343 "vec3 line_coord = mix( uStart, uEnd, t );"
344
345 "float curve_amt = 1.0-(pow((t*2.0-1.0),2.0));"
346 "return vec3( line_coord.x, line_coord.y - curve_amt*uCurve, line_coord.z );"
347 "}"
348 ""
349 "void main()"
350 "{"
351 // Vertex transform
352 "vec3 p0 = sample_curve_time( a_co.x );"
353 "vec3 p1 = sample_curve_time( a_co.x + 0.025 );"
354
355 "vec2 line_tangent = normalize(p1.xy-p0.xy);"
356 "vec2 line_normal = vec2( -line_tangent.y, line_tangent.x );"
357
358 "vec2 worldfinal = p0.xy + line_normal*a_co.y*p0.z;"
359
360 "gl_Position = vec4( uPv * vec3(worldfinal, 1.0), 1.0 );"
361
362 // Create texture coords (todo: include stretch adjusted coords?)
363 "aTexCoords = vec2( a_co.x, a_co.y + 0.5 );"
364 "}",
365
366 // FRAGMENT
367 "out vec4 FragColor;"
368 ""
369 "uniform sampler2D uTexMain;"
370 "uniform vec4 uColour;"
371 ""
372 "in vec2 aTexCoords;"
373 ""
374 "void main()"
375 "{"
376 "FragColor = uColour;"
377 "}"
378 ,
379 UNIFORMS({ "uPv", "uColour", "uTexMain", "uStart", "uEnd", "uCurve" })
380 )
381
382
383 void vg_register(void)
384 {
385 SHADER_INIT( shader_tile_colour );
386 SHADER_INIT( shader_tile_main );
387 SHADER_INIT( shader_ball );
388 SHADER_INIT( shader_background );
389 SHADER_INIT( shader_wire );
390 }
391
392 /*
393 0000 0 | 0001 1 | 0010 2 | 0011 3
394 | | | | |
395 X | X= | X | X=
396 | | |
397 0100 4 | 0101 5 | 0110 6 | 0111 7
398 | | | | |
399 =X | =X= | =X | =X=
400 | | |
401 1000 8 | 1001 9 | 1010 10 | 1011 11
402 | | | | |
403 X | X= | X | X=
404 | | | | | | |
405 1100 12 | 1101 13 | 1110 14 | 1111 15
406 | | | | |
407 =X | =X= | =X | =X=
408 | | | | | | |
409 */
410
411 float const MESH_NUMBER_0[] = {
412 #include "fonts/numbers/n0.h"
413 };
414
415 float const MESH_NUMBER_1[] = {
416 #include "fonts/numbers/n1.h"
417 };
418
419 float const MESH_NUMBER_2[] = {
420 #include "fonts/numbers/n2.h"
421 };
422
423 float const MESH_NUMBER_3[] = {
424 #include "fonts/numbers/n3.h"
425 };
426
427 float const MESH_NUMBER_4[] = {
428 #include "fonts/numbers/n4.h"
429 };
430
431 float const MESH_NUMBER_5[] = {
432 #include "fonts/numbers/n5.h"
433 };
434
435 float const MESH_NUMBER_6[] = {
436 #include "fonts/numbers/n6.h"
437 };
438
439 float const MESH_NUMBER_7[] = {
440 #include "fonts/numbers/n7.h"
441 };
442
443 float const MESH_NUMBER_8[] = {
444 #include "fonts/numbers/n8.h"
445 };
446
447 float const MESH_NUMBER_9[] = {
448 #include "fonts/numbers/n9.h"
449 };
450
451 float const MESH_NUMBERS_BUFFER[] =
452 {
453 #include "fonts/numbers/n0.h"
454 #include "fonts/numbers/n1.h"
455 #include "fonts/numbers/n2.h"
456 #include "fonts/numbers/n3.h"
457 #include "fonts/numbers/n4.h"
458 #include "fonts/numbers/n5.h"
459 #include "fonts/numbers/n6.h"
460 #include "fonts/numbers/n7.h"
461 #include "fonts/numbers/n8.h"
462 #include "fonts/numbers/n9.h"
463 };
464
465 #define MESH_NUMBER_DIVISOR 6
466
467 u32 const MESH_NUMBERS_OFFSETS[][2] =
468 {
469 {
470 0,
471 vg_list_size( MESH_NUMBER_0 ) / MESH_NUMBER_DIVISOR
472 },
473 {
474 vg_list_size( MESH_NUMBER_0 ) / MESH_NUMBER_DIVISOR,
475 vg_list_size( MESH_NUMBER_1 ) / MESH_NUMBER_DIVISOR
476 },
477 {
478 (
479 vg_list_size( MESH_NUMBER_0 ) +
480 vg_list_size( MESH_NUMBER_1 )
481 ) / MESH_NUMBER_DIVISOR,
482 vg_list_size( MESH_NUMBER_2 ) / MESH_NUMBER_DIVISOR
483 },
484 {
485 (
486 vg_list_size( MESH_NUMBER_0 ) +
487 vg_list_size( MESH_NUMBER_1 ) +
488 vg_list_size( MESH_NUMBER_2 )
489 ) / MESH_NUMBER_DIVISOR,
490 vg_list_size( MESH_NUMBER_3 ) / MESH_NUMBER_DIVISOR
491 },
492 {
493 (
494 vg_list_size( MESH_NUMBER_0 ) +
495 vg_list_size( MESH_NUMBER_1 ) +
496 vg_list_size( MESH_NUMBER_2 ) +
497 vg_list_size( MESH_NUMBER_3 )
498 ) / MESH_NUMBER_DIVISOR,
499 vg_list_size( MESH_NUMBER_4 ) / MESH_NUMBER_DIVISOR
500 },
501 {
502 (
503 vg_list_size( MESH_NUMBER_0 ) +
504 vg_list_size( MESH_NUMBER_1 ) +
505 vg_list_size( MESH_NUMBER_2 ) +
506 vg_list_size( MESH_NUMBER_3 ) +
507 vg_list_size( MESH_NUMBER_4 )
508 ) / MESH_NUMBER_DIVISOR,
509 vg_list_size( MESH_NUMBER_5 ) / MESH_NUMBER_DIVISOR
510 },
511 {
512 (
513 vg_list_size( MESH_NUMBER_0 ) +
514 vg_list_size( MESH_NUMBER_1 ) +
515 vg_list_size( MESH_NUMBER_2 ) +
516 vg_list_size( MESH_NUMBER_3 ) +
517 vg_list_size( MESH_NUMBER_4 ) +
518 vg_list_size( MESH_NUMBER_5 )
519 ) / MESH_NUMBER_DIVISOR,
520 vg_list_size( MESH_NUMBER_6 ) / MESH_NUMBER_DIVISOR
521 },
522 {
523 (
524 vg_list_size( MESH_NUMBER_0 ) +
525 vg_list_size( MESH_NUMBER_1 ) +
526 vg_list_size( MESH_NUMBER_2 ) +
527 vg_list_size( MESH_NUMBER_3 ) +
528 vg_list_size( MESH_NUMBER_4 ) +
529 vg_list_size( MESH_NUMBER_5 ) +
530 vg_list_size( MESH_NUMBER_6 )
531 ) / MESH_NUMBER_DIVISOR,
532 vg_list_size( MESH_NUMBER_7 ) / MESH_NUMBER_DIVISOR
533 },
534 {
535 (
536 vg_list_size( MESH_NUMBER_0 ) +
537 vg_list_size( MESH_NUMBER_1 ) +
538 vg_list_size( MESH_NUMBER_2 ) +
539 vg_list_size( MESH_NUMBER_3 ) +
540 vg_list_size( MESH_NUMBER_4 ) +
541 vg_list_size( MESH_NUMBER_5 ) +
542 vg_list_size( MESH_NUMBER_6 ) +
543 vg_list_size( MESH_NUMBER_7 )
544 ) / MESH_NUMBER_DIVISOR,
545 vg_list_size( MESH_NUMBER_8 ) / MESH_NUMBER_DIVISOR
546 },
547 {
548 (
549 vg_list_size( MESH_NUMBER_0 ) +
550 vg_list_size( MESH_NUMBER_1 ) +
551 vg_list_size( MESH_NUMBER_2 ) +
552 vg_list_size( MESH_NUMBER_3 ) +
553 vg_list_size( MESH_NUMBER_4 ) +
554 vg_list_size( MESH_NUMBER_5 ) +
555 vg_list_size( MESH_NUMBER_6 ) +
556 vg_list_size( MESH_NUMBER_7 ) +
557 vg_list_size( MESH_NUMBER_8 )
558 ) / MESH_NUMBER_DIVISOR,
559 vg_list_size( MESH_NUMBER_9 ) / MESH_NUMBER_DIVISOR
560 }
561 };
562
563 struct cmp_level
564 {
565 const char *map_name;
566 const char *title;
567 const char *description;
568
569 int completed_score;
570
571 int unlocks; // When completed, unlock this many levels
572 int linked_unlocks; // When unlocked, unlock this many levels additionally
573
574 int serial_id;
575
576 SteamLeaderboard_t steam_leaderboard;
577 };
578
579 struct cmp_level cmp_levels_tutorials[] =
580 {
581 {
582 .title = "PRINCIPLE 1",
583 .map_name = "cmp_t01",
584 .description = "Utilize basic transport methods",
585
586 .serial_id = 0,
587 .unlocks = 1
588 },
589 {
590 .title = "PRINCIPLE 2",
591 .map_name = "cmp_t02",
592 .description = "Utilize the twisty turny(TM) piece",
593
594 .serial_id = 1,
595 .unlocks = 1
596 },
597 {
598 .title = "PRINCIPLE 3",
599 .map_name = "cmp_t03",
600 .description = "Merge transport into one",
601
602 .serial_id = 2,
603 .unlocks = 1,
604 },
605 {
606 .title = "PRINCIPLE 4",
607 .map_name = "cmp_t04",
608 .description = "Some stages require multiple runs to succeed in order to pass",
609
610 .serial_id = 12,
611 .unlocks = 3
612 }
613 };
614
615 struct cmp_level cmp_levels_basic[] =
616 {
617 {
618 .title = "SUBDIVISION 1",
619 .map_name = "cmp_b01",
620 .description = "Simple maths, branching required.",
621
622 .serial_id = 3,
623 .unlocks = 1
624 },
625 {
626 .title = "SUBDIVISION 2",
627 .map_name = "cmp_b02",
628 .description = "Simple maths. Futher.",
629
630 .serial_id = 4,
631 .unlocks = 1
632 },
633 {
634 .title = "RESTRUCTURE",
635 .map_name = "cmp_b03",
636 .description = "Not so simple swap",
637
638 .serial_id = 5,
639 .unlocks = 1
640 },
641 {
642 .title = "SERIALIZE",
643 .map_name = "cmp_b04",
644 .description = "Merge and sort",
645
646 .serial_id = 6,
647 .unlocks = 1
648 },
649 {
650 .title = "PATTERNS 1",
651 .map_name = "cmp_b05",
652 .description = "Replicate",
653
654 .serial_id = 7,
655 .unlocks = 1
656 },
657 {
658 .title = "PATTERNS 2",
659 .map_name = "cmp_b06",
660 .description = "Replicate MORE",
661
662 .serial_id = 8,
663 .unlocks = 1
664 },
665 {
666 .title = "MIGHTY CONSUMER",
667 .map_name = "cmp_b07",
668 .description = "Build a greedy system",
669
670 .serial_id = 9,
671 .unlocks = 1
672 },
673 {
674 .title = "ENCRYPTED 1",
675 .map_name = "cmp_b08",
676 .description = "Some configurations may not be valid",
677
678 .serial_id = 10,
679 .unlocks = 1
680 },
681 {
682 .title = "REVERSE",
683 .map_name = "cmp_b09",
684 .description = "Reverse the incoming order. Always length 4",
685
686 .serial_id = 11,
687 .unlocks = 1
688 },
689 {
690 .title = "PRINCIPLE 5",
691 .map_name = "cmp_b10",
692 .description =
693 "The competent engineers among you may have already\n"
694 "spotted and utilized these parts of the system\n"
695 "\n"
696 "We forgot to include the relevant principle tasks as\n"
697 "of your training package, you will now be tasked to\n"
698 "complete them",
699
700 .serial_id = 15,
701 .linked_unlocks = 1
702 },
703 {
704 .title = "ROUTING PROBLEM",
705 .map_name = "cmp_routing",
706 .description =
707 "Things can get a little chaotic on tight boards, do your\n"
708 "best to utilize principle 5 to get the job done\n",
709
710 .serial_id = 16,
711 .unlocks = 1
712 },
713 {
714 .title = "PRINCIPLE 6",
715 .map_name = "cmp_b11",
716 .description =
717 "While hovering over a simple tile peice, right click and\n"
718 "drag to start creating a wire. These can be connected to\n"
719 "the left, or right recieving pins of a Twisty Turny(TM).\n"
720 "\n"
721 "Once connected, the Twisty Turny(TM) will no longer\n"
722 "'flip flop' as marbles run through them, but instead be\n"
723 "et to left or right rotating only. As indicated by the\n"
724 "status arrow beneath them\n"
725 "\n"
726 "When the left or right slot is triggered, the Twisty\n"
727 "Turny(TM) will switch modes according to that input.\n"
728 "\n"
729 "Trigger wires apply instantaneously, however if both the\n"
730 "left and right inputs are recieved at the same time,\n"
731 "this results in no operation being performed, and no\n"
732 "state changes take place in the Twisty Turny(TM)\n",
733
734 .serial_id = 17,
735 .linked_unlocks = 1
736 },
737 {
738 .title = "NOT GATE",
739 .map_name = "cmp_not",
740 .description =
741 "Test your knowledge of triggers, build an 'NOT GATE'\n"
742 "emulated by marble logic.",
743
744 .serial_id = 18,
745 .unlocks = 1
746 },
747 {
748 .title = "AND GATE",
749 .map_name = "cmp_and",
750 .description =
751 "A slightly more complicated gate, but shouldn't be\n"
752 "too difficult for your skillset.",
753
754 .serial_id = 19,
755 .unlocks = 1
756 },
757 {
758 .title = "QUALIFICATION PROJECT",
759 .map_name = "cmp_grad",
760 .description =
761 "There's no instructions here, resolve and complete this\n"
762 "task to qualify yourself as an official marble engineer",
763 .serial_id = 20,
764 .unlocks = 3
765 }
766 };
767
768 struct cmp_level cmp_levels_grad[] =
769 {
770 {
771 .title = "SORT",
772 .map_name = "cmp_i01",
773 .description =
774 "Device a scheme to filter and sort the inputs. If you\n"
775 "believe you lack the tools required to solve this one,\n"
776 "take a harder look at the inputs.",
777
778 .serial_id = 13
779 },
780 {
781 .title = "THIRDS",
782 .map_name = "cmp_i02",
783 .description =
784 "Split the inputs up into a third of their values\n"
785 "\n"
786 "Is this possible? -HG",
787
788 .serial_id = 14
789 },
790 {
791 .title = "XOR CHIP",
792 .map_name = "cmp_xor",
793 .description =
794 "Significantly more complicated than an AND or NOT gate,\n"
795 "but possible.",
796 .serial_id = 21
797 },
798 {
799 .title = "SECRET CODE",
800 .map_name = "cmp_secret",
801 .description =
802 "Only one input should send an unlock signal marble to\n"
803 "the output.\n"
804 "The code: 100110",
805 .serial_id = 22
806 }
807 };
808
809 struct
810 {
811 int total_unlocked;
812 }
813 career_local =
814 {
815 .total_unlocked = 1
816 };