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();
+    }
+}