Virtual Boy: envelope bug status

This commit is contained in:
tildearrow 2025-06-24 02:54:18 -05:00
parent 7fbe9c01a5
commit 38e4245ee0
13 changed files with 62 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 B

View file

@ -51,6 +51,14 @@ additionally, channel 5 offers a modulation/sweep unit. the former is similar to
this chip uses the [Virtual Boy](../4-instrument/virtual-boy.md) instrument editor.
## channel status
the following icons are displayed when channel status is enabled in the pattern view:
- ![envelope off](status-VBoy-env-none.png) hardware envelope is disabled or running OK
- ![envelope warning](status-VBoy-env-warn.png) hardware envelope has finished - attempting to write a new envelope won't work without phase reset!
- ![envelope error](status-VBoy-env-error.png) can't start hardware envelope - please reset phase
## chip config
the following options are available in the Chip Manager window:

View file

@ -564,6 +564,8 @@ struct DivChannelModeHints {
// - 18: inc linear
// - 19: inc bent
// - 20: direct
// - 21: warning
// - 22: error
unsigned char type[4];
// up to 4
unsigned char count;

View file

@ -156,8 +156,9 @@ void VSU::Write(int timestamp, unsigned int A, unsigned char V)
WavePos[ch] = 0;
if(ch == 5) // Not sure if this is correct.
if(ch == 5) { // Not sure if this is correct.
lfsr = 1;
}
EnvelopeModMask[ch] = 0;
if(!(EnvControl[ch] & 0x200) && (

View file

@ -92,10 +92,12 @@ class VSU
int EnvelopeClockDivider[6];
int SweepModClockDivider;
public:
int EnvelopeModMask[6];
int ModState;
int ModLock;
private:
int NoiseLatcherClockDivider;
unsigned int NoiseLatcher;

View file

@ -19,6 +19,8 @@
#include "vb.h"
#include "../engine.h"
#include "IconsFontAwesome4.h"
#include "furIcons.h"
#include <math.h>
//#define rWrite(a,v) pendingWrites[a]=v;
@ -252,6 +254,27 @@ void DivPlatformVB::tick(bool sysTick) {
}
}
}
for (int i=0; i<6; i++) {
if ((chan[i].envHigh&3)==0) {
chan[i].hasEnvWarning=0;
} else {
switch (vb->EnvelopeModMask[i]) {
case 0: // envelope OK
chan[i].hasEnvWarning=0;
break;
case 1: // envelope has finished
chan[i].hasEnvWarning=21;
break;
case 2: // can't envelope
chan[i].hasEnvWarning=22;
break;
}
}
}
/*if (vb->ModLock) {
chan[4].hasEnvWarning=4;
}*/
}
int DivPlatformVB::dispatch(DivCommand c) {
@ -477,6 +500,16 @@ unsigned short DivPlatformVB::getPan(int ch) {
return ((chan[ch].pan&0xf0)<<4)|(chan[ch].pan&15);
}
DivChannelModeHints DivPlatformVB::getModeHints(int ch) {
DivChannelModeHints ret;
//if (ch>4) return ret;
ret.count=1;
ret.hint[0]=ICON_FA_EXCLAMATION_TRIANGLE;
ret.type[0]=chan[ch].hasEnvWarning;
return ret;
}
DivDispatchOscBuffer* DivPlatformVB::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -30,6 +30,7 @@ class DivPlatformVB: public DivDispatch {
int antiClickPeriodCount, antiClickWavePos;
unsigned char pan, envLow, envHigh;
bool noise, deferredWaveUpdate, intWritten;
unsigned char hasEnvWarning;
signed short wave;
DivWaveSynth ws;
Channel():
@ -42,6 +43,7 @@ class DivPlatformVB: public DivDispatch {
noise(false),
deferredWaveUpdate(false),
intWritten(false),
hasEnvWarning(0),
wave(-1) {}
};
Channel chan[6];
@ -78,6 +80,7 @@ class DivPlatformVB: public DivDispatch {
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
unsigned short getPan(int chan);
DivChannelModeHints getModeHints(int chan);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();

View file

@ -434,6 +434,8 @@ enum FurnaceGUIColors {
GUI_COLOR_PATTERN_STATUS_INC,
GUI_COLOR_PATTERN_STATUS_BENT,
GUI_COLOR_PATTERN_STATUS_DIRECT,
GUI_COLOR_PATTERN_STATUS_WARNING,
GUI_COLOR_PATTERN_STATUS_ERROR,
GUI_COLOR_PATTERN_PAIR,
GUI_COLOR_SAMPLE_BG,

View file

@ -1134,6 +1134,8 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={
D(GUI_COLOR_PATTERN_STATUS_INC,"",ImVec4(0.1f,0.1f,1.0f,1.0f)),
D(GUI_COLOR_PATTERN_STATUS_BENT,"",ImVec4(1.0f,1.0f,0.1f,1.0f)),
D(GUI_COLOR_PATTERN_STATUS_DIRECT,"",ImVec4(1.0f,0.5f,0.2f,1.0f)),
D(GUI_COLOR_PATTERN_STATUS_WARNING,"",ImVec4(0.98f,0.98f,0.06f,1.0f)),
D(GUI_COLOR_PATTERN_STATUS_ERROR,"",ImVec4(0.98f,0.06f,0.06f,1.0f)),
D(GUI_COLOR_PATTERN_PAIR,"",ImVec4(0.6f,0.8f,1.0f,1.0f)),

View file

@ -1138,6 +1138,12 @@ void FurnaceGUI::drawPattern() {
case 20:
hintColor=uiColors[GUI_COLOR_PATTERN_STATUS_DIRECT];
break;
case 21:
hintColor=uiColors[GUI_COLOR_PATTERN_STATUS_WARNING];
break;
case 22:
hintColor=uiColors[GUI_COLOR_PATTERN_STATUS_ERROR];
break;
default:
hintColor=uiColors[GUI_COLOR_TEXT];
break;

View file

@ -4312,6 +4312,8 @@ void FurnaceGUI::drawSettings() {
UI_COLOR_CONFIG(GUI_COLOR_PATTERN_STATUS_INC,_("Status: increase"));
UI_COLOR_CONFIG(GUI_COLOR_PATTERN_STATUS_BENT,_("Status: bent"));
UI_COLOR_CONFIG(GUI_COLOR_PATTERN_STATUS_DIRECT,_("Status: direct"));
UI_COLOR_CONFIG(GUI_COLOR_PATTERN_STATUS_WARNING,_("Status: warning"));
UI_COLOR_CONFIG(GUI_COLOR_PATTERN_STATUS_ERROR,_("Status: error"));
ImGui::TreePop();
}
if (ImGui::TreeNode(_("Sample Editor"))) {