Mercurial > hg > dmlib
diff edmain.cpp @ 376:40e33ad0d153
Work towards a working editor .. some day.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 17 Oct 2012 02:27:55 +0300 |
parents | |
children | feaeec4c6c55 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edmain.cpp Wed Oct 17 02:27:55 2012 +0300 @@ -0,0 +1,436 @@ +// +// Demo Editor -- Main program +// (C) Copyright 2012 Matti 'ccr' Hämäläinen <ccr@tnsp.org> +// +#include <SDL.h> +#include "dmengine.h" +#include "edmain.h" +#include "eddemoobj.h" +#include <QSettings> +#include <QGLWidget> + + +int main(int argc, char *argv[]) +{ + dmVerbosity = 5; + + QApplication app(argc, argv); + + app.setOrganizationName("TNSP"); + app.setOrganizationDomain("tnsp.org"); + app.setApplicationName(PROGRAM_NAME); + app.setApplicationVersion(PROGRAM_VERSION); + + DemoEditor mainWin; + + mainWin.show(); + + return app.exec(); +} + + +void engineAudioCallback(void *userdata, Uint8 * stream, int len) +{ + DMEngineData *engine = (DMEngineData *) userdata; + + if (engine->paused) + { + memset(stream, 0, len); + } + else +#ifdef DM_USE_JSS + { + if (engine->dev != NULL) + jvmRenderAudio(engine->dev, stream, + len / jvmGetSampleSize(engine->dev)); + } +#endif +#ifdef DM_USE_TREMOR + if (engine->audioPos + len >= engine->audioRes->rdataSize) + { + engine->exitFlag = true; + } + else + { + memcpy(stream, (Uint8 *) engine->audioRes->rdata + engine->audioPos, len); + engine->audioPos += len; + } +#endif +} + + +int DemoEditor::reopenResources() +{ + int err; + + if ((err = dmres_init(&engine.resources, engine.optPackFilename, engine.optDataPath, + engine.optResFlags, engineClassifier)) != DMERR_OK) + { + dmError("Could not initialize resource manager: %d, %s.\n", + err, dmErrorStr(err)); + } + return err; +} + + +int DemoEditor::loadResources() +{ + int err, loaded, total; + err = dmres_preload(engine.resources, true, &loaded, &total); + + while ((err = dmres_preload(engine.resources, false, &loaded, &total)) == DMERR_PROGRESS) + { + // Show a nice progress bar while loading + if (total > 0 && (loaded % 2) == 0) + { +/* + if ((err = engineShowProgress(loaded, total)) != DMERR_OK) + return err; +*/ + } + } + return DMERR_OK; +} + + +DemoEditor::DemoEditor() +{ + int err; + initSDL = FALSE; + + resize(1024, 768); + setWindowTitle(QCoreApplication::applicationName()); + + memset(&engine, 0, sizeof(engine)); + + // Pre-initialization + if ((err = demoPreInit(&engine)) != DMERR_OK) + goto error_exit; + + // Initialize resource subsystem + dmPrint(1, "Initializing resources subsystem.\n"); + if ((err = reopenResources()) != DMERR_OK) + goto error_exit; + + // Initialize SDL components + dmPrint(1, "Initializing libSDL.\n"); + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) != 0) + { + dmError("Could not initialize SDL: %s\n", SDL_GetError()); + goto error_exit; + } + initSDL = true; + + // Initialize audio parts + if (engine.optAfmt.freq == 0 && engine.optAfmt.channels == 0) + { + // Defaults, if none seem to be set + engine.optAfmt.freq = 44100; + engine.optAfmt.format = AUDIO_S16SYS; + engine.optAfmt.channels = 2; + engine.optAfmt.samples = engine.optAfmt.freq / 16; + } + +#ifdef DM_USE_JSS + jssInit(); + + switch (engine.optAfmt.format) + { + case AUDIO_S16SYS: + engine.jss_format = JSS_AUDIO_S16; + break; + case AUDIO_U16SYS: + engine.jss_format = JSS_AUDIO_U16; + break; + case AUDIO_S8: + engine.jss_format = JSS_AUDIO_S8; + break; + case AUDIO_U8: + engine.jss_format = JSS_AUDIO_U8; + break; + } + + dmPrint(1, "Initializing miniJSS mixer with fmt=%d, chn=%d, freq=%d\n", + engine.jss_format, engine.optAfmt.channels, engine.optAfmt.freq); + + if ((engine.dev = + jvmInit(engine.jss_format, engine.optAfmt.channels, + engine.optAfmt.freq, JMIX_AUTO)) == NULL) + { + dmError("jvmInit() returned NULL, voi perkele.\n"); + goto error_exit; + } + + if ((engine.plr = jmpInit(engine.dev)) == NULL) + { + dmError("jmpInit() returned NULL\n"); + goto error_exit; + } +#endif + + // Initialize SDL audio + dmPrint(1, "Trying to init SDL audio with: fmt=%d, chn=%d, freq=%d\n", + engine.optAfmt.format, engine.optAfmt.channels, + engine.optAfmt.freq); + + engine.optAfmt.callback = engineAudioCallback; + + if (SDL_OpenAudio(&engine.optAfmt, NULL) < 0) + { + dmError("Couldn't open SDL audio: %s\n", SDL_GetError()); + goto error_exit; + } + + // Initialize SDL video + if (engine.demoInitPreVideo != NULL && + (err = engine.demoInitPreVideo(&engine)) != DMERR_OK) + { + dmError("demoInitPreVideo() failed, %d: %s\n", err, dmErrorStr(err)); + goto error_exit; + } + + dmPrint(1, "Initializing SDL video %d x %d x %dbpp, flags=0x%08x\n", + engine.optScrWidth, engine.optScrHeight, engine.optBitDepth, engine.optVFlags); + + engine.screen = SDL_CreateRGBSurface(SDL_SWSURFACE, engine.optScrWidth, engine.optScrHeight, engine.optBitDepth, 0, 0, 0, 0); + if (engine.screen == NULL) + { + dmError("Could not allocate video backbuffer surface.\n"); + goto error_exit; + } + + if (engine.demoInitPostVideo != NULL && + (err = engine.demoInitPostVideo(&engine)) != DMERR_OK) + { + dmError("demoInitPostVideo() failed, %d: %s\n", err, dmErrorStr(err)); + goto error_exit; + } + + // Load resources + dmPrint(1, "Loading resources, please wait...\n"); + if ((err = loadResources()) != DMERR_OK) + { + dmError("Error loading resources, %d: %s.\n", err, dmErrorStr(err)); + goto error_exit; + } + + dmPrint(1, "Initializing effects, etc.\n"); + + // Final initializations + if ((err = engine.demoInit(&engine)) != DMERR_OK) + { + dmError("Failure in demoInit(), %d: %s\n", + err, dmErrorStr(err)); + goto error_exit; + } + + // Initialize effects + if ((err = engineInitializeEffects(&engine)) != DMERR_OK) + { + dmError("Effects initialization failed, %d: %s\n", + err, dmErrorStr(err)); + goto error_exit; + } + +error_exit: + + // Setup GUI elements + demo = NULL; + createMainGUI(); + createNewFile(); + + // Finalize init + settingsRestore(); + +// view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + + updateMenuStates(); + statusMsg("Application started."); +} + + +DemoEditor::~DemoEditor() +{ + dmPrint(1, "Shutting down.\n"); + + settingsSave(); +// delete view; + delete demo; + historyReset(); + + if (engine.screen) + SDL_FreeSurface(engine.screen); + + SDL_LockAudio(); + SDL_PauseAudio(1); +#ifdef DM_USE_JSS + jmpClose(engine.plr); + jvmClose(engine.dev); + jssClose(); +#endif + SDL_UnlockAudio(); + + dmFreeTimeline(engine.tl); + dmFreePreparedTimelineData(engine.ptl); + engineShutdownEffects(&engine); + dmres_close(engine.resources); + + if (engine.demoShutdown != NULL) + engine.demoShutdown(&engine); + + if (initSDL) + SDL_Quit(); + + if (engine.demoQuit != NULL) + engine.demoQuit(&engine); +} + + +void DemoEditor::rehashFile() +{ +// view->setDemoObject(demo); + update(); + historyReset(); + changed = false; + updateMenuStates(); +} + + +void DemoEditor::createNewFile() +{ + delete demo; + demo = new DemoObject(); + rehashFile(); +} + + +void DemoEditor::readFromFile(QString filename) +{ + DemoObject *tmp = new DemoObject(); + int ret = tmp->load(filename); + if (ret != DMERR_OK) + { + showFileErrorDialog("Loading demo blob file "+ filename, ret, tmp->lastError); + delete tmp; + } + else + { + delete demo; + demo = tmp; + rehashFile(); + } +} + + +void DemoEditor::saveToFile(QString filename) +{ + int ret = demo->save(filename); + if (ret != DMERR_OK) + { + showFileErrorDialog("Saving demo blob file "+ filename, ret, demo->lastError); + } + + updateMenuStates(); +} + + +void DemoEditor::settingsRestore() +{ + QSettings s; + + restoreGeometry(s.value("windowGeometry").toByteArray()); + restoreState(s.value("windowState").toByteArray()); + +} + + +void DemoEditor::settingsSave() +{ + QSettings s; + + s.setValue("windowGeometry", saveGeometry()); + s.setValue("windowState", saveState()); + +} + + +// +// Edit history functionality +// +void DemoEditor::historyReset() +{ + changed = false; + undoHistoryPos = -1; + undoHistoryMax = DOC_UNDO_MAX; + undoHistory.clear(); +} + + +void DemoEditor::historyPush(QString description) +{ + if (!undoHistory.isEmpty() && undoHistory.last()->state == "-") + { + delete undoHistory.takeLast(); + } + + while (undoHistory.size() >= undoHistoryMax) + { + delete undoHistory.takeFirst(); + } + + DemoObject *copy = new DemoObject(demo); + copy->state = description; + undoHistory.append(copy); +} + + +void DemoEditor::historyTop() +{ + DemoObject *copy = new DemoObject(demo); + copy->state = "-"; + undoHistory.append(copy); + + undoHistoryPos = undoHistory.size() - 1; + changed = true; + updateMenuStates(); + update(); +} + + +void DemoEditor::historyPop() +{ + if (!undoHistory.isEmpty()) + { + delete undoHistory.takeLast(); + } +} + + +void DemoEditor::performRedo() +{ + if (undoHistoryPos >= 0 && undoHistoryPos < undoHistory.size() - 1) + { + undoHistoryPos++; + delete demo; + demo = new DemoObject(undoHistory.at(undoHistoryPos)); + changed = true; + + updateMenuStates(); + update(); + } +} + + +void DemoEditor::performUndo() +{ + if (undoHistoryPos > 0 && undoHistory.size() > 1) + { + undoHistoryPos--; + delete demo; + demo = new DemoObject(undoHistory.at(undoHistoryPos)); + changed = true; + + updateMenuStates(); + update(); + } +}