first sorta working port
[fishladder.git] / fishladder_resources_vg1.h
1 #include "shaders/tile_colour.h"
2 #include "shaders/tile_main.h"
3 #include "shaders/ball.h"
4 #include "shaders/background.h"
5 #include "shaders/wire.h"
6 #include "shaders/button.h"
7 #include "shaders/sprite.h"
8 #include "shaders/post_darken.h"
9 #include "shaders/post_comp.h"
10 #include "shaders/post_blur.h"
11
12 /* FIXME */
13 #define UI_GLYPH_SPACING_X 8
14
15 void _mc_vg1_register(void){
16 shader_tile_colour_register();
17 shader_tile_main_register();
18 shader_ball_register();
19 shader_background_register();
20 shader_wire_register();
21 shader_button_register();
22 shader_sprite_register();
23 shader_post_darken_register();
24 shader_post_comp_register();
25 shader_post_blur_register();
26 }
27
28 // TEXTURES
29 // ===========================================================================================================
30
31 typedef struct vg1_tex2d vg1_tex2d;
32 struct vg1_tex2d {
33 const char *path;
34 GLuint name;
35 };
36
37 vg1_tex2d tex_tile_data = { "textures/tileset.qoi" };
38 vg1_tex2d tex_tile_glow = { "textures/lineset.qoi" };
39 vg1_tex2d tex_tile_detail = { "textures/tile_overlays.qoi" };
40 vg1_tex2d tex_tiles_wood = { "textures/tile_wood.qoi" };
41 vg1_tex2d tex_tiles_min = { "textures/tile_minimal.qoi" };
42 vg1_tex2d tex_tiles_lab = { "textures/tile_lab.qoi" };
43 vg1_tex2d tex_ball_noise = { "textures/bnoise.qoi" };
44 vg1_tex2d tex_unkown = { "textures/unkown.qoi" };
45 vg1_tex2d tex_buttons = { "textures/buttons.qoi" };
46 vg1_tex2d tex_sprites = { "textures/autocombine.qoi" };
47
48 vg1_tex2d *texture_list[] = {
49 &tex_tile_detail,
50 &tex_tile_data,
51 &tex_tile_glow,
52 &tex_tiles_wood,
53 &tex_tiles_min,
54 &tex_tiles_lab,
55 &tex_ball_noise,
56 &tex_unkown,
57 &tex_buttons,
58 &tex_sprites
59 };
60
61 #include "sprites_autocombine.h"
62
63 // AUDIO
64 // ===========================================================================================================
65
66 #if 0
67 sfx_vol_control audio_volume_sfx = { .val = 1.0f, .name = "Sound effects" };
68 sfx_vol_control audio_volume_music = { .val = 1.0f, .name = "Music" };
69
70 sfx_system audio_system_sfx =
71 {
72 .vol = 1.f,
73 .ch = 1,
74 .vol_src = &audio_volume_sfx,
75 .name = "sfx"
76 };
77 #endif
78
79 audio_clip audio_tile_mod[] = {
80 { .path="sound/mod_01.ogg" },
81 { .path="sound/mod_02.ogg" },
82 { .path="sound/mod_03.ogg" },
83 { .path="sound/mod_04.ogg" },
84 { .path="sound/mod_05.ogg" },
85 { .path="sound/mod_06.ogg" },
86 };
87
88 audio_clip audio_splitter[] = {
89 { .path="sound/splitter_01.ogg" },
90 };
91
92 audio_clip audio_rolls[] = {
93 { .path="sound/rolling_01.ogg" },
94 { .path="sound/rolling_02.ogg" }
95 };
96
97 audio_clip audio_random[] ={
98 { .path="sound/random_01.ogg" },
99 { .path="sound/random_02.ogg" },
100 { .path="sound/random_03.ogg" },
101 { .path="sound/random_04.ogg" },
102 { .path="sound/random_05.ogg" },
103 { .path="sound/random_06.ogg" },
104 { .path="sound/random_07.ogg" },
105 { .path="sound/random_08.ogg" },
106 };
107
108 audio_clip audio_clicks[] = {
109 { .path="sound/click_a.ogg" },
110 { .path="sound/click_b.ogg" },
111 { .path="sound/click_c.ogg" },
112 };
113
114 audio_clip audio_tones[] = {
115 { .path="sound/y0.ogg" },
116 { .path="sound/y1.ogg" },
117 { .path="sound/y2.ogg" },
118 { .path="sound/y3.ogg" },
119 { .path="sound/y4.ogg" },
120 { .path="sound/y5.ogg" },
121 { .path="sound/y6.ogg" },
122 { .path="sound/y7.ogg" },
123 { .path="sound/y8.ogg" },
124 { .path="sound/win.ogg" },
125 };
126
127 audio_clip audio_music[] = {
128 { .path="sound/mccompt2.ogg" },
129 };
130
131 #if 0
132 static void *load_and_play_bgm( void *_inf )
133 {
134 sfx_set_init( &audio_music, NULL );
135 sfx_set_play( &audio_music, &audio_system_music, 0 );
136 return NULL;
137 }
138 #endif
139
140 #define INIT_AUDIO( X ) audio_clip_loadn( X, vg_list_size(X), NULL );
141
142 static void _mc_resource_load_main(void){
143 // Textures // UI
144 for( u32 i=0; i<vg_list_size(texture_list); i ++ ){
145 struct vg1_tex2d *tex = texture_list[i];
146 vg_tex2d_load_qoi_async_file( tex->path, 0, &tex->name );
147 }
148
149 // Audio
150 INIT_AUDIO( audio_tile_mod );
151 INIT_AUDIO( audio_tile_mod );
152 INIT_AUDIO( audio_splitter );
153 INIT_AUDIO( audio_rolls );
154 INIT_AUDIO( audio_random );
155 INIT_AUDIO( audio_clicks );
156 INIT_AUDIO( audio_tones );
157
158 #if 0
159 vg_thread_run( load_and_play_bgm, NULL );
160 #endif
161 }
162
163 /*
164 0000 0 | 0001 1 | 0010 2 | 0011 3
165 | | | | |
166 X | X= | X | X=
167 | | |
168 0100 4 | 0101 5 | 0110 6 | 0111 7
169 | | | | |
170 =X | =X= | =X | =X=
171 | | |
172 1000 8 | 1001 9 | 1010 10 | 1011 11
173 | | | | |
174 X | X= | X | X=
175 | | | | | | |
176 1100 12 | 1101 13 | 1110 14 | 1111 15
177 | | | | |
178 =X | =X= | =X | =X=
179 | | | | | | |
180 */
181
182 struct cmp_level
183 {
184 // Basic info
185 int serial_id;
186
187 const char *map_name;
188 const char *title;
189 const char *description;
190
191 const char *achievement;
192
193 int _unlock, _linked; // When completed, unlock this level
194 int is_tutorial;
195
196 // Aesthetic
197 struct world_string
198 {
199 enum placement
200 {
201 k_placement_top,
202 k_placement_bottom
203 }
204 placement;
205
206 const char *str;
207 }
208 strings[2];
209
210 // Persistent stats
211 int unlocked;
212 int completed_score;
213
214 // Runtime
215 struct world_button btn;
216 struct cmp_level *unlock, *linked;
217
218 #ifdef VG_STEAM
219 SteamLeaderboard_t steam_leaderboard;
220 #endif
221 };
222
223 static struct cmp_level cmp_levels_tutorials[] =
224 {
225 {
226 0, "cmp_t01", "PRINCIPLE 1", "",
227 ._unlock = 1,
228 .is_tutorial = 1
229 },
230 {
231 1, "cmp_t02", "PRINCIPLE 2", "",
232 ._unlock = 2,
233 .is_tutorial = 1,
234 },
235 {
236 2, "cmp_t03", "PRINCIPLE 3", "",
237 ._unlock = 12,
238 .is_tutorial = 1
239 },
240 {
241 12, "cmp_t04", "PRINCIPLE 4", "",
242 ._unlock = 6,
243 .is_tutorial = 1,
244 .achievement = "TUTORIALS"
245 },
246 {
247 15, "cmp_b10", "PRINCIPLE 5", "",
248 ._unlock = 16,
249 .is_tutorial = 1
250 },
251 {
252 17, "cmp_b11", "PRINCIPLE 6", "(Right click)",
253 ._unlock = 18,
254 .is_tutorial = 1
255 },
256 {
257 26, "cmp_p7", "PRINCIPLE 7", "Emitters",
258 ._unlock = 27,
259 ._linked = 13,
260 .is_tutorial = 1
261 }
262 };
263
264 static struct cmp_level cmp_levels_basic[] =
265 {
266 {
267 6, "cmp_b04", "PATCH", "",
268 ._unlock = 7,
269 ._linked = 3
270 },
271 {
272 3, "cmp_b01", "SUBDIVISION 1", "",
273 ._linked = 4,
274 ._unlock = 5
275 },
276 {
277 4, "cmp_b02", "SUBDIVISION 2", "",
278 ._unlock = 7
279 },
280 {
281 5, "cmp_b03", "RESTRUCTURE", "",
282 ._unlock = 8,
283 ._linked = 31
284 },
285 {
286 31, "cmp_121", "1-2-1", "",
287 ._unlock = 8
288 },
289 {
290 7, "cmp_b05", "PATTERNS 1", "",
291 ._unlock = 15,
292 ._linked = 8
293 },
294 {
295 8, "cmp_b06", "PATTERNS 2", "",
296 ._unlock = 15
297 },
298 {
299 16, "cmp_routing", "ROUTING PROBLEM", "",
300 ._linked = 9
301 },
302 {
303 9, "cmp_b07", "MIGHTY CONSUMER", "",
304 ._linked = 10,
305 ._unlock = 11,
306 .achievement = "MIGHTY_CONSUMER"
307 },
308 {
309 10, "cmp_b08", "SHIFT", "",
310 ._unlock = 17
311 },
312 {
313 11, "cmp_b09", "REVERSE", "",
314 ._unlock = 17
315 },
316 {
317 18, "cmp_not", "NOT GATE", "",
318 ._linked = 19,
319 ._unlock = 20
320 },
321 {
322 19, "cmp_and", "AND GATE", "",
323 ._unlock = 20
324 },
325 {
326 20, "cmp_xor", "QUALIFICATION PROJECT", "",
327 ._unlock = 26,
328 .achievement = "GRADUATE"
329 },
330 {
331 27, "cmp_expander", "EXPAND", "",
332 ._unlock = 28
333 },
334 {
335 28, "cmp_pattern3", "PATTERNS 3", "",
336 ._linked = 29
337 },
338 {
339 29, "cmp_routing2", "ROUTING PROBLEM 2", "Spaghetti!",
340 ._linked = 30,
341 ._unlock = 32
342 },
343 {
344 30, "cmp_exact5", "EXACTLY 5", "",
345 ._unlock = 32
346 },
347 {
348 32, "cmp_3and2", "THREE AND FOUR", "",
349 ._linked = 34
350 },
351 {
352 34, "doublex2", "DOUBLE DOUBLE", "Delay & repeat",
353 ._linked = 35
354 },
355 {
356 35, "oddoreven", "ODD OR EVEN", ""
357 }
358 };
359
360 static struct cmp_level cmp_levels_grad[] =
361 {
362 {
363 13, "cmp_i01", "SORT", "",
364 ._linked = 14
365 },
366 {
367 14, "cmp_i02", "THIRDS", "",
368 ._linked = 21
369 },
370 {
371 21, "cmp_grad", "SIMPLE ADDITION", "",
372 ._linked = 22,
373 ._unlock = 23
374 },
375 {
376 22, "cmp_secret", "SECRET CODE", "",
377 ._unlock = 23
378 }
379 };
380
381 static struct cmp_level cmp_levels_computer[] =
382 {
383 {
384 23, "cmp_binary", "3 BIT BINARY", "Convert amount to binary",
385 ._unlock = 24,
386 .strings =
387 {
388 {
389 .placement = k_placement_bottom,
390 .str =
391 "\t\t\t\t\t\t\t\t\t\t\x83 \x84\n"
392 "\t\t\t\t\t\t\t\t\t\t\x83 \x84 Binary\n"
393 "\t\t\t\t\t\t\t\t\t\t\x83 4 2 1 \x84"
394 },
395 {
396 .placement = k_placement_top,
397 .str =
398 "\n"
399 "\t\t\t\t\t\t\t\t\t\t\t Count"
400 }
401 }
402 },
403 {
404 24, "cmp_add3b", "3 BIT ADDER", "Binary addition",
405 ._unlock = 25,
406 .strings =
407 {
408 {
409 .placement = k_placement_top,
410 //.str ="\t\t\t\t\t\t\t\t\t| NUMBER A | | NUMBER B |\n"
411 .str =""
412 "\t\t\t\t\t\t\t\t\t\x8A 4 2 1 \x8B \x8A 4 2 1 \x8B\n"
413 "\t\t\t\t\t\t\t\t\t\x83 \x84 add \x83 \x84\n"
414 "\t\t\t\t\t\t\t\t\t\x83 \x84 \x83 \x84"
415 },
416 {
417 .placement = k_placement_bottom,
418 .str =
419 "\t\t\t\x83 \x84\n"
420 "\t\t\t\x83 \x84 result a+b\n"
421 "\t\t\t\x83 8 4 2 1 \x84"
422 }
423 }
424 },
425 {
426 25, "cmp_plot3x3", "3x3 PLOT", "2 bit x/y",
427 ._unlock = 33,
428 .strings =
429 {
430 {
431 .placement = k_placement_top,
432 .str=
433 "\t\t\t\t\t\t\t\t\x8A 2 1 \x8B \x8A 2 1 \x8B\n"
434 "\t\t\t\t\t\t\t\t\x83 \x84 X Y \x83 \x84\n"
435 "\t\t\t\t\t\t\t\t\x83 \x84 \x83 \x84"
436 }
437 }
438 },
439 {
440 33, "compactxor", "Compact XOR", "",
441 .strings =
442 {
443 {
444 .placement = k_placement_top,
445 .str=
446 "\t\t\t\t\x8A \x8B \x8A \x8B\n"
447 "\t\t\t\t\x83 \x84""A B\x83 \x84\n"
448 "\t\t\t\t\x83 \x84 \x83 \x84"
449 },
450 {
451 .placement = k_placement_bottom,
452 .str =
453 "\t\t\t\x83 \x84\n"
454 "\t\t\t\x83 \x84 result a xor b\n"
455 "\t\t\t\x83 \x84"
456 }
457 }
458 }
459 };
460
461 #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 ) )
462
463 static struct career_level_pack
464 {
465 struct cmp_level *pack;
466 const char *title;
467 int count;
468
469 v3f primary_colour;
470 v2i origin;
471 v2i dims;
472 }
473 career_packs[] =
474 {
475 {
476 .pack = cmp_levels_tutorials,
477 .title = "",
478 .count = vg_list_size( cmp_levels_tutorials ),
479 .primary_colour = { 0.204f, 0.345f, 0.553f },
480 .origin = { -4, -2 },
481 .dims = { 1, 7 }
482 },
483 {
484 .pack = cmp_levels_basic,
485 .title = "\x8C\x8D"" Core",
486 .count = vg_list_size( cmp_levels_basic ),
487 .primary_colour = { 0.304f, 0.245f, 0.553f },
488 .origin = { -3, -2 },
489 .dims = { 3, 7 }
490 },
491 {
492 .pack = cmp_levels_grad,
493 .title = "\x8C\x8E"" Challenge",
494 .count = vg_list_size( cmp_levels_grad ),
495 .primary_colour = { 0.75f, 0.23f, 0.39f },
496 .origin = { -4, 5 },
497 .dims = { 4, 1 }
498 },
499 {
500 .pack = cmp_levels_computer,
501 .title = "\x8C\x8F"" 3 Bit computer\n\n (preview)",
502 .count = vg_list_size( cmp_levels_computer ),
503 .primary_colour = { 0.75f, 0.14f, 0.1f },
504 .origin = { -4, 6 },
505 .dims = { 4, 1 }
506 }
507 };
508
509 // Setup pointers and that
510 static void career_local_data_init(void)
511 {
512 struct cmp_level *level_ptrs[ NUM_CAMPAIGN_LEVELS ];
513 for( int i = 0; i < NUM_CAMPAIGN_LEVELS; i ++ )
514 level_ptrs[i] = NULL;
515
516 // COllect pointers
517 for( int i = 0; i < vg_list_size( career_packs ); i ++ )
518 {
519 struct career_level_pack *set = &career_packs[i];
520
521 for( int j = 0; j < set->count; j ++ )
522 {
523 int id = set->pack[j].serial_id;
524
525 if( level_ptrs[ id ] )
526 vg_error( "Serial id %u already used!\n", id );
527 else
528 level_ptrs[ set->pack[j].serial_id ] = &set->pack[j];
529 }
530 }
531
532 // Apply
533 for( int i = 0; i < vg_list_size( career_packs ); i ++ )
534 {
535 struct career_level_pack *set = &career_packs[i];
536
537 for( int j = 0; j < set->count; j ++ )
538 {
539 struct cmp_level *lvl = &set->pack[j];
540
541 if( lvl->_unlock >= NUM_CAMPAIGN_LEVELS ||
542 lvl->_linked >= NUM_CAMPAIGN_LEVELS )
543 {
544 vg_error( "_unlock / _linked out of range (%d, %d)\n",
545 lvl->_unlock, lvl->_linked );
546 }
547 else
548 {
549 lvl->unlock = lvl->_unlock? level_ptrs[ lvl->_unlock ]: NULL;
550 lvl->linked = lvl->_linked? level_ptrs[ lvl->_linked ]: NULL;
551 }
552 }
553 }
554 }