From f59512c47ea21c851535eeabf822aabdfde9167f Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Fri, 17 May 2013 00:18:09 +0300 Subject: RECORDER: Implement Events Recorder --- gui/EventRecorder.cpp | 699 +++++++++++++ gui/EventRecorder.h | 293 ++++++ gui/ThemeEngine.cpp | 35 +- gui/ThemeEngine.h | 13 + gui/dialog.h | 3 + gui/editrecorddialog.cpp | 87 ++ gui/editrecorddialog.h | 56 ++ gui/gui-manager.cpp | 138 +-- gui/gui-manager.h | 6 + gui/launcher.cpp | 83 +- gui/launcher.h | 15 +- gui/module.mk | 8 + gui/onscreendialog.cpp | 231 +++++ gui/onscreendialog.h | 64 ++ gui/recorderdialog.cpp | 291 ++++++ gui/recorderdialog.h | 81 ++ gui/themes/default.inc | 1052 ++++++++++++-------- gui/themes/scummclassic.zip | Bin 104059 -> 110000 bytes gui/themes/scummclassic/classic_layout.stx | 128 +++ gui/themes/scummclassic/classic_layout_lowres.stx | 104 ++ gui/themes/scummmodern.zip | Bin 1462338 -> 1485585 bytes gui/themes/scummmodern/editbtn.bmp | Bin 0 -> 3126 bytes gui/themes/scummmodern/editbtn_small.bmp | Bin 0 -> 822 bytes gui/themes/scummmodern/fastreplay.bmp | Bin 0 -> 3126 bytes gui/themes/scummmodern/fastreplay_small.bmp | Bin 0 -> 822 bytes gui/themes/scummmodern/scummmodern_gfx.stx | 8 + gui/themes/scummmodern/scummmodern_layout.stx | 130 +++ .../scummmodern/scummmodern_layout_lowres.stx | 125 +++ gui/themes/scummmodern/stopbtn.bmp | Bin 0 -> 3126 bytes gui/themes/scummmodern/stopbtn_small.bmp | Bin 0 -> 822 bytes gui/themes/scummmodern/switchbtn.bmp | Bin 0 -> 3126 bytes gui/themes/scummmodern/switchbtn_small.bmp | Bin 0 -> 822 bytes 32 files changed, 3152 insertions(+), 498 deletions(-) create mode 100644 gui/EventRecorder.cpp create mode 100644 gui/EventRecorder.h create mode 100644 gui/editrecorddialog.cpp create mode 100644 gui/editrecorddialog.h create mode 100644 gui/onscreendialog.cpp create mode 100644 gui/onscreendialog.h create mode 100644 gui/recorderdialog.cpp create mode 100644 gui/recorderdialog.h create mode 100644 gui/themes/scummmodern/editbtn.bmp create mode 100644 gui/themes/scummmodern/editbtn_small.bmp create mode 100644 gui/themes/scummmodern/fastreplay.bmp create mode 100644 gui/themes/scummmodern/fastreplay_small.bmp create mode 100644 gui/themes/scummmodern/stopbtn.bmp create mode 100644 gui/themes/scummmodern/stopbtn_small.bmp create mode 100644 gui/themes/scummmodern/switchbtn.bmp create mode 100644 gui/themes/scummmodern/switchbtn_small.bmp (limited to 'gui') diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp new file mode 100644 index 0000000000..94b955cb22 --- /dev/null +++ b/gui/EventRecorder.cpp @@ -0,0 +1,699 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#include "gui/EventRecorder.h" + +namespace Common { +DECLARE_SINGLETON(GUI::EventRecorder); +} + +#ifdef ENABLE_EVENTRECORDER + +#include "common/debug-channels.h" +#include "backends/timer/sdl/sdl-timer.h" +#include "backends/mixer/sdl/sdl-mixer.h" +#include "common/config-manager.h" +#include "common/md5.h" +#include "gui/gui-manager.h" +#include "gui/widget.h" +#include "gui/onscreendialog.h" +#include "common/random.h" +#include "common/savefile.h" +#include "common/textconsole.h" +#include "graphics/thumbnail.h" +#include "graphics/surface.h" +#include "graphics/scaler.h" + +namespace GUI { + + +const int kMaxRecordsNames = 0x64; +const int kDefaultScreenshotPeriod = 60000; +const int kDefaultBPP = 2; + +uint32 readTime(Common::ReadStream *inFile) { + uint32 d = inFile->readByte(); + if (d == 0xff) { + d = inFile->readUint32LE(); + } + + return d; +} + +void writeTime(Common::WriteStream *outFile, uint32 d) { + //Simple RLE compression + if (d >= 0xff) { + outFile->writeByte(0xff); + outFile->writeUint32LE(d); + } else { + outFile->writeByte(d); + } +} + +EventRecorder::EventRecorder() { + _timerManager = NULL; + _recordMode = kPassthrough; + _fakeMixerManager = NULL; + _initialized = false; + _needRedraw = false; + _fastPlayback = false; + DebugMan.addDebugChannel(kDebugLevelEventRec, "EventRec", "Event recorder debug level"); +} + +EventRecorder::~EventRecorder() { + if (_timerManager != NULL) { + delete _timerManager; + } +} + +void EventRecorder::deinit() { + if (!_initialized) { + return; + } + setFileHeader(); + _needRedraw = false; + _initialized = false; + _recordMode = kPassthrough; + delete _fakeMixerManager; + _fakeMixerManager = NULL; + controlPanel->close(); + delete controlPanel; + debugC(1, kDebugLevelEventRec, "playback:action=stopplayback"); + g_system->getEventManager()->getEventDispatcher()->unregisterSource(this); + _recordMode = kPassthrough; + _playbackFile->close(); + delete _playbackFile; + switchMixer(); + switchTimerManagers(); + DebugMan.disableDebugChannel("EventRec"); +} + +void EventRecorder::processMillis(uint32 &millis, bool skipRecord) { + if (!_initialized) { + return; + } + if (skipRecord) { + millis = _fakeTimer; + return; + } + if (_recordMode == kRecorderPlaybackPause) { + millis = _fakeTimer; + } + uint32 millisDelay; + Common::RecorderEvent timerEvent; + switch (_recordMode) { + case kRecorderRecord: + updateSubsystems(); + millisDelay = millis - _lastMillis; + _lastMillis = millis; + _fakeTimer += millisDelay; + controlPanel->setReplayedTime(_fakeTimer); + timerEvent.recordedtype = Common::kRecorderEventTypeTimer; + timerEvent.time = _fakeTimer; + _playbackFile->writeEvent(timerEvent); + takeScreenshot(); + _timerManager->handler(); + break; + case kRecorderPlayback: + updateSubsystems(); + if (_nextEvent.recordedtype == Common::kRecorderEventTypeTimer) { + _fakeTimer = _nextEvent.time; + _nextEvent = _playbackFile->getNextEvent(); + _timerManager->handler(); + } else { + if (_nextEvent.type == Common::EVENT_RTL) { + error("playback:action=stopplayback"); + } else { + uint32 seconds = _fakeTimer / 1000; + Common::String screenTime = Common::String::format("%.2d:%.2d:%.2d", seconds / 3600 % 24, seconds / 60 % 60, seconds % 60); + error("playback:action=error reason=\"synchronization error\" time = %s", screenTime.c_str()); + } + } + millis = _fakeTimer; + controlPanel->setReplayedTime(_fakeTimer); + break; + case kRecorderPlaybackPause: + millis = _fakeTimer; + break; + default: + break; + } +} + +bool EventRecorder::processDelayMillis() { + return _fastPlayback; +} + +void EventRecorder::checkForKeyCode(const Common::Event &event) { + if ((event.type == Common::EVENT_KEYDOWN) && (event.kbd.flags & Common::KBD_CTRL) && (event.kbd.keycode == Common::KEYCODE_p) && (!event.synthetic)) { + togglePause(); + } +} + +bool EventRecorder::pollEvent(Common::Event &ev) { + if ((_recordMode != kRecorderPlayback) || !_initialized) + return false; + + if ((_nextEvent.recordedtype == Common::kRecorderEventTypeTimer) || (_nextEvent.type == Common::EVENT_INVALID)) { + return false; + } + + switch (_nextEvent.type) { + case Common::EVENT_MOUSEMOVE: + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONDOWN: + case Common::EVENT_RBUTTONUP: + case Common::EVENT_WHEELUP: + case Common::EVENT_WHEELDOWN: + g_system->warpMouse(_nextEvent.mouse.x, _nextEvent.mouse.y); + break; + default: + break; + } + ev = _nextEvent; + _nextEvent = _playbackFile->getNextEvent(); + return true; +} + +void EventRecorder::switchFastMode() { + if (_recordMode == kRecorderPlaybackPause) { + _fastPlayback = !_fastPlayback; + } +} + +void EventRecorder::togglePause() { + RecordMode oldState; + switch (_recordMode) { + case kRecorderPlayback: + case kRecorderRecord: + oldState = _recordMode; + _recordMode = kRecorderPlaybackPause; + controlPanel->runModal(); + _recordMode = oldState; + _initialized = true; + break; + case kRecorderPlaybackPause: + controlPanel->close(); + break; + default: + break; + } +} + +void EventRecorder::RegisterEventSource() { + g_system->getEventManager()->getEventDispatcher()->registerMapper(this, false); +} + +uint32 EventRecorder::getRandomSeed(const Common::String &name) { + uint32 result = g_system->getMillis(); + if (_recordMode == kRecorderRecord) { + _playbackFile->getHeader().randomSourceRecords[name] = result; + } else if (_recordMode == kRecorderPlayback) { + result = _playbackFile->getHeader().randomSourceRecords[name]; + } + return result; +} + +Common::String EventRecorder::generateRecordFileName(const Common::String &target) { + Common::String pattern(target+".r??"); + Common::StringArray files = g_system->getSavefileManager()->listSavefiles(pattern); + for (int i = 0; i < kMaxRecordsNames; ++i) { + Common::String recordName = Common::String::format("%s.r%02d", target.c_str(), i); + if (find(files.begin(), files.end(), recordName) != files.end()) { + continue; + } + return recordName; + } + return ""; +} + + +void EventRecorder::init(Common::String recordFileName, RecordMode mode) { + _fakeMixerManager = new NullSdlMixerManager(); + _fakeMixerManager->init(); + _fakeMixerManager->suspendAudio(); + _fakeTimer = 0; + _lastMillis = g_system->getMillis(); + _playbackFile = new Common::PlaybackFile(); + _lastScreenshotTime = 0; + _recordMode = mode; + _needcontinueGame = false; + if (ConfMan.hasKey("disable_display")) { + DebugMan.enableDebugChannel("EventRec"); + gDebugLevel = 1; + } + if (_recordMode == kRecorderPlayback) { + debugC(1, kDebugLevelEventRec, "playback:action=\"Load file\" filename=%s", recordFileName.c_str()); + } + g_system->getEventManager()->getEventDispatcher()->registerSource(this, false); + _screenshotPeriod = ConfMan.getInt("screenshot_period"); + if (_screenshotPeriod == 0) { + _screenshotPeriod = kDefaultScreenshotPeriod; + } + if (!openRecordFile(recordFileName)) { + deinit(); + error("playback:action=error reason=\"Record file loading error\""); + return; + } + if (_recordMode != kPassthrough) { + controlPanel = new GUI::OnScreenDialog(_recordMode == kRecorderRecord); + } + if (_recordMode == kRecorderPlayback) { + applyPlaybackSettings(); + _nextEvent = _playbackFile->getNextEvent(); + } + if (_recordMode == kRecorderRecord) { + getConfig(); + } + + switchMixer(); + switchTimerManagers(); + _needRedraw = true; + _initialized = true; +} + + +/** + * Opens or creates file depend of recording mode. + * + *@param id of recording or playing back game + *@return true in case of success, false in case of error + * + */ +bool EventRecorder::openRecordFile(const Common::String &fileName) { + bool result; + switch (_recordMode) { + case kRecorderRecord: + return _playbackFile->openWrite(fileName); + case kRecorderPlayback: + _recordMode = kPassthrough; + result = _playbackFile->openRead(fileName); + _recordMode = kRecorderPlayback; + return result; + default: + return false; + } + return true; +} + +bool EventRecorder::checkGameHash(const ADGameDescription *gameDesc) { + if ((gameDesc == NULL) && (_playbackFile->getHeader().hashRecords.size() != 0)) { + warning("Engine doesn't contain description table"); + return false; + } + for (const ADGameFileDescription *fileDesc = gameDesc->filesDescriptions; fileDesc->fileName; fileDesc++) { + if (_playbackFile->getHeader().hashRecords.find(fileDesc->fileName) == _playbackFile->getHeader().hashRecords.end()) { + warning("MD5 hash for file %s not found in record file", fileDesc->fileName); + debugC(1, kDebugLevelEventRec, "playback:action=\"Check game hash\" filename=%s filehash=%s storedhash=\"\" result=different", fileDesc->fileName, fileDesc->md5); + return false; + } + if (_playbackFile->getHeader().hashRecords[fileDesc->fileName] != fileDesc->md5) { + warning("Incorrect version of game file %s. Stored MD5 is %s. MD5 of loaded game is %s", fileDesc->fileName, _playbackFile->getHeader().hashRecords[fileDesc->fileName].c_str(), fileDesc->md5); + debugC(1, kDebugLevelEventRec, "playback:action=\"Check game hash\" filename=%s filehash=%s storedhash=%s result=different", fileDesc->fileName, fileDesc->md5, _playbackFile->getHeader().hashRecords[fileDesc->fileName].c_str()); + return false; + } + debugC(1, kDebugLevelEventRec, "playback:action=\"Check game hash\" filename=%s filehash=%s storedhash=%s result=equal", fileDesc->fileName, fileDesc->md5, _playbackFile->getHeader().hashRecords[fileDesc->fileName].c_str()); + } + return true; +} + +void EventRecorder::registerMixerManager(SdlMixerManager *mixerManager) { + _realMixerManager = mixerManager; +} + +void EventRecorder::switchMixer() { + if (_recordMode == kPassthrough) { + _realMixerManager->resumeAudio(); + } else { + _realMixerManager->suspendAudio(); + _fakeMixerManager->resumeAudio(); + } +} + +SdlMixerManager *EventRecorder::getMixerManager() { + if (_recordMode == kPassthrough) { + return _realMixerManager; + } else { + return _fakeMixerManager; + } +} + +void EventRecorder::getConfigFromDomain(Common::ConfigManager::Domain *domain) { + for (Common::ConfigManager::Domain::iterator entry = domain->begin(); entry!= domain->end(); ++entry) { + _playbackFile->getHeader().settingsRecords[entry->_key] = entry->_value; + } +} + +void EventRecorder::getConfig() { + getConfigFromDomain(ConfMan.getDomain(ConfMan.kApplicationDomain)); + getConfigFromDomain(ConfMan.getActiveDomain()); + _playbackFile->getHeader().settingsRecords["save_slot"] = ConfMan.get("save_slot"); +} + + +void EventRecorder::applyPlaybackSettings() { + for (Common::StringMap::iterator i = _playbackFile->getHeader().settingsRecords.begin(); i != _playbackFile->getHeader().settingsRecords.end(); ++i) { + Common::String currentValue = ConfMan.get(i->_key); + if (currentValue != i->_value) { + ConfMan.set(i->_key, i->_value, ConfMan.kTransientDomain); + debugC(1, kDebugLevelEventRec, "playback:action=\"Apply settings\" key=%s storedvalue=%s currentvalue=%s result=different", i->_key.c_str(), i->_value.c_str(), currentValue.c_str()); + } else { + debugC(1, kDebugLevelEventRec, "playback:action=\"Apply settings\" key=%s storedvalue=%s currentvalue=%s result=equal", i->_key.c_str(), i->_value.c_str(), currentValue.c_str()); + } + } + removeDifferentEntriesInDomain(ConfMan.getDomain(ConfMan.kApplicationDomain)); + removeDifferentEntriesInDomain(ConfMan.getActiveDomain()); +} + +void EventRecorder::removeDifferentEntriesInDomain(Common::ConfigManager::Domain *domain) { + for (Common::ConfigManager::Domain::iterator entry = domain->begin(); entry!= domain->end(); ++entry) { + if (_playbackFile->getHeader().settingsRecords.find(entry->_key) == _playbackFile->getHeader().settingsRecords.end()) { + debugC(1, kDebugLevelEventRec, "playback:action=\"Apply settings\" checksettings:key=%s storedvalue=%s currentvalue="" result=different", entry->_key.c_str(), entry->_value.c_str()); + domain->erase(entry->_key); + } + } +} + +DefaultTimerManager *EventRecorder::getTimerManager() { + return _timerManager; +} + +void EventRecorder::registerTimerManager(DefaultTimerManager *timerManager) { + _timerManager = timerManager; +} + +void EventRecorder::switchTimerManagers() { + delete _timerManager; + if (_recordMode == kPassthrough) { + _timerManager = new SdlTimerManager(); + } else { + _timerManager = new DefaultTimerManager(); + } +} + +void EventRecorder::updateSubsystems() { + if (_recordMode == kPassthrough) { + return; + } + RecordMode oldRecordMode = _recordMode; + _recordMode = kPassthrough; + _fakeMixerManager->update(); + _recordMode = oldRecordMode; +} + +Common::List EventRecorder::mapEvent(const Common::Event &ev, Common::EventSource *source) { + if ((!_initialized) && (_recordMode != kRecorderPlaybackPause)) { + return DefaultEventMapper::mapEvent(ev, source); + } + + checkForKeyCode(ev); + Common::Event evt = ev; + evt.mouse.x = evt.mouse.x * (g_system->getOverlayWidth() / g_system->getWidth()); + evt.mouse.y = evt.mouse.y * (g_system->getOverlayHeight() / g_system->getHeight()); + switch (_recordMode) { + case kRecorderPlayback: + if (ev.synthetic != true) { + return Common::List(); + } + return Common::DefaultEventMapper::mapEvent(ev, source); + break; + case kRecorderRecord: + g_gui.processEvent(evt, controlPanel); + if (((evt.type == Common::EVENT_LBUTTONDOWN) || (evt.type == Common::EVENT_LBUTTONUP) || (evt.type == Common::EVENT_MOUSEMOVE)) && controlPanel->isMouseOver()) { + return Common::List(); + } else { + Common::RecorderEvent e; + memcpy(&e, &ev, sizeof(ev)); + e.recordedtype = Common::kRecorderEventTypeNormal; + e.time = _fakeTimer; + _playbackFile->writeEvent(e); + return DefaultEventMapper::mapEvent(ev, source); + } + break; + case kRecorderPlaybackPause: { + Common::Event dialogEvent; + if (controlPanel->isEditDlgVisible()) { + dialogEvent = ev; + } else { + dialogEvent = evt; + } + g_gui.processEvent(dialogEvent, controlPanel->getActiveDlg()); + if (((dialogEvent.type == Common::EVENT_LBUTTONDOWN) || (dialogEvent.type == Common::EVENT_LBUTTONUP) || (dialogEvent.type == Common::EVENT_MOUSEMOVE)) && controlPanel->isMouseOver()) { + return Common::List(); + } + return Common::DefaultEventMapper::mapEvent(dialogEvent, source); + } + break; + default: + return Common::DefaultEventMapper::mapEvent(ev, source); + } +} + +void EventRecorder::setGameMd5(const ADGameDescription *gameDesc) { + for (const ADGameFileDescription *fileDesc = gameDesc->filesDescriptions; fileDesc->fileName; fileDesc++) { + if (fileDesc->md5 != NULL) { + _playbackFile->getHeader().hashRecords[fileDesc->fileName] = fileDesc->md5; + } + } +} + +void EventRecorder::processGameDescription(const ADGameDescription *desc) { + if (_recordMode == kRecorderRecord) { + setGameMd5(desc); + } + if ((_recordMode == kRecorderPlayback) && !checkGameHash(desc)) { + deinit(); + error("playback:action=error reason=\"\""); + } +} + +void EventRecorder::deleteRecord(const Common::String& fileName) { + g_system->getSavefileManager()->removeSavefile(fileName); +} + +void EventRecorder::takeScreenshot() { + if ((_fakeTimer - _lastScreenshotTime) > _screenshotPeriod) { + Graphics::Surface screen; + uint8 md5[16]; + if (grabScreenAndComputeMD5(screen, md5)) { + _lastScreenshotTime = _fakeTimer; + _playbackFile->saveScreenShot(screen, md5); + screen.free(); + } + } +} + +bool EventRecorder::grabScreenAndComputeMD5(Graphics::Surface &screen, uint8 md5[16]) { + if (!createScreenShot(screen)) { + warning("Can't save screenshot"); + return false; + } + Common::MemoryReadStream bitmapStream((const byte*)screen.pixels, screen.w * screen.h * screen.format.bytesPerPixel); + computeStreamMD5(bitmapStream, md5); + return true; +} + +Common::SeekableReadStream *EventRecorder::processSaveStream(const Common::String &fileName) { + Common::InSaveFile *saveFile; + switch (_recordMode) { + case kRecorderPlayback: + debugC(1, kDebugLevelEventRec, "playback:action=\"Process save file\" filename=%s len=%d", fileName.c_str(), _playbackFile->getHeader().saveFiles[fileName].size); + return new Common::MemoryReadStream(_playbackFile->getHeader().saveFiles[fileName].buffer, _playbackFile->getHeader().saveFiles[fileName].size); + case kRecorderRecord: + saveFile = _realSaveManager->openForLoading(fileName); + if (saveFile != NULL) { + _playbackFile->addSaveFile(fileName, saveFile); + saveFile->seek(0); + } + return saveFile; + default: + return NULL; + break; + } +} + +Common::SaveFileManager *EventRecorder::getSaveManager(Common::SaveFileManager *realSaveManager) { + _realSaveManager = realSaveManager; + if (_recordMode != kPassthrough) { + return &_fakeSaveManager; + } else { + return realSaveManager; + } +} + +void EventRecorder::preDrawOverlayGui() { + if ((_initialized) || (_needRedraw)) { + RecordMode oldMode = _recordMode; + _recordMode = kPassthrough; + g_system->showOverlay(); + g_gui.theme()->clearAll(); + g_gui.theme()->openDialog(true, GUI::ThemeEngine::kShadingNone); + controlPanel->drawDialog(); + g_gui.theme()->finishBuffering(); + g_gui.theme()->updateScreen(); + _recordMode = oldMode; + } +} + +void EventRecorder::postDrawOverlayGui() { + if ((_initialized) || (_needRedraw)) { + RecordMode oldMode = _recordMode; + _recordMode = kPassthrough; + g_system->hideOverlay(); + _recordMode = oldMode; + } +} + +Common::StringArray EventRecorder::listSaveFiles(const Common::String &pattern) { + if (_recordMode == kRecorderPlayback) { + Common::StringArray result; + for (Common::HashMap::iterator i = _playbackFile->getHeader().saveFiles.begin(); i != _playbackFile->getHeader().saveFiles.end(); ++i) { + if (i->_key.matchString(pattern, false, true)) { + result.push_back(i->_key); + } + } + return result; + } else { + return _realSaveManager->listSavefiles(pattern); + } +} + +void EventRecorder::setFileHeader() { + if (_recordMode != kRecorderRecord) { + return; + } + TimeDate t; + const EnginePlugin *plugin = 0; + GameDescriptor desc = EngineMan.findGame(ConfMan.getActiveDomainName(), &plugin); + g_system->getTimeAndDate(t); + if (_author.empty()) { + setAuthor("Unknown Author"); + } + if (_name.empty()) { + g_eventRec.setName(Common::String::format("%.2d.%.2d.%.4d ", t.tm_mday, t.tm_mon, 1900 + t.tm_year) + desc.description()); + } + _playbackFile->getHeader().author = _author; + _playbackFile->getHeader().notes = _desc; + _playbackFile->getHeader().name = _name; +} + +SDL_Surface *EventRecorder::getSurface(int width, int height) { + SDL_Surface *surface = new SDL_Surface(); + surface->format = new SDL_PixelFormat(); + surface->flags = 0; + surface->format->palette = NULL; + surface->format->BitsPerPixel = 16; + surface->format->BytesPerPixel = 2; + surface->format->Rloss = 3; + surface->format->Gloss = 2; + surface->format->Bloss = 3; + surface->format->Aloss = 8; + surface->format->Rshift = 11; + surface->format->Gshift = 5; + surface->format->Bshift = 0; + surface->format->Ashift = 0; + surface->format->Rmask = 63488; + surface->format->Gmask = 2016; + surface->format->Bmask = 31; + surface->format->Amask = 0; + surface->format->colorkey = 0; + surface->format->alpha = 255; + surface->w = width; + surface->h = height; + surface->pitch = width * 2; + surface->pixels = (char *)malloc(surface->pitch * surface->h); + surface->offset = 0; + surface->hwdata = NULL; + surface->clip_rect.x = 0; + surface->clip_rect.y = 0; + surface->clip_rect.w = width; + surface->clip_rect.h = height; + surface->unused1 = 0; + surface->locked = 0; + surface->map = NULL; + surface->format_version = 4; + surface->refcount = 1; + return surface; +} + +bool EventRecorder::switchMode() { + const Common::String gameId = ConfMan.get("gameid"); + const EnginePlugin *plugin = 0; + EngineMan.findGame(gameId, &plugin); + bool metaInfoSupport = (*plugin)->hasFeature(MetaEngine::kSavesSupportMetaInfo); + bool featuresSupport = metaInfoSupport && + g_engine->canSaveGameStateCurrently() && + (*plugin)->hasFeature(MetaEngine::kSupportsListSaves) && + (*plugin)->hasFeature(MetaEngine::kSupportsDeleteSave); + if (!featuresSupport) { + return false; + } + + int emptySlot = 1; + SaveStateList saveList = (*plugin)->listSaves(gameId.c_str()); + for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) { + int saveSlot = x->getSaveSlot(); + if (saveSlot == 0) { + continue; + } + if (emptySlot != saveSlot) { + break; + } + emptySlot++; + } + Common::String saveName; + if (emptySlot >= 0) { + saveName = Common::String::format("Save %d", emptySlot + 1); + Common::Error status = g_engine->saveGameState(emptySlot, saveName); + if (status.getCode() == Common::kNoError) { + Common::Event eventRTL; + eventRTL.type = Common::EVENT_RTL; + g_system->getEventManager()->pushEvent(eventRTL); + } + } + ConfMan.set("record_mode", "", Common::ConfigManager::kTransientDomain); + ConfMan.setInt("save_slot", emptySlot, Common::ConfigManager::kTransientDomain); + _needcontinueGame = true; + return true; +} + +bool EventRecorder::checkForContinueGame() { + bool result = _needcontinueGame; + _needcontinueGame = false; + return result; +} + +void EventRecorder::deleteTemporarySave() { + if (_temporarySlot == -1) return; + const Common::String gameId = ConfMan.get("gameid"); + const EnginePlugin *plugin = 0; + EngineMan.findGame(gameId, &plugin); + (*plugin)->removeSaveState(gameId.c_str(), _temporarySlot); + _temporarySlot = -1; +} + +} // End of namespace GUI + +#endif // ENABLE_EVENTRECORDER + diff --git a/gui/EventRecorder.h b/gui/EventRecorder.h new file mode 100644 index 0000000000..3e32d89232 --- /dev/null +++ b/gui/EventRecorder.h @@ -0,0 +1,293 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GUI_EVENTRECORDER_H +#define GUI_EVENTRECORDER_H + +#include "common/system.h" + +#include "common/events.h" +#include "common/savefile.h" +#include "common/singleton.h" + +#include "engines/advancedDetector.h" + +#ifdef ENABLE_EVENTRECORDER + +#include "common/mutex.h" +#include "common/array.h" +#include "common/memstream.h" +#include "backends/keymapper/keymapper.h" +#include "backends/mixer/sdl/sdl-mixer.h" +#include "common/hashmap.h" +#include "common/hash-str.h" +#include "backends/timer/sdl/sdl-timer.h" +#include "common/config-manager.h" +#include "common/recorderfile.h" +#include "backends/saves/recorder/recorder-saves.h" +#include "backends/mixer/nullmixer/nullsdl-mixer.h" +#include "backends/saves/default/default-saves.h" + + +#define g_eventRec (GUI::EventRecorder::instance()) + +namespace GUI { + class OnScreenDialog; +} + +namespace GUI { +class RandomSource; +class SeekableReadStream; +class WriteStream; + + +/** + * Our generic event recorder. + * + * TODO: Add more documentation. + */ +class EventRecorder : private Common::EventSource, public Common::Singleton, private Common::DefaultEventMapper { + friend class Common::Singleton; + EventRecorder(); + ~EventRecorder(); +public: + /** Specify operation mode of Event Recorder */ + enum RecordMode { + kPassthrough = 0, /**< kPassthrough, do nothing */ + kRecorderRecord = 1, /**< kRecorderRecord, do the recording */ + kRecorderPlayback = 2, /**< kRecorderPlayback, playback existing recording */ + kRecorderPlaybackPause = 3 /**< kRecordetPlaybackPause, interal state when user pauses the playback */ + }; + + void init(Common::String recordFileName, RecordMode mode); + void deinit(); + bool processDelayMillis(); + uint32 getRandomSeed(const Common::String &name); + void processMillis(uint32 &millis, bool skipRecord); + bool processAudio(uint32 &samples, bool paused); + void processGameDescription(const ADGameDescription *desc); + Common::SeekableReadStream *processSaveStream(const Common::String & fileName); + + /** Hooks for intercepting into GUI processing, so required events could be shoot + * or filtered out */ + void preDrawOverlayGui(); + void postDrawOverlayGui(); + + /** Set recording author + * + * @see getAuthor + */ + void setAuthor(const Common::String &author) { + _author = author; + } + + /** Set recording notes + * + * @see getNotes + */ + void setNotes(const Common::String &desc){ + _desc = desc; + } + + /** Set descriptive name of the recording + * + * @see getName + */ + void setName(const Common::String &name) { + _name = name; + } + + /** Get recording author + * + * @see getAuthor + */ + const Common::String getAuthor() { + return _author; + } + + /** Get recording notes + * + * @see setNotes + */ + const Common::String getNotes() { + return _desc; + } + + /** Get recording name + * + * @see setName + */ + const Common::String getName() { + return _name; + } + void setRedraw(bool redraw) { + _needRedraw = redraw; + } + + void registerMixerManager(SdlMixerManager *mixerManager); + void registerTimerManager(DefaultTimerManager *timerManager); + + SdlMixerManager *getMixerManager(); + DefaultTimerManager *getTimerManager(); + + void deleteRecord(const Common::String& fileName); + bool checkForContinueGame(); + + void suspendRecording() { + _savedState = _initialized; + _initialized = false; + } + + void resumeRecording() { + _initialized = _savedState; + } + + Common::StringArray listSaveFiles(const Common::String &pattern); + Common::String generateRecordFileName(const Common::String &target); + + Common::SaveFileManager *getSaveManager(Common::SaveFileManager *realSaveManager); + SDL_Surface *getSurface(int width, int height); + void RegisterEventSource(); + + /** Retrieve game screenshot and compute its checksum for comparison */ + bool grabScreenAndComputeMD5(Graphics::Surface &screen, uint8 md5[16]); + + void updateSubsystems(); + bool switchMode(); + void switchFastMode(); + +private: + virtual Common::List mapEvent(const Common::Event &ev, Common::EventSource *source); + bool notifyPoll(); + bool pollEvent(Common::Event &ev); + bool _initialized; + volatile uint32 _fakeTimer; + bool _savedState; + bool _needcontinueGame; + int _temporarySlot; + Common::String _author; + Common::String _desc; + Common::String _name; + + Common::SaveFileManager *_realSaveManager; + SdlMixerManager *_realMixerManager; + DefaultTimerManager *_timerManager; + RecorderSaveFileManager _fakeSaveManager; + NullSdlMixerManager *_fakeMixerManager; + GUI::OnScreenDialog *controlPanel; + Common::RecorderEvent _nextEvent; + + void setFileHeader(); + void setGameMd5(const ADGameDescription *gameDesc); + void getConfig(); + void getConfigFromDomain(Common::ConfigManager::Domain *domain); + void removeDifferentEntriesInDomain(Common::ConfigManager::Domain *domain); + void applyPlaybackSettings(); + + void switchMixer(); + void switchTimerManagers(); + + void togglePause(); + + void takeScreenshot(); + + bool openRecordFile(const Common::String &fileName); + + bool checkGameHash(const ADGameDescription *desc); + + void checkForKeyCode(const Common::Event &event); + bool allowMapping() const { return false; } + + volatile uint32 _lastMillis; + uint32 _lastScreenshotTime; + uint32 _screenshotPeriod; + Common::PlaybackFile *_playbackFile; + + void saveScreenShot(); + void checkRecordedMD5(); + void deleteTemporarySave(); + volatile RecordMode _recordMode; + Common::String _recordFileName; + bool _fastPlayback; + bool _needRedraw; +}; + +} // End of namespace GUI + +#else + +#ifdef SDL_BACKEND +#include "backends/timer/default/default-timer.h" +#include "backends/mixer/sdl/sdl-mixer.h" +#endif + +#define g_eventRec (GUI::EventRecorder::instance()) + +namespace GUI { + +class EventRecorder : private Common::EventSource, public Common::Singleton, private Common::DefaultEventMapper { + friend class Common::Singleton; + + public: + EventRecorder() { +#ifdef SDL_BACKEND + _timerManager = NULL; + _realMixerManager = NULL; +#endif + } + ~EventRecorder() {} + + bool pollEvent(Common::Event &ev) { return false; } + void RegisterEventSource() {} + void deinit() {} + void suspendRecording() {} + void resumeRecording() {} + void preDrawOverlayGui() {} + void postDrawOverlayGui() {} + void processGameDescription(const ADGameDescription *desc) {} + void updateSubsystems() {} + uint32 getRandomSeed(const Common::String &name) { return g_system->getMillis(); } + Common::SaveFileManager *getSaveManager(Common::SaveFileManager *realSaveManager) { return realSaveManager; } + +#ifdef SDL_BACKEND + private: + DefaultTimerManager *_timerManager; + SdlMixerManager *_realMixerManager; + + public: + DefaultTimerManager *getTimerManager() { return _timerManager; } + void registerTimerManager(DefaultTimerManager *timerManager) { _timerManager = timerManager; } + + SdlMixerManager *getMixerManager() { return _realMixerManager; } + void registerMixerManager(SdlMixerManager *mixerManager) { _realMixerManager = mixerManager; } + + void processMillis(uint32 &millis, bool skipRecord) {} + bool processDelayMillis() { return false; } +#endif + +}; + +} // namespace GUI + +#endif // ENABLE_EVENTRECORDER + +#endif diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index e2fa2580f5..3ce043cb39 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -50,6 +50,14 @@ const char * const ThemeEngine::kImageEraser = "eraser.bmp"; const char * const ThemeEngine::kImageDelbtn = "delbtn.bmp"; const char * const ThemeEngine::kImageList = "list.bmp"; const char * const ThemeEngine::kImageGrid = "grid.bmp"; +const char * const ThemeEngine::kImageStopbtn = "stopbtn.bmp"; +const char * const ThemeEngine::kImageEditbtn = "editbtn.bmp"; +const char * const ThemeEngine::kImageSwitchModebtn = "switchbtn.bmp"; +const char * const ThemeEngine::kImageFastReplaybtn = "fastreplay.bmp"; +const char * const ThemeEngine::kImageStopSmallbtn = "stopbtn_small.bmp"; +const char * const ThemeEngine::kImageEditSmallbtn = "editbtn_small.bmp"; +const char * const ThemeEngine::kImageSwitchModeSmallbtn = "switchbtn_small.bmp"; +const char * const ThemeEngine::kImageFastReplaySmallbtn = "fastreplay_small.bmp"; struct TextDrawData { const Graphics::Font *_fontPtr; @@ -465,11 +473,7 @@ void ThemeEngine::enable() { if (_enabled) return; - if (_useCursor) { - CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize); - CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true); - CursorMan.showMouse(true); - } + showCursor(); _system->showOverlay(); clearAll(); @@ -482,10 +486,8 @@ void ThemeEngine::disable() { _system->hideOverlay(); - if (_useCursor) { - CursorMan.popCursorPalette(); - CursorMan.popCursor(); - } + hideCursor(); + _enabled = false; } @@ -1787,5 +1789,20 @@ Common::String ThemeEngine::getThemeId(const Common::String &filename) { } } +void ThemeEngine::showCursor() { + if (_useCursor) { + CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize); + CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true); + CursorMan.showMouse(true); + } +} + +void ThemeEngine::hideCursor() { + if (_useCursor) { + CursorMan.popCursorPalette(); + CursorMan.popCursor(); + } +} + } // End of namespace GUI. diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 6e5fd291b7..160ceb3259 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -234,6 +234,14 @@ public: static const char *const kImageDelbtn; ///< Delete characters in the predictive dialog static const char *const kImageList; ///< List image used in save/load chooser selection static const char *const kImageGrid; ///< Grid image used in save/load chooser selection + static const char *const kImageStopbtn; ///< Stop recording button in recorder onscreen dialog + static const char *const kImageEditbtn; ///< Edit recording metadata in recorder onscreen dialog + static const char *const kImageSwitchModebtn; ///< Switch mode button in recorder onscreen dialog + static const char *const kImageFastReplaybtn; ///< Fast playback mode button in recorder onscreen dialog + static const char *const kImageStopSmallbtn; ///< Stop recording button in recorder onscreen dialog (for 320xY) + static const char *const kImageEditSmallbtn; ///< Edit recording metadata in recorder onscreen dialog (for 320xY) + static const char *const kImageSwitchModeSmallbtn; ///< Switch mode button in recorder onscreen dialog (for 320xY) + static const char *const kImageFastReplaySmallbtn; ///< Fast playback mode button in recorder onscreen dialog (for 320xY) /** * Graphics mode enumeration. @@ -275,8 +283,13 @@ public: void refresh(); void enable(); + + void showCursor(); + void hideCursor(); + void disable(); + /** * Query the set up pixel format. */ diff --git a/gui/dialog.h b/gui/dialog.h index 1773c6633e..d269a2f645 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -37,6 +37,8 @@ struct Event; namespace GUI { +class EventRecorder; + class Widget; // Some "common" commands sent to handleCommand() @@ -47,6 +49,7 @@ enum { class Dialog : public GuiObject { friend class GuiManager; + friend class EventRecorder; friend class Tooltip; protected: Widget *_mouseWidget; diff --git a/gui/editrecorddialog.cpp b/gui/editrecorddialog.cpp new file mode 100644 index 0000000000..a6a7a2560e --- /dev/null +++ b/gui/editrecorddialog.cpp @@ -0,0 +1,87 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "editrecorddialog.h" +#include "gui/widgets/edittext.h" +#include "common/translation.h" + + +namespace GUI { + +const Common::String EditRecordDialog::getAuthor() { + return _authorEdit->getEditString(); +} + +void EditRecordDialog::setAuthor(const Common::String &author) { + _authorEdit->setEditString(author); +} + +const Common::String EditRecordDialog::getNotes() { + return _notesEdit->getEditString(); +} + +void EditRecordDialog::setNotes(const Common::String &desc) { + _notesEdit->setEditString(desc); +} + +const Common::String EditRecordDialog::getName() { + return _nameEdit->getEditString(); +} + +void EditRecordDialog::setName(const Common::String &name) { + _nameEdit->setEditString(name); +} + +EditRecordDialog::~EditRecordDialog() { +} + +EditRecordDialog::EditRecordDialog(const Common::String author, const Common::String name, const Common::String notes) : Dialog("EditRecordDialog") { + new StaticTextWidget(this,"EditRecordDialog.AuthorLabel",_("Author:")); + new StaticTextWidget(this,"EditRecordDialog.NameLabel",_("Name:")); + new StaticTextWidget(this,"EditRecordDialog.NotesLabel",_("Notes:")); + _authorEdit = new EditTextWidget(this, "EditRecordDialog.AuthorEdit",""); + _notesEdit = new EditTextWidget(this, "EditRecordDialog.NotesEdit",""); + _nameEdit = new EditTextWidget(this, "EditRecordDialog.NameEdit",""); + _authorEdit->setEditString(author); + _notesEdit->setEditString(notes); + _nameEdit->setEditString(name); + new GUI::ButtonWidget(this, "EditRecordDialog.Cancel", _("Cancel"), 0, kCloseCmd); + new GUI::ButtonWidget(this, "EditRecordDialog.OK", _("Ok"), 0, kOKCmd); +} + +void EditRecordDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { + switch(cmd) { + case kCloseCmd: + setResult(kCloseCmd); + close(); + break; + case kOKCmd: + setResult(kOKCmd); + close(); + break; + default: + Dialog::handleCommand(sender, cmd, data); + break; + } +} + +} diff --git a/gui/editrecorddialog.h b/gui/editrecorddialog.h new file mode 100644 index 0000000000..c8da4521ca --- /dev/null +++ b/gui/editrecorddialog.h @@ -0,0 +1,56 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GUI_EDITRECORDDIALOG_H +#define GUI_EDITRECORDDIALOG_H + +#include "gui/dialog.h" + +namespace GUI { + +class EditTextWidget; +class StaticTextWidget; + +class EditRecordDialog : public Dialog { +private: + EditTextWidget *_notesEdit; + EditTextWidget *_nameEdit; + EditTextWidget *_authorEdit; + EditRecordDialog() : Dialog("EditRecordDialog") {}; +public: + EditRecordDialog(const Common::String author, const Common::String name, const Common::String notes); + ~EditRecordDialog(); + + const Common::String getAuthor(); + const Common::String getNotes(); + const Common::String getName(); + + void setAuthor(const Common::String &author); + void setNotes(const Common::String &desc); + void setName(const Common::String &name); + + virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); +}; + +}// End of namespace GUI + +#endif diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp index a0ef4216aa..78b40a46ce 100644 --- a/gui/gui-manager.cpp +++ b/gui/gui-manager.cpp @@ -27,6 +27,7 @@ #include "common/rect.h" #include "common/textconsole.h" #include "common/translation.h" +#include "gui/EventRecorder.h" #include "backends/keymapper/keymapper.h" @@ -253,12 +254,13 @@ Dialog *GuiManager::getTopDialog() const { void GuiManager::runLoop() { Dialog * const activeDialog = getTopDialog(); bool didSaveState = false; - int button; - uint32 time; if (activeDialog == 0) return; + // Suspend recording while GUI is shown + g_eventRec.suspendRecording(); + if (!_stateIsSaved) { saveState(); _theme->enable(); @@ -296,10 +298,10 @@ void GuiManager::runLoop() { // _theme->updateScreen(); // _system->updateScreen(); - if (lastRedraw + waitTime < _system->getMillis()) { + if (lastRedraw + waitTime < _system->getMillis(true)) { _theme->updateScreen(); _system->updateScreen(); - lastRedraw = _system->getMillis(); + lastRedraw = _system->getMillis(true); } Common::Event event; @@ -314,72 +316,21 @@ void GuiManager::runLoop() { if (activeDialog != getTopDialog() && event.type != Common::EVENT_SCREEN_CHANGED) continue; - Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y); - - switch (event.type) { - case Common::EVENT_KEYDOWN: - activeDialog->handleKeyDown(event.kbd); - break; - case Common::EVENT_KEYUP: - activeDialog->handleKeyUp(event.kbd); - break; - case Common::EVENT_MOUSEMOVE: - activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); - - if (mouse.x != _lastMousePosition.x || mouse.y != _lastMousePosition.y) { - _lastMousePosition.x = mouse.x; - _lastMousePosition.y = mouse.y; - _lastMousePosition.time = _system->getMillis(); - } + processEvent(event, activeDialog); + if (event.type == Common::EVENT_MOUSEMOVE) { tooltipCheck = true; - break; - // We don't distinguish between mousebuttons (for now at least) - case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_RBUTTONDOWN: - button = (event.type == Common::EVENT_LBUTTONDOWN ? 1 : 2); - time = _system->getMillis(); - if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay) - && ABS(_lastClick.x - event.mouse.x) < 3 - && ABS(_lastClick.y - event.mouse.y) < 3) { - _lastClick.count++; - } else { - _lastClick.x = event.mouse.x; - _lastClick.y = event.mouse.y; - _lastClick.count = 1; - } - _lastClick.time = time; - activeDialog->handleMouseDown(mouse.x, mouse.y, button, _lastClick.count); - break; - case Common::EVENT_LBUTTONUP: - case Common::EVENT_RBUTTONUP: - button = (event.type == Common::EVENT_LBUTTONUP ? 1 : 2); - activeDialog->handleMouseUp(mouse.x, mouse.y, button, _lastClick.count); - break; - case Common::EVENT_WHEELUP: - activeDialog->handleMouseWheel(mouse.x, mouse.y, -1); - break; - case Common::EVENT_WHEELDOWN: - activeDialog->handleMouseWheel(mouse.x, mouse.y, 1); - break; - case Common::EVENT_SCREEN_CHANGED: - screenChange(); - break; - default: -#ifdef ENABLE_KEYMAPPER - activeDialog->handleOtherEvent(event); -#endif - break; } - if (lastRedraw + waitTime < _system->getMillis()) { + + if (lastRedraw + waitTime < _system->getMillis(true)) { _theme->updateScreen(); _system->updateScreen(); - lastRedraw = _system->getMillis(); + lastRedraw = _system->getMillis(true); } } - if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis()) { + if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis(true)) { Widget *wdg = activeDialog->findWidget(_lastMousePosition.x, _lastMousePosition.y); if (wdg && wdg->hasTooltip() && !(wdg->getFlags() & WIDGET_PRESSED)) { Tooltip *tooltip = new Tooltip(); @@ -409,6 +360,9 @@ void GuiManager::runLoop() { restoreState(); _useStdCursor = false; } + + // Resume recording once GUI is shown + g_eventRec.resumeRecording(); } #pragma mark - @@ -492,7 +446,7 @@ void GuiManager::setupCursor() { // very much. We could plug in a different cursor here if we like to. void GuiManager::animateCursor() { - int time = _system->getMillis(); + int time = _system->getMillis(true); if (time > _cursorAnimateTimer + kCursorAnimateDelay) { for (int i = 0; i < 15; i++) { if ((i < 6) || (i > 8)) { @@ -537,4 +491,64 @@ void GuiManager::screenChange() { _system->updateScreen(); } +void GuiManager::processEvent(const Common::Event &event, Dialog *const activeDialog) { + int button; + uint32 time; + Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y); + switch (event.type) { + case Common::EVENT_KEYDOWN: + activeDialog->handleKeyDown(event.kbd); + break; + case Common::EVENT_KEYUP: + activeDialog->handleKeyUp(event.kbd); + break; + case Common::EVENT_MOUSEMOVE: + activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); + + if (mouse.x != _lastMousePosition.x || mouse.y != _lastMousePosition.y) { + _lastMousePosition.x = mouse.x; + _lastMousePosition.y = mouse.y; + _lastMousePosition.time = _system->getMillis(true); + } + + break; + // We don't distinguish between mousebuttons (for now at least) + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: + button = (event.type == Common::EVENT_LBUTTONDOWN ? 1 : 2); + time = _system->getMillis(true); + if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay) + && ABS(_lastClick.x - event.mouse.x) < 3 + && ABS(_lastClick.y - event.mouse.y) < 3) { + _lastClick.count++; + } else { + _lastClick.x = event.mouse.x; + _lastClick.y = event.mouse.y; + _lastClick.count = 1; + } + _lastClick.time = time; + activeDialog->handleMouseDown(mouse.x, mouse.y, button, _lastClick.count); + break; + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONUP: + button = (event.type == Common::EVENT_LBUTTONUP ? 1 : 2); + activeDialog->handleMouseUp(mouse.x, mouse.y, button, _lastClick.count); + break; + case Common::EVENT_WHEELUP: + activeDialog->handleMouseWheel(mouse.x, mouse.y, -1); + break; + case Common::EVENT_WHEELDOWN: + activeDialog->handleMouseWheel(mouse.x, mouse.y, 1); + break; + case Common::EVENT_SCREEN_CHANGED: + screenChange(); + break; + default: + #ifdef ENABLE_KEYMAPPER + activeDialog->handleOtherEvent(event); + #endif + break; + } +} + } // End of namespace GUI diff --git a/gui/gui-manager.h b/gui/gui-manager.h index 49542fd001..b52d91ba08 100644 --- a/gui/gui-manager.h +++ b/gui/gui-manager.h @@ -35,6 +35,10 @@ namespace Graphics { class Font; } +namespace Common { + struct Event; +} + namespace GUI { class Dialog; @@ -67,6 +71,8 @@ public: // until no dialogs are active anymore. void runLoop(); + void processEvent(const Common::Event &event, Dialog *const activeDialog); + bool isActive() const { return ! _dialogStack.empty(); } bool loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx = ThemeEngine::kGfxDisabled, bool force = false); diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 4e35b54db8..77d4cce794 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -37,6 +37,11 @@ #include "gui/message.h" #include "gui/gui-manager.h" #include "gui/options.h" +#ifdef ENABLE_EVENTRECORDER +#include "gui/onscreendialog.h" +#include "gui/recorderdialog.h" +#include "gui/EventRecorder.h" +#endif #include "gui/saveload.h" #include "gui/widgets/edittext.h" #include "gui/widgets/list.h" @@ -596,7 +601,6 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat LauncherDialog::LauncherDialog() : Dialog(0, 0, 320, 200) { _backgroundType = GUI::ThemeEngine::kDialogBackgroundMain; - const int screenW = g_system->getOverlayWidth(); const int screenH = g_system->getOverlayHeight(); @@ -779,10 +783,9 @@ void LauncherDialog::updateListing() { } void LauncherDialog::addGame() { - int modifiers = g_system->getEventManager()->getModifierState(); #ifndef DISABLE_MASS_ADD - const bool massAdd = (modifiers & Common::KBD_SHIFT) != 0; + const bool massAdd = checkModifier(Common::KBD_SHIFT); if (massAdd) { MessageDialog alert(_("Do you really want to run the mass game detector? " @@ -975,6 +978,49 @@ void LauncherDialog::editGame(int item) { } } +void LauncherDialog::loadGameButtonPressed(int item) { +#ifdef ENABLE_EVENTRECORDER + const bool shiftPressed = checkModifier(Common::KBD_SHIFT); + if (shiftPressed) { + recordGame(item); + } else { + loadGame(item); + } + updateButtons(); +#else + loadGame(item); +#endif +} + +#ifdef ENABLE_EVENTRECORDER +void LauncherDialog::recordGame(int item) { + RecorderDialog recorderDialog; + MessageDialog alert(_("Do you want to load savegame?"), + _("Yes"), _("No")); + switch(recorderDialog.runModal(_domains[item])) { + case RecorderDialog::kRecordDialogClose: + break; + case RecorderDialog::kRecordDialogPlayback: + ConfMan.setActiveDomain(_domains[item]); + close(); + ConfMan.set("record_mode", "playback", ConfigManager::kTransientDomain); + ConfMan.set("record_file_name", recorderDialog.getFileName(), ConfigManager::kTransientDomain); + break; + case RecorderDialog::kRecordDialogRecord: + ConfMan.setActiveDomain(_domains[item]); + if (alert.runModal() == GUI::kMessageOK) { + loadGame(item); + } + close(); + g_eventRec.setAuthor(recorderDialog._author); + g_eventRec.setName(recorderDialog._name); + g_eventRec.setNotes(recorderDialog._notes); + ConfMan.set("record_mode", "record", ConfigManager::kTransientDomain); + break; + } +} +#endif + void LauncherDialog::loadGame(int item) { String gameId = ConfMan.get("gameid", _domains[item]); if (gameId.empty()) @@ -1039,7 +1085,7 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat editGame(item); break; case kLoadGameCmd: - loadGame(item); + loadGameButtonPressed(item); break; case kOptionsCmd: { GlobalOptionsDialog options; @@ -1109,20 +1155,28 @@ void LauncherDialog::updateButtons() { _loadButton->setEnabled(en); _loadButton->draw(); } + switchButtonsText(_addButton, "~A~dd Game...", "Mass Add..."); +#ifdef ENABLE_EVENTRECORDER + switchButtonsText(_loadButton, "~L~oad...", "Record..."); +#endif +} - // Update the label of the "Add" button depending on whether shift is pressed or not - int modifiers = g_system->getEventManager()->getModifierState(); - const bool massAdd = (modifiers & Common::KBD_SHIFT) != 0; +// Update the label of the button depending on whether shift is pressed or not +void LauncherDialog::switchButtonsText(ButtonWidget *button, const char *normalText, const char *shiftedText) { + const bool shiftPressed = checkModifier(Common::KBD_SHIFT); const bool lowRes = g_system->getOverlayWidth() <= 320; - const char *newAddButtonLabel = massAdd - ? (lowRes ? _c("Mass Add...", "lowres") : _("Mass Add...")) - : (lowRes ? _c("~A~dd Game...", "lowres") : _("~A~dd Game...")); + const char *newAddButtonLabel = shiftPressed + ? (lowRes ? _c(shiftedText, "lowres") : _(shiftedText)) + : (lowRes ? _c(normalText, "lowres") : _(normalText)); - if (_addButton->getLabel() != newAddButtonLabel) - _addButton->setLabel(newAddButtonLabel); + if (button->getLabel() != newAddButtonLabel) + button->setLabel(newAddButtonLabel); } + + + void LauncherDialog::reflowLayout() { #ifndef DISABLE_FANCY_THEMES if (g_gui.xmlEval()->getVar("Globals.ShowLauncherLogo") == 1 && g_gui.theme()->supportsImages()) { @@ -1186,4 +1240,9 @@ void LauncherDialog::reflowLayout() { Dialog::reflowLayout(); } +bool LauncherDialog::checkModifier(int checkedModifier) { + int modifiers = g_system->getEventManager()->getModifierState(); + return (modifiers & checkedModifier) != 0; +} + } // End of namespace GUI diff --git a/gui/launcher.h b/gui/launcher.h index fc0484350a..2ab47be98d 100644 --- a/gui/launcher.h +++ b/gui/launcher.h @@ -56,7 +56,7 @@ protected: ListWidget *_list; ButtonWidget *_addButton; Widget *_startButton; - Widget *_loadButton; + ButtonWidget *_loadButton; Widget *_editButton; Widget *_removeButton; #ifndef DISABLE_FANCY_THEMES @@ -80,6 +80,7 @@ protected: void updateListing(); void updateButtons(); + void switchButtonsText(ButtonWidget *button, const char *normalText, const char *shiftedText); void open(); void close(); @@ -99,6 +100,16 @@ protected: */ void editGame(int item); + /** + * Facade for "Load..."/"Record..." buttons. + */ + void loadGameButtonPressed(int item); + + /** + * Handle "Record..." button. + */ + void recordGame(int item); + /** * Handle "Load..." button. */ @@ -111,6 +122,8 @@ protected: * @target name of target to select */ void selectTarget(const String &target); +private: + bool checkModifier(int modifier); }; } // End of namespace GUI diff --git a/gui/module.mk b/gui/module.mk index bda3c88cd5..338e43c6a4 100644 --- a/gui/module.mk +++ b/gui/module.mk @@ -7,6 +7,7 @@ MODULE_OBJS := \ debugger.o \ dialog.o \ error.o \ + EventRecorder.o \ gui-manager.o \ launcher.o \ massadd.o \ @@ -38,6 +39,13 @@ MODULE_OBJS += \ browser.o endif +ifdef ENABLE_EVENTRECORDER +MODULE_OBJS += \ + editrecorddialog.o \ + onscreendialog.o \ + recorderdialog.o +endif + ifdef USE_FLUIDSYNTH MODULE_OBJS += \ fluidsynth-dialog.o diff --git a/gui/onscreendialog.cpp b/gui/onscreendialog.cpp new file mode 100644 index 0000000000..efe8038e68 --- /dev/null +++ b/gui/onscreendialog.cpp @@ -0,0 +1,231 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/system.h" + +#include "gui/gui-manager.h" + +#include "gui/EventRecorder.h" + +#include "common/events.h" +#include "common/rect.h" +#include "common/translation.h" + +#include "graphics/cursorman.h" + +#include "gui/editrecorddialog.h" +#include "gui/ThemeEval.h" + +#include "gui/onscreendialog.h" + +namespace GUI { + +bool OnScreenDialog::isVisible() const { + return true; +} + +enum { + kStopCmd = 'STOP', + kEditCmd = 'EDIT', + kSwitchModeCmd = 'MODE', + kFastModeCmd = 'FAST' +}; + +void OnScreenDialog::reflowLayout() { + GuiObject::reflowLayout(); +} + +void OnScreenDialog::releaseFocus() { +} + +OnScreenDialog::OnScreenDialog(bool isRecord) : Dialog("OnScreenDialog") { + _x = _y = 0; + +#ifndef DISABLE_FANCY_THEMES + if (g_gui.xmlEval()->getVar("Globals.OnScreenDialog.ShowPics") == 1 && g_gui.theme()->supportsImages()) { + GUI::PicButtonWidget *btn; + btn = new PicButtonWidget(this, "OnScreenDialog.StopButton", 0, kStopCmd, 0); + btn->useThemeTransparency(true); + + if (g_system->getOverlayWidth() > 320) + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageStopbtn)); + else + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageStopSmallbtn)); + + if (isRecord) { + btn = new PicButtonWidget(this, "OnScreenDialog.EditButton", 0, kEditCmd, 0); + btn->useThemeTransparency(true); + + if (g_system->getOverlayWidth() > 320) + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageEditbtn)); + else + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageEditSmallbtn)); + } else { + btn = new PicButtonWidget(this, "OnScreenDialog.SwitchModeButton", 0, kSwitchModeCmd, 0); + btn->useThemeTransparency(true); + if (g_system->getOverlayWidth() > 320) + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageSwitchModebtn)); + else + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageSwitchModeSmallbtn)); + + btn = new PicButtonWidget(this, "OnScreenDialog.FastReplayButton", 0, kFastModeCmd, 0); + btn->useThemeTransparency(true); + if (g_system->getOverlayWidth() > 320) + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageFastReplaybtn)); + else + btn->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageFastReplaySmallbtn)); + } + } else +#endif + { + GUI::ButtonWidget *btn; + if (g_system->getOverlayWidth() > 320) + btn = new ButtonWidget(this, "OnScreenDialog.StopButton", "[ ]", _("Stop"), kStopCmd); + else + btn = new ButtonWidget(this, "OnScreenDialog.StopButton", "[]", _("Stop"), kStopCmd); + + if (isRecord) { + btn = new ButtonWidget(this, "OnScreenDialog.EditButton", "E", _("Edit record description"), kEditCmd); + } else { + btn = new ButtonWidget(this, "OnScreenDialog.SwitchModeButton", "G", _("Switch to Game"), kSwitchModeCmd); + + btn = new ButtonWidget(this, "OnScreenDialog.FastReplayButton", ">>", _("Fast replay"), kFastModeCmd); + } + } + + + text = new GUI::StaticTextWidget(this, "OnScreenDialog.TimeLabel", "00:00:00"); + _enableDrag = false; + _mouseOver = false; + _editDlgShown = false; +} + +void OnScreenDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + Common::Event eventRTL; + switch (cmd) { + case kStopCmd: + eventRTL.type = Common::EVENT_RTL; + g_system->getEventManager()->pushEvent(eventRTL); + close(); + break; + case kEditCmd: + dlg = new EditRecordDialog(g_eventRec.getAuthor(), g_eventRec.getName(), g_eventRec.getNotes()); + CursorMan.lock(false); + g_eventRec.setRedraw(false); + g_system->showOverlay(); + _editDlgShown = true; + dlg->runModal(); + _editDlgShown = false; + g_system->hideOverlay(); + g_eventRec.setRedraw(true); + CursorMan.lock(true); + g_eventRec.setAuthor(((EditRecordDialog *)dlg)->getAuthor()); + g_eventRec.setName(((EditRecordDialog *)dlg)->getName()); + g_eventRec.setNotes(((EditRecordDialog *)dlg)->getNotes()); + delete dlg; + break; + case kSwitchModeCmd: + if (g_eventRec.switchMode()) { + close(); + } + break; + case kFastModeCmd: + g_eventRec.switchFastMode(); + break; + } +} + +void OnScreenDialog::setReplayedTime(uint32 newTime) { + if (newTime - lastTime > 1000) { + uint32 seconds = newTime / 1000; + text->setLabel(Common::String::format("%.2d:%.2d:%.2d", seconds / 3600 % 24, seconds / 60 % 60, seconds % 60)); + lastTime = newTime; + } +} + +OnScreenDialog::~OnScreenDialog() { +} + +void OnScreenDialog::handleMouseMoved(int x, int y, int button) { + if (_enableDrag) { + _x = _x + x - _dragPoint.x; + _y = _y + y - _dragPoint.y; + } + Dialog::handleMouseMoved(x, y, button); + if (isMouseOver(x, y)) { + if (_mouseOver == false) { + g_gui.theme()->showCursor(); + CursorMan.lock(true); + } + _mouseOver = true; + } else { + if (_mouseOver == true) { + CursorMan.lock(false); + g_gui.theme()->hideCursor(); + } + _mouseOver = false; + } +} + +void OnScreenDialog::handleMouseDown(int x, int y, int button, int clickCount) { + if (isMouseOver(x, y)) { + _dragPoint.x = x; + _dragPoint.y = y; + _enableDrag = true; + } + Dialog::handleMouseDown(x, y, button, clickCount); +} + +void OnScreenDialog::handleMouseUp(int x, int y, int button, int clickCount) { + if (isMouseOver(x, y)) { + + } + _enableDrag = false; + Dialog::handleMouseUp(x, y, button, clickCount); +} + +bool OnScreenDialog::isMouseOver(int x, int y) { + return (x >= 0 && x < _w && y >= 0 && y < _h); +} + +bool OnScreenDialog::isMouseOver() { + return _mouseOver; +} + +void OnScreenDialog::close() { + CursorMan.lock(false); + Dialog::close(); +} + +Dialog *OnScreenDialog::getActiveDlg() { + if (_editDlgShown) { + return dlg; + } else { + return this; + } +} + +bool OnScreenDialog::isEditDlgVisible() { + return _editDlgShown; +} + +} diff --git a/gui/onscreendialog.h b/gui/onscreendialog.h new file mode 100644 index 0000000000..4f3839acb6 --- /dev/null +++ b/gui/onscreendialog.h @@ -0,0 +1,64 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GUI_ONSCREENDIALOG_H +#define GUI_ONSCREENDIALOG_H + +#include "gui/dialog.h" +#include "gui/widget.h" + +namespace GUI { + +class OnScreenDialog : public Dialog { +private: + uint32 lastTime; + bool _enableDrag; + bool _mouseOver; + bool _editDlgShown; + Common::Point _dragPoint; + GUI::StaticTextWidget *text; + Dialog *dlg; + bool isMouseOver(int x, int y); +public: + OnScreenDialog(bool recordingMode); + ~OnScreenDialog(); + virtual void close(); + virtual bool isVisible() const; + virtual void reflowLayout(); + + void setReplayedTime(uint32 newTime); + + virtual void handleMouseMoved(int x, int y, int button); + virtual void handleMouseDown(int x, int y, int button, int clickCount); + virtual void handleMouseUp(int x, int y, int button, int clickCount); + void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); + + bool isMouseOver(); + bool isEditDlgVisible(); + Dialog *getActiveDlg(); +protected: + virtual void releaseFocus(); +}; + +} // End of namespace GUI + +#endif diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp new file mode 100644 index 0000000000..55f342d4a1 --- /dev/null +++ b/gui/recorderdialog.cpp @@ -0,0 +1,291 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "common/algorithm.h" +#include "common/bufferedstream.h" +#include "common/savefile.h" +#include "common/system.h" +#include "graphics/colormasks.h" +#include "graphics/palette.h" +#include "graphics/scaler.h" +#include "graphics/thumbnail.h" +#include "common/translation.h" +#include "gui/widgets/list.h" +#include "gui/editrecorddialog.h" +#include "gui/EventRecorder.h" +#include "gui/message.h" +#include "gui/saveload.h" +#include "common/system.h" +#include "gui/ThemeEval.h" +#include "gui/gui-manager.h" +#include "recorderdialog.h" + +#define MAX_RECORDS_NAMES 0xFF + +namespace GUI { + +enum { + kRecordCmd = 'RCRD', + kPlaybackCmd = 'PBCK', + kDeleteCmd = 'DEL ', + kNextScreenshotCmd = 'NEXT', + kPrevScreenshotCmd = 'PREV', + kEditRecordCmd = 'EDIT' +}; + +RecorderDialog::RecorderDialog() : Dialog("RecorderDialog"), _list(0), _currentScreenshot(0) { + _backgroundType = ThemeEngine::kDialogBackgroundSpecial; + + new StaticTextWidget(this, "SaveLoadChooser.Title", _("Recorder or Playback Gameplay")); + + _list = new GUI::ListWidget(this, "RecorderDialog.List"); + _list->setNumberingMode(GUI::kListNumberingOff); + + _deleteButton = new GUI::ButtonWidget(this, "RecorderDialog.Delete", _("Delete"), 0, kDeleteCmd); + new GUI::ButtonWidget(this, "RecorderDialog.Cancel", _("Cancel"), 0, kCloseCmd); + new GUI::ButtonWidget(this, "RecorderDialog.Record", _("Record"), 0, kRecordCmd); + _playbackButton = new GUI::ButtonWidget(this, "RecorderDialog.Playback", _("Playback"), 0, kPlaybackCmd); + + _editButton = new GUI::ButtonWidget(this, "RecorderDialog.Edit", _("Edit"), 0, kEditRecordCmd); + + _editButton->setEnabled(false); + _deleteButton->setEnabled(false); + _playbackButton->setEnabled(false); + + _gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10); + _container = new GUI::ContainerWidget(this, 0, 0, 10, 10); + if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 1) { + new GUI::ButtonWidget(this,"RecorderDialog.NextScreenShotButton", "<", 0, kPrevScreenshotCmd); + new GUI::ButtonWidget(this, "RecorderDialog.PreviousScreenShotButton", ">", 0, kNextScreenshotCmd); + _currentScreenshotText = new StaticTextWidget(this, "RecorderDialog.currentScreenshot", "0/0"); + _authorText = new StaticTextWidget(this, "RecorderDialog.Author", _("Author: ")); + _notesText = new StaticTextWidget(this, "RecorderDialog.Notes", _("Notes: ")); + } + if (_gfxWidget) + _gfxWidget->setGfx(0); +} + + +void RecorderDialog::reflowLayout() { + if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 1) { + int16 x, y; + uint16 w, h; + + if (!g_gui.xmlEval()->getWidgetData("RecorderDialog.Thumbnail", x, y, w, h)) { + error("Error when loading position data for Recorder Thumbnails"); + } + + int thumbW = kThumbnailWidth; + int thumbH = kThumbnailHeight2; + int thumbX = x + (w >> 1) - (thumbW >> 1); + int thumbY = y + kLineHeight; + + _container->resize(x, y, w, h); + _gfxWidget->resize(thumbX, thumbY, thumbW, thumbH); + + _container->setVisible(true); + _gfxWidget->setVisible(true); + updateSelection(false); + } else { + _container->setVisible(false); + _gfxWidget->setVisible(false); + } + Dialog::reflowLayout(); +} + + + +void RecorderDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + switch(cmd) { + case kEditRecordCmd: { + if (_list->getSelected() >= 0) { + EditRecordDialog editDlg(_fileHeaders[_list->getSelected()].author, _fileHeaders[_list->getSelected()].name, _fileHeaders[_list->getSelected()].notes); + if (editDlg.runModal() != kOKCmd) { + return; + } + _playbackFile.openRead(_fileHeaders[_list->getSelected()].fileName); + _playbackFile.getHeader().author = editDlg.getAuthor(); + _playbackFile.getHeader().name = editDlg.getName(); + _playbackFile.getHeader().notes = editDlg.getNotes(); + _playbackFile.updateHeader(); + _fileHeaders[_list->getSelected()] = _playbackFile.getHeader(); + int oldselection = _list->getSelected(); + updateList(); + _list->setSelected(oldselection); + updateSelection(true); + _playbackFile.close(); + } + } + break; + case kNextScreenshotCmd: + ++_currentScreenshot; + updateScreenshot(); + break; + case kPrevScreenshotCmd: + --_currentScreenshot; + updateScreenshot(); + break; + case kDeleteCmd: + if (_list->getSelected() >= 0) { + MessageDialog alert(_("Do you really want to delete this record?"), + _("Delete"), _("Cancel")); + if (alert.runModal() == GUI::kMessageOK) { + _playbackFile.close(); + g_eventRec.deleteRecord(_fileHeaders[_list->getSelected()].fileName); + _list->setSelected(-1); + updateList(); + } + } + break; + case GUI::kListSelectionChangedCmd: + updateSelection(true); + break; + case kRecordCmd: { + TimeDate t; + Common::String gameId = ConfMan.get("gameid", _target); + const EnginePlugin *plugin = 0; + GameDescriptor desc = EngineMan.findGame(gameId, &plugin); + g_system->getTimeAndDate(t); + EditRecordDialog editDlg("Unknown Author", Common::String::format("%.2d.%.2d.%.4d ", t.tm_mday, t.tm_mon, 1900 + t.tm_year) + desc.description(), ""); + if (editDlg.runModal() != kOKCmd) { + return; + } + _author = editDlg.getAuthor(); + _name = editDlg.getName(); + _notes = editDlg.getNotes(); + _filename = g_eventRec.generateRecordFileName(_target); + setResult(kRecordDialogRecord); + close(); + } + break; + case kPlaybackCmd: + if (_list->getSelected() >= 0) { + _filename = _fileHeaders[_list->getSelected()].fileName; + setResult(kRecordDialogPlayback); + close(); + } + break; + case kCloseCmd: + setResult(kRecordDialogClose); + default: + Dialog::handleCommand(sender, cmd, data); + } + } + +void RecorderDialog::updateList() { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::String pattern(_target+".r??"); + Common::StringArray files = saveFileMan->listSavefiles(pattern); + Common::PlaybackFile file; + Common::StringArray namesList; + _fileHeaders.clear(); + for (Common::StringArray::iterator i = files.begin(); i != files.end(); ++i) { + if (file.openRead(*i)) { + namesList.push_back(file.getHeader().name); + _fileHeaders.push_back(file.getHeader()); + } + file.close(); + } + _list->setList(namesList); + _list->draw(); +} + +int RecorderDialog::runModal(Common::String &target) { + _target = target; + updateList(); + return Dialog::runModal(); +} + +RecorderDialog::~RecorderDialog() { +} + +void RecorderDialog::updateSelection(bool redraw) { + if (_list->getSelected() >= 0) { + _editButton->setEnabled(true); + _deleteButton->setEnabled(true); + _playbackButton->setEnabled(true); + } + + if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") != 1) + return; + + _gfxWidget->setGfx(-1, -1, 0, 0, 0); + _screenShotsCount = 0; + _currentScreenshot = 0; + updateScreenShotsText(); + if (_list->getSelected() >= 0) { + _authorText->setLabel(_("Author: ") + _fileHeaders[_list->getSelected()].author); + _notesText->setLabel(_("Notes: ") + _fileHeaders[_list->getSelected()].notes); + + _firstScreenshotUpdate = true; + updateScreenshot(); + if ((_screenShotsCount) > 0) { + _currentScreenshot = 1; + } + updateScreenshot(); + } else { + _authorText->setLabel(_("Author: ")); + _notesText->setLabel(_("Notes: ")); + _screenShotsCount = -1; + _currentScreenshot = 0; + _gfxWidget->setGfx(-1, -1, 0, 0, 0); + _gfxWidget->draw(); + updateScreenShotsText(); + } +} + +void RecorderDialog::updateScreenshot() { + if (_list->getSelected() == -1) { + return; + } + if (_currentScreenshot < 1) { + _currentScreenshot = _screenShotsCount; + } + if (_currentScreenshot > _screenShotsCount) { + _currentScreenshot = 1; + } + if (_firstScreenshotUpdate) { + _playbackFile.openRead(_fileHeaders[_list->getSelected()].fileName); + _screenShotsCount = _playbackFile.getScreensCount(); + _firstScreenshotUpdate = false; + } + Graphics::Surface *srcsf = _playbackFile.getScreenShot(_currentScreenshot); + if (srcsf != NULL) { + Graphics::Surface *destsf = Graphics::scale(*srcsf, _gfxWidget->getWidth(), _gfxWidget->getHeight()); + _gfxWidget->setGfx(destsf); + updateScreenShotsText(); + delete destsf; + delete srcsf; + } else { + _gfxWidget->setGfx(-1, -1, 0, 0, 0); + } + _gfxWidget->draw(); +} + +void RecorderDialog::updateScreenShotsText() { + if (_screenShotsCount == -1) { + _currentScreenshotText->setLabel(Common::String::format("%d / ?", _currentScreenshot)); + } else { + _currentScreenshotText->setLabel(Common::String::format("%d / %d", _currentScreenshot, _screenShotsCount)); + } +} + +} // End of namespace GUI diff --git a/gui/recorderdialog.h b/gui/recorderdialog.h new file mode 100644 index 0000000000..eb690a4f38 --- /dev/null +++ b/gui/recorderdialog.h @@ -0,0 +1,81 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef GUI_RECORDER_DIALOG_H +#define GUI_RECORDER_DIALOG_H +#include "common/stream.h" +#include "common/recorderfile.h" +#include "gui/dialog.h" +namespace GUI { + +class ListWidget; +class GraphicsWidget; +class ButtonWidget; +class CommandSender; +class ContainerWidget; +class StaticTextWidget; + +class RecorderDialog : public GUI::Dialog { +private: + bool _firstScreenshotUpdate; + Common::PlaybackFile _playbackFile; + Common::String _target; + Common::String _filename; + int _currentScreenshot; + int _screenShotsCount; + Common::Array _fileHeaders; + GUI::ListWidget *_list; + GUI::ContainerWidget *_container; + GUI::GraphicsWidget *_gfxWidget; + GUI::StaticTextWidget *_currentScreenshotText; + GUI::StaticTextWidget *_authorText; + GUI::StaticTextWidget *_notesText; + GUI::ButtonWidget *_editButton; + GUI::ButtonWidget *_deleteButton; + GUI::ButtonWidget *_playbackButton; + + void updateList(); + void updateScreenShotsText(); + void updateSelection(bool redraw); + void updateScreenshot(); +public: + Common::String _author; + Common::String _name; + Common::String _notes; + enum DialogResult { + kRecordDialogClose, + kRecordDialogRecord, + kRecordDialogPlayback + }; + RecorderDialog(); + ~RecorderDialog(); + + virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); + virtual void reflowLayout(); + + int runModal(Common::String &target); + const Common::String getFileName() {return _filename;} +}; + +} // End of namespace GUI + + +#endif diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 6d8e6baac7..1b6ae3ec27 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -610,50 +610,54 @@ "/> " " " " " -" " +" " " " -" " -" " -" " -" " +" " +" " +" " +" " " " " " " " " " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " " " +" " +" " +" " " " " " " " " " " " " " " " " " " " +" " +" " " " " " -" " +" " " " -" " +" " " " @@ -702,38 +712,39 @@ " " " " " " -" " +" " " " " " " " " " " " -" " +" " +" " " " " " " " " " " " " " " " -" " -" " +" " +" " " " @@ -741,7 +752,7 @@ "height='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -760,10 +771,10 @@ " " " " " " -" " +" " " " " " -" " +" " " " " " " " " " -" " +" " " " @@ -784,7 +795,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -802,7 +813,7 @@ " " " " " " -" " +" " " " @@ -810,7 +821,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -818,7 +829,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -826,7 +837,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -840,7 +851,7 @@ "type='Radiobutton' " "/> " " " -" " +" " " " @@ -854,8 +865,9 @@ " " " " " " -" " -" " +" " +" " +" " " " @@ -866,7 +878,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -877,7 +889,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -888,8 +900,8 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " @@ -897,8 +909,8 @@ " " " " " " -" " -" " +" " +" " " " @@ -906,7 +918,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -921,7 +933,7 @@ " " -" " +" " " " @@ -934,14 +946,14 @@ "/> " " " " " " " " " " " " " -" " +" " " " @@ -959,7 +971,7 @@ " " " " " " -" " +" " " " @@ -971,7 +983,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -983,7 +995,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -1007,7 +1019,7 @@ " " " " " " -" " +" " " " @@ -1015,31 +1027,25 @@ "height='Globals.Line.Height' " "/> " " " -" " +" " " " " " " " -" " +" " " " " " " " -" " +" " " " " " " " " " -" " +" " " " " " -" " +" " " " " " " " " " -" " +" " " " @@ -1097,7 +1103,7 @@ " " " " " " -" " +" " " " @@ -1105,7 +1111,7 @@ " " " " " " -" " +" " " " @@ -1113,7 +1119,7 @@ " " " " " " -" " +" " " " @@ -1121,7 +1127,7 @@ " " " " " " -" " +" " " " @@ -1129,43 +1135,34 @@ " " " " " " -" " -" " +" " +" " " " " " " " -" " +" " " " " " " " -" " -" " +" " " " " " " " -" " +" " " " " " " " " " -" " -" " +" " +" " " " @@ -1187,7 +1184,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -1199,7 +1196,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -1210,7 +1207,7 @@ " " " " " " -" " +" " " " @@ -1235,55 +1232,57 @@ " " " " " " -" " +" " " " " " -" " +" " +" " " " " " -" " +" " " " " " " " -" " -" " +" " " " " " " " " " " " " " -" " +" " +" " +" " " " @@ -1294,7 +1293,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -1305,7 +1304,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -1316,34 +1315,33 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " " " -" " +" " +" " +" " " " -" " " " " " " " " " -" " -" " -" " +" " " " @@ -1354,8 +1352,8 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " @@ -1372,7 +1370,7 @@ " " " " " " -" " +" " " " " " " " " " -" " +" " " " @@ -1450,7 +1448,7 @@ " " " " " " -" " +" " " " @@ -1505,7 +1503,7 @@ " " " " " " -" " +" " " " " " " " " " -" " -" " +" " +" " +" " +" " +" " +" " +" " " " -" " +" " +" " +" " " " -" " +" " " " @@ -1546,7 +1559,7 @@ " " " " " " " " +" " " " " " " " " " -" " -" " +" " +" " " " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " -" " +" " " " @@ -1588,7 +1718,7 @@ " " " " " " " " " " " " -" " +" " " " " " " " -" " +" " " " @@ -1630,20 +1760,20 @@ " " " " " " -" " +" " " " " " " " " " " " " " " " " " -" " +" " " " -" " +" " " " " " " " +" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " -" " +" " " " " " " " " " -" " -" " +" " +" " " " +" " " " " " " " " " " " " " -" " +" " " " -" " -" " -" " -" " +" " +" " +" " +" " " " " " " " " " -" " -" " -" " -" " -" " -" " -" " -" " -" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " " " -" " -" " -" " " " " " " " " " " " " " " " " " " " +" " +" " " " " " -" " +" " " " -" " +" " " " @@ -1835,39 +1973,38 @@ " " " " " " -" " +" " " " " " " " " " " " -" " -" " +" " " " " " " " " " " " " " " " -" " -" " +" " +" " " " @@ -1875,7 +2012,7 @@ "height='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -1894,10 +2031,10 @@ " " " " " " -" " +" " " " " " -" " +" " " " " " " " " " -" " +" " " " @@ -1918,7 +2055,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -1936,7 +2073,7 @@ " " " " " " -" " +" " " " @@ -1944,7 +2081,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -1952,7 +2089,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -1960,7 +2097,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -1974,7 +2111,7 @@ "type='Radiobutton' " "/> " " " -" " +" " " " @@ -1988,9 +2125,8 @@ " " " " " " -" " -" " -" " +" " +" " " " @@ -2001,7 +2137,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -2012,7 +2148,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -2023,8 +2159,8 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " @@ -2032,8 +2168,8 @@ " " " " " " -" " -" " +" " +" " " " @@ -2041,7 +2177,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -2056,7 +2192,7 @@ " " -" " +" " " " @@ -2069,14 +2205,14 @@ "/> " " " " " " " " " " " " " -" " +" " " " @@ -2094,7 +2230,7 @@ " " " " " " -" " +" " " " @@ -2106,7 +2242,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -2118,7 +2254,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -2142,7 +2278,7 @@ " " " " " " -" " +" " " " @@ -2150,25 +2286,31 @@ "height='Globals.Line.Height' " "/> " " " -" " +" " " " " " " " -" " +" " " " " " " " -" " +" " " " " " " " " " -" " +" " " " " " -" " +" " " " " " " " " " -" " +" " " " @@ -2226,7 +2368,7 @@ " " " " " " -" " +" " " " @@ -2234,7 +2376,7 @@ " " " " " " -" " +" " " " @@ -2242,7 +2384,7 @@ " " " " " " -" " +" " " " @@ -2250,7 +2392,7 @@ " " " " " " -" " +" " " " @@ -2258,34 +2400,43 @@ " " " " " " -" " -" " +" " +" " " " " " " " -" " +" " " " " " " " -" " +" " +" " " " " " " " -" " +" " " " " " " " " " -" " -" " +" " +" " " " @@ -2307,7 +2458,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -2319,7 +2470,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -2330,7 +2481,7 @@ " " " " " " -" " +" " " " @@ -2355,57 +2506,55 @@ " " " " " " -" " +" " " " " " -" " -" " +" " " " " " -" " +" " " " " " " " +" " +" " -" " " " " " " " " " " " " " -" " -" " -" " +" " " " @@ -2416,7 +2565,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -2427,7 +2576,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -2438,33 +2587,34 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " " " -" " -" " -" " +" " " " +" " " " " " " " " " -" " +" " +" " +" " " " @@ -2475,8 +2625,8 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " @@ -2493,7 +2643,7 @@ " " " " " " -" " +" " " " " " " " " " -" " +" " " " @@ -2571,7 +2721,7 @@ " " " " " " -" " +" " " " @@ -2626,7 +2776,7 @@ " " " " " " -" " +" " " " " " " " " " -" " -" " -" " -" " -" " -" " -" " +" " +" " " " -" " -" " -" " +" " " " -" " +" " " " @@ -2682,7 +2817,7 @@ " " " " " " " " -" " " " " " " " " " -" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " " " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " -" " +" " " " @@ -2725,7 +2951,7 @@ " " " " " " " " " " " " -" " +" " " " " " " " -" " +" " " " @@ -2767,20 +2993,20 @@ " " " " " " -" " +" " " " " " " " " " " " " " " " " " -" " +" " " " -" " +" " " " " " " " -" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " -" " +" " " " " " " " " " -" " -" " +" " +" " " " -" " " " " " " " " " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip index 297ff20344..4154c6c33a 100644 Binary files a/gui/themes/scummclassic.zip and b/gui/themes/scummclassic.zip differ diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx index 180e8fba74..5fd2d6f835 100644 --- a/gui/themes/scummclassic/classic_layout.stx +++ b/gui/themes/scummclassic/classic_layout.stx @@ -36,6 +36,9 @@ + + + @@ -101,6 +104,12 @@ size = '15, 18' padding = '0, 3, 4, 0' /> + + @@ -1019,6 +1028,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -99,6 +102,12 @@ size = '32, 18' padding = '0, 0, 1, 0' /> + + @@ -1013,6 +1022,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx index 49c13cf1b0..4fd6ae6eba 100644 --- a/gui/themes/scummmodern/scummmodern_layout.stx +++ b/gui/themes/scummmodern/scummmodern_layout.stx @@ -43,6 +43,9 @@ + + + @@ -106,6 +109,13 @@ size = '15, 18' padding = '0, 3, 4, 0' /> + + + @@ -1032,6 +1042,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -97,6 +100,12 @@ size = '32, 18' padding = '0, 0, 2, 0' /> + + @@ -1012,6 +1021,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + setFeatureState(OSystem::kFeatureVirtualKeyboard, true); +#endif +} void EditTextWidget::drawWidget() { g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x+_w, _y+_h), 0, ThemeEngine::kWidgetBackgroundEditText); -- cgit v1.2.3 From baafae672f3489b0eaf77c22be0c65ba31e6b73d Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Thu, 4 Jul 2013 15:23:56 +0300 Subject: RECORDER: Fix crash at startup --- gui/themes/scummmodern.zip | Bin 1485585 -> 1485763 bytes gui/themes/scummmodern/scummmodern_layout.stx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'gui') diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip index 3925c67121..0f10003e94 100644 Binary files a/gui/themes/scummmodern.zip and b/gui/themes/scummmodern.zip differ diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx index 4fd6ae6eba..b760e15919 100644 --- a/gui/themes/scummmodern/scummmodern_layout.stx +++ b/gui/themes/scummmodern/scummmodern_layout.stx @@ -114,7 +114,7 @@ size = '60, 25' /> -- cgit v1.2.3 From 8d6aa77769d2d914fc05464435d6558b734bd4c1 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 4 Jul 2013 15:41:01 +0200 Subject: GUI: Cleanup EventRecorder::getSurface. Formerly the function created a SDL_Surface by hand. Instead now it uses SDL_CreateRGBSurface (which is used in the SDL backend anyway and yields the same results). This should fix PS3 port compilation. --- gui/EventRecorder.cpp | 38 ++------------------------------------ 1 file changed, 2 insertions(+), 36 deletions(-) (limited to 'gui') diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index 94b955cb22..47358a0b3d 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -599,42 +599,8 @@ void EventRecorder::setFileHeader() { } SDL_Surface *EventRecorder::getSurface(int width, int height) { - SDL_Surface *surface = new SDL_Surface(); - surface->format = new SDL_PixelFormat(); - surface->flags = 0; - surface->format->palette = NULL; - surface->format->BitsPerPixel = 16; - surface->format->BytesPerPixel = 2; - surface->format->Rloss = 3; - surface->format->Gloss = 2; - surface->format->Bloss = 3; - surface->format->Aloss = 8; - surface->format->Rshift = 11; - surface->format->Gshift = 5; - surface->format->Bshift = 0; - surface->format->Ashift = 0; - surface->format->Rmask = 63488; - surface->format->Gmask = 2016; - surface->format->Bmask = 31; - surface->format->Amask = 0; - surface->format->colorkey = 0; - surface->format->alpha = 255; - surface->w = width; - surface->h = height; - surface->pitch = width * 2; - surface->pixels = (char *)malloc(surface->pitch * surface->h); - surface->offset = 0; - surface->hwdata = NULL; - surface->clip_rect.x = 0; - surface->clip_rect.y = 0; - surface->clip_rect.w = width; - surface->clip_rect.h = height; - surface->unused1 = 0; - surface->locked = 0; - surface->map = NULL; - surface->format_version = 4; - surface->refcount = 1; - return surface; + // Create a RGB565 surface of the requested dimensions. + return SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 16, 0xF800, 0x07E0, 0x001F, 0x0000); } bool EventRecorder::switchMode() { -- cgit v1.2.3 From 4a7e4e5b22da3587a9d68978d7be31e4e78a8ccc Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Sat, 6 Jul 2013 23:54:45 -0400 Subject: ALL: Don't use EventRecorder at all when not compiled in --- gui/EventRecorder.cpp | 4 ++-- gui/EventRecorder.h | 55 --------------------------------------------------- gui/gui-manager.cpp | 4 ++++ 3 files changed, 6 insertions(+), 57 deletions(-) (limited to 'gui') diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index 47358a0b3d..d8cb0b8830 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -23,12 +23,12 @@ #include "gui/EventRecorder.h" +#ifdef ENABLE_EVENTRECORDER + namespace Common { DECLARE_SINGLETON(GUI::EventRecorder); } -#ifdef ENABLE_EVENTRECORDER - #include "common/debug-channels.h" #include "backends/timer/sdl/sdl-timer.h" #include "backends/mixer/sdl/sdl-mixer.h" diff --git a/gui/EventRecorder.h b/gui/EventRecorder.h index 3e32d89232..4abefc05f5 100644 --- a/gui/EventRecorder.h +++ b/gui/EventRecorder.h @@ -233,61 +233,6 @@ private: } // End of namespace GUI -#else - -#ifdef SDL_BACKEND -#include "backends/timer/default/default-timer.h" -#include "backends/mixer/sdl/sdl-mixer.h" -#endif - -#define g_eventRec (GUI::EventRecorder::instance()) - -namespace GUI { - -class EventRecorder : private Common::EventSource, public Common::Singleton, private Common::DefaultEventMapper { - friend class Common::Singleton; - - public: - EventRecorder() { -#ifdef SDL_BACKEND - _timerManager = NULL; - _realMixerManager = NULL; -#endif - } - ~EventRecorder() {} - - bool pollEvent(Common::Event &ev) { return false; } - void RegisterEventSource() {} - void deinit() {} - void suspendRecording() {} - void resumeRecording() {} - void preDrawOverlayGui() {} - void postDrawOverlayGui() {} - void processGameDescription(const ADGameDescription *desc) {} - void updateSubsystems() {} - uint32 getRandomSeed(const Common::String &name) { return g_system->getMillis(); } - Common::SaveFileManager *getSaveManager(Common::SaveFileManager *realSaveManager) { return realSaveManager; } - -#ifdef SDL_BACKEND - private: - DefaultTimerManager *_timerManager; - SdlMixerManager *_realMixerManager; - - public: - DefaultTimerManager *getTimerManager() { return _timerManager; } - void registerTimerManager(DefaultTimerManager *timerManager) { _timerManager = timerManager; } - - SdlMixerManager *getMixerManager() { return _realMixerManager; } - void registerMixerManager(SdlMixerManager *mixerManager) { _realMixerManager = mixerManager; } - - void processMillis(uint32 &millis, bool skipRecord) {} - bool processDelayMillis() { return false; } -#endif - -}; - -} // namespace GUI - #endif // ENABLE_EVENTRECORDER #endif diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp index 78b40a46ce..1505c8c707 100644 --- a/gui/gui-manager.cpp +++ b/gui/gui-manager.cpp @@ -258,8 +258,10 @@ void GuiManager::runLoop() { if (activeDialog == 0) return; +#ifdef ENABLE_EVENTRECORDER // Suspend recording while GUI is shown g_eventRec.suspendRecording(); +#endif if (!_stateIsSaved) { saveState(); @@ -361,8 +363,10 @@ void GuiManager::runLoop() { _useStdCursor = false; } +#ifdef ENABLE_EVENTRECORDER // Resume recording once GUI is shown g_eventRec.resumeRecording(); +#endif } #pragma mark - -- cgit v1.2.3 From c1397788f240bb029ece9d0a551f702eb08e043a Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Sun, 14 Jul 2013 19:14:00 +0300 Subject: RECORDER: Fix CID 1046884. Uninitialized class variables. --- gui/EventRecorder.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'gui') diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index 47358a0b3d..8917eac2d7 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -77,6 +77,19 @@ EventRecorder::EventRecorder() { _initialized = false; _needRedraw = false; _fastPlayback = false; + + _fakeTimer = 0; + _savedState = false; + _needcontinueGame = false; + _temporarySlot = 0; + _realSaveManager = 0; + _realMixerManager = 0; + controlPanel = 0; + _lastMillis = 0; + _lastScreenshotTime = 0; + _screenshotPeriod = 0; + _playbackFile = 0; + DebugMan.addDebugChannel(kDebugLevelEventRec, "EventRec", "Event recorder debug level"); } -- cgit v1.2.3 From 977038e847f9e08280e9accae2db28b3f5d40abc Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Sun, 14 Jul 2013 19:16:01 +0300 Subject: RECORDER: Rename class variable in accoudance with our code style. --- gui/EventRecorder.cpp | 28 ++++++++++++++-------------- gui/EventRecorder.h | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'gui') diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index 8917eac2d7..b62399d799 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -84,7 +84,7 @@ EventRecorder::EventRecorder() { _temporarySlot = 0; _realSaveManager = 0; _realMixerManager = 0; - controlPanel = 0; + _controlPanel = 0; _lastMillis = 0; _lastScreenshotTime = 0; _screenshotPeriod = 0; @@ -109,8 +109,8 @@ void EventRecorder::deinit() { _recordMode = kPassthrough; delete _fakeMixerManager; _fakeMixerManager = NULL; - controlPanel->close(); - delete controlPanel; + _controlPanel->close(); + delete _controlPanel; debugC(1, kDebugLevelEventRec, "playback:action=stopplayback"); g_system->getEventManager()->getEventDispatcher()->unregisterSource(this); _recordMode = kPassthrough; @@ -140,7 +140,7 @@ void EventRecorder::processMillis(uint32 &millis, bool skipRecord) { millisDelay = millis - _lastMillis; _lastMillis = millis; _fakeTimer += millisDelay; - controlPanel->setReplayedTime(_fakeTimer); + _controlPanel->setReplayedTime(_fakeTimer); timerEvent.recordedtype = Common::kRecorderEventTypeTimer; timerEvent.time = _fakeTimer; _playbackFile->writeEvent(timerEvent); @@ -163,7 +163,7 @@ void EventRecorder::processMillis(uint32 &millis, bool skipRecord) { } } millis = _fakeTimer; - controlPanel->setReplayedTime(_fakeTimer); + _controlPanel->setReplayedTime(_fakeTimer); break; case kRecorderPlaybackPause: millis = _fakeTimer; @@ -222,12 +222,12 @@ void EventRecorder::togglePause() { case kRecorderRecord: oldState = _recordMode; _recordMode = kRecorderPlaybackPause; - controlPanel->runModal(); + _controlPanel->runModal(); _recordMode = oldState; _initialized = true; break; case kRecorderPlaybackPause: - controlPanel->close(); + _controlPanel->close(); break; default: break; @@ -290,7 +290,7 @@ void EventRecorder::init(Common::String recordFileName, RecordMode mode) { return; } if (_recordMode != kPassthrough) { - controlPanel = new GUI::OnScreenDialog(_recordMode == kRecorderRecord); + _controlPanel = new GUI::OnScreenDialog(_recordMode == kRecorderRecord); } if (_recordMode == kRecorderPlayback) { applyPlaybackSettings(); @@ -452,8 +452,8 @@ Common::List EventRecorder::mapEvent(const Common::Event &ev, Com return Common::DefaultEventMapper::mapEvent(ev, source); break; case kRecorderRecord: - g_gui.processEvent(evt, controlPanel); - if (((evt.type == Common::EVENT_LBUTTONDOWN) || (evt.type == Common::EVENT_LBUTTONUP) || (evt.type == Common::EVENT_MOUSEMOVE)) && controlPanel->isMouseOver()) { + g_gui.processEvent(evt, _controlPanel); + if (((evt.type == Common::EVENT_LBUTTONDOWN) || (evt.type == Common::EVENT_LBUTTONUP) || (evt.type == Common::EVENT_MOUSEMOVE)) && _controlPanel->isMouseOver()) { return Common::List(); } else { Common::RecorderEvent e; @@ -466,13 +466,13 @@ Common::List EventRecorder::mapEvent(const Common::Event &ev, Com break; case kRecorderPlaybackPause: { Common::Event dialogEvent; - if (controlPanel->isEditDlgVisible()) { + if (_controlPanel->isEditDlgVisible()) { dialogEvent = ev; } else { dialogEvent = evt; } - g_gui.processEvent(dialogEvent, controlPanel->getActiveDlg()); - if (((dialogEvent.type == Common::EVENT_LBUTTONDOWN) || (dialogEvent.type == Common::EVENT_LBUTTONUP) || (dialogEvent.type == Common::EVENT_MOUSEMOVE)) && controlPanel->isMouseOver()) { + g_gui.processEvent(dialogEvent, _controlPanel->getActiveDlg()); + if (((dialogEvent.type == Common::EVENT_LBUTTONDOWN) || (dialogEvent.type == Common::EVENT_LBUTTONUP) || (dialogEvent.type == Common::EVENT_MOUSEMOVE)) && _controlPanel->isMouseOver()) { return Common::List(); } return Common::DefaultEventMapper::mapEvent(dialogEvent, source); @@ -562,7 +562,7 @@ void EventRecorder::preDrawOverlayGui() { g_system->showOverlay(); g_gui.theme()->clearAll(); g_gui.theme()->openDialog(true, GUI::ThemeEngine::kShadingNone); - controlPanel->drawDialog(); + _controlPanel->drawDialog(); g_gui.theme()->finishBuffering(); g_gui.theme()->updateScreen(); _recordMode = oldMode; diff --git a/gui/EventRecorder.h b/gui/EventRecorder.h index 3e32d89232..60fe07fafc 100644 --- a/gui/EventRecorder.h +++ b/gui/EventRecorder.h @@ -193,7 +193,7 @@ private: DefaultTimerManager *_timerManager; RecorderSaveFileManager _fakeSaveManager; NullSdlMixerManager *_fakeMixerManager; - GUI::OnScreenDialog *controlPanel; + GUI::OnScreenDialog *_controlPanel; Common::RecorderEvent _nextEvent; void setFileHeader(); -- cgit v1.2.3 From e3a11085a9c07082dfebb8b4bcf4031ac0569df5 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Sun, 14 Jul 2013 19:20:06 +0300 Subject: RECORDER: Fix CID 1046888. Wrong check. --- gui/EventRecorder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui') diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index b62399d799..f2df146804 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -331,7 +331,7 @@ bool EventRecorder::openRecordFile(const Common::String &fileName) { } bool EventRecorder::checkGameHash(const ADGameDescription *gameDesc) { - if ((gameDesc == NULL) && (_playbackFile->getHeader().hashRecords.size() != 0)) { + if (_playbackFile->getHeader().hashRecords.size() != 0) { warning("Engine doesn't contain description table"); return false; } -- cgit v1.2.3 From 51046d0ce722309a0a347849e0a60176e0b9069c Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Sun, 14 Jul 2013 19:22:53 +0300 Subject: RECORDER: Fix CID 1046881. Unused value --- gui/onscreendialog.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'gui') diff --git a/gui/onscreendialog.cpp b/gui/onscreendialog.cpp index efe8038e68..84b84f0192 100644 --- a/gui/onscreendialog.cpp +++ b/gui/onscreendialog.cpp @@ -97,18 +97,17 @@ OnScreenDialog::OnScreenDialog(bool isRecord) : Dialog("OnScreenDialog") { } else #endif { - GUI::ButtonWidget *btn; if (g_system->getOverlayWidth() > 320) - btn = new ButtonWidget(this, "OnScreenDialog.StopButton", "[ ]", _("Stop"), kStopCmd); + new ButtonWidget(this, "OnScreenDialog.StopButton", "[ ]", _("Stop"), kStopCmd); else - btn = new ButtonWidget(this, "OnScreenDialog.StopButton", "[]", _("Stop"), kStopCmd); + new ButtonWidget(this, "OnScreenDialog.StopButton", "[]", _("Stop"), kStopCmd); if (isRecord) { - btn = new ButtonWidget(this, "OnScreenDialog.EditButton", "E", _("Edit record description"), kEditCmd); + new ButtonWidget(this, "OnScreenDialog.EditButton", "E", _("Edit record description"), kEditCmd); } else { - btn = new ButtonWidget(this, "OnScreenDialog.SwitchModeButton", "G", _("Switch to Game"), kSwitchModeCmd); + new ButtonWidget(this, "OnScreenDialog.SwitchModeButton", "G", _("Switch to Game"), kSwitchModeCmd); - btn = new ButtonWidget(this, "OnScreenDialog.FastReplayButton", ">>", _("Fast replay"), kFastModeCmd); + new ButtonWidget(this, "OnScreenDialog.FastReplayButton", ">>", _("Fast replay"), kFastModeCmd); } } -- cgit v1.2.3 From 6751a385a81902e03ad2d205133560b57bacaa21 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Sun, 14 Jul 2013 19:24:47 +0300 Subject: RECORDER: Fix CID 1046883. Uninitialized variables --- gui/onscreendialog.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gui') diff --git a/gui/onscreendialog.cpp b/gui/onscreendialog.cpp index 84b84f0192..e508c64290 100644 --- a/gui/onscreendialog.cpp +++ b/gui/onscreendialog.cpp @@ -116,6 +116,9 @@ OnScreenDialog::OnScreenDialog(bool isRecord) : Dialog("OnScreenDialog") { _enableDrag = false; _mouseOver = false; _editDlgShown = false; + + lastTime = 0; + dlg = 0; } void OnScreenDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { -- cgit v1.2.3 From 9efff8f35012a6dc42d330b8155b1ed8918f8529 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Sun, 14 Jul 2013 19:27:13 +0300 Subject: RECORDER: Rename class variables in accoudance with our code style --- gui/onscreendialog.cpp | 26 +++++++++++++------------- gui/onscreendialog.h | 10 ++++++---- 2 files changed, 19 insertions(+), 17 deletions(-) (limited to 'gui') diff --git a/gui/onscreendialog.cpp b/gui/onscreendialog.cpp index e508c64290..03a6f26ec0 100644 --- a/gui/onscreendialog.cpp +++ b/gui/onscreendialog.cpp @@ -112,13 +112,13 @@ OnScreenDialog::OnScreenDialog(bool isRecord) : Dialog("OnScreenDialog") { } - text = new GUI::StaticTextWidget(this, "OnScreenDialog.TimeLabel", "00:00:00"); + _text = new GUI::StaticTextWidget(this, "OnScreenDialog.TimeLabel", "00:00:00"); _enableDrag = false; _mouseOver = false; _editDlgShown = false; - lastTime = 0; - dlg = 0; + _lastTime = 0; + _dlg = 0; } void OnScreenDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { @@ -130,20 +130,20 @@ void OnScreenDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat close(); break; case kEditCmd: - dlg = new EditRecordDialog(g_eventRec.getAuthor(), g_eventRec.getName(), g_eventRec.getNotes()); + _dlg = new EditRecordDialog(g_eventRec.getAuthor(), g_eventRec.getName(), g_eventRec.getNotes()); CursorMan.lock(false); g_eventRec.setRedraw(false); g_system->showOverlay(); _editDlgShown = true; - dlg->runModal(); + _dlg->runModal(); _editDlgShown = false; g_system->hideOverlay(); g_eventRec.setRedraw(true); CursorMan.lock(true); - g_eventRec.setAuthor(((EditRecordDialog *)dlg)->getAuthor()); - g_eventRec.setName(((EditRecordDialog *)dlg)->getName()); - g_eventRec.setNotes(((EditRecordDialog *)dlg)->getNotes()); - delete dlg; + g_eventRec.setAuthor(((EditRecordDialog *)_dlg)->getAuthor()); + g_eventRec.setName(((EditRecordDialog *)_dlg)->getName()); + g_eventRec.setNotes(((EditRecordDialog *)_dlg)->getNotes()); + delete _dlg; break; case kSwitchModeCmd: if (g_eventRec.switchMode()) { @@ -157,10 +157,10 @@ void OnScreenDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat } void OnScreenDialog::setReplayedTime(uint32 newTime) { - if (newTime - lastTime > 1000) { + if (newTime - _lastTime > 1000) { uint32 seconds = newTime / 1000; - text->setLabel(Common::String::format("%.2d:%.2d:%.2d", seconds / 3600 % 24, seconds / 60 % 60, seconds % 60)); - lastTime = newTime; + _text->setLabel(Common::String::format("%.2d:%.2d:%.2d", seconds / 3600 % 24, seconds / 60 % 60, seconds % 60)); + _lastTime = newTime; } } @@ -220,7 +220,7 @@ void OnScreenDialog::close() { Dialog *OnScreenDialog::getActiveDlg() { if (_editDlgShown) { - return dlg; + return _dlg; } else { return this; } diff --git a/gui/onscreendialog.h b/gui/onscreendialog.h index 4f3839acb6..2fae14cbc6 100644 --- a/gui/onscreendialog.h +++ b/gui/onscreendialog.h @@ -30,14 +30,16 @@ namespace GUI { class OnScreenDialog : public Dialog { private: - uint32 lastTime; + uint32 _lastTime; bool _enableDrag; bool _mouseOver; bool _editDlgShown; Common::Point _dragPoint; - GUI::StaticTextWidget *text; - Dialog *dlg; + GUI::StaticTextWidget *_text; + Dialog *_dlg; + bool isMouseOver(int x, int y); + public: OnScreenDialog(bool recordingMode); ~OnScreenDialog(); @@ -56,7 +58,7 @@ public: bool isEditDlgVisible(); Dialog *getActiveDlg(); protected: - virtual void releaseFocus(); + virtual void releaseFocus(); }; } // End of namespace GUI -- cgit v1.2.3 From 54d0eef6f23046376674c95bc7467216dc0d2766 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Sun, 14 Jul 2013 19:30:35 +0300 Subject: RECORDER: Fix CID 1046882. Uninitalized variables --- gui/recorderdialog.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gui') diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp index 55f342d4a1..e2e73a4845 100644 --- a/gui/recorderdialog.cpp +++ b/gui/recorderdialog.cpp @@ -52,6 +52,12 @@ enum { }; RecorderDialog::RecorderDialog() : Dialog("RecorderDialog"), _list(0), _currentScreenshot(0) { + _firstScreenshotUpdate = false; + _screenShotsCount = 0; + _currentScreenshotText = 0; + _authorText = 0; + _notesText = 0; + _backgroundType = ThemeEngine::kDialogBackgroundSpecial; new StaticTextWidget(this, "SaveLoadChooser.Title", _("Recorder or Playback Gameplay")); -- cgit v1.2.3 From 6e4217e1ba1df9fd2ee4cd0d61151ed7dfc53021 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Sun, 14 Jul 2013 19:35:17 +0300 Subject: RECORDER: Fix CID 1046887. Missing break in switch --- gui/recorderdialog.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'gui') diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp index e2e73a4845..59fd83362e 100644 --- a/gui/recorderdialog.cpp +++ b/gui/recorderdialog.cpp @@ -191,6 +191,7 @@ void RecorderDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat break; case kCloseCmd: setResult(kRecordDialogClose); + break; default: Dialog::handleCommand(sender, cmd, data); } -- cgit v1.2.3 From 989ea7cb56245ce1918ddf54c2e06973ebcd6239 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 14 Jul 2013 19:01:47 +0200 Subject: JANITORIAL: Remove trailing whitespace --- gui/EventRecorder.cpp | 4 ++-- gui/about.cpp | 4 ++-- gui/editrecorddialog.cpp | 2 +- gui/recorderdialog.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'gui') diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index f2df146804..89a226922a 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -89,7 +89,7 @@ EventRecorder::EventRecorder() { _lastScreenshotTime = 0; _screenshotPeriod = 0; _playbackFile = 0; - + DebugMan.addDebugChannel(kDebugLevelEventRec, "EventRec", "Event recorder debug level"); } @@ -186,7 +186,7 @@ void EventRecorder::checkForKeyCode(const Common::Event &event) { bool EventRecorder::pollEvent(Common::Event &ev) { if ((_recordMode != kRecorderPlayback) || !_initialized) return false; - + if ((_nextEvent.recordedtype == Common::kRecorderEventTypeTimer) || (_nextEvent.type == Common::EVENT_INVALID)) { return false; } diff --git a/gui/about.cpp b/gui/about.cpp index 088971f273..20145886c6 100644 --- a/gui/about.cpp +++ b/gui/about.cpp @@ -46,7 +46,7 @@ enum { // 0 - 2 -- set a custom color: // 0 normal text // 1 highlighted text -// 2 disabled text +// 2 disabled text // TODO: Maybe add a tab/indent feature; that is, make it possible to specify // an amount by which that line shall be indented (the indent of course would have // to be considered while performing any word wrapping, too). @@ -139,7 +139,7 @@ void AboutDialog::addLine(const char *str) { } else { Common::String format(str, 2); str += 2; - + static Common::String asciiStr; if (format[0] == 'A') { bool useAscii = false; diff --git a/gui/editrecorddialog.cpp b/gui/editrecorddialog.cpp index a6a7a2560e..cfcc747121 100644 --- a/gui/editrecorddialog.cpp +++ b/gui/editrecorddialog.cpp @@ -37,7 +37,7 @@ void EditRecordDialog::setAuthor(const Common::String &author) { const Common::String EditRecordDialog::getNotes() { return _notesEdit->getEditString(); -} +} void EditRecordDialog::setNotes(const Common::String &desc) { _notesEdit->setEditString(desc); diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp index 59fd83362e..18eb9a00a3 100644 --- a/gui/recorderdialog.cpp +++ b/gui/recorderdialog.cpp @@ -69,7 +69,7 @@ RecorderDialog::RecorderDialog() : Dialog("RecorderDialog"), _list(0), _currentS new GUI::ButtonWidget(this, "RecorderDialog.Cancel", _("Cancel"), 0, kCloseCmd); new GUI::ButtonWidget(this, "RecorderDialog.Record", _("Record"), 0, kRecordCmd); _playbackButton = new GUI::ButtonWidget(this, "RecorderDialog.Playback", _("Playback"), 0, kPlaybackCmd); - + _editButton = new GUI::ButtonWidget(this, "RecorderDialog.Edit", _("Edit"), 0, kEditRecordCmd); _editButton->setEnabled(false); @@ -80,7 +80,7 @@ RecorderDialog::RecorderDialog() : Dialog("RecorderDialog"), _list(0), _currentS _container = new GUI::ContainerWidget(this, 0, 0, 10, 10); if (g_gui.xmlEval()->getVar("Globals.RecorderDialog.ExtInfo.Visible") == 1) { new GUI::ButtonWidget(this,"RecorderDialog.NextScreenShotButton", "<", 0, kPrevScreenshotCmd); - new GUI::ButtonWidget(this, "RecorderDialog.PreviousScreenShotButton", ">", 0, kNextScreenshotCmd); + new GUI::ButtonWidget(this, "RecorderDialog.PreviousScreenShotButton", ">", 0, kNextScreenshotCmd); _currentScreenshotText = new StaticTextWidget(this, "RecorderDialog.currentScreenshot", "0/0"); _authorText = new StaticTextWidget(this, "RecorderDialog.Author", _("Author: ")); _notesText = new StaticTextWidget(this, "RecorderDialog.Notes", _("Notes: ")); -- cgit v1.2.3 From 5e835ef91529d9350d05864fd174a5e3db8d9615 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 14 Jul 2013 19:04:09 +0200 Subject: RECORDER: Fix indenting --- gui/recorderdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui') diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp index 18eb9a00a3..a4c7428116 100644 --- a/gui/recorderdialog.cpp +++ b/gui/recorderdialog.cpp @@ -194,8 +194,8 @@ void RecorderDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat break; default: Dialog::handleCommand(sender, cmd, data); - } } +} void RecorderDialog::updateList() { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); -- cgit v1.2.3 From ddcfdf532927a3b31f0dd7033be5805fa38db15f Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 15 Jul 2013 13:40:59 +0200 Subject: GUI: Allow the event recorder dialog to be closed. This is a regression from 6e4217e1ba1df9fd2ee4cd0d61151ed7dfc53021. setResult does not automatically close the dialog. However, Dialog::handleCommand will close the dialog when kCloseCmd is received. --- gui/recorderdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui') diff --git a/gui/recorderdialog.cpp b/gui/recorderdialog.cpp index a4c7428116..1a11dbac65 100644 --- a/gui/recorderdialog.cpp +++ b/gui/recorderdialog.cpp @@ -191,7 +191,7 @@ void RecorderDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat break; case kCloseCmd: setResult(kRecordDialogClose); - break; + // Fall through default: Dialog::handleCommand(sender, cmd, data); } -- cgit v1.2.3 From 6a1112f98ff3739dde809275f1d09951b9a20ec6 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 15 Jul 2013 13:44:24 +0200 Subject: GUI: Mark some intentional fall throughs in switches. All of these are for handling kCloseCmd. --- gui/chooser.cpp | 1 + gui/saveload-dialog.cpp | 2 ++ 2 files changed, 3 insertions(+) (limited to 'gui') diff --git a/gui/chooser.cpp b/gui/chooser.cpp index 6ae08161df..c195e94c9b 100644 --- a/gui/chooser.cpp +++ b/gui/chooser.cpp @@ -67,6 +67,7 @@ void ChooserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data break; case kCloseCmd: setResult(-1); + // Fall through default: Dialog::handleCommand(sender, cmd, data); } diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index c7dd62b6c6..585117fba4 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -286,6 +286,7 @@ void SaveLoadChooserSimple::handleCommand(CommandSender *sender, uint32 cmd, uin break; case kCloseCmd: setResult(-1); + // Fall through default: SaveLoadChooserDialog::handleCommand(sender, cmd, data); } @@ -595,6 +596,7 @@ void SaveLoadChooserGrid::handleCommand(CommandSender *sender, uint32 cmd, uint3 case kCloseCmd: setResult(-1); + // Fall through default: SaveLoadChooserDialog::handleCommand(sender, cmd, data); } -- cgit v1.2.3 From 103e926c0765c45267c1cfac0eb07a201e5084bd Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sat, 3 Aug 2013 01:26:04 +0200 Subject: GUI: Prefer getBasePtr instead of direct Surface::pixels access. --- gui/EventRecorder.cpp | 2 +- gui/ThemeEngine.cpp | 6 +++--- gui/widget.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'gui') diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index fd0093d266..4f569b75c5 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -522,7 +522,7 @@ bool EventRecorder::grabScreenAndComputeMD5(Graphics::Surface &screen, uint8 md5 warning("Can't save screenshot"); return false; } - Common::MemoryReadStream bitmapStream((const byte*)screen.pixels, screen.w * screen.h * screen.format.bytesPerPixel); + Common::MemoryReadStream bitmapStream((const byte*)screen.getBasePtr(0, 0), screen.w * screen.h * screen.format.bytesPerPixel); computeStreamMD5(bitmapStream, md5); return true; } diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 3ce043cb39..80f3946729 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -389,7 +389,7 @@ bool ThemeEngine::init() { _overlayFormat = _system->getOverlayFormat(); setGraphicsMode(_graphicsMode); - if (_screen.pixels && _backBuffer.pixels) { + if (_screen.getBasePtr(0, 0) && _backBuffer.getBasePtr(0, 0)) { _initOk = true; } @@ -439,7 +439,7 @@ bool ThemeEngine::init() { void ThemeEngine::clearAll() { if (_initOk) { _system->clearOverlay(); - _system->grabOverlay(_screen.pixels, _screen.pitch); + _system->grabOverlay(_screen.getBasePtr(0, 0), _screen.pitch); } } @@ -1326,7 +1326,7 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int // to 8 bit mode, and have to create a suitable palette on the fly. uint colorsFound = 0; Common::HashMap colorToIndex; - const OverlayColor *src = (const OverlayColor *)cursor->pixels; + const OverlayColor *src = (const OverlayColor *)cursor->getBasePtr(0, 0); for (uint y = 0; y < _cursorHeight; ++y) { for (uint x = 0; x < _cursorWidth; ++x) { byte r, g, b; diff --git a/gui/widget.cpp b/gui/widget.cpp index c3f10a861f..197250a940 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -396,7 +396,7 @@ PicButtonWidget::~PicButtonWidget() { void PicButtonWidget::setGfx(const Graphics::Surface *gfx) { _gfx.free(); - if (!gfx || !gfx->pixels) + if (!gfx || !gfx->getBasePtr(0, 0)) return; if (gfx->format.bytesPerPixel == 1) { @@ -429,7 +429,7 @@ void PicButtonWidget::setGfx(int w, int h, int r, int g, int b) { void PicButtonWidget::drawWidget() { g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), "", _state, getFlags()); - if (_gfx.pixels) { + if (_gfx.getBasePtr(0, 0)) { // Check whether the set up surface needs to be converted to the GUI // color format. const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat(); @@ -646,7 +646,7 @@ GraphicsWidget::~GraphicsWidget() { void GraphicsWidget::setGfx(const Graphics::Surface *gfx) { _gfx.free(); - if (!gfx || !gfx->pixels) + if (!gfx || !gfx->getBasePtr(0, 0)) return; if (gfx->format.bytesPerPixel == 1) { @@ -676,7 +676,7 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) { } void GraphicsWidget::drawWidget() { - if (_gfx.pixels) { + if (_gfx.getBasePtr(0, 0)) { // Check whether the set up surface needs to be converted to the GUI // color format. const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat(); -- cgit v1.2.3 From b1bd9322a1867d95d0faa7a3ce2865b8ead8d3f8 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sat, 3 Aug 2013 02:36:28 +0200 Subject: GUI: Take advantage of Surface::getPixels. --- gui/EventRecorder.cpp | 2 +- gui/ThemeEngine.cpp | 10 +++++----- gui/widget.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'gui') diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index 4f569b75c5..4bf5832864 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -522,7 +522,7 @@ bool EventRecorder::grabScreenAndComputeMD5(Graphics::Surface &screen, uint8 md5 warning("Can't save screenshot"); return false; } - Common::MemoryReadStream bitmapStream((const byte*)screen.getBasePtr(0, 0), screen.w * screen.h * screen.format.bytesPerPixel); + Common::MemoryReadStream bitmapStream((const byte*)screen.getPixels(), screen.w * screen.h * screen.format.bytesPerPixel); computeStreamMD5(bitmapStream, md5); return true; } diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 80f3946729..0f8b449b58 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -389,7 +389,7 @@ bool ThemeEngine::init() { _overlayFormat = _system->getOverlayFormat(); setGraphicsMode(_graphicsMode); - if (_screen.getBasePtr(0, 0) && _backBuffer.getBasePtr(0, 0)) { + if (_screen.getPixels() && _backBuffer.getPixels()) { _initOk = true; } @@ -439,7 +439,7 @@ bool ThemeEngine::init() { void ThemeEngine::clearAll() { if (_initOk) { _system->clearOverlay(); - _system->grabOverlay(_screen.getBasePtr(0, 0), _screen.pitch); + _system->grabOverlay(_screen.getPixels(), _screen.pitch); } } @@ -1219,7 +1219,7 @@ void ThemeEngine::updateScreen(bool render) { } _vectorRenderer->setSurface(&_screen); - memcpy(_screen.getBasePtr(0, 0), _backBuffer.getBasePtr(0, 0), _screen.pitch * _screen.h); + memcpy(_screen.getPixels(), _backBuffer.getPixels(), _screen.pitch * _screen.h); _bufferQueue.clear(); } @@ -1287,7 +1287,7 @@ void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) { addDirtyRect(Common::Rect(0, 0, _screen.w, _screen.h)); } - memcpy(_backBuffer.getBasePtr(0, 0), _screen.getBasePtr(0, 0), _screen.pitch * _screen.h); + memcpy(_backBuffer.getPixels(), _screen.getPixels(), _screen.pitch * _screen.h); _vectorRenderer->setSurface(&_screen); } @@ -1326,7 +1326,7 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int // to 8 bit mode, and have to create a suitable palette on the fly. uint colorsFound = 0; Common::HashMap colorToIndex; - const OverlayColor *src = (const OverlayColor *)cursor->getBasePtr(0, 0); + const OverlayColor *src = (const OverlayColor *)cursor->getPixels(); for (uint y = 0; y < _cursorHeight; ++y) { for (uint x = 0; x < _cursorWidth; ++x) { byte r, g, b; diff --git a/gui/widget.cpp b/gui/widget.cpp index 197250a940..d97c46a5cc 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -396,7 +396,7 @@ PicButtonWidget::~PicButtonWidget() { void PicButtonWidget::setGfx(const Graphics::Surface *gfx) { _gfx.free(); - if (!gfx || !gfx->getBasePtr(0, 0)) + if (!gfx || !gfx->getPixels()) return; if (gfx->format.bytesPerPixel == 1) { @@ -429,7 +429,7 @@ void PicButtonWidget::setGfx(int w, int h, int r, int g, int b) { void PicButtonWidget::drawWidget() { g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), "", _state, getFlags()); - if (_gfx.getBasePtr(0, 0)) { + if (_gfx.getPixels()) { // Check whether the set up surface needs to be converted to the GUI // color format. const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat(); @@ -646,7 +646,7 @@ GraphicsWidget::~GraphicsWidget() { void GraphicsWidget::setGfx(const Graphics::Surface *gfx) { _gfx.free(); - if (!gfx || !gfx->getBasePtr(0, 0)) + if (!gfx || !gfx->getPixels()) return; if (gfx->format.bytesPerPixel == 1) { @@ -676,7 +676,7 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) { } void GraphicsWidget::drawWidget() { - if (_gfx.getBasePtr(0, 0)) { + if (_gfx.getPixels()) { // Check whether the set up surface needs to be converted to the GUI // color format. const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat(); -- cgit v1.2.3 From 11eb168582a8a580bbed0e55e594bded201e39e4 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 8 Aug 2013 03:12:02 +0200 Subject: GUI: Use Domain::const_iterator in EventRecorder code when possible. --- gui/EventRecorder.cpp | 8 ++++---- gui/EventRecorder.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'gui') diff --git a/gui/EventRecorder.cpp b/gui/EventRecorder.cpp index 4bf5832864..21152dd079 100644 --- a/gui/EventRecorder.cpp +++ b/gui/EventRecorder.cpp @@ -372,8 +372,8 @@ SdlMixerManager *EventRecorder::getMixerManager() { } } -void EventRecorder::getConfigFromDomain(Common::ConfigManager::Domain *domain) { - for (Common::ConfigManager::Domain::iterator entry = domain->begin(); entry!= domain->end(); ++entry) { +void EventRecorder::getConfigFromDomain(const Common::ConfigManager::Domain *domain) { + for (Common::ConfigManager::Domain::const_iterator entry = domain->begin(); entry!= domain->end(); ++entry) { _playbackFile->getHeader().settingsRecords[entry->_key] = entry->_value; } } @@ -386,7 +386,7 @@ void EventRecorder::getConfig() { void EventRecorder::applyPlaybackSettings() { - for (Common::StringMap::iterator i = _playbackFile->getHeader().settingsRecords.begin(); i != _playbackFile->getHeader().settingsRecords.end(); ++i) { + for (Common::StringMap::const_iterator i = _playbackFile->getHeader().settingsRecords.begin(); i != _playbackFile->getHeader().settingsRecords.end(); ++i) { Common::String currentValue = ConfMan.get(i->_key); if (currentValue != i->_value) { ConfMan.set(i->_key, i->_value, ConfMan.kTransientDomain); @@ -400,7 +400,7 @@ void EventRecorder::applyPlaybackSettings() { } void EventRecorder::removeDifferentEntriesInDomain(Common::ConfigManager::Domain *domain) { - for (Common::ConfigManager::Domain::iterator entry = domain->begin(); entry!= domain->end(); ++entry) { + for (Common::ConfigManager::Domain::const_iterator entry = domain->begin(); entry!= domain->end(); ++entry) { if (_playbackFile->getHeader().settingsRecords.find(entry->_key) == _playbackFile->getHeader().settingsRecords.end()) { debugC(1, kDebugLevelEventRec, "playback:action=\"Apply settings\" checksettings:key=%s storedvalue=%s currentvalue="" result=different", entry->_key.c_str(), entry->_value.c_str()); domain->erase(entry->_key); diff --git a/gui/EventRecorder.h b/gui/EventRecorder.h index 68ffe16fbc..b2a549ece8 100644 --- a/gui/EventRecorder.h +++ b/gui/EventRecorder.h @@ -199,7 +199,7 @@ private: void setFileHeader(); void setGameMd5(const ADGameDescription *gameDesc); void getConfig(); - void getConfigFromDomain(Common::ConfigManager::Domain *domain); + void getConfigFromDomain(const Common::ConfigManager::Domain *domain); void removeDifferentEntriesInDomain(Common::ConfigManager::Domain *domain); void applyPlaybackSettings(); -- cgit v1.2.3 From 969a33a32dc331ec8d89da056e584a68974dfeec Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 20 Jun 2012 18:39:03 +0200 Subject: GUI: Allow GUI cursor creation to work with abitrary 2/4Bpp formats. --- gui/ThemeEngine.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'gui') diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 0f8b449b58..2ba45a4bc3 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -1320,22 +1320,31 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int memset(_cursor, 0xFF, sizeof(byte) * _cursorWidth * _cursorHeight); // the transparent color is 0xFF00FF - const int colTransparent = _overlayFormat.RGBToColor(0xFF, 0, 0xFF); + const uint32 colTransparent = _overlayFormat.RGBToColor(0xFF, 0, 0xFF); // Now, scan the bitmap. We have to convert it from 16 bit color mode // to 8 bit mode, and have to create a suitable palette on the fly. uint colorsFound = 0; Common::HashMap colorToIndex; - const OverlayColor *src = (const OverlayColor *)cursor->getPixels(); + const byte *src = (const byte *)cursor->getPixels(); for (uint y = 0; y < _cursorHeight; ++y) { for (uint x = 0; x < _cursorWidth; ++x) { + uint32 color = colTransparent; byte r, g, b; + if (cursor->format.bytesPerPixel == 2) { + color = READ_UINT16(src); + } else if (cursor->format.bytesPerPixel == 4) { + color = READ_UINT32(src); + } + + src += cursor->format.bytesPerPixel; + // Skip transparency - if (src[x] == colTransparent) + if (color == colTransparent) continue; - _overlayFormat.colorToRGB(src[x], r, g, b); + cursor->format.colorToRGB(color, r, g, b); const int col = (r << 16) | (g << 8) | b; // If there is no entry yet for this color in the palette: Add one @@ -1357,7 +1366,6 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int const int index = colorToIndex[col]; _cursor[y * _cursorWidth + x] = index; } - src += _cursorWidth; } _useCursor = true; -- cgit v1.2.3 From f545a2f08fc8989fa22726ce0b74e03ece099300 Mon Sep 17 00:00:00 2001 From: Narek Mailian Date: Thu, 1 Aug 2013 01:38:22 +0200 Subject: GUI: Change name of GUI-renderers to remove "16-bit" --- gui/ThemeEngine.cpp | 12 ++++++------ gui/ThemeEngine.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'gui') diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 2ba45a4bc3..b7199fbf68 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -343,9 +343,9 @@ ThemeEngine::~ThemeEngine() { *********************************************************/ const ThemeEngine::Renderer ThemeEngine::_rendererModes[] = { { _s("Disabled GFX"), _sc("Disabled GFX", "lowres"), "none", kGfxDisabled }, - { _s("Standard Renderer (16bpp)"), _s("Standard (16bpp)"), "normal_16bpp", kGfxStandard16bit }, + { _s("Standard Renderer"), _s("Standard"), "normal", kGfxStandard }, #ifndef DISABLE_FANCY_THEMES - { _s("Antialiased Renderer (16bpp)"), _s("Antialiased (16bpp)"), "aa_16bpp", kGfxAntialias16bit } + { _s("Antialiased Renderer"), _s("Antialiased"), "antialias", kGfxAntialias } #endif }; @@ -353,9 +353,9 @@ const uint ThemeEngine::_rendererModesSize = ARRAYSIZE(ThemeEngine::_rendererMod const ThemeEngine::GraphicsMode ThemeEngine::_defaultRendererMode = #ifndef DISABLE_FANCY_THEMES - ThemeEngine::kGfxAntialias16bit; + ThemeEngine::kGfxAntialias; #else - ThemeEngine::kGfxStandard16bit; + ThemeEngine::kGfxStandard; #endif ThemeEngine::GraphicsMode ThemeEngine::findMode(const Common::String &cfg) { @@ -494,9 +494,9 @@ void ThemeEngine::disable() { void ThemeEngine::setGraphicsMode(GraphicsMode mode) { switch (mode) { - case kGfxStandard16bit: + case kGfxStandard: #ifndef DISABLE_FANCY_THEMES - case kGfxAntialias16bit: + case kGfxAntialias: #endif _bytesPerPixel = sizeof(uint16); break; diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 160ceb3259..c0e47a19e6 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -250,8 +250,8 @@ public: */ enum GraphicsMode { kGfxDisabled = 0, ///< No GFX - kGfxStandard16bit, ///< 2BPP with the standard (aliased) renderer. - kGfxAntialias16bit ///< 2BPP with the optimized AA renderer. + kGfxStandard, ///< Standard (aliased) renderer. + kGfxAntialias ///< Optimized AA renderer. }; /** Constant value to expand dirty rectangles, to make sure they are fully copied */ -- cgit v1.2.3 From 1f1d35bd3d31fe3430b9b5227b6127cfd52e52a2 Mon Sep 17 00:00:00 2001 From: Narek Mailian Date: Mon, 5 Aug 2013 17:59:36 +0200 Subject: GRAPHICS: Allow VectorRenderer and ThemeEngine to init with 4BPP --- gui/ThemeEngine.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'gui') diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index b7199fbf68..561c0244a2 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -498,9 +498,13 @@ void ThemeEngine::setGraphicsMode(GraphicsMode mode) { #ifndef DISABLE_FANCY_THEMES case kGfxAntialias: #endif - _bytesPerPixel = sizeof(uint16); - break; - + if (g_system->getOverlayFormat().bytesPerPixel == 4) { + _bytesPerPixel = sizeof(uint32); + break; + } else if (g_system->getOverlayFormat().bytesPerPixel == 2) { + _bytesPerPixel = sizeof(uint16); + break; + } default: error("Invalid graphics mode"); } -- cgit v1.2.3 From f125dce608026b868fa2d705ecd1c15b3e0272ac Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Sat, 10 Aug 2013 23:25:54 +0100 Subject: GUI: Initialise _hotkey in ButtonWidget constructor One of the two ButtonWidget constructor did not initialise _hotkey when given a non-null value. This caused valgrind to report an access to uninitialised variable in Dialog::handleKeyDown(). --- gui/widget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui') diff --git a/gui/widget.cpp b/gui/widget.cpp index d97c46a5cc..e96b62e359 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -287,7 +287,7 @@ ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Co ButtonWidget::ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) : StaticTextWidget(boss, name, cleanupHotkey(label), tooltip), CommandSender(boss), - _cmd(cmd), _lastTime(0) { + _cmd(cmd), _hotkey(hotkey), _lastTime(0) { if (hotkey == 0) _hotkey = parseHotkey(label); setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG); -- cgit v1.2.3 From 49ea7cd1fdac7e85f6744ca79232fcfc9e11d3c4 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Fri, 16 Aug 2013 06:54:54 +0100 Subject: GUI: Add too long string literal warning code to theme generation tool. This has the same effect as clang's -Woverlength-strings warning of string literals longer than C++ compilers are specified to work with. --- gui/themes/scummtheme.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'gui') diff --git a/gui/themes/scummtheme.py b/gui/themes/scummtheme.py index 4c55fd79de..e8001f8bc6 100755 --- a/gui/themes/scummtheme.py +++ b/gui/themes/scummtheme.py @@ -37,6 +37,7 @@ def parseSTX(theme_file, def_file): comm = re.compile("", re.DOTALL) head = re.compile("<\?(.*?)\?>") + strlitcount = 0 output = "" for line in theme_file: output += line.rstrip("\r\n\t ").lstrip() + " \n" @@ -48,7 +49,9 @@ def parseSTX(theme_file, def_file): for line in output.splitlines(): if line and not line.isspace(): + strlitcount += len(line) def_file.write("\"" + line + "\"\n") + return strlitcount def buildDefTheme(themeName): def_file = open("default.inc", "w") @@ -57,16 +60,23 @@ def buildDefTheme(themeName): print ("Cannot open default theme dir.") def_file.write(""" ""\n""") + strlitcount = 24 for filename in os.listdir(themeName): filename = os.path.join(themeName, filename) if os.path.isfile(filename) and filename.endswith(".stx"): theme_file = open(filename, "r") - parseSTX(theme_file, def_file) + strlitcount += parseSTX(theme_file, def_file) theme_file.close() def_file.close() + if strlitcount > 65535: + print("WARNING: default.inc string literal is of length %d which exceeds the" % strlitcount) + print(" maximum length of 65536 that C++ compilers are required to support.") + print(" It is likely that bugs will occur dependent on compiler behaviour.") + print(" To avoid this, reduce the size of the theme.") + def printUsage(): print ("===============================") print ("ScummVM Theme Generation Script") -- cgit v1.2.3 From 01a1e63786cc8c37d1a49f9eb33635d2ad1a2b62 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Fri, 16 Aug 2013 06:57:40 +0100 Subject: GUI: Add code to default theme generation to reduce string length. The additional code skips the extraneous spaces after the end of an XML close brace (>) reducing the string literal by 3106 characters, thus bringing it within the limit for C++ string literals. Have regenerated the default.inc from scummclassic with this change. --- gui/themes/default.inc | 2892 +++++++++++++++++++++++----------------------- gui/themes/scummtheme.py | 5 +- 2 files changed, 1450 insertions(+), 1447 deletions(-) (limited to 'gui') diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 1b6ae3ec27..352cc86852 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -1,142 +1,142 @@ "" -" " -" " +"" +"" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" " " -" " -" " +"" +"" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " -" " +"/>" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " +"/>" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " +"/>" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " +"/>" +"" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " -" " +"/>" +"" " " -" " -" " +"/>" +"" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " -" " +"/>" +"" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " +"/>" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " -" " +"/>" +"" " " -" " +"/>" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " -" " +"/>" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " +"/>" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" " " -" " -" " -" " +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " -" " +"/>" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " +"/>" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " +"/>" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " +"/>" +"" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " -" " +"/>" +"" " " -" " -" " +"/>" +"" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " +"/>" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " -" " -" " +"/>" +"" +"" " " -" " +"/>" +"" " " -" " -" " +"/>" +"" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " +"/>" +"" " " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" " " +"/>" " " +"/>" " " +"/>" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " +"/>" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" +"" +"" " " +"/>" " " -" " +"/>" +"" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" " " -" " +"/>" +"" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " +"/>" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " +"/>" +"" +"" +"" " " +"/>" " " +"/>" " " -" " -" " -" " -" " +"/>" +"" +"" +"" +"" diff --git a/gui/themes/scummtheme.py b/gui/themes/scummtheme.py index e8001f8bc6..524e91468e 100755 --- a/gui/themes/scummtheme.py +++ b/gui/themes/scummtheme.py @@ -40,7 +40,10 @@ def parseSTX(theme_file, def_file): strlitcount = 0 output = "" for line in theme_file: - output += line.rstrip("\r\n\t ").lstrip() + " \n" + output += line.rstrip("\r\n\t ").lstrip() + if not output.endswith('>'): + output += ' ' + output += "\n" output = re.sub(comm, "", output) output = re.sub(head, "", output) -- cgit v1.2.3