improve cmd stream hex view visual aid

definitely not vspcplay
This commit is contained in:
tildearrow 2025-04-11 04:57:26 -05:00
parent a4ecc86fc2
commit a813f73557
3 changed files with 57 additions and 22 deletions

View file

@ -39,6 +39,10 @@ unsigned char* DivCSPlayer::getData() {
return b; return b;
} }
unsigned short* DivCSPlayer::getDataAccess() {
return bAccessTS;
}
size_t DivCSPlayer::getDataLen() { size_t DivCSPlayer::getDataLen() {
return bLen; return bLen;
} }
@ -59,10 +63,19 @@ unsigned char* DivCSPlayer::getFastCmds() {
return fastCmds; return fastCmds;
} }
unsigned int DivCSPlayer::getCurTick() {
return curTick;
}
void DivCSPlayer::cleanup() { void DivCSPlayer::cleanup() {
delete b; delete[] b;
b=NULL; b=NULL;
bLen=0; bLen=0;
if (bAccessTS) {
delete[] bAccessTS;
bAccessTS=NULL;
}
} }
bool DivCSPlayer::tick() { bool DivCSPlayer::tick() {
@ -82,6 +95,8 @@ bool DivCSPlayer::tick() {
break; break;
} }
unsigned int accessTSBegin=stream.tell();
chan[i].trace[chan[i].tracePos++]=chan[i].readPos; chan[i].trace[chan[i].tracePos++]=chan[i].readPos;
if (chan[i].tracePos>=DIV_MAX_CSTRACE) { if (chan[i].tracePos>=DIV_MAX_CSTRACE) {
chan[i].tracePos=0; chan[i].tracePos=0;
@ -97,9 +112,11 @@ bool DivCSPlayer::tick() {
chan[i].vibratoPos=0; chan[i].vibratoPos=0;
} else if (next>=0xd0 && next<=0xdf) { } else if (next>=0xd0 && next<=0xdf) {
command=fastCmds[next&15]; command=fastCmds[next&15];
bAccessTS[fastCmdsOff+(next&15)]=curTick;
} else if (next>=0xe0 && next<=0xef) { // preset delay } else if (next>=0xe0 && next<=0xef) { // preset delay
chan[i].waitTicks=fastDelays[next&15]; chan[i].waitTicks=fastDelays[next&15];
chan[i].lastWaitLen=chan[i].waitTicks; chan[i].lastWaitLen=chan[i].waitTicks;
bAccessTS[fastDelaysOff+(next&15)]=curTick;
} else switch (next) { } else switch (next) {
case 0xb4: // note on null case 0xb4: // note on null
e->dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,DIV_NOTE_NULL)); e->dispatchCmd(DivCommand(DIV_CMD_NOTE_ON,i,DIV_NOTE_NULL));
@ -126,6 +143,7 @@ bool DivCSPlayer::tick() {
case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xd8: case 0xd9: case 0xda: case 0xdb:
case 0xdc: case 0xdd: case 0xde: case 0xdf: case 0xdc: case 0xdd: case 0xde: case 0xdf:
command=fastCmds[next-0xd0]; command=fastCmds[next-0xd0];
break; break;
case 0xf0: // placeholder case 0xf0: // placeholder
stream.readC(); stream.readC();
@ -529,6 +547,12 @@ bool DivCSPlayer::tick() {
} }
} }
for (unsigned int j=accessTSBegin; j<stream.tell(); j++) {
if (j<bLen) {
bAccessTS[j]=curTick;
}
}
if (mustTell) chan[i].readPos=stream.tell(); if (mustTell) chan[i].readPos=stream.tell();
} }
@ -597,6 +621,20 @@ bool DivCSPlayer::tick() {
} }
} }
// cycle over access times in order to ensure deltas are always higher than 256
// (and prevent spurious highlights)
for (int i=0; i<16; i++) {
short delta=(((short)(curTick&0xffff))-(short)bAccessTS[deltaCyclePos]);
if (delta>256) {
bAccessTS[deltaCyclePos]=curTick-512;
}
if (++deltaCyclePos>=bLen) {
deltaCyclePos=0;
}
}
curTick++;
return ticked; return ticked;
} }
@ -622,7 +660,9 @@ bool DivCSPlayer::init() {
chan[i].readPos=chan[i].startPos; chan[i].readPos=chan[i].startPos;
} }
fastDelaysOff=stream.tell();
stream.read(fastDelays,16); stream.read(fastDelays,16);
fastCmdsOff=stream.tell();
stream.read(fastCmds,16); stream.read(fastCmds,16);
// initialize state // initialize state
@ -636,6 +676,11 @@ bool DivCSPlayer::init() {
} }
arpSpeed=1; arpSpeed=1;
bAccessTS=new unsigned short[bLen];
// this value ensures all deltas are higher than 256
memset(bAccessTS,0xc0,bLen*sizeof(unsigned short));
curTick=0;
deltaCyclePos=0;
return true; return true;
} }

View file

@ -77,6 +77,7 @@ struct DivCSChannelState {
class DivCSPlayer { class DivCSPlayer {
DivEngine* e; DivEngine* e;
unsigned char* b; unsigned char* b;
unsigned short* bAccessTS;
size_t bLen; size_t bLen;
SafeReader stream; SafeReader stream;
DivCSChannelState chan[DIV_MAX_CHANS]; DivCSChannelState chan[DIV_MAX_CHANS];
@ -84,21 +85,25 @@ class DivCSPlayer {
unsigned char fastCmds[16]; unsigned char fastCmds[16];
unsigned char arpSpeed; unsigned char arpSpeed;
unsigned int fileChans; unsigned int fileChans;
unsigned int curTick, fastDelaysOff, fastCmdsOff, deltaCyclePos;
short vibTable[64]; short vibTable[64];
public: public:
unsigned char* getData(); unsigned char* getData();
unsigned short* getDataAccess();
size_t getDataLen(); size_t getDataLen();
DivCSChannelState* getChanState(int ch); DivCSChannelState* getChanState(int ch);
unsigned int getFileChans(); unsigned int getFileChans();
unsigned char* getFastDelays(); unsigned char* getFastDelays();
unsigned char* getFastCmds(); unsigned char* getFastCmds();
unsigned int getCurTick();
void cleanup(); void cleanup();
bool tick(); bool tick();
bool init(); bool init();
DivCSPlayer(DivEngine* en, unsigned char* buf, size_t len): DivCSPlayer(DivEngine* en, unsigned char* buf, size_t len):
e(en), e(en),
b(buf), b(buf),
bAccessTS(NULL),
bLen(len), bLen(len),
stream(buf,len) {} stream(buf,len) {}
}; };

View file

@ -478,22 +478,12 @@ void FurnaceGUI::drawCSPlayer() {
// content // content
unsigned char* buf=cs->getData(); unsigned char* buf=cs->getData();
unsigned short* accessTS=cs->getDataAccess();
unsigned int csTick=cs->getCurTick();
const float fadeTime=64.0f;
size_t bufSize=cs->getDataLen(); size_t bufSize=cs->getDataLen();
csClipper.Begin((bufSize+15)>>4,ImGui::GetTextLineHeightWithSpacing()); csClipper.Begin((bufSize+15)>>4,ImGui::GetTextLineHeightWithSpacing());
while (csClipper.Step()) { while (csClipper.Step()) {
//std::vector<int> highlightsUnsorted;
std::vector<int> highlights;
int nextHighlight=-1;
int highlightPos=0;
for (int i=0; i<chans; i++) {
DivCSChannelState* state=cs->getChanState(i);
if ((int)state->readPos>=(csClipper.DisplayStart<<4) && (int)state->readPos<=(csClipper.DisplayEnd<<4)) {
highlights.push_back(state->readPos);
}
}
if (!highlights.empty()) nextHighlight=highlights[0];
for (int i=csClipper.DisplayStart; i<csClipper.DisplayEnd; i++) { for (int i=csClipper.DisplayStart; i<csClipper.DisplayEnd; i++) {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
@ -504,14 +494,9 @@ void FurnaceGUI::drawCSPlayer() {
int pos=(i<<4)|j; int pos=(i<<4)|j;
ImGui::TableNextColumn(); ImGui::TableNextColumn();
if (pos>=(int)bufSize) continue; if (pos>=(int)bufSize) continue;
if (pos==nextHighlight) { float cellAlpha=(float)(fadeTime-(((short)(csTick&0xffff))-(short)accessTS[pos]))/fadeTime;
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(ImGuiCol_HeaderActive)); if (cellAlpha>0.0f) {
highlightPos++; ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(ImGuiCol_HeaderActive,cellAlpha));
if (highlightPos>=(int)highlights.size()) {
nextHighlight=-1;
} else {
nextHighlight=highlights[highlightPos];
}
} }
ImGui::Text("%.2X",buf[pos]); ImGui::Text("%.2X",buf[pos]);
} }