prepare for multiple chip support

This commit is contained in:
tildearrow 2022-01-08 01:57:37 -05:00
parent 6aab9f01cf
commit 121a9b2cb8
9 changed files with 35 additions and 29 deletions

View file

@ -141,6 +141,10 @@ int DivEngine::getChannelCount(DivSystem sys) {
return 0; return 0;
} }
int DivEngine::getTotalChannelCount() {
return chans;
}
const char* DivEngine::getSystemName(DivSystem sys) { const char* DivEngine::getSystemName(DivSystem sys) {
switch (sys) { switch (sys) {
case DIV_SYSTEM_NULL: case DIV_SYSTEM_NULL:
@ -1579,7 +1583,7 @@ void DivEngine::stop() {
} }
void DivEngine::reset() { void DivEngine::reset() {
for (int i=0; i<17; i++) { for (int i=0; i<DIV_MAX_CHANS; i++) {
chan[i]=DivChannelState(); chan[i]=DivChannelState();
chan[i].volMax=(dispatch->dispatch(DivCommand(DIV_CMD_GET_VOLMAX,i))<<8)|0xff; chan[i].volMax=(dispatch->dispatch(DivCommand(DIV_CMD_GET_VOLMAX,i))<<8)|0xff;
chan[i].volume=chan[i].volMax; chan[i].volume=chan[i].volMax;
@ -2132,7 +2136,7 @@ void DivEngine::quitDispatch() {
totalCmds=0; totalCmds=0;
lastCmds=0; lastCmds=0;
cmdsPerSecond=0; cmdsPerSecond=0;
for (int i=0; i<17; i++) { for (int i=0; i<DIV_MAX_CHANS; i++) {
isMuted[i]=0; isMuted[i]=0;
} }
isBusy.unlock(); isBusy.unlock();
@ -2281,7 +2285,7 @@ bool DivEngine::init(String outName) {
vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI)); vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI));
} }
for (int i=0; i<17; i++) { for (int i=0; i<DIV_MAX_CHANS; i++) {
isMuted[i]=0; isMuted[i]=0;
} }

View file

@ -12,7 +12,6 @@
// TODO; // TODO;
// - prepare for multi-chip support // - prepare for multi-chip support
// - implement the .fur format // - implement the .fur format
// - increase all 17 fields to 128 or more
#define DIV_VERSION "0.2.2" #define DIV_VERSION "0.2.2"
#define DIV_ENGINE_VERSION 14 #define DIV_ENGINE_VERSION 14
@ -112,11 +111,11 @@ class DivEngine {
unsigned char extValue; unsigned char extValue;
unsigned char speed1, speed2; unsigned char speed1, speed2;
DivStatusView view; DivStatusView view;
DivChannelState chan[17]; DivChannelState chan[DIV_MAX_CHANS];
DivAudioEngines audioEngine; DivAudioEngines audioEngine;
std::map<String,String> conf; std::map<String,String> conf;
std::queue<DivNoteEvent> pendingNotes; std::queue<DivNoteEvent> pendingNotes;
bool isMuted[17]; bool isMuted[DIV_MAX_CHANS];
std::mutex isBusy; std::mutex isBusy;
String configPath; String configPath;
String configFile; String configFile;
@ -211,7 +210,7 @@ class DivEngine {
// get sys channel count // get sys channel count
int getChannelCount(DivSystem sys); int getChannelCount(DivSystem sys);
// TODO: get channel count // get channel count
int getTotalChannelCount(); int getTotalChannelCount();
// get channel type // get channel type

View file

@ -1,7 +1,7 @@
struct DivOrders { struct DivOrders {
unsigned char ord[32][128]; unsigned char ord[DIV_MAX_CHANS][128];
DivOrders() { DivOrders() {
memset(ord,0,32*128); memset(ord,0,DIV_MAX_CHANS*128);
} }
}; };

View file

@ -76,7 +76,7 @@ void DivPlatformDummy::reset() {
int DivPlatformDummy::init(DivEngine* p, int channels, int sugRate, bool pal) { int DivPlatformDummy::init(DivEngine* p, int channels, int sugRate, bool pal) {
parent=p; parent=p;
skipRegisterWrites=false; skipRegisterWrites=false;
for (int i=0; i<17; i++) { for (int i=0; i<DIV_MAX_CHANS; i++) {
isMuted[i]=false; isMuted[i]=false;
} }
rate=65536; rate=65536;

View file

@ -12,8 +12,8 @@ class DivPlatformDummy: public DivDispatch {
signed char amp; signed char amp;
Channel(): freq(0), baseFreq(0), pitch(0), pos(0), active(false), freqChanged(false), vol(0), amp(64) {} Channel(): freq(0), baseFreq(0), pitch(0), pos(0), active(false), freqChanged(false), vol(0), amp(64) {}
}; };
Channel chan[17]; Channel chan[128];
bool isMuted[17]; bool isMuted[128];
unsigned char chans; unsigned char chans;
public: public:
void acquire(short* bufL, short* bufR, size_t start, size_t len); void acquire(short* bufL, short* bufR, size_t start, size_t len);

View file

@ -16,7 +16,7 @@ void DivSong::unload() {
} }
sample.clear(); sample.clear();
for (int i=0; i<17; i++) { for (int i=0; i<DIV_MAX_CHANS; i++) {
pat[i].wipePatterns(); pat[i].wipePatterns();
} }
} }

View file

@ -1,5 +1,8 @@
#include <stdio.h> #include <stdio.h>
#include <vector> #include <vector>
#define DIV_MAX_CHANS 128
#include "../ta-utils.h" #include "../ta-utils.h"
#include "orders.h" #include "orders.h"
#include "instrument.h" #include "instrument.h"
@ -94,7 +97,7 @@ struct DivSong {
DivOrders orders; DivOrders orders;
std::vector<DivInstrument*> ins; std::vector<DivInstrument*> ins;
DivChannelData pat[17]; DivChannelData pat[DIV_MAX_CHANS];
std::vector<DivWavetable*> wave; std::vector<DivWavetable*> wave;
std::vector<DivSample*> sample; std::vector<DivSample*> sample;

View file

@ -382,7 +382,7 @@ void FurnaceGUI::drawOrders() {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(1.0f*dpiScale,1.0f*dpiScale)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(1.0f*dpiScale,1.0f*dpiScale));
ImGui::Columns(2,NULL,false); ImGui::Columns(2,NULL,false);
ImGui::SetColumnWidth(-1,regionX-24.0f*dpiScale); ImGui::SetColumnWidth(-1,regionX-24.0f*dpiScale);
if (ImGui::BeginTable("OrdersTable",1+e->getChannelCount(e->song.system),ImGuiTableFlags_ScrollY)) { if (ImGui::BeginTable("OrdersTable",1+e->getTotalChannelCount(),ImGuiTableFlags_ScrollY)) {
ImGui::PushFont(patFont); ImGui::PushFont(patFont);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,prevSpacing); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,prevSpacing);
ImGui::TableSetupScrollFreeze(0,1); ImGui::TableSetupScrollFreeze(0,1);
@ -395,7 +395,7 @@ void FurnaceGUI::drawOrders() {
ImGui::TableNextRow(0,lineHeight); ImGui::TableNextRow(0,lineHeight);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_ROW_INDEX]); ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_PATTERN_ROW_INDEX]);
for (int i=0; i<e->getChannelCount(e->song.system); i++) { for (int i=0; i<e->getTotalChannelCount(); i++) {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%s",e->getChannelShortName(i)); ImGui::Text("%s",e->getChannelShortName(i));
} }
@ -410,14 +410,14 @@ void FurnaceGUI::drawOrders() {
e->setOrder(i); e->setOrder(i);
} }
ImGui::PopStyleColor(); ImGui::PopStyleColor();
for (int j=0; j<e->getChannelCount(e->song.system); j++) { for (int j=0; j<e->getTotalChannelCount(); j++) {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
snprintf(selID,64,"%.2x##O_%.2x_%.2x",e->song.orders.ord[j][i],j,i); snprintf(selID,64,"%.2x##O_%.2x_%.2x",e->song.orders.ord[j][i],j,i);
if (ImGui::Selectable(selID)) { if (ImGui::Selectable(selID)) {
if (e->getOrder()==i) { if (e->getOrder()==i) {
prepareUndo(GUI_ACTION_CHANGE_ORDER); prepareUndo(GUI_ACTION_CHANGE_ORDER);
if (changeAllOrders) { if (changeAllOrders) {
for (int k=0; k<e->getChannelCount(e->song.system); k++) { for (int k=0; k<e->getTotalChannelCount(); k++) {
if (e->song.orders.ord[k][i]<0x7f) e->song.orders.ord[k][i]++; if (e->song.orders.ord[k][i]<0x7f) e->song.orders.ord[k][i]++;
} }
} else { } else {
@ -432,7 +432,7 @@ void FurnaceGUI::drawOrders() {
if (e->getOrder()==i) { if (e->getOrder()==i) {
prepareUndo(GUI_ACTION_CHANGE_ORDER); prepareUndo(GUI_ACTION_CHANGE_ORDER);
if (changeAllOrders) { if (changeAllOrders) {
for (int k=0; k<e->getChannelCount(e->song.system); k++) { for (int k=0; k<e->getTotalChannelCount(); k++) {
if (e->song.orders.ord[k][i]>0) e->song.orders.ord[k][i]--; if (e->song.orders.ord[k][i]>0) e->song.orders.ord[k][i]--;
} }
} else { } else {
@ -1088,7 +1088,7 @@ void FurnaceGUI::drawPattern() {
ImGui::PushFont(patFont); ImGui::PushFont(patFont);
unsigned char ord=e->isPlaying()?oldOrder:e->getOrder(); unsigned char ord=e->isPlaying()?oldOrder:e->getOrder();
oldOrder=e->getOrder(); oldOrder=e->getOrder();
int chans=e->getChannelCount(e->song.system); int chans=e->getTotalChannelCount();
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(0.0f,0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(0.0f,0.0f));
ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_SELECTION]); ImGui::PushStyleColor(ImGuiCol_Header,uiColors[GUI_COLOR_PATTERN_SELECTION]);
ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_SELECTION_HOVER]); ImGui::PushStyleColor(ImGuiCol_HeaderHovered,uiColors[GUI_COLOR_PATTERN_SELECTION_HOVER]);
@ -1670,8 +1670,8 @@ void FurnaceGUI::moveCursor(int x, int y) {
for (int i=0; i<x; i++) { for (int i=0; i<x; i++) {
if (++cursor.xFine>=3+e->song.pat[cursor.xCoarse].effectRows*2) { if (++cursor.xFine>=3+e->song.pat[cursor.xCoarse].effectRows*2) {
cursor.xFine=0; cursor.xFine=0;
if (++cursor.xCoarse>=e->getChannelCount(e->song.system)) { if (++cursor.xCoarse>=e->getTotalChannelCount()) {
cursor.xCoarse=e->getChannelCount(e->song.system)-1; cursor.xCoarse=e->getTotalChannelCount()-1;
cursor.xFine=2+e->song.pat[cursor.xCoarse].effectRows*2; cursor.xFine=2+e->song.pat[cursor.xCoarse].effectRows*2;
} }
} }
@ -1724,7 +1724,7 @@ void FurnaceGUI::prepareUndo(ActionType action) {
case GUI_ACTION_PATTERN_PUSH: case GUI_ACTION_PATTERN_PUSH:
case GUI_ACTION_PATTERN_CUT: case GUI_ACTION_PATTERN_CUT:
case GUI_ACTION_PATTERN_PASTE: case GUI_ACTION_PATTERN_PASTE:
for (int i=0; i<17; i++) { for (int i=0; i<e->getTotalChannelCount(); i++) {
memcpy(oldPat[i],e->song.pat[i].getPattern(e->song.orders.ord[i][order],false),sizeof(DivPattern)); memcpy(oldPat[i],e->song.pat[i].getPattern(e->song.orders.ord[i][order],false),sizeof(DivPattern));
} }
break; break;
@ -1772,7 +1772,7 @@ void FurnaceGUI::makeUndo(ActionType action) {
case GUI_ACTION_PATTERN_PUSH: case GUI_ACTION_PATTERN_PUSH:
case GUI_ACTION_PATTERN_CUT: case GUI_ACTION_PATTERN_CUT:
case GUI_ACTION_PATTERN_PASTE: case GUI_ACTION_PATTERN_PASTE:
for (int i=0; i<17; i++) { for (int i=0; i<e->getTotalChannelCount(); i++) {
DivPattern* p=e->song.pat[i].getPattern(e->song.orders.ord[i][order],false); DivPattern* p=e->song.pat[i].getPattern(e->song.orders.ord[i][order],false);
for (int j=0; j<e->song.patLen; j++) { for (int j=0; j<e->song.patLen; j++) {
for (int k=0; k<16; k++) { for (int k=0; k<16; k++) {
@ -1802,7 +1802,7 @@ void FurnaceGUI::doSelectAll() {
if (selStart.y==0 && selEnd.y==e->song.patLen-1) { // select entire pattern if (selStart.y==0 && selEnd.y==e->song.patLen-1) { // select entire pattern
selStart.xCoarse=0; selStart.xCoarse=0;
selStart.xFine=0; selStart.xFine=0;
selEnd.xCoarse=e->getChannelCount(e->song.system)-1; selEnd.xCoarse=e->getTotalChannelCount()-1;
selEnd.xFine=2+e->song.pat[selEnd.xCoarse].effectRows*2; selEnd.xFine=2+e->song.pat[selEnd.xCoarse].effectRows*2;
} else { // select entire column } else { // select entire column
selStart.y=0; selStart.y=0;
@ -2008,7 +2008,7 @@ void FurnaceGUI::doPaste() {
String& line=data[i]; String& line=data[i];
while (charPos<line.size() && iCoarse<e->getChannelCount(e->song.system)) { while (charPos<line.size() && iCoarse<e->getTotalChannelCount()) {
DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true); DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true);
if (line[charPos]=='|') { if (line[charPos]=='|') {
iCoarse++; iCoarse++;
@ -3009,7 +3009,7 @@ bool FurnaceGUI::init() {
updateWindowTitle(); updateWindowTitle();
for (int i=0; i<17; i++) { for (int i=0; i<DIV_MAX_CHANS; i++) {
oldPat[i]=new DivPattern; oldPat[i]=new DivPattern;
} }
return true; return true;
@ -3025,7 +3025,7 @@ bool FurnaceGUI::finish() {
e->setConf("lastDir",workingDir); e->setConf("lastDir",workingDir);
for (int i=0; i<17; i++) { for (int i=0; i<DIV_MAX_CHANS; i++) {
delete oldPat[i]; delete oldPat[i];
} }
return true; return true;

View file

@ -206,7 +206,7 @@ class FurnaceGUI {
DivSystem oldSystem; DivSystem oldSystem;
int oldOrdersLen; int oldOrdersLen;
DivOrders oldOrders; DivOrders oldOrders;
DivPattern* oldPat[17]; DivPattern* oldPat[128];
std::deque<UndoStep> undoHist; std::deque<UndoStep> undoHist;
std::deque<UndoStep> redoHist; std::deque<UndoStep> redoHist;