ALL: Synced with ScummVM - rev: 33a47d23b8
This commit is contained in:
parent
acd114234f
commit
d5304e2568
261 changed files with 79849 additions and 60443 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -47,6 +47,8 @@ lib*.a
|
|||
/README.html*
|
||||
/NEWS
|
||||
/NEWS.html
|
||||
/CONTRIBUTING
|
||||
/CONTRIBUTING.html
|
||||
|
||||
/build*
|
||||
/staging
|
||||
|
|
9
CONTRIBUTING.md
Normal file
9
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
Thank you for considering contributing to ResidualVM.
|
||||
|
||||
Please make sure to read our guidelines for contributions on our
|
||||
[wiki](https://wiki.scummvm.org/index.php/Developer_Central). In particular:
|
||||
|
||||
* [Coding style](https://wiki.scummvm.org/index.php/Code_Formatting_Conventions)
|
||||
* [Portability](https://wiki.scummvm.org/index.php/Coding_Conventions)
|
||||
* [Commit message style](https://wiki.scummvm.org/index.php/Commit_Guidelines)
|
||||
* License: GPLv2+
|
|
@ -203,6 +203,11 @@ ifdef AMIGAOS
|
|||
AMIGA_DATE = $(shell gdate '+%d.%m.%Y')
|
||||
VERFLAGS += -DAMIGA_DATE=\"$(AMIGA_DATE)\"
|
||||
endif
|
||||
ifdef MORPHOS
|
||||
# MorphOS needs date in specific format for the version cookie
|
||||
AMIGA_DATE = $(shell date +"%-d.%-m.%Y")
|
||||
VERFLAGS += -DAMIGA_DATE=\"$(AMIGA_DATE)\"
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
# Get git's working copy information
|
||||
|
@ -247,7 +252,7 @@ VERFILE := $(DISTDIR)/$(DISTNAME)/base/internal_version.h
|
|||
|
||||
ifdef USE_PANDOC
|
||||
# Convert README.md and NEWS.md to plain text for any platform that might require it
|
||||
PANDOC_CONVERT: README$(PANDOCEXT) NEWS$(PANDOCEXT)
|
||||
PANDOC_CONVERT: README$(PANDOCEXT) CONTRIBUTING$(PANDOCEXT) NEWS$(PANDOCEXT)
|
||||
@sed -i'' -e "s/NEWS.md/NEWS$(PANDOCEXT)/g" README$(PANDOCEXT)
|
||||
@sed -i'' -e "s/CONTRIBUTING.md/CONTRIBUTING$(PANDOCEXT)/g" README$(PANDOCEXT)
|
||||
|
||||
|
@ -285,7 +290,7 @@ dist-src: \
|
|||
@#DEB-src?
|
||||
|
||||
# Common files
|
||||
DIST_FILES_DOCS:=$(addprefix $(srcdir)/,AUTHORS COPYING COPYING.BSD COPYING.LGPL COPYING.FREEFONT COPYING.OFL COPYING.ISC COPYING.LUA COPYING.MIT COPYING.TINYGL COPYRIGHT KNOWN_BUGS NEWS.md README.md)
|
||||
DIST_FILES_DOCS:=$(addprefix $(srcdir)/,AUTHORS COPYING COPYING.BSD COPYING.LGPL COPYING.FREEFONT COPYING.OFL COPYING.ISC COPYING.LUA COPYING.MIT COPYING.TINYGL COPYRIGHT KNOWN_BUGS NEWS.md README.md CONTRIBUTING.md)
|
||||
ifdef USE_PANDOC
|
||||
DIST_FILES_DOCS+=README$(PANDOCEXT) NEWS$(PANDOCEXT)
|
||||
endif
|
||||
|
|
|
@ -91,11 +91,11 @@ SeekableAudioStream *SeekableAudioStream::openStreamFile(const Common::String &b
|
|||
#pragma mark --- LoopingAudioStream ---
|
||||
#pragma mark -
|
||||
|
||||
LoopingAudioStream::LoopingAudioStream(RewindableAudioStream *stream, uint loops, DisposeAfterUse::Flag disposeAfterUse)
|
||||
LoopingAudioStream::LoopingAudioStream(RewindableAudioStream *stream, uint loops, DisposeAfterUse::Flag disposeAfterUse, bool rewind)
|
||||
: _parent(stream, disposeAfterUse), _loops(loops), _completeIterations(0) {
|
||||
assert(stream);
|
||||
|
||||
if (!stream->rewind()) {
|
||||
if (rewind && !stream->rewind()) {
|
||||
// TODO: Properly indicate error
|
||||
_loops = _completeIterations = 1;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ public:
|
|||
* @param loops How often to loop (0 = infinite)
|
||||
* @param disposeAfterUse Destroy the stream after the LoopingAudioStream has finished playback.
|
||||
*/
|
||||
LoopingAudioStream(RewindableAudioStream *stream, uint loops, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
|
||||
LoopingAudioStream(RewindableAudioStream *stream, uint loops, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES, bool rewind = true);
|
||||
|
||||
int readBuffer(int16 *buffer, const int numSamples);
|
||||
bool endOfData() const;
|
||||
|
|
|
@ -39,6 +39,8 @@ namespace Audio {
|
|||
//
|
||||
// In addition, also MS IMA ADPCM is supported. See
|
||||
// <http://wiki.multimedia.cx/index.php?title=Microsoft_IMA_ADPCM>.
|
||||
//
|
||||
// XA ADPCM support is based on FFmpeg/libav
|
||||
|
||||
ADPCMStream::ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
|
||||
: _stream(stream, disposeAfterUse),
|
||||
|
@ -119,6 +121,106 @@ int16 Oki_ADPCMStream::decodeOKI(byte code) {
|
|||
#pragma mark -
|
||||
|
||||
|
||||
int XA_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
|
||||
int samples;
|
||||
byte *data = new byte[128];
|
||||
|
||||
for (samples = 0; samples < numSamples && !endOfData(); samples++) {
|
||||
if (_decodedSampleCount == 0) {
|
||||
uint32 bytesLeft = _stream->size() - _stream->pos();
|
||||
if (bytesLeft < 128) {
|
||||
_stream->skip(bytesLeft);
|
||||
memset(&buffer[samples], 0, (numSamples - samples) * sizeof(uint16));
|
||||
samples = numSamples;
|
||||
break;
|
||||
}
|
||||
_stream->read(data, 128);
|
||||
decodeXA(data);
|
||||
_decodedSampleIndex = 0;
|
||||
}
|
||||
|
||||
// _decodedSamples acts as a FIFO of depth 2 or 4;
|
||||
buffer[samples] = _decodedSamples[_decodedSampleIndex++];
|
||||
_decodedSampleCount--;
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
return samples;
|
||||
}
|
||||
|
||||
static const int s_xaTable[5][2] = {
|
||||
{ 0, 0 },
|
||||
{ 60, 0 },
|
||||
{ 115, -52 },
|
||||
{ 98, -55 },
|
||||
{ 122, -60 }
|
||||
};
|
||||
|
||||
void XA_ADPCMStream::decodeXA(const byte *src) {
|
||||
int16 *leftChannel = _decodedSamples;
|
||||
int16 *rightChannel = _decodedSamples + 1;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int shift = 12 - (src[4 + i * 2] & 0xf);
|
||||
int filter = src[4 + i * 2] >> 4;
|
||||
int f0 = s_xaTable[filter][0];
|
||||
int f1 = s_xaTable[filter][1];
|
||||
int16 s_1 = _status.ima_ch[0].sample[0];
|
||||
int16 s_2 = _status.ima_ch[0].sample[1];
|
||||
|
||||
for (int j = 0; j < 28; j++) {
|
||||
byte d = src[16 + i + j * 4];
|
||||
int t = (int8)(d << 4) >> 4;
|
||||
int s = (t << shift) + ((s_1 * f0 + s_2 * f1 + 32) >> 6);
|
||||
s_2 = s_1;
|
||||
s_1 = CLIP<int>(s, -32768, 32767);
|
||||
*leftChannel = s_1;
|
||||
leftChannel += _channels;
|
||||
_decodedSampleCount++;
|
||||
}
|
||||
|
||||
if (_channels == 2) {
|
||||
_status.ima_ch[0].sample[0] = s_1;
|
||||
_status.ima_ch[0].sample[1] = s_2;
|
||||
s_1 = _status.ima_ch[1].sample[0];
|
||||
s_2 = _status.ima_ch[1].sample[1];
|
||||
}
|
||||
|
||||
shift = 12 - (src[5 + i * 2] & 0xf);
|
||||
filter = src[5 + i * 2] >> 4;
|
||||
f0 = s_xaTable[filter][0];
|
||||
f1 = s_xaTable[filter][1];
|
||||
|
||||
for (int j = 0; j < 28; j++) {
|
||||
byte d = src[16 + i + j * 4];
|
||||
int t = (int8)d >> 4;
|
||||
int s = (t << shift) + ((s_1 * f0 + s_2 * f1 + 32) >> 6);
|
||||
s_2 = s_1;
|
||||
s_1 = CLIP<int>(s, -32768, 32767);
|
||||
|
||||
if (_channels == 2) {
|
||||
*rightChannel = s_1;
|
||||
rightChannel += 2;
|
||||
} else {
|
||||
*leftChannel++ = s_1;
|
||||
}
|
||||
_decodedSampleCount++;
|
||||
}
|
||||
|
||||
if (_channels == 2) {
|
||||
_status.ima_ch[1].sample[0] = s_1;
|
||||
_status.ima_ch[1].sample[1] = s_2;
|
||||
} else {
|
||||
_status.ima_ch[0].sample[0] = s_1;
|
||||
_status.ima_ch[0].sample[1] = s_2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
||||
int DVI_ADPCMStream::readBuffer(int16 *buffer, const int numSamples) {
|
||||
int samples;
|
||||
byte data;
|
||||
|
@ -474,6 +576,8 @@ SeekableAudioStream *makeADPCMStream(Common::SeekableReadStream *stream, Dispose
|
|||
return new Apple_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
|
||||
case kADPCMDK3:
|
||||
return new DK3_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
|
||||
case kADPCMXA:
|
||||
return new XA_ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign);
|
||||
default:
|
||||
error("Unsupported ADPCM encoding");
|
||||
break;
|
||||
|
@ -501,6 +605,7 @@ PacketizedAudioStream *makePacketizedADPCMStream(ADPCMType type, int rate, int c
|
|||
// Filter out types we can't support (they're not fully stateless)
|
||||
switch (type) {
|
||||
case kADPCMOki:
|
||||
case kADPCMXA:
|
||||
case kADPCMDVI:
|
||||
return 0;
|
||||
default:
|
||||
|
|
|
@ -59,7 +59,8 @@ enum ADPCMType {
|
|||
kADPCMMS, // Microsoft ADPCM
|
||||
kADPCMDVI, // Intel DVI IMA ADPCM
|
||||
kADPCMApple, // Apple QuickTime IMA ADPCM
|
||||
kADPCMDK3 // Duck DK3 IMA ADPCM
|
||||
kADPCMDK3, // Duck DK3 IMA ADPCM
|
||||
kADPCMXA // XA ADPCM
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -88,7 +89,7 @@ SeekableAudioStream *makeADPCMStream(
|
|||
* packets as individual AudioStreams like returned by makeADPCMStream.
|
||||
*
|
||||
* Due to the ADPCM types not necessarily supporting stateless
|
||||
* streaming, OKI and DVI are not supported by this function
|
||||
* streaming, OKI, XA and DVI are not supported by this function
|
||||
* and will return NULL.
|
||||
*
|
||||
* @param type the compression type used
|
||||
|
|
|
@ -54,6 +54,7 @@ protected:
|
|||
struct {
|
||||
int32 last;
|
||||
int32 stepIndex;
|
||||
int16 sample[2];
|
||||
} ima_ch[2];
|
||||
} _status;
|
||||
|
||||
|
@ -97,6 +98,24 @@ private:
|
|||
int16 _decodedSamples[2];
|
||||
};
|
||||
|
||||
class XA_ADPCMStream : public ADPCMStream {
|
||||
public:
|
||||
XA_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
|
||||
: ADPCMStream(stream, disposeAfterUse, size, rate, channels, blockAlign) { _decodedSampleCount = 0; }
|
||||
|
||||
virtual bool endOfData() const { return (_stream->eos() || _stream->pos() >= _endpos) && (_decodedSampleCount == 0); }
|
||||
|
||||
virtual int readBuffer(int16 *buffer, const int numSamples);
|
||||
|
||||
protected:
|
||||
void decodeXA(const byte *src);
|
||||
|
||||
private:
|
||||
uint8 _decodedSampleCount;
|
||||
uint8 _decodedSampleIndex;
|
||||
int16 _decodedSamples[28 * 2 * 4];
|
||||
};
|
||||
|
||||
class Ima_ADPCMStream : public ADPCMStream {
|
||||
protected:
|
||||
int16 decodeIMA(byte code, int channel = 0); // Default to using the left channel/using one channel
|
||||
|
|
|
@ -255,7 +255,9 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
|
|||
// If the expressly selected driver or device cannot be found (no longer compiled in, turned off, etc.)
|
||||
// we display a warning and continue.
|
||||
failedDevStr = selDevStr;
|
||||
Common::String warningMsg = Common::String::format(_("The selected audio device '%s' was not found (e.g. might be turned off or disconnected)."), failedDevStr.c_str()) + " " + _("Attempting to fall back to the next available device...");
|
||||
Common::U32String warningMsg = Common::U32String::format(
|
||||
_("The selected audio device '%s' was not found (e.g. might be turned off or disconnected)."), failedDevStr.c_str())
|
||||
+ Common::U32String(" ") + _("Attempting to fall back to the next available device...");
|
||||
GUI::MessageDialog dialog(warningMsg);
|
||||
dialog.runModal();
|
||||
}
|
||||
|
@ -267,7 +269,9 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
|
|||
} else {
|
||||
// If the expressly selected device cannot be used we display a warning and continue.
|
||||
failedDevStr = getDeviceString(hdl, MidiDriver::kDeviceName);
|
||||
Common::String warningMsg = Common::String::format(_("The selected audio device '%s' cannot be used. See log file for more information."), failedDevStr.c_str()) + " " + _("Attempting to fall back to the next available device...");
|
||||
Common::U32String warningMsg = Common::U32String::format(
|
||||
_("The selected audio device '%s' cannot be used. See log file for more information."), failedDevStr.c_str())
|
||||
+ Common::U32String(" ") + _("Attempting to fall back to the next available device...");
|
||||
GUI::MessageDialog dialog(warningMsg);
|
||||
dialog.runModal();
|
||||
}
|
||||
|
@ -303,7 +307,9 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
|
|||
// we display a warning and continue. Don't warn about the missing device if we did already (this becomes relevant if the
|
||||
// missing device is selected as preferred device and also as GM or MT-32 device).
|
||||
if (failedDevStr != devStr) {
|
||||
Common::String warningMsg = Common::String::format(_("The preferred audio device '%s' was not found (e.g. might be turned off or disconnected)."), devStr.c_str()) + " " + _("Attempting to fall back to the next available device...");
|
||||
Common::U32String warningMsg = Common::U32String::format(
|
||||
_("The preferred audio device '%s' was not found (e.g. might be turned off or disconnected)."), devStr.c_str())
|
||||
+ Common::U32String(" ") + _("Attempting to fall back to the next available device...");
|
||||
GUI::MessageDialog dialog(warningMsg);
|
||||
dialog.runModal();
|
||||
}
|
||||
|
@ -318,7 +324,9 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
|
|||
// Don't warn about the failing device if we did already (this becomes relevant if the failing
|
||||
// device is selected as preferred device and also as GM or MT-32 device).
|
||||
if (failedDevStr != getDeviceString(hdl, MidiDriver::kDeviceName)) {
|
||||
Common::String warningMsg = Common::String::format(_("The preferred audio device '%s' cannot be used. See log file for more information."), getDeviceString(hdl, MidiDriver::kDeviceName).c_str()) + " " + _("Attempting to fall back to the next available device...");
|
||||
Common::U32String warningMsg = Common::U32String::format(
|
||||
_("The preferred audio device '%s' cannot be used. See log file for more information."), getDeviceString(hdl, MidiDriver::kDeviceName).c_str())
|
||||
+ Common::U32String(" ") + _("Attempting to fall back to the next available device...");
|
||||
GUI::MessageDialog dialog(warningMsg);
|
||||
dialog.runModal();
|
||||
}
|
||||
|
|
|
@ -187,6 +187,8 @@ MixerImpl::~MixerImpl() {
|
|||
}
|
||||
|
||||
void MixerImpl::setReady(bool ready) {
|
||||
Common::StackLock lock(_mutex);
|
||||
|
||||
_mixerReady = ready;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
MixerImpl(uint sampleRate);
|
||||
~MixerImpl();
|
||||
|
||||
virtual bool isReady() const { return _mixerReady; }
|
||||
virtual bool isReady() const { Common::StackLock lock(_mutex); return _mixerReady; }
|
||||
|
||||
virtual void playStream(
|
||||
SoundType type,
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#include "common/translation.h"
|
||||
|
||||
MusicDevice::MusicDevice(MusicPluginObject const *musicPlugin, Common::String name, MusicType mt) :
|
||||
_musicDriverName(_(musicPlugin->getName())), _musicDriverId(musicPlugin->getId()),
|
||||
_name(_(name)), _type(mt) {
|
||||
_musicDriverName(musicPlugin->getName()), _musicDriverId(musicPlugin->getId()),
|
||||
_name(name), _type(mt) {
|
||||
}
|
||||
|
||||
Common::String MusicDevice::getCompleteName() {
|
||||
|
@ -57,5 +57,5 @@ Common::String MusicDevice::getCompleteId() {
|
|||
}
|
||||
|
||||
MidiDriver::DeviceHandle MusicDevice::getHandle() {
|
||||
return (MidiDriver::DeviceHandle)Common::hashit(getCompleteId().c_str());
|
||||
return (MidiDriver::DeviceHandle)Common::hashit(getCompleteId());
|
||||
}
|
||||
|
|
|
@ -33,19 +33,13 @@
|
|||
|
||||
#include "gui/message.h"
|
||||
|
||||
void BaseBackend::displayMessageOnOSD(const char *msg) {
|
||||
void BaseBackend::displayMessageOnOSD(const Common::U32String &msg) {
|
||||
// Display the message for 1.5 seconds
|
||||
GUI::TimedMessageDialog dialog(msg, 1500);
|
||||
dialog.runModal();
|
||||
}
|
||||
|
||||
void BaseBackend::initBackend() {
|
||||
// Init Event manager
|
||||
#ifndef DISABLE_DEFAULT_EVENT_MANAGER
|
||||
if (!_eventManager)
|
||||
_eventManager = new DefaultEventManager(getDefaultEventSource());
|
||||
#endif
|
||||
|
||||
// Init audio CD manager
|
||||
#ifndef DISABLE_DEFAULT_AUDIOCD_MANAGER
|
||||
if (!_audiocdManager)
|
||||
|
@ -61,3 +55,13 @@ void BaseBackend::fillScreen(uint32 col) {
|
|||
screen->fillRect(Common::Rect(screen->w, screen->h), col);
|
||||
unlockScreen();
|
||||
}
|
||||
|
||||
void EventsBaseBackend::initBackend() {
|
||||
// Init Event manager
|
||||
#ifndef DISABLE_DEFAULT_EVENT_MANAGER
|
||||
if (!_eventManager)
|
||||
_eventManager = new DefaultEventManager(this);
|
||||
#endif
|
||||
|
||||
BaseBackend::initBackend();
|
||||
}
|
||||
|
|
|
@ -27,20 +27,17 @@
|
|||
#include "common/events.h"
|
||||
|
||||
class BaseBackend : public OSystem {
|
||||
protected:
|
||||
virtual Common::EventSource *getDefaultEventSource() = 0;
|
||||
public:
|
||||
virtual void initBackend();
|
||||
|
||||
virtual void displayMessageOnOSD(const char *msg);
|
||||
virtual void displayMessageOnOSD(const Common::U32String &msg);
|
||||
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) {}
|
||||
virtual void fillScreen(uint32 col);
|
||||
};
|
||||
|
||||
class EventsBaseBackend : public BaseBackend, Common::EventSource {
|
||||
protected:
|
||||
virtual Common::EventSource *getDefaultEventSource() { return this; }
|
||||
class EventsBaseBackend : virtual public BaseBackend, Common::EventSource {
|
||||
public:
|
||||
virtual void initBackend();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -153,8 +153,8 @@ void CloudManager::replaceStorage(Storage *storage, uint32 index) {
|
|||
_currentStorageIndex = index;
|
||||
if (_storages[index].username == "") {
|
||||
// options' Cloud tab believes Storage is connected once it has non-empty username
|
||||
_storages[index].username = _("<syncing...>");
|
||||
_storages[index].lastSyncDate = _("<right now>");
|
||||
_storages[index].username = Common::convertFromU32String(_("<syncing...>"));
|
||||
_storages[index].lastSyncDate = Common::convertFromU32String(_("<right now>"));
|
||||
_storages[index].usedBytes = 0;
|
||||
}
|
||||
save();
|
||||
|
|
|
@ -343,13 +343,13 @@ void Storage::directoryDownloadedCallback(FileArrayResponse response) {
|
|||
_downloadFolderRequest = nullptr;
|
||||
_runningRequestsMutex.unlock();
|
||||
|
||||
Common::String message;
|
||||
Common::U32String message;
|
||||
if (response.value.size()) {
|
||||
message = Common::String::format(_("Download complete.\nFailed to download %u files."), response.value.size());
|
||||
message = Common::U32String::format(_("Download complete.\nFailed to download %u files."), response.value.size());
|
||||
} else {
|
||||
message = _("Download complete.");
|
||||
}
|
||||
Common::OSDMessageQueue::instance().addMessage(message.c_str());
|
||||
Common::OSDMessageQueue::instance().addMessage(message);
|
||||
}
|
||||
|
||||
void Storage::directoryDownloadedErrorCallback(Networking::ErrorResponse error) {
|
||||
|
|
|
@ -35,40 +35,28 @@
|
|||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
Common::DialogManager::DialogResult GtkDialogManager::showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser) {
|
||||
Common::DialogManager::DialogResult GtkDialogManager::showFileBrowser(const Common::U32String &title, Common::FSNode &choice, bool isDirBrowser) {
|
||||
if (!gtk_init_check(NULL, NULL))
|
||||
return kDialogError;
|
||||
|
||||
DialogResult result = kDialogCancel;
|
||||
|
||||
// Get current encoding
|
||||
Common::String guiEncoding = "ASCII";
|
||||
#ifdef USE_TRANSLATION
|
||||
guiEncoding = TransMan.getCurrentCharset();
|
||||
#endif
|
||||
Common::Encoding utf8("utf-8", guiEncoding);
|
||||
|
||||
// Convert labels to UTF-8
|
||||
char *utf8Title = utf8.convert(title, strlen(title));
|
||||
Common::String choose = _("Choose");
|
||||
char *utf8Choose = utf8.convert(choose.c_str(), choose.size());
|
||||
Common::String cancel = _("Cancel");
|
||||
char* utf8Cancel = utf8.convert(cancel.c_str(), cancel.size());
|
||||
Common::String utf8Title = title.encode();
|
||||
Common::String utf8Choose = _("Choose").encode();
|
||||
Common::String utf8Cancel = _("Cancel").encode();
|
||||
|
||||
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
|
||||
if (isDirBrowser) {
|
||||
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
|
||||
}
|
||||
#if GTK_CHECK_VERSION(3,20,0)
|
||||
GtkFileChooserNative *native = gtk_file_chooser_native_new(utf8Title, NULL, action, utf8Choose, utf8Cancel);
|
||||
GtkFileChooserNative *native = gtk_file_chooser_native_new(utf8Title.c_str(), NULL, action, utf8Choose.c_str(), utf8Cancel.c_str());
|
||||
GtkFileChooser *chooser = GTK_FILE_CHOOSER(native);
|
||||
#else
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(utf8Title, NULL, action, utf8Choose, GTK_RESPONSE_ACCEPT, utf8Cancel, GTK_RESPONSE_CANCEL, NULL);
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(utf8Title.c_str(), NULL, action, utf8Choose.c_str(), GTK_RESPONSE_ACCEPT, utf8Cancel.c_str(), GTK_RESPONSE_CANCEL, NULL);
|
||||
GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog);
|
||||
#endif
|
||||
free(utf8Cancel);
|
||||
free(utf8Choose);
|
||||
free(utf8Title);
|
||||
|
||||
// Customize dialog
|
||||
gtk_file_chooser_set_show_hidden(chooser, ConfMan.getBool("gui_browser_show_hidden", Common::ConfigManager::kApplicationDomain));
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
class GtkDialogManager : public Common::DialogManager {
|
||||
public:
|
||||
virtual DialogResult showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser);
|
||||
virtual DialogResult showFileBrowser(const Common::U32String &title, Common::FSNode &choice, bool isDirBrowser);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,10 +27,11 @@
|
|||
|
||||
#include "common/fs.h"
|
||||
#include "common/dialogs.h"
|
||||
#include "common/ustr.h"
|
||||
|
||||
class MacOSXDialogManager : public Common::DialogManager {
|
||||
public:
|
||||
virtual DialogResult showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser);
|
||||
virtual DialogResult showFileBrowser(const Common::U32String &title, Common::FSNode &choice, bool isDirBrowser);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -75,14 +75,7 @@
|
|||
showHiddenFilesButton = [[NSButton alloc] init];
|
||||
[showHiddenFilesButton setButtonType:NSSwitchButton];
|
||||
|
||||
#ifdef USE_TRANSLATION
|
||||
CFStringRef encStr = CFStringCreateWithCString(NULL, TransMan.getCurrentCharset().c_str(), kCFStringEncodingASCII);
|
||||
CFStringEncoding stringEncoding = CFStringConvertIANACharSetNameToEncoding(encStr);
|
||||
CFRelease(encStr);
|
||||
#else
|
||||
CFStringEncoding stringEncoding = kCFStringEncodingASCII;
|
||||
#endif
|
||||
CFStringRef hiddenFilesString = CFStringCreateWithCString(0, _("Show hidden files"), stringEncoding);
|
||||
CFStringRef hiddenFilesString = CFStringCreateWithCString(0, _("Show hidden files").encode().c_str(), kCFStringEncodingUTF8);
|
||||
[showHiddenFilesButton setTitle:(NSString*)hiddenFilesString];
|
||||
CFRelease(hiddenFilesString);
|
||||
|
||||
|
@ -128,22 +121,15 @@
|
|||
|
||||
@end
|
||||
|
||||
Common::DialogManager::DialogResult MacOSXDialogManager::showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser) {
|
||||
|
||||
Common::DialogManager::DialogResult MacOSXDialogManager::showFileBrowser(const Common::U32String &title, Common::FSNode &choice, bool isDirBrowser) {
|
||||
DialogResult result = kDialogCancel;
|
||||
|
||||
// Get current encoding
|
||||
#ifdef USE_TRANSLATION
|
||||
CFStringRef encStr = CFStringCreateWithCString(NULL, TransMan.getCurrentCharset().c_str(), kCFStringEncodingASCII);
|
||||
CFStringEncoding stringEncoding = CFStringConvertIANACharSetNameToEncoding(encStr);
|
||||
CFRelease(encStr);
|
||||
#else
|
||||
CFStringEncoding stringEncoding = kCFStringEncodingASCII;
|
||||
#endif
|
||||
CFStringEncoding stringEncoding = kCFStringEncodingUTF8;
|
||||
|
||||
// Convert labels to NSString
|
||||
CFStringRef titleRef = CFStringCreateWithCString(0, title, stringEncoding);
|
||||
CFStringRef chooseRef = CFStringCreateWithCString(0, _("Choose"), stringEncoding);
|
||||
CFStringRef titleRef = CFStringCreateWithCString(0, title.encode().c_str(), stringEncoding);
|
||||
CFStringRef chooseRef = CFStringCreateWithCString(0, _("Choose").encode().c_str(), stringEncoding);
|
||||
|
||||
beginDialog();
|
||||
|
||||
|
|
|
@ -95,12 +95,12 @@ HRESULT getShellPath(IShellItem *item, Common::String &path) {
|
|||
char *str = Win32::unicodeToAnsi(name);
|
||||
path = Common::String(str);
|
||||
CoTaskMemFree(name);
|
||||
delete[] str;
|
||||
free(str);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser) {
|
||||
Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const Common::U32String &title, Common::FSNode &choice, bool isDirBrowser) {
|
||||
DialogResult result = kDialogError;
|
||||
|
||||
// Do nothing if not running on Windows Vista or later
|
||||
|
@ -130,14 +130,15 @@ Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const ch
|
|||
hr = dialog->SetOptions(dwOptions);
|
||||
}
|
||||
|
||||
LPWSTR str = Win32::ansiToUnicode(title, Win32::getCurrentCharset());
|
||||
hr = dialog->SetTitle(str);
|
||||
delete[] str;
|
||||
LPWSTR dialogTitle = Win32::UTF8ToUnicode(title.encode().c_str());
|
||||
hr = dialog->SetTitle(dialogTitle);
|
||||
free(dialogTitle);
|
||||
|
||||
str = Win32::ansiToUnicode(_("Choose"), Win32::getCurrentCharset());
|
||||
hr = dialog->SetOkButtonLabel(str);
|
||||
delete[] str;
|
||||
LPWSTR okTitle = Win32::UTF8ToUnicode(_("Choose").encode().c_str());
|
||||
hr = dialog->SetOkButtonLabel(okTitle);
|
||||
free(okTitle);
|
||||
|
||||
LPWSTR str;
|
||||
if (ConfMan.hasKey("browser_lastpath")) {
|
||||
str = Win32::ansiToUnicode(ConfMan.get("browser_lastpath").c_str());
|
||||
IShellItem *item = NULL;
|
||||
|
@ -145,7 +146,7 @@ Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const ch
|
|||
if (SUCCEEDED(hr)) {
|
||||
hr = dialog->SetDefaultFolder(item);
|
||||
}
|
||||
delete[] str;
|
||||
free(str);
|
||||
}
|
||||
|
||||
// Show dialog
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "common/fs.h"
|
||||
#include "common/dialogs.h"
|
||||
#include "common/ustr.h"
|
||||
|
||||
class SdlWindow_Win32;
|
||||
|
||||
|
@ -34,7 +35,7 @@ class Win32DialogManager : public Common::DialogManager {
|
|||
public:
|
||||
Win32DialogManager(SdlWindow_Win32 *window);
|
||||
virtual ~Win32DialogManager();
|
||||
virtual DialogResult showFileBrowser(const char *title, Common::FSNode &choice, bool isDirBrowser);
|
||||
virtual DialogResult showFileBrowser(const Common::U32String &title, Common::FSNode &choice, bool isDirBrowser);
|
||||
|
||||
private:
|
||||
SdlWindow_Win32 *_window;
|
||||
|
|
|
@ -312,6 +312,7 @@ Common::Keymap *DefaultEventManager::getGlobalKeymap() {
|
|||
act->setEvent(EVENT_MUTE);
|
||||
globalKeymap->addAction(act);
|
||||
|
||||
if (!g_system->hasFeature(OSystem::kFeatureNoQuit)) {
|
||||
act = new Action("QUIT", _("Quit"));
|
||||
act->setEvent(EVENT_QUIT);
|
||||
|
||||
|
@ -332,6 +333,7 @@ Common::Keymap *DefaultEventManager::getGlobalKeymap() {
|
|||
#endif
|
||||
|
||||
globalKeymap->addAction(act);
|
||||
}
|
||||
|
||||
act = new Action("DEBUGGER", _("Open Debugger"));
|
||||
act->addDefaultInputMapping("C+A+d");
|
||||
|
|
|
@ -426,7 +426,7 @@ bool SdlEventSource::pollEvent(Common::Event &event) {
|
|||
#endif
|
||||
|
||||
// If the screen changed, send an Common::EVENT_SCREEN_CHANGED
|
||||
int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID();
|
||||
int screenID = g_system->getScreenChangeID();
|
||||
if (screenID != _lastScreenID) {
|
||||
_lastScreenID = screenID;
|
||||
event.type = Common::EVENT_SCREEN_CHANGED;
|
||||
|
@ -963,7 +963,7 @@ bool SdlEventSource::handleResizeEvent(Common::Event &event, int w, int h) {
|
|||
_graphicsManager->notifyResize(w, h);
|
||||
|
||||
// If the screen changed, send an Common::EVENT_SCREEN_CHANGED
|
||||
int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID();
|
||||
int screenID = g_system->getScreenChangeID();
|
||||
if (screenID != _lastScreenID) {
|
||||
_lastScreenID = screenID;
|
||||
event.type = Common::EVENT_SCREEN_CHANGED;
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) = 0;
|
||||
virtual void setCursorPalette(const byte *colors, uint start, uint num) = 0;
|
||||
|
||||
virtual void displayMessageOnOSD(const char *msg) {}
|
||||
virtual void displayMessageOnOSD(const Common::U32String &msg) {}
|
||||
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) {}
|
||||
|
||||
|
||||
|
|
|
@ -305,7 +305,7 @@ void SdlGraphicsManager::saveScreenshot() {
|
|||
#endif
|
||||
|
||||
for (int n = 0;; n++) {
|
||||
filename = Common::String::format("scummvm%s%s-%05d.%s", currentTarget.empty() ? "" : "-",
|
||||
filename = Common::String::format("residualvm%s%s-%05d.%s", currentTarget.empty() ? "" : "-",
|
||||
currentTarget.c_str(), n, extension);
|
||||
|
||||
Common::FSNode file = Common::FSNode(screenshotsPath + filename);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
namespace Common {
|
||||
|
||||
Action::Action(const char *i, const String &des) :
|
||||
Action::Action(const char *i, const U32String &des) :
|
||||
id(i),
|
||||
description(des),
|
||||
_shouldTriggerOnKbdRepeats(false) {
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "common/array.h"
|
||||
#include "common/events.h"
|
||||
#include "common/str.h"
|
||||
#include "common/ustr.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
@ -42,7 +43,7 @@ struct Action {
|
|||
/** unique id used for saving/loading to config */
|
||||
const char *id;
|
||||
/** Human readable description */
|
||||
String description;
|
||||
U32String description;
|
||||
|
||||
/** Event to be sent when mapped key is pressed */
|
||||
Event event;
|
||||
|
@ -52,7 +53,7 @@ private:
|
|||
bool _shouldTriggerOnKbdRepeats;
|
||||
|
||||
public:
|
||||
Action(const char *id, const String &description);
|
||||
Action(const char *id, const U32String &description);
|
||||
|
||||
void setEvent(const Event &evt) {
|
||||
event = evt;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
namespace Common {
|
||||
|
||||
Keymap::Keymap(KeymapType type, const String &id, const String &description) :
|
||||
Keymap::Keymap(KeymapType type, const String &id, const U32String &description) :
|
||||
_type(type),
|
||||
_id(id),
|
||||
_description(description),
|
||||
|
@ -44,6 +44,17 @@ Keymap::Keymap(KeymapType type, const String &id, const String &description) :
|
|||
|
||||
}
|
||||
|
||||
Keymap::Keymap(KeymapType type, const String &id, const String &description) :
|
||||
_type(type),
|
||||
_id(id),
|
||||
_description(U32String(description)),
|
||||
_enabled(true),
|
||||
_configDomain(nullptr),
|
||||
_hardwareInputSet(nullptr),
|
||||
_backendDefaultBindings(nullptr) {
|
||||
|
||||
}
|
||||
|
||||
Keymap::~Keymap() {
|
||||
for (ActionArray::iterator it = _actions.begin(); it != _actions.end(); ++it)
|
||||
delete *it;
|
||||
|
|
|
@ -80,6 +80,7 @@ public:
|
|||
|
||||
typedef Array<Action *> ActionArray;
|
||||
|
||||
Keymap(KeymapType type, const String &id, const U32String &description);
|
||||
Keymap(KeymapType type, const String &id, const String &description);
|
||||
~Keymap();
|
||||
void setConfigDomain(ConfigManager::Domain *configDomain);
|
||||
|
@ -155,7 +156,7 @@ public:
|
|||
void saveMappings();
|
||||
|
||||
const String &getId() const { return _id; }
|
||||
const String &getDescription() const { return _description; }
|
||||
const U32String &getDescription() const { return _description; }
|
||||
KeymapType getType() const { return _type; }
|
||||
|
||||
/**
|
||||
|
@ -180,7 +181,7 @@ private:
|
|||
|
||||
KeymapType _type;
|
||||
String _id;
|
||||
String _description;
|
||||
U32String _description;
|
||||
|
||||
bool _enabled;
|
||||
|
||||
|
|
|
@ -222,9 +222,13 @@ void RemapWidget::startRemapping(uint actionIndex) {
|
|||
_actions[actionIndex].keyButton->setLabel("...");
|
||||
_actions[actionIndex].keyButton->setTooltip("");
|
||||
_actions[actionIndex].keyButton->markAsDirty();
|
||||
|
||||
g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
|
||||
}
|
||||
|
||||
void RemapWidget::stopRemapping() {
|
||||
g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
|
||||
|
||||
_remapKeymap = nullptr;
|
||||
_remapAction = nullptr;
|
||||
|
||||
|
@ -274,10 +278,10 @@ void RemapWidget::refreshKeymap() {
|
|||
ActionRow &row = _actions[i];
|
||||
|
||||
if (!row.actionText) {
|
||||
row.actionText = new GUI::StaticTextWidget(widgetsBoss(), 0, 0, 0, 0, "", Graphics::kTextAlignStart, nullptr, GUI::ThemeEngine::kFontStyleNormal);
|
||||
row.actionText = new GUI::StaticTextWidget(widgetsBoss(), 0, 0, 0, 0, U32String(""), Graphics::kTextAlignStart, U32String(""), GUI::ThemeEngine::kFontStyleNormal);
|
||||
row.actionText->setLabel(row.action->description);
|
||||
|
||||
row.keyButton = new GUI::DropdownButtonWidget(widgetsBoss(), 0, 0, 0, 0, "", nullptr, kRemapCmd + i);
|
||||
row.keyButton = new GUI::DropdownButtonWidget(widgetsBoss(), 0, 0, 0, 0, U32String(""), U32String(""), kRemapCmd + i);
|
||||
row.keyButton->appendEntry(_("Reset to defaults"), kResetActionCmd + i);
|
||||
row.keyButton->appendEntry(_("Clear mapping"), kClearCmd + i);
|
||||
}
|
||||
|
@ -304,7 +308,7 @@ void RemapWidget::refreshKeymap() {
|
|||
KeymapTitleRow &keymapTitle = _keymapSeparators[row.keymap];
|
||||
if (!keymapTitle.descriptionText) {
|
||||
keymapTitle.descriptionText = new GUI::StaticTextWidget(widgetsBoss(), 0, 0, 0, 0, row.keymap->getDescription(), Graphics::kTextAlignStart);
|
||||
keymapTitle.resetButton = new GUI::ButtonWidget(widgetsBoss(), 0, 0, 0, 0, "", nullptr, kResetKeymapCmd + i);
|
||||
keymapTitle.resetButton = new GUI::ButtonWidget(widgetsBoss(), 0, 0, 0, 0, U32String(""), U32String(""), kResetKeymapCmd + i);
|
||||
|
||||
// I18N: Button to reset keymap mappings to defaults
|
||||
keymapTitle.resetButton->setLabel(_("Reset"));
|
||||
|
|
67
backends/mixer/mixer.h
Normal file
67
backends/mixer/mixer.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* 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 BACKENDS_MIXER_ABSTRACT_H
|
||||
#define BACKENDS_MIXER_ABSTRACT_H
|
||||
|
||||
#include "audio/mixer_intern.h"
|
||||
|
||||
/**
|
||||
* Abstract class for mixer manager. Subclasses
|
||||
* implement the real functionality.
|
||||
*/
|
||||
class MixerManager {
|
||||
public:
|
||||
MixerManager() : _mixer(0), _audioSuspended(false) {}
|
||||
virtual ~MixerManager() { delete _mixer; }
|
||||
|
||||
/**
|
||||
* Initialize and setups the mixer
|
||||
*/
|
||||
virtual void init() = 0;
|
||||
|
||||
/**
|
||||
* Get the audio mixer implementation
|
||||
*/
|
||||
Audio::Mixer *getMixer() { return (Audio::Mixer *)_mixer; }
|
||||
|
||||
// Used by LinuxMoto Port
|
||||
|
||||
/**
|
||||
* Pauses the audio system
|
||||
*/
|
||||
virtual void suspendAudio() = 0;
|
||||
|
||||
/**
|
||||
* Resumes the audio system
|
||||
*/
|
||||
virtual int resumeAudio() = 0;
|
||||
|
||||
protected:
|
||||
/** The mixer implementation */
|
||||
Audio::MixerImpl *_mixer;
|
||||
|
||||
/** State of the audio system */
|
||||
bool _audioSuspended;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -38,19 +38,12 @@
|
|||
#define SAMPLES_PER_SEC 44100
|
||||
#endif
|
||||
|
||||
SdlMixerManager::SdlMixerManager()
|
||||
:
|
||||
_mixer(0),
|
||||
_audioSuspended(false) {
|
||||
|
||||
}
|
||||
|
||||
SdlMixerManager::~SdlMixerManager() {
|
||||
_mixer->setReady(false);
|
||||
|
||||
SDL_CloseAudio();
|
||||
|
||||
delete _mixer;
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
}
|
||||
|
||||
void SdlMixerManager::init() {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#define BACKENDS_MIXER_SDL_H
|
||||
|
||||
#include "backends/platform/sdl/sdl-sys.h"
|
||||
#include "audio/mixer_intern.h"
|
||||
#include "backends/mixer/mixer.h"
|
||||
|
||||
/**
|
||||
* SDL mixer manager. It wraps the actual implementation
|
||||
|
@ -32,9 +32,8 @@
|
|||
* the SDL audio subsystem and the callback for the
|
||||
* audio mixer implementation.
|
||||
*/
|
||||
class SdlMixerManager {
|
||||
class SdlMixerManager : public MixerManager {
|
||||
public:
|
||||
SdlMixerManager();
|
||||
virtual ~SdlMixerManager();
|
||||
|
||||
/**
|
||||
|
@ -42,11 +41,6 @@ public:
|
|||
*/
|
||||
virtual void init();
|
||||
|
||||
/**
|
||||
* Get the audio mixer implementation
|
||||
*/
|
||||
Audio::Mixer *getMixer() { return (Audio::Mixer *)_mixer; }
|
||||
|
||||
// Used by Event recorder
|
||||
|
||||
/**
|
||||
|
@ -60,18 +54,12 @@ public:
|
|||
virtual int resumeAudio();
|
||||
|
||||
protected:
|
||||
/** The mixer implementation */
|
||||
Audio::MixerImpl *_mixer;
|
||||
|
||||
/**
|
||||
* The obtained audio specification after opening the
|
||||
* audio system.
|
||||
*/
|
||||
SDL_AudioSpec _obtained;
|
||||
|
||||
/** State of the audio system */
|
||||
bool _audioSuspended;
|
||||
|
||||
/**
|
||||
* Returns the desired audio specification
|
||||
*/
|
||||
|
|
|
@ -22,181 +22,173 @@
|
|||
|
||||
#include "backends/modular-backend.h"
|
||||
|
||||
#include "backends/audiocd/audiocd.h"
|
||||
#include "backends/graphics/graphics.h"
|
||||
#include "backends/graphics/resvm-graphics.h" // ResidualVM specific
|
||||
#include "backends/mixer/mixer.h"
|
||||
#include "backends/mutex/mutex.h"
|
||||
#include "gui/EventRecorder.h"
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "common/timer.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
#include "graphics/pixelbuffer.h" // ResidualVM specific:
|
||||
|
||||
ModularBackend::ModularBackend()
|
||||
ModularGraphicsBackend::ModularGraphicsBackend()
|
||||
:
|
||||
_mutexManager(0),
|
||||
_graphicsManager(0),
|
||||
_mixer(0) {
|
||||
_graphicsManager(0) {
|
||||
|
||||
}
|
||||
|
||||
ModularBackend::~ModularBackend() {
|
||||
ModularGraphicsBackend::~ModularGraphicsBackend() {
|
||||
delete _graphicsManager;
|
||||
_graphicsManager = 0;
|
||||
delete _mixer;
|
||||
_mixer = 0;
|
||||
// _timerManager needs to be deleted before _mutexManager to avoid a crash.
|
||||
delete _timerManager;
|
||||
_timerManager = 0;
|
||||
delete _mutexManager;
|
||||
_mutexManager = 0;
|
||||
}
|
||||
|
||||
bool ModularBackend::hasFeature(Feature f) {
|
||||
bool ModularGraphicsBackend::hasFeature(Feature f) {
|
||||
return _graphicsManager->hasFeature(f);
|
||||
}
|
||||
|
||||
void ModularBackend::setFeatureState(Feature f, bool enable) {
|
||||
void ModularGraphicsBackend::setFeatureState(Feature f, bool enable) {
|
||||
_graphicsManager->setFeatureState(f, enable);
|
||||
}
|
||||
|
||||
bool ModularBackend::getFeatureState(Feature f) {
|
||||
bool ModularGraphicsBackend::getFeatureState(Feature f) {
|
||||
return _graphicsManager->getFeatureState(f);
|
||||
}
|
||||
|
||||
GraphicsManager *ModularBackend::getGraphicsManager() {
|
||||
GraphicsManager *ModularGraphicsBackend::getGraphicsManager() {
|
||||
assert(_graphicsManager);
|
||||
return (GraphicsManager *)_graphicsManager;
|
||||
}
|
||||
|
||||
const OSystem::GraphicsMode *ModularBackend::getSupportedGraphicsModes() const {
|
||||
const OSystem::GraphicsMode *ModularGraphicsBackend::getSupportedGraphicsModes() const {
|
||||
return _graphicsManager->getSupportedGraphicsModes();
|
||||
}
|
||||
|
||||
int ModularBackend::getDefaultGraphicsMode() const {
|
||||
int ModularGraphicsBackend::getDefaultGraphicsMode() const {
|
||||
return _graphicsManager->getDefaultGraphicsMode();
|
||||
}
|
||||
|
||||
bool ModularBackend::setGraphicsMode(int mode) {
|
||||
bool ModularGraphicsBackend::setGraphicsMode(int mode) {
|
||||
return _graphicsManager->setGraphicsMode(mode);
|
||||
}
|
||||
|
||||
int ModularBackend::getGraphicsMode() const {
|
||||
int ModularGraphicsBackend::getGraphicsMode() const {
|
||||
return _graphicsManager->getGraphicsMode();
|
||||
}
|
||||
|
||||
const OSystem::GraphicsMode *ModularBackend::getSupportedShaders() const {
|
||||
const OSystem::GraphicsMode *ModularGraphicsBackend::getSupportedShaders() const {
|
||||
return _graphicsManager->getSupportedShaders();
|
||||
}
|
||||
|
||||
int ModularBackend::getDefaultShader() const {
|
||||
int ModularGraphicsBackend::getDefaultShader() const {
|
||||
return _graphicsManager->getDefaultShader();
|
||||
}
|
||||
|
||||
bool ModularBackend::setShader(int id) {
|
||||
bool ModularGraphicsBackend::setShader(int id) {
|
||||
return _graphicsManager->setShader(id);
|
||||
}
|
||||
|
||||
int ModularBackend::getShader() const {
|
||||
int ModularGraphicsBackend::getShader() const {
|
||||
return _graphicsManager->getShader();
|
||||
}
|
||||
|
||||
const OSystem::GraphicsMode *ModularBackend::getSupportedStretchModes() const {
|
||||
const OSystem::GraphicsMode *ModularGraphicsBackend::getSupportedStretchModes() const {
|
||||
return _graphicsManager->getSupportedStretchModes();
|
||||
}
|
||||
|
||||
int ModularBackend::getDefaultStretchMode() const {
|
||||
int ModularGraphicsBackend::getDefaultStretchMode() const {
|
||||
return _graphicsManager->getDefaultStretchMode();
|
||||
}
|
||||
|
||||
bool ModularBackend::setStretchMode(int mode) {
|
||||
bool ModularGraphicsBackend::setStretchMode(int mode) {
|
||||
return _graphicsManager->setStretchMode(mode);
|
||||
}
|
||||
|
||||
int ModularBackend::getStretchMode() const {
|
||||
int ModularGraphicsBackend::getStretchMode() const {
|
||||
return _graphicsManager->getStretchMode();
|
||||
}
|
||||
|
||||
void ModularBackend::resetGraphicsScale() {
|
||||
void ModularGraphicsBackend::resetGraphicsScale() {
|
||||
_graphicsManager->resetGraphicsScale();
|
||||
}
|
||||
|
||||
#ifdef USE_RGB_COLOR
|
||||
|
||||
Graphics::PixelFormat ModularBackend::getScreenFormat() const {
|
||||
Graphics::PixelFormat ModularGraphicsBackend::getScreenFormat() const {
|
||||
return _graphicsManager->getScreenFormat();
|
||||
}
|
||||
|
||||
Common::List<Graphics::PixelFormat> ModularBackend::getSupportedFormats() const {
|
||||
Common::List<Graphics::PixelFormat> ModularGraphicsBackend::getSupportedFormats() const {
|
||||
return _graphicsManager->getSupportedFormats();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ResidualVM specific method
|
||||
void ModularBackend::setupScreen(uint screenW, uint screenH, bool fullscreen, bool accel3d) {
|
||||
void ModularGraphicsBackend::setupScreen(uint screenW, uint screenH, bool fullscreen, bool accel3d) {
|
||||
_graphicsManager->setupScreen(screenW, screenH, fullscreen, accel3d);
|
||||
}
|
||||
|
||||
// ResidualVM specific method
|
||||
Graphics::PixelBuffer ModularBackend::getScreenPixelBuffer() {
|
||||
Graphics::PixelBuffer ModularGraphicsBackend::getScreenPixelBuffer() {
|
||||
return _graphicsManager->getScreenPixelBuffer();
|
||||
}
|
||||
|
||||
// ResidualVM specific method
|
||||
void ModularBackend::suggestSideTextures(Graphics::Surface *left, Graphics::Surface *right) {
|
||||
void ModularGraphicsBackend::suggestSideTextures(Graphics::Surface *left, Graphics::Surface *right) {
|
||||
_graphicsManager->suggestSideTextures(left, right);
|
||||
}
|
||||
|
||||
void ModularBackend::initSize(uint w, uint h, const Graphics::PixelFormat *format ) {
|
||||
void ModularGraphicsBackend::initSize(uint w, uint h, const Graphics::PixelFormat *format ) {
|
||||
_graphicsManager->initSize(w, h, format);
|
||||
}
|
||||
|
||||
void ModularBackend::initSizeHint(const Graphics::ModeList &modes) {
|
||||
void ModularGraphicsBackend::initSizeHint(const Graphics::ModeList &modes) {
|
||||
_graphicsManager->initSizeHint(modes);
|
||||
}
|
||||
|
||||
int ModularBackend::getScreenChangeID() const {
|
||||
int ModularGraphicsBackend::getScreenChangeID() const {
|
||||
return _graphicsManager->getScreenChangeID();
|
||||
}
|
||||
|
||||
void ModularBackend::beginGFXTransaction() {
|
||||
void ModularGraphicsBackend::beginGFXTransaction() {
|
||||
_graphicsManager->beginGFXTransaction();
|
||||
}
|
||||
|
||||
OSystem::TransactionError ModularBackend::endGFXTransaction() {
|
||||
OSystem::TransactionError ModularGraphicsBackend::endGFXTransaction() {
|
||||
return _graphicsManager->endGFXTransaction();
|
||||
}
|
||||
|
||||
int16 ModularBackend::getHeight() {
|
||||
int16 ModularGraphicsBackend::getHeight() {
|
||||
return _graphicsManager->getHeight();
|
||||
}
|
||||
|
||||
int16 ModularBackend::getWidth() {
|
||||
int16 ModularGraphicsBackend::getWidth() {
|
||||
return _graphicsManager->getWidth();
|
||||
}
|
||||
|
||||
PaletteManager *ModularBackend::getPaletteManager() {
|
||||
PaletteManager *ModularGraphicsBackend::getPaletteManager() {
|
||||
return _graphicsManager;
|
||||
}
|
||||
|
||||
void ModularBackend::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
|
||||
void ModularGraphicsBackend::copyRectToScreen(const void *buf, int pitch, int x, int y, int w, int h) {
|
||||
_graphicsManager->copyRectToScreen(buf, pitch, x, y, w, h);
|
||||
}
|
||||
|
||||
Graphics::Surface *ModularBackend::lockScreen() {
|
||||
Graphics::Surface *ModularGraphicsBackend::lockScreen() {
|
||||
return _graphicsManager->lockScreen();
|
||||
}
|
||||
|
||||
void ModularBackend::unlockScreen() {
|
||||
void ModularGraphicsBackend::unlockScreen() {
|
||||
_graphicsManager->unlockScreen();
|
||||
}
|
||||
|
||||
void ModularBackend::fillScreen(uint32 col) {
|
||||
void ModularGraphicsBackend::fillScreen(uint32 col) {
|
||||
_graphicsManager->fillScreen(col);
|
||||
}
|
||||
|
||||
void ModularBackend::updateScreen() {
|
||||
void ModularGraphicsBackend::updateScreen() {
|
||||
#ifdef ENABLE_EVENTRECORDER
|
||||
g_eventRec.preDrawOverlayGui();
|
||||
#endif
|
||||
|
@ -208,100 +200,135 @@ void ModularBackend::updateScreen() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void ModularBackend::setShakePos(int shakeXOffset, int shakeYOffset) {
|
||||
void ModularGraphicsBackend::setShakePos(int shakeXOffset, int shakeYOffset) {
|
||||
_graphicsManager->setShakePos(shakeXOffset, shakeYOffset);
|
||||
}
|
||||
void ModularBackend::setFocusRectangle(const Common::Rect& rect) {
|
||||
void ModularGraphicsBackend::setFocusRectangle(const Common::Rect& rect) {
|
||||
_graphicsManager->setFocusRectangle(rect);
|
||||
}
|
||||
|
||||
void ModularBackend::clearFocusRectangle() {
|
||||
void ModularGraphicsBackend::clearFocusRectangle() {
|
||||
_graphicsManager->clearFocusRectangle();
|
||||
}
|
||||
|
||||
void ModularBackend::showOverlay() {
|
||||
void ModularGraphicsBackend::showOverlay() {
|
||||
_graphicsManager->showOverlay();
|
||||
}
|
||||
|
||||
void ModularBackend::hideOverlay() {
|
||||
void ModularGraphicsBackend::hideOverlay() {
|
||||
_graphicsManager->hideOverlay();
|
||||
}
|
||||
|
||||
Graphics::PixelFormat ModularBackend::getOverlayFormat() const {
|
||||
Graphics::PixelFormat ModularGraphicsBackend::getOverlayFormat() const {
|
||||
return _graphicsManager->getOverlayFormat();
|
||||
}
|
||||
|
||||
void ModularBackend::clearOverlay() {
|
||||
void ModularGraphicsBackend::clearOverlay() {
|
||||
_graphicsManager->clearOverlay();
|
||||
}
|
||||
|
||||
void ModularBackend::grabOverlay(void *buf, int pitch) {
|
||||
void ModularGraphicsBackend::grabOverlay(void *buf, int pitch) {
|
||||
_graphicsManager->grabOverlay(buf, pitch);
|
||||
}
|
||||
|
||||
void ModularBackend::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
|
||||
void ModularGraphicsBackend::copyRectToOverlay(const void *buf, int pitch, int x, int y, int w, int h) {
|
||||
_graphicsManager->copyRectToOverlay(buf, pitch, x, y, w, h);
|
||||
}
|
||||
|
||||
int16 ModularBackend::getOverlayHeight() {
|
||||
int16 ModularGraphicsBackend::getOverlayHeight() {
|
||||
return _graphicsManager->getOverlayHeight();
|
||||
}
|
||||
|
||||
int16 ModularBackend::getOverlayWidth() {
|
||||
int16 ModularGraphicsBackend::getOverlayWidth() {
|
||||
return _graphicsManager->getOverlayWidth();
|
||||
}
|
||||
|
||||
bool ModularBackend::showMouse(bool visible) {
|
||||
bool ModularGraphicsBackend::showMouse(bool visible) {
|
||||
return _graphicsManager->showMouse(visible);
|
||||
}
|
||||
|
||||
// ResidualVM specific method
|
||||
bool ModularBackend::lockMouse(bool visible) {
|
||||
bool ModularGraphicsBackend::lockMouse(bool visible) {
|
||||
return _graphicsManager->lockMouse(visible);
|
||||
}
|
||||
|
||||
void ModularBackend::warpMouse(int x, int y) {
|
||||
void ModularGraphicsBackend::warpMouse(int x, int y) {
|
||||
_eventManager->purgeMouseEvents();
|
||||
_graphicsManager->warpMouse(x, y);
|
||||
}
|
||||
|
||||
void ModularBackend::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||
void ModularGraphicsBackend::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||
_graphicsManager->setMouseCursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
|
||||
}
|
||||
|
||||
void ModularBackend::setCursorPalette(const byte *colors, uint start, uint num) {
|
||||
void ModularGraphicsBackend::setCursorPalette(const byte *colors, uint start, uint num) {
|
||||
_graphicsManager->setCursorPalette(colors, start, num);
|
||||
}
|
||||
|
||||
OSystem::MutexRef ModularBackend::createMutex() {
|
||||
void ModularGraphicsBackend::displayMessageOnOSD(const Common::U32String &msg) {
|
||||
_graphicsManager->displayMessageOnOSD(msg);
|
||||
}
|
||||
|
||||
void ModularGraphicsBackend::displayActivityIconOnOSD(const Graphics::Surface *icon) {
|
||||
_graphicsManager->displayActivityIconOnOSD(icon);
|
||||
}
|
||||
|
||||
|
||||
ModularMixerBackend::ModularMixerBackend()
|
||||
:
|
||||
_mixerManager(0) {
|
||||
|
||||
}
|
||||
|
||||
ModularMixerBackend::~ModularMixerBackend() {
|
||||
// _audiocdManager needs to be deleted before _mixerManager to avoid a crash.
|
||||
delete _audiocdManager;
|
||||
_audiocdManager = 0;
|
||||
delete _mixerManager;
|
||||
_mixerManager = 0;
|
||||
}
|
||||
|
||||
MixerManager *ModularMixerBackend::getMixerManager() {
|
||||
assert(_mixerManager);
|
||||
return _mixerManager;
|
||||
}
|
||||
|
||||
Audio::Mixer *ModularMixerBackend::getMixer() {
|
||||
assert(_mixerManager);
|
||||
return getMixerManager()->getMixer();
|
||||
}
|
||||
|
||||
|
||||
ModularMutexBackend::ModularMutexBackend()
|
||||
:
|
||||
_mutexManager(0) {
|
||||
|
||||
}
|
||||
|
||||
ModularMutexBackend::~ModularMutexBackend() {
|
||||
// _timerManager needs to be deleted before _mutexManager to avoid a crash.
|
||||
delete _timerManager;
|
||||
_timerManager = 0;
|
||||
delete _mutexManager;
|
||||
_mutexManager = 0;
|
||||
}
|
||||
|
||||
OSystem::MutexRef ModularMutexBackend::createMutex() {
|
||||
assert(_mutexManager);
|
||||
return _mutexManager->createMutex();
|
||||
}
|
||||
|
||||
void ModularBackend::lockMutex(MutexRef mutex) {
|
||||
void ModularMutexBackend::lockMutex(MutexRef mutex) {
|
||||
assert(_mutexManager);
|
||||
_mutexManager->lockMutex(mutex);
|
||||
}
|
||||
|
||||
void ModularBackend::unlockMutex(MutexRef mutex) {
|
||||
void ModularMutexBackend::unlockMutex(MutexRef mutex) {
|
||||
assert(_mutexManager);
|
||||
_mutexManager->unlockMutex(mutex);
|
||||
}
|
||||
|
||||
void ModularBackend::deleteMutex(MutexRef mutex) {
|
||||
void ModularMutexBackend::deleteMutex(MutexRef mutex) {
|
||||
assert(_mutexManager);
|
||||
_mutexManager->deleteMutex(mutex);
|
||||
}
|
||||
|
||||
Audio::Mixer *ModularBackend::getMixer() {
|
||||
assert(_mixer);
|
||||
return (Audio::Mixer *)_mixer;
|
||||
}
|
||||
|
||||
void ModularBackend::displayMessageOnOSD(const char *msg) {
|
||||
_graphicsManager->displayMessageOnOSD(msg);
|
||||
}
|
||||
|
||||
void ModularBackend::displayActivityIconOnOSD(const Graphics::Surface *icon) {
|
||||
_graphicsManager->displayActivityIconOnOSD(icon);
|
||||
}
|
||||
|
|
|
@ -27,15 +27,16 @@
|
|||
|
||||
class GraphicsManager;
|
||||
class ResVmGraphicsManager; // ResidualVM specific
|
||||
class MixerManager;
|
||||
class MutexManager;
|
||||
|
||||
/**
|
||||
* Base class for modular backends.
|
||||
* Base classes for modular backends.
|
||||
*
|
||||
* It wraps most functions to their manager equivalent, but not
|
||||
* They wrap most functions to their manager equivalent, but not
|
||||
* all OSystem functions are implemented here.
|
||||
*
|
||||
* A backend derivated from this class, will need to implement
|
||||
* A backend derivated from these classes, will need to implement
|
||||
* these functions on its own:
|
||||
* OSystem::pollEvent()
|
||||
* OSystem::getMillis()
|
||||
|
@ -46,10 +47,10 @@ class MutexManager;
|
|||
* And, it should also initialize all the managers variables
|
||||
* declared in this class, or override their related functions.
|
||||
*/
|
||||
class ModularBackend : public BaseBackend {
|
||||
class ModularGraphicsBackend : virtual public BaseBackend {
|
||||
public:
|
||||
ModularBackend();
|
||||
virtual ~ModularBackend();
|
||||
ModularGraphicsBackend();
|
||||
virtual ~ModularGraphicsBackend();
|
||||
|
||||
/** @name Features */
|
||||
//@{
|
||||
|
@ -120,6 +121,50 @@ public:
|
|||
|
||||
//@}
|
||||
|
||||
/** @name Miscellaneous */
|
||||
//@{
|
||||
|
||||
virtual void displayMessageOnOSD(const Common::U32String &msg) override final;
|
||||
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override final;
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
/** @name Managers variables */
|
||||
//@{
|
||||
|
||||
ResVmGraphicsManager *_graphicsManager; // ResidualVM: was GraphicsManager
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
class ModularMixerBackend : virtual public BaseBackend {
|
||||
public:
|
||||
ModularMixerBackend();
|
||||
virtual ~ModularMixerBackend();
|
||||
|
||||
/** @name Sound */
|
||||
//@{
|
||||
|
||||
virtual MixerManager *getMixerManager();
|
||||
virtual Audio::Mixer *getMixer() override final;
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
/** @name Managers variables */
|
||||
//@{
|
||||
|
||||
MixerManager *_mixerManager;
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
class ModularMutexBackend : virtual public BaseBackend {
|
||||
public:
|
||||
ModularMutexBackend();
|
||||
virtual ~ModularMutexBackend();
|
||||
|
||||
/** @name Mutex handling */
|
||||
//@{
|
||||
|
||||
|
@ -130,28 +175,11 @@ public:
|
|||
|
||||
//@}
|
||||
|
||||
/** @name Sound */
|
||||
//@{
|
||||
|
||||
virtual Audio::Mixer *getMixer() override;
|
||||
|
||||
//@}
|
||||
|
||||
/** @name Miscellaneous */
|
||||
//@{
|
||||
|
||||
virtual void displayMessageOnOSD(const char *msg) override final;
|
||||
virtual void displayActivityIconOnOSD(const Graphics::Surface *icon) override final;
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
/** @name Managers variables */
|
||||
//@{
|
||||
|
||||
MutexManager *_mutexManager;
|
||||
ResVmGraphicsManager *_graphicsManager; // ResidualVM: was GraphicsManager
|
||||
Audio::Mixer *_mixer;
|
||||
|
||||
//@}
|
||||
};
|
||||
|
|
|
@ -137,6 +137,11 @@ ifdef USE_OPENGL
|
|||
MODULE_OBJS += \
|
||||
graphics/openglsdl/openglsdl-graphics.o
|
||||
endif
|
||||
|
||||
ifdef USE_DISCORD
|
||||
MODULE_OBJS += \
|
||||
presence/discord/discord.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef POSIX
|
||||
|
@ -210,6 +215,12 @@ MODULE_OBJS += \
|
|||
fs/amigaos4/amigaos4-fs-factory.o
|
||||
endif
|
||||
|
||||
ifdef MORPHOS
|
||||
MODULE_OBJS += \
|
||||
fs/morphos/morphos-fs.o \
|
||||
fs/morphos/morphos-fs-factory.o
|
||||
endif
|
||||
|
||||
ifdef RISCOS
|
||||
MODULE_OBJS += \
|
||||
events/riscossdl/riscossdl-events.o \
|
||||
|
@ -270,6 +281,11 @@ MODULE_OBJS += \
|
|||
fs/n64/romfsstream.o
|
||||
endif
|
||||
|
||||
ifeq ($(BACKEND),null)
|
||||
MODULE_OBJS += \
|
||||
mixer/null/null-mixer.o
|
||||
endif
|
||||
|
||||
ifeq ($(BACKEND),openpandora)
|
||||
MODULE_OBJS += \
|
||||
events/openpandora/op-events.o \
|
||||
|
@ -314,7 +330,7 @@ endif
|
|||
|
||||
ifdef ENABLE_EVENTRECORDER
|
||||
MODULE_OBJS += \
|
||||
mixer/nullmixer/nullsdl-mixer.o \
|
||||
mixer/null/null-mixer.o \
|
||||
saves/recorder/recorder-saves.o
|
||||
endif
|
||||
|
||||
|
|
|
@ -57,35 +57,35 @@ void CreateDirectoryHandler::handle(Client &client) {
|
|||
|
||||
// check that <path> is not an absolute root
|
||||
if (path == "" || path == "/") {
|
||||
handleError(client, HandlerUtils::toUtf8(_("Can't create directory here!")));
|
||||
handleError(client, Common::convertFromU32String(_("Can't create directory here!")));
|
||||
return;
|
||||
}
|
||||
|
||||
// check that <path> contains no '../'
|
||||
if (HandlerUtils::hasForbiddenCombinations(path)) {
|
||||
handleError(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
handleError(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
|
||||
// transform virtual path to actual file system one
|
||||
Common::String prefixToRemove = "", prefixToAdd = "";
|
||||
if (!transformPath(path, prefixToRemove, prefixToAdd) || path.empty()) {
|
||||
handleError(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
handleError(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
|
||||
// check that <path> exists, is directory and isn't forbidden
|
||||
AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path);
|
||||
if (!HandlerUtils::permittedPath(node->getPath())) {
|
||||
handleError(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
handleError(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
if (!node->exists()) {
|
||||
handleError(client, HandlerUtils::toUtf8(_("Parent directory doesn't exists!")));
|
||||
handleError(client, Common::convertFromU32String(_("Parent directory doesn't exists!")));
|
||||
return;
|
||||
}
|
||||
if (!node->isDirectory()) {
|
||||
handleError(client, HandlerUtils::toUtf8(_("Can't create a directory within a file!")));
|
||||
handleError(client, Common::convertFromU32String(_("Can't create a directory within a file!")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -95,20 +95,20 @@ void CreateDirectoryHandler::handle(Client &client) {
|
|||
node = g_system->getFilesystemFactory()->makeFileNodePath(path + name);
|
||||
if (node->exists()) {
|
||||
if (!node->isDirectory()) {
|
||||
handleError(client, HandlerUtils::toUtf8(_("There is a file with that name in the parent directory!")));
|
||||
handleError(client, Common::convertFromU32String(_("There is a file with that name in the parent directory!")));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// create the <directory_name> in <path>
|
||||
if (!node->createDirectory()) {
|
||||
handleError(client, HandlerUtils::toUtf8(_("Failed to create the directory!")));
|
||||
handleError(client, Common::convertFromU32String(_("Failed to create the directory!")));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if json requested, respond with it
|
||||
if (client.queryParameter("answer_json") == "true") {
|
||||
setJsonResponseHandler(client, "success", HandlerUtils::toUtf8(_("Directory created successfully!")));
|
||||
setJsonResponseHandler(client, "success", Common::convertFromU32String(_("Directory created successfully!")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -117,9 +117,9 @@ void CreateDirectoryHandler::handle(Client &client) {
|
|||
client,
|
||||
Common::String::format(
|
||||
"%s<br/><a href=\"files?path=%s\">%s</a>",
|
||||
HandlerUtils::toUtf8(_("Directory created successfully!")).c_str(),
|
||||
Common::convertFromU32String(_("Directory created successfully!")).c_str(),
|
||||
client.queryParameter("path").c_str(),
|
||||
HandlerUtils::toUtf8(_("Back to parent directory")).c_str()
|
||||
Common::convertFromU32String(_("Back to parent directory")).c_str()
|
||||
),
|
||||
(client.queryParameter("ajax") == "true" ? "/filesAJAX?path=" : "/files?path=") +
|
||||
LocalWebserver::urlEncodeQueryParameterValue(client.queryParameter("path"))
|
||||
|
|
|
@ -40,40 +40,40 @@ void DownloadFileHandler::handle(Client &client) {
|
|||
|
||||
// check that <path> is not an absolute root
|
||||
if (path == "" || path == "/") {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
|
||||
// check that <path> contains no '../'
|
||||
if (HandlerUtils::hasForbiddenCombinations(path)) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
|
||||
// transform virtual path to actual file system one
|
||||
Common::String prefixToRemove = "", prefixToAdd = "";
|
||||
if (!transformPath(path, prefixToRemove, prefixToAdd, false) || path.empty()) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
|
||||
// check that <path> exists, is directory and isn't forbidden
|
||||
AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path);
|
||||
if (!HandlerUtils::permittedPath(node->getPath())) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
if (!node->exists()) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("The file doesn't exist!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("The file doesn't exist!")));
|
||||
return;
|
||||
}
|
||||
if (node->isDirectory()) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Can't download a directory!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Can't download a directory!")));
|
||||
return;
|
||||
}
|
||||
Common::SeekableReadStream *stream = node->createReadStream();
|
||||
if (stream == nullptr) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Failed to read the file!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Failed to read the file!")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ void FilesAjaxPageHandler::handle(Client &client) {
|
|||
// load stylish response page from the archive
|
||||
Common::SeekableReadStream *const stream = HandlerUtils::getArchiveFile(FILES_PAGE_NAME);
|
||||
if (stream == nullptr) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("The page is not available without the resources. Make sure file wwwroot.zip from ResidualVM distribution is available in 'themepath'.")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("The page is not available without the resources. Make sure file wwwroot.zip from ResidualVM distribution is available in 'themepath'.")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -64,16 +64,16 @@ void FilesAjaxPageHandler::handle(Client &client) {
|
|||
Common::String path = client.queryParameter("path");
|
||||
|
||||
//these occur twice:
|
||||
replace(response, "{create_directory_button}", HandlerUtils::toUtf8(_("Create directory")));
|
||||
replace(response, "{create_directory_button}", HandlerUtils::toUtf8(_("Create directory")));
|
||||
replace(response, "{upload_files_button}", HandlerUtils::toUtf8(_("Upload files"))); //tab
|
||||
replace(response, "{upload_file_button}", HandlerUtils::toUtf8(_("Upload files"))); //button in the tab
|
||||
replace(response, "{create_directory_desc}", HandlerUtils::toUtf8(_("Type new directory name:")));
|
||||
replace(response, "{upload_file_desc}", HandlerUtils::toUtf8(_("Select a file to upload:")));
|
||||
replace(response, "{or_upload_directory_desc}", HandlerUtils::toUtf8(_("Or select a directory (works in Chrome only):")));
|
||||
replace(response, "{index_of}", HandlerUtils::toUtf8(_("Index of ")));
|
||||
replace(response, "{loading}", HandlerUtils::toUtf8(("Loading...")));
|
||||
replace(response, "{error}", HandlerUtils::toUtf8(_("Error occurred")));
|
||||
replace(response, "{create_directory_button}", _("Create directory").encode());
|
||||
replace(response, "{create_directory_button}", _("Create directory").encode());
|
||||
replace(response, "{upload_files_button}", _("Upload files").encode()); //tab
|
||||
replace(response, "{upload_file_button}", _("Upload files").encode()); //button in the tab
|
||||
replace(response, "{create_directory_desc}", _("Type new directory name:").encode());
|
||||
replace(response, "{upload_file_desc}", _("Select a file to upload:").encode());
|
||||
replace(response, "{or_upload_directory_desc}", _("Or select a directory (works in Chrome only):").encode());
|
||||
replace(response, "{index_of}", _("Index of ").encode());
|
||||
replace(response, "{loading}", ("Loading..."));
|
||||
replace(response, "{error}", _("Error occurred").encode());
|
||||
replace(response, "{start_path}", encodeDoubleQuotesAndSlashes(path));
|
||||
LocalWebserver::setClientGetHandler(client, response);
|
||||
}
|
||||
|
|
|
@ -78,8 +78,8 @@ Common::String getDisplayPath(Common::String s) {
|
|||
bool FilesPageHandler::listDirectory(Common::String path, Common::String &content, const Common::String &itemTemplate) {
|
||||
if (path == "" || path == "/") {
|
||||
if (ConfMan.hasKey("rootpath", "cloud"))
|
||||
addItem(content, itemTemplate, IT_DIRECTORY, "/root/", HandlerUtils::toUtf8(_("File system root")));
|
||||
addItem(content, itemTemplate, IT_DIRECTORY, "/saves/", HandlerUtils::toUtf8(_("Saved games")));
|
||||
addItem(content, itemTemplate, IT_DIRECTORY, "/root/", Common::convertFromU32String(_("File system root")));
|
||||
addItem(content, itemTemplate, IT_DIRECTORY, "/saves/", Common::convertFromU32String(_("Saved games")));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ bool FilesPageHandler::listDirectory(Common::String path, Common::String &conten
|
|||
filePath = "/";
|
||||
else
|
||||
filePath = parentPath(prefixToAdd + filePath);
|
||||
addItem(content, itemTemplate, IT_PARENT_DIRECTORY, filePath, HandlerUtils::toUtf8(_("Parent directory")));
|
||||
addItem(content, itemTemplate, IT_PARENT_DIRECTORY, filePath, Common::convertFromU32String(_("Parent directory")));
|
||||
}
|
||||
|
||||
// fill the content
|
||||
|
@ -215,21 +215,21 @@ void FilesPageHandler::handle(Client &client) {
|
|||
|
||||
// show an error message if failed to list directory
|
||||
if (!listDirectory(path, content, itemTemplate)) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("ResidualVM couldn't list the directory you specified.")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("ResidualVM couldn't list the directory you specified.")).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
//these occur twice:
|
||||
replace(response, "{create_directory_button}", HandlerUtils::toUtf8(_("Create directory")));
|
||||
replace(response, "{create_directory_button}", HandlerUtils::toUtf8(_("Create directory")));
|
||||
replace(response, "{create_directory_button}", _("Create directory").encode());
|
||||
replace(response, "{create_directory_button}", _("Create directory").encode());
|
||||
replace(response, "{path}", encodeDoubleQuotes(client.queryParameter("path")));
|
||||
replace(response, "{path}", encodeDoubleQuotes(client.queryParameter("path")));
|
||||
replace(response, "{upload_files_button}", HandlerUtils::toUtf8(_("Upload files"))); //tab
|
||||
replace(response, "{upload_file_button}", HandlerUtils::toUtf8(_("Upload files"))); //button in the tab
|
||||
replace(response, "{create_directory_desc}", HandlerUtils::toUtf8(_("Type new directory name:")));
|
||||
replace(response, "{upload_file_desc}", HandlerUtils::toUtf8(_("Select a file to upload:")));
|
||||
replace(response, "{or_upload_directory_desc}", HandlerUtils::toUtf8(_("Or select a directory (works in Chrome only):")));
|
||||
replace(response, "{index_of_directory}", Common::String::format("%s %s", HandlerUtils::toUtf8(_("Index of")).c_str(), encodeHtmlEntities(getDisplayPath(client.queryParameter("path"))).c_str()));
|
||||
replace(response, "{upload_files_button}", _("Upload files").encode()); //tab
|
||||
replace(response, "{upload_file_button}", _("Upload files").encode()); //button in the tab
|
||||
replace(response, "{create_directory_desc}", _("Type new directory name:").encode());
|
||||
replace(response, "{upload_file_desc}", _("Select a file to upload:").encode());
|
||||
replace(response, "{or_upload_directory_desc}", _("Or select a directory (works in Chrome only):").encode());
|
||||
replace(response, "{index_of_directory}", Common::String::format("%s %s", _("Index of").encode().c_str(), encodeHtmlEntities(getDisplayPath(client.queryParameter("path"))).c_str()));
|
||||
replace(response, "{content}", content);
|
||||
LocalWebserver::setClientGetHandler(client, response);
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ void IndexPageHandler::handle(Client &client) {
|
|||
client,
|
||||
Common::String::format(
|
||||
"%s<br/><a href=\"files\">%s</a>",
|
||||
HandlerUtils::toUtf8(_("This is a local webserver index page.")).c_str(),
|
||||
HandlerUtils::toUtf8(_("Open Files manager")).c_str()
|
||||
Common::convertFromU32String(_("This is a local webserver index page.")).c_str(),
|
||||
Common::convertFromU32String(_("Open Files manager")).c_str()
|
||||
),
|
||||
"/filesAJAX"
|
||||
);
|
||||
|
|
|
@ -42,8 +42,8 @@ Common::JSONObject ListAjaxHandler::listDirectory(Common::String path) {
|
|||
|
||||
if (path == "" || path == "/") {
|
||||
if (ConfMan.hasKey("rootpath", "cloud"))
|
||||
addItem(itemsList, IT_DIRECTORY, "/root/", HandlerUtils::toUtf8(_("File system root")));
|
||||
addItem(itemsList, IT_DIRECTORY, "/saves/", HandlerUtils::toUtf8(_("Saved games")));
|
||||
addItem(itemsList, IT_DIRECTORY, "/root/", Common::convertFromU32String(_("File system root")));
|
||||
addItem(itemsList, IT_DIRECTORY, "/saves/", Common::convertFromU32String(_("Saved games")));
|
||||
successResult.setVal("items", new Common::JSONValue(itemsList));
|
||||
return successResult;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ Common::JSONObject ListAjaxHandler::listDirectory(Common::String path) {
|
|||
filePath = "/";
|
||||
else
|
||||
filePath = parentPath(prefixToAdd + filePath);
|
||||
addItem(itemsList, IT_PARENT_DIRECTORY, filePath, HandlerUtils::toUtf8(_("Parent directory")));
|
||||
addItem(itemsList, IT_PARENT_DIRECTORY, filePath, Common::convertFromU32String(_("Parent directory")));
|
||||
}
|
||||
|
||||
// fill the content
|
||||
|
|
|
@ -40,35 +40,35 @@ void UploadFileHandler::handle(Client &client) {
|
|||
|
||||
// check that <path> is not an absolute root
|
||||
if (path == "" || path == "/" || path == "\\") {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
|
||||
// check that <path> contains no '../'
|
||||
if (HandlerUtils::hasForbiddenCombinations(path)) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
|
||||
// transform virtual path to actual file system one
|
||||
Common::String prefixToRemove = "", prefixToAdd = "";
|
||||
if (!transformPath(path, prefixToRemove, prefixToAdd, false) || path.empty()) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
|
||||
// check that <path> exists, is directory and isn't forbidden
|
||||
AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path);
|
||||
if (!HandlerUtils::permittedPath(node->getPath())) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
if (!node->exists()) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("The parent directory doesn't exist!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("The parent directory doesn't exist!")));
|
||||
return;
|
||||
}
|
||||
if (!node->isDirectory()) {
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, HandlerUtils::toUtf8(_("Can't upload into a file!")));
|
||||
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Can't upload into a file!")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -172,21 +172,6 @@ bool HandlerUtils::permittedPath(const Common::String path) {
|
|||
return hasPermittedPrefix(path) && !isBlacklisted(path);
|
||||
}
|
||||
|
||||
Common::String HandlerUtils::toUtf8(const char *text) {
|
||||
#ifdef USE_TRANSLATION
|
||||
Common::String guiEncoding = TransMan.getCurrentCharset();
|
||||
if (guiEncoding != "ASCII") {
|
||||
char *utf8Text = Common::Encoding::convert("utf-8", guiEncoding, text, strlen(text));
|
||||
if (utf8Text != nullptr) {
|
||||
Common::String str(utf8Text);
|
||||
free(utf8Text);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Common::String(text);
|
||||
}
|
||||
|
||||
void HandlerUtils::setMessageHandler(Client &client, Common::String message, Common::String redirectTo) {
|
||||
Common::String response = "<html><head><title>ResidualVM</title><meta charset=\"utf-8\"/></head><body>{message}</body></html>";
|
||||
|
||||
|
@ -210,7 +195,7 @@ void HandlerUtils::setFilesManagerErrorMessageHandler(Client &client, Common::St
|
|||
message.c_str(),
|
||||
client.queryParameter("ajax") == "true" ? "AJAX" : "",
|
||||
"%2F", //that's encoded "/"
|
||||
toUtf8(_("Back to the files manager")).c_str()
|
||||
Common::convertFromU32String(_("Back to the files manager")).c_str()
|
||||
),
|
||||
redirectTo
|
||||
);
|
||||
|
|
|
@ -41,8 +41,6 @@ public:
|
|||
static bool hasPermittedPrefix(const Common::String &path);
|
||||
static bool permittedPath(const Common::String path);
|
||||
|
||||
static Common::String toUtf8(const char*);
|
||||
|
||||
static void setMessageHandler(Client &client, Common::String message, Common::String redirectTo = "");
|
||||
static void setFilesManagerErrorMessageHandler(Client &client, Common::String message, Common::String redirectTo = "");
|
||||
};
|
||||
|
|
|
@ -66,7 +66,7 @@ void UploadFileClientHandler::handle(Client *client) {
|
|||
|
||||
// fail on suspicious headers
|
||||
if (_headersStream->size() > Reader::SUSPICIOUS_HEADERS_SIZE) {
|
||||
setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("Invalid request: headers are too long!")));
|
||||
setErrorMessageHandler(*client, Common::convertFromU32String(_("Invalid request: headers are too long!")));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -108,7 +108,7 @@ void UploadFileClientHandler::handleBlockHeaders(Client *client) {
|
|||
|
||||
// fail on suspicious headers
|
||||
if (_headersStream->size() > Reader::SUSPICIOUS_HEADERS_SIZE) {
|
||||
setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("Invalid request: headers are too long!")));
|
||||
setErrorMessageHandler(*client, Common::convertFromU32String(_("Invalid request: headers are too long!")));
|
||||
}
|
||||
|
||||
// search for "upload_file" field
|
||||
|
@ -134,11 +134,11 @@ void UploadFileClientHandler::handleBlockHeaders(Client *client) {
|
|||
path += '/';
|
||||
AbstractFSNode *originalNode = g_system->getFilesystemFactory()->makeFileNodePath(path + filename);
|
||||
if (!HandlerUtils::permittedPath(originalNode->getPath())) {
|
||||
setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("Invalid path!")));
|
||||
setErrorMessageHandler(*client, Common::convertFromU32String(_("Invalid path!")));
|
||||
return;
|
||||
}
|
||||
if (originalNode->exists()) {
|
||||
setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("There is a file with that name in the parent directory!")));
|
||||
setErrorMessageHandler(*client, Common::convertFromU32String(_("There is a file with that name in the parent directory!")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ void UploadFileClientHandler::handleBlockHeaders(Client *client) {
|
|||
Common::DumpFile *f = new Common::DumpFile();
|
||||
if (!f->open(originalNode->getPath(), true)) {
|
||||
delete f;
|
||||
setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("Failed to upload the file!")));
|
||||
setErrorMessageHandler(*client, Common::convertFromU32String(_("Failed to upload the file!")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ void UploadFileClientHandler::handleBlockContent(Client *client) {
|
|||
if (client->noMoreContent()) {
|
||||
// if no file field was found - failure
|
||||
if (_uploadedFiles == 0) {
|
||||
setErrorMessageHandler(*client, HandlerUtils::toUtf8(_("No file was passed!")));
|
||||
setErrorMessageHandler(*client, Common::convertFromU32String(_("No file was passed!")));
|
||||
} else {
|
||||
setSuccessHandler(*client);
|
||||
}
|
||||
|
@ -199,9 +199,9 @@ void UploadFileClientHandler::setSuccessHandler(Client &client) {
|
|||
client,
|
||||
Common::String::format(
|
||||
"%s<br/><a href=\"files?path=%s\">%s</a>",
|
||||
HandlerUtils::toUtf8(_("Uploaded successfully!")).c_str(),
|
||||
Common::convertFromU32String(_("Uploaded successfully!")).c_str(),
|
||||
client.queryParameter("path").c_str(),
|
||||
HandlerUtils::toUtf8(_("Back to parent directory")).c_str()
|
||||
Common::convertFromU32String(_("Back to parent directory")).c_str()
|
||||
),
|
||||
(client.queryParameter("ajax") == "true" ? "/filesAJAX?path=" : "/files?path=") +
|
||||
LocalWebserver::urlEncodeQueryParameterValue(client.queryParameter("path"))
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_getenv(a)
|
||||
|
||||
// Allow use of stuff in <time.h>
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
|
||||
|
||||
|
@ -53,11 +55,16 @@
|
|||
#include "common/events.h"
|
||||
#include "common/config-manager.h"
|
||||
|
||||
#include "backends/keymapper/keymapper.h"
|
||||
#include "backends/audiocd/default/default-audiocd.h"
|
||||
#include "backends/events/default/default-events.h"
|
||||
#include "backends/mutex/pthread/pthread-mutex.h"
|
||||
#include "backends/saves/default/default-saves.h"
|
||||
#include "backends/timer/default/default-timer.h"
|
||||
|
||||
#include "backends/keymapper/keymapper.h"
|
||||
#include "backends/keymapper/keymapper-defaults.h"
|
||||
#include "backends/keymapper/standard-actions.h"
|
||||
|
||||
#include "backends/platform/android/jni-android.h"
|
||||
#include "backends/platform/android/android.h"
|
||||
#include "backends/platform/android/graphics.h"
|
||||
|
@ -153,10 +160,10 @@ OSystem_Android::~OSystem_Android() {
|
|||
delete _timerManager;
|
||||
_timerManager = 0;
|
||||
|
||||
deleteMutex(_event_queue_lock);
|
||||
delete _event_queue_lock;
|
||||
|
||||
delete _mutexManager;
|
||||
_mutexManager = 0;
|
||||
delete _savefileManager;
|
||||
_savefileManager = 0;
|
||||
}
|
||||
|
||||
void *OSystem_Android::timerThreadFunc(void *arg) {
|
||||
|
|
|
@ -69,7 +69,7 @@ int main(int argc, char *argv[]) {
|
|||
assert(g_system);
|
||||
|
||||
// Pre-initialize the backend.
|
||||
((OSystem_AmigaOS *)g_system)->init();
|
||||
g_system->init();
|
||||
|
||||
#ifdef DYNAMIC_MODULES
|
||||
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "backends/platform/sdl/macosx/appmenu_osx.h"
|
||||
#include "common/translation.h"
|
||||
#include "common/ustr.h"
|
||||
|
||||
#include "backends/platform/sdl/macosx/macosx-compat.h"
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
@ -41,6 +42,16 @@
|
|||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
|
||||
typedef unsigned long NSUInteger;
|
||||
|
||||
// Those are not defined in the 10.4 SDK, but they are defined when targetting
|
||||
// Mac OS X 10.4 or above in the 10.5 SDK. So hopfully that means it works with 10.4 as well.
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
enum {
|
||||
NSUTF32StringEncoding = 0x8c000100,
|
||||
NSUTF32BigEndianStringEncoding = 0x98000100,
|
||||
NSUTF32LittleEndianStringEncoding = 0x9c000100
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Apple added setAppleMenu in 10.5 and removed it in 10.6.
|
||||
|
@ -132,16 +143,21 @@ static void openFromBundle(NSString *file) {
|
|||
}
|
||||
@end
|
||||
|
||||
NSString *constructNSStringFromCString(const char *rawCString, CFStringEncoding stringEncoding) {
|
||||
return (NSString *)CFStringCreateWithCString(NULL, rawCString, stringEncoding);
|
||||
NSString *constructNSStringFromU32String(const Common::U32String &rawU32String) {
|
||||
#ifdef SCUMM_LITTLE_ENDIAN
|
||||
NSStringEncoding stringEncoding = NSUTF32LittleEndianStringEncoding;
|
||||
#else
|
||||
NSStringEncoding stringEncoding = NSUTF32BigEndianStringEncoding;
|
||||
#endif
|
||||
return [[NSString alloc] initWithBytes:rawU32String.c_str() length:4*rawU32String.size() encoding: stringEncoding];
|
||||
}
|
||||
|
||||
static NSMenu *addMenu(const char *title, CFStringEncoding encoding, NSString *key, SEL setAs) {
|
||||
static NSMenu *addMenu(const Common::U32String &title, NSString *key, SEL setAs) {
|
||||
if (setAs && ![NSApp respondsToSelector:setAs]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString *str = constructNSStringFromCString(title, encoding);
|
||||
NSString *str = constructNSStringFromU32String(title);
|
||||
NSMenu *menu = [[NSMenu alloc] initWithTitle:str];
|
||||
|
||||
NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:str action:nil keyEquivalent:key];
|
||||
|
@ -158,8 +174,8 @@ static NSMenu *addMenu(const char *title, CFStringEncoding encoding, NSString *k
|
|||
return menu;
|
||||
}
|
||||
|
||||
static void addMenuItem(const char *title, CFStringEncoding encoding, id target, SEL selector, NSString *key, NSMenu *parent, NSEventModifierFlags flags = 0) {
|
||||
NSString *nsString = constructNSStringFromCString(title, encoding);
|
||||
static void addMenuItem(const Common::U32String &title, id target, SEL selector, NSString *key, NSMenu *parent, NSEventModifierFlags flags = 0) {
|
||||
NSString *nsString = constructNSStringFromU32String(title);
|
||||
NSMenuItem *menuItem = [[NSMenuItem alloc]
|
||||
initWithTitle:nsString
|
||||
action:selector
|
||||
|
@ -189,48 +205,38 @@ void replaceApplicationMenuItems() {
|
|||
}
|
||||
|
||||
NSString *nsString = NULL;
|
||||
|
||||
// Get current encoding
|
||||
#ifdef USE_TRANSLATION
|
||||
nsString = constructNSStringFromCString(TransMan.getCurrentCharset().c_str(), NSASCIIStringEncoding);
|
||||
CFStringEncoding stringEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)nsString);
|
||||
[nsString release];
|
||||
#else
|
||||
CFStringEncoding stringEncoding = kCFStringEncodingASCII;
|
||||
#endif
|
||||
|
||||
NSMenu *appleMenu = addMenu("ResidualVM", kCFStringEncodingASCII, @"", @selector(setAppleMenu:));
|
||||
NSMenu *appleMenu = addMenu(Common::U32String("ResidualVM"), @"", @selector(setAppleMenu:));
|
||||
if (appleMenu) {
|
||||
addMenuItem(_("About ResidualVM"), stringEncoding, nil, @selector(orderFrontStandardAboutPanel:), @"", appleMenu);
|
||||
addMenuItem(_("About ResidualVM"), nil, @selector(orderFrontStandardAboutPanel:), @"", appleMenu);
|
||||
[appleMenu addItem:[NSMenuItem separatorItem]];
|
||||
addMenuItem(_("Hide ResidualVM"), stringEncoding, nil, @selector(hide:), @"h", appleMenu);
|
||||
addMenuItem(_("Hide Others"), stringEncoding, nil, @selector(hideOtherApplications:), @"h", appleMenu, (NSEventModifierFlagOption|NSEventModifierFlagCommand));
|
||||
addMenuItem(_("Show All"), stringEncoding, nil, @selector(unhideAllApplications:), @"", appleMenu);
|
||||
addMenuItem(_("Hide ResidualVM"), nil, @selector(hide:), @"h", appleMenu);
|
||||
addMenuItem(_("Hide Others"), nil, @selector(hideOtherApplications:), @"h", appleMenu, (NSEventModifierFlagOption|NSEventModifierFlagCommand));
|
||||
addMenuItem(_("Show All"), nil, @selector(unhideAllApplications:), @"", appleMenu);
|
||||
[appleMenu addItem:[NSMenuItem separatorItem]];
|
||||
addMenuItem(_("Quit ResidualVM"), stringEncoding, nil, @selector(terminate:), @"q", appleMenu);
|
||||
addMenuItem(_("Quit ResidualVM"), nil, @selector(terminate:), @"q", appleMenu);
|
||||
}
|
||||
|
||||
NSMenu *windowMenu = addMenu(_("Window"), stringEncoding, @"", @selector(setWindowsMenu:));
|
||||
NSMenu *windowMenu = addMenu(_("Window"), @"", @selector(setWindowsMenu:));
|
||||
if (windowMenu) {
|
||||
addMenuItem(_("Minimize"), stringEncoding, nil, @selector(performMiniaturize:), @"m", windowMenu);
|
||||
addMenuItem(_("Minimize"), nil, @selector(performMiniaturize:), @"m", windowMenu);
|
||||
}
|
||||
|
||||
NSMenu *helpMenu = addMenu(_("Help"), stringEncoding, @"", @selector(setHelpMenu:));
|
||||
NSMenu *helpMenu = addMenu(_("Help"), @"", @selector(setHelpMenu:));
|
||||
if (helpMenu) {
|
||||
if (!delegate) {
|
||||
delegate = [[ScummVMMenuHandler alloc] init];
|
||||
}
|
||||
addMenuItem(_("User Manual"), stringEncoding, delegate, @selector(openUserManual), @"", helpMenu);
|
||||
addMenuItem(_("User Manual"), delegate, @selector(openUserManual), @"", helpMenu);
|
||||
[helpMenu addItem:[NSMenuItem separatorItem]];
|
||||
addMenuItem(_("General Information"), stringEncoding, delegate, @selector(openReadme), @"", helpMenu);
|
||||
addMenuItem(_("What's New in ResidualVM"), stringEncoding, delegate, @selector(openNews), @"", helpMenu);
|
||||
addMenuItem(_("General Information"), delegate, @selector(openReadme), @"", helpMenu);
|
||||
addMenuItem(_("What's New in ResidualVM"), delegate, @selector(openNews), @"", helpMenu);
|
||||
[helpMenu addItem:[NSMenuItem separatorItem]];
|
||||
addMenuItem(_("Credits"), stringEncoding, delegate, @selector(openCredits), @"", helpMenu);
|
||||
addMenuItem(_("GPL License"), stringEncoding, delegate, @selector(openLicenseGPL), @"", helpMenu);
|
||||
addMenuItem(_("LGPL License"), stringEncoding, delegate, @selector(openLicenseLGPL), @"", helpMenu);
|
||||
addMenuItem(_("Freefont License"), stringEncoding, delegate, @selector(openLicenseFreefont), @"", helpMenu);
|
||||
addMenuItem(_("OFL License"), stringEncoding, delegate, @selector(openLicenseOFL), @"", helpMenu);
|
||||
addMenuItem(_("BSD License"), stringEncoding, delegate, @selector(openLicenseBSD), @"", helpMenu);
|
||||
addMenuItem(_("Credits"), delegate, @selector(openCredits), @"", helpMenu);
|
||||
addMenuItem(_("GPL License"), delegate, @selector(openLicenseGPL), @"", helpMenu);
|
||||
addMenuItem(_("LGPL License"), delegate, @selector(openLicenseLGPL), @"", helpMenu);
|
||||
addMenuItem(_("Freefont License"), delegate, @selector(openLicenseFreefont), @"", helpMenu);
|
||||
addMenuItem(_("OFL License"), delegate, @selector(openLicenseOFL), @"", helpMenu);
|
||||
addMenuItem(_("BSD License"), delegate, @selector(openLicenseBSD), @"", helpMenu);
|
||||
}
|
||||
|
||||
[appleMenu release];
|
||||
|
|
|
@ -35,7 +35,7 @@ int main(int argc, char *argv[]) {
|
|||
assert(g_system);
|
||||
|
||||
// Pre initialize the backend
|
||||
((OSystem_MacOSX *)g_system)->init();
|
||||
g_system->init();
|
||||
|
||||
#ifdef DYNAMIC_MODULES
|
||||
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
|
||||
|
|
|
@ -139,11 +139,11 @@ bool OSystem_MacOSX::hasTextInClipboard() {
|
|||
return hasTextInClipboardMacOSX();
|
||||
}
|
||||
|
||||
Common::String OSystem_MacOSX::getTextFromClipboard() {
|
||||
Common::U32String OSystem_MacOSX::getTextFromClipboard() {
|
||||
return getTextFromClipboardMacOSX();
|
||||
}
|
||||
|
||||
bool OSystem_MacOSX::setTextInClipboard(const Common::String &text) {
|
||||
bool OSystem_MacOSX::setTextInClipboard(const Common::U32String &text) {
|
||||
return setTextInClipboardMacOSX(text);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ public:
|
|||
virtual bool displayLogFile();
|
||||
|
||||
virtual bool hasTextInClipboard();
|
||||
virtual Common::String getTextFromClipboard();
|
||||
virtual bool setTextInClipboard(const Common::String &text);
|
||||
virtual Common::U32String getTextFromClipboard();
|
||||
virtual bool setTextInClipboard(const Common::U32String &text);
|
||||
|
||||
virtual bool openUrl(const Common::String &url);
|
||||
|
||||
|
|
|
@ -24,10 +24,11 @@
|
|||
#define PLATFORM_SDL_MACOSX_WRAPPER_H
|
||||
|
||||
#include <common/str.h>
|
||||
#include <common/ustr.h>
|
||||
|
||||
bool hasTextInClipboardMacOSX();
|
||||
Common::String getTextFromClipboardMacOSX();
|
||||
bool setTextInClipboardMacOSX(const Common::String &text);
|
||||
Common::U32String getTextFromClipboardMacOSX();
|
||||
bool setTextInClipboardMacOSX(const Common::U32String &text);
|
||||
Common::String getDesktopPathMacOSX();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "backends/platform/sdl/macosx/macosx_wrapper.h"
|
||||
#include "common/translation.h"
|
||||
#include "backends/platform/sdl/macosx/macosx-compat.h"
|
||||
|
||||
#include <AppKit/NSPasteboard.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
|
@ -32,43 +33,67 @@
|
|||
#include <AvailabilityMacros.h>
|
||||
#include <CoreFoundation/CFString.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
|
||||
typedef unsigned long NSUInteger;
|
||||
|
||||
// Those are not defined in the 10.4 SDK, but they are defined when targetting
|
||||
// Mac OS X 10.4 or above in the 10.5 SDK. So hopfully that means it works with 10.4 as well.
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
enum {
|
||||
NSUTF32StringEncoding = 0x8c000100,
|
||||
NSUTF32BigEndianStringEncoding = 0x98000100,
|
||||
NSUTF32LittleEndianStringEncoding = 0x9c000100
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool hasTextInClipboardMacOSX() {
|
||||
return [[NSPasteboard generalPasteboard] availableTypeFromArray:[NSArray arrayWithObject:NSStringPboardType]] != nil;
|
||||
}
|
||||
|
||||
Common::String getTextFromClipboardMacOSX() {
|
||||
Common::U32String getTextFromClipboardMacOSX() {
|
||||
if (!hasTextInClipboardMacOSX())
|
||||
return Common::String();
|
||||
return Common::U32String();
|
||||
// Note: on OS X 10.6 and above it is recommanded to use NSPasteboardTypeString rather than NSStringPboardType.
|
||||
// But since we still target older version use NSStringPboardType.
|
||||
NSPasteboard *pb = [NSPasteboard generalPasteboard];
|
||||
NSString *str = [pb stringForType:NSStringPboardType];
|
||||
if (str == nil)
|
||||
return Common::String();
|
||||
return Common::U32String();
|
||||
|
||||
// If translations are supported, use the current TranslationManager charset and otherwise
|
||||
// use ASCII. If the string cannot be represented using the requested encoding we get a null
|
||||
// pointer below, which is fine as ScummVM would not know what to do with the string anyway.
|
||||
#ifdef USE_TRANSLATION
|
||||
NSString* encStr = [NSString stringWithCString:TransMan.getCurrentCharset().c_str() encoding:NSASCIIStringEncoding];
|
||||
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)encStr));
|
||||
#ifdef SCUMM_LITTLE_ENDIAN
|
||||
NSStringEncoding stringEncoding = NSUTF32LittleEndianStringEncoding;
|
||||
#else
|
||||
NSStringEncoding encoding = NSISOLatin1StringEncoding;
|
||||
NSStringEncoding stringEncoding = NSUTF32BigEndianStringEncoding;
|
||||
#endif
|
||||
return Common::String([str cStringUsingEncoding:encoding]);
|
||||
NSUInteger textLength = [str length];
|
||||
uint32 *text = new uint32[textLength];
|
||||
if (![str getBytes:text maxLength:4*textLength usedLength:NULL encoding: stringEncoding options:0 range:NSMakeRange(0, textLength) remainingRange:NULL]) {
|
||||
delete[] text;
|
||||
return Common::U32String();
|
||||
}
|
||||
Common::U32String u32String(text, textLength);
|
||||
delete[] text;
|
||||
|
||||
return u32String;
|
||||
}
|
||||
|
||||
bool setTextInClipboardMacOSX(const Common::String &text) {
|
||||
bool setTextInClipboardMacOSX(const Common::U32String &text) {
|
||||
NSPasteboard *pb = [NSPasteboard generalPasteboard];
|
||||
[pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
||||
|
||||
#ifdef USE_TRANSLATION
|
||||
NSString* encStr = [NSString stringWithCString:TransMan.getCurrentCharset().c_str() encoding:NSASCIIStringEncoding];
|
||||
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)encStr));
|
||||
#ifdef SCUMM_LITTLE_ENDIAN
|
||||
NSStringEncoding stringEncoding = NSUTF32LittleEndianStringEncoding;
|
||||
#else
|
||||
NSStringEncoding encoding = NSISOLatin1StringEncoding;
|
||||
NSStringEncoding stringEncoding = NSUTF32BigEndianStringEncoding;
|
||||
#endif
|
||||
return [pb setString:[NSString stringWithCString:text.c_str() encoding:encoding] forType:NSStringPboardType];
|
||||
NSString *nsstring = [[NSString alloc] initWithBytes:text.c_str() length:4*text.size() encoding: stringEncoding];
|
||||
bool status = [pb setString:nsstring forType:NSStringPboardType];
|
||||
[nsstring release];
|
||||
return status;
|
||||
}
|
||||
|
||||
Common::String getDesktopPathMacOSX() {
|
||||
|
|
|
@ -35,7 +35,7 @@ int main(int argc, char *argv[]) {
|
|||
assert(g_system);
|
||||
|
||||
// Pre initialize the backend
|
||||
((OSystem_POSIX *)g_system)->init();
|
||||
g_system->init();
|
||||
|
||||
#ifdef DYNAMIC_MODULES
|
||||
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
|
||||
|
|
|
@ -40,7 +40,7 @@ int main(int argc, char *argv[]) {
|
|||
assert(g_system);
|
||||
|
||||
// Pre initialize the backend
|
||||
((OSystem_PS3 *)g_system)->init();
|
||||
g_system->init();
|
||||
|
||||
#ifdef DYNAMIC_MODULES
|
||||
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
|
||||
|
|
|
@ -35,7 +35,7 @@ int main(int argc, char *argv[]) {
|
|||
assert(g_system);
|
||||
|
||||
// Pre initialize the backend
|
||||
((OSystem_RISCOS *)g_system)->init();
|
||||
g_system->init();
|
||||
|
||||
#ifdef DYNAMIC_MODULES
|
||||
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
|
||||
|
|
|
@ -202,8 +202,10 @@ bool SdlWindow::getSDLWMInformation(SDL_SysWMinfo *info) const {
|
|||
SDL_VERSION(&info->version);
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
return _window ? (SDL_GetWindowWMInfo(_window, info) == SDL_TRUE) : false;
|
||||
#else
|
||||
#elif !defined(__MORPHOS__)
|
||||
return SDL_GetWMInfo(info);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#include "common/translation.h"
|
||||
#include "common/encoding.h"
|
||||
|
||||
#ifdef USE_DISCORD
|
||||
#include "backends/presence/discord/discord.h"
|
||||
#endif
|
||||
|
||||
#include "backends/saves/default/default-saves.h"
|
||||
|
||||
// Audio CD support was removed with SDL 2.0
|
||||
|
@ -90,7 +94,6 @@ OSystem_SDL::OSystem_SDL()
|
|||
_initedSDLnet(false),
|
||||
#endif
|
||||
_logger(0),
|
||||
_mixerManager(0),
|
||||
_eventSource(0),
|
||||
_eventSourceWrapper(nullptr),
|
||||
_window(0) {
|
||||
|
@ -100,7 +103,7 @@ OSystem_SDL::~OSystem_SDL() {
|
|||
SDL_ShowCursor(SDL_ENABLE);
|
||||
|
||||
// Delete the various managers here. Note that the ModularBackend
|
||||
// destructor would also take care of this for us. However, various
|
||||
// destructors would also take care of this for us. However, various
|
||||
// of our managers must be deleted *before* we call SDL_Quit().
|
||||
// Hence, we perform the destruction on our own.
|
||||
delete _savefileManager;
|
||||
|
@ -138,6 +141,11 @@ OSystem_SDL::~OSystem_SDL() {
|
|||
delete _logger;
|
||||
_logger = 0;
|
||||
|
||||
#ifdef USE_DISCORD
|
||||
delete _presence;
|
||||
_presence = 0;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL_NET
|
||||
if (_initedSDLnet) SDLNet_Quit();
|
||||
#endif
|
||||
|
@ -179,7 +187,7 @@ bool OSystem_SDL::hasFeature(Feature f) {
|
|||
if (f == kFeatureJoystickDeadzone || f == kFeatureKbdMouseSpeed) {
|
||||
return _eventSource->isJoystickConnected();
|
||||
}
|
||||
return ModularBackend::hasFeature(f);
|
||||
return ModularGraphicsBackend::hasFeature(f);
|
||||
}
|
||||
|
||||
void OSystem_SDL::initBackend() {
|
||||
|
@ -282,9 +290,13 @@ void OSystem_SDL::initBackend() {
|
|||
// Setup a custom program icon.
|
||||
_window->setupIcon();
|
||||
|
||||
#ifdef USE_DISCORD
|
||||
_presence = new DiscordPresence();
|
||||
#endif
|
||||
|
||||
_inited = true;
|
||||
|
||||
ModularBackend::initBackend();
|
||||
BaseBackend::initBackend();
|
||||
|
||||
// We have to initialize the graphics manager before the event manager
|
||||
// so the virtual keyboard can be initialized, but we have to add the
|
||||
|
@ -383,9 +395,14 @@ void OSystem_SDL::engineInit() {
|
|||
// Add the started engine to the list of recent tasks
|
||||
_taskbarManager->addRecent(ConfMan.getActiveDomainName(), ConfMan.get("description"));
|
||||
|
||||
// Set the overlay icon the current running engine
|
||||
// Set the overlay icon to the current running engine
|
||||
_taskbarManager->setOverlayIcon(ConfMan.getActiveDomainName(), ConfMan.get("description"));
|
||||
#endif
|
||||
#ifdef USE_DISCORD
|
||||
// Set the presence status to the current running engine
|
||||
_presence->updateStatus(ConfMan.get("gameid"), ConfMan.get("description"));
|
||||
#endif
|
||||
|
||||
_eventSource->setEngineRunning(true);
|
||||
}
|
||||
|
||||
|
@ -397,6 +414,10 @@ void OSystem_SDL::engineDone() {
|
|||
#ifdef USE_TASKBAR
|
||||
// Remove overlay icon
|
||||
_taskbarManager->setOverlayIcon("", "");
|
||||
#endif
|
||||
#ifdef USE_DISCORD
|
||||
// Reset presence status
|
||||
_presence->updateStatus("", "");
|
||||
#endif
|
||||
_eventSource->setEngineRunning(false);
|
||||
}
|
||||
|
@ -486,7 +507,7 @@ void OSystem_SDL::setupScreen(uint screenW, uint screenH, bool fullscreen, bool
|
|||
sdlGraphicsManager->activateManager();
|
||||
}
|
||||
|
||||
ModularBackend::setupScreen(screenW, screenH, fullscreen, accel3d);
|
||||
ModularGraphicsBackend::setupScreen(screenW, screenH, fullscreen, accel3d);
|
||||
}
|
||||
|
||||
Common::Array<uint> OSystem_SDL::getSupportedAntiAliasingLevels() const {
|
||||
|
@ -517,7 +538,7 @@ void OSystem_SDL::fatalError() {
|
|||
}
|
||||
|
||||
Common::KeymapArray OSystem_SDL::getGlobalKeymaps() {
|
||||
Common::KeymapArray globalMaps = ModularBackend::getGlobalKeymaps();
|
||||
Common::KeymapArray globalMaps = BaseBackend::getGlobalKeymaps();
|
||||
|
||||
SdlGraphicsManager *graphicsManager = dynamic_cast<SdlGraphicsManager *>(_graphicsManager);
|
||||
globalMaps.push_back(graphicsManager->getKeymap());
|
||||
|
@ -588,7 +609,7 @@ Common::String OSystem_SDL::getSystemLanguage() const {
|
|||
|
||||
// Detect the language from the locale
|
||||
if (locale.empty()) {
|
||||
return ModularBackend::getSystemLanguage();
|
||||
return BaseBackend::getSystemLanguage();
|
||||
} else {
|
||||
int length = 0;
|
||||
|
||||
|
@ -606,7 +627,7 @@ Common::String OSystem_SDL::getSystemLanguage() const {
|
|||
return Common::String(locale.c_str(), length);
|
||||
}
|
||||
#else // USE_DETECTLANG
|
||||
return ModularBackend::getSystemLanguage();
|
||||
return BaseBackend::getSystemLanguage();
|
||||
#endif // USE_DETECTLANG
|
||||
}
|
||||
|
||||
|
@ -615,41 +636,22 @@ bool OSystem_SDL::hasTextInClipboard() {
|
|||
return SDL_HasClipboardText() == SDL_TRUE;
|
||||
}
|
||||
|
||||
Common::String OSystem_SDL::getTextFromClipboard() {
|
||||
if (!hasTextInClipboard()) return "";
|
||||
Common::U32String OSystem_SDL::getTextFromClipboard() {
|
||||
if (!hasTextInClipboard()) return Common::U32String("");
|
||||
|
||||
char *text = SDL_GetClipboardText();
|
||||
// The string returned by SDL is in UTF-8. Convert to the
|
||||
// current TranslationManager encoding or ISO-8859-1.
|
||||
#ifdef USE_TRANSLATION
|
||||
char *conv_text = SDL_iconv_string(TransMan.getCurrentCharset().c_str(), "UTF-8", text, SDL_strlen(text) + 1);
|
||||
#else
|
||||
char *conv_text = SDL_iconv_string("ISO-8859-1", "UTF-8", text, SDL_strlen(text) + 1);
|
||||
#endif
|
||||
if (conv_text) {
|
||||
SDL_free(text);
|
||||
text = conv_text;
|
||||
}
|
||||
Common::String strText = text;
|
||||
|
||||
Common::String utf8Text(text);
|
||||
Common::U32String strText = utf8Text.decode();
|
||||
SDL_free(text);
|
||||
|
||||
return strText;
|
||||
}
|
||||
|
||||
bool OSystem_SDL::setTextInClipboard(const Common::String &text) {
|
||||
// The encoding we need to use is UTF-8. Assume we currently have the
|
||||
// current TranslationManager encoding or ISO-8859-1.
|
||||
#ifdef USE_TRANSLATION
|
||||
char *utf8_text = SDL_iconv_string("UTF-8", TransMan.getCurrentCharset().c_str(), text.c_str(), text.size() + 1);
|
||||
#else
|
||||
char *utf8_text = SDL_iconv_string("UTF-8", "ISO-8859-1", text.c_str(), text.size() + 1);
|
||||
#endif
|
||||
if (utf8_text) {
|
||||
int status = SDL_SetClipboardText(utf8_text);
|
||||
SDL_free(utf8_text);
|
||||
return status == 0;
|
||||
}
|
||||
return SDL_SetClipboardText(text.c_str()) == 0;
|
||||
bool OSystem_SDL::setTextInClipboard(const Common::U32String &text) {
|
||||
// The encoding we need to use is UTF-8.
|
||||
Common::String utf8Text = text.encode();
|
||||
return SDL_SetClipboardText(utf8Text.c_str()) == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -682,12 +684,7 @@ void OSystem_SDL::getTimeAndDate(TimeDate &td) const {
|
|||
td.tm_wday = t.tm_wday;
|
||||
}
|
||||
|
||||
Audio::Mixer *OSystem_SDL::getMixer() {
|
||||
assert(_mixerManager);
|
||||
return getMixerManager()->getMixer();
|
||||
}
|
||||
|
||||
SdlMixerManager *OSystem_SDL::getMixerManager() {
|
||||
MixerManager *OSystem_SDL::getMixerManager() {
|
||||
assert(_mixerManager);
|
||||
|
||||
#ifdef ENABLE_EVENTRECORDER
|
||||
|
@ -882,7 +879,7 @@ void OSystem_SDL::setupGraphicsModes() {
|
|||
#endif // ResidualVM
|
||||
|
||||
char *OSystem_SDL::convertEncoding(const char *to, const char *from, const char *string, size_t length) {
|
||||
#if SDL_VERSION_ATLEAST(1, 2, 10)
|
||||
#if SDL_VERSION_ATLEAST(1, 2, 10) && !defined(__MORPHOS__)
|
||||
int zeroBytes = 1;
|
||||
if (Common::String(from).hasPrefixIgnoreCase("utf-16"))
|
||||
zeroBytes = 2;
|
||||
|
@ -924,7 +921,7 @@ char *OSystem_SDL::convertEncoding(const char *to, const char *from, const char
|
|||
SDL_free(result);
|
||||
return finalResult;
|
||||
#else
|
||||
return ModularBackend::convertEncoding(to, from, string, length);
|
||||
return BaseBackend::convertEncoding(to, from, string, length);
|
||||
#endif // SDL_VERSION_ATLEAST(1, 2, 10)
|
||||
}
|
||||
|
||||
|
|
|
@ -30,18 +30,22 @@
|
|||
#include "backends/events/sdl/sdl-events.h"
|
||||
#include "backends/log/log.h"
|
||||
#include "backends/platform/sdl/sdl-window.h"
|
||||
|
||||
#include "common/array.h"
|
||||
|
||||
#ifdef USE_DISCORD
|
||||
class DiscordPresence;
|
||||
#endif
|
||||
// ResidualVM - Start
|
||||
#ifdef USE_OPENGL
|
||||
#include "backends/graphics/openglsdl/openglsdl-graphics.h"
|
||||
#endif
|
||||
// ResidualVM - End
|
||||
|
||||
#include "common/array.h"
|
||||
|
||||
/**
|
||||
* Base OSystem class for all SDL ports.
|
||||
*/
|
||||
class OSystem_SDL : public ModularBackend {
|
||||
class OSystem_SDL : public ModularMutexBackend, public ModularMixerBackend, public ModularGraphicsBackend {
|
||||
public:
|
||||
OSystem_SDL();
|
||||
virtual ~OSystem_SDL();
|
||||
|
@ -51,14 +55,7 @@ public:
|
|||
* instantiating the backend. Early needed managers are
|
||||
* created here.
|
||||
*/
|
||||
virtual void init();
|
||||
|
||||
/**
|
||||
* Get the Mixer Manager instance. Not to confuse with getMixer(),
|
||||
* that returns Audio::Mixer. The Mixer Manager is a SDL wrapper class
|
||||
* for the Audio::Mixer. Used by other managers.
|
||||
*/
|
||||
virtual SdlMixerManager *getMixerManager();
|
||||
virtual void init() override;
|
||||
|
||||
virtual bool hasFeature(Feature f) override;
|
||||
|
||||
|
@ -79,8 +76,8 @@ public:
|
|||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
// Clipboard
|
||||
virtual bool hasTextInClipboard() override;
|
||||
virtual Common::String getTextFromClipboard() override;
|
||||
virtual bool setTextInClipboard(const Common::String &text) override;
|
||||
virtual Common::U32String getTextFromClipboard() override;
|
||||
virtual bool setTextInClipboard(const Common::U32String &text) override;
|
||||
#endif
|
||||
|
||||
virtual void setWindowCaption(const char *caption) override;
|
||||
|
@ -88,7 +85,7 @@ public:
|
|||
virtual uint32 getMillis(bool skipRecord = false) override;
|
||||
virtual void delayMillis(uint msecs) override;
|
||||
virtual void getTimeAndDate(TimeDate &td) const override;
|
||||
virtual Audio::Mixer *getMixer() override;
|
||||
virtual MixerManager *getMixerManager() override;
|
||||
virtual Common::TimerManager *getTimerManager() override;
|
||||
virtual Common::SaveFileManager *getSavefileManager() override;
|
||||
|
||||
|
@ -110,6 +107,10 @@ protected:
|
|||
bool _initedSDLnet;
|
||||
#endif
|
||||
|
||||
#ifdef USE_DISCORD
|
||||
DiscordPresence *_presence;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The path of the currently open log file, if any.
|
||||
*
|
||||
|
@ -120,12 +121,6 @@ protected:
|
|||
*/
|
||||
Common::String _logFilePath;
|
||||
|
||||
/**
|
||||
* Mixer manager that configures and setups SDL for
|
||||
* the wrapped Audio::Mixer, the true mixer.
|
||||
*/
|
||||
SdlMixerManager *_mixerManager;
|
||||
|
||||
/**
|
||||
* The event source we use for obtaining SDL events.
|
||||
*/
|
||||
|
@ -146,7 +141,6 @@ protected:
|
|||
#endif
|
||||
// End of ResidualVM specific code
|
||||
|
||||
virtual Common::EventSource *getDefaultEventSource() override { return _eventSource; }
|
||||
|
||||
/**
|
||||
* Initialze the SDL library.
|
||||
|
|
|
@ -61,7 +61,7 @@ int main(int argc, char *argv[]) {
|
|||
assert(g_system);
|
||||
|
||||
// Pre initialize the backend
|
||||
((OSystem_Win32 *)g_system)->init();
|
||||
g_system->init();
|
||||
|
||||
#ifdef DYNAMIC_MODULES
|
||||
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
|
||||
|
|
|
@ -474,18 +474,12 @@ char *OSystem_Win32::convertEncoding(const char* to, const char *from, const cha
|
|||
}
|
||||
memcpy(tmpStr, string, length);
|
||||
} else {
|
||||
// Win32::ansiToUnicode uses new to allocate the memory. We need to copy it into an array
|
||||
// allocated with malloc as it is going to be freed using free.
|
||||
WCHAR *tmpStr2 = Win32::ansiToUnicode(string, Win32::getCodePageId(from));
|
||||
if (!tmpStr2) {
|
||||
tmpStr = Win32::ansiToUnicode(string, Win32::getCodePageId(from));
|
||||
if (!tmpStr) {
|
||||
if (newString != nullptr)
|
||||
free(newString);
|
||||
return nullptr;
|
||||
}
|
||||
size_t size = wcslen(tmpStr2) + 1; // +1 for the terminating null wchar
|
||||
tmpStr = (WCHAR *) malloc(sizeof(WCHAR) * size);
|
||||
memcpy(tmpStr, tmpStr2, sizeof(WCHAR) * size);
|
||||
delete[] tmpStr2;
|
||||
}
|
||||
|
||||
if (newString != nullptr)
|
||||
|
@ -501,15 +495,7 @@ char *OSystem_Win32::convertEncoding(const char* to, const char *from, const cha
|
|||
} else {
|
||||
result = Win32::unicodeToAnsi(tmpStr, Win32::getCodePageId(to));
|
||||
free(tmpStr);
|
||||
if (!result)
|
||||
return nullptr;
|
||||
// Win32::unicodeToAnsi uses new to allocate the memory. We need to copy it into an array
|
||||
// allocated with malloc as it is going to be freed using free.
|
||||
size_t size = strlen(result) + 1;
|
||||
char *resultCopy = (char *) malloc(sizeof(char) * size);
|
||||
memcpy(resultCopy, result, sizeof(char) * size);
|
||||
delete[] result;
|
||||
return resultCopy;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ wchar_t *ansiToUnicode(const char *s, uint codePage) {
|
|||
DWORD size = MultiByteToWideChar(codePage, 0, s, -1, NULL, 0);
|
||||
|
||||
if (size > 0) {
|
||||
LPWSTR result = new WCHAR[size];
|
||||
LPWSTR result = (LPWSTR)calloc(size, sizeof(WCHAR));
|
||||
if (MultiByteToWideChar(codePage, 0, s, -1, result, size) != 0)
|
||||
return result;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ char *unicodeToAnsi(const wchar_t *s, uint codePage) {
|
|||
DWORD size = WideCharToMultiByte(codePage, 0, s, -1, NULL, 0, 0, 0);
|
||||
|
||||
if (size > 0) {
|
||||
char *result = new char[size];
|
||||
char *result = (char *)calloc(size, sizeof(char));
|
||||
if (WideCharToMultiByte(codePage, 0, s, -1, result, size, 0, 0) != 0)
|
||||
return result;
|
||||
}
|
||||
|
@ -105,19 +105,16 @@ char *unicodeToAnsi(const wchar_t *s, uint codePage) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
uint getCurrentCharset() {
|
||||
#ifdef USE_TRANSLATION
|
||||
Common::String charset = TransMan.getCurrentCharset();
|
||||
if (charset == "iso-8859-2")
|
||||
return 28592;
|
||||
if (charset == "iso-8859-5")
|
||||
return 28595;
|
||||
if (charset == "iso-8859-7")
|
||||
return 28597;
|
||||
if (charset == "iso-8859-8")
|
||||
return 28598;
|
||||
#endif
|
||||
return 28591;
|
||||
wchar_t *UTF8ToUnicode(const char *s) {
|
||||
DWORD size = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0);
|
||||
|
||||
if (size > 0) {
|
||||
LPWSTR result = (LPWSTR)calloc(size, sizeof(WCHAR));
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, s, -1, result, size) != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ bool confirmWindowsVersion(int majorVersion, int minorVersion);
|
|||
* Used to interact with Win32 Unicode APIs with no ANSI fallback.
|
||||
*
|
||||
* @param s Source string
|
||||
* @param c Code Page, by default is CP_ACP (default Windows ANSI code page)
|
||||
* @return Converted string
|
||||
*
|
||||
* @note Return value must be freed by the caller.
|
||||
|
@ -53,13 +54,23 @@ wchar_t *ansiToUnicode(const char *s, uint codePage = CP_ACP);
|
|||
* Used to interact with Win32 Unicode APIs with no ANSI fallback.
|
||||
*
|
||||
* @param s Source string
|
||||
* @param c Code Page, by default is CP_ACP (default Windows ANSI code page)
|
||||
* @return Converted string
|
||||
*
|
||||
* @note Return value must be freed by the caller.
|
||||
*/
|
||||
char *unicodeToAnsi(const wchar_t *s, uint codePage = CP_ACP);
|
||||
|
||||
uint getCurrentCharset();
|
||||
/**
|
||||
* Converts a C string encoded in UTF8-multibyte char into a Windows wide-character string.
|
||||
* Used to interact with Win32 Unicode APIs with no ANSI fallback.
|
||||
*
|
||||
* @param s Source string, encoded in UTF8
|
||||
* @return Converted string
|
||||
*
|
||||
* @note Return value must be freed by the caller.
|
||||
*/
|
||||
wchar_t *UTF8ToUnicode(const char *s);
|
||||
|
||||
}
|
||||
|
||||
|
|
59
backends/presence/discord/discord.cpp
Normal file
59
backends/presence/discord/discord.cpp
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
|
||||
#include "backends/presence/discord/discord.h"
|
||||
|
||||
#ifdef USE_DISCORD
|
||||
#include "common/translation.h"
|
||||
|
||||
#include <discord_rpc.h>
|
||||
#include <time.h>
|
||||
|
||||
#define DISCORD_CLIENT_ID "714287866464698470"
|
||||
|
||||
DiscordPresence::DiscordPresence() {
|
||||
Discord_Initialize(DISCORD_CLIENT_ID, nullptr, 0, nullptr);
|
||||
updateStatus("", "");
|
||||
}
|
||||
|
||||
DiscordPresence::~DiscordPresence() {
|
||||
Discord_ClearPresence();
|
||||
Discord_Shutdown();
|
||||
}
|
||||
|
||||
void DiscordPresence::updateStatus(const Common::String &name, const Common::String &description) {
|
||||
Common::String gameName = name.empty() ? "residualvm" : name;
|
||||
Common::String gameDesc = description.empty() ? _("Launcher").encode() : description;
|
||||
|
||||
DiscordRichPresence presence;
|
||||
memset(&presence, 0, sizeof(presence));
|
||||
presence.largeImageKey = gameName.c_str();
|
||||
presence.largeImageText = gameDesc.c_str();
|
||||
presence.details = gameDesc.c_str();
|
||||
presence.smallImageKey = "residualvm";
|
||||
presence.smallImageText = "ResidualVM";
|
||||
presence.startTimestamp = time(0);
|
||||
Discord_UpdatePresence(&presence);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -18,37 +18,33 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* This is a utility for create the translations.dat file from all the po files.
|
||||
* The generated files is used by ScummVM to propose translation of its GUI.
|
||||
*/
|
||||
|
||||
#ifndef CP_PARSER_H
|
||||
#define CP_PARSER_H
|
||||
#ifndef BACKENDS_DISCORD_H
|
||||
#define BACKENDS_DISCORD_H
|
||||
|
||||
#include "create_translations.h"
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#include <string>
|
||||
#ifdef USE_DISCORD
|
||||
#include "common/str.h"
|
||||
|
||||
/**
|
||||
* Codepage description.
|
||||
*
|
||||
* This includes a name, and the codepage -> unicode mapping.
|
||||
* Manager for interacting with the Discord Rich Presence API.
|
||||
*/
|
||||
class Codepage {
|
||||
class DiscordPresence {
|
||||
public:
|
||||
Codepage(const std::string &name, const uint32 *mapping);
|
||||
|
||||
const std::string &getName() const { return _name; }
|
||||
|
||||
uint32 getMapping(unsigned char src) const { return _mapping[src]; }
|
||||
private:
|
||||
std::string _name;
|
||||
uint32 _mapping[256];
|
||||
DiscordPresence();
|
||||
~DiscordPresence();
|
||||
/**
|
||||
* Updates the Discord presence status with game information.
|
||||
* Blank parameters default to no game running (Launcher).
|
||||
*
|
||||
* @param name Game ID and icon to display.
|
||||
* @param description Game name to display.
|
||||
*/
|
||||
void updateStatus(const Common::String &name, const Common::String &description);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the codepage file and create a codepage.
|
||||
*/
|
||||
Codepage *parseCodepageMapping(const std::string &filename);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -32,4 +32,3 @@ Common::InSaveFile *RecorderSaveFileManager::openForLoading(const Common::String
|
|||
Common::StringArray RecorderSaveFileManager::listSaveFiles(const Common::String &pattern) {
|
||||
return g_eventRec.listSaveFiles(pattern);
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ void Win32TaskbarManager::setOverlayIcon(const Common::String &name, const Commo
|
|||
|
||||
DestroyIcon(pIcon);
|
||||
|
||||
delete[] desc;
|
||||
free(desc);
|
||||
}
|
||||
|
||||
void Win32TaskbarManager::setProgressValue(int completed, int total) {
|
||||
|
@ -267,7 +267,7 @@ void Win32TaskbarManager::setCount(int count) {
|
|||
// Sets the overlay icon
|
||||
LPWSTR desc = Win32::ansiToUnicode(Common::String::format("Found games: %d", count).c_str());
|
||||
_taskbar->SetOverlayIcon(_window->getHwnd(), _icon, desc);
|
||||
delete[] desc;
|
||||
free(desc);
|
||||
}
|
||||
|
||||
void Win32TaskbarManager::addRecent(const Common::String &name, const Common::String &description) {
|
||||
|
@ -301,7 +301,7 @@ void Win32TaskbarManager::addRecent(const Common::String &name, const Common::St
|
|||
|
||||
link->SetIconLocation(icon, 0);
|
||||
|
||||
delete[] icon;
|
||||
free(icon);
|
||||
}
|
||||
|
||||
// The link's display name must be set via property store.
|
||||
|
@ -321,8 +321,8 @@ void Win32TaskbarManager::addRecent(const Common::String &name, const Common::St
|
|||
// SHAddToRecentDocs will cause the games to be added to the Recent list, allowing the user to pin them.
|
||||
SHAddToRecentDocs(SHARD_LINK, link);
|
||||
link->Release();
|
||||
delete[] game;
|
||||
delete[] desc;
|
||||
free(game);
|
||||
free(desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ void SpeechDispatcherManager::updateState(SpeechDispatcherManager::SpeechEvent e
|
|||
}
|
||||
}
|
||||
|
||||
bool SpeechDispatcherManager::say(Common::String str, Action action, Common::String charset) {
|
||||
bool SpeechDispatcherManager::say(const Common::U32String &str, Action action) {
|
||||
|
||||
pthread_mutex_lock(&_speechMutex);
|
||||
// reinitialize if needed
|
||||
|
@ -194,22 +194,7 @@ bool SpeechDispatcherManager::say(Common::String str, Action action, Common::Str
|
|||
return true;
|
||||
}
|
||||
|
||||
if (charset.empty()) {
|
||||
#ifdef USE_TRANSLATION
|
||||
charset = TransMan.getCurrentCharset();
|
||||
#else
|
||||
charset = "ASCII";
|
||||
#endif
|
||||
}
|
||||
|
||||
char *tmpStr = Common::Encoding::convert("UTF-8", charset, str.c_str(), str.size());
|
||||
if (tmpStr == nullptr) {
|
||||
warning("Cannot convert from %s encoding for text to speech", charset.c_str());
|
||||
pthread_mutex_unlock(&_speechMutex);
|
||||
return true;
|
||||
}
|
||||
Common::String strUtf8 = tmpStr;
|
||||
free(tmpStr);
|
||||
Common::String strUtf8 = str.encode();
|
||||
|
||||
if (!_speechQueue.empty() && action == INTERRUPT_NO_REPEAT &&
|
||||
_speechQueue.front() == strUtf8 && isSpeaking()) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "common/text-to-speech.h"
|
||||
#include "common/str.h"
|
||||
#include "common/ustr.h"
|
||||
#include "common/list.h"
|
||||
#include "common/mutex.h"
|
||||
|
||||
|
@ -59,7 +60,7 @@ public:
|
|||
SpeechDispatcherManager();
|
||||
virtual ~SpeechDispatcherManager() override;
|
||||
|
||||
virtual bool say(Common::String str, Action action, Common::String charset = "") override;
|
||||
virtual bool say(const Common::U32String &str, Action action) override;
|
||||
|
||||
virtual bool stop() override;
|
||||
virtual bool pause() override;
|
||||
|
|
|
@ -29,13 +29,14 @@
|
|||
|
||||
#include "common/text-to-speech.h"
|
||||
#include "common/queue.h"
|
||||
#include "common/ustr.h"
|
||||
|
||||
class MacOSXTextToSpeechManager : public Common::TextToSpeechManager {
|
||||
public:
|
||||
MacOSXTextToSpeechManager();
|
||||
virtual ~MacOSXTextToSpeechManager() override;
|
||||
|
||||
virtual bool say(Common::String str, Action action, Common::String charset = "") override;
|
||||
virtual bool say(const Common::U32String &str, Action action) override;
|
||||
|
||||
virtual bool stop() override;
|
||||
virtual bool pause() override;
|
||||
|
@ -64,12 +65,7 @@ public:
|
|||
private:
|
||||
virtual void updateVoices() override;
|
||||
|
||||
struct SpeechText {
|
||||
Common::String text;
|
||||
Common::String encoding;
|
||||
SpeechText(const Common::String& txt, const Common::String& enc) : text(txt), encoding(enc) {}
|
||||
};
|
||||
Common::Queue<SpeechText> _messageQueue;
|
||||
Common::Queue<Common::String> _messageQueue;
|
||||
Common::String _currentSpeech;
|
||||
bool _paused;
|
||||
};
|
||||
|
|
|
@ -81,7 +81,8 @@ MacOSXTextToSpeechManager::~MacOSXTextToSpeechManager() {
|
|||
[synthesizerDelegate release];
|
||||
}
|
||||
|
||||
bool MacOSXTextToSpeechManager::say(Common::String text, Action action, Common::String encoding) {
|
||||
bool MacOSXTextToSpeechManager::say(const Common::U32String &text, Action action) {
|
||||
Common::String textToSpeak = text.encode();
|
||||
if (isSpeaking()) {
|
||||
// Interruptions are done on word boundaries for nice transitions.
|
||||
// Should we interrupt immediately?
|
||||
|
@ -94,25 +95,19 @@ bool MacOSXTextToSpeechManager::say(Common::String text, Action action, Common::
|
|||
// If the new speech is the one being currently said, continue that speech but clear the queue.
|
||||
// And otherwise both clear the queue and interrupt the current speech.
|
||||
_messageQueue.clear();
|
||||
if (_currentSpeech == text)
|
||||
if (_currentSpeech == textToSpeak)
|
||||
return true;
|
||||
[synthesizer stopSpeakingAtBoundary:NSSpeechWordBoundary];
|
||||
} else if (action == QUEUE_NO_REPEAT) {
|
||||
if (!_messageQueue.empty()) {
|
||||
if (_messageQueue.back().text == text)
|
||||
if (_messageQueue.back() == textToSpeak)
|
||||
return true;
|
||||
} else if (_currentSpeech == text)
|
||||
} else if (_currentSpeech == textToSpeak)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (encoding.empty()) {
|
||||
#ifdef USE_TRANSLATION
|
||||
encoding = TransMan.getCurrentCharset();
|
||||
#endif
|
||||
}
|
||||
|
||||
_messageQueue.push(SpeechText(text, encoding));
|
||||
_messageQueue.push(textToSpeak);
|
||||
if (!isSpeaking())
|
||||
startNextSpeech();
|
||||
return true;
|
||||
|
@ -122,20 +117,17 @@ bool MacOSXTextToSpeechManager::startNextSpeech() {
|
|||
_currentSpeech.clear();
|
||||
if (_messageQueue.empty())
|
||||
return false;
|
||||
SpeechText text = _messageQueue.pop();
|
||||
// Get current encoding
|
||||
CFStringEncoding stringEncoding = kCFStringEncodingASCII;
|
||||
if (!text.encoding.empty()) {
|
||||
CFStringRef encStr = CFStringCreateWithCString(NULL, text.encoding.c_str(), kCFStringEncodingASCII);
|
||||
stringEncoding = CFStringConvertIANACharSetNameToEncoding(encStr);
|
||||
CFRelease(encStr);
|
||||
}
|
||||
|
||||
CFStringRef textNSString = CFStringCreateWithCString(NULL, text.text.c_str(), stringEncoding);
|
||||
Common::String textToSpeak = _messageQueue.pop();
|
||||
|
||||
// Get current encoding
|
||||
CFStringEncoding stringEncoding = kCFStringEncodingUTF8;
|
||||
|
||||
CFStringRef textNSString = CFStringCreateWithCString(NULL, textToSpeak.c_str(), stringEncoding);
|
||||
bool status = [synthesizer startSpeakingString:(NSString *)textNSString];
|
||||
CFRelease(textNSString);
|
||||
if (status)
|
||||
_currentSpeech = text.text;
|
||||
_currentSpeech = textToSpeak;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ DWORD WINAPI startSpeech(LPVOID parameters) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool WindowsTextToSpeechManager::say(Common::String str, Action action, Common::String charset) {
|
||||
bool WindowsTextToSpeechManager::say(const Common::U32String &str, Action action) {
|
||||
if (_speechState == BROKEN || _speechState == NO_VOICE) {
|
||||
warning("The text to speech cannot speak in this state");
|
||||
return true;
|
||||
|
@ -183,18 +183,13 @@ bool WindowsTextToSpeechManager::say(Common::String str, Action action, Common::
|
|||
if (isSpeaking() && action == DROP)
|
||||
return true;
|
||||
|
||||
if (charset.empty()) {
|
||||
#ifdef USE_TRANSLATION
|
||||
charset = TransMan.getCurrentCharset();
|
||||
#else
|
||||
charset = "ASCII";
|
||||
#endif
|
||||
}
|
||||
Common::String strToSpeak = str.encode();
|
||||
Common::String charset = "UTF-8";
|
||||
|
||||
// We have to set the pitch by prepending xml code at the start of the said string;
|
||||
Common::String pitch= Common::String::format("<pitch absmiddle=\"%d\">", _ttsState->_pitch / 10);
|
||||
str.replace((uint32)0, 0, pitch);
|
||||
WCHAR *strW = (WCHAR *) Common::Encoding::convert("UTF-16", charset, str.c_str(), str.size());
|
||||
Common::String pitch = Common::String::format("<pitch absmiddle=\"%d\">", _ttsState->_pitch / 10);
|
||||
strToSpeak.replace((uint32)0, 0, pitch);
|
||||
WCHAR *strW = (WCHAR *) Common::Encoding::convert("UTF-16", charset, strToSpeak.c_str(), strToSpeak.size());
|
||||
if (strW == nullptr) {
|
||||
warning("Cannot convert from %s encoding for text to speech", charset.c_str());
|
||||
return true;
|
||||
|
@ -362,7 +357,7 @@ void WindowsTextToSpeechManager::createVoice(void *cpVoiceToken) {
|
|||
if (SUCCEEDED(hr)) {
|
||||
buffer = Win32::unicodeToAnsi(descW);
|
||||
desc = buffer;
|
||||
delete[] buffer;
|
||||
free(buffer);
|
||||
CoTaskMemFree(descW);
|
||||
}
|
||||
|
||||
|
@ -389,9 +384,7 @@ void WindowsTextToSpeechManager::createVoice(void *cpVoiceToken) {
|
|||
warning("Could not get the language attribute for voice: %s", desc.c_str());
|
||||
return;
|
||||
}
|
||||
buffer = Win32::unicodeToAnsi(data);
|
||||
Common::String language = lcidToLocale(buffer);
|
||||
delete[] buffer;
|
||||
Common::String language = lcidToLocale(data);
|
||||
CoTaskMemFree(data);
|
||||
|
||||
// only get the voices for the current language
|
||||
|
@ -407,9 +400,7 @@ void WindowsTextToSpeechManager::createVoice(void *cpVoiceToken) {
|
|||
warning("Could not get the gender attribute for voice: %s", desc.c_str());
|
||||
return;
|
||||
}
|
||||
buffer = Win32::unicodeToAnsi(data);
|
||||
Common::TTSVoice::Gender gender = !strcmp(buffer, "Male") ? Common::TTSVoice::MALE : Common::TTSVoice::FEMALE;
|
||||
delete[] buffer;
|
||||
Common::TTSVoice::Gender gender = !wcscmp(data, L"Male") ? Common::TTSVoice::MALE : Common::TTSVoice::FEMALE;
|
||||
CoTaskMemFree(data);
|
||||
|
||||
// age
|
||||
|
@ -419,35 +410,31 @@ void WindowsTextToSpeechManager::createVoice(void *cpVoiceToken) {
|
|||
warning("Could not get the age attribute for voice: %s", desc.c_str());
|
||||
return;
|
||||
}
|
||||
buffer = Win32::unicodeToAnsi(data);
|
||||
Common::TTSVoice::Age age = !strcmp(buffer, "Adult") ? Common::TTSVoice::ADULT : Common::TTSVoice::UNKNOWN_AGE;
|
||||
delete[] buffer;
|
||||
Common::TTSVoice::Age age = !wcscmp(data, L"Adult") ? Common::TTSVoice::ADULT : Common::TTSVoice::UNKNOWN_AGE;
|
||||
CoTaskMemFree(data);
|
||||
|
||||
_ttsState->_availableVoices.push_back(Common::TTSVoice(gender, age, (void *) voiceToken, desc));
|
||||
}
|
||||
|
||||
int strToInt(Common::String str) {
|
||||
str.toUppercase();
|
||||
int strToInt(WCHAR *str) {
|
||||
int result = 0;
|
||||
for (unsigned i = 0; i < str.size(); i++) {
|
||||
if (str[i] < '0' || (str[i] > '9' && str[i] < 'A') || str[i] > 'F')
|
||||
for (unsigned i = 0; i < wcslen(str); i++) {
|
||||
WCHAR c = towupper(str[i]);
|
||||
if (c < L'0' || (c > L'9' && c < L'A') || c > L'F')
|
||||
break;
|
||||
int num = (str[i] <= '9') ? str[i] - '0' : str[i] - 55;
|
||||
int num = (c <= L'9') ? c - L'0' : c - 55;
|
||||
result = result * 16 + num;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Common::String WindowsTextToSpeechManager::lcidToLocale(Common::String lcid) {
|
||||
Common::String WindowsTextToSpeechManager::lcidToLocale(WCHAR *lcid) {
|
||||
LCID locale = strToInt(lcid);
|
||||
int nchars = GetLocaleInfoW(locale, LOCALE_SISO639LANGNAME, NULL, 0);
|
||||
wchar_t *languageCode = new wchar_t[nchars];
|
||||
GetLocaleInfoW(locale, LOCALE_SISO639LANGNAME, languageCode, nchars);
|
||||
char *resultTmp = Win32::unicodeToAnsi(languageCode);
|
||||
Common::String result = resultTmp;
|
||||
int nchars = GetLocaleInfoA(locale, LOCALE_SISO639LANGNAME, NULL, 0);
|
||||
char *languageCode = new char[nchars];
|
||||
GetLocaleInfoA(locale, LOCALE_SISO639LANGNAME, languageCode, nchars);
|
||||
Common::String result = languageCode;
|
||||
delete[] languageCode;
|
||||
free(resultTmp);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "common/text-to-speech.h"
|
||||
#include "common/str.h"
|
||||
#include "common/ustr.h"
|
||||
#include "common/list.h"
|
||||
|
||||
|
||||
|
@ -51,7 +52,7 @@ public:
|
|||
WindowsTextToSpeechManager();
|
||||
virtual ~WindowsTextToSpeechManager() override;
|
||||
|
||||
virtual bool say(Common::String str, Action action, Common::String charset = "") override;
|
||||
virtual bool say(const Common::U32String &str, Action action) override;
|
||||
|
||||
virtual bool stop() override;
|
||||
virtual bool pause() override;
|
||||
|
@ -77,7 +78,7 @@ private:
|
|||
void init();
|
||||
virtual void updateVoices() override;
|
||||
void createVoice(void *cpVoiceToken);
|
||||
Common::String lcidToLocale(Common::String lcid);
|
||||
Common::String lcidToLocale(WCHAR *lcid);
|
||||
SpeechState _speechState;
|
||||
Common::String _lastSaid;
|
||||
HANDLE _thread;
|
||||
|
|
|
@ -29,11 +29,10 @@
|
|||
|
||||
#include "common/textconsole.h"
|
||||
|
||||
static volatile bool timerInstalled = false;
|
||||
OSystem::MutexRef timerMutex;
|
||||
|
||||
static Uint32 timer_handler(Uint32 interval, void *param) {
|
||||
if (!timerInstalled)
|
||||
return interval;
|
||||
Common::StackLock lock(timerMutex);
|
||||
|
||||
((DefaultTimerManager *)param)->handler();
|
||||
return interval;
|
||||
|
@ -45,16 +44,17 @@ SdlTimerManager::SdlTimerManager() {
|
|||
error("Could not initialize SDL: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
timerInstalled = true;
|
||||
|
||||
// Creates the timer callback
|
||||
_timerID = SDL_AddTimer(10, &timer_handler, this);
|
||||
}
|
||||
|
||||
SdlTimerManager::~SdlTimerManager() {
|
||||
timerInstalled = false;
|
||||
Common::StackLock lock(timerMutex);
|
||||
|
||||
// Removes the timer callback
|
||||
SDL_RemoveTimer(_timerID);
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_TIMER);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -70,13 +70,8 @@ MacOSXUpdateManager::MacOSXUpdateManager() {
|
|||
// Set appcast URL
|
||||
[sparkleUpdater setFeedURL:[NSURL URLWithString:feedbackURL]];
|
||||
|
||||
// Get current encoding
|
||||
CFStringRef encStr = CFStringCreateWithCString(NULL, TransMan.getCurrentCharset().c_str(), kCFStringEncodingASCII);
|
||||
CFStringEncoding stringEncoding = CFStringConvertIANACharSetNameToEncoding(encStr);
|
||||
CFRelease(encStr);
|
||||
|
||||
// Add "Check for Updates..." menu item
|
||||
CFStringRef title = CFStringCreateWithCString(NULL, _("Check for Updates..."), stringEncoding);
|
||||
CFStringRef title = CFStringCreateWithCString(NULL, _("Check for Updates...").encode().c_str(), kCFStringEncodingUTF8);
|
||||
NSMenuItem *updateMenuItem = [applicationMenu insertItemWithTitle:(NSString *)title action:@selector(checkForUpdates:) keyEquivalent:@"" atIndex:1];
|
||||
CFRelease(title);
|
||||
|
||||
|
|
|
@ -248,7 +248,6 @@ void registerDefaults() {
|
|||
// Graphics
|
||||
ConfMan.registerDefault("fullscreen", false);
|
||||
ConfMan.registerDefault("filtering", false);
|
||||
ConfMan.registerDefault("show_fps", false);
|
||||
ConfMan.registerDefault("aspect_ratio", false);
|
||||
/* ResidualVM - not used
|
||||
ConfMan.registerDefault("gfx_mode", "normal");
|
||||
|
@ -993,7 +992,7 @@ static Common::Error listSaves(const Common::String &singleTarget) {
|
|||
" ---- ------------------------------------------------------\n");
|
||||
|
||||
for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) {
|
||||
printf(" %-4d %s\n", x->getSaveSlot(), x->getDescription().c_str());
|
||||
printf(" %-4d %s\n", x->getSaveSlot(), x->getDescription().encode().c_str());
|
||||
// TODO: Could also iterate over the full hashmap, printing all key-value pairs
|
||||
}
|
||||
atLeastOneFound = true;
|
||||
|
@ -1056,8 +1055,8 @@ static DetectedGames getGameList(const Common::FSNode &dir) {
|
|||
DetectionResults detectionResults = EngineMan.detectGames(files);
|
||||
|
||||
if (detectionResults.foundUnknownGames()) {
|
||||
Common::String report = detectionResults.generateUnknownGameReport(false, 80);
|
||||
g_system->logMessage(LogMessageType::kInfo, report.c_str());
|
||||
Common::U32String report = detectionResults.generateUnknownGameReport(false, 80);
|
||||
g_system->logMessage(LogMessageType::kInfo, report.encode().c_str());
|
||||
}
|
||||
|
||||
return detectionResults.listRecognizedGames();
|
||||
|
|
|
@ -261,7 +261,7 @@ static Common::Error runGame(const Plugin *plugin, OSystem &system, const Common
|
|||
if (token.equalsIgnoreCase("all"))
|
||||
DebugMan.enableAllDebugChannels();
|
||||
else if (!DebugMan.enableDebugChannel(token))
|
||||
warning(_("Engine does not support debug level '%s'"), token.c_str());
|
||||
warning("Engine does not support debug level '%s'", token.c_str());
|
||||
}
|
||||
|
||||
#ifdef USE_TRANSLATION
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include "base/plugins.h"
|
||||
|
||||
#include "common/translation.h"
|
||||
#include "common/func.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/config-manager.h"
|
||||
|
@ -362,7 +361,7 @@ void PluginManagerUncached::loadFirstPlugin() {
|
|||
bool PluginManagerUncached::loadNextPlugin() {
|
||||
unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false);
|
||||
|
||||
if (!_currentPlugin)
|
||||
if (!_currentPlugin || _currentPlugin == _allEnginePlugins.end())
|
||||
return false;
|
||||
|
||||
for (++_currentPlugin; _currentPlugin != _allEnginePlugins.end(); ++_currentPlugin) {
|
||||
|
|
|
@ -52,6 +52,11 @@
|
|||
#include "common/hash-str.h"
|
||||
#include "common/rect.h"
|
||||
|
||||
#ifndef DONT_TEST_UNICODE_STRING_LITERAL
|
||||
const char16_t *u16str = u"\u00DAnicode string";
|
||||
const char32_t *u32str = U"\u00DAnicode string";
|
||||
#endif
|
||||
|
||||
#ifndef DONT_TEST_INITIALIZIER_LIST1
|
||||
#ifndef USE_INITIALIZIER_LIST_REPLACEMENT
|
||||
#include <initializer_list>
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
* to properly work in exports (i.e. release tar balls etc.).
|
||||
*/
|
||||
const char *gScummVMVersion = SCUMMVM_VERSION SCUMMVM_REVISION;
|
||||
#ifdef __amigaos4__
|
||||
#if defined(__amigaos4__) || defined(__MORPHOS__)
|
||||
static const char *version_cookie __attribute__((used)) = "$VER: ResidualVM " SCUMMVM_VERSION SCUMMVM_REVISION " (" AMIGA_DATE ")";
|
||||
#endif
|
||||
const char *gScummVMBuildDate = __DATE__ " " __TIME__;
|
||||
|
|
|
@ -88,9 +88,12 @@ bool AchievementsManager::setAchievement(const String &id, const String &display
|
|||
_iniFile->saveToSaveFile(_iniFileName);
|
||||
|
||||
if (!displayedMessage.empty() && g_system) {
|
||||
String msg;
|
||||
msg = Common::String::format("%s\n%s", _("Achievement unlocked!"), displayedMessage.c_str());
|
||||
g_system->displayMessageOnOSD(msg.c_str());
|
||||
U32String msg;
|
||||
msg = Common::U32String::format(Common::U32String("%S\n%S"),
|
||||
_("Achievement unlocked!").c_str(),
|
||||
Common::U32String(displayedMessage).c_str()
|
||||
);
|
||||
g_system->displayMessageOnOSD(msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -392,13 +392,14 @@ protected:
|
|||
/**
|
||||
* Double linked list with sorted nodes.
|
||||
*/
|
||||
template<class T>
|
||||
template<class T, typename CompareArgType = const void *>
|
||||
class SortedArray : public Array<T> {
|
||||
public:
|
||||
typedef int (*Comparator)(CompareArgType, CompareArgType);
|
||||
typedef T *iterator;
|
||||
typedef uint size_type;
|
||||
|
||||
SortedArray(int (*comparator)(const void *, const void *)) {
|
||||
SortedArray(Comparator comparator) {
|
||||
_comparator = comparator;
|
||||
}
|
||||
|
||||
|
@ -435,7 +436,7 @@ private:
|
|||
// Based on code Copyright (C) 2008-2009 Ksplice, Inc.
|
||||
// Author: Tim Abbott <tabbott@ksplice.com>
|
||||
// Licensed under GPLv2+
|
||||
T *bsearchMin(void *key) {
|
||||
T *bsearchMin(CompareArgType key) {
|
||||
uint start_ = 0, end_ = this->_size;
|
||||
int result;
|
||||
|
||||
|
@ -445,16 +446,14 @@ private:
|
|||
result = this->_comparator(key, this->_storage[mid]);
|
||||
if (result < 0)
|
||||
end_ = mid;
|
||||
else if (result > 0)
|
||||
start_ = mid + 1;
|
||||
else
|
||||
return &this->_storage[mid];
|
||||
start_ = mid + 1;
|
||||
}
|
||||
|
||||
return &this->_storage[start_];
|
||||
}
|
||||
|
||||
int (*_comparator)(const void *, const void *);
|
||||
Comparator _comparator;
|
||||
};
|
||||
|
||||
} // End of namespace Common
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
* @param isDirBrowser Restrict selection to directories
|
||||
* @return The dialog result
|
||||
*/
|
||||
virtual DialogResult showFileBrowser(const char *title, FSNode &choice, bool isDirBrowser = false) { return kDialogError; }
|
||||
virtual DialogResult showFileBrowser(const Common::U32String &title, FSNode &choice, bool isDirBrowser = false) { return kDialogError; }
|
||||
|
||||
protected:
|
||||
bool _wasFullscreen;
|
||||
|
|
|
@ -180,10 +180,6 @@ char *Encoding::conversion(const String &to, const String &from, const char *str
|
|||
result = g_system->convertEncoding(addUtfEndianness(to).c_str(),
|
||||
addUtfEndianness(from).c_str(), string, length);
|
||||
|
||||
if (result == nullptr) {
|
||||
result = convertTransManMapping(addUtfEndianness(to).c_str(), addUtfEndianness(from).c_str(), string, length);
|
||||
}
|
||||
|
||||
if (result == nullptr) {
|
||||
result = convertConversionTable(addUtfEndianness(to).c_str(), addUtfEndianness(from).c_str(), string, length);
|
||||
}
|
||||
|
@ -239,7 +235,7 @@ char *Encoding::convertIconv(const char *to, const char *from, const char *strin
|
|||
}
|
||||
dst = buffer + (dst - oldString);
|
||||
outSize = stringSize - (dst - buffer);
|
||||
memset(dst, 0, stringSize / 2);
|
||||
memset(dst, 0, outSize);
|
||||
} else {
|
||||
error = true;
|
||||
break;
|
||||
|
@ -277,81 +273,6 @@ char *Encoding::convertIconv(const char *to, const char *from, const char *strin
|
|||
#endif //USE_ICONV
|
||||
}
|
||||
|
||||
// This algorithm is able to convert only between the current TransMan charset
|
||||
// and UTF-32, but if it fails, it tries to at least convert from the current
|
||||
// TransMan encoding to UTF-32 and then it calls convert() again with that.
|
||||
char *Encoding::convertTransManMapping(const char *to, const char *from, const char *string, size_t length) {
|
||||
#ifdef USE_TRANSLATION
|
||||
String currentCharset = TransMan.getCurrentCharset();
|
||||
if (currentCharset.equalsIgnoreCase(from)) {
|
||||
// We can use the transMan mapping directly
|
||||
uint32 *partialResult = (uint32 *)calloc(sizeof(uint32), (length + 1));
|
||||
if (!partialResult) {
|
||||
warning("Couldn't allocate memory for encoding conversion");
|
||||
return nullptr;
|
||||
}
|
||||
const uint32 *mapping = TransMan.getCharsetMapping();
|
||||
if (mapping == 0) {
|
||||
for(unsigned i = 0; i < length; i++) {
|
||||
partialResult[i] = string[i];
|
||||
}
|
||||
} else {
|
||||
for(unsigned i = 0; i < length; i++) {
|
||||
partialResult[i] = mapping[(unsigned char)string[i]] & 0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
char *finalResult = convert(to, "UTF-32", (char *)partialResult, length * 4);
|
||||
free(partialResult);
|
||||
return finalResult;
|
||||
} else if (currentCharset.equalsIgnoreCase(to) && String(from).hasPrefixIgnoreCase("utf-32")) {
|
||||
bool swapEndian = false;
|
||||
char *newString = nullptr;
|
||||
|
||||
#ifdef SCUMM_BIG_ENDIAN
|
||||
if (String(from).hasSuffixIgnoreCase("LE"))
|
||||
swapEndian = true;
|
||||
#else
|
||||
if (String(from).hasSuffixIgnoreCase("BE"))
|
||||
swapEndian = true;
|
||||
#endif
|
||||
if (swapEndian) {
|
||||
if (String(from).hasPrefixIgnoreCase("utf-16"))
|
||||
newString = switchEndian(string, length, 16);
|
||||
if (String(from).hasPrefixIgnoreCase("utf-32"))
|
||||
newString = switchEndian(string, length, 32);
|
||||
if (newString != nullptr)
|
||||
string = newString;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
// We can do reverse mapping
|
||||
const uint32 *mapping = TransMan.getCharsetMapping();
|
||||
const uint32 *src = (const uint32 *)string;
|
||||
char *result = (char *)calloc(sizeof(char), (length + 4));
|
||||
if (!result) {
|
||||
warning("Couldn't allocate memory for encoding conversion");
|
||||
if (newString != nullptr)
|
||||
free(newString);
|
||||
return nullptr;
|
||||
}
|
||||
for (unsigned i = 0; i < length; i++) {
|
||||
for (int j = 0; j < 256; j++) {
|
||||
if ((mapping[j] & 0x7FFFFFFF) == src[i]) {
|
||||
result[i] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newString != nullptr)
|
||||
free(newString);
|
||||
return result;
|
||||
} else
|
||||
return nullptr;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif // USE_TRANSLATION
|
||||
}
|
||||
|
||||
static uint32 g_cp850ConversionTable[] = {
|
||||
0x0000, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
|
||||
0x25d8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
|
||||
|
|
|
@ -172,22 +172,6 @@ class Encoding {
|
|||
*/
|
||||
static char *convertIconv(const char *to, const char *from, const char *string, size_t length);
|
||||
|
||||
/**
|
||||
* Tries to use the TransMan to convert the string. It can convert only
|
||||
* between UTF-32 and the current GUI charset. It also tries to convert
|
||||
* from the current GUI charset to UTF-32 and then it calls convert() again.
|
||||
*
|
||||
* The result has to be freed after use.
|
||||
*
|
||||
* @param to Name of the encoding the strings will be converted to
|
||||
* @param from Name of the encoding the strings will be converted from
|
||||
* @param string String that should be converted.
|
||||
* @param length Length of the string to convert in bytes.
|
||||
*
|
||||
* @return Converted string (must be freed) or nullptr if the conversion failed
|
||||
*/
|
||||
static char *convertTransManMapping(const char *to, const char *from, const char *string, size_t length);
|
||||
|
||||
/**
|
||||
* Uses conversion table to convert the string to unicode and from that
|
||||
* to the final encoding. Important encodings, that aren't supported by
|
||||
|
|
|
@ -72,6 +72,7 @@ bool INIFile::loadFromStream(SeekableReadStream &stream) {
|
|||
KeyValue kv;
|
||||
String comment;
|
||||
int lineno = 0;
|
||||
section.name = _defaultSectionName;
|
||||
|
||||
// TODO: Detect if a section occurs multiple times (or likewise, if
|
||||
// a key occurs multiple times inside one section).
|
||||
|
@ -297,6 +298,9 @@ void INIFile::renameSection(const String &oldName, const String &newName) {
|
|||
// - merge the two sections "oldName" and "newName"
|
||||
}
|
||||
|
||||
void INIFile::setDefaultSectionName(const String &name) {
|
||||
_defaultSectionName = name;
|
||||
}
|
||||
|
||||
bool INIFile::hasKey(const String &key, const String §ion) const {
|
||||
if (!isValidName(key)) {
|
||||
|
|
|
@ -105,6 +105,8 @@ public:
|
|||
void removeSection(const String §ion);
|
||||
void renameSection(const String &oldName, const String &newName);
|
||||
|
||||
void setDefaultSectionName(const String &name); ///< sets initial section name for section-less ini files
|
||||
|
||||
bool hasKey(const String &key, const String §ion) const;
|
||||
bool getKey(const String &key, const String §ion, String &value) const;
|
||||
void setKey(const String &key, const String §ion, const String &value);
|
||||
|
@ -118,6 +120,7 @@ public:
|
|||
void allowNonEnglishCharacters();
|
||||
|
||||
private:
|
||||
String _defaultSectionName;
|
||||
SectionList _sections;
|
||||
bool _allowNonEnglishCharacters;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#if defined(__amigaos4__)
|
||||
#if defined(__amigaos4__) || defined(__MORPHOS__)
|
||||
// KEYCODE_LESS and KEYCODE_GREATER are already defined in AmigaOS, inside
|
||||
// include/include_h/intuition/intuition.h (bug #3121350)
|
||||
#if defined(KEYCODE_LESS) && defined(KEYCODE_GREATER)
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace Common {
|
|||
* Simple memory based 'stream', which implements the ReadStream interface for
|
||||
* a plain memory block.
|
||||
*/
|
||||
class MemoryReadStream : public SeekableReadStream {
|
||||
class MemoryReadStream : virtual public SeekableReadStream {
|
||||
private:
|
||||
const byte * const _ptrOrig;
|
||||
const byte *_ptr;
|
||||
|
@ -80,8 +80,8 @@ public:
|
|||
*/
|
||||
class MemoryReadStreamEndian : public MemoryReadStream, public SeekableReadStreamEndian {
|
||||
public:
|
||||
MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian)
|
||||
: MemoryReadStream(buf, len), SeekableReadStreamEndian(bigEndian), ReadStreamEndian(bigEndian) {}
|
||||
MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian, DisposeAfterUse::Flag disposeMemory = DisposeAfterUse::NO)
|
||||
: MemoryReadStream(buf, len, disposeMemory), SeekableReadStreamEndian(bigEndian), ReadStreamEndian(bigEndian) {}
|
||||
|
||||
int32 pos() const { return MemoryReadStream::pos(); }
|
||||
int32 size() const { return MemoryReadStream::size(); }
|
||||
|
|
|
@ -47,7 +47,7 @@ void Mutex::unlock() {
|
|||
#pragma mark -
|
||||
|
||||
|
||||
StackLock::StackLock(MutexRef mutex, const char *mutexName)
|
||||
StackLock::StackLock(OSystem::MutexRef mutex, const char *mutexName)
|
||||
: _mutex(mutex), _mutexName(mutexName) {
|
||||
lock();
|
||||
}
|
||||
|
|
|
@ -30,23 +30,17 @@ namespace Common {
|
|||
|
||||
class Mutex;
|
||||
|
||||
/**
|
||||
* An pseudo-opaque mutex type. See OSystem::createMutex etc. for more details.
|
||||
*/
|
||||
typedef OSystem::MutexRef MutexRef;
|
||||
|
||||
|
||||
/**
|
||||
* Auxillary class to (un)lock a mutex on the stack.
|
||||
*/
|
||||
class StackLock {
|
||||
MutexRef _mutex;
|
||||
OSystem::MutexRef _mutex;
|
||||
const char *_mutexName;
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
public:
|
||||
explicit StackLock(MutexRef mutex, const char *mutexName = nullptr);
|
||||
explicit StackLock(OSystem::MutexRef mutex, const char *mutexName = nullptr);
|
||||
explicit StackLock(const Mutex &mutex, const char *mutexName = nullptr);
|
||||
~StackLock();
|
||||
};
|
||||
|
@ -58,7 +52,7 @@ public:
|
|||
class Mutex {
|
||||
friend class StackLock;
|
||||
|
||||
MutexRef _mutex;
|
||||
OSystem::MutexRef _mutex;
|
||||
|
||||
public:
|
||||
Mutex();
|
||||
|
|
|
@ -38,7 +38,7 @@ void OSDMessageQueue::registerEventSource() {
|
|||
g_system->getEventManager()->getEventDispatcher()->registerSource(this, false);
|
||||
}
|
||||
|
||||
void OSDMessageQueue::addMessage(const char *msg) {
|
||||
void OSDMessageQueue::addMessage(const Common::U32String &msg) {
|
||||
_mutex.lock();
|
||||
_messages.push(msg);
|
||||
_mutex.unlock();
|
||||
|
@ -50,8 +50,8 @@ bool OSDMessageQueue::pollEvent(Common::Event &event) {
|
|||
uint t = g_system->getMillis();
|
||||
if (t - _lastUpdate >= kMinimumDelay) {
|
||||
_lastUpdate = t;
|
||||
String msg = _messages.pop();
|
||||
g_system->displayMessageOnOSD(msg.c_str());
|
||||
Common::U32String msg = _messages.pop();
|
||||
g_system->displayMessageOnOSD(msg);
|
||||
}
|
||||
}
|
||||
_mutex.unlock();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "common/events.h"
|
||||
#include "common/singleton.h"
|
||||
#include "common/str.h"
|
||||
#include "common/ustr.h"
|
||||
#include "common/queue.h"
|
||||
#include "common/mutex.h"
|
||||
|
||||
|
@ -48,7 +49,7 @@ public:
|
|||
/**
|
||||
* Add a message to the OSD message queue.
|
||||
*/
|
||||
void addMessage(const char *msg);
|
||||
void addMessage(const Common::U32String &msg);
|
||||
|
||||
/**
|
||||
* Common::EventSource interface
|
||||
|
@ -63,7 +64,7 @@ public:
|
|||
|
||||
private:
|
||||
Mutex _mutex;
|
||||
Queue<String> _messages;
|
||||
Queue<U32String> _messages;
|
||||
uint32 _lastUpdate;
|
||||
};
|
||||
|
||||
|
|
|
@ -633,7 +633,11 @@ Graphics::Surface *PlaybackFile::getScreenShot(int number) {
|
|||
|
||||
void PlaybackFile::updateHeader() {
|
||||
if (_mode == kWrite) {
|
||||
StringArray dummy;
|
||||
g_system->getSavefileManager()->updateSavefilesList(dummy);
|
||||
_readStream = g_system->getSavefileManager()->openForLoading(_header.fileName);
|
||||
|
||||
assert (_readStream);
|
||||
}
|
||||
_readStream->seek(0);
|
||||
skipHeader();
|
||||
|
|
|
@ -267,6 +267,34 @@ struct Rect {
|
|||
int x = cx - w / 2, y = cy - h / 2;
|
||||
return Rect(x, y, x + w, y + h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given target surface with size clip, this function ensures that
|
||||
* blit arguments dst, rect are within clip rectangle.
|
||||
* @param dst blit destination coordinates
|
||||
* @param rect blit source rectangle
|
||||
* @param clip clip rectangle (size of destination surface)
|
||||
*/
|
||||
static bool getBlitRect(Point &dst, Rect &rect, const Rect &clip) {
|
||||
if (dst.x < clip.left) {
|
||||
rect.left += clip.left - dst.x;
|
||||
dst.x = clip.left;
|
||||
}
|
||||
|
||||
if (dst.y < clip.top) {
|
||||
rect.top += clip.top - dst.y;
|
||||
dst.y = clip.top;
|
||||
}
|
||||
|
||||
int right = dst.x + rect.right;
|
||||
if (right > clip.right)
|
||||
rect.right -= right - clip.right;
|
||||
|
||||
int bottom = dst.y + rect.bottom;
|
||||
if (bottom > clip.bottom)
|
||||
rect.bottom -= bottom - clip.bottom;
|
||||
return !rect.isEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Common
|
||||
|
|
|
@ -282,7 +282,7 @@
|
|||
|
||||
#define SCUMM_LITTLE_ENDIAN
|
||||
|
||||
#elif defined(__amigaos4__) || defined(__N64__) || defined(__WII__)
|
||||
#elif defined(__MORPHOS__) || defined(__amigaos4__) || defined(__N64__) || defined(__WII__)
|
||||
|
||||
#define SCUMM_BIG_ENDIAN
|
||||
#define SCUMM_NEED_ALIGNMENT
|
||||
|
|
|
@ -433,7 +433,7 @@ public:
|
|||
|
||||
inline MemoryReadStream toStream(const index_type index = 0, size_type numEntries = kSpanMaxSize) const {
|
||||
if (numEntries == kSpanMaxSize) {
|
||||
numEntries = impl().size();
|
||||
numEntries = impl().size() - index;
|
||||
}
|
||||
|
||||
impl().validate(index, numEntries * sizeof(value_type));
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "common/array.h"
|
||||
#include "common/str.h"
|
||||
#include "common/ustr.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
@ -32,6 +33,7 @@ namespace Common {
|
|||
* An array of of strings.
|
||||
*/
|
||||
typedef Array<String> StringArray;
|
||||
typedef Array<U32String> U32StringArray;
|
||||
|
||||
|
||||
} // End of namespace Common
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue