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