asset directories, part 7
This commit is contained in:
parent
22638d5199
commit
160753243d
|
@ -32,6 +32,7 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
|
|||
|
||||
the format versions are:
|
||||
|
||||
- 156: Furnace dev156
|
||||
- 155: Furnace dev155
|
||||
- 154: Furnace dev154
|
||||
- 153: Furnace dev153
|
||||
|
@ -435,6 +436,10 @@ size | description
|
|||
??? | groove entries. the format is:
|
||||
| - 1 byte: length of groove
|
||||
| - 16 bytes: groove pattern
|
||||
--- | **pointers to asset directories** (>=156)
|
||||
4 | instrument directories
|
||||
4 | wavetable directories
|
||||
4 | sample directories
|
||||
```
|
||||
|
||||
# patchbay
|
||||
|
@ -526,6 +531,22 @@ clock=4000000
|
|||
stereo=true
|
||||
```
|
||||
|
||||
# asset directories (>=156)
|
||||
|
||||
also known as "folder" in the user interface.
|
||||
|
||||
```
|
||||
size | description
|
||||
-----|------------------------------------
|
||||
4 | "ADIR" block ID
|
||||
4 | size of this block
|
||||
4 | number of directories
|
||||
--- | **asset directory** (×numberOfDirs)
|
||||
STR | name (if empty, this is the uncategorized directory)
|
||||
2 | number of assets
|
||||
1?? | assets in this directory
|
||||
```
|
||||
|
||||
# instrument (>=127)
|
||||
|
||||
Furnace dev127 and higher use the new instrument format.
|
||||
|
|
|
@ -1601,14 +1601,14 @@ void DivEngine::checkAssetDir(std::vector<DivAssetDir>& dir, size_t entries) {
|
|||
}
|
||||
|
||||
// erase duplicate entry
|
||||
if (inAssetDir[j]) {
|
||||
if (inAssetDir[i.entries[j]]) {
|
||||
i.entries.erase(i.entries.begin()+j);
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
|
||||
// mark entry as present
|
||||
inAssetDir[j]=true;
|
||||
inAssetDir[i.entries[j]]=true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,8 +53,8 @@
|
|||
#define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock();
|
||||
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
|
||||
|
||||
#define DIV_VERSION "dev155"
|
||||
#define DIV_ENGINE_VERSION 155
|
||||
#define DIV_VERSION "dev156"
|
||||
#define DIV_ENGINE_VERSION 156
|
||||
// for imports
|
||||
#define DIV_VERSION_MOD 0xff01
|
||||
#define DIV_VERSION_FC 0xff02
|
||||
|
@ -523,6 +523,10 @@ class DivEngine {
|
|||
// check whether an asset directory is complete
|
||||
void checkAssetDir(std::vector<DivAssetDir>& dir, size_t entries);
|
||||
|
||||
// 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;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "dataErrors.h"
|
||||
#include "engine.h"
|
||||
#include "../ta-log.h"
|
||||
#include "instrument.h"
|
||||
|
@ -1655,6 +1656,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
unsigned int samplePtr[256];
|
||||
unsigned int subSongPtr[256];
|
||||
unsigned int sysFlagsPtr[DIV_MAX_CHIPS];
|
||||
unsigned int assetDirPtr[3];
|
||||
std::vector<int> patPtr;
|
||||
int numberOfSubSongs=0;
|
||||
char magic[5];
|
||||
|
@ -2332,6 +2334,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
if (ds.version>=156) {
|
||||
assetDirPtr[0]=reader.readI();
|
||||
assetDirPtr[1]=reader.readI();
|
||||
assetDirPtr[2]=reader.readI();
|
||||
}
|
||||
|
||||
// read system flags
|
||||
if (ds.version>=119) {
|
||||
logD("reading chip flags...");
|
||||
|
@ -2366,6 +2374,53 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
// read asset directories
|
||||
if (ds.version>=156) {
|
||||
logD("reading asset directories...");
|
||||
|
||||
if (!reader.seek(assetDirPtr[0],SEEK_SET)) {
|
||||
logE("couldn't seek to ins dir!");
|
||||
lastError=fmt::sprintf("couldn't read instrument directory");
|
||||
ds.unload();
|
||||
delete[] file;
|
||||
return false;
|
||||
}
|
||||
if (readAssetDirData(reader,ds.insDir)!=DIV_DATA_SUCCESS) {
|
||||
lastError="invalid instrument directory data!";
|
||||
ds.unload();
|
||||
delete[] file;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!reader.seek(assetDirPtr[1],SEEK_SET)) {
|
||||
logE("couldn't seek to wave dir!");
|
||||
lastError=fmt::sprintf("couldn't read wavetable directory");
|
||||
ds.unload();
|
||||
delete[] file;
|
||||
return false;
|
||||
}
|
||||
if (readAssetDirData(reader,ds.waveDir)!=DIV_DATA_SUCCESS) {
|
||||
lastError="invalid wavetable directory data!";
|
||||
ds.unload();
|
||||
delete[] file;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!reader.seek(assetDirPtr[2],SEEK_SET)) {
|
||||
logE("couldn't seek to sample dir!");
|
||||
lastError=fmt::sprintf("couldn't read sample directory");
|
||||
ds.unload();
|
||||
delete[] file;
|
||||
return false;
|
||||
}
|
||||
if (readAssetDirData(reader,ds.sampleDir)!=DIV_DATA_SUCCESS) {
|
||||
lastError="invalid sample directory data!";
|
||||
ds.unload();
|
||||
delete[] file;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// read subsongs
|
||||
if (ds.version>=95) {
|
||||
for (int i=0; i<numberOfSubSongs; i++) {
|
||||
|
@ -4843,6 +4898,61 @@ 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;
|
||||
}
|
||||
|
||||
logV("reading");
|
||||
|
||||
reader.readI(); // reserved
|
||||
|
||||
unsigned int numDirs=reader.readI();
|
||||
|
||||
for (unsigned int i=0; i<numDirs; i++) {
|
||||
DivAssetDir d;
|
||||
|
||||
d.name=reader.readString();
|
||||
unsigned short numEntries=reader.readS();
|
||||
|
||||
logV("reading %d entries for %s",numEntries,d.name);
|
||||
|
||||
for (unsigned short j=0; j<numEntries; j++) {
|
||||
d.entries.push_back(((unsigned char)reader.readC()));
|
||||
}
|
||||
|
||||
dir.push_back(d);
|
||||
}
|
||||
|
||||
return DIV_DATA_SUCCESS;
|
||||
}
|
||||
|
||||
SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||
saveLock.lock();
|
||||
std::vector<int> subSongPtr;
|
||||
|
@ -4851,7 +4961,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
std::vector<int> wavePtr;
|
||||
std::vector<int> samplePtr;
|
||||
std::vector<int> patPtr;
|
||||
size_t ptrSeek, subSongPtrSeek, sysFlagsPtrSeek, blockStartSeek, blockEndSeek;
|
||||
int assetDirPtr[3];
|
||||
size_t ptrSeek, subSongPtrSeek, sysFlagsPtrSeek, blockStartSeek, blockEndSeek, assetDirPtrSeek;
|
||||
size_t subSongIndex=0;
|
||||
DivSubSong* subSong=song.subsong[subSongIndex];
|
||||
warnings="";
|
||||
|
@ -5150,6 +5261,12 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
}
|
||||
}
|
||||
|
||||
// asset dir pointers (we'll seek here later)
|
||||
assetDirPtrSeek=w->tell();
|
||||
w->writeI(0);
|
||||
w->writeI(0);
|
||||
w->writeI(0);
|
||||
|
||||
blockEndSeek=w->tell();
|
||||
w->seek(blockStartSeek,SEEK_SET);
|
||||
w->writeI(blockEndSeek-blockStartSeek-4);
|
||||
|
@ -5237,6 +5354,14 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
w->seek(0,SEEK_END);
|
||||
}
|
||||
|
||||
/// ASSET DIRECTORIES
|
||||
assetDirPtr[0]=w->tell();
|
||||
putAssetDirData(w,song.insDir);
|
||||
assetDirPtr[1]=w->tell();
|
||||
putAssetDirData(w,song.waveDir);
|
||||
assetDirPtr[2]=w->tell();
|
||||
putAssetDirData(w,song.sampleDir);
|
||||
|
||||
/// INSTRUMENT
|
||||
for (int i=0; i<song.insLen; i++) {
|
||||
DivInstrument* ins=song.ins[i];
|
||||
|
@ -5328,6 +5453,12 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
w->writeI(sysFlagsPtr[i]);
|
||||
}
|
||||
|
||||
// asset dir pointers
|
||||
w->seek(assetDirPtrSeek,SEEK_SET);
|
||||
for (size_t i=0; i<3; i++) {
|
||||
w->writeI(assetDirPtr[i]);
|
||||
}
|
||||
|
||||
saveLock.unlock();
|
||||
return w;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue