diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 148 |
1 files changed, 53 insertions, 95 deletions
@@ -20,6 +20,7 @@ WITH REGARD TO THIS SOFTWARE. | |||
20 | #include "uxn/uxn.c" | 20 | #include "uxn/uxn.c" |
21 | #include "uxn/devices/ppu.h" | 21 | #include "uxn/devices/ppu.h" |
22 | #include "uxn/devices/ppu.c" | 22 | #include "uxn/devices/ppu.c" |
23 | #include "uxn/devices/apu.c" | ||
23 | 24 | ||
24 | #include "text.h" | 25 | #include "text.h" |
25 | 26 | ||
@@ -56,6 +57,7 @@ static Ppu ppu; | |||
56 | static Device *devscreen; | 57 | static Device *devscreen; |
57 | static Device *devctrl; | 58 | static Device *devctrl; |
58 | static Device *devmouse; | 59 | static Device *devmouse; |
60 | static Device *devaudio; | ||
59 | 61 | ||
60 | static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2}; | 62 | static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2}; |
61 | 63 | ||
@@ -110,6 +112,36 @@ screen_talk(Device *d, u8 b0, u8 w) { | |||
110 | } | 112 | } |
111 | } | 113 | } |
112 | 114 | ||
115 | static void | ||
116 | audio_talk(Device *d, u8 b0, u8 w) { | ||
117 | AudioChannel *c = &apu.chan_0; | ||
118 | if(!w) { | ||
119 | if(b0 == 0x2) { | ||
120 | mempoke16(d->dat, 0x2, c->position); | ||
121 | } else if(b0 == 0x4) { | ||
122 | // d->dat[0x4] = apu_get_vu(c); | ||
123 | } | ||
124 | } else if(b0 == 0xf) { | ||
125 | // SDL_LockAudioDevice(audio_id); | ||
126 | c->n_samples = mempeek16(d->dat, 0xa); | ||
127 | c->samples = &d->mem[mempeek16(d->dat, 0xc)]; | ||
128 | // Transform the samples from u8 to s8. | ||
129 | // for (size_t i = 0; i < c->n_samples; ++i) { | ||
130 | // c->samples[i] = c->samples[i] + 0x80; | ||
131 | // } | ||
132 | // c->volume[0] = d->dat[0xe] >> 4; | ||
133 | // c->volume[1] = d->dat[0xe] & 0xf; | ||
134 | c->loop = !(d->dat[0xf] & 0x80); | ||
135 | c->pitch = d->dat[0xf] & 0x7f; | ||
136 | init_sound(c); | ||
137 | reset_sound(c); | ||
138 | txt_printf("note: %d \n", c->pitch); | ||
139 | // apu_start(c, mempeek16(d->dat, 0x8), d->dat[0xf] & 0x7f); | ||
140 | // SDL_UnlockAudioDevice(audio_id); | ||
141 | } | ||
142 | // txt_printf("AUDIO TALK: %d\n", d); | ||
143 | } | ||
144 | |||
113 | void | 145 | void |
114 | datetime_talk(Device *d, u8 b0, u8 w) { | 146 | datetime_talk(Device *d, u8 b0, u8 w) { |
115 | (void)d; | 147 | (void)d; |
@@ -155,7 +187,7 @@ init_uxn(Uxn *u) { | |||
155 | portuxn(u, 0x0, "system", system_talk); | 187 | portuxn(u, 0x0, "system", system_talk); |
156 | portuxn(u, 0x1, "console", console_talk); | 188 | portuxn(u, 0x1, "console", console_talk); |
157 | devscreen = portuxn(u, 0x2, "screen", screen_talk); | 189 | devscreen = portuxn(u, 0x2, "screen", screen_talk); |
158 | portuxn(u, 0x3, "---", nil_talk); | 190 | devaudio = portuxn(u, 0x3, "audio0", audio_talk); |
159 | portuxn(u, 0x4, "---", nil_talk); | 191 | portuxn(u, 0x4, "---", nil_talk); |
160 | portuxn(u, 0x5, "---", nil_talk); | 192 | portuxn(u, 0x5, "---", nil_talk); |
161 | portuxn(u, 0x6, "---", nil_talk); | 193 | portuxn(u, 0x6, "---", nil_talk); |
@@ -344,75 +376,6 @@ static Uxn u; | |||
344 | EWRAM_BSS | 376 | EWRAM_BSS |
345 | static u8 umem[65536]; | 377 | static u8 umem[65536]; |
346 | 378 | ||
347 | #include "kick.c" | ||
348 | |||
349 | typedef struct AudioChannel { | ||
350 | u32 *samples; | ||
351 | u32 n_samples; | ||
352 | u16 sampling_freq; | ||
353 | bool loop; | ||
354 | // TODO: u16 adsr; // attack, decay, sustain, release | ||
355 | // TODO: u8 pitch; // Bit 8 is the "loop" bit | ||
356 | // TODO: u8 volume; // VOL_LEFT | (VOL_RIGHT << 4) | ||
357 | } AudioChannel; | ||
358 | |||
359 | typedef struct APU { | ||
360 | AudioChannel chan_0; | ||
361 | // u32 *samples_1; | ||
362 | // u32 *samples_2; | ||
363 | // u32 *samples_3; | ||
364 | } APU; | ||
365 | |||
366 | |||
367 | static APU apu = {0}; | ||
368 | |||
369 | void | ||
370 | reset_sound(AudioChannel *chan) { | ||
371 | TIMER_CTRL_0 = 0; | ||
372 | TIMER_CTRL_1 = 0; | ||
373 | DMA_CTRL(1) = 0; | ||
374 | |||
375 | // Set max volume, left-right sound, fifo reset and use timer 0 for | ||
376 | // DirectSound A. | ||
377 | SOUND_DSOUND_MASTER = SOUND_DSOUND_RATIO_A | ||
378 | | SOUND_DSOUND_LEFT_A | ||
379 | | SOUND_DSOUND_RIGHT_A | ||
380 | | SOUND_DSOUND_RESET_A; | ||
381 | |||
382 | // Prepare DMA copy. | ||
383 | dma_transfer_copy(SOUND_FIFO_A, chan->samples, 1, 1, | ||
384 | DMA_CHUNK_32 | DMA_REFRESH | DMA_REPEAT | DMA_ENABLE); | ||
385 | |||
386 | // Timer 1 used to stop playing samples. | ||
387 | u32 sample_duration = chan->n_samples; | ||
388 | TIMER_DATA_1 = 0xFFFF - sample_duration; | ||
389 | TIMER_CTRL_1 = TIMER_CTRL_IRQ | ||
390 | | TIMER_CTRL_ENABLE | ||
391 | | TIMER_CTRL_CASCADE; | ||
392 | |||
393 | // Timer 0 used to stop sample playing. | ||
394 | TIMER_DATA_0 = 0xFFFF - CPU_FREQUENCY / chan->sampling_freq; | ||
395 | TIMER_CTRL_0 = TIMER_CTRL_ENABLE; | ||
396 | } | ||
397 | |||
398 | void | ||
399 | irs_stop_sample(void) { | ||
400 | if (apu.chan_0.loop) { | ||
401 | reset_sound(&apu.chan_0); | ||
402 | } else { | ||
403 | TIMER_CTRL_0 = 0; | ||
404 | DMA_CTRL(1) = 0; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | void | ||
409 | init_sound(AudioChannel *chan) { | ||
410 | chan->samples = voiceraw; | ||
411 | chan->n_samples = LEN(voiceraw); | ||
412 | chan->sampling_freq = 44100; | ||
413 | chan->loop = true; | ||
414 | } | ||
415 | |||
416 | int main(void) { | 379 | int main(void) { |
417 | // Initialize filesystem. | 380 | // Initialize filesystem. |
418 | fs_init(); | 381 | fs_init(); |
@@ -431,39 +394,34 @@ int main(void) { | |||
431 | txt_init(1, TEXT_LAYER); | 394 | txt_init(1, TEXT_LAYER); |
432 | txt_position(0,0); | 395 | txt_position(0,0); |
433 | 396 | ||
434 | txt_printf("VOICE LOADED: %lu\n", LEN(voiceraw)); | 397 | // init_sound(&apu.chan_0); |
435 | 398 | // reset_sound(&apu.chan_0); | |
436 | // Enable sound. | ||
437 | SOUND_STATUS = SOUND_ENABLE; | ||
438 | |||
439 | init_sound(&apu.chan_0); | ||
440 | reset_sound(&apu.chan_0); | ||
441 | 399 | ||
442 | // Main loop. | 400 | // Main loop. |
443 | // int frame_counter = 0; | 401 | int frame_counter = 0; |
444 | // evaluxn(&u, 0x0100); | 402 | evaluxn(&u, 0x0100); |
445 | // u32 flip_cycles = 0; | 403 | u32 flip_cycles = 0; |
446 | while(true) { | 404 | while(true) { |
447 | bios_vblank_wait(); | 405 | bios_vblank_wait(); |
448 | // profile_start(); | 406 | profile_start(); |
449 | // handle_input(&u); | 407 | handle_input(&u); |
450 | // u32 input_cycles = profile_stop(); | 408 | u32 input_cycles = profile_stop(); |
451 | // profile_start(); | 409 | profile_start(); |
452 | // evaluxn(&u, mempeek16(devscreen->dat, 0)); | 410 | evaluxn(&u, mempeek16(devscreen->dat, 0)); |
453 | // u32 eval_cycles = profile_stop(); | 411 | u32 eval_cycles = profile_stop(); |
454 | // txt_position(0, 8); | 412 | txt_position(0, 8); |
455 | // txt_printf("INPUT: %lu \n", input_cycles); | 413 | // txt_printf("INPUT: %lu \n", input_cycles); |
456 | // txt_printf("EVAL: %lu \n", eval_cycles); | 414 | // txt_printf("EVAL: %lu \n", eval_cycles); |
457 | // txt_printf("FLIP: %lu \n", flip_cycles); | 415 | // txt_printf("FLIP: %lu \n", flip_cycles); |
458 | // profile_start(); | 416 | profile_start(); |
459 | flipbuf(&ppu); | 417 | flipbuf(&ppu); |
460 | // flip_cycles = profile_stop(); | 418 | flip_cycles = profile_stop(); |
461 | // frame_counter++; | 419 | frame_counter++; |
462 | poll_keys(); | 420 | // if (frame_counter == 120) { |
463 | if (key_tap(KEY_B)) { | 421 | // init_sound(&apu.chan_0); |
464 | txt_printf("TAP B\n"); | 422 | // reset_sound(&apu.chan_0); |
465 | reset_sound(&apu.chan_0); | 423 | // frame_counter = 0; |
466 | } | 424 | // } |
467 | } | 425 | } |
468 | 426 | ||
469 | return 0; | 427 | return 0; |