Merge branch 'master' into hasSampleHeader

This commit is contained in:
tildearrow 2025-09-13 04:23:19 -05:00
commit de1ab67d4a
42 changed files with 1634 additions and 91 deletions

View file

@ -525,6 +525,72 @@ void FurnaceGUI::drawCSPlayer() {
ImGui::PopFont();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem(_("Data Access Visualizer"))) {
ImGui::Text("%d bytes",(int)cs->getDataLen());
ImGui::PushFont(patFont);
if (ImGui::BeginTable("CSHexPos",chans,ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableNextRow();
for (int i=0; i<chans; i++) {
ImGui::TableNextColumn();
ImGui::Text("%d",i);
}
ImGui::TableNextRow();
for (int i=0; i<chans; i++) {
DivCSChannelState* state=cs->getChanState(i);
ImGui::TableNextColumn();
ImGui::Text("$%.4x",state->readPos);
}
ImGui::EndTable();
}
ImGui::PopFont();
if (csTex==NULL || !rend->isTextureValid(csTex)) {
logD("recreating command stream data texture.");
csTex=rend->createTexture(true,256,256,false,GUI_TEXFORMAT_ABGR32);
if (csTex==NULL) {
logE("error while creating command stream data texture! %s",SDL_GetError());
}
}
if (csTex!=NULL) {
unsigned int* dataT=NULL;
int pitch=0;
if (!rend->lockTexture(csTex,(void**)&dataT,&pitch)) {
logE("error while locking command stream data texture! %s",SDL_GetError());
} else {
unsigned short* accessTS=cs->getDataAccess();
unsigned int csTick=cs->getCurTick();
const float fadeTime=64.0f;
size_t bufSize=cs->getDataLen();
if (bufSize>65536) bufSize=65536;
for (size_t i=0; i<bufSize; i++) {
float cellAlpha=(float)(fadeTime-(((short)(csTick&0xffff))-(short)accessTS[i]))/fadeTime;
if (cellAlpha>0.0f) {
dataT[i]=ImGui::GetColorU32(ImGuiCol_HeaderActive,cellAlpha);
} else {
dataT[i]=0;
}
}
for (size_t i=bufSize; i<65536; i++) {
dataT[i]=0;
}
for (int i=0; i<e->getTotalChannelCount(); i++) {
unsigned int pos=cs->getChanState(i)->readPos;
if (pos<65536) {
ImVec4 col=ImVec4(1.0f,1.0f,1.0f,1.0f);
ImGui::ColorConvertHSVtoRGB((float)i/(float)e->getTotalChannelCount(),0.8f,1.0f,col.x,col.y,col.z);
dataT[pos]=ImGui::GetColorU32(col);
}
}
rend->unlockTexture(csTex);
}
ImGui::Image(rend->getTextureID(csTex),ImVec2(768.0*dpiScale,768.0*dpiScale));
}
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem(_("Stream Info"))) {
ImGui::Text("%d bytes",(int)cs->getDataLen());
ImGui::Text("%u channels",cs->getFileChans());
@ -538,6 +604,11 @@ void FurnaceGUI::drawCSPlayer() {
ImGui::SameLine();
ImGui::Text("%d",cs->getFastCmds()[i]);
}
ImGui::Text("stack sizes:");
for (unsigned int i=0; i<cs->getFileChans(); i++) {
ImGui::SameLine();
ImGui::Text("%d",cs->getChanState(i)->callStackSize);
}
ImGui::Text("ticks: %u",cs->getCurTick());
ImGui::EndTabItem();
}

View file

@ -365,12 +365,10 @@ void FurnaceGUI::drawDebug() {
ImGui::TreePop();
}
if (ImGui::TreeNode("Scroll Text Test")) {
/*
ImGui::ScrollText(ImGui::GetID("scrolltest1"),"Lorem ipsum, quia dolor sit, amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt, ut labore et dolore magnam aliquam quaerat voluptatem. ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?");
ImGui::ScrollText(ImGui::GetID("scrolltest2"),"quis autem vel eum iure reprehenderit");
ImGui::ScrollText(ImGui::GetID("scrolltest3"),"qui in ea voluptate velit esse",ImVec2(100.0f*dpiScale,0),true);
ImGui::ScrollText(ImGui::GetID("scrolltest4"),"quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla pariatur?",ImVec2(0,0),true);
*/
ImGui::ScrollText(ImGui::GetID("scrolltest1"),"Lorem ipsum, quia dolor sit, amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt, ut labore et dolore magnam aliquam quaerat voluptatem. ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?",ImGui::GetCursorPos());
ImGui::ScrollText(ImGui::GetID("scrolltest2"),"quis autem vel eum iure reprehenderit",ImGui::GetCursorPos());
ImGui::ScrollText(ImGui::GetID("scrolltest3"),"qui in ea voluptate velit esse",ImGui::GetCursorPos(),ImVec2(100.0f*dpiScale,0),true);
ImGui::ScrollText(ImGui::GetID("scrolltest4"),"quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla pariatur?",ImGui::GetCursorPos(),ImVec2(0,0),true);
ImGui::TreePop();
}
if (ImGui::TreeNode("Pitch Table Calculator")) {

View file

@ -38,9 +38,21 @@ struct InflateBlock {
};
ImFont* FurnaceGUI::addFontZlib(const void* data, size_t len, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges) {
// find font in cache
logV("addFontZlib...");
for (FurnaceGUIUncompFont& i: fontCache) {
if (i.origPtr==data && i.origLen==len) {
logV("found in cache");
ImFontConfig fontConfig=(font_cfg==NULL)?ImFontConfig():(*font_cfg);
fontConfig.FontDataOwnedByAtlas=false;
return ImGui::GetIO().Fonts->AddFontFromMemoryTTF(i.data,i.len,size_pixels,&fontConfig,glyph_ranges);
}
}
z_stream zl;
memset(&zl,0,sizeof(z_stream));
logV("addFontZlib...");
logV("not found in cache - decompressing...");
zl.avail_in=len;
zl.next_in=(Bytef*)data;
@ -116,10 +128,11 @@ ImFont* FurnaceGUI::addFontZlib(const void* data, size_t len, float size_pixels,
delete i;
}
blocks.clear();
len=finalSize;
fontCache.push_back(FurnaceGUIUncompFont(data,len,finalData,finalSize));
ImFontConfig fontConfig=(font_cfg==NULL)?ImFontConfig():(*font_cfg);
fontConfig.FontDataOwnedByAtlas=true;
fontConfig.FontDataOwnedByAtlas=false;
return ImGui::GetIO().Fonts->AddFontFromMemoryTTF(finalData,finalSize,size_pixels,&fontConfig,glyph_ranges);
}

View file

@ -2640,7 +2640,7 @@ void FurnaceGUI::exportAudio(String path, DivAudioExportModes mode) {
e->findSongLength(loopOrder,loopRow,audioExportOptions.fadeOut,songFadeoutSectionLength,songHasSongEndCommand,songOrdersLengths,songLength); // for progress estimation
songLoopedSectionLength=songLength;
for (int i=0; i<loopOrder; i++) {
for (int i=0; i<loopOrder && i<(int)songOrdersLengths.size(); i++) {
songLoopedSectionLength-=songOrdersLengths[i];
}
songLoopedSectionLength-=loopRow;

View file

@ -1546,6 +1546,18 @@ struct FurnaceGUIPerfMetric {
elapsed(0) {}
};
struct FurnaceGUIUncompFont {
const void* origPtr;
size_t origLen;
void* data;
size_t len;
FurnaceGUIUncompFont(const void* ptr, size_t len, void* d, size_t l):
origPtr(ptr),
origLen(len),
data(d),
len(l) {}
};
struct FurnaceGUIBackupEntry {
String name;
uint64_t size;
@ -1666,6 +1678,8 @@ class FurnaceGUI {
int sampleTexW, sampleTexH;
bool updateSampleTex;
FurnaceGUITexture* csTex;
String workingDir, fileName, clipboard, warnString, errorString, lastError, curFileName, nextFile, sysSearchQuery, newSongQuery, paletteQuery, sampleBankSearchQuery;
String workingDirSong, workingDirIns, workingDirWave, workingDirSample, workingDirAudioExport;
String workingDirVGMExport, workingDirROMExport;
@ -1776,6 +1790,7 @@ class FurnaceGUI {
MIDIMap midiMap;
int learning;
std::vector<FurnaceGUIUncompFont> fontCache;
ImFont* mainFont;
ImFont* iconFont;
ImFont* furIconFont;

View file

@ -6761,7 +6761,7 @@ void FurnaceGUI::applyUISettings(bool updateFonts) {
logW("could not load header font! reverting to default font");
settings.headFont=0;
if ((headFont=addFontZlib(builtinFont[settings.headFont],builtinFontLen[settings.headFont],MAX(1,e->getConfInt("headFontSize",27)*dpiScale),&fontConfH))==NULL) {
logE("could not load header font! falling back to IBM Plex Sans.");
logE("could not load header font! falling back to fallback. wahahaha, get it? fallback.");
headFont=ImGui::GetIO().Fonts->AddFontDefault();
}
}
@ -6775,6 +6775,14 @@ void FurnaceGUI::applyUISettings(bool updateFonts) {
}
}
// four fallback fonts
if (settings.loadFallback) {
headFont=addFontZlib(font_plexSans_compressed_data,font_plexSans_compressed_size,MAX(1,e->getConfInt("headFontSize",27)*dpiScale),&fc1);
headFont=addFontZlib(font_plexSansJP_compressed_data,font_plexSansJP_compressed_size,MAX(1,e->getConfInt("headFontSize",27)*dpiScale),&fc1);
headFont=addFontZlib(font_plexSansKR_compressed_data,font_plexSansKR_compressed_size,MAX(1,e->getConfInt("headFontSize",27)*dpiScale),&fc1);
headFont=addFontZlib(font_unifont_compressed_data,font_unifont_compressed_size,MAX(1,e->getConfInt("headFontSize",27)*dpiScale),&fc1);
}
mainFont->FallbackChar='?';
mainFont->EllipsisChar='.';
//mainFont->EllipsisCharCount=3;

View file

@ -1313,7 +1313,7 @@ void FurnaceCV::buildStage(int which) {
curStage=NULL;
}
if (which>19 || which==4 || which==7 || which==9 || which==11 || which==13 || which==16 || which==17) {
if (which>18 || which==4 || which==7 || which==9 || which==11 || which==13 || which==16 || which==17) {
stageWidth=80;
stageHeight=56;
} else {
@ -1346,26 +1346,7 @@ void FurnaceCV::buildStage(int which) {
memset(busy,0,28*40*sizeof(bool));
// special stages
if ((which%10)==9) {
// vortex
for (int i=0; i<20+(which>>2); i++) {
int tries=0;
while (tries<20) {
int x=rand()%(stageWidth>>1);
int y=rand()%(stageHeight>>1);
int finalX=x<<4;
int finalY=y<<4;
if (busy[y][x]) {
tries++;
continue;
}
createObject<FurnaceCVEnemyVortex>(finalX,finalY);
createObject<FurnaceCVFurBallMedium>(finalX-4,finalY-4);
busy[y][x]=true;
break;
}
}
} else if ((which%10)==19) {
if ((which%20)==19) {
for (int i=0; i<20+(which>>2); i++) {
int tries=0;
while (tries<20) {
@ -1387,6 +1368,25 @@ void FurnaceCV::buildStage(int which) {
break;
}
}
} else if ((which%10)==9) {
// vortex
for (int i=0; i<20+(which>>2); i++) {
int tries=0;
while (tries<20) {
int x=rand()%(stageWidth>>1);
int y=rand()%(stageHeight>>1);
int finalX=x<<4;
int finalY=y<<4;
if (busy[y][x]) {
tries++;
continue;
}
createObject<FurnaceCVEnemyVortex>(finalX,finalY);
createObject<FurnaceCVFurBallMedium>(finalX-4,finalY-4);
busy[y][x]=true;
break;
}
}
} else {
// large
if (which>=2) for (int i=0; i<(rand()%3)+which-2; i++) {
@ -1675,6 +1675,7 @@ void FurnaceCV::render(unsigned char joyIn) {
lives+=lifeBank;
respawnTime=1;
lifeBank=0;
score=0;
gameOver=false;
}