move asset dir functions to another file

and get them out of the engine
This commit is contained in:
tildearrow 2025-11-11 18:33:23 -05:00
parent 2ff3def8f8
commit 2f25acd017
8 changed files with 210 additions and 156 deletions

View file

@ -782,6 +782,8 @@ src/engine/brrUtils.c
src/engine/safeReader.cpp
src/engine/safeWriter.cpp
src/engine/workPool.cpp
src/engine/assetDir.cpp
src/engine/cmdStream.cpp
src/engine/cmdStreamOps.cpp
src/engine/config.cpp

152
src/engine/assetDir.cpp Normal file
View file

@ -0,0 +1,152 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2025 tildearrow and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "assetDir.h"
#include "../ta-log.h"
void moveAsset(std::vector<DivAssetDir>& dir, int before, int after) {
if (before<0 || after<0) return;
for (DivAssetDir& i: dir) {
for (size_t j=0; j<i.entries.size(); j++) {
// erase matching entry
if (i.entries[j]==before) {
i.entries[j]=after;
} else if (i.entries[j]==after) {
i.entries[j]=before;
}
}
}
}
void removeAsset(std::vector<DivAssetDir>& dir, int entry) {
if (entry<0) return;
for (DivAssetDir& i: dir) {
for (size_t j=0; j<i.entries.size(); j++) {
// erase matching entry
if (i.entries[j]==entry) {
i.entries.erase(i.entries.begin()+j);
j--;
} else if (i.entries[j]>entry) {
i.entries[j]--;
}
}
}
}
void checkAssetDir(std::vector<DivAssetDir>& dir, size_t entries) {
bool* inAssetDir=new bool[entries];
memset(inAssetDir,0,entries*sizeof(bool));
for (DivAssetDir& i: dir) {
for (size_t j=0; j<i.entries.size(); j++) {
// erase invalid entry
if (i.entries[j]<0 || i.entries[j]>=(int)entries) {
i.entries.erase(i.entries.begin()+j);
j--;
continue;
}
// erase duplicate entry
if (inAssetDir[i.entries[j]]) {
i.entries.erase(i.entries.begin()+j);
j--;
continue;
}
// mark entry as present
inAssetDir[i.entries[j]]=true;
}
}
// get unsorted directory
DivAssetDir* unsortedDir=NULL;
for (DivAssetDir& i: dir) {
if (i.name.empty()) {
unsortedDir=&i;
break;
}
}
// add missing items to unsorted directory
for (size_t i=0; i<entries; i++) {
if (!inAssetDir[i]) {
// create unsorted directory if it doesn't exist
if (unsortedDir==NULL) {
dir.push_back(DivAssetDir(""));
unsortedDir=&(*dir.rbegin());
}
unsortedDir->entries.push_back(i);
}
}
delete[] inAssetDir;
}
void putAssetDirData(SafeWriter* w, std::vector<DivAssetDir>& dir) {
size_t blockStartSeek, blockEndSeek;
w->write("ADIR",4);
blockStartSeek=w->tell();
w->writeI(0);
w->writeI(dir.size());
for (DivAssetDir& i: dir) {
w->writeString(i.name,false);
w->writeS(i.entries.size());
for (int j: i.entries) {
w->writeC(j);
}
}
blockEndSeek=w->tell();
w->seek(blockStartSeek,SEEK_SET);
w->writeI(blockEndSeek-blockStartSeek-4);
w->seek(0,SEEK_END);
}
DivDataErrors readAssetDirData(SafeReader& reader, std::vector<DivAssetDir>& dir) {
char magic[4];
reader.read(magic,4);
if (memcmp(magic,"ADIR",4)!=0) {
logV("header is invalid: %c%c%c%c",magic[0],magic[1],magic[2],magic[3]);
return DIV_DATA_INVALID_HEADER;
}
reader.readI(); // reserved
unsigned int numDirs=reader.readI();
dir.reserve(numDirs);
for (unsigned int i=0; i<numDirs; i++) {
DivAssetDir d;
d.name=reader.readString();
unsigned short numEntries=reader.readS();
d.entries.reserve(numEntries);
for (unsigned short j=0; j<numEntries; j++) {
d.entries.push_back(((unsigned char)reader.readC()));
}
dir.push_back(d);
}
return DIV_DATA_SUCCESS;
}

52
src/engine/assetDir.h Normal file
View file

@ -0,0 +1,52 @@
/**
* Furnace Tracker - multi-system chiptune tracker
* Copyright (C) 2021-2025 tildearrow and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _ASSET_DIR_H
#define _ASSET_DIR_H
#include "../ta-utils.h"
#include <vector>
#include "dataErrors.h"
#include "safeReader.h"
#include "safeWriter.h"
struct DivAssetDir {
String name;
std::vector<int> entries;
DivAssetDir():
name("New Directory") {}
DivAssetDir(String n):
name(n) {}
};
// check whether an asset directory is complete (UNSAFE)
void checkAssetDir(std::vector<DivAssetDir>& dir, size_t entries);
// move an asset
void moveAsset(std::vector<DivAssetDir>& dir, int before, int after);
// remove an asset
void removeAsset(std::vector<DivAssetDir>& dir, int entry);
// read/write asset dir
void putAssetDirData(SafeWriter* w, std::vector<DivAssetDir>& dir);
DivDataErrors readAssetDirData(SafeReader& reader, std::vector<DivAssetDir>& dir);
#endif

View file

@ -709,84 +709,6 @@ void DivEngine::changeSong(size_t songIndex) {
prevRow=0;
}
void DivEngine::moveAsset(std::vector<DivAssetDir>& dir, int before, int after) {
if (before<0 || after<0) return;
for (DivAssetDir& i: dir) {
for (size_t j=0; j<i.entries.size(); j++) {
// erase matching entry
if (i.entries[j]==before) {
i.entries[j]=after;
} else if (i.entries[j]==after) {
i.entries[j]=before;
}
}
}
}
void DivEngine::removeAsset(std::vector<DivAssetDir>& dir, int entry) {
if (entry<0) return;
for (DivAssetDir& i: dir) {
for (size_t j=0; j<i.entries.size(); j++) {
// erase matching entry
if (i.entries[j]==entry) {
i.entries.erase(i.entries.begin()+j);
j--;
} else if (i.entries[j]>entry) {
i.entries[j]--;
}
}
}
}
void DivEngine::checkAssetDir(std::vector<DivAssetDir>& dir, size_t entries) {
bool* inAssetDir=new bool[entries];
memset(inAssetDir,0,entries*sizeof(bool));
for (DivAssetDir& i: dir) {
for (size_t j=0; j<i.entries.size(); j++) {
// erase invalid entry
if (i.entries[j]<0 || i.entries[j]>=(int)entries) {
i.entries.erase(i.entries.begin()+j);
j--;
continue;
}
// erase duplicate entry
if (inAssetDir[i.entries[j]]) {
i.entries.erase(i.entries.begin()+j);
j--;
continue;
}
// mark entry as present
inAssetDir[i.entries[j]]=true;
}
}
// get unsorted directory
DivAssetDir* unsortedDir=NULL;
for (DivAssetDir& i: dir) {
if (i.name.empty()) {
unsortedDir=&i;
break;
}
}
// add missing items to unsorted directory
for (size_t i=0; i<entries; i++) {
if (!inAssetDir[i]) {
// create unsorted directory if it doesn't exist
if (unsortedDir==NULL) {
dir.push_back(DivAssetDir(""));
unsortedDir=&(*dir.rbegin());
}
unsortedDir->entries.push_back(i);
}
}
delete[] inAssetDir;
}
void DivEngine::copyChannelP(int src, int dest) {
if (src<0 || src>=chans) return;
if (dest<0 || dest>=chans) return;

View file

@ -701,16 +701,6 @@ class DivEngine {
void swapSystemUnsafe(int src, int dest, bool preserveOrder=true);
// move an asset
void moveAsset(std::vector<DivAssetDir>& dir, int before, int after);
// remove an asset
void removeAsset(std::vector<DivAssetDir>& dir, int entry);
// read/write asset dir
void putAssetDirData(SafeWriter* w, std::vector<DivAssetDir>& dir);
DivDataErrors readAssetDirData(SafeReader& reader, std::vector<DivAssetDir>& dir);
// add every export method here
friend class DivROMExport;
friend class DivExportAmigaValidation;
@ -819,9 +809,6 @@ class DivEngine {
// convert old flags
static void convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivSystem sys);
// check whether an asset directory is complete (UNSAFE)
void checkAssetDir(std::vector<DivAssetDir>& dir, size_t entries);
// benchmark (returns time in seconds)
double benchmarkPlayback();
double benchmarkSeek();

View file

@ -63,58 +63,6 @@ struct PatToWrite {
pat(p) {}
};
void DivEngine::putAssetDirData(SafeWriter* w, std::vector<DivAssetDir>& dir) {
size_t blockStartSeek, blockEndSeek;
w->write("ADIR",4);
blockStartSeek=w->tell();
w->writeI(0);
w->writeI(dir.size());
for (DivAssetDir& i: dir) {
w->writeString(i.name,false);
w->writeS(i.entries.size());
for (int j: i.entries) {
w->writeC(j);
}
}
blockEndSeek=w->tell();
w->seek(blockStartSeek,SEEK_SET);
w->writeI(blockEndSeek-blockStartSeek-4);
w->seek(0,SEEK_END);
}
DivDataErrors DivEngine::readAssetDirData(SafeReader& reader, std::vector<DivAssetDir>& dir) {
char magic[4];
reader.read(magic,4);
if (memcmp(magic,"ADIR",4)!=0) {
logV("header is invalid: %c%c%c%c",magic[0],magic[1],magic[2],magic[3]);
return DIV_DATA_INVALID_HEADER;
}
reader.readI(); // reserved
unsigned int numDirs=reader.readI();
dir.reserve(numDirs);
for (unsigned int i=0; i<numDirs; i++) {
DivAssetDir d;
d.name=reader.readString();
unsigned short numEntries=reader.readS();
d.entries.reserve(numEntries);
for (unsigned short j=0; j<numEntries; j++) {
d.entries.push_back(((unsigned char)reader.readC()));
}
dir.push_back(d);
}
return DIV_DATA_SUCCESS;
}
void DivEngine::convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivSystem sys) {
newFlags.clear();

View file

@ -26,6 +26,7 @@
#include "../timeutils.h"
#include "../ta-utils.h"
#include "config.h"
#include "assetDir.h"
#include "orders.h"
#include "instrument.h"
#include "pattern.h"
@ -253,16 +254,6 @@ struct DivSubSong {
}
};
struct DivAssetDir {
String name;
std::vector<int> entries;
DivAssetDir():
name("New Directory") {}
DivAssetDir(String n):
name(n) {}
};
struct DivEffectStorage {
DivEffectType id;
unsigned short slot, storageVer;

View file

@ -745,7 +745,7 @@ void FurnaceGUI::drawInsList(bool asChild) {
if (dirToDelete!=-1) {
e->lockEngine([this,dirToDelete]() {
e->song.insDir.erase(e->song.insDir.begin()+dirToDelete);
e->checkAssetDir(e->song.insDir,e->song.ins.size());
checkAssetDir(e->song.insDir,e->song.ins.size());
});
}
} else {
@ -1402,7 +1402,7 @@ void FurnaceGUI::actualWaveList() {
if (dirToDelete!=-1) {
e->lockEngine([this,dirToDelete]() {
e->song.waveDir.erase(e->song.waveDir.begin()+dirToDelete);
e->checkAssetDir(e->song.waveDir,e->song.wave.size());
checkAssetDir(e->song.waveDir,e->song.wave.size());
});
}
} else {
@ -1457,7 +1457,7 @@ void FurnaceGUI::actualSampleList() {
if (dirToDelete!=-1) {
e->lockEngine([this,dirToDelete]() {
e->song.sampleDir.erase(e->song.sampleDir.begin()+dirToDelete);
e->checkAssetDir(e->song.sampleDir,e->song.sample.size());
checkAssetDir(e->song.sampleDir,e->song.sample.size());
});
}
} else {