untested saving code and memory leak fix
This commit is contained in:
parent
2879b5e4d0
commit
ebb28d912b
|
@ -89,10 +89,13 @@ src/engine/platform/ym2610Interface.cpp
|
|||
|
||||
src/engine/blip_buf.c
|
||||
src/engine/safeReader.cpp
|
||||
src/engine/safeWriter.cpp
|
||||
src/engine/engine.cpp
|
||||
src/engine/macroInt.cpp
|
||||
src/engine/pattern.cpp
|
||||
src/engine/playback.cpp
|
||||
src/engine/sample.cpp
|
||||
src/engine/song.cpp
|
||||
src/engine/platform/abstract.cpp
|
||||
src/engine/platform/genesis.cpp
|
||||
src/engine/platform/genesisext.cpp
|
||||
|
|
|
@ -805,6 +805,7 @@ bool DivEngine::load(void* f, size_t slen) {
|
|||
}
|
||||
}
|
||||
|
||||
song.unload();
|
||||
song=ds;
|
||||
chans=getChannelCount(song.system);
|
||||
renderSamples();
|
||||
|
@ -815,166 +816,162 @@ bool DivEngine::load(void* f, size_t slen) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#define ERR_CHECK(x) x; if (ferror(f)) return false;
|
||||
|
||||
bool DivEngine::save(FILE* f) {
|
||||
SafeWriter* DivEngine::save() {
|
||||
SafeWriter* w=new SafeWriter;
|
||||
w->init();
|
||||
// write magic
|
||||
ERR_CHECK(fwrite(DIV_DMF_MAGIC,1,16,f));
|
||||
w->write(DIV_DMF_MAGIC,16);
|
||||
// version
|
||||
ERR_CHECK(fputc(24,f));
|
||||
ERR_CHECK(fputc(systemToFile(song.system),f));
|
||||
w->writeC(24);
|
||||
w->writeC(systemToFile(song.system));
|
||||
|
||||
// song info
|
||||
ERR_CHECK(fputc(song.name.size(),f));
|
||||
ERR_CHECK(fwrite(song.name.c_str(),1,song.name.size(),f));
|
||||
ERR_CHECK(fputc(song.author.size(),f));
|
||||
ERR_CHECK(fwrite(song.author.c_str(),1,song.author.size(),f));
|
||||
ERR_CHECK(fputc(song.hilightA,f));
|
||||
ERR_CHECK(fputc(song.hilightB,f));
|
||||
w->writeString(song.name,true);
|
||||
w->writeString(song.author,true);
|
||||
w->writeC(song.hilightA);
|
||||
w->writeC(song.hilightB);
|
||||
|
||||
ERR_CHECK(fputc(song.timeBase,f));
|
||||
ERR_CHECK(fputc(song.speed1,f));
|
||||
ERR_CHECK(fputc(song.speed2,f));
|
||||
ERR_CHECK(fputc(song.pal,f));
|
||||
ERR_CHECK(fputc(song.customTempo,f));
|
||||
w->writeC(song.timeBase);
|
||||
w->writeC(song.speed1);
|
||||
w->writeC(song.speed2);
|
||||
w->writeC(song.pal);
|
||||
w->writeC(song.customTempo);
|
||||
char customHz[4];
|
||||
memset(customHz,0,4);
|
||||
snprintf(customHz,4,"%d",song.hz);
|
||||
ERR_CHECK(fwrite(customHz,1,3,f));
|
||||
ERR_CHECK(fwrite(&song.patLen,4,1,f));
|
||||
ERR_CHECK(fputc(song.ordersLen,f));
|
||||
w->write(customHz,3);
|
||||
w->writeI(song.patLen);
|
||||
w->writeC(song.ordersLen);
|
||||
|
||||
for (int i=0; i<getChannelCount(song.system); i++) {
|
||||
for (int j=0; j<song.ordersLen; j++) {
|
||||
ERR_CHECK(fputc(song.orders.ord[i][j],f));
|
||||
w->writeC(song.orders.ord[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
ERR_CHECK(fputc(song.ins.size(),f));
|
||||
w->writeC(song.ins.size());
|
||||
for (DivInstrument* i: song.ins) {
|
||||
ERR_CHECK(fputc(i->name.size(),f));
|
||||
ERR_CHECK(fwrite(i->name.c_str(),1,i->name.size(),f));
|
||||
ERR_CHECK(fputc(i->mode,f));
|
||||
w->writeString(i->name,true);
|
||||
w->writeC(i->mode);
|
||||
if (i->mode) { // FM
|
||||
ERR_CHECK(fputc(i->fm.alg,f));
|
||||
ERR_CHECK(fputc(i->fm.fb,f));
|
||||
ERR_CHECK(fputc(i->fm.fms,f));
|
||||
ERR_CHECK(fputc(i->fm.ams,f));
|
||||
w->writeC(i->fm.alg);
|
||||
w->writeC(i->fm.fb);
|
||||
w->writeC(i->fm.fms);
|
||||
w->writeC(i->fm.ams);
|
||||
|
||||
for (int j=0; j<4; j++) {
|
||||
DivInstrumentFM::Operator& op=i->fm.op[j];
|
||||
ERR_CHECK(fputc(op.am,f));
|
||||
ERR_CHECK(fputc(op.ar,f));
|
||||
ERR_CHECK(fputc(op.dr,f));
|
||||
ERR_CHECK(fputc(op.mult,f));
|
||||
ERR_CHECK(fputc(op.rr,f));
|
||||
ERR_CHECK(fputc(op.sl,f));
|
||||
ERR_CHECK(fputc(op.tl,f));
|
||||
ERR_CHECK(fputc(op.dt2,f));
|
||||
ERR_CHECK(fputc(op.rs,f));
|
||||
ERR_CHECK(fputc(op.dt,f));
|
||||
ERR_CHECK(fputc(op.d2r,f));
|
||||
ERR_CHECK(fputc(op.ssgEnv,f));
|
||||
w->writeC(op.am);
|
||||
w->writeC(op.ar);
|
||||
w->writeC(op.dr);
|
||||
w->writeC(op.mult);
|
||||
w->writeC(op.rr);
|
||||
w->writeC(op.sl);
|
||||
w->writeC(op.tl);
|
||||
w->writeC(op.dt2);
|
||||
w->writeC(op.rs);
|
||||
w->writeC(op.dt);
|
||||
w->writeC(op.d2r);
|
||||
w->writeC(op.ssgEnv);
|
||||
}
|
||||
} else { // STD
|
||||
if (song.system!=DIV_SYSTEM_GB) {
|
||||
ERR_CHECK(fputc(i->std.volMacroLen,f));
|
||||
ERR_CHECK(fwrite(i->std.volMacro,4,i->std.volMacroLen,f));
|
||||
w->writeC(i->std.volMacroLen);
|
||||
w->write(i->std.volMacro,4*i->std.volMacroLen);
|
||||
if (i->std.volMacroLen>0) {
|
||||
ERR_CHECK(fputc(i->std.volMacroLoop,f));
|
||||
w->writeC(i->std.volMacroLoop);
|
||||
}
|
||||
}
|
||||
|
||||
ERR_CHECK(fputc(i->std.arpMacroLen,f));
|
||||
ERR_CHECK(fwrite(i->std.arpMacro,4,i->std.arpMacroLen,f));
|
||||
w->writeC(i->std.arpMacroLen);
|
||||
w->write(i->std.arpMacro,4*i->std.arpMacroLen);
|
||||
if (i->std.arpMacroLen>0) {
|
||||
ERR_CHECK(fputc(i->std.arpMacroLoop,f));
|
||||
w->writeC(i->std.arpMacroLoop);
|
||||
}
|
||||
ERR_CHECK(fputc(i->std.arpMacroMode,f));
|
||||
w->writeC(i->std.arpMacroMode);
|
||||
|
||||
ERR_CHECK(fputc(i->std.dutyMacroLen,f));
|
||||
ERR_CHECK(fwrite(i->std.dutyMacro,4,i->std.dutyMacroLen,f));
|
||||
w->writeC(i->std.dutyMacroLen);
|
||||
w->write(i->std.dutyMacro,4*i->std.dutyMacroLen);
|
||||
if (i->std.dutyMacroLen>0) {
|
||||
ERR_CHECK(fputc(i->std.dutyMacroLoop,f));
|
||||
w->writeC(i->std.dutyMacroLoop);
|
||||
}
|
||||
|
||||
ERR_CHECK(fputc(i->std.waveMacroLen,f));
|
||||
ERR_CHECK(fwrite(i->std.waveMacro,4,i->std.waveMacroLen,f));
|
||||
w->writeC(i->std.waveMacroLen);
|
||||
w->write(i->std.waveMacro,4*i->std.waveMacroLen);
|
||||
if (i->std.waveMacroLen>0) {
|
||||
ERR_CHECK(fputc(i->std.waveMacroLoop,f));
|
||||
w->writeC(i->std.waveMacroLoop);
|
||||
}
|
||||
|
||||
if (song.system==DIV_SYSTEM_C64_6581 || song.system==DIV_SYSTEM_C64_8580) {
|
||||
ERR_CHECK(fputc(i->c64.triOn,f));
|
||||
ERR_CHECK(fputc(i->c64.sawOn,f));
|
||||
ERR_CHECK(fputc(i->c64.pulseOn,f));
|
||||
ERR_CHECK(fputc(i->c64.noiseOn,f));
|
||||
w->writeC(i->c64.triOn);
|
||||
w->writeC(i->c64.sawOn);
|
||||
w->writeC(i->c64.pulseOn);
|
||||
w->writeC(i->c64.noiseOn);
|
||||
|
||||
ERR_CHECK(fputc(i->c64.a,f));
|
||||
ERR_CHECK(fputc(i->c64.d,f));
|
||||
ERR_CHECK(fputc(i->c64.s,f));
|
||||
ERR_CHECK(fputc(i->c64.r,f));
|
||||
w->writeC(i->c64.a);
|
||||
w->writeC(i->c64.d);
|
||||
w->writeC(i->c64.s);
|
||||
w->writeC(i->c64.r);
|
||||
|
||||
ERR_CHECK(fputc(i->c64.duty,f));
|
||||
w->writeC(i->c64.duty);
|
||||
|
||||
ERR_CHECK(fputc(i->c64.ringMod,f));
|
||||
ERR_CHECK(fputc(i->c64.oscSync,f));
|
||||
w->writeC(i->c64.ringMod);
|
||||
w->writeC(i->c64.oscSync);
|
||||
|
||||
ERR_CHECK(fputc(i->c64.toFilter,f));
|
||||
ERR_CHECK(fputc(i->c64.volIsCutoff,f));
|
||||
ERR_CHECK(fputc(i->c64.initFilter,f));
|
||||
w->writeC(i->c64.toFilter);
|
||||
w->writeC(i->c64.volIsCutoff);
|
||||
w->writeC(i->c64.initFilter);
|
||||
|
||||
ERR_CHECK(fputc(i->c64.res,f));
|
||||
ERR_CHECK(fputc(i->c64.cut,f));
|
||||
ERR_CHECK(fputc(i->c64.hp,f));
|
||||
ERR_CHECK(fputc(i->c64.bp,f));
|
||||
ERR_CHECK(fputc(i->c64.lp,f));
|
||||
ERR_CHECK(fputc(i->c64.ch3off,f));
|
||||
w->writeC(i->c64.res);
|
||||
w->writeC(i->c64.cut);
|
||||
w->writeC(i->c64.hp);
|
||||
w->writeC(i->c64.bp);
|
||||
w->writeC(i->c64.lp);
|
||||
w->writeC(i->c64.ch3off);
|
||||
}
|
||||
|
||||
if (song.system==DIV_SYSTEM_GB) {
|
||||
ERR_CHECK(fputc(i->gb.envVol,f));
|
||||
ERR_CHECK(fputc(i->gb.envDir,f));
|
||||
ERR_CHECK(fputc(i->gb.envLen,f));
|
||||
ERR_CHECK(fputc(i->gb.soundLen,f));
|
||||
w->writeC(i->gb.envVol);
|
||||
w->writeC(i->gb.envDir);
|
||||
w->writeC(i->gb.envLen);
|
||||
w->writeC(i->gb.soundLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ERR_CHECK(fputc(song.wave.size(),f));
|
||||
w->writeC(song.wave.size());
|
||||
for (DivWavetable* i: song.wave) {
|
||||
ERR_CHECK(fwrite(&i->len,4,1,f));
|
||||
ERR_CHECK(fwrite(&i->data,4,i->len,f));
|
||||
w->writeI(i->len);
|
||||
w->write(i->data,4*i->len);
|
||||
}
|
||||
|
||||
for (int i=0; i<getChannelCount(song.system); i++) {
|
||||
ERR_CHECK(fputc(song.pat[i].effectRows,f));
|
||||
w->writeC(song.pat[i].effectRows);
|
||||
|
||||
for (int j=0; j<song.ordersLen; j++) {
|
||||
DivPattern* pat=song.pat[i].getPattern(song.orders.ord[i][j],false);
|
||||
for (int k=0; k<song.patLen; k++) {
|
||||
ERR_CHECK(fwrite(&pat->data[k][0],2,1,f)); // note
|
||||
ERR_CHECK(fwrite(&pat->data[k][1],2,1,f)); // octave
|
||||
ERR_CHECK(fwrite(&pat->data[k][3],2,1,f)); // volume
|
||||
ERR_CHECK(fwrite(&pat->data[k][4],2,song.pat[i].effectRows*2,f)); // volume
|
||||
ERR_CHECK(fwrite(&pat->data[k][2],2,1,f)); // instrument
|
||||
w->writeS(pat->data[k][0]); // note
|
||||
w->writeS(pat->data[k][1]); // octave
|
||||
w->writeS(pat->data[k][3]); // volume
|
||||
w->write(&pat->data[k][4],2*song.pat[i].effectRows*2); // effects
|
||||
w->writeS(pat->data[k][2]); // instrument
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ERR_CHECK(fputc(song.sample.size(),f));
|
||||
w->writeC(song.sample.size());
|
||||
for (DivSample* i: song.sample) {
|
||||
ERR_CHECK(fwrite(&i->length,4,1,f));
|
||||
ERR_CHECK(fputc(i->name.size(),f));
|
||||
ERR_CHECK(fwrite(i->name.c_str(),1,i->name.size(),f));
|
||||
ERR_CHECK(fputc(i->rate,f));
|
||||
ERR_CHECK(fputc(i->pitch,f));
|
||||
ERR_CHECK(fputc(i->vol,f));
|
||||
ERR_CHECK(fputc(i->depth,f));
|
||||
ERR_CHECK(fwrite(i->data,2,i->length,f));
|
||||
w->writeI(i->length);
|
||||
w->writeString(i->name,true);
|
||||
w->writeC(i->rate);
|
||||
w->writeC(i->pitch);
|
||||
w->writeC(i->vol);
|
||||
w->writeC(i->depth);
|
||||
w->write(i->data,2*i->length);
|
||||
}
|
||||
|
||||
return true;
|
||||
return w;
|
||||
}
|
||||
|
||||
// ADPCM code attribution: https://wiki.neogeodev.org/index.php?title=ADPCM_codecs
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _ENGINE_H
|
||||
#include "song.h"
|
||||
#include "dispatch.h"
|
||||
#include "safeWriter.h"
|
||||
#include "../audio/taAudio.h"
|
||||
#include "blip_buf.h"
|
||||
#include <mutex>
|
||||
|
@ -104,7 +105,7 @@ class DivEngine {
|
|||
// load a .dmf.
|
||||
bool load(void* f, size_t length);
|
||||
// save as .dmf.
|
||||
bool save(FILE* f);
|
||||
SafeWriter* save();
|
||||
|
||||
// play
|
||||
void play();
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
#include "safeWriter.h"
|
||||
|
||||
#define WRITER_BUF_SIZE 16384
|
||||
|
||||
unsigned char* SafeWriter::getFinalBuf() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
void SafeWriter::checkSize(size_t amount) {
|
||||
if (curSeek+amount>=bufLen) {
|
||||
unsigned char* newBuf=new unsigned char[bufLen+WRITER_BUF_SIZE];
|
||||
memcpy(newBuf,buf,bufLen);
|
||||
delete[] buf;
|
||||
buf=newBuf;
|
||||
bufLen+=WRITER_BUF_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
bool SafeWriter::seek(ssize_t where, int whence) {
|
||||
ssize_t supposed;
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
supposed=where;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
supposed=curSeek+where;
|
||||
break;
|
||||
case SEEK_END:
|
||||
supposed=len+where;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (supposed<0) supposed=0;
|
||||
if (supposed>(ssize_t)len) supposed=len;
|
||||
curSeek=supposed;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t SafeWriter::tell() {
|
||||
return curSeek;
|
||||
}
|
||||
|
||||
size_t SafeWriter::size() {
|
||||
return len;
|
||||
}
|
||||
|
||||
int SafeWriter::write(const void* what, size_t count) {
|
||||
if (!operative) return 0;
|
||||
checkSize(count);
|
||||
memcpy(buf+curSeek,what,count);
|
||||
curSeek+=count;
|
||||
if (curSeek>len) len=curSeek;
|
||||
return count;
|
||||
}
|
||||
|
||||
int SafeWriter::writeC(signed char val) {
|
||||
return write(&val,1);
|
||||
}
|
||||
|
||||
int SafeWriter::writeS(short val) {
|
||||
return write(&val,2);
|
||||
}
|
||||
|
||||
int SafeWriter::writeI(int val) {
|
||||
return write(&val,4);
|
||||
}
|
||||
int SafeWriter::writeL(int64_t val) {
|
||||
return write(&val,8);
|
||||
}
|
||||
int SafeWriter::writeF(float val) {
|
||||
return write(&val,4);
|
||||
}
|
||||
int SafeWriter::writeD(double val) {
|
||||
return write(&val,8);
|
||||
}
|
||||
int SafeWriter::writeString(String val, bool pascal) {
|
||||
if (pascal) {
|
||||
writeC((unsigned char)val.size());
|
||||
return write(val.c_str(),val.size())+1;
|
||||
} else {
|
||||
return write(val.c_str(),val.size()+1);
|
||||
}
|
||||
}
|
||||
|
||||
void SafeWriter::init() {
|
||||
if (operative) return;
|
||||
buf=new unsigned char[WRITER_BUF_SIZE];
|
||||
bufLen=WRITER_BUF_SIZE;
|
||||
len=0;
|
||||
curSeek=0;
|
||||
operative=true;
|
||||
}
|
||||
|
||||
void SafeWriter::finish() {
|
||||
if (!operative) return;
|
||||
delete[] buf;
|
||||
buf=NULL;
|
||||
operative=false;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef _SAFEWRITER_H
|
||||
#define _SAFEWRITER_H
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "../ta-utils.h"
|
||||
|
||||
class SafeWriter {
|
||||
bool operative;
|
||||
unsigned char* buf;
|
||||
size_t bufLen;
|
||||
size_t len;
|
||||
|
||||
size_t curSeek;
|
||||
|
||||
void checkSize(size_t amount);
|
||||
|
||||
public:
|
||||
unsigned char* getFinalBuf();
|
||||
|
||||
bool seek(ssize_t where, int whence);
|
||||
size_t tell();
|
||||
size_t size();
|
||||
|
||||
int write(const void* what, size_t count);
|
||||
|
||||
int writeC(signed char val);
|
||||
int writeS(short val);
|
||||
int writeS_BE(short val);
|
||||
int writeI(int val);
|
||||
int writeI_BE(int val);
|
||||
int writeL(int64_t val);
|
||||
int writeL_BE(int64_t val);
|
||||
int writeF(float val);
|
||||
int writeF_BE(float val);
|
||||
int writeD(double val);
|
||||
int writeD_BE(double val);
|
||||
int writeString(String val, bool pascal);
|
||||
|
||||
void init();
|
||||
void finish();
|
||||
|
||||
SafeWriter():
|
||||
operative(false),
|
||||
buf(NULL),
|
||||
bufLen(0),
|
||||
len(0),
|
||||
curSeek(0) {}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,7 @@
|
|||
#include "sample.h"
|
||||
|
||||
DivSample::~DivSample() {
|
||||
if (data) delete data;
|
||||
if (rendData) delete rendData;
|
||||
if (adpcmRendData) delete adpcmRendData;
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
#include "../ta-utils.h"
|
||||
|
||||
struct DivSample {
|
||||
String name;
|
||||
int length, rate;
|
||||
|
@ -21,4 +23,5 @@ struct DivSample {
|
|||
rendOff(0),
|
||||
rendData(NULL),
|
||||
adpcmRendData(NULL) {}
|
||||
~DivSample();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#include "song.h"
|
||||
|
||||
void DivSong::unload() {
|
||||
for (DivInstrument* i: ins) {
|
||||
delete i;
|
||||
}
|
||||
ins.clear();
|
||||
|
||||
for (DivWavetable* i: wave) {
|
||||
delete i;
|
||||
}
|
||||
wave.clear();
|
||||
|
||||
for (DivSample* i: sample) {
|
||||
delete i;
|
||||
}
|
||||
sample.clear();
|
||||
}
|
|
@ -98,6 +98,8 @@ struct DivSong {
|
|||
DivInstrument nullIns;
|
||||
DivWavetable nullWave;
|
||||
|
||||
void unload();
|
||||
|
||||
DivSong():
|
||||
version(24),
|
||||
system(DIV_SYSTEM_GENESIS),
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "imgui_internal.h"
|
||||
#include "ImGuiFileDialog.h"
|
||||
#include "misc/cpp/imgui_stdlib.h"
|
||||
#include <zlib.h>
|
||||
#include <fmt/printf.h>
|
||||
#include <stdexcept>
|
||||
|
||||
|
@ -870,6 +871,81 @@ void FurnaceGUI::keyUp(SDL_Event& ev) {
|
|||
|
||||
}
|
||||
|
||||
#define FURNACE_ZLIB_COMPRESS
|
||||
|
||||
int FurnaceGUI::save(String path) {
|
||||
FILE* outFile=fopen(path.c_str(),"wb");
|
||||
if (outFile==NULL) {
|
||||
return 1;
|
||||
}
|
||||
SafeWriter* w=e->save();
|
||||
#ifdef FURNACE_ZLIB_COMPRESS
|
||||
unsigned char zbuf[131072];
|
||||
int ret;
|
||||
z_stream zl;
|
||||
memset(&zl,0,sizeof(z_stream));
|
||||
ret=deflateInit(&zl,Z_DEFAULT_COMPRESSION);
|
||||
if (ret!=Z_OK) {
|
||||
logE("zlib error!\n");
|
||||
fclose(outFile);
|
||||
w->finish();
|
||||
return 2;
|
||||
}
|
||||
zl.avail_in=w->size();
|
||||
zl.next_in=w->getFinalBuf();
|
||||
while (zl.avail_in>0) {
|
||||
zl.avail_out=131072;
|
||||
zl.next_out=zbuf;
|
||||
if ((ret=deflate(&zl,Z_NO_FLUSH))==Z_STREAM_ERROR) {
|
||||
logE("zlib stream error!\n");
|
||||
deflateEnd(&zl);
|
||||
fclose(outFile);
|
||||
w->finish();
|
||||
return 2;
|
||||
}
|
||||
size_t amount=131072-zl.avail_out;
|
||||
if (amount>0) {
|
||||
if (fwrite(zbuf,1,amount,outFile)!=amount) {
|
||||
logE("did not write entirely: %s!\n",strerror(errno));
|
||||
deflateEnd(&zl);
|
||||
fclose(outFile);
|
||||
w->finish();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
zl.avail_out=131072;
|
||||
zl.next_out=zbuf;
|
||||
if ((ret=deflate(&zl,Z_FINISH))==Z_STREAM_ERROR) {
|
||||
logE("zlib finish stream error!\n");
|
||||
deflateEnd(&zl);
|
||||
fclose(outFile);
|
||||
w->finish();
|
||||
return 2;
|
||||
}
|
||||
if (131072-zl.avail_out>0) {
|
||||
if (fwrite(zbuf,1,131072-zl.avail_out,outFile)!=(131072-zl.avail_out)) {
|
||||
logE("did not write entirely: %s!\n",strerror(errno));
|
||||
deflateEnd(&zl);
|
||||
fclose(outFile);
|
||||
w->finish();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
deflateEnd(&zl);
|
||||
#else
|
||||
if (fwrite(w->getFinalBuf(),1,w->size(),outFile)!=w->size()) {
|
||||
logE("did not write entirely: %s!\n",strerror(errno));
|
||||
fclose(outFile);
|
||||
w->finish();
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
fclose(outFile);
|
||||
w->finish();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FurnaceGUI::load(String path) {
|
||||
if (!path.empty()) {
|
||||
logI("loading module...\n");
|
||||
|
@ -989,10 +1065,14 @@ bool FurnaceGUI::loop() {
|
|||
ImGui::MenuItem("new");
|
||||
if (ImGui::MenuItem("open...")) {
|
||||
ImGuiFileDialog::Instance()->OpenDialog("FileDialog","Open File","DefleMask module{.dmf},.*",workingDir);
|
||||
isSaving=false;
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::MenuItem("save");
|
||||
ImGui::MenuItem("save as...");
|
||||
if (ImGui::MenuItem("save as...")) {
|
||||
ImGuiFileDialog::Instance()->OpenDialog("FileDialog","Save File","DefleMask module{.dmf}",workingDir);
|
||||
isSaving=true;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("exit")) {
|
||||
quit=true;
|
||||
|
@ -1029,7 +1109,7 @@ bool FurnaceGUI::loop() {
|
|||
String copyOfName=fileName;
|
||||
if (isSaving) {
|
||||
printf("saving: %s\n",copyOfName.c_str());
|
||||
//SaveFile(copyOfName.c_str());
|
||||
save(copyOfName);
|
||||
isSaving=false;
|
||||
} else {
|
||||
load(copyOfName);
|
||||
|
|
|
@ -111,6 +111,7 @@ class FurnaceGUI {
|
|||
void keyDown(SDL_Event& ev);
|
||||
void keyUp(SDL_Event& ev);
|
||||
|
||||
int save(String path);
|
||||
int load(String path);
|
||||
|
||||
public:
|
||||
|
|
|
@ -283,13 +283,6 @@ int main(int argc, char** argv) {
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
/*FILE* outFile=fopen("testout.dmf","wb");
|
||||
if (outFile!=NULL) {
|
||||
if (!e.save(outFile)) {
|
||||
logE("could not save file!\n");
|
||||
}
|
||||
fclose(outFile);
|
||||
}*/
|
||||
if (!e.init(outName)) {
|
||||
logE("could not initialize engine!\n");
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue