Mercurial > hg > dmlib
view editor/edmain.cpp @ 2208:90ec1ec89c56
Revamp the palette handling in lib64gfx somewhat, add helper functions to
lib64util for handling external palette file options and add support for
specifying one of the "internal" palettes or external (.act) palette file to
gfxconv and 64vw.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 14 Jun 2019 05:01:12 +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(); } }