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:
|
the format versions are:
|
||||||
|
|
||||||
|
- 156: Furnace dev156
|
||||||
- 155: Furnace dev155
|
- 155: Furnace dev155
|
||||||
- 154: Furnace dev154
|
- 154: Furnace dev154
|
||||||
- 153: Furnace dev153
|
- 153: Furnace dev153
|
||||||
|
@ -435,6 +436,10 @@ size | description
|
||||||
??? | groove entries. the format is:
|
??? | groove entries. the format is:
|
||||||
| - 1 byte: length of groove
|
| - 1 byte: length of groove
|
||||||
| - 16 bytes: groove pattern
|
| - 16 bytes: groove pattern
|
||||||
|
--- | **pointers to asset directories** (>=156)
|
||||||
|
4 | instrument directories
|
||||||
|
4 | wavetable directories
|
||||||
|
4 | sample directories
|
||||||
```
|
```
|
||||||
|
|
||||||
# patchbay
|
# patchbay
|
||||||
|
@ -526,6 +531,22 @@ clock=4000000
|
||||||
stereo=true
|
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)
|
# instrument (>=127)
|
||||||
|
|
||||||
Furnace dev127 and higher use the new instrument format.
|
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
|
// erase duplicate entry
|
||||||
if (inAssetDir[j]) {
|
if (inAssetDir[i.entries[j]]) {
|
||||||
i.entries.erase(i.entries.begin()+j);
|
i.entries.erase(i.entries.begin()+j);
|
||||||
j--;
|
j--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark entry as present
|
// 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_BEGIN_SOFT e->softLocked=true; e->isBusy.lock();
|
||||||
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
|
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "dev155"
|
#define DIV_VERSION "dev156"
|
||||||
#define DIV_ENGINE_VERSION 155
|
#define DIV_ENGINE_VERSION 156
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
@ -523,6 +523,10 @@ class DivEngine {
|
||||||
// check whether an asset directory is complete
|
// check whether an asset directory is complete
|
||||||
void checkAssetDir(std::vector<DivAssetDir>& dir, size_t entries);
|
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
|
// add every export method here
|
||||||
friend class DivROMExport;
|
friend class DivROMExport;
|
||||||
friend class DivExportAmigaValidation;
|
friend class DivExportAmigaValidation;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "dataErrors.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "../ta-log.h"
|
#include "../ta-log.h"
|
||||||
#include "instrument.h"
|
#include "instrument.h"
|
||||||
|
@ -1655,6 +1656,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
unsigned int samplePtr[256];
|
unsigned int samplePtr[256];
|
||||||
unsigned int subSongPtr[256];
|
unsigned int subSongPtr[256];
|
||||||
unsigned int sysFlagsPtr[DIV_MAX_CHIPS];
|
unsigned int sysFlagsPtr[DIV_MAX_CHIPS];
|
||||||
|
unsigned int assetDirPtr[3];
|
||||||
std::vector<int> patPtr;
|
std::vector<int> patPtr;
|
||||||
int numberOfSubSongs=0;
|
int numberOfSubSongs=0;
|
||||||
char magic[5];
|
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
|
// read system flags
|
||||||
if (ds.version>=119) {
|
if (ds.version>=119) {
|
||||||
logD("reading chip flags...");
|
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
|
// read subsongs
|
||||||
if (ds.version>=95) {
|
if (ds.version>=95) {
|
||||||
for (int i=0; i<numberOfSubSongs; i++) {
|
for (int i=0; i<numberOfSubSongs; i++) {
|
||||||
|
@ -4843,6 +4898,61 @@ struct PatToWrite {
|
||||||
pat(p) {}
|
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) {
|
SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
std::vector<int> subSongPtr;
|
std::vector<int> subSongPtr;
|
||||||
|
@ -4851,7 +4961,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||||
std::vector<int> wavePtr;
|
std::vector<int> wavePtr;
|
||||||
std::vector<int> samplePtr;
|
std::vector<int> samplePtr;
|
||||||
std::vector<int> patPtr;
|
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;
|
size_t subSongIndex=0;
|
||||||
DivSubSong* subSong=song.subsong[subSongIndex];
|
DivSubSong* subSong=song.subsong[subSongIndex];
|
||||||
warnings="";
|
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();
|
blockEndSeek=w->tell();
|
||||||
w->seek(blockStartSeek,SEEK_SET);
|
w->seek(blockStartSeek,SEEK_SET);
|
||||||
w->writeI(blockEndSeek-blockStartSeek-4);
|
w->writeI(blockEndSeek-blockStartSeek-4);
|
||||||
|
@ -5237,6 +5354,14 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||||
w->seek(0,SEEK_END);
|
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
|
/// INSTRUMENT
|
||||||
for (int i=0; i<song.insLen; i++) {
|
for (int i=0; i<song.insLen; i++) {
|
||||||
DivInstrument* ins=song.ins[i];
|
DivInstrument* ins=song.ins[i];
|
||||||
|
@ -5328,6 +5453,12 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||||
w->writeI(sysFlagsPtr[i]);
|
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();
|
saveLock.unlock();
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue