diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a3f8e641..8a8f3805c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -495,6 +495,8 @@ extern/YMF276-LLE/fmopn2.c extern/ESFMu/esfm.c extern/ESFMu/esfm_registers.c +extern/pwrnoise/pwrnoise.c + src/pch.cpp src/engine/platform/sound/sn76496.cpp @@ -703,6 +705,7 @@ src/engine/platform/k053260.cpp src/engine/platform/ted.cpp src/engine/platform/c140.cpp src/engine/platform/esfm.cpp +src/engine/platform/powernoise.cpp src/engine/platform/pcmdac.cpp src/engine/platform/dummy.cpp diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index c459cc3b0..8f9d2f05f 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -248,6 +248,9 @@ enum DivDispatchCmds { DIV_CMD_ESFM_MODIN, // (op, value) DIV_CMD_ESFM_ENV_DELAY, // (op, value) + DIV_CMD_POWER_NOISE_COUNTER_LOAD, // (which, val) + DIV_CMD_POWER_NOISE_IO_WRITE, // (port, value) + DIV_CMD_MACRO_RESTART, // (which) DIV_CMD_MAX diff --git a/src/engine/dispatchContainer.cpp b/src/engine/dispatchContainer.cpp index ffcbe91eb..d6be1ece8 100644 --- a/src/engine/dispatchContainer.cpp +++ b/src/engine/dispatchContainer.cpp @@ -83,6 +83,7 @@ #include "platform/c140.h" #include "platform/pcmdac.h" #include "platform/esfm.h" +#include "platform/powernoise.h" #include "platform/dummy.h" #include "../ta-log.h" #include "song.h" @@ -648,6 +649,9 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do case DIV_SYSTEM_ESFM: dispatch=new DivPlatformESFM; break; + case DIV_SYSTEM_POWER_NOISE: + dispatch=new DivPlatformPowerNoise; + break; case DIV_SYSTEM_DUMMY: dispatch=new DivPlatformDummy; break; diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 71aaeb012..f7f3e26b7 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -1043,6 +1043,8 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo featureFM=true; featureEF=true; break; + case DIV_INS_POWER_NOISE: + break; case DIV_INS_MAX: break; case DIV_INS_NULL: diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 4304d5526..3e7b98e62 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -86,6 +86,7 @@ enum DivInstrumentType: unsigned short { DIV_INS_C140=53, DIV_INS_C219=54, DIV_INS_ESFM=55, + DIV_INS_POWER_NOISE=56, DIV_INS_MAX, DIV_INS_NULL }; diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 3ff0560bc..4494736d8 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -247,6 +247,9 @@ const char* cmdName[]={ "ESFM_MODIN", "ESFM_ENV_DELAY", + "POWER_NOISE_COUNTER_LOAD", + "POWER_NOISE_IO_WRITE", + "MACRO_RESTART", }; diff --git a/src/engine/song.h b/src/engine/song.h index 7f29ddb69..e9e1f72e0 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -132,7 +132,8 @@ enum DivSystem { DIV_SYSTEM_TED, DIV_SYSTEM_C140, DIV_SYSTEM_C219, - DIV_SYSTEM_ESFM + DIV_SYSTEM_ESFM, + DIV_SYSTEM_POWER_NOISE, }; enum DivEffectType: unsigned short { diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 0da85e855..375019671 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1984,6 +1984,23 @@ void DivEngine::registerSystems() { }, fmESFMPostEffectHandlerMap ); + + sysDefs[DIV_SYSTEM_POWER_NOISE]=new DivSysDef( + "BS-C-04xx series (Power Noise)", NULL, 0xd2, 0, 4, false, false, 0, false, 0, 0, 0, + "a fantasy sound chip designed by jvsTSX and The Beesh-Spweesh!\nused in the Hexheld fantasy console.", + {"Noise 1", "Noise 2", "Noise 3", "Slope"}, + {"N1", "N2", "N3", "SL"}, + {DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_PULSE}, + {DIV_INS_POWER_NOISE, DIV_INS_POWER_NOISE, DIV_INS_POWER_NOISE, DIV_INS_POWER_NOISE}, + {}, + { + {0x20, {DIV_CMD_POWER_NOISE_COUNTER_LOAD, "20xx: Load low byte of noise channel LFSR (00 to FF) or slope channel accumulator (00 to 7F)", constVal<0>, effectVal}}, + {0x21, {DIV_CMD_POWER_NOISE_COUNTER_LOAD, "21xx: Load high byte of noise channel LFSR (00 to FF)", constVal<1>, effectVal}}, + {0x22, {DIV_CMD_POWER_NOISE_IO_WRITE, "22xx: Write to I/O port A", constVal<0>, effectVal}}, + {0x23, {DIV_CMD_POWER_NOISE_IO_WRITE, "23xx: Write to I/O port B", constVal<1>, effectVal}}, + }, + {} + ); sysDefs[DIV_SYSTEM_DUMMY]=new DivSysDef( "Dummy System", NULL, 0xfd, 0, 8, false, true, 0, false, 0, 0, 0, diff --git a/src/gui/gui.h b/src/gui/gui.h index a41251f43..a5da4d865 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -291,6 +291,7 @@ enum FurnaceGUIColors { GUI_COLOR_INSTR_C140, GUI_COLOR_INSTR_C219, GUI_COLOR_INSTR_ESFM, + GUI_COLOR_INSTR_POWER_NOISE, GUI_COLOR_INSTR_UNKNOWN, GUI_COLOR_CHANNEL_BG, diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index f48b8b906..43638329d 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -176,6 +176,7 @@ const char* insTypes[DIV_INS_MAX+1][3]={ {"C140",ICON_FA_VOLUME_UP,ICON_FUR_INS_C140}, {"C219",ICON_FA_VOLUME_UP,ICON_FUR_INS_C219}, {"FM (ESFM)",ICON_FA_AREA_CHART,ICON_FUR_INS_ESFM}, + {"Power Noise",ICON_FUR_NOISE,ICON_FA_QUESTION}, {NULL,ICON_FA_QUESTION,ICON_FA_QUESTION} }; @@ -986,6 +987,7 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={ D(GUI_COLOR_INSTR_C140,"",ImVec4(1.0f,1.0f,0.0f,1.0f)), D(GUI_COLOR_INSTR_C219,"",ImVec4(1.0f,0.8f,0.0f,1.0f)), D(GUI_COLOR_INSTR_ESFM,"",ImVec4(0.1f,0.9f,1.0f,1.0f)), + D(GUI_COLOR_INSTR_POWER_NOISE,"",ImVec4(1.0f,1.0f,0.8f,1.0f)), D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)), D(GUI_COLOR_CHANNEL_BG,"",ImVec4(0.4f,0.6f,0.8f,1.0f)), @@ -1203,6 +1205,7 @@ const int availableSystems[]={ DIV_SYSTEM_PCM_DAC, DIV_SYSTEM_ESFM, DIV_SYSTEM_PONG, + DIV_SYSTEM_POWER_NOISE, 0 // don't remove this last one! }; @@ -1292,6 +1295,7 @@ const int chipsSpecial[]={ DIV_SYSTEM_VRC6, DIV_SYSTEM_MMC5, DIV_SYSTEM_SM8521, + DIV_SYSTEM_POWER_NOISE, 0 // don't remove this last one! }; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 6ce4e9dfb..bd8a3660a 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -6936,6 +6936,7 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_TED) waveMax=0; if (ins->type==DIV_INS_C140) waveMax=0; if (ins->type==DIV_INS_C219) waveMax=0; + if (ins->type==DIV_INS_POWER_NOISE) waveMax=0; if (ins->type==DIV_INS_SU || ins->type==DIV_INS_POKEY) waveMax=7; if (ins->type==DIV_INS_PET) { waveMax=8; @@ -7074,6 +7075,9 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_ES5506) { panMax=4095; } + if (ins->type==DIV_INS_POWER_NOISE) { + panMax=15; + } if (volMax>0) { macroList.push_back(FurnaceGUIMacroDesc(volumeLabel,&ins->std.volMacro,volMin,volMax,160,uiColors[GUI_COLOR_MACRO_VOLUME])); @@ -7161,7 +7165,8 @@ void FurnaceGUI::drawInsEdit() { ins->type==DIV_INS_C140 || ins->type==DIV_INS_C219 || ins->type==DIV_INS_TED || - ins->type==DIV_INS_ESFM) { + ins->type==DIV_INS_ESFM || + ins->type==DIV_INS_POWER_NOISE) { macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); } if (ex1Max>0) { @@ -7254,6 +7259,15 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_MSM5232) { macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.ex3Macro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); } + if (ins->type==DIV_INS_POWER_NOISE) { + macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.ex1Macro,0,8,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc("Portion A Length",&ins->std.ex2Macro,0,255,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Portion B Length",&ins->std.ex3Macro,0,255,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Tap A Location",&ins->std.ex4Macro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Tap B Location",&ins->std.ex5Macro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Portion A Offset",&ins->std.ex6Macro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Portion B Offset",&ins->std.ex7Macro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER])); + } drawMacros(macroList,macroEditStateMacros); ImGui::EndTabItem();