Mercurial > hg > dmlib
view editor/edmain.cpp @ 2229:72e15cc14927
Make the offset mode (-o) also support lists of offsets.
Also improve the readability of the output.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 14 Jun 2019 18:39:59 +0300 |
parents | b4992d9f72fe |
children | 69a5af2eb1ea |
line wrap: on
line source
// // 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 <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) { dmMemset(stream, 0, len); } else #ifdef DM_USE_JSS { if (engine->jssDev != NULL) jvmRenderAudio(engine->jssDev, stream, len / jvmGetSampleSize(engine->jssDev)); } #endif #ifdef DM_USE_TREMOR if (engine->audioPos + len >= engine->audioRes->resSize) { engine->exitFlag = true; } else { memcpy(stream, (Uint8 *) engine->audioRes->resData + engine->audioPos, len); engine->audioPos += len; } #endif } int DemoEditor::reopenResources() { int err; if ((err = dmResourcesInit( &engine.resources, engine.optPackFilename, engine.optDataPath, engine.optResFlags, engineClassifier)) != DMERR_OK) { dmErrorMsg("Could not initialize resource manager: %d, %s.\n", err, dmErrorStr(err)); } return err; } int DemoEditor::loadResources() { int err, loaded = 0, total = 0; BOOL first = TRUE; do { /* // Show a nice progress bar while loading if ((err = engineShowProgress(loaded, total)) != DMERR_OK) return err; */ err = dmResourcesPreload(engine.resources, first, &loaded, &total); first = FALSE; } while (err == DMERR_PROGRESS); return DMERR_OK; } DemoEditor::DemoEditor() { int err; resize(1024, 768); setWindowTitle(QCoreApplication::applicationName()); dmMemset(&engine, 0, sizeof(engine)); initSDL = FALSE; currTimeline = NULL; // Pre-initialization if ((err = demoPreInit(&engine)) != 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) { dmErrorMsg("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.jssFormat = JSS_AUDIO_S16; break; case AUDIO_U16SYS: engine.jssFormat = JSS_AUDIO_U16; break; case AUDIO_S8: engine.jssFormat = JSS_AUDIO_S8; break; case AUDIO_U8: engine.jssFormat = JSS_AUDIO_U8; break; } dmPrint(1, "Initializing miniJSS mixer with fmt=%d, chn=%d, freq=%d\n", engine.jssFormat, engine.optAfmt.channels, engine.optAfmt.freq); if ((engine.jssDev = jvmInit(engine.jssFormat, engine.optAfmt.channels, engine.optAfmt.freq, JMIX_AUTO)) == NULL) { dmErrorMsg("jvmInit() returned NULL, voi perkele.\n"); goto error_exit; } if ((engine.jssPlr = jmpInit(engine.jssDev)) == NULL) { dmErrorMsg("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) { dmErrorMsg("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) { dmErrorMsg("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.optVidWidth, engine.optVidHeight, engine.optVidDepth, engine.optVFlags); engine.screen = SDL_CreateRGBSurface(SDL_SWSURFACE, engine.optVidWidth, engine.optVidHeight, engine.optVidDepth, 0, 0, 0, 0); if (engine.screen == NULL) { dmErrorMsg("Could not allocate video backbuffer surface.\n"); goto error_exit; } if (engine.demoInitPostVideo != NULL && (err = engine.demoInitPostVideo(&engine)) != DMERR_OK) { dmErrorMsg("demoInitPostVideo() failed, %d: %s\n", err, dmErrorStr(err)); goto error_exit; } error_exit: // Setup GUI elements createMainGUI(); createNewFile(); timelineView->setTimeline(currTimeline); settingsRestore(); initEffectsAndResources(); statusMsg("Application started."); } DemoEditor::~DemoEditor() { statusMsg("Shutting down."); settingsSave(); delete demoView; historyReset(); if (engine.screen) SDL_FreeSurface(engine.screen); SDL_LockAudio(); SDL_PauseAudio(1); #ifdef DM_USE_JSS jmpClose(engine.jssPlr); jvmClose(engine.jssDev); jssClose(); #endif SDL_UnlockAudio(); shutdownEffectsAndResources(); if (initSDL) SDL_Quit(); } int DemoEditor::getTimelineDuration() { return timelineAudioTrack->getDuration(); } void DemoEditor::updateResourceView() { } void DemoEditor::updateTimelineView() { demoView->setEngineData(&engine); if (engine.audioRes != NULL) { timelineAudioTrack->setWaveform( engine.audioRes->resData, engine.audioRes->resSize, engine.optAfmt.format, engine.optAfmt.channels, engine.optAfmt.freq); } timelineAudioTrack->setOffset(currViewOffset); timelineAudioTrack->setScale(currViewScale); timelineView->setTime(currFrameTime); timelineView->setOffset(currViewOffset); timelineView->setScale(currViewScale); timelineScrollBar->setRange(0, getTimelineDuration()); timelineScrollBar->setValue(currViewOffset); } void DemoEditor::actionTimelineScrollChanged(int value) { currViewOffset = value; updateTimelineView(); } void DemoEditor::actionOffsetChanged(float value) { currViewOffset = value; updateTimelineView(); } void DemoEditor::actionTimeChanged(float value) { currFrameTime = value; updateTimelineView(); } void DemoEditor::actionTimelineChanged() { updateMenuStates(); update(); } int DemoEditor::initEffectsAndResources() { int err; currViewOffset = 0; currFrameTime = 0; currViewScale = 1.0f; // Initialize resource subsystem statusMsg("Initializing resources subsystem."); if ((err = reopenResources()) != DMERR_OK) return err; // Load resources statusMsg("Loading resources, please wait..."); if ((err = loadResources()) != DMERR_OK) { dmErrorMsg("Error loading resources, %d: %s.\n", err, dmErrorStr(err)); return err; } // Final initializations statusMsg("Initializing custom demo data."); if ((err = engine.demoInit(&engine)) != DMERR_OK) { dmErrorMsg("Failure in demoInit(), %d: %s\n", err, dmErrorStr(err)); return err; } // Initialize effects statusMsg("Initializing effects ..."); if ((err = engineInitializeEffects(&engine)) != DMERR_OK) { dmErrorMsg("Effects initialization failed, %d: %s\n", err, dmErrorStr(err)); return err; } // Etc. rehash(); return DMERR_OK; } void DemoEditor::shutdownEffectsAndResources() { delete currTimeline; dmFreePreparedTimelineData(engine.ptl); engineShutdownEffects(&engine); dmResourcesClose(engine.resources); if (engine.demoShutdown != NULL) engine.demoShutdown(&engine); } void DemoEditor::rehash() { timelineView->setTimeline(currTimeline); updateResourceView(); updateTimelineView(); updateMenuStates(); update(); } void DemoEditor::createNewFile() { delete currTimeline; currTimeline = new EDTimelineObject(); DMTimelineTrack *tr; dmTimelineAddTrack(currTimeline->tl, &tr, "Penis"); DMTimelineEvent *ev; dmTimelineTrackAddEvent(tr, 500, 100, &ev); dmTimelineEventSetEffectByIndex(ev, 0); historyReset(); updateMenuStates(); update(); } void DemoEditor::readFromFile(QString filename) { EDTimelineObject *tmp = new EDTimelineObject(); int ret = tmp->load(filename); if (ret != DMERR_OK) { showFileErrorDialog("Loading demo blob file "+ filename, ret); delete tmp; } else { delete currTimeline; currTimeline = tmp; rehash(); } } void DemoEditor::saveToFile(QString filename) { int ret = currTimeline->save(filename); if (ret != DMERR_OK) { showFileErrorDialog("Saving demo blob file "+ filename, ret); } 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() { if (currTimeline != NULL) currTimeline->scrub(); undoHistoryPos = -1; undoHistoryMax = DOC_UNDO_MAX; undoHistory.clear(); } void DemoEditor::historyPush(QString description) { if (currTimeline == NULL) return; if (!undoHistory.isEmpty() && undoHistory.last()->state() == "-") { delete undoHistory.takeLast(); } while (undoHistory.size() >= undoHistoryMax) { delete undoHistory.takeFirst(); } EDTimelineObject *copy = new EDTimelineObject(currTimeline); copy->setState(description); undoHistory.append(copy); } void DemoEditor::historyTop() { if (currTimeline == NULL) return; EDTimelineObject *copy = new EDTimelineObject(currTimeline); copy->setState("-"); undoHistory.append(copy); undoHistoryPos = undoHistory.size() - 1; currTimeline->touch(); updateTimelineView(); updateMenuStates(); update(); } void DemoEditor::historyPop() { if (!undoHistory.isEmpty()) { delete undoHistory.takeLast(); } } void DemoEditor::performRedo() { if (undoHistoryPos >= 0 && undoHistoryPos < undoHistory.size() - 1) { undoHistoryPos++; delete currTimeline; currTimeline = new EDTimelineObject(undoHistory.at(undoHistoryPos)); currTimeline->touch(); updateTimelineView(); updateMenuStates(); update(); } } void DemoEditor::performUndo() { if (undoHistoryPos > 0 && undoHistory.size() > 1) { undoHistoryPos--; delete currTimeline; currTimeline = new EDTimelineObject(undoHistory.at(undoHistoryPos)); currTimeline->touch(); updateTimelineView(); updateMenuStates(); update(); } }