aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c148
1 files changed, 53 insertions, 95 deletions
diff --git a/src/main.c b/src/main.c
index 0862ca5..fc7dad1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
56static Device *devscreen; 57static Device *devscreen;
57static Device *devctrl; 58static Device *devctrl;
58static Device *devmouse; 59static Device *devmouse;
60static Device *devaudio;
59 61
60static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2}; 62static 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
115static void
116audio_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
113void 145void
114datetime_talk(Device *d, u8 b0, u8 w) { 146datetime_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;
344EWRAM_BSS 376EWRAM_BSS
345static u8 umem[65536]; 377static u8 umem[65536];
346 378
347#include "kick.c"
348
349typedef 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
359typedef struct APU {
360 AudioChannel chan_0;
361 // u32 *samples_1;
362 // u32 *samples_2;
363 // u32 *samples_3;
364} APU;
365
366
367static APU apu = {0};
368
369void
370reset_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
398void
399irs_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
408void
409init_sound(AudioChannel *chan) {
410 chan->samples = voiceraw;
411 chan->n_samples = LEN(voiceraw);
412 chan->sampling_freq = 44100;
413 chan->loop = true;
414}
415
416int main(void) { 379int 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;