void GBAudioWriteNR14(struct GBAudio* audio, uint8_t value) { audio->ch1.control.frequency &= 0xFF; audio->ch1.control.frequency |= GBAudioRegisterControlGetFrequency(value << 8); bool wasStop = audio->ch1.control.stop; audio->ch1.control.stop = GBAudioRegisterControlGetStop(value << 8); if (!wasStop && audio->ch1.control.stop && audio->ch1.control.length && !(audio->frame & 1)) { --audio->ch1.control.length; if (audio->ch1.control.length == 0) { audio->playingCh1 = false; } } if (GBAudioRegisterControlIsRestart(value << 8)) { if (audio->nextEvent == INT_MAX) { audio->eventDiff = 0; } if (audio->playingCh1) { audio->ch1.control.hi = !audio->ch1.control.hi; } audio->nextCh1 = audio->eventDiff; audio->playingCh1 = audio->ch1.envelope.initialVolume || audio->ch1.envelope.direction; audio->ch1.envelope.currentVolume = audio->ch1.envelope.initialVolume; if (audio->ch1.envelope.currentVolume > 0) { audio->ch1.envelope.dead = audio->ch1.envelope.stepTime ? 0 : 1; } else { audio->ch1.envelope.dead = audio->ch1.envelope.stepTime ? 0 : 2; } audio->ch1.realFrequency = audio->ch1.control.frequency; audio->ch1.sweepStep = audio->ch1.time; audio->ch1.sweepEnable = (audio->ch1.sweepStep != 8) || audio->ch1.shift; audio->ch1.sweepOccurred = false; if (audio->playingCh1 && audio->ch1.shift) { audio->playingCh1 = _updateSweep(&audio->ch1, true); } if (!audio->ch1.control.length) { audio->ch1.control.length = 64; if (audio->ch1.control.stop && !(audio->frame & 1)) { --audio->ch1.control.length; } } _scheduleEvent(audio); } *audio->nr52 &= ~0x0001; *audio->nr52 |= audio->playingCh1; }
void GBAudioWriteNR24(struct GBAudio* audio, uint8_t value) { audio->ch2.control.frequency &= 0xFF; audio->ch2.control.frequency |= GBAudioRegisterControlGetFrequency(value << 8); bool wasStop = audio->ch2.control.stop; audio->ch2.control.stop = GBAudioRegisterControlGetStop(value << 8); if (!wasStop && audio->ch2.control.stop && audio->ch2.control.length && !(audio->frame & 1)) { --audio->ch2.control.length; if (audio->ch2.control.length == 0) { audio->playingCh2 = false; } } if (GBAudioRegisterControlIsRestart(value << 8)) { audio->playingCh2 = audio->ch2.envelope.initialVolume || audio->ch2.envelope.direction; audio->ch2.envelope.currentVolume = audio->ch2.envelope.initialVolume; if (audio->ch2.envelope.currentVolume > 0) { audio->ch2.envelope.dead = audio->ch2.envelope.stepTime ? 0 : 1; } else { audio->ch2.envelope.dead = audio->ch2.envelope.stepTime ? 0 : 2; } if (audio->nextEvent == INT_MAX) { audio->eventDiff = 0; } if (audio->playingCh2) { audio->ch2.control.hi = !audio->ch2.control.hi; } audio->nextCh2 = audio->eventDiff; if (!audio->ch2.control.length) { audio->ch2.control.length = 64; if (audio->ch2.control.stop && !(audio->frame & 1)) { --audio->ch2.control.length; } } _scheduleEvent(audio); } *audio->nr52 &= ~0x0002; *audio->nr52 |= audio->playingCh2 << 1; }
/************************************************** * OFFイベントのスケジュールを登録する **************************************************/ void LightScheduler_scheduleTurnOff(int id, DAY day, int minuite_of_day) { _scheduleEvent(id, day, minuite_of_day, TURN_OFF); }