mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-31 20:11:29 +00:00
prepare for eventual export
This commit is contained in:
parent
499af535da
commit
12236248dd
21 changed files with 137 additions and 3 deletions
|
@ -2,6 +2,7 @@
|
|||
#define _DISPATCH_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
|
||||
#define ONE_SEMITONE 2200
|
||||
|
||||
|
@ -98,15 +99,27 @@ struct DivDelayedCommand {
|
|||
DivCommand cmd;
|
||||
};
|
||||
|
||||
struct DivRegWrite {
|
||||
/**
|
||||
* an address of 0xffffff00 indicates a Furnace specific command.
|
||||
* the following addresses are available:
|
||||
* - 0xffffff00: start sample playback
|
||||
* - data is the sample number
|
||||
*/
|
||||
unsigned int addr;
|
||||
unsigned char val;
|
||||
};
|
||||
|
||||
class DivEngine;
|
||||
|
||||
class DivDispatch {
|
||||
protected:
|
||||
DivEngine* parent;
|
||||
std::vector<DivRegWrite> regWrites;
|
||||
/**
|
||||
* please honor this variable if needed.
|
||||
* please honor these variables if needed.
|
||||
*/
|
||||
bool skipRegisterWrites;
|
||||
bool skipRegisterWrites, dumpWrites;
|
||||
public:
|
||||
/**
|
||||
* the rate the samples are provided.
|
||||
|
@ -208,6 +221,16 @@ class DivDispatch {
|
|||
*/
|
||||
virtual void forceIns();
|
||||
|
||||
/**
|
||||
* enable register dumping.
|
||||
*/
|
||||
void toggleRegisterDump(bool enable);
|
||||
|
||||
/**
|
||||
* get register writes.
|
||||
*/
|
||||
std::vector<DivRegWrite>& getRegisterWrites();
|
||||
|
||||
/**
|
||||
* initialize this DivDispatch.
|
||||
* @param parent the parent DivEngine.
|
||||
|
|
|
@ -189,6 +189,11 @@ class DivEngine {
|
|||
SafeWriter* saveDMF();
|
||||
// save as .fur.
|
||||
SafeWriter* saveFur();
|
||||
// build a ROM file (TODO).
|
||||
// specify system to build ROM for.
|
||||
SafeWriter* buildROM(int sys);
|
||||
// dump to VGM (TODO).
|
||||
SafeWriter* saveVGM();
|
||||
|
||||
// save config
|
||||
bool saveConf();
|
||||
|
|
|
@ -30,6 +30,81 @@ void DivChannelData::wipePatterns() {
|
|||
}
|
||||
}
|
||||
|
||||
SafeReader* DivPattern::compile(int len, int fxRows) {
|
||||
SafeWriter w;
|
||||
w.init();
|
||||
short lastNote, lastOctave, lastInstr, lastVolume, lastEffect[8], lastEffectVal[8];
|
||||
unsigned char rows=0;
|
||||
|
||||
lastNote=0;
|
||||
lastOctave=0;
|
||||
lastInstr=-1;
|
||||
lastVolume=-1;
|
||||
memset(lastEffect,-1,8*sizeof(short));
|
||||
memset(lastEffectVal,-1,8*sizeof(short));
|
||||
|
||||
for (int i=0; i<len; i++) {
|
||||
unsigned char mask=0;
|
||||
if (data[i][0]!=-1) {
|
||||
lastNote=data[i][0];
|
||||
lastOctave=data[i][1];
|
||||
mask|=128;
|
||||
}
|
||||
if (data[i][2]!=-1 && data[i][2]!=lastInstr) {
|
||||
lastInstr=data[i][2];
|
||||
mask|=32;
|
||||
}
|
||||
if (data[i][3]!=-1 && data[i][3]!=lastVolume) {
|
||||
lastVolume=data[i][3];
|
||||
mask|=64;
|
||||
}
|
||||
for (int j=0; j<fxRows; j++) {
|
||||
if (data[i][4+(j<<1)]!=-1) {
|
||||
lastEffect[j]=data[i][4+(j<<1)];
|
||||
lastEffectVal[j]=data[i][5+(j<<1)];
|
||||
mask=(mask&0xf8)|j;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mask) {
|
||||
rows++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rows!=0) {
|
||||
w.writeC(rows);
|
||||
}
|
||||
rows=1;
|
||||
|
||||
w.writeC(mask);
|
||||
if (mask&128) {
|
||||
if (lastNote==100) {
|
||||
w.writeC(-128);
|
||||
} else {
|
||||
w.writeC(lastNote+(lastOctave*12));
|
||||
}
|
||||
}
|
||||
if (mask&64) {
|
||||
w.writeC(lastVolume);
|
||||
}
|
||||
if (mask&32) {
|
||||
w.writeC(lastInstr);
|
||||
}
|
||||
for (int j=0; j<(mask&7); j++) {
|
||||
w.writeC(lastEffect[j]);
|
||||
if (lastEffectVal[j]==-1) {
|
||||
w.writeC(0);
|
||||
} else {
|
||||
w.writeC(lastEffectVal[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
w.writeC(rows);
|
||||
w.writeC(0);
|
||||
|
||||
return w.toReader();
|
||||
}
|
||||
|
||||
DivChannelData::DivChannelData():
|
||||
effectRows(1) {
|
||||
memset(data,0,128*sizeof(void*));
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "safeReader.h"
|
||||
|
||||
struct DivPattern {
|
||||
short data[256][16];
|
||||
SafeReader* compile(int len=256, int fxRows=1);
|
||||
DivPattern();
|
||||
};
|
||||
|
||||
|
|
|
@ -54,6 +54,14 @@ void DivDispatch::forceIns() {
|
|||
|
||||
}
|
||||
|
||||
void DivDispatch::toggleRegisterDump(bool enable) {
|
||||
dumpWrites=enable;
|
||||
}
|
||||
|
||||
std::vector<DivRegWrite>& DivDispatch::getRegisterWrites() {
|
||||
return regWrites;
|
||||
}
|
||||
|
||||
int DivDispatch::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@ void DivPlatformAmiga::setPAL(bool pal) {
|
|||
|
||||
int DivPlatformAmiga::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<4; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -473,6 +473,7 @@ void DivPlatformArcade::setYMFM(bool use) {
|
|||
|
||||
int DivPlatformArcade::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<13; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -318,6 +318,7 @@ void DivPlatformAY8910::setPAL(bool pal) {
|
|||
|
||||
int DivPlatformAY8910::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<3; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -356,6 +356,7 @@ void DivPlatformAY8930::setPAL(bool pal) {
|
|||
|
||||
int DivPlatformAY8930::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<3; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -351,6 +351,7 @@ void DivPlatformC64::setPAL(bool pal) {
|
|||
|
||||
int DivPlatformC64::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<3; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -75,6 +75,7 @@ void DivPlatformDummy::reset() {
|
|||
|
||||
int DivPlatformDummy::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -328,6 +328,7 @@ int DivPlatformGB::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
|||
isMuted[i]=false;
|
||||
}
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
rate=262144;
|
||||
gb=new GB_gameboy_t;
|
||||
|
|
|
@ -437,6 +437,7 @@ void DivPlatformGenesis::setPAL(bool pal) {
|
|||
|
||||
int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<10; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -332,6 +332,7 @@ void DivPlatformNES::notifyInsDeletion(void* ins) {
|
|||
|
||||
int DivPlatformNES::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<5; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -329,6 +329,7 @@ void DivPlatformPCE::setPAL(bool pal) {
|
|||
|
||||
int DivPlatformPCE::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<6; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -308,6 +308,7 @@ void DivPlatformSAA1099::setPAL(bool pal) {
|
|||
|
||||
int DivPlatformSAA1099::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<6; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -209,6 +209,7 @@ void DivPlatformSMS::setPAL(bool pal) {
|
|||
|
||||
int DivPlatformSMS::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<4; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -253,6 +253,7 @@ void DivPlatformTIA::setPAL(bool pal) {
|
|||
|
||||
int DivPlatformTIA::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<2; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -597,6 +597,7 @@ void DivPlatformYM2610::notifyInsDeletion(void* ins) {
|
|||
|
||||
int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, bool pal) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<13; i++) {
|
||||
isMuted[i]=false;
|
||||
|
|
|
@ -92,9 +92,13 @@ void SafeWriter::init() {
|
|||
operative=true;
|
||||
}
|
||||
|
||||
SafeReader* SafeWriter::toReader() {
|
||||
return new SafeReader(buf,len);
|
||||
}
|
||||
|
||||
void SafeWriter::finish() {
|
||||
if (!operative) return;
|
||||
delete[] buf;
|
||||
buf=NULL;
|
||||
operative=false;
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "safeReader.h"
|
||||
#include "../ta-utils.h"
|
||||
|
||||
class SafeWriter {
|
||||
|
@ -38,6 +39,7 @@ class SafeWriter {
|
|||
int writeString(String val, bool pascal);
|
||||
|
||||
void init();
|
||||
SafeReader* toReader();
|
||||
void finish();
|
||||
|
||||
SafeWriter():
|
||||
|
|
Loading…
Reference in a new issue