diff --git a/doc/3-pattern/effects.md b/doc/3-pattern/effects.md index c76826c02..152ff23df 100644 --- a/doc/3-pattern/effects.md +++ b/doc/3-pattern/effects.md @@ -93,7 +93,9 @@ not all chips support these effects. - this effect is currently incomplete. - `F5xx`: **Disable macro.** - `F6xx`: **Enable macro.** +- `F7xx`: **Retrigger macro.** - see macro table at the end of this document for possible values. + - `F7xx` resets LFO macro phase to the phase that is set in instrument macro settings. additionally, [each chip has its own effects](../7-systems/README.md). diff --git a/src/engine/cmdStream.cpp b/src/engine/cmdStream.cpp index 841524f46..6036364c5 100644 --- a/src/engine/cmdStream.cpp +++ b/src/engine/cmdStream.cpp @@ -233,6 +233,7 @@ bool DivCSPlayer::tick() { case DIV_CMD_AMIGA_PM: case DIV_CMD_MACRO_OFF: case DIV_CMD_MACRO_ON: + case DIV_CMD_MACRO_RESTART: arg0=(unsigned char)stream.readC(); break; case DIV_CMD_FM_TL: diff --git a/src/engine/cmdStreamOps.cpp b/src/engine/cmdStreamOps.cpp index 4ba6cd893..1d8b24fb8 100644 --- a/src/engine/cmdStreamOps.cpp +++ b/src/engine/cmdStreamOps.cpp @@ -153,6 +153,7 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) { case DIV_CMD_AMIGA_PM: case DIV_CMD_MACRO_OFF: case DIV_CMD_MACRO_ON: + case DIV_CMD_MACRO_RESTART: case DIV_CMD_HINT_ARP_TIME: w->writeC(1); // length w->writeC(c.value); diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 4f9812caa..c459cc3b0 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -248,6 +248,8 @@ enum DivDispatchCmds { DIV_CMD_ESFM_MODIN, // (op, value) DIV_CMD_ESFM_ENV_DELAY, // (op, value) + DIV_CMD_MACRO_RESTART, // (which) + DIV_CMD_MAX }; diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 809dc87b4..971559719 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -129,6 +129,8 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul return "F5xx: Disable macro (see manual)"; case 0xf6: return "F6xx: Enable macro (see manual)"; + case 0xf7: + return "F7xx: Restart macro (see manual)"; case 0xf8: return "F8xx: Single tick volume slide up"; case 0xf9: diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 0599d3966..621eab424 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -245,6 +245,81 @@ void DivMacroInt::mask(unsigned char id, bool enabled) { #undef CONSIDER_OP #undef CONSIDER +#define CONSIDER(x,y,z) \ + case z: \ + macroState=&x; \ + macro=&ins->std.y; \ + break; + +#define CONSIDER_OP(oi,o) \ + CONSIDER(op[oi].am,opMacros[oi].amMacro,0+o) \ + CONSIDER(op[oi].ar,opMacros[oi].arMacro,1+o) \ + CONSIDER(op[oi].dr,opMacros[oi].drMacro,2+o) \ + CONSIDER(op[oi].mult,opMacros[oi].multMacro,3+o) \ + CONSIDER(op[oi].rr,opMacros[oi].rrMacro,4+o) \ + CONSIDER(op[oi].sl,opMacros[oi].slMacro,5+o) \ + CONSIDER(op[oi].tl,opMacros[oi].tlMacro,6+o) \ + CONSIDER(op[oi].dt2,opMacros[oi].dt2Macro,7+o) \ + CONSIDER(op[oi].rs,opMacros[oi].rsMacro,8+o) \ + CONSIDER(op[oi].dt,opMacros[oi].dtMacro,9+o) \ + CONSIDER(op[oi].d2r,opMacros[oi].d2rMacro,10+o) \ + CONSIDER(op[oi].ssg,opMacros[oi].ssgMacro,11+o) \ + CONSIDER(op[oi].dam,opMacros[oi].damMacro,12+o) \ + CONSIDER(op[oi].dvb,opMacros[oi].dvbMacro,13+o) \ + CONSIDER(op[oi].egt,opMacros[oi].egtMacro,14+o) \ + CONSIDER(op[oi].ksl,opMacros[oi].kslMacro,15+o) \ + CONSIDER(op[oi].sus,opMacros[oi].susMacro,16+o) \ + CONSIDER(op[oi].vib,opMacros[oi].vibMacro,17+o) \ + CONSIDER(op[oi].ws,opMacros[oi].wsMacro,18+o) \ + CONSIDER(op[oi].ksr,opMacros[oi].ksrMacro,19+o) + +void DivMacroInt::restart(unsigned char id) { + DivMacroStruct* macroState=NULL; + DivInstrumentMacro* macro=NULL; + + if (e==NULL) return; + if (ins==NULL) return; + + switch (id) { + CONSIDER(vol,volMacro,0) + CONSIDER(arp,arpMacro,1) + CONSIDER(duty,dutyMacro,2) + CONSIDER(wave,waveMacro,3) + CONSIDER(pitch,pitchMacro,4) + CONSIDER(ex1,ex1Macro,5) + CONSIDER(ex2,ex2Macro,6) + CONSIDER(ex3,ex3Macro,7) + CONSIDER(alg,algMacro,8) + CONSIDER(fb,fbMacro,9) + CONSIDER(fms,fmsMacro,10) + CONSIDER(ams,amsMacro,11) + CONSIDER(panL,panLMacro,12) + CONSIDER(panR,panRMacro,13) + CONSIDER(phaseReset,phaseResetMacro,14) + CONSIDER(ex4,ex4Macro,15) + CONSIDER(ex5,ex5Macro,16) + CONSIDER(ex6,ex6Macro,17) + CONSIDER(ex7,ex7Macro,18) + CONSIDER(ex8,ex8Macro,19) + + CONSIDER_OP(0,0x20) + CONSIDER_OP(2,0x40) + CONSIDER_OP(1,0x60) + CONSIDER_OP(3,0x80) + } + + if (macroState==NULL || macro==NULL) return; + + if (macro->len<=0) return; + if (macroState->masked) return; + + macroState->init(); + macroState->prepare(*macro,e); +} + +#undef CONSIDER_OP +#undef CONSIDER + void DivMacroInt::release() { released=true; } diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index 4c100562c..611349966 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -119,6 +119,11 @@ class DivMacroInt { */ void release(); + /** + * restart macro. + */ + void restart(unsigned char id); + /** * trigger next macro tick. */ diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index 107c1493a..95c9d49d5 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -721,6 +721,9 @@ int DivPlatformAmiga::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index b760d8e6a..2b6663c32 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -783,6 +783,9 @@ int DivPlatformArcade::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 823b0b3a1..df75c4af8 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -651,6 +651,9 @@ int DivPlatformAY8910::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 15; break; diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 4fc32ac5c..1a6072717 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -653,6 +653,9 @@ int DivPlatformAY8930::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 31; break; diff --git a/src/engine/platform/bubsyswsg.cpp b/src/engine/platform/bubsyswsg.cpp index 452fb8f89..095876688 100644 --- a/src/engine/platform/bubsyswsg.cpp +++ b/src/engine/platform/bubsyswsg.cpp @@ -246,6 +246,9 @@ int DivPlatformBubSysWSG::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/c140.cpp b/src/engine/platform/c140.cpp index 46f793a9a..14d203587 100644 --- a/src/engine/platform/c140.cpp +++ b/src/engine/platform/c140.cpp @@ -441,6 +441,9 @@ int DivPlatformC140::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 4c3245b82..9130cdccf 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -536,6 +536,9 @@ int DivPlatformC64::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index 0121d19d5..6c6e1732f 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -1022,6 +1022,9 @@ int DivPlatformES5506::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/esfm.cpp b/src/engine/platform/esfm.cpp index 1981b855d..090254a00 100644 --- a/src/engine/platform/esfm.cpp +++ b/src/engine/platform/esfm.cpp @@ -920,6 +920,9 @@ int DivPlatformESFM::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 63; break; diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index 1afcd0df0..6d6a3c768 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -387,6 +387,9 @@ int DivPlatformFDS::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/ga20.cpp b/src/engine/platform/ga20.cpp index a2ff81eb3..df8677584 100644 --- a/src/engine/platform/ga20.cpp +++ b/src/engine/platform/ga20.cpp @@ -311,6 +311,9 @@ int DivPlatformGA20::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index 4f9c85960..3ae02dcf9 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -553,6 +553,9 @@ int DivPlatformGB::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 9a2b514d0..57bb640e6 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -1183,6 +1183,9 @@ int DivPlatformGenesis::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/k007232.cpp b/src/engine/platform/k007232.cpp index ba742a2dc..eb2157e05 100644 --- a/src/engine/platform/k007232.cpp +++ b/src/engine/platform/k007232.cpp @@ -395,6 +395,9 @@ int DivPlatformK007232::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 2af1d5bd3..b084f3a23 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -345,6 +345,9 @@ int DivPlatformK053260::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index 909e4b20c..68f3ac762 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -353,6 +353,9 @@ int DivPlatformLynx::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/mmc5.cpp b/src/engine/platform/mmc5.cpp index 656288c6a..899bf7d8a 100644 --- a/src/engine/platform/mmc5.cpp +++ b/src/engine/platform/mmc5.cpp @@ -327,6 +327,9 @@ int DivPlatformMMC5::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/msm5232.cpp b/src/engine/platform/msm5232.cpp index ef4e14afc..875b5a8ef 100644 --- a/src/engine/platform/msm5232.cpp +++ b/src/engine/platform/msm5232.cpp @@ -297,6 +297,9 @@ int DivPlatformMSM5232::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/msm6258.cpp b/src/engine/platform/msm6258.cpp index 1b7b2434b..b2dd96a4c 100644 --- a/src/engine/platform/msm6258.cpp +++ b/src/engine/platform/msm6258.cpp @@ -268,6 +268,9 @@ int DivPlatformMSM6258::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 8; break; diff --git a/src/engine/platform/msm6295.cpp b/src/engine/platform/msm6295.cpp index 8ca92d9fb..6b00ba1d8 100644 --- a/src/engine/platform/msm6295.cpp +++ b/src/engine/platform/msm6295.cpp @@ -226,6 +226,9 @@ int DivPlatformMSM6295::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 8; break; diff --git a/src/engine/platform/n163.cpp b/src/engine/platform/n163.cpp index c1320ef1a..5e2ccd9c0 100644 --- a/src/engine/platform/n163.cpp +++ b/src/engine/platform/n163.cpp @@ -452,6 +452,9 @@ int DivPlatformN163::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/namcowsg.cpp b/src/engine/platform/namcowsg.cpp index 7c56b1c5e..f6d358a57 100644 --- a/src/engine/platform/namcowsg.cpp +++ b/src/engine/platform/namcowsg.cpp @@ -445,6 +445,9 @@ int DivPlatformNamcoWSG::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 1b15c5da5..6abdf1dc9 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -659,6 +659,9 @@ int DivPlatformNES::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 088c72f38..fbad13218 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -1970,6 +1970,9 @@ int DivPlatformOPL::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: if (c.chan==adpcmChan) return 255; if (pretendYMU) return 127; diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index 1c0831c35..262f55d78 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -853,6 +853,9 @@ int DivPlatformOPLL::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 15; break; diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index f28fb5a8d..d8be4dd21 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -474,6 +474,9 @@ int DivPlatformPCE::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/pcmdac.cpp b/src/engine/platform/pcmdac.cpp index 7d242f556..eebcd3860 100644 --- a/src/engine/platform/pcmdac.cpp +++ b/src/engine/platform/pcmdac.cpp @@ -452,6 +452,9 @@ int DivPlatformPCMDAC::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/pcspkr.cpp b/src/engine/platform/pcspkr.cpp index ee0051cbd..d1500dd55 100644 --- a/src/engine/platform/pcspkr.cpp +++ b/src/engine/platform/pcspkr.cpp @@ -476,6 +476,9 @@ int DivPlatformPCSpeaker::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/pet.cpp b/src/engine/platform/pet.cpp index 17e044d03..aa730fbbf 100644 --- a/src/engine/platform/pet.cpp +++ b/src/engine/platform/pet.cpp @@ -239,6 +239,9 @@ int DivPlatformPET::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/pokemini.cpp b/src/engine/platform/pokemini.cpp index b589adbbd..d2e6d4e49 100644 --- a/src/engine/platform/pokemini.cpp +++ b/src/engine/platform/pokemini.cpp @@ -253,6 +253,9 @@ int DivPlatformPokeMini::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/pokey.cpp b/src/engine/platform/pokey.cpp index ecab418f9..de39cd77a 100644 --- a/src/engine/platform/pokey.cpp +++ b/src/engine/platform/pokey.cpp @@ -374,6 +374,9 @@ int DivPlatformPOKEY::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/pong.cpp b/src/engine/platform/pong.cpp index f2cfb3e1c..9f8781f45 100644 --- a/src/engine/platform/pong.cpp +++ b/src/engine/platform/pong.cpp @@ -180,6 +180,9 @@ int DivPlatformPong::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/pv1000.cpp b/src/engine/platform/pv1000.cpp index abfe9f990..17ad84e72 100644 --- a/src/engine/platform/pv1000.cpp +++ b/src/engine/platform/pv1000.cpp @@ -188,6 +188,9 @@ int DivPlatformPV1000::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index f8ae9d3c4..4709fb668 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -587,6 +587,9 @@ int DivPlatformQSound::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/rf5c68.cpp b/src/engine/platform/rf5c68.cpp index ce2723e34..06f9ab53e 100644 --- a/src/engine/platform/rf5c68.cpp +++ b/src/engine/platform/rf5c68.cpp @@ -291,6 +291,9 @@ int DivPlatformRF5C68::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index 93a40579e..e58cbe578 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -316,6 +316,9 @@ int DivPlatformSAA1099::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 15; break; diff --git a/src/engine/platform/scc.cpp b/src/engine/platform/scc.cpp index f0075822e..eca067ae4 100644 --- a/src/engine/platform/scc.cpp +++ b/src/engine/platform/scc.cpp @@ -261,6 +261,9 @@ int DivPlatformSCC::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index c2dc6f3d5..5c5170186 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -339,6 +339,9 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/sm8521.cpp b/src/engine/platform/sm8521.cpp index 55430c552..ada99de24 100644 --- a/src/engine/platform/sm8521.cpp +++ b/src/engine/platform/sm8521.cpp @@ -277,6 +277,9 @@ int DivPlatformSM8521::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 83351e855..27693e7cb 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -420,6 +420,9 @@ int DivPlatformSMS::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index 0b7860b66..8cc205a16 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -587,6 +587,9 @@ int DivPlatformSNES::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 891bab206..5ac95d3cd 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -502,6 +502,9 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index 0f7b6911f..484151595 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -446,6 +446,9 @@ int DivPlatformSwan::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/t6w28.cpp b/src/engine/platform/t6w28.cpp index 138d395be..b93780ba2 100644 --- a/src/engine/platform/t6w28.cpp +++ b/src/engine/platform/t6w28.cpp @@ -271,6 +271,9 @@ int DivPlatformT6W28::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/ted.cpp b/src/engine/platform/ted.cpp index 5078a9a37..a30c0fd79 100644 --- a/src/engine/platform/ted.cpp +++ b/src/engine/platform/ted.cpp @@ -236,6 +236,9 @@ int DivPlatformTED::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index d49d00af6..ea0b7e6e1 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -258,6 +258,9 @@ int DivPlatformTIA::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 15; break; diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index 7d68342be..3fee5e04e 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -880,6 +880,9 @@ int DivPlatformTX81Z::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/vb.cpp b/src/engine/platform/vb.cpp index c0e5b49af..2ee8f8af5 100644 --- a/src/engine/platform/vb.cpp +++ b/src/engine/platform/vb.cpp @@ -395,6 +395,9 @@ int DivPlatformVB::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/vera.cpp b/src/engine/platform/vera.cpp index 48b800672..7c48dc108 100644 --- a/src/engine/platform/vera.cpp +++ b/src/engine/platform/vera.cpp @@ -434,6 +434,9 @@ int DivPlatformVERA::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_EXTERNAL: rWriteZSMSync(c.value); break; diff --git a/src/engine/platform/vic20.cpp b/src/engine/platform/vic20.cpp index 66a11fadd..fae616370 100644 --- a/src/engine/platform/vic20.cpp +++ b/src/engine/platform/vic20.cpp @@ -252,6 +252,9 @@ int DivPlatformVIC20::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/vrc6.cpp b/src/engine/platform/vrc6.cpp index 3b2f660ac..f5f7371d6 100644 --- a/src/engine/platform/vrc6.cpp +++ b/src/engine/platform/vrc6.cpp @@ -412,6 +412,9 @@ int DivPlatformVRC6::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index e5cfe72ac..9600cc09b 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -832,6 +832,9 @@ int DivPlatformX1_010::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index a666a62b9..974a2ad2b 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -861,6 +861,9 @@ int DivPlatformYM2203::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: if (c.chan>2) return 15; return 127; diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 7738ae979..4d3986b2d 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -1352,6 +1352,9 @@ int DivPlatformYM2608::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: if (c.chan>14) return 255; if (c.chan>8) return 31; diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index e982fe086..f30ce9082 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -1324,6 +1324,9 @@ int DivPlatformYM2610::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: if (c.chan>=adpcmBChanOffs) return 255; if (c.chan>=adpcmAChanOffs) return 31; diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 6c183a57d..e588bea94 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -1391,6 +1391,9 @@ int DivPlatformYM2610B::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; case DIV_CMD_GET_VOLMAX: if (c.chan>=adpcmBChanOffs) return 255; if (c.chan>=adpcmAChanOffs) return 31; diff --git a/src/engine/platform/ymz280b.cpp b/src/engine/platform/ymz280b.cpp index 4158b4fa9..395d1524e 100644 --- a/src/engine/platform/ymz280b.cpp +++ b/src/engine/platform/ymz280b.cpp @@ -321,6 +321,9 @@ int DivPlatformYMZ280B::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/zxbeeper.cpp b/src/engine/platform/zxbeeper.cpp index 70272613a..ffa974e9f 100644 --- a/src/engine/platform/zxbeeper.cpp +++ b/src/engine/platform/zxbeeper.cpp @@ -218,6 +218,9 @@ int DivPlatformZXBeeper::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/platform/zxbeeperquadtone.cpp b/src/engine/platform/zxbeeperquadtone.cpp index 35a8a5d1d..bc3fc884d 100644 --- a/src/engine/platform/zxbeeperquadtone.cpp +++ b/src/engine/platform/zxbeeperquadtone.cpp @@ -288,6 +288,9 @@ int DivPlatformZXBeeperQuadTone::dispatch(DivCommand c) { case DIV_CMD_MACRO_ON: chan[c.chan].std.mask(c.value,false); break; + case DIV_CMD_MACRO_RESTART: + chan[c.chan].std.restart(c.value); + break; default: break; } diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 06ce4ed1c..3ff0560bc 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -246,6 +246,8 @@ const char* cmdName[]={ "ESFM_OUTLVL", "ESFM_MODIN", "ESFM_ENV_DELAY", + + "MACRO_RESTART", }; static_assert((sizeof(cmdName)/sizeof(void*))==DIV_CMD_MAX,"update cmdName!"); @@ -1006,6 +1008,9 @@ void DivEngine::processRow(int i, bool afterDelay) { case 0xf6: // enable macro dispatchCmd(DivCommand(DIV_CMD_MACRO_ON,i,effectVal&0xff)); break; + case 0xf7: // restart macro + dispatchCmd(DivCommand(DIV_CMD_MACRO_RESTART,i,effectVal&0xff)); + break; case 0xf8: // single volume ramp up chan[i].volume=MIN(chan[i].volume+effectVal*256,chan[i].volMax); dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index 900669dd0..f48b8b906 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -516,7 +516,7 @@ const FurnaceGUIColors fxColors[256]={ GUI_COLOR_PATTERN_EFFECT_VOLUME, // F4 GUI_COLOR_PATTERN_EFFECT_MISC, // F5 GUI_COLOR_PATTERN_EFFECT_MISC, // F6 - GUI_COLOR_PATTERN_EFFECT_INVALID, // F7 + GUI_COLOR_PATTERN_EFFECT_MISC, // F7 GUI_COLOR_PATTERN_EFFECT_VOLUME, // F8 GUI_COLOR_PATTERN_EFFECT_VOLUME, // F9 GUI_COLOR_PATTERN_EFFECT_VOLUME, // FA