prepare for pattern optimization
This commit is contained in:
parent
976e193309
commit
edddff8431
|
@ -2916,6 +2916,10 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
ds.insLen=(int)ds.ins.size();
|
ds.insLen=(int)ds.ins.size();
|
||||||
|
|
||||||
|
// optimize
|
||||||
|
ds.subsong[0]->optimizePatterns();
|
||||||
|
ds.subsong[0]->rearrangePatterns();
|
||||||
|
|
||||||
if (active) quitDispatch();
|
if (active) quitDispatch();
|
||||||
BUSY_BEGIN_SOFT;
|
BUSY_BEGIN_SOFT;
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
#include "../ta-log.h"
|
||||||
|
|
||||||
static DivPattern emptyPat;
|
static DivPattern emptyPat;
|
||||||
|
|
||||||
|
@ -40,6 +41,44 @@ DivPattern* DivChannelData::getPattern(int index, bool create) {
|
||||||
return data[index];
|
return data[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<int,int>> DivChannelData::optimize() {
|
||||||
|
std::vector<std::pair<int,int>> ret;
|
||||||
|
for (int i=0; i<256; i++) {
|
||||||
|
if (data[i]!=NULL) {
|
||||||
|
// compare
|
||||||
|
for (int j=0; j<256; j++) {
|
||||||
|
if (j==i) continue;
|
||||||
|
if (data[j]==NULL) continue;
|
||||||
|
if (memcmp(data[i]->data,data[j]->data,256*32*sizeof(short))==0) {
|
||||||
|
delete data[j];
|
||||||
|
data[j]=NULL;
|
||||||
|
logV("%d == %d",i,j);
|
||||||
|
ret.push_back(std::pair<int,int>(j,i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<int,int>> DivChannelData::rearrange() {
|
||||||
|
std::vector<std::pair<int,int>> ret;
|
||||||
|
for (int i=0; i<256; i++) {
|
||||||
|
if (data[i]==NULL) {
|
||||||
|
for (int j=i; j<256; j++) {
|
||||||
|
if (data[j]!=NULL) {
|
||||||
|
data[i]=data[j];
|
||||||
|
data[j]=NULL;
|
||||||
|
logV("%d -> %d",j,i);
|
||||||
|
ret.push_back(std::pair<int,int>(j,i));
|
||||||
|
if (++i>=256) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void DivChannelData::wipePatterns() {
|
void DivChannelData::wipePatterns() {
|
||||||
for (int i=0; i<256; i++) {
|
for (int i=0; i<256; i++) {
|
||||||
if (data[i]!=NULL) {
|
if (data[i]!=NULL) {
|
||||||
|
@ -54,81 +93,6 @@ void DivPattern::copyOn(DivPattern* dest) {
|
||||||
memcpy(dest->data,data,sizeof(data));
|
memcpy(dest->data,data,sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
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():
|
DivChannelData::DivChannelData():
|
||||||
effectCols(1) {
|
effectCols(1) {
|
||||||
memset(data,0,256*sizeof(void*));
|
memset(data,0,256*sizeof(void*));
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "safeReader.h"
|
#include "safeReader.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct DivPattern {
|
struct DivPattern {
|
||||||
String name;
|
String name;
|
||||||
|
@ -28,14 +29,6 @@ struct DivPattern {
|
||||||
* @param dest the destination pattern.
|
* @param dest the destination pattern.
|
||||||
*/
|
*/
|
||||||
void copyOn(DivPattern* dest);
|
void copyOn(DivPattern* dest);
|
||||||
|
|
||||||
/**
|
|
||||||
* don't use yet!
|
|
||||||
* @param len the pattern length
|
|
||||||
* @param fxRows number of effect ...columns
|
|
||||||
* @return a SafeReader.
|
|
||||||
*/
|
|
||||||
SafeReader* compile(int len=256, int fxRows=1);
|
|
||||||
DivPattern();
|
DivPattern();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,6 +52,20 @@ struct DivChannelData {
|
||||||
*/
|
*/
|
||||||
DivPattern* getPattern(int index, bool create);
|
DivPattern* getPattern(int index, bool create);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optimize pattern data.
|
||||||
|
* not thread-safe! use a mutex!
|
||||||
|
* @return a list of From -> To pairs
|
||||||
|
*/
|
||||||
|
std::vector<std::pair<int,int>> optimize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* re-arrange NULLs.
|
||||||
|
* not thread-safe! use a mutex!
|
||||||
|
* @return a list of From -> To pairs
|
||||||
|
*/
|
||||||
|
std::vector<std::pair<int,int>> rearrange();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* destroy all patterns on this DivChannelData.
|
* destroy all patterns on this DivChannelData.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "song.h"
|
#include "song.h"
|
||||||
|
#include "../ta-log.h"
|
||||||
|
|
||||||
void DivSubSong::clearData() {
|
void DivSubSong::clearData() {
|
||||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||||
|
@ -28,6 +29,34 @@ void DivSubSong::clearData() {
|
||||||
ordersLen=1;
|
ordersLen=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivSubSong::optimizePatterns() {
|
||||||
|
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||||
|
logD("optimizing channel %d...",i);
|
||||||
|
std::vector<std::pair<int,int>> clearOuts=pat[i].optimize();
|
||||||
|
for (auto& j: clearOuts) {
|
||||||
|
for (int k=0; k<256; k++) {
|
||||||
|
if (orders.ord[i][k]==j.first) {
|
||||||
|
orders.ord[i][k]=j.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivSubSong::rearrangePatterns() {
|
||||||
|
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||||
|
logD("re-arranging channel %d...",i);
|
||||||
|
std::vector<std::pair<int,int>> clearOuts=pat[i].rearrange();
|
||||||
|
for (auto& j: clearOuts) {
|
||||||
|
for (int k=0; k<256; k++) {
|
||||||
|
if (orders.ord[i][k]==j.first) {
|
||||||
|
orders.ord[i][k]=j.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DivSong::clearSongData() {
|
void DivSong::clearSongData() {
|
||||||
for (DivSubSong* i: subsong) {
|
for (DivSubSong* i: subsong) {
|
||||||
i->clearData();
|
i->clearData();
|
||||||
|
|
|
@ -138,6 +138,8 @@ struct DivSubSong {
|
||||||
String chanShortName[DIV_MAX_CHANS];
|
String chanShortName[DIV_MAX_CHANS];
|
||||||
|
|
||||||
void clearData();
|
void clearData();
|
||||||
|
void optimizePatterns();
|
||||||
|
void rearrangePatterns();
|
||||||
|
|
||||||
DivSubSong():
|
DivSubSong():
|
||||||
hilightA(4),
|
hilightA(4),
|
||||||
|
|
Loading…
Reference in a new issue