move asset dir functions to another file
and get them out of the engine
This commit is contained in:
parent
2ff3def8f8
commit
2f25acd017
8 changed files with 210 additions and 156 deletions
|
|
@ -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
152
src/engine/assetDir.cpp
Normal 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
52
src/engine/assetDir.h
Normal 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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue