From a813f73557461bb1186c54fcfff47527efdfc9ac Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 11 Apr 2025 04:57:26 -0500 Subject: [PATCH] improve cmd stream hex view visual aid definitely not vspcplay --- src/engine/cmdStream.cpp | 47 +++++++++++++++++++++++++++++++++++++++- src/engine/cmdStream.h | 5 +++++ src/gui/csPlayer.cpp | 27 +++++------------------ 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/src/engine/cmdStream.cpp b/src/engine/cmdStream.cpp index c2821ca0b..9098e8f57 100644 --- a/src/engine/cmdStream.cpp +++ b/src/engine/cmdStream.cpp @@ -39,6 +39,10 @@ unsigned char* DivCSPlayer::getData() { return b; } +unsigned short* DivCSPlayer::getDataAccess() { + return bAccessTS; +} + size_t DivCSPlayer::getDataLen() { return bLen; } @@ -59,10 +63,19 @@ unsigned char* DivCSPlayer::getFastCmds() { return fastCmds; } +unsigned int DivCSPlayer::getCurTick() { + return curTick; +} + void DivCSPlayer::cleanup() { - delete b; + delete[] b; b=NULL; bLen=0; + + if (bAccessTS) { + delete[] bAccessTS; + bAccessTS=NULL; + } } bool DivCSPlayer::tick() { @@ -82,6 +95,8 @@ bool DivCSPlayer::tick() { break; } + unsigned int accessTSBegin=stream.tell(); + chan[i].trace[chan[i].tracePos++]=chan[i].readPos; if (chan[i].tracePos>=DIV_MAX_CSTRACE) { chan[i].tracePos=0; @@ -97,9 +112,11 @@ bool DivCSPlayer::tick() { chan[i].vibratoPos=0; } else if (next>=0xd0 && next<=0xdf) { command=fastCmds[next&15]; + bAccessTS[fastCmdsOff+(next&15)]=curTick; } else if (next>=0xe0 && next<=0xef) { // preset delay chan[i].waitTicks=fastDelays[next&15]; chan[i].lastWaitLen=chan[i].waitTicks; + bAccessTS[fastDelaysOff+(next&15)]=curTick; } else switch (next) { case 0xb4: // note on 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 0xdc: case 0xdd: case 0xde: case 0xdf: command=fastCmds[next-0xd0]; + break; case 0xf0: // placeholder stream.readC(); @@ -529,6 +547,12 @@ bool DivCSPlayer::tick() { } } + for (unsigned int j=accessTSBegin; j256) { + bAccessTS[deltaCyclePos]=curTick-512; + } + if (++deltaCyclePos>=bLen) { + deltaCyclePos=0; + } + } + + curTick++; + return ticked; } @@ -622,7 +660,9 @@ bool DivCSPlayer::init() { chan[i].readPos=chan[i].startPos; } + fastDelaysOff=stream.tell(); stream.read(fastDelays,16); + fastCmdsOff=stream.tell(); stream.read(fastCmds,16); // initialize state @@ -636,6 +676,11 @@ bool DivCSPlayer::init() { } 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; } diff --git a/src/engine/cmdStream.h b/src/engine/cmdStream.h index 72f458067..f879240f1 100644 --- a/src/engine/cmdStream.h +++ b/src/engine/cmdStream.h @@ -77,6 +77,7 @@ struct DivCSChannelState { class DivCSPlayer { DivEngine* e; unsigned char* b; + unsigned short* bAccessTS; size_t bLen; SafeReader stream; DivCSChannelState chan[DIV_MAX_CHANS]; @@ -84,21 +85,25 @@ class DivCSPlayer { unsigned char fastCmds[16]; unsigned char arpSpeed; unsigned int fileChans; + unsigned int curTick, fastDelaysOff, fastCmdsOff, deltaCyclePos; short vibTable[64]; public: unsigned char* getData(); + unsigned short* getDataAccess(); size_t getDataLen(); DivCSChannelState* getChanState(int ch); unsigned int getFileChans(); unsigned char* getFastDelays(); unsigned char* getFastCmds(); + unsigned int getCurTick(); void cleanup(); bool tick(); bool init(); DivCSPlayer(DivEngine* en, unsigned char* buf, size_t len): e(en), b(buf), + bAccessTS(NULL), bLen(len), stream(buf,len) {} }; diff --git a/src/gui/csPlayer.cpp b/src/gui/csPlayer.cpp index 82127561a..78328d1db 100644 --- a/src/gui/csPlayer.cpp +++ b/src/gui/csPlayer.cpp @@ -478,22 +478,12 @@ void FurnaceGUI::drawCSPlayer() { // content 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(); csClipper.Begin((bufSize+15)>>4,ImGui::GetTextLineHeightWithSpacing()); while (csClipper.Step()) { - //std::vector highlightsUnsorted; - std::vector highlights; - int nextHighlight=-1; - int highlightPos=0; - - for (int i=0; igetChanState(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=(int)bufSize) continue; - if (pos==nextHighlight) { - ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(ImGuiCol_HeaderActive)); - highlightPos++; - if (highlightPos>=(int)highlights.size()) { - nextHighlight=-1; - } else { - nextHighlight=highlights[highlightPos]; - } + float cellAlpha=(float)(fadeTime-(((short)(csTick&0xffff))-(short)accessTS[pos]))/fadeTime; + if (cellAlpha>0.0f) { + ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg,ImGui::GetColorU32(ImGuiCol_HeaderActive,cellAlpha)); } ImGui::Text("%.2X",buf[pos]); }