ALL: Sync with ScummVM - rev. ea3f8f2e33

This commit is contained in:
Bastien Bouclet 2019-06-29 19:08:44 +02:00
parent 308c018141
commit d474e3f94f
155 changed files with 11308 additions and 6208 deletions

98
COPYING.OFL Normal file
View file

@ -0,0 +1,98 @@
NOTE: This license file only applies to the Source Code Pro font file:
"SourceCodeVariable-Roman.ttf" distributed along with our theme files.
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/),
with Reserved Font Name 'Source'. All Rights Reserved. Source is a
trademark of Adobe Systems Incorporated in the United States and/or other
countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View file

@ -267,7 +267,7 @@ dist-src: \
@#DEB-src?
# Common files
DIST_FILES_DOCS:=$(addprefix $(srcdir)/,AUTHORS COPYING COPYING.BSD COPYING.LGPL COPYING.FREEFONT COPYING.ISC COPYING.LUA COPYING.MIT COPYING.TINYGL COPYRIGHT KNOWN_BUGS NEWS 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 README.md)
ifdef USE_PANDOC
DIST_FILES_DOCS+=$(PANDOCOUTPUT)
endif

View file

@ -24,6 +24,7 @@
#include "common/ptr.h"
#include "common/stream.h"
#include "common/textconsole.h"
#include "common/util.h"
#include "audio/audiostream.h"
#include "audio/decoders/ac3.h"
@ -37,7 +38,7 @@ namespace Audio {
class AC3Stream : public PacketizedAudioStream {
public:
AC3Stream();
AC3Stream(double decibel);
~AC3Stream();
bool init(Common::SeekableReadStream &firstPacket);
@ -62,9 +63,11 @@ private:
byte *_inBufPtr;
int _flags;
int _sampleRate;
double _audioGain;
};
AC3Stream::AC3Stream() : _a52State(0), _frameSize(0), _inBufPtr(0), _flags(0), _sampleRate(0) {
AC3Stream::AC3Stream(double decibel) : _a52State(0), _frameSize(0), _inBufPtr(0), _flags(0), _sampleRate(0) {
_audioGain = pow(2, decibel / 6);
}
AC3Stream::~AC3Stream() {
@ -153,7 +156,7 @@ void AC3Stream::queuePacket(Common::SeekableReadStream *data) {
} else {
// TODO: Eventually support more than just stereo max
int flags = A52_STEREO | A52_ADJUST_LEVEL;
sample_t level = 32767;
sample_t level = 32767 * _audioGain;
if (a52_frame(_a52State, _inBuf, &flags, &level, 0) != 0)
error("Frame fail");
@ -165,8 +168,8 @@ void AC3Stream::queuePacket(Common::SeekableReadStream *data) {
if (a52_block(_a52State) == 0) {
sample_t *samples = a52_samples(_a52State);
for (int j = 0; j < 256; j++) {
*outputPtr++ = (int16)samples[j];
*outputPtr++ = (int16)samples[j + 256];
*outputPtr++ = (int16)CLIP<sample_t>(samples[j], -32768, 32767);
*outputPtr++ = (int16)CLIP<sample_t>(samples[j + 256], -32768, 32767);
}
outputLength += 1024;
@ -189,8 +192,8 @@ void AC3Stream::queuePacket(Common::SeekableReadStream *data) {
}
}
PacketizedAudioStream *makeAC3Stream(Common::SeekableReadStream &firstPacket) {
Common::ScopedPtr<AC3Stream> stream(new AC3Stream());
PacketizedAudioStream *makeAC3Stream(Common::SeekableReadStream &firstPacket, double decibel) {
Common::ScopedPtr<AC3Stream> stream(new AC3Stream(decibel));
if (!stream->init(firstPacket))
return 0;

View file

@ -41,7 +41,7 @@ class PacketizedAudioStream;
* @param firstPacket The stream containing the first packet of data
* @return A new PacketizedAudioStream, or NULL on error
*/
PacketizedAudioStream *makeAC3Stream(Common::SeekableReadStream &firstPacket);
PacketizedAudioStream *makeAC3Stream(Common::SeekableReadStream &firstPacket, double decibel = 0.0);
} // End of namespace Audio

View file

@ -68,7 +68,7 @@ public:
virtual bool rewind();
virtual bool seek(const Timestamp &where) { return false; }
virtual Timestamp getLength() const { return -1; }
virtual Timestamp getLength() const { return Timestamp(); }
/**
* This table is used by some ADPCM variants (IMA and OKI) to adjust the

View file

@ -27,9 +27,9 @@
namespace Cloud {
const float CloudIcon::ALPHA_SPEED = 0.0005;
const float CloudIcon::ALPHA_MAX = 1;
const float CloudIcon::ALPHA_MIN = 0.6;
const float CloudIcon::ALPHA_SPEED = 0.0005f;
const float CloudIcon::ALPHA_MAX = 1.f;
const float CloudIcon::ALPHA_MIN = 0.6f;
CloudIcon::CloudIcon() {
initIcons();

View file

@ -138,11 +138,11 @@ Common::DialogManager::DialogResult Win32DialogManager::showFileBrowser(const ch
hr = dialog->SetOptions(dwOptions);
}
LPWSTR str = Win32::ansiToUnicode(title);
LPWSTR str = Win32::ansiToUnicode(title, Win32::getCurrentCharset());
hr = dialog->SetTitle(str);
delete[] str;
str = Win32::ansiToUnicode(_("Choose"));
str = Win32::ansiToUnicode(_("Choose"), Win32::getCurrentCharset());
hr = dialog->SetOkButtonLabel(str);
delete[] str;

View file

@ -281,15 +281,32 @@ void DefaultEventManager::purgeMouseEvents() {
while (!_eventQueue.empty()) {
Common::Event event = _eventQueue.pop();
switch (event.type) {
case Common::EVENT_MOUSEMOVE:
// Update button state even when purging events to avoid desynchronisation with real button state
case Common::EVENT_LBUTTONDOWN:
_mousePos = event.mouse;
_buttonState |= LBUTTON;
break;
case Common::EVENT_LBUTTONUP:
_mousePos = event.mouse;
_buttonState &= ~LBUTTON;
break;
case Common::EVENT_RBUTTONDOWN:
_mousePos = event.mouse;
_buttonState |= RBUTTON;
break;
case Common::EVENT_RBUTTONUP:
_mousePos = event.mouse;
_buttonState &= ~RBUTTON;
break;
case Common::EVENT_WHEELUP:
case Common::EVENT_WHEELDOWN:
case Common::EVENT_MBUTTONDOWN:
case Common::EVENT_MBUTTONUP:
case Common::EVENT_MOUSEMOVE:
// do nothing
break;
default:

View 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.
*
*/
#include "common/scummsys.h"
#if defined(RISCOS) && defined(SDL_BACKEND)
#include "backends/events/riscossdl/riscossdl-events.h"
#include "backends/platform/sdl/riscos/riscos-utils.h"
#include "common/events.h"
#include <swis.h>
RISCOSSdlEventSource::RISCOSSdlEventSource()
: SdlEventSource() {
int messages[2];
messages[0] = 3; // Message_DataLoad
messages[1] = 0;
_swix(Wimp_AddMessages, _IN(0), messages);
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
}
bool RISCOSSdlEventSource::handleSysWMEvent(SDL_Event &ev, Common::Event &event) {
int eventCode = ev.syswm.msg->eventCode;
int pollBlock[64];
memcpy(pollBlock, ev.syswm.msg->pollBlock, 64 * sizeof(int));
if (eventCode == 17 || eventCode == 18) {
char *filename;
switch (pollBlock[4]) {
case 3: // Message_DataLoad
filename = (char *)(pollBlock) + 44;
event.type = Common::EVENT_DROP_FILE;
event.path = RISCOS_Utils::toUnix(Common::String(filename));
// Acknowledge that the event has been received
pollBlock[4] = 4; // Message_DataLoadAck
pollBlock[3] = pollBlock[2];
_swix(Wimp_SendMessage, _INR(0,2), 19, pollBlock, 0);
return true;
}
}
return false;
}
#endif

View file

@ -20,20 +20,19 @@
*
*/
#ifndef NETWORKING_CONNECTION_ISLIMITED_H
#define NETWORKING_CONNECTION_ISLIMITED_H
#if !defined(BACKEND_EVENTS_RISCOS_H) && !defined(DISABLE_DEFAULT_EVENTMANAGER)
#define BACKEND_EVENTS_RISCOS_H
namespace Networking {
namespace Connection {
#include "backends/events/sdl/sdl-events.h"
/**
* Returns whether connection's limited (if available on the target system).
*
* Returns true if connection seems limited.
*/
bool isLimited();
* SDL Events manager for RISC OS.
*/
class RISCOSSdlEventSource : public SdlEventSource {
public:
RISCOSSdlEventSource();
protected:
bool handleSysWMEvent(SDL_Event &ev, Common::Event &event) override;
};
} // End of namespace Connection
} // End of namespace Networking
#endif /*NETWORKING_CONNECTION_ISLIMITED_H*/
#endif /* BACKEND_EVENTS_RISCOS_H */

View file

@ -180,8 +180,14 @@ int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) {
if (key >= Common::KEYCODE_F1 && key <= Common::KEYCODE_F9) {
return key - Common::KEYCODE_F1 + Common::ASCII_F1;
} else if (key >= Common::KEYCODE_KP0 && key <= Common::KEYCODE_KP9) {
if ((mod & KMOD_NUM) == 0)
return 0; // In case Num-Lock is NOT enabled, return 0 for ascii, so that directional keys on numpad work
// WORKAROUND: Disable this change for AmigaOS4 as it is breaking numpad usage ("fighting") on that platform.
// This fixes bug #10558.
// The actual issue here is that the SCUMM engine uses ASCII codes instead of keycodes for input.
// See also the relevant FIXME in SCUMM's input.cpp.
#ifndef __amigaos4__
if ((mod & KMOD_NUM) == 0)
return 0; // In case Num-Lock is NOT enabled, return 0 for ascii, so that directional keys on numpad work
#endif
return key - Common::KEYCODE_KP0 + '0';
} else if (key >= Common::KEYCODE_UP && key <= Common::KEYCODE_PAGEDOWN) {
return key;
@ -574,6 +580,8 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
return handleMouseButtonDown(ev, event);
case SDL_MOUSEBUTTONUP:
return handleMouseButtonUp(ev, event);
case SDL_SYSWMEVENT:
return handleSysWMEvent(ev, event);
#if SDL_VERSION_ATLEAST(2, 0, 0)
case SDL_MOUSEWHEEL: {
@ -647,6 +655,12 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
case SDL_JOYDEVICEREMOVED:
return handleJoystickRemoved(ev.jdevice);
case SDL_DROPFILE:
event.type = Common::EVENT_DROP_FILE;
event.path = Common::String(ev.drop.file);
SDL_free(ev.drop.file);
return true;
#else
case SDL_VIDEOEXPOSE:
if (_graphicsManager)
@ -861,6 +875,10 @@ bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
return processMouseEvent(event, ev.button.x, ev.button.y);
}
bool SdlEventSource::handleSysWMEvent(SDL_Event &ev, Common::Event &event) {
return false;
}
void SdlEventSource::openJoystick(int joystickIndex) {
if (SDL_NumJoysticks() > joystickIndex) {
#if SDL_VERSION_ATLEAST(2, 0, 0)

View file

@ -66,7 +66,8 @@ protected:
//@{
struct KbdMouse {
int16 x, y, x_vel, y_vel, x_max, y_max, x_down_count, y_down_count, joy_x, joy_y;
int32 x, y;
int16 x_vel, y_vel, x_max, y_max, x_down_count, y_down_count, joy_x, joy_y;
uint32 last_time, delay_time, x_down_time, y_down_time;
bool modifier;
};
@ -137,6 +138,7 @@ protected:
virtual bool handleMouseMotion(SDL_Event &ev, Common::Event &event);
virtual bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event);
virtual bool handleMouseButtonUp(SDL_Event &ev, Common::Event &event);
virtual bool handleSysWMEvent(SDL_Event &ev, Common::Event &event);
virtual bool handleJoyButtonDown(SDL_Event &ev, Common::Event &event);
virtual bool handleJoyButtonUp(SDL_Event &ev, Common::Event &event);
virtual bool handleJoyAxisMotion(SDL_Event &ev, Common::Event &event);

View file

@ -29,6 +29,8 @@
#define FORBIDDEN_SYMBOL_EXCEPTION_random
#define FORBIDDEN_SYMBOL_EXCEPTION_srandom
#include <unistd.h>
#include "backends/fs/chroot/chroot-fs-factory.h"
#include "backends/fs/chroot/chroot-fs.h"

View file

@ -34,6 +34,8 @@
#include "backends/fs/posix/posix-fs-factory.h"
#include "backends/fs/posix/posix-fs.h"
#include <unistd.h>
AbstractFSNode *POSIXFilesystemFactory::makeRootFileNode() const {
return new POSIXFilesystemNode("/");
}

View file

@ -38,6 +38,9 @@
#include <sys/param.h>
#include <sys/stat.h>
#ifdef MACOSX
#include <sys/types.h>
#endif
#ifdef PSP2
#include "backends/fs/psp2/psp2-dirent.h"
#define mkdir sceIoMkdir
@ -47,6 +50,7 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef __OS2__
#define INCL_DOS
@ -54,6 +58,18 @@
#endif
bool POSIXFilesystemNode::exists() const {
return access(_path.c_str(), F_OK) == 0;
}
bool POSIXFilesystemNode::isReadable() const {
return access(_path.c_str(), R_OK) == 0;
}
bool POSIXFilesystemNode::isWritable() const {
return access(_path.c_str(), W_OK) == 0;
}
void POSIXFilesystemNode::setFlags() {
struct stat st;
@ -247,9 +263,9 @@ AbstractFSNode *POSIXFilesystemNode::getParent() const {
return 0; // The filesystem root has no parent
#ifdef __OS2__
if (_path.size() == 3 && _path.hasSuffix(":/"))
// This is a root directory of a drive
return makeNode("/"); // return a virtual root for a list of drives
if (_path.size() == 3 && _path.hasSuffix(":/"))
// This is a root directory of a drive
return makeNode("/"); // return a virtual root for a list of drives
#endif
#ifdef PSP2
if (_path.hasSuffix(":"))

View file

@ -25,11 +25,6 @@
#include "backends/fs/abstract-fs.h"
#ifdef MACOSX
#include <sys/types.h>
#endif
#include <unistd.h>
/**
* Implementation of the ScummVM file system API based on POSIX.
*
@ -59,13 +54,13 @@ public:
*/
POSIXFilesystemNode(const Common::String &path);
virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; }
virtual bool exists() const;
virtual Common::String getDisplayName() const { return _displayName; }
virtual Common::String getName() const { return _displayName; }
virtual Common::String getPath() const { return _path; }
virtual bool isDirectory() const { return _isDirectory; }
virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; }
virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; }
virtual bool isReadable() const;
virtual bool isWritable() const;
virtual AbstractFSNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;

View file

@ -26,6 +26,7 @@
#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir
#include "backends/platform/sdl/riscos/riscos-utils.h"
#include "backends/fs/riscos/riscos-fs.h"
#include "backends/fs/stdiostream.h"
#include "common/algorithm.h"
@ -57,7 +58,7 @@ RISCOSFilesystemNode::RISCOSFilesystemNode(const Common::String &p) {
_isDirectory = true;
_isValid = true;
} else {
int type = _swi(OS_File, _INR(0,1)|_RETURN(0), 20, toRISCOS(_path).c_str());
int type = _swi(OS_File, _INR(0,1)|_RETURN(0), 20, RISCOS_Utils::toRISCOS(_path).c_str());
if (type == 0) {
_isDirectory = false;
_isValid = false;
@ -71,45 +72,6 @@ RISCOSFilesystemNode::RISCOSFilesystemNode(const Common::String &p) {
}
}
Common::String RISCOSFilesystemNode::toRISCOS(Common::String &path) {
char start[PATH_MAX];
char *end = __riscosify_std(path.c_str(), 0, start, PATH_MAX, 0);
return Common::String(start, end);
}
Common::String RISCOSFilesystemNode::toUnix(Common::String &path) {
Common::String out = Common::String(path);
uint32 start = 0;
if (out.contains("$")) {
char *x = strstr(out.c_str(), "$");
start = x ? x - out.c_str() : -1;
} else if (out.contains(":")) {
char *x = strstr(out.c_str(), ":");
start = x ? x - out.c_str() : -1;
}
for (uint32 ptr = start; ptr < out.size(); ptr += 1) {
switch (out.c_str()[ptr]) {
case '.':
out.setChar('/', ptr);
break;
case '/':
out.setChar('.', ptr);
break;
case '\xA0':
out.setChar(' ', ptr);
break;
default:
break;
}
}
if (out.contains("$") || out.contains(":"))
out = "/" + out;
return out;
}
AbstractFSNode *RISCOSFilesystemNode::getChild(const Common::String &n) const {
assert(!_path.empty());
assert(_isDirectory);
@ -169,7 +131,7 @@ bool RISCOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bo
Common::String dir = _path;
while (count != -1) {
_swix(OS_GBPB, _INR(0,5)|_OUTR(3,4), 9, toRISCOS(dir).c_str(), file, 1, count, sizeof(file), &read, &count);
_swix(OS_GBPB, _INR(0,5)|_OUTR(3,4), 9, RISCOS_Utils::toRISCOS(dir).c_str(), file, 1, count, sizeof(file), &read, &count);
if (count == -1)
continue;
@ -177,12 +139,12 @@ bool RISCOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bo
// Start with a clone of this node, with the correct path set
RISCOSFilesystemNode entry(*this);
entry._displayName = file;
entry._displayName = toUnix(entry._displayName);
entry._displayName = RISCOS_Utils::toUnix(entry._displayName);
if (_path.lastChar() != '/')
entry._path += '/';
entry._path += entry._displayName;
int type = _swi(OS_File, _INR(0,1)|_RETURN(0), 20, toRISCOS(entry._path).c_str());
int type = _swi(OS_File, _INR(0,1)|_RETURN(0), 20, RISCOS_Utils::toRISCOS(entry._path).c_str());
if (type == 0) {
continue;
} else if (type == 2) {
@ -240,7 +202,7 @@ bool RISCOSFilesystemNode::create(bool isDirectoryFlag) {
bool success;
if (isDirectoryFlag) {
success = _swix(OS_File, _INR(0,1), 8, toRISCOS(_path).c_str()) == NULL;
success = _swix(OS_File, _INR(0,1), 8, RISCOS_Utils::toRISCOS(_path).c_str()) == NULL;
} else {
int fd = open(_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0755);
success = fd >= 0;
@ -252,7 +214,7 @@ bool RISCOSFilesystemNode::create(bool isDirectoryFlag) {
if (success) {
if (exists()) {
_isDirectory = _swi(OS_File, _INR(0,1)|_RETURN(0), 20, toRISCOS(_path).c_str()) == 2;
_isDirectory = _swi(OS_File, _INR(0,1)|_RETURN(0), 20, RISCOS_Utils::toRISCOS(_path).c_str()) == 2;
if (_isDirectory != isDirectoryFlag) warning("failed to create %s: got %s", isDirectoryFlag ? "directory" : "file", _isDirectory ? "directory" : "file");
return _isDirectory == isDirectoryFlag;
}

View file

@ -68,24 +68,6 @@ public:
virtual Common::SeekableReadStream *createReadStream();
virtual Common::WriteStream *createWriteStream();
virtual bool create(bool isDirectoryFlag);
private:
/**
* Converts a Unix style path to a RISC OS style path.
*
* @param str Unix style path to convert.
* @return RISC OS style path.
*/
static Common::String toRISCOS(Common::String &path);
/**
* Converts a RISC OS style path to a Unix style path.
*
* @param str RISC OS style path to convert.
* @return Unix style path.
*/
static Common::String toUnix(Common::String &path);
};
namespace Riscos {

View file

@ -26,6 +26,9 @@
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "backends/fs/stdiostream.h"
#ifdef _WIN32_WCE
#include "backends/platform/wince/missing/fopen.h"
#endif
StdioStream::StdioStream(void *handle) : _handle(handle) {
assert(handle);

View file

@ -28,7 +28,7 @@
#include "common/stream.h"
#include "common/str.h"
class StdioStream : public Common::SeekableReadStream, public Common::WriteStream, public Common::NonCopyable {
class StdioStream : public Common::SeekableReadStream, public Common::SeekableWriteStream, public Common::NonCopyable {
protected:
/** File handle to the actual file. */
void *_handle;
@ -43,17 +43,17 @@ public:
StdioStream(void *handle);
virtual ~StdioStream();
virtual bool err() const;
virtual void clearErr();
virtual bool eos() const;
virtual bool err() const override;
virtual void clearErr() override;
virtual bool eos() const override;
virtual uint32 write(const void *dataPtr, uint32 dataSize);
virtual bool flush();
virtual uint32 write(const void *dataPtr, uint32 dataSize) override;
virtual bool flush() override;
virtual int32 pos() const;
virtual int32 size() const;
virtual bool seek(int32 offs, int whence = SEEK_SET);
virtual uint32 read(void *dataPtr, uint32 dataSize);
virtual int32 pos() const override;
virtual int32 size() const override;
virtual bool seek(int32 offs, int whence = SEEK_SET) override;
virtual uint32 read(void *dataPtr, uint32 dataSize) override;
};
#endif

View file

@ -37,8 +37,11 @@
#include "graphics/opengl/system_headers.h"
#include "graphics/opengl/texture.h"
#include "graphics/opengl/tiledsurface.h"
#ifdef USE_PNG
#include "image/png.h"
#else
#include "image/bmp.h"
#endif
OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window, const Capabilities &capabilities)
@ -708,39 +711,17 @@ bool OpenGLSdlGraphicsManager::saveScreenshot(const Common::String &file) const
_frameBuffer->attach();
}
#ifdef USE_PNG
Graphics::PixelFormat format(3, 8, 8, 8, 0, 16, 8, 0, 0);
#ifdef SCUMM_LITTLE_ENDIAN
const Graphics::PixelFormat format(3, 8, 8, 8, 0, 0, 8, 16, 0);
#else
const Graphics::PixelFormat format(3, 8, 8, 8, 0, 16, 8, 0, 0);
#endif
Graphics::Surface data;
data.init(width, height, lineSize, &pixels.front(), format);
#ifdef USE_PNG
return Image::writePNG(out, data, true);
#else
for (uint y = height; y-- > 0;) {
uint8 *line = &pixels.front() + y * lineSize;
for (uint x = width; x > 0; --x, line += 3) {
SWAP(line[0], line[2]);
}
}
out.writeByte('B');
out.writeByte('M');
out.writeUint32LE(height * lineSize + 54);
out.writeUint32LE(0);
out.writeUint32LE(54);
out.writeUint32LE(40);
out.writeUint32LE(width);
out.writeUint32LE(height);
out.writeUint16LE(1);
out.writeUint16LE(24);
out.writeUint32LE(0);
out.writeUint32LE(0);
out.writeUint32LE(0);
out.writeUint32LE(0);
out.writeUint32LE(0);
out.writeUint32LE(0);
out.write(&pixels.front(), pixels.size());
return true;
return Image::writeBMP(out, data, true);
#endif
}

View file

@ -1,6 +1,6 @@
/* ScummVM - Graphic Adventure Engine
/* ResidualVM - A 3D game interpreter
*
* ScummVM is the legal property of its developers, whose names
* ResidualVM 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.
*

View file

@ -507,7 +507,11 @@ bool SurfaceSdlGraphicsManager::saveScreenshot(const Common::String &file) const
success = false;
}
Graphics::PixelFormat format(3, 8, 8, 8, 0, 16, 8, 0, 0);
#ifdef SCUMM_LITTLE_ENDIAN
const Graphics::PixelFormat format(3, 8, 8, 8, 0, 0, 8, 16, 0);
#else
const Graphics::PixelFormat format(3, 8, 8, 8, 0, 16, 8, 0, 0);
#endif
Graphics::Surface data;
data.init(screen->w, screen->h, screen->pitch, screen->pixels, format);
success = Image::writePNG(out, data);

View file

@ -32,7 +32,7 @@
#if defined(GP2X)
#define SAMPLES_PER_SEC 11025
#elif defined(PLAYSTATION3) || defined(PSP2)
#elif defined(PLAYSTATION3) || defined(PSP2) || defined(NINTENDO_SWITCH)
#define SAMPLES_PER_SEC 48000
#else
#define SAMPLES_PER_SEC 44100

View file

@ -78,7 +78,7 @@ public:
virtual Graphics::PixelFormat getScreenFormat() const override;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
#endif
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL);
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) override;
virtual void setupScreen(uint screenW, uint screenH, bool fullscreen, bool accel3d); // ResidualVM specific method
virtual Graphics::PixelBuffer getScreenPixelBuffer(); // ResidualVM specific method
virtual void suggestSideTextures(Graphics::Surface *left, Graphics::Surface *right); // ResidualVM specific method

View file

@ -137,15 +137,6 @@ MODULE_OBJS += \
endif
endif
# Connection::isLimited
ifeq ($(BACKEND),android)
MODULE_OBJS += \
networking/connection/islimited-android.o
else
MODULE_OBJS += \
networking/connection/islimited-default.o
endif
ifdef POSIX
MODULE_OBJS += \
fs/posix/posix-fs.o \
@ -177,6 +168,11 @@ MODULE_OBJS += \
taskbar/win32/win32-taskbar.o
endif
ifeq ($(BACKEND),android)
MODULE_OBJS += \
mutex/pthread/pthread-mutex.o
endif
ifdef AMIGAOS
MODULE_OBJS += \
fs/amigaos4/amigaos4-fs.o \
@ -185,8 +181,10 @@ endif
ifdef RISCOS
MODULE_OBJS += \
events/riscossdl/riscossdl-events.o \
fs/riscos/riscos-fs.o \
fs/riscos/riscos-fs-factory.o
fs/riscos/riscos-fs-factory.o \
platform/sdl/riscos/riscos-utils.o
endif
ifdef PLAYSTATION3
@ -305,6 +303,11 @@ MODULE_OBJS += \
plugins/wii/wii-provider.o
endif
ifeq ($(BACKEND),switch)
MODULE_OBJS += \
events/switchsdl/switchsdl-events.o
endif
ifdef ENABLE_EVENTRECORDER
MODULE_OBJS += \
mixer/nullmixer/nullsdl-mixer.o \

View file

@ -1,36 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "backends/networking/connection/islimited.h"
#include "common/textconsole.h"
namespace Networking {
namespace Connection {
bool isLimited() {
warning("Networking::Connection::isLimited(): not limited by default");
return false;
}
} // End of namespace Connection
} // End of namespace Networking

View file

@ -54,6 +54,7 @@
#include "common/config-manager.h"
#include "backends/keymapper/keymapper.h"
#include "backends/mutex/pthread/pthread-mutex.h"
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
@ -133,9 +134,10 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
_show_mouse(false),
_show_overlay(false),
_enable_zoning(false),
_mutexManager(0),
_mixer(0),
_queuedEventTime(0),
_event_queue_lock(createMutex()),
_event_queue_lock(0),
_touch_pt_down(),
_touch_pt_scroll(),
_touch_pt_dt(),
@ -175,6 +177,9 @@ OSystem_Android::~OSystem_Android() {
_timerManager = 0;
deleteMutex(_event_queue_lock);
delete _mutexManager;
_mutexManager = 0;
}
void *OSystem_Android::timerThreadFunc(void *arg) {
@ -362,8 +367,11 @@ void OSystem_Android::initBackend() {
// screen. Passing the savepath in this way makes it stick
// (via ConfMan.registerDefault)
_savefileManager = new DefaultSaveFileManager(ConfMan.get("savepath"));
_mutexManager = new PthreadMutexManager();
_timerManager = new DefaultTimerManager();
_event_queue_lock = createMutex();
gettimeofday(&_startTime, 0);
_mixer = new Audio::MixerImpl(this, _audio_sample_rate);
@ -469,41 +477,23 @@ void OSystem_Android::delayMillis(uint msecs) {
}
OSystem::MutexRef OSystem_Android::createMutex() {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_t *mutex = new pthread_mutex_t;
if (pthread_mutex_init(mutex, &attr) != 0) {
warning("pthread_mutex_init() failed");
delete mutex;
return 0;
}
return (MutexRef)mutex;
assert(_mutexManager);
return _mutexManager->createMutex();
}
void OSystem_Android::lockMutex(MutexRef mutex) {
if (pthread_mutex_lock((pthread_mutex_t *)mutex) != 0)
warning("pthread_mutex_lock() failed");
assert(_mutexManager);
_mutexManager->lockMutex(mutex);
}
void OSystem_Android::unlockMutex(MutexRef mutex) {
if (pthread_mutex_unlock((pthread_mutex_t *)mutex) != 0)
warning("pthread_mutex_unlock() failed");
assert(_mutexManager);
_mutexManager->unlockMutex(mutex);
}
void OSystem_Android::deleteMutex(MutexRef mutex) {
pthread_mutex_t *m = (pthread_mutex_t *)mutex;
if (pthread_mutex_destroy(m) != 0)
warning("pthread_mutex_destroy() failed");
else
delete m;
assert(_mutexManager);
_mutexManager->deleteMutex(mutex);
}
void OSystem_Android::quit() {
@ -612,6 +602,10 @@ bool OSystem_Android::setTextInClipboard(const Common::String &text) {
return JNI::setTextInClipboard(text);
}
bool OSystem_Android::isConnectionLimited() {
return JNI::isConnectionLimited();
}
Common::String OSystem_Android::getSystemProperty(const char *name) const {
char value[PROP_VALUE_MAX];

View file

@ -98,6 +98,7 @@ extern void checkGlError(const char *expr, const char *file, int line);
#define GLTHREADCHECK do { } while (false)
#endif
class MutexManager;
class OSystem_Android : public EventsBaseBackend, public PaletteManager, public KeyReceiver {
private:
// passed from the dark side
@ -150,6 +151,7 @@ private:
bool _enable_zoning;
bool _virtkeybd_on;
MutexManager *_mutexManager;
Audio::MixerImpl *_mixer;
timeval _startTime;
@ -300,6 +302,7 @@ public:
virtual bool hasTextInClipboard();
virtual Common::String getTextFromClipboard();
virtual bool setTextInClipboard(const Common::String &text);
virtual bool isConnectionLimited();
virtual Common::String getSystemLanguage() const;
// ResidualVM specific method

View file

@ -62,11 +62,22 @@ typedef unsigned long NSUInteger;
static void openFromBundle(NSString *file) {
NSString *path = [[NSBundle mainBundle] pathForResource:file ofType:@"rtf"];
if (!path) {
path = [[NSBundle mainBundle] pathForResource:file ofType:@""];
path = [[NSBundle mainBundle] pathForResource:file ofType:@"html"];
if (!path) {
path = [[NSBundle mainBundle] pathForResource:file ofType:@""];
if (!path)
path = [[NSBundle mainBundle] pathForResource:file ofType:@"md"];
}
}
if (path) {
[[NSWorkspace sharedWorkspace] openFile:path];
// RTF and HTML files are widely recognized and we can rely on the default
// file association working for those. For the other ones this might not be
// the case so we explicitely indicate they should be open with TextEdit.
if ([path hasSuffix:@".html"] || [path hasSuffix:@".rtf"])
[[NSWorkspace sharedWorkspace] openFile:path];
else
[[NSWorkspace sharedWorkspace] openFile:path withApplication:@"TextEdit"];
}
}
@ -76,6 +87,7 @@ static void openFromBundle(NSString *file) {
- (void) openLicenseGPL;
- (void) openLicenseLGPL;
- (void) openLicenseFreefont;
- (void) openLicenseOFL;
- (void) openLicenseBSD;
- (void) openNews;
- (void) openUserManual;
@ -99,6 +111,10 @@ static void openFromBundle(NSString *file) {
openFromBundle(@"COPYING-FREEFONT");
}
- (void)openLicenseOFL {
openFromBundle(@"COPYING-OFL");
}
- (void)openLicenseBSD {
openFromBundle(@"COPYING-BSD");
}
@ -108,7 +124,7 @@ static void openFromBundle(NSString *file) {
}
- (void)openUserManual {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.residualvm.org/documentation"]];
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.residualvm.org/documentation"]];
}
- (void)openCredits {
@ -205,6 +221,7 @@ void replaceApplicationMenuItems() {
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);

View file

@ -35,6 +35,7 @@ endif
ifdef RISCOS
MODULE_OBJS += \
riscos/riscos-main.o \
riscos/riscos-utils.o \
riscos/riscos.o
endif
@ -51,6 +52,12 @@ MODULE_OBJS += \
psp2/psp2.o
endif
ifdef SWITCH
MODULE_OBJS += \
switch/switch-main.o \
switch/switch.o
endif
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
OBJS := $(MODULE_OBJS) $(OBJS)

View file

@ -22,7 +22,7 @@
#include "common/scummsys.h"
#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(PSP2) && !defined(ANDROIDSDL)
#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(PSP2) && !defined(ANDROIDSDL) && !defined(NINTENDO_SWITCH)
#include "backends/platform/sdl/posix/posix.h"
#include "backends/plugins/sdl/sdl-provider.h"

View file

@ -0,0 +1,70 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/scummsys.h"
#include "backends/platform/sdl/riscos/riscos-utils.h"
#include <unixlib/local.h>
#include <limits.h>
namespace RISCOS_Utils {
Common::String toRISCOS(Common::String path) {
char start[PATH_MAX];
char *end = __riscosify_std(path.c_str(), 0, start, PATH_MAX, 0);
return Common::String(start, end);
}
Common::String toUnix(Common::String path) {
Common::String out = Common::String(path);
uint32 start = 0;
if (out.contains("$")) {
char *x = strstr(out.c_str(), "$");
start = x ? x - out.c_str() : -1;
} else if (out.contains(":")) {
char *x = strstr(out.c_str(), ":");
start = x ? x - out.c_str() : -1;
}
for (uint32 ptr = start; ptr < out.size(); ptr += 1) {
switch (out.c_str()[ptr]) {
case '.':
out.setChar('/', ptr);
break;
case '/':
out.setChar('.', ptr);
break;
case '\xA0':
out.setChar(' ', ptr);
break;
default:
break;
}
}
if (out.contains("$") || out.contains(":"))
out = "/" + out;
return out;
}
}

View file

@ -20,16 +20,30 @@
*
*/
#include "backends/networking/connection/islimited.h"
#include "backends/platform/android/jni.h"
#ifndef PLATFORM_SDL_RISCOS_UTILS_H
#define PLATFORM_SDL_RISCOS_UTILS_H
namespace Networking {
namespace Connection {
#include "common/str.h"
// Helper functions
namespace RISCOS_Utils {
/**
* Converts a Unix style path to a RISC OS style path.
*
* @param str Unix style path to convert.
* @return RISC OS style path.
*/
Common::String toRISCOS(Common::String path);
/**
* Converts a RISC OS style path to a Unix style path.
*
* @param str RISC OS style path to convert.
* @return Unix style path.
*/
Common::String toUnix(Common::String path);
bool isLimited() {
return JNI::isConnectionLimited();
}
} // End of namespace Connection
} // End of namespace Networking
#endif

View file

@ -26,6 +26,7 @@
#include "backends/platform/sdl/riscos/riscos.h"
#include "backends/saves/default/default-saves.h"
#include "backends/events/riscossdl/riscossdl-events.h"
#include "backends/fs/riscos/riscos-fs-factory.h"
#include "backends/fs/riscos/riscos-fs.h"
@ -36,6 +37,10 @@
#define URI_Dispatch 0x4e381
#endif
#ifndef Report_Text0
#define Report_Text0 0x54c80
#endif
void OSystem_RISCOS::init() {
// Initialze File System Factory
_fsFactory = new RISCOSFilesystemFactory();
@ -45,6 +50,12 @@ void OSystem_RISCOS::init() {
}
void OSystem_RISCOS::initBackend() {
ConfMan.registerDefault("enable_reporter", false);
// Create the events manager
if (_eventSource == 0)
_eventSource = new RISCOSSdlEventSource();
// Create the savefile manager
if (_savefileManager == 0) {
Common::String savePath = "/<Choices$Write>/ResidualVM/Saves";
@ -76,6 +87,34 @@ bool OSystem_RISCOS::openUrl(const Common::String &url) {
return true;
}
void OSystem_RISCOS::logMessage(LogMessageType::Type type, const char *message) {
OSystem_SDL::logMessage(type, message);
// Log messages using !Reporter, available from http://www.avisoft.force9.co.uk/Reporter.htm
if (!ConfMan.getBool("enable_reporter"))
return;
char colour;
switch (type) {
case LogMessageType::kError:
colour = 'r';
break;
case LogMessageType::kWarning:
colour = 'o';
break;
case LogMessageType::kInfo:
colour = 'l';
break;
case LogMessageType::kDebug:
default:
colour = 'f';
break;
}
Common::String report = Common::String::format("\\%c %s", colour, message);
_swix(Report_Text0, _IN(0), report.c_str());
}
Common::String OSystem_RISCOS::getDefaultConfigFileName() {
return "/<Choices$Write>/ResidualVM/residualvm";
}

View file

@ -34,6 +34,8 @@ public:
virtual bool openUrl(const Common::String &url);
virtual void logMessage(LogMessageType::Type type, const char *message);
protected:
/**
* The path of the currently open log file, if any.

View file

@ -144,7 +144,11 @@
#include <SDL.h>
#endif
// Ignore warnings from system headers pulled by SDL
#pragma warning(push)
#pragma warning(disable:4121) // alignment of a member was sensitive to packing
#include <SDL_syswm.h>
#pragma warning(pop)
// Restore the forbidden exceptions from the hack above
#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && defined(_MSC_VER)

View file

@ -78,6 +78,8 @@ void SdlWindow::setupIcon() {
col = 0x00000000;
else if (!strcmp(color, "black"))
col = 0xFF000000;
else if (!strcmp(color, "gray20"))
col = 0xFF333333;
else if (color[0] == '#') {
if (sscanf(color + 1, "%06x", &col) != 1) {
warning("Wrong format of color (%s)", color + 1);

View file

@ -74,9 +74,23 @@ void OSystem_Win32::init() {
OSystem_SDL::init();
}
WORD GetCurrentSubsystem() {
// HMODULE is the module base address. And the PIMAGE_DOS_HEADER is located at the beginning.
PIMAGE_DOS_HEADER EXEHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);
assert(EXEHeader->e_magic == IMAGE_DOS_SIGNATURE);
// PIMAGE_NT_HEADERS is bitness dependant.
// Conveniently, since it's for our own process, it's always the correct bitness.
// IMAGE_NT_HEADERS has to be found using a byte offset from the EXEHeader,
// which requires the ugly cast.
PIMAGE_NT_HEADERS PEHeader = (PIMAGE_NT_HEADERS)(((char*)EXEHeader) + EXEHeader->e_lfanew);
assert(PEHeader->Signature == IMAGE_NT_SIGNATURE);
return PEHeader->OptionalHeader.Subsystem;
}
void OSystem_Win32::initBackend() {
// Console window is enabled by default on Windows
ConfMan.registerDefault("console", true);
// The console window is enabled for the console subsystem,
// since Windows already creates the console window for us
ConfMan.registerDefault("console", GetCurrentSubsystem() == IMAGE_SUBSYSTEM_WINDOWS_CUI);
// Enable or disable the window console window
if (ConfMan.getBool("console")) {
@ -122,7 +136,7 @@ bool OSystem_Win32::displayLogFile() {
// Try opening the log file with the default text editor
// log files should be registered as "txtfile" by default and thus open in the default text editor
HINSTANCE shellExec = ShellExecute(NULL, NULL, _logFilePath.c_str(), NULL, NULL, SW_SHOWNORMAL);
HINSTANCE shellExec = ShellExecute(getHwnd(), NULL, _logFilePath.c_str(), NULL, NULL, SW_SHOWNORMAL);
if ((intptr_t)shellExec > 32)
return true;
@ -145,17 +159,20 @@ bool OSystem_Win32::displayLogFile() {
NULL,
&startupInfo,
&processInformation);
if (result)
if (result) {
CloseHandle(processInformation.hProcess);
CloseHandle(processInformation.hThread);
return true;
}
return false;
}
bool OSystem_Win32::openUrl(const Common::String &url) {
const uint64 result = (uint64)ShellExecute(0, 0, /*(wchar_t*)nativeFilePath.utf16()*/url.c_str(), 0, 0, SW_SHOWNORMAL);
HINSTANCE result = ShellExecute(getHwnd(), NULL, /*(wchar_t*)nativeFilePath.utf16()*/url.c_str(), NULL, NULL, SW_SHOWNORMAL);
// ShellExecute returns a value greater than 32 if successful
if (result <= 32) {
warning("ShellExecute failed: error = %u", result);
if ((intptr_t)result <= 32) {
warning("ShellExecute failed: error = %p", (void*)result);
return false;
}
return true;

View file

@ -24,6 +24,7 @@
#define PLATFORM_SDL_WIN32_H
#include "backends/platform/sdl/sdl.h"
#include "backends/platform/sdl/win32/win32-window.h"
class OSystem_Win32 : public OSystem_SDL {
public:
@ -61,6 +62,8 @@ protected:
// Override createAudioCDManager() to get our Mac-specific
// version.
virtual AudioCDManager *createAudioCDManager();
HWND getHwnd() { return ((SdlWindow_Win32*)_window)->getHwnd(); }
};
#endif

View file

@ -16,6 +16,7 @@ win32dist: all
cp $(srcdir)/COPYING.BSD $(WIN32PATH)/COPYING.BSD.txt
cp $(srcdir)/COPYING.LGPL $(WIN32PATH)/COPYING.LGPL.txt
cp $(srcdir)/COPYING.FREEFONT $(WIN32PATH)/COPYING.FREEFONT.txt
cp $(srcdir)/COPYING.OFL $(WIN32PATH)/COPYING.OFL.txt
cp $(srcdir)/COPYING.ISC $(WIN32PATH)/COPYING.ISC.txt
cp $(srcdir)/COPYING.LUA $(WIN32PATH)/COPYING.LUA.txt
cp $(srcdir)/COPYING.MIT $(WIN32PATH)/COPYING.MIT.txt

View file

@ -29,6 +29,7 @@
#include <shlobj.h>
#include "common/scummsys.h"
#include "common/translation.h"
#include "backends/platform/sdl/win32/win32_wrapper.h"
// VerSetConditionMask, VerifyVersionInfo and SHGetFolderPath didn't appear until Windows 2000,
@ -80,28 +81,43 @@ bool confirmWindowsVersion(int majorVersion, int minorVersion) {
return VerifyVersionInfoFunc(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask);
}
wchar_t *ansiToUnicode(const char *s) {
DWORD size = MultiByteToWideChar(0, 0, s, -1, NULL, 0);
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];
if (MultiByteToWideChar(0, 0, s, -1, result, size) != 0)
if (MultiByteToWideChar(codePage, 0, s, -1, result, size) != 0)
return result;
}
return NULL;
}
char *unicodeToAnsi(const wchar_t *s) {
DWORD size = WideCharToMultiByte(0, 0, s, -1, NULL, 0, 0, 0);
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];
if (WideCharToMultiByte(0, 0, s, -1, result, size, 0, 0) != 0)
if (WideCharToMultiByte(codePage, 0, s, -1, result, size, 0, 0) != 0)
return result;
}
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;
}
}

View file

@ -45,7 +45,7 @@ bool confirmWindowsVersion(int majorVersion, int minorVersion);
*
* @note Return value must be freed by the caller.
*/
wchar_t *ansiToUnicode(const char *s);
wchar_t *ansiToUnicode(const char *s, uint codePage = CP_ACP);
/**
* Converts a Windows wide-character string into a C string.
* Used to interact with Win32 Unicode APIs with no ANSI fallback.
@ -55,7 +55,9 @@ wchar_t *ansiToUnicode(const char *s);
*
* @note Return value must be freed by the caller.
*/
char *unicodeToAnsi(const wchar_t *s);
char *unicodeToAnsi(const wchar_t *s, uint codePage = CP_ACP);
uint getCurrentCharset();
}

View file

@ -36,7 +36,7 @@
class Win32Plugin : public DynamicPlugin {
private:
static const TCHAR* toUnicode(const char *x) {
#ifndef _WIN32_WCE
#ifndef UNICODE
return (const TCHAR *)x;
#else
static TCHAR unicodeString[MAX_PATH];
@ -50,11 +50,7 @@ protected:
void *_dlHandle;
virtual VoidFunc findSymbol(const char *symbol) {
#ifndef _WIN32_WCE
FARPROC func = GetProcAddress((HMODULE)_dlHandle, symbol);
#else
FARPROC func = GetProcAddress((HMODULE)_dlHandle, toUnicode(symbol));
#endif
if (!func)
debug("Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str());
@ -67,11 +63,7 @@ public:
bool loadPlugin() {
assert(!_dlHandle);
#ifndef _WIN32_WCE
_dlHandle = LoadLibrary(_filename.c_str());
#else
_dlHandle = LoadLibrary(toUnicode(_filename.c_str()));
#endif
if (!_dlHandle) {
debug("Failed loading plugin '%s' (error code %d)", _filename.c_str(), (int32) GetLastError());

View file

@ -29,8 +29,9 @@
#if defined(USE_CLOUD) && defined(USE_LIBCURL)
#include "backends/cloud/cloudmanager.h"
#include "common/file.h"
#endif
#include "common/file.h"
#include "common/system.h"
#if !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
@ -369,6 +370,8 @@ void DefaultSaveFileManager::saveTimestamps(Common::HashMap<Common::String, uint
f.close();
}
#endif // ifdef USE_LIBCURL
Common::String DefaultSaveFileManager::concatWithSavesPath(Common::String name) {
DefaultSaveFileManager *manager = dynamic_cast<DefaultSaveFileManager *>(g_system->getSavefileManager());
Common::String path = (manager ? manager->getSavePath() : ConfMan.get("savepath"));
@ -385,6 +388,4 @@ Common::String DefaultSaveFileManager::concatWithSavesPath(Common::String name)
return path + '/' + name;
}
#endif // ifdef USE_LIBCURL
#endif // !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)

View file

@ -52,10 +52,10 @@ public:
static Common::HashMap<Common::String, uint32> loadTimestamps();
static void saveTimestamps(Common::HashMap<Common::String, uint32> &timestamps);
static Common::String concatWithSavesPath(Common::String name);
#endif
static Common::String concatWithSavesPath(Common::String name);
protected:
/**
* Get the path to the savegame directory.

View file

@ -24,11 +24,8 @@
// Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h.
// Also with clock() in sys/time.h in some Mac OS X SDKs.
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h //On IRIX, sys/stat.h includes sys/time.h
#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir
#define FORBIDDEN_SYMBOL_EXCEPTION_getenv
#define FORBIDDEN_SYMBOL_EXCEPTION_random
#define FORBIDDEN_SYMBOL_EXCEPTION_srandom
#include "common/scummsys.h"
@ -50,6 +47,9 @@ POSIXSaveFileManager::POSIXSaveFileManager() {
// Register default savepath.
#if defined(SAMSUNGTV)
ConfMan.registerDefault("savepath", "/mtd_wiselink/residualvm savegames");
#elif defined(NINTENDO_SWITCH)
Posix::assureDirectoryExists("./saves", nullptr);
ConfMan.registerDefault("savepath", "./saves");
#else
Common::String savePath;

View file

@ -55,7 +55,7 @@
- (NSMenu*)dockMenu {
// Get the list or recent games
CFPreferencesAppSynchronize(CFSTR("org.residualvm.residaulvm"));
CFPreferencesAppSynchronize(CFSTR("org.residualvm.residualvm"));
NSArray *array = CFPreferencesCopyAppValue(CFSTR("recentGames"), CFSTR("org.residualvm.residualvm"));
if (array == nil)
return nil;

View file

@ -35,6 +35,8 @@ struct TimerSlot {
uint32 nextFireTimeMicro; // microseconds part of nextFire
TimerSlot *next;
TimerSlot() : refCon(0), interval(0), nextFireTime(0), nextFireTimeMicro(0), next(0) {}
};
void insertPrioQueue(TimerSlot *head, TimerSlot *newSlot) {
@ -63,7 +65,6 @@ DefaultTimerManager::DefaultTimerManager() :
_head(0) {
_head = new TimerSlot();
memset(_head, 0, sizeof(TimerSlot));
}
DefaultTimerManager::~DefaultTimerManager() {

19
base/internal_plugins.h Normal file
View file

@ -0,0 +1,19 @@
#if !defined(INCLUDED_FROM_BASE_PLUGINS_H) && !defined(RC_INVOKED)
#error This file may only be included by base/plugins.h or dists/residualvm.rc
#endif
// plugin macros are defined in this simple internal header so that residualvm.rc
// can include them without causing problems for Windows resource compilers.
#define STATIC_PLUGIN 1
#define DYNAMIC_PLUGIN 2
#define PLUGIN_ENABLED_STATIC(ID) \
(ENABLE_##ID && !PLUGIN_ENABLED_DYNAMIC(ID))
#ifdef DYNAMIC_MODULES
#define PLUGIN_ENABLED_DYNAMIC(ID) \
(ENABLE_##ID && (ENABLE_##ID == DYNAMIC_PLUGIN))
#else
#define PLUGIN_ENABLED_DYNAMIC(ID) 0
#endif

View file

@ -607,7 +607,7 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
ConfMan.setActiveDomain("");
}
PluginManager::instance().loadAllPlugins(); // only for cached manager
PluginManager::instance().loadAllPluginsOfType(PLUGIN_TYPE_ENGINE); // only for cached manager
} else {
GUI::displayErrorDialog(_("Could not find any engine capable of running the selected game"));

View file

@ -380,6 +380,30 @@ void PluginManager::loadAllPlugins() {
}
}
void PluginManager::loadAllPluginsOfType(PluginType type) {
for (ProviderList::iterator pp = _providers.begin();
pp != _providers.end();
++pp) {
PluginList pl((*pp)->getPlugins());
for (PluginList::iterator p = pl.begin();
p != pl.end();
++p) {
if ((*p)->loadPlugin()) {
if ((*p)->getType() == type) {
addToPluginsInMemList((*p));
} else {
// Plugin is wrong type
(*p)->unloadPlugin();
delete (*p);
}
} else {
// Plugin did not load
delete (*p);
}
}
}
}
void PluginManager::unloadAllPlugins() {
for (int i = 0; i < PLUGIN_TYPE_MAX; i++)
unloadPluginsExcept((PluginType)i, NULL);
@ -530,6 +554,7 @@ DetectionResults EngineManager::detectGames(const Common::FSList &fslist) const
for (uint i = 0; i < engineCandidates.size(); i++) {
engineCandidates[i].engineName = metaEngine.getName();
engineCandidates[i].path = fslist.begin()->getParent().getPath();
engineCandidates[i].shortPath = fslist.begin()->getParent().getDisplayName();
candidates.push_back(engineCandidates[i]);
}

View file

@ -28,6 +28,10 @@
#include "common/str.h"
//#include "backends/plugins/elf/version.h" // ResidualVM specific
#define INCLUDED_FROM_BASE_PLUGINS_H
#include "base/internal_plugins.h"
#undef INCLUDED_FROM_BASE_PLUGINS_H
/**
* @page pagePlugins An overview of the ScummVM plugin system
@ -73,19 +77,6 @@ extern int pluginTypeVersions[PLUGIN_TYPE_MAX];
// Plugin linking
#define STATIC_PLUGIN 1
#define DYNAMIC_PLUGIN 2
#define PLUGIN_ENABLED_STATIC(ID) \
(ENABLE_##ID && !PLUGIN_ENABLED_DYNAMIC(ID))
#ifdef DYNAMIC_MODULES
#define PLUGIN_ENABLED_DYNAMIC(ID) \
(ENABLE_##ID && (ENABLE_##ID == DYNAMIC_PLUGIN))
#else
#define PLUGIN_ENABLED_DYNAMIC(ID) 0
#endif
// see comments in backends/plugins/elf/elf-provider.cpp
#if defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT)
#define PLUGIN_DYNAMIC_DSO_HANDLE \
@ -329,6 +320,7 @@ public:
// Functions used only by the cached PluginManager
virtual void loadAllPlugins();
virtual void loadAllPluginsOfType(PluginType type);
void unloadAllPlugins();
void unloadPluginsExcept(PluginType type, const Plugin *plugin, bool deletePlugin = true);
@ -356,7 +348,8 @@ public:
virtual bool loadPluginFromGameId(const Common::String &gameId);
virtual void updateConfigWithFileName(const Common::String &gameId);
virtual void loadAllPlugins() {} // we don't allow this
virtual void loadAllPlugins() {} // we don't allow these
virtual void loadAllPluginsOfType(PluginType type) {}
};
#endif

View file

@ -573,15 +573,31 @@ inline uint32 READ_LE_UINT24(const void *ptr) {
return (b[2] << 16) | (b[1] << 8) | (b[0]);
}
inline void WRITE_LE_UINT24(void *ptr, uint32 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 0);
b[1] = (uint8)(value >> 8);
b[2] = (uint8)(value >> 16);
}
inline uint32 READ_BE_UINT24(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
return (b[0] << 16) | (b[1] << 8) | (b[2]);
}
inline void WRITE_BE_UINT24(void *ptr, uint32 value) {
uint8 *b = (uint8 *)ptr;
b[0] = (uint8)(value >> 16);
b[1] = (uint8)(value >> 8);
b[2] = (uint8)(value >> 0);
}
#ifdef SCUMM_LITTLE_ENDIAN
#define READ_UINT24(a) READ_LE_UINT24(a)
#define WRITE_UINT24(a,b) WRITE_LE_UINT24(a,b)
#else
#define READ_UINT24(a) READ_BE_UINT24(a)
#define WRITE_UINT24(a,b) WRITE_BE_UINT24(a,b)
#endif
inline int16 READ_LE_INT16(const void *ptr) {

View file

@ -72,7 +72,7 @@ enum EventType {
* use events to ask for the save game dialog or to pause the engine.
* An associated enumerated type can accomplish this.
**/
EVENT_PREDICTIVE_DIALOG = 12
EVENT_PREDICTIVE_DIALOG = 12,
#ifdef ENABLE_KEYMAPPER
,
@ -81,17 +81,20 @@ enum EventType {
EVENT_CUSTOM_BACKEND_ACTION = 18,
EVENT_CUSTOM_BACKEND_HARDWARE = 21,
EVENT_GUI_REMAP_COMPLETE_ACTION = 22,
EVENT_KEYMAPPER_REMAP = 19
EVENT_KEYMAPPER_REMAP = 19,
#endif
#ifdef ENABLE_VKEYBD
,
EVENT_VIRTUAL_KEYBOARD = 20
EVENT_VIRTUAL_KEYBOARD = 20,
#endif
EVENT_DROP_FILE = 23
/* START of ResidualVM-specific code */
,
EVENT_JOYAXIS_MOTION = 23,
EVENT_JOYBUTTON_DOWN = 24,
EVENT_JOYBUTTON_UP = 25
EVENT_JOYAXIS_MOTION = 24,
EVENT_JOYBUTTON_DOWN = 25,
EVENT_JOYBUTTON_UP = 26
};
const int16 JOYAXIS_MIN = -32768;
@ -178,6 +181,9 @@ struct Event {
CustomEventType customType;
#endif
/* The path of the file or directory dragged to the ScummVM window */
Common::String path;
/**
* Mouse movement since the last mouse movement event.
*

View file

@ -162,8 +162,12 @@ bool DumpFile::open(const String &filename, bool createPath) {
subpath.erase(i);
if (subpath.empty()) continue;
AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(subpath);
if (node->exists()) continue;
if (node->exists()) {
delete node;
continue;
}
if (!node->create(true)) warning("DumpFile: unable to create directories from path prefix");
delete node;
}
}
}
@ -219,4 +223,14 @@ bool DumpFile::flush() {
int32 DumpFile::pos() const { return _handle->pos(); }
bool DumpFile::seek(int32 offset, int whence) {
SeekableWriteStream *ws = dynamic_cast<SeekableWriteStream *>(_handle);
return ws ? ws->seek(offset, whence) : false;
}
int32 DumpFile::size() const {
SeekableWriteStream *ws = dynamic_cast<SeekableWriteStream *>(_handle);
return ws ? ws->size() : -1;
}
} // End of namespace Common

View file

@ -134,7 +134,7 @@ public:
* Some design ideas:
* - automatically drop all files into dumps/ dir? Might not be desired in all cases
*/
class DumpFile : public WriteStream, public NonCopyable {
class DumpFile : public SeekableWriteStream, public NonCopyable {
protected:
/** File handle to the actual file; 0 if no file is open. */
WriteStream *_handle;
@ -158,11 +158,14 @@ public:
bool err() const;
void clearErr();
virtual uint32 write(const void *dataPtr, uint32 dataSize);
virtual uint32 write(const void *dataPtr, uint32 dataSize) override;
virtual bool flush();
virtual bool flush() override;
virtual int32 pos() const;
virtual int32 pos() const override;
virtual bool seek(int32 offset, int whence = SEEK_SET) override;
virtual int32 size() const override;
};
} // End of namespace Common

View file

@ -30,7 +30,7 @@ namespace Common {
bool INIFile::isValidName(const String &name) {
const char *p = name.c_str();
while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.'))
while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == ' '))
p++;
return *p == 0;
}
@ -108,7 +108,7 @@ bool INIFile::loadFromStream(SeekableReadStream &stream) {
// is, verify that it only consists of alphanumerics,
// periods, dashes and underscores). Mohawk Living Books games
// can have periods in their section names.
while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.'))
while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == ' '))
p++;
if (*p == '\0')

View file

@ -88,7 +88,7 @@ public:
* Simple memory based 'stream', which implements the WriteStream interface for
* a plain memory block.
*/
class MemoryWriteStream : public WriteStream {
class MemoryWriteStream : public SeekableWriteStream {
private:
const uint32 _bufSize;
protected:
@ -111,11 +111,13 @@ public:
return dataSize;
}
int32 pos() const { return _pos; }
uint32 size() const { return _bufSize; }
virtual int32 pos() const override { return _pos; }
virtual int32 size() const override { return _bufSize; }
virtual bool err() const { return _err; }
virtual void clearErr() { _err = false; }
virtual bool err() const override { return _err; }
virtual void clearErr() override { _err = false; }
virtual bool seek(int32 offset, int whence = SEEK_SET) override { return false; }
};
/**
@ -126,7 +128,8 @@ private:
byte *_ptrOrig;
public:
SeekableMemoryWriteStream(byte *buf, uint32 len) : MemoryWriteStream(buf, len), _ptrOrig(buf) {}
uint32 seek(uint32 offset, int whence = SEEK_SET) {
virtual bool seek(int32 offset, int whence = SEEK_SET) override {
switch (whence) {
case SEEK_END:
// SEEK_END works just like SEEK_SET, only 'reversed',
@ -143,11 +146,12 @@ public:
break;
}
// Post-Condition
if (_pos > size()) {
if ((int32)_pos > size()) {
_pos = size();
_ptr = _ptrOrig + _pos;
}
return _pos;
return true;
}
};
@ -156,7 +160,7 @@ public:
* A sort of hybrid between MemoryWriteStream and Array classes. A stream
* that grows as it's written to.
*/
class MemoryWriteStreamDynamic : public WriteStream {
class MemoryWriteStreamDynamic : public SeekableWriteStream {
protected:
uint32 _capacity;
uint32 _size;
@ -201,18 +205,39 @@ public:
return dataSize;
}
int32 pos() const { return _pos; }
uint32 size() const { return _size; }
virtual int32 pos() const override { return _pos; }
virtual int32 size() const override { return _size; }
byte *getData() { return _data; }
bool seek(int32 offset, int whence = SEEK_SET);
virtual bool seek(int32 offs, int whence = SEEK_SET) override {
// Pre-Condition
assert(_pos <= _size);
switch (whence) {
case SEEK_END:
// SEEK_END works just like SEEK_SET, only 'reversed', i.e. from the end.
offs = _size + offs;
// Fall through
case SEEK_SET:
_ptr = _data + offs;
_pos = offs;
break;
case SEEK_CUR:
_ptr += offs;
_pos += offs;
break;
}
assert(_pos <= _size);
return true;
}
};
/**
* MemoryStream based on RingBuffer. Grows if has insufficient buffer size.
*/
class MemoryReadWriteStream : public SeekableReadStream, public WriteStream {
class MemoryReadWriteStream : public SeekableReadStream, public SeekableWriteStream {
private:
uint32 _capacity;
uint32 _size;
@ -271,7 +296,7 @@ public:
return dataSize;
}
virtual uint32 read(void *dataPtr, uint32 dataSize) {
virtual uint32 read(void *dataPtr, uint32 dataSize) override {
if (_length < dataSize) {
dataSize = _length;
_eos = true;
@ -289,11 +314,11 @@ public:
return dataSize;
}
int32 pos() const { return _pos - _length; } // 'read' position in the stream
int32 size() const { return _size; } // that's also 'write' position in the stream, as it's append-only
bool seek(int32, int) { return false; }
bool eos() const { return _eos; }
void clearErr() { _eos = false; }
virtual int32 pos() const override { return _pos - _length; }
virtual int32 size() const override { return _size; }
virtual bool seek(int32, int) override { return false; }
virtual bool eos() const override { return _eos; }
virtual void clearErr() override { _eos = false; }
byte *getData() { return _data; }
};

View file

@ -35,10 +35,6 @@
#define GCC_ATLEAST(major, minor) 0
#endif
#if defined(_WIN32_WCE) && _WIN32_WCE < 300
#define NONSTANDARD_PORT
#endif
#if defined(NONSTANDARD_PORT)
// Ports which need to perform #includes and #defines visible in
@ -89,8 +85,6 @@
}
#endif
#if !defined(_WIN32_WCE)
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define NOGDICAPMASKS
#define OEMRESOURCE
@ -115,8 +109,6 @@
#define NOSOUND
#define NODRAWTEXT
#endif
#endif
#if defined(__QNXNTO__)

View file

@ -884,6 +884,7 @@ bool matchString(const char *str, const char *pat, bool ignoreCase, bool pathMod
const char *p = nullptr;
const char *q = nullptr;
bool escaped = false;
for (;;) {
if (pathMode && *str == '/') {
@ -893,6 +894,7 @@ bool matchString(const char *str, const char *pat, bool ignoreCase, bool pathMod
return false;
}
const char curPat = *pat;
switch (*pat) {
case '*':
if (*str) {
@ -912,12 +914,23 @@ bool matchString(const char *str, const char *pat, bool ignoreCase, bool pathMod
return true;
break;
case '\\':
if (!escaped) {
pat++;
break;
}
// fallthrough
case '#':
if (!isDigit(*str))
return false;
pat++;
str++;
break;
// treat # as a wildcard for digits unless escaped
if (!escaped) {
if (!isDigit(*str))
return false;
pat++;
str++;
break;
}
// fallthrough
default:
if ((!ignoreCase && *pat != *str) ||
@ -940,6 +953,8 @@ bool matchString(const char *str, const char *pat, bool ignoreCase, bool pathMod
pat++;
str++;
}
escaped = !escaped && (curPat == '\\');
}
}

View file

@ -179,6 +179,7 @@ public:
* "*": any character, any amount of times.
* "?": any character, only once.
* "#": any decimal digit, only once.
* "\#": #, only once.
*
* Example strings/patterns:
* String: monkey.s01 Pattern: monkey.s?? => true

View file

@ -102,31 +102,6 @@ bool MemoryReadStream::seek(int32 offs, int whence) {
return true; // FIXME: STREAM REWRITE
}
bool MemoryWriteStreamDynamic::seek(int32 offs, int whence) {
// Pre-Condition
assert(_pos <= _size);
switch (whence) {
case SEEK_END:
// SEEK_END works just like SEEK_SET, only 'reversed',
// i.e. from the end.
offs = _size + offs;
// Fall through
case SEEK_SET:
_ptr = _data + offs;
_pos = offs;
break;
case SEEK_CUR:
_ptr += offs;
_pos += offs;
break;
}
// Post-Condition
assert(_pos <= _size);
return true; // FIXME: STREAM REWRITE
}
#pragma mark -
enum {

View file

@ -203,6 +203,31 @@ public:
writeUint32BE(n);
}
/**
* Write the given 64-bit floating point value stored
* in little endian(LSB first) order into the stream.
*/
FORCEINLINE void writeDoubleLE(double value) {
uint64 n;
memcpy(&n, &value, 8);
writeUint64LE(n);
}
/**
* Write the given 64-bit floating point value stored
* in big endian order into the stream.
*/
FORCEINLINE void writeDoubleBE(double value) {
uint64 n;
memcpy(&n, &value, 8);
writeUint64BE(n);
}
/**
* Write the given string to the stream.
* This writes str.size() characters, but no terminating zero byte.
@ -210,6 +235,37 @@ public:
void writeString(const String &str);
};
/**
* Derived abstract base class for write streams streams that are seekable
*/
class SeekableWriteStream : public WriteStream {
public:
/**
* Sets the stream position indicator for the stream. The new position,
* measured in bytes, is obtained by adding offset bytes to the position
* specified by whence. If whence is set to SEEK_SET, SEEK_CUR, or
* SEEK_END, the offset is relative to the start of the file, the current
* position indicator, or end-of-file, respectively. A successful call
* to the seek() method clears the end-of-file indicator for the stream.
*
* @note The semantics of any implementation of this method are
* supposed to match those of ISO C fseek().
*
* @param offset the relative offset in bytes
* @param whence the seek reference: SEEK_SET, SEEK_CUR, or SEEK_END
* @return true on success, false in case of a failure
*/
virtual bool seek(int32 offset, int whence = SEEK_SET) = 0;
/**
* Obtains the current size of the stream, measured in bytes.
* If this value is unknown or can not be computed, -1 is returned.
*
* @return the size of the stream, or -1 if an error occurred
*/
virtual int32 size() const = 0;
};
/**
* Generic interface for a readable data stream.
*/
@ -443,6 +499,39 @@ public:
return f;
}
/**
* Read a 64-bit floating point value stored in little endian (LSB first)
* order from the stream and return it.
* Performs no error checking. The return value is undefined
* if a read error occurred (for which client code can check by
* calling err() and eos() ).
*/
FORCEINLINE double readDoubleLE() {
uint64 n = readUint64LE();
double d;
memcpy(&d, &n, 8);
return d;
}
/**
* Read a 64-bit floating point value stored in big endian
* order from the stream and return it.
* Performs no error checking. The return value is undefined
* if a read error occurred (for which client code can check by
* calling err() and eos() ).
*/
FORCEINLINE double readDoubleBE() {
uint64 n = readUint64BE();
double d;
memcpy(&d, &n, 8);
return d;
}
/**
* Read the specified amount of data into a malloc'ed buffer
* which then is wrapped into a MemoryReadStream.

View file

@ -193,6 +193,11 @@ Common::String OSystem::getSystemLanguage() const {
return "en_US";
}
bool OSystem::isConnectionLimited() {
warning("OSystem::isConnectionLimited(): not limited by default");
return false;
}
Common::TimerManager *OSystem::getTimerManager() {
return _timerManager;
}

View file

@ -1008,7 +1008,7 @@ public:
* This method could be called very often by engines. Backends are hence
* supposed to only perform any redrawing if it is necessary, and otherwise
* return immediately. See
* <http://wiki.scummvm.org/index.php/HOWTO-Backends#updateScreen.28.29_method>
* <https://wiki.scummvm.org/index.php/HOWTO-Backends#updateScreen.28.29_method>
*/
virtual void updateScreen() = 0;
@ -1627,6 +1627,13 @@ public:
*/
virtual Common::String getSystemLanguage() const;
/**
* Returns whether connection's limited (if available on the target system).
*
* Returns true if connection seems limited.
*/
virtual bool isConnectionLimited();
//@}
};

View file

@ -207,7 +207,7 @@ bool U32String::equals(const String &x) const {
return false;
for (size_t idx = 0; idx < _size; ++idx)
if (_str[idx] != x[idx])
if (_str[idx] != (value_type)x[idx])
return false;
return true;

View file

@ -23,6 +23,7 @@
#define FORBIDDEN_SYMBOL_EXCEPTION_isalnum
#define FORBIDDEN_SYMBOL_EXCEPTION_isalpha
#define FORBIDDEN_SYMBOL_EXCEPTION_isdigit
#define FORBIDDEN_SYMBOL_EXCEPTION_isxdigit
#define FORBIDDEN_SYMBOL_EXCEPTION_isnumber
#define FORBIDDEN_SYMBOL_EXCEPTION_islower
#define FORBIDDEN_SYMBOL_EXCEPTION_isspace
@ -132,6 +133,11 @@ bool isDigit(int c) {
return isdigit((byte)c);
}
bool isXDigit(int c) {
ENSURE_ASCII_CHAR(c);
return isxdigit((byte)c);
}
bool isLower(int c) {
ENSURE_ASCII_CHAR(c);
return islower((byte)c);

View file

@ -141,6 +141,16 @@ bool isAlpha(int c);
*/
bool isDigit(int c);
/**
* Test whether the given character is a hwzadecimal-digit (0-9 or A-F).
* If the parameter is outside the range of a signed or unsigned char, then
* false is returned.
*
* @param c the character to test
* @return true if the character is a hexadecimal-digit, false otherwise.
*/
bool isXDigit(int c);
/**
* Test whether the given character is a lower-case letter (a-z).
* If the parameter is outside the range of a signed or unsigned char, then

View file

@ -28,6 +28,31 @@
namespace Common {
/** The default Windows resources. */
enum WinResourceType {
kWinCursor = 0x01,
kWinBitmap = 0x02,
kWinIcon = 0x03,
kWinMenu = 0x04,
kWinDialog = 0x05,
kWinString = 0x06,
kWinFontDir = 0x07,
kWinFont = 0x08,
kWinAccelerator = 0x09,
kWinRCData = 0x0A,
kWinMessageTable = 0x0B,
kWinGroupCursor = 0x0C,
kWinGroupIcon = 0x0E,
kWinVersion = 0x10,
kWinDlgInclude = 0x11,
kWinPlugPlay = 0x13,
kWinVXD = 0x14,
kWinAniCursor = 0x15,
kWinAniIcon = 0x16,
kWinHTML = 0x17,
kWinManifest = 0x18
};
class WinResourceID {
public:
WinResourceID() { _idType = kIDTypeNull; }

View file

@ -32,31 +32,6 @@ namespace Common {
template<class T> class Array;
class SeekableReadStream;
/** The default Windows resources. */
enum NEResourceType {
kNECursor = 0x01,
kNEBitmap = 0x02,
kNEIcon = 0x03,
kNEMenu = 0x04,
kNEDialog = 0x05,
kNEString = 0x06,
kNEFontDir = 0x07,
kNEFont = 0x08,
kNEAccelerator = 0x09,
kNERCData = 0x0A,
kNEMessageTable = 0x0B,
kNEGroupCursor = 0x0C,
kNEGroupIcon = 0x0E,
kNEVersion = 0x10,
kNEDlgInclude = 0x11,
kNEPlugPlay = 0x13,
kNEVXD = 0x14,
kNEAniCursor = 0x15,
kNEAniIcon = 0x16,
kNEHTML = 0x17,
kNEManifest = 0x18
};
/**
* A class able to load resources from a Windows New Executable, such
* as cursors, bitmaps, and sounds.

View file

@ -33,29 +33,6 @@ namespace Common {
template<class T> class Array;
class SeekableReadStream;
/** The default Windows PE resources. */
enum PEResourceType {
kPECursor = 0x01,
kPEBitmap = 0x02,
kPEIcon = 0x03,
kPEMenu = 0x04,
kPEDialog = 0x05,
kPEString = 0x06,
kPEFontDir = 0x07,
kPEFont = 0x08,
kPEAccelerator = 0x09,
kPERCData = 0x0A,
kPEMessageTable = 0x0B,
kPEGroupCursor = 0x0C,
kPEGroupIcon = 0x0E,
kPEVersion = 0x10,
kPEDlgInclude = 0x11,
kPEPlugPlay = 0x13,
kPEVXD = 0x14,
kPEAniCursor = 0x15,
kPEAniIcon = 0x16
};
/**
* A class able to load resources from a Windows Portable Executable, such
* as cursors, bitmaps, and sounds.

View file

@ -133,7 +133,8 @@ int main(int argc, char *argv[]) {
setup.features = getAllFeatures();
ProjectType projectType = kProjectNone;
int msvcVersion = 12;
const MSVCVersion* msvc = NULL;
int msvcVersion = 0;
// Parse command line arguments
using std::cout;
@ -192,10 +193,6 @@ int main(int argc, char *argv[]) {
msvcVersion = atoi(argv[++i]);
if (msvcVersion != 9 && msvcVersion != 10 && msvcVersion != 11 && msvcVersion != 12 && msvcVersion != 14 && msvcVersion != 15) {
std::cerr << "ERROR: Unsupported version: \"" << msvcVersion << "\" passed to \"--msvc-version\"!\n";
return -1;
}
} else if (!strncmp(argv[i], "--enable-engine=", 16)) {
const char *names = &argv[i][16];
if (!*names) {
@ -482,6 +479,23 @@ int main(int argc, char *argv[]) {
break;
case kProjectMSVC:
// Auto-detect if no version is specified
if (msvcVersion == 0) {
msvcVersion = getInstalledMSVC();
if (msvcVersion == 0) {
std::cerr << "ERROR: No Visual Studio versions found, please specify one with \"--msvc-version\"\n";
return -1;
} else {
cout << "Visual Studio " << msvcVersion << " detected\n\n";
}
}
msvc = getMSVCVersion(msvcVersion);
if (!msvc) {
std::cerr << "ERROR: Unsupported version: \"" << msvcVersion << "\" passed to \"--msvc-version\"!\n";
return -1;
}
////////////////////////////////////////////////////////////////////////////
// For Visual Studio, all warnings are on by default in the project files,
// so we pass a list of warnings to disable globally or per-project
@ -584,7 +598,7 @@ int main(int argc, char *argv[]) {
globalWarnings.push_back("6385");
globalWarnings.push_back("6386");
if (msvcVersion == 14 || msvcVersion == 15) {
if (msvcVersion >= 14) {
globalWarnings.push_back("4267");
globalWarnings.push_back("4577");
}
@ -608,9 +622,9 @@ int main(int argc, char *argv[]) {
projectWarnings["sci"].push_back("4373");
if (msvcVersion == 9)
provider = new CreateProjectTool::VisualStudioProvider(globalWarnings, projectWarnings, msvcVersion);
provider = new CreateProjectTool::VisualStudioProvider(globalWarnings, projectWarnings, msvcVersion, *msvc);
else
provider = new CreateProjectTool::MSBuildProvider(globalWarnings, projectWarnings, msvcVersion);
provider = new CreateProjectTool::MSBuildProvider(globalWarnings, projectWarnings, msvcVersion, *msvc);
break;
@ -700,14 +714,13 @@ void displayHelp(const char *exe) {
" directory\n"
"\n"
"MSVC specific settings:\n"
" --msvc-version version set the targeted MSVC version. Possible values:\n"
" 9 stands for \"Visual Studio 2008\"\n"
" 10 stands for \"Visual Studio 2010\"\n"
" 11 stands for \"Visual Studio 2012\"\n"
" 12 stands for \"Visual Studio 2013\"\n"
" 14 stands for \"Visual Studio 2015\"\n"
" 15 stands for \"Visual Studio 2017\"\n"
" The default is \"12\", thus \"Visual Studio 2013\"\n"
" --msvc-version version set the targeted MSVC version. Possible values:\n";
const MSVCList msvc = getAllMSVCVersions();
for (MSVCList::const_iterator i = msvc.begin(); i != msvc.end(); ++i)
cout << " " << i->version << " stands for \"" << i->name << "\"\n";
cout << " If no version is set, the latest installed version is used\n"
" --build-events Run custom build events as part of the build\n"
" (default: false)\n"
" --installer Create installer after the build (implies --build-events)\n"
@ -1048,29 +1061,43 @@ const Feature s_features[] = {
{ "glew", "USE_GLEW", "GLEW", true, "GLEW support" }, // ResidualVM specific
// Feature flags
{ "bink", "USE_BINK", "", true, "Bink video support" },
{ "scalers", "USE_SCALERS", "", true, "Scalers" },
{ "hqscalers", "USE_HQ_SCALERS", "", true, "HQ scalers" },
{ "16bit", "USE_RGB_COLOR", "", true, "16bit color support" },
// { "mt32emu", "USE_MT32EMU", "", true, "integrated MT-32 emulator" }, // ResidualVM change
{ "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling.
{ "opengl", "USE_OPENGL", "", true, "OpenGL support" },
{ "openglshaders", "USE_OPENGL_SHADERS", "", true, "OpenGL support (shaders)" }, // ResidualVM specific
{ "opengles", "USE_GLES", "", true, "forced OpenGL ES mode" },
{ "taskbar", "USE_TASKBAR", "", true, "Taskbar integration support" },
{ "cloud", "USE_CLOUD", "", true, "Cloud integration support" },
{ "translation", "USE_TRANSLATION", "", true, "Translation support" },
{ "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"},
{ "keymapper", "ENABLE_KEYMAPPER", "", false, "Keymapper support"},
{ "eventrecorder", "ENABLE_EVENTRECORDER", "", false, "Event recorder support"},
{ "updates", "USE_UPDATES", "", false, "Updates support"},
{ "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there
// is just no current way of properly detecting this...
{ "bink", "USE_BINK", "", true, "Bink video support" },
{ "scalers", "USE_SCALERS", "", true, "Scalers" },
{ "hqscalers", "USE_HQ_SCALERS", "", true, "HQ scalers" },
{ "16bit", "USE_RGB_COLOR", "", true, "16bit color support" },
{ "highres", "USE_HIGHRES", "", true, "high resolution" },
// { "mt32emu", "USE_MT32EMU", "", true, "integrated MT-32 emulator" }, // ResidualVM change
{ "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling.
{ "opengl", "USE_OPENGL", "", true, "OpenGL support" },
{ "openglshaders", "USE_OPENGL_SHADERS", "", true, "OpenGL support (shaders)" }, // ResidualVM specific
{ "opengles", "USE_GLES", "", true, "forced OpenGL ES mode" },
{ "taskbar", "USE_TASKBAR", "", true, "Taskbar integration support" },
{ "cloud", "USE_CLOUD", "", true, "Cloud integration support" },
{ "translation", "USE_TRANSLATION", "", true, "Translation support" },
{ "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"},
{ "keymapper", "ENABLE_KEYMAPPER", "", false, "Keymapper support"},
{ "eventrecorder", "ENABLE_EVENTRECORDER", "", false, "Event recorder support"},
{ "updates", "USE_UPDATES", "", false, "Updates support"},
{ "dialogs", "USE_SYSDIALOGS", "", true, "System dialogs support"},
{ "langdetect", "USE_DETECTLANG", "", true, "System language detection support" }, // This feature actually depends on "translation", there
// is just no current way of properly detecting this...
{ "text-console", "USE_TEXT_CONSOLE_FOR_DEBUGGER", "", false, "Text console debugger" } // This feature is always applied in xcode projects
};
const Tool s_tools[] = {
{ "create_translations", true},
};
const MSVCVersion s_msvc[] = {
// Ver Name Solution Project Toolset LLVM
{ 9, "Visual Studio 2008", "10.00", "2008", "4.0", "v90", "LLVM-vs2008" },
{ 10, "Visual Studio 2010", "11.00", "2010", "4.0", "v100", "LLVM-vs2010" },
{ 11, "Visual Studio 2012", "11.00", "2012", "4.0", "v110", "LLVM-vs2012" },
{ 12, "Visual Studio 2013", "12.00", "2013", "12.0", "v120", "LLVM-vs2013" },
{ 14, "Visual Studio 2015", "12.00", "14", "14.0", "v140", "LLVM-vs2014" },
{ 15, "Visual Studio 2017", "12.00", "15", "15.0", "v141", "llvm" },
{ 16, "Visual Studio 2019", "12.00", "Version 16", "16.0", "v142", "llvm" }
};
} // End of anonymous namespace
FeatureList getAllFeatures() {
@ -1136,6 +1163,63 @@ ToolList getAllTools() {
return tools;
}
MSVCList getAllMSVCVersions() {
const size_t msvcCount = sizeof(s_msvc) / sizeof(s_msvc[0]);
MSVCList msvcVersions;
for (size_t i = 0; i < msvcCount; ++i)
msvcVersions.push_back(s_msvc[i]);
return msvcVersions;
}
const MSVCVersion *getMSVCVersion(int version) {
const size_t msvcCount = sizeof(s_msvc) / sizeof(s_msvc[0]);
for (size_t i = 0; i < msvcCount; ++i) {
if (s_msvc[i].version == version)
return &s_msvc[i];
}
return NULL;
}
int getInstalledMSVC() {
int latest = 0;
#if defined(_WIN32) || defined(WIN32)
// Use the Visual Studio Installer to get the latest version
const char *vsWhere = "\"\"%PROGRAMFILES(X86)%\\Microsoft Visual Studio\\Installer\\vswhere.exe\" -latest -legacy -property installationVersion\"";
FILE *pipe = _popen(vsWhere, "rt");
if (pipe != NULL) {
char version[50];
if (fgets(version, 50, pipe) != NULL) {
latest = atoi(version);
}
_pclose(pipe);
}
// Use the registry to get the latest version
if (latest == 0) {
HKEY key;
LSTATUS err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key);
if (err == ERROR_SUCCESS && key != NULL) {
const MSVCList msvc = getAllMSVCVersions();
for (MSVCList::const_reverse_iterator i = msvc.rbegin(); i != msvc.rend(); ++i) {
std::ostringstream version;
version << i->version << ".0";
err = RegQueryValueEx(key, version.str().c_str(), NULL, NULL, NULL, NULL);
if (err == ERROR_SUCCESS) {
latest = i->version;
break;
}
}
RegCloseKey(key);
}
}
#endif
return latest;
}
namespace CreateProjectTool {
//////////////////////////////////////////////////////////////////////////
@ -1403,7 +1487,7 @@ void ProjectProvider::createProject(BuildSetup &setup) {
}
// We also need to add the UUID of the main project file.
const std::string svmUUID = _uuidMap[setup.projectName] = createUUID();
const std::string svmUUID = _uuidMap[setup.projectName] = createUUID(setup.projectName);
createWorkspace(setup);
@ -1463,6 +1547,7 @@ void ProjectProvider::createProject(BuildSetup &setup) {
in.push_back(setup.srcDir + "/COPYING.LGPL");
in.push_back(setup.srcDir + "/COPYING.BSD");
in.push_back(setup.srcDir + "/COPYING.FREEFONT");
in.push_back(setup.srcDir + "/COPYING.OFL");
in.push_back(setup.srcDir + "/COPYRIGHT");
in.push_back(setup.srcDir + "/NEWS");
in.push_back(setup.srcDir + "/README.md");
@ -1489,7 +1574,7 @@ ProjectProvider::UUIDMap ProjectProvider::createUUIDMap(const BuildSetup &setup)
if (!i->enable || isSubEngine(i->name, setup.engines))
continue;
result[i->name] = createUUID();
result[i->name] = createUUID(i->name);
}
return result;
@ -1503,17 +1588,20 @@ ProjectProvider::UUIDMap ProjectProvider::createToolsUUIDMap() const {
if (!i->enable)
continue;
result[i->name] = createUUID();
result[i->name] = createUUID(i->name);
}
return result;
}
const int kUUIDLen = 16;
std::string ProjectProvider::createUUID() const {
#ifdef USE_WIN32_API
UUID uuid;
if (UuidCreate(&uuid) != RPC_S_OK)
error("UuidCreate failed");
RPC_STATUS status = UuidCreateSequential(&uuid);
if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY)
error("UuidCreateSequential failed");
unsigned char *string = 0;
if (UuidToStringA(&uuid, &string) != RPC_S_OK)
@ -1524,25 +1612,81 @@ std::string ProjectProvider::createUUID() const {
RpcStringFreeA(&string);
return result;
#else
unsigned char uuid[16];
unsigned char uuid[kUUIDLen];
for (int i = 0; i < 16; ++i)
for (int i = 0; i < kUUIDLen; ++i)
uuid[i] = (unsigned char)((std::rand() / (double)(RAND_MAX)) * 0xFF);
uuid[8] &= 0xBF; uuid[8] |= 0x80;
uuid[6] &= 0x4F; uuid[6] |= 0x40;
return UUIDToString(uuid);
#endif
}
std::string ProjectProvider::createUUID(const std::string &name) const {
#ifdef USE_WIN32_API
HCRYPTPROV hProv = NULL;
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
error("CryptAcquireContext failed");
}
// Use MD5 hashing algorithm
HCRYPTHASH hHash = NULL;
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
CryptReleaseContext(hProv, 0);
error("CryptCreateHash failed");
}
// Hash unique ScummVM namespace {5f5b43e8-35ff-4f1e-ad7e-a2a87e9b5254}
const BYTE uuidNs[kUUIDLen] =
{ 0x5f, 0x5b, 0x43, 0xe8, 0x35, 0xff, 0x4f, 0x1e, 0xad, 0x7e, 0xa2, 0xa8, 0x7e, 0x9b, 0x52, 0x54 };
if (!CryptHashData(hHash, uuidNs, kUUIDLen, 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
error("CryptHashData failed");
}
// Hash project name
if (!CryptHashData(hHash, (const BYTE *)name.c_str(), name.length(), 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
error("CryptHashData failed");
}
// Get resulting UUID
BYTE uuid[kUUIDLen];
DWORD len = kUUIDLen;
if (!CryptGetHashParam(hHash, HP_HASHVAL, uuid, &len, 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
error("CryptGetHashParam failed");
}
// Add version and variant
uuid[6] &= 0x0F; uuid[6] |= 0x30;
uuid[8] &= 0x3F; uuid[8] |= 0x80;
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return UUIDToString(uuid);
#else
// Fallback to random UUID
return createUUID();
#endif
}
std::string ProjectProvider::UUIDToString(unsigned char *uuid) const {
std::stringstream uuidString;
uuidString << std::hex << std::uppercase << std::setfill('0');
for (int i = 0; i < 16; ++i) {
for (int i = 0; i < kUUIDLen; ++i) {
uuidString << std::setw(2) << (int)uuid[i];
if (i == 3 || i == 5 || i == 7 || i == 9) {
uuidString << std::setw(0) << '-';
}
}
return uuidString.str();
#endif
}
std::string ProjectProvider::getLastPathComponent(const std::string &path) {

View file

@ -277,6 +277,45 @@ struct BuildSetup {
#endif
void NORETURN_PRE error(const std::string &message) NORETURN_POST;
/**
* Structure to describe a Visual Studio version specification.
*
* This includes various generation details for MSVC projects,
* as well as describe the versions supported.
*/
struct MSVCVersion {
int version; ///< Version number passed as parameter.
const char *name; ///< Full program name.
const char *solutionFormat; ///< Format used for solution files.
const char *solutionVersion; ///< Version number used in solution files.
const char *project; ///< Version number used in project files.
const char *toolsetMSVC; ///< Toolset version for MSVC compiler.
const char *toolsetLLVM; ///< Toolset version for Clang/LLVM compiler.
};
typedef std::list<MSVCVersion> MSVCList;
/**
* Creates a list of all supported versions of Visual Studio.
*
* @return A list including all versions available.
*/
MSVCList getAllMSVCVersions();
/**
* Returns the definitions for a specific Visual Studio version.
*
* @param version The requested version.
* @return The version information, or NULL if the version isn't supported.
*/
const MSVCVersion *getMSVCVersion(int version);
/**
* Auto-detects the latest version of Visual Studio installed.
*
* @return Version number, or 0 if no installations were found.
*/
int getInstalledMSVC();
namespace CreateProjectTool {
/**
@ -542,7 +581,24 @@ protected:
*/
std::string createUUID() const;
/**
* Creates a name-based UUID and returns it in string representation.
*
* @param name Unique name to hash.
* @return A new UUID as string.
*/
std::string createUUID(const std::string &name) const;
private:
/**
* Returns the string representation of an existing UUID.
*
* @param uuid 128-bit array.
* @return Existing UUID as string.
*/
std::string UUIDToString(unsigned char *uuid) const;
/**
* This creates the engines/plugins_table.h file required for building
* ScummVM.

View file

@ -29,12 +29,11 @@
namespace CreateProjectTool {
//////////////////////////////////////////////////////////////////////////
// MSBuild Provider (Visual Studio 2010)
// MSBuild Provider (Visual Studio 2010 and later)
//////////////////////////////////////////////////////////////////////////
MSBuildProvider::MSBuildProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version)
: MSVCProvider(global_warnings, project_warnings, version) {
MSBuildProvider::MSBuildProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version, const MSVCVersion& msvc)
: MSVCProvider(global_warnings, project_warnings, version, msvc) {
}
const char *MSBuildProvider::getProjectExtension() {
@ -45,32 +44,6 @@ const char *MSBuildProvider::getPropertiesExtension() {
return ".props";
}
int MSBuildProvider::getVisualStudioVersion() {
if (_version == 10)
return 2010;
if (_version == 11)
return 2012;
if (_version == 12)
return 2013;
if (_version == 14)
return 14;
if (_version == 15)
return 15;
error("Unsupported version passed to getVisualStudioVersion");
}
int MSBuildProvider::getSolutionVersion() {
if (_version == 14 || _version == 15)
return 14;
return _version + 1;
}
namespace {
inline void outputConfiguration(std::ostream &project, const std::string &config, const std::string &platform) {
@ -80,7 +53,7 @@ inline void outputConfiguration(std::ostream &project, const std::string &config
"\t\t</ProjectConfiguration>\n";
}
inline void outputConfigurationType(const BuildSetup &setup, std::ostream &project, const std::string &name, const std::string &config, std::string toolset) {
inline void outputConfigurationType(const BuildSetup &setup, std::ostream &project, const std::string &name, const std::string &config, const std::string &toolset) {
project << "\t<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='" << config << "'\" Label=\"Configuration\">\n"
"\t\t<ConfigurationType>" << ((name == setup.projectName || setup.devTools || setup.tests) ? "Application" : "StaticLibrary") << "</ConfigurationType>\n"
"\t\t<PlatformToolset>" << toolset << "</PlatformToolset>\n"
@ -104,7 +77,7 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri
error("Could not open \"" + projectFile + "\" for writing");
project << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
"<Project DefaultTargets=\"Build\" ToolsVersion=\"" << _msvcVersion.project << "\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
"\t<ItemGroup Label=\"ProjectConfigurations\">\n";
outputConfiguration(project, "Debug", "Win32");
@ -129,17 +102,14 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri
// Shared configuration
project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n";
std::string version = _version == 15 ? "v141" : "v" + toString(_version) + "0";
std::string llvm = "LLVM-vs" + toString(getVisualStudioVersion());
outputConfigurationType(setup, project, name, "Release|Win32", version);
outputConfigurationType(setup, project, name, "Analysis|Win32", version);
outputConfigurationType(setup, project, name, "LLVM|Win32", llvm);
outputConfigurationType(setup, project, name, "Debug|Win32", version);
outputConfigurationType(setup, project, name, "Release|x64", version);
outputConfigurationType(setup, project, name, "LLVM|x64", llvm);
outputConfigurationType(setup, project, name, "Analysis|x64", version);
outputConfigurationType(setup, project, name, "Debug|x64", version);
outputConfigurationType(setup, project, name, "Release|Win32", _msvcVersion.toolsetMSVC);
outputConfigurationType(setup, project, name, "Analysis|Win32", _msvcVersion.toolsetMSVC);
outputConfigurationType(setup, project, name, "LLVM|Win32", _msvcVersion.toolsetLLVM);
outputConfigurationType(setup, project, name, "Debug|Win32", _msvcVersion.toolsetMSVC);
outputConfigurationType(setup, project, name, "Release|x64", _msvcVersion.toolsetMSVC);
outputConfigurationType(setup, project, name, "LLVM|x64", _msvcVersion.toolsetLLVM);
outputConfigurationType(setup, project, name, "Analysis|x64", _msvcVersion.toolsetMSVC);
outputConfigurationType(setup, project, name, "Debug|x64", _msvcVersion.toolsetMSVC);
project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n"
"\t<ImportGroup Label=\"ExtensionSettings\">\n"
@ -234,7 +204,7 @@ void MSBuildProvider::createFiltersFile(const BuildSetup &setup, const std::stri
error("Could not open \"" + filtersFile + "\" for writing");
filters << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<Project ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n";
"<Project ToolsVersion=\"" << _msvcVersion.project << "\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n";
// Output the list of filters
filters << "\t<ItemGroup>\n";
@ -367,7 +337,7 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea
definesList += REVISION_DEFINE ";";
properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
"<Project DefaultTargets=\"Build\" ToolsVersion=\"" << _msvcVersion.project << "\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
"\t<PropertyGroup>\n"
"\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_Global</_PropertySheetDisplayName>\n"
"\t\t<ExecutablePath>$(" << LIBS_DEFINE << ")\\bin;$(" << LIBS_DEFINE << ")\\bin\\" << (bits == 32 ? "x86" : "x64") << ";$(ExecutablePath)</ExecutablePath>\n"
@ -421,7 +391,7 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b
error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing");
properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
"<Project DefaultTargets=\"Build\" ToolsVersion=\"" << _msvcVersion.project << "\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
"\t<ImportGroup Label=\"PropertySheets\">\n"
"\t\t<Import Project=\"" << setup.projectDescription << "_Global" << (isWin32 ? "" : "64") << ".props\" />\n"
"\t</ImportGroup>\n"

View file

@ -29,7 +29,7 @@ namespace CreateProjectTool {
class MSBuildProvider : public MSVCProvider {
public:
MSBuildProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version);
MSBuildProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version, const MSVCVersion &msvc);
protected:
void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir,
@ -48,8 +48,6 @@ protected:
const char *getProjectExtension();
const char *getPropertiesExtension();
int getVisualStudioVersion();
int getSolutionVersion();
private:
struct FileEntry {

View file

@ -31,8 +31,8 @@ namespace CreateProjectTool {
//////////////////////////////////////////////////////////////////////////
// MSVC Provider (Base class)
//////////////////////////////////////////////////////////////////////////
MSVCProvider::MSVCProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version)
: ProjectProvider(global_warnings, project_warnings, version) {
MSVCProvider::MSVCProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version, const MSVCVersion &msvc)
: ProjectProvider(global_warnings, project_warnings, version), _msvcVersion(msvc) {
_enableLanguageExtensions = tokenize(ENABLE_LANGUAGE_EXTENSIONS, ',');
_disableEditAndContinue = tokenize(DISABLE_EDIT_AND_CONTINUE, ',');
@ -46,14 +46,14 @@ void MSVCProvider::createWorkspace(const BuildSetup &setup) {
const std::string svmProjectUUID = svmUUID->second;
assert(!svmProjectUUID.empty());
std::string solutionUUID = createUUID();
std::string solutionUUID = createUUID(setup.projectName + ".sln");
std::ofstream solution((setup.outputDir + '/' + setup.projectName + ".sln").c_str());
if (!solution)
error("Could not open \"" + setup.outputDir + '/' + setup.projectName + ".sln\" for writing");
solution << "Microsoft Visual Studio Solution File, Format Version " << getSolutionVersion() << ".00\n";
solution << "# Visual Studio " << getVisualStudioVersion() << "\n";
solution << "Microsoft Visual Studio Solution File, Format Version " << _msvcVersion.solutionFormat << "\n";
solution << "# Visual Studio " << _msvcVersion.solutionVersion << "\n";
// Write main project
if (!setup.devTools) {
@ -162,10 +162,6 @@ void MSVCProvider::createGlobalProp(const BuildSetup &setup) {
outputGlobalPropFile(setup, properties, 64, x64Defines, convertPathToWin(setup.filePrefix), setup.runBuildEvents);
}
int MSVCProvider::getSolutionVersion() {
return _version + 1;
}
std::string MSVCProvider::getPreBuildEvent() const {
std::string cmdLine = "";

View file

@ -29,9 +29,11 @@ namespace CreateProjectTool {
class MSVCProvider : public ProjectProvider {
public:
MSVCProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version);
MSVCProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version, const MSVCVersion &msvcVersion);
protected:
const MSVCVersion _msvcVersion;
StringList _enableLanguageExtensions;
StringList _disableEditAndContinue;
@ -70,7 +72,7 @@ protected:
* @param setup Description of the desired build setup.
* @param isRelease Type of property file
* @param isWin32 Bitness of property file
* @param enableAnalysis PREfast support
* @param configuration Name of property file
*/
virtual void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) = 0;
@ -79,16 +81,6 @@ protected:
*/
virtual const char *getPropertiesExtension() = 0;
/**
* Get the Visual Studio version (used by the VS shell extension to launch the correct VS version)
*/
virtual int getVisualStudioVersion() = 0;
/**
* Get the Solution version (used in the sln file header)
*/
virtual int getSolutionVersion();
/**
* Get the command line for the revision tool (shared between all Visual Studio based providers)
*/

View file

@ -32,8 +32,8 @@ namespace CreateProjectTool {
// Visual Studio Provider (Visual Studio 2008)
//////////////////////////////////////////////////////////////////////////
VisualStudioProvider::VisualStudioProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version)
: MSVCProvider(global_warnings, project_warnings, version) {
VisualStudioProvider::VisualStudioProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version, const MSVCVersion& msvc)
: MSVCProvider(global_warnings, project_warnings, version, msvc) {
}
const char *VisualStudioProvider::getProjectExtension() {
@ -44,13 +44,6 @@ const char *VisualStudioProvider::getPropertiesExtension() {
return ".vsprops";
}
int VisualStudioProvider::getVisualStudioVersion() {
if (_version == 9)
return 2008;
error("Unsupported version passed to getVisualStudioVersion");
}
void VisualStudioProvider::createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir,
const StringList &includeList, const StringList &excludeList) {
const std::string projectFile = setup.outputDir + '/' + name + getProjectExtension();

View file

@ -29,7 +29,7 @@ namespace CreateProjectTool {
class VisualStudioProvider : public MSVCProvider {
public:
VisualStudioProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version);
VisualStudioProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version, const MSVCVersion& msvc);
protected:
void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir,
@ -46,7 +46,6 @@ protected:
const char *getProjectExtension();
const char *getPropertiesExtension();
int getVisualStudioVersion();
void outputConfiguration(std::ostream &project, const BuildSetup &setup, const std::string &libraries, const std::string &config, const std::string &platform, const std::string &props, const bool isWin32);
void outputConfiguration(const BuildSetup &setup, std::ostream &project, const std::string &toolConfig, const std::string &config, const std::string &platform, const std::string &props);

View file

@ -780,6 +780,7 @@ XcodeProvider::ValueList& XcodeProvider::getResourceFiles() const {
files.push_back("COPYING.LGPL");
files.push_back("COPYING.BSD");
files.push_back("COPYING.FREEFONT");
files.push_back("COPYING.OFL");
files.push_back("NEWS");
files.push_back("README.md");
}
@ -1136,7 +1137,9 @@ void XcodeProvider::setupDefines(const BuildSetup &setup) {
REMOVE_DEFINE(_defines, "IPHONE_IOS7");
REMOVE_DEFINE(_defines, "IPHONE_SANDBOXED");
REMOVE_DEFINE(_defines, "SDL_BACKEND");
ADD_DEFINE(_defines, "USE_TEXT_CONSOLE_FOR_DEBUGGER");
if (!CONTAINS_DEFINE(_defines, "USE_TEXT_CONSOLE_FOR_DEBUGGER")) {
ADD_DEFINE(_defines, "USE_TEXT_CONSOLE_FOR_DEBUGGER");
}
ADD_DEFINE(_defines, "CONFIG_H");
ADD_DEFINE(_defines, "UNIX");
ADD_DEFINE(_defines, "SCUMMVM");

View file

@ -36,11 +36,12 @@ if ($#ARGV >= 0) {
$mode = "CPP" if ($ARGV[0] eq "--cpp"); # credits.h (for use by about.cpp)
$mode = "XML-DOC" if ($ARGV[0] eq "--xml-docbook"); # credits.xml (DocBook)
$mode = "RTF" if ($ARGV[0] eq "--rtf"); # Credits.rtf (Mac OS X About box)
$mode = "STRONGHELP" if ($ARGV[0] eq "--stronghelp"); # AUTHORS (RISC OS StrongHelp manual)
}
if ($mode eq "") {
print STDERR "Usage: $0 [--text | --xml-website | --cpp | --xml-docbook | --rtf]\n";
print STDERR " Just pass --text / --xml-website / --cpp / --xml-docbook / --rtf as parameter, and credits.pl\n";
print STDERR "Usage: $0 [--text | --xml-website | --cpp | --xml-docbook | --rtf | --stronghelp]\n";
print STDERR " Just pass --text / --xml-website / --cpp / --xml-docbook / --rtf / --stronghelp as parameter, and credits.pl\n";
print STDERR " will print out the corresponding version of the credits to stdout.\n";
exit 1;
}
@ -106,6 +107,36 @@ sub html_entities_to_ascii {
return $text;
}
# Convert HTML entities to ISO/IEC 8859-1 for the StrongHelp manual
sub html_entities_to_iso8859_1 {
my $text = shift;
$text =~ s/&aacute;/\xE1/g;
$text =~ s/&eacute;/\xE9/g;
$text =~ s/&iacute;/\xED/g;
$text =~ s/&igrave;/\xEC/g;
$text =~ s/&oacute;/\xF3/g;
$text =~ s/&oslash;/\xF8/g;
$text =~ s/&uacute;/\xFA/g;
$text =~ s/&#261;/a/g;
$text =~ s/&#321;/L/g;
$text =~ s/&#322;/l/g;
$text =~ s/&#347;/s/g;
$text =~ s/&Lcaron;/L/g;
$text =~ s/&Scaron;/S/g;
$text =~ s/&aring;/\xE5/g;
$text =~ s/&ntilde;/\xF1/g;
$text =~ s/&auml;/\xE4/g;
$text =~ s/&euml;/\xEB/g;
$text =~ s/&uuml;/\xFC/g;
$text =~ s/&ouml;/\xF6/g;
$text =~ s/&amp;/&/g;
return $text;
}
# Convert HTML entities to C++ characters
sub html_entities_to_cpp {
my $text = shift;
@ -219,6 +250,9 @@ sub begin_credits {
print "<?xml version='1.0'?>\n";
print "<!-- This file was generated by credits.pl. Do not edit by hand! -->\n";
print "<credits>\n";
} elsif ($mode eq "STRONGHELP") {
print "ScummVM - AUTHORS\n";
print "# This file was generated by credits.pl. Do not edit by hand!\n";
}
}
@ -314,6 +348,9 @@ sub begin_section {
#print "\t\t\t<group>" . $title . "</group>\n";
#print "\t\t\t\t<name>" . $title . "</name>\n";
}
} elsif ($mode eq "STRONGHELP") {
$title = html_entities_to_iso8859_1($title);
print "#fH" . ($section_level + 1) . ":" . $title."\n";
}
# Implicit start of person list on section level 2
@ -369,6 +406,8 @@ sub end_persons {
} elsif ($mode eq "XML-WEB") {
#print "\t\t\t\t</persons>\n";
print "\t\t\t</group>\n";
} elsif ($mode eq "STRONGHELP") {
print "\n";
}
}
@ -443,6 +482,15 @@ sub add_person {
print "\t\t\t\t\t<alias>" . $nick . "</alias>\n";
print "\t\t\t\t\t<description>" . $desc . "</description>\n";
print "\t\t\t\t</person>\n";
} elsif ($mode eq "STRONGHELP") {
my $min_name_width = length $desc > 0 ? $max_name_width : 0;
$name = $nick if $name eq "";
$name = html_entities_to_iso8859_1($name);
$desc = html_entities_to_iso8859_1($desc);
$tab = " " x ($section_level * 2 + 1);
print $tab . "{*}" . $name . "{*}";
print "\t" . $desc . "\n";
}
}
@ -471,6 +519,12 @@ sub add_paragraph {
print " <row><entry namest='start' nameend='job'> </entry></row>\n\n";
} elsif ($mode eq "XML-WEB") {
print "\t\t<paragraph>" . $text . "</paragraph>\n";
} elsif ($mode eq "STRONGHELP") {
$text = html_entities_to_iso8859_1($text);
print "#Wrap On\n";
$tab = " " x ($section_level * 2 + 1);
print $text . "\n";
print "#Wrap\n\n";
}
}

View file

@ -78,7 +78,7 @@ fi
#------------------------------------------------------------------------------
%files
%defattr(0644,root,root,0755)
%doc AUTHORS README.md KNOWN_BUGS NEWS COPYING COPYING.LGPL COPYING.BSD COPYING.FREEFONT COPYING.ISC COPYING.LUA COPYING.TINYGL COPYRIGHT
%doc AUTHORS README.md KNOWN_BUGS NEWS COPYING COPYING.LGPL COPYING.BSD COPYING.FREEFONT COPYING.OFL COPYING.ISC COPYING.LUA COPYING.TINYGL COPYRIGHT
%attr(0755,root,root)%{_bindir}/residualvm
%{_datadir}/applications/*
%{_datadir}/pixmaps/residualvm.xpm

View file

@ -78,7 +78,7 @@ fi
#------------------------------------------------------------------------------
%files
%defattr(0644,root,root,0755)
%doc AUTHORS README.md KNOWN_BUGS NEWS COPYING COPYING.LGPL COPYING.BSD COPYING.FREEFONT COPYING.ISC COPYING.LUA COPYING.TINYGL COPYRIGHT
%doc AUTHORS README.md KNOWN_BUGS NEWS COPYING COPYING.LGPL COPYING.BSD COPYING.FREEFONT COPYING.OFL COPYING.ISC COPYING.LUA COPYING.TINYGL COPYRIGHT
%attr(0755,root,root)%{_bindir}/residualvm
%{_datadir}/applications/*
%{_datadir}/pixmaps/residualvm.xpm

View file

@ -4,6 +4,7 @@
#include "config.h"
#endif
#include "base/internal_plugins.h" // for PLUGIN_ENABLED_STATIC
#include "base/internal_version.h"
#define FILE 256
@ -15,7 +16,7 @@ IDI_COUNT ICON DISCARDABLE "icons/count.ico"
residualvm-grim-patch.lab FILE "dists/engine-data/residualvm-grim-patch.lab"
residualvm-emi-patch.m4b FILE "dists/engine-data/residualvm-emi-patch.m4b"
#if ENABLE_MYST3 == STATIC_PLUGIN
#if PLUGIN_ENABLED_STATIC(MYST3)
myst3.dat FILE "dists/engine-data/myst3.dat"
#endif
modern.zip FILE "gui/themes/modern.zip"
@ -24,7 +25,7 @@ translations.dat FILE "gui/themes/translations.dat"
#endif
#ifdef USE_OPENGL_SHADERS
#if ENABLE_GRIM == STATIC_PLUGIN
#if PLUGIN_ENABLED_STATIC(GRIM)
shaders/dim.fragment FILE "engines/grim/shaders/dim.fragment"
shaders/dim.vertex FILE "engines/grim/shaders/dim.vertex"
shaders/emerg.fragment FILE "engines/grim/shaders/emerg.fragment"
@ -48,7 +49,7 @@ shaders/smush.vertex FILE "engines/grim/shaders/smush.vertex"
shaders/text.fragment FILE "engines/grim/shaders/text.fragment"
shaders/text.vertex FILE "engines/grim/shaders/text.vertex"
#endif
#if ENABLE_MYST3 == STATIC_PLUGIN
#if PLUGIN_ENABLED_STATIC(MYST3)
shaders/myst3_box.fragment FILE "engines/myst3/shaders/myst3_box.fragment"
shaders/myst3_box.vertex FILE "engines/myst3/shaders/myst3_box.vertex"
shaders/myst3_cube.fragment FILE "engines/myst3/shaders/myst3_cube.fragment"
@ -56,7 +57,7 @@ shaders/myst3_cube.vertex FILE "engines/myst3/shaders/myst3_cube.verte
shaders/myst3_text.fragment FILE "engines/myst3/shaders/myst3_text.fragment"
shaders/myst3_text.vertex FILE "engines/myst3/shaders/myst3_text.vertex"
#endif
#if ENABLE_STARK == STATIC_PLUGIN
#if PLUGIN_ENABLED_STATIC(STARK)
shaders/stark_actor.fragment FILE "engines/stark/shaders/stark_actor.fragment"
shaders/stark_actor.vertex FILE "engines/stark/shaders/stark_actor.vertex"
shaders/stark_prop.fragment FILE "engines/stark/shaders/stark_prop.fragment"

View file

@ -29,6 +29,7 @@ Name: {group}\ResidualVM (noconsole); Filename: {app}\residualvm.exe; Parameters
Name: {group}\Authors; Filename: {app}\AUTHORS.txt; WorkingDir: {app}; Comment: AUTHORS; Flags: createonlyiffileexists
Name: {group}\Copying; Filename: {app}\COPYING.txt; WorkingDir: {app}; Comment: COPYING; Flags: createonlyiffileexists
Name: {group}\Copying.FREEFONT; Filename: {app}\COPYING.FREEFONT.txt; WorkingDir: {app}; Comment: COPYING.FREEFONT; Flags: createonlyiffileexists
Name: {group}\Copying.OFL; Filename: {app}\COPYING.OFL.txt; WorkingDir: {app}; Comment: COPYING.OFL; Flags: createonlyiffileexists
Name: {group}\Copying.BSD; Filename: {app}\COPYING.BSD.txt; WorkingDir: {app}; Comment: COPYING.BSD; Flags: createonlyiffileexists
Name: {group}\Copying.LGPL; Filename: {app}\COPYING.LGPL.txt; WorkingDir: {app}; Comment: COPYING.LGPL; Flags: createonlyiffileexists
Name: {group}\Copying.ISC; Filename: {app}\COPYING.ISC.txt; WorkingDir: {app}; Comment: COPYING.ISC; Flags: createonlyiffileexists
@ -59,6 +60,7 @@ Name: "{userappdata}\ResidualVM\Saved Games"; MinVersion: 0, 1
Source: AUTHORS.txt; DestDir: {app}; Flags: ignoreversion
Source: COPYING.txt; DestDir: {app}; Flags: ignoreversion
Source: COPYING.FREEFONT.txt; DestDir: {app}; Flags: ignoreversion
Source: COPYING.OFL.txt; DestDir: {app}; Flags: ignoreversion
Source: COPYING.BSD.txt; DestDir: {app}; Flags: ignoreversion
Source: COPYING.LGPL.txt; DestDir: {app}; Flags: ignoreversion
Source: COPYING.ISC.txt; DestDir: {app}; Flags: ignoreversion

View file

@ -142,7 +142,7 @@ bool DetectionResults::foundUnknownGames() const {
return false;
}
DetectedGames DetectionResults::listRecognizedGames() {
DetectedGames DetectionResults::listRecognizedGames() const {
DetectedGames candidates;
for (uint i = 0; i < _detectedGames.size(); i++) {
if (_detectedGames[i].canBeAdded) {
@ -152,8 +152,16 @@ DetectedGames DetectionResults::listRecognizedGames() {
return candidates;
}
DetectedGames DetectionResults::listDetectedGames() const {
return _detectedGames;
}
Common::String DetectionResults::generateUnknownGameReport(bool translate, uint32 wordwrapAt) const {
assert(!_detectedGames.empty());
return ::generateUnknownGameReport(_detectedGames, translate, false, wordwrapAt);
}
Common::String generateUnknownGameReport(const DetectedGames &detectedGames, bool translate, bool fullPath, uint32 wordwrapAt) {
assert(!detectedGames.empty());
const char *reportStart = _s("The game in '%s' seems to be an unknown game variant.\n\n"
"Please report the following data to the ResidualVM team at %s "
@ -162,7 +170,8 @@ Common::String DetectionResults::generateUnknownGameReport(bool translate, uint3
const char *reportEngineHeader = _s("Matched game IDs for the %s engine:");
Common::String report = Common::String::format(
translate ? _(reportStart) : reportStart, _detectedGames[0].path.c_str(),
translate ? _(reportStart) : reportStart,
fullPath ? detectedGames[0].path.c_str() : detectedGames[0].shortPath.c_str(),
"https://github.com/residualvm/residualvm/issues"
);
report += "\n";
@ -170,8 +179,8 @@ Common::String DetectionResults::generateUnknownGameReport(bool translate, uint3
FilePropertiesMap matchedFiles;
const char *currentEngineName = nullptr;
for (uint i = 0; i < _detectedGames.size(); i++) {
const DetectedGame &game = _detectedGames[i];
for (uint i = 0; i < detectedGames.size(); i++) {
const DetectedGame &game = detectedGames[i];
if (!game.hasUnknownFiles) continue;
@ -214,3 +223,10 @@ Common::String DetectionResults::generateUnknownGameReport(bool translate, uint3
return report;
}
Common::String generateUnknownGameReport(const DetectedGame &detectedGame, bool translate, bool fullPath, uint32 wordwrapAt) {
DetectedGames detectedGames;
detectedGames.push_back(detectedGame);
return generateUnknownGameReport(detectedGames, translate, fullPath, wordwrapAt);
}

View file

@ -26,6 +26,7 @@
#include "common/array.h"
#include "common/hash-str.h"
#include "common/str.h"
#include "common/str-array.h"
#include "common/language.h"
#include "common/platform.h"
@ -141,6 +142,7 @@ struct DetectedGame {
Common::Language language;
Common::Platform platform;
Common::String path;
Common::String shortPath;
Common::String extra;
/**
@ -198,7 +200,15 @@ public:
*
* Recognized games can be added to the configuration manager and then launched.
*/
DetectedGames listRecognizedGames();
DetectedGames listRecognizedGames() const;
/**
* List all the games that were detected
*
* That includes entries that don't have enough information to be added to the
* configuration manager.
*/
DetectedGames listDetectedGames() const;
/**
* Were unknown game variants found by the engines?
@ -208,11 +218,9 @@ public:
bool foundUnknownGames() const;
/**
* Generate a report that we found an unknown game variant, together with the file
* names, sizes and MD5 sums.
* Generate a report that we found an unknown game variant.
*
* @param translate translate the report to the currently active GUI language
* @param wordwrapAt word wrap the text part of the report after a number of characters
* @see ::generateUnknownGameReport
*/
Common::String generateUnknownGameReport(bool translate, uint32 wordwrapAt = 0) const;
@ -220,4 +228,16 @@ private:
DetectedGames _detectedGames;
};
/**
* Generate a report that we found an unknown game variant, together with the file
* names, sizes and MD5 sums.
*
* @param translate translate the report to the currently active GUI language
* @param fullPath include the full path where the files are located, otherwise only the name
* of last component of the path is included
* @param wordwrapAt word wrap the text part of the report after a number of characters
*/
Common::String generateUnknownGameReport(const DetectedGames &detectedGames, bool translate, bool fullPath, uint32 wordwrapAt = 0);
Common::String generateUnknownGameReport(const DetectedGame &detectedGame, bool translate, bool fullPath, uint32 wordwrapAt = 0);
#endif

View file

@ -223,7 +223,7 @@ Graphics::Surface *DialogBox::loadBackground() {
return nullptr;
}
Common::SeekableReadStream *stream = executable.getResource(Common::kPEBitmap, 147);
Common::SeekableReadStream *stream = executable.getResource(Common::kWinBitmap, 147);
if (!stream) {
warning("Unable to find the modal dialog background bitmap in 'game.exe'");
return nullptr;

View file

@ -2352,12 +2352,17 @@ drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, P
// Fill Background
ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y);
i = h;
if (fill) {
assert((_bgColor & ~_alphaMask) == 0); // only support black
// Optimize rendering in case the background color is black
if ((_bgColor & ~_alphaMask) == 0) {
while (i--) {
darkenFill(ptr_left, ptr_left + w);
ptr_left += pitch;
}
} else {
while (i--) {
blendFill(ptr_left, ptr_left + w, _bgColor, 200);
ptr_left += pitch;
}
}
x = MAX(x - bevel, 0);
@ -2409,13 +2414,18 @@ drawBevelSquareAlgClip(int x, int y, int w, int h, int bevel, PixelType top_colo
ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y);
ptr_x = x; ptr_y = y;
i = h;
if (fill) {
assert((_bgColor & ~_alphaMask) == 0); // only support black
// Optimize rendering in case the background color is black
if ((_bgColor & ~_alphaMask) == 0) {
while (i--) {
darkenFillClip(ptr_left, ptr_left + w, ptr_x, ptr_y);
ptr_left += pitch;
++ptr_y;
}
} else {
while (i-- ) {
blendFillClip(ptr_left, ptr_left + w, ptr_x, ptr_y, _bgColor, 200);
ptr_left += pitch;
}
}
x = MAX(x - bevel, 0);

View file

@ -59,8 +59,8 @@ The meaning of these is masks is the following:
To be specific: They pack the masks for two 16 bit pixels at once. The pixels
are split into "high" and "low" bits, which are then separately interpolated
and finally re-composed. That way, 2x2 pixels or even 4x2 pixels can
be interpolated in one go.
be interpolated in one go. They are also included in 888 and 8888 to make
the same functions compatible when interpolating 2 32-bit pixels.
*/
@ -96,6 +96,8 @@ struct ColorMasks<565> {
kLow2Bits = (3 << kRedShift) | (3 << kGreenShift) | (3 << kBlueShift),
kLow3Bits = (7 << kRedShift) | (7 << kGreenShift) | (7 << kBlueShift)
};
typedef uint16 PixelType;
};
template<>
@ -138,6 +140,8 @@ struct ColorMasks<555> {
kLow2Bits = (3 << kRedShift) | (3 << kGreenShift) | (3 << kBlueShift),
kLow3Bits = (7 << kRedShift) | (7 << kGreenShift) | (7 << kBlueShift)
};
typedef uint16 PixelType;
};
template<>
@ -162,6 +166,8 @@ struct ColorMasks<1555> {
kRedBlueMask = kRedMask | kBlueMask
};
typedef uint16 PixelType;
};
template<>
@ -186,6 +192,8 @@ struct ColorMasks<5551> {
kRedBlueMask = kRedMask | kBlueMask
};
typedef uint16 PixelType;
};
template<>
@ -217,6 +225,8 @@ struct ColorMasks<4444> {
kRedBlueMask = kRedMask | kBlueMask
};
typedef uint16 PixelType;
};
template<>
@ -239,8 +249,21 @@ struct ColorMasks<888> {
kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift,
kRedBlueMask = kRedMask | kBlueMask
kRedBlueMask = kRedMask | kBlueMask,
kLowBits = (1 << kRedShift) | (1 << kGreenShift) | (1 << kBlueShift),
kLow2Bits = (3 << kRedShift) | (3 << kGreenShift) | (3 << kBlueShift),
kLow3Bits = (7 << kRedShift) | (7 << kGreenShift) | (7 << kBlueShift),
kLow4Bits = (15 << kRedShift) | (15 << kGreenShift) | (15 << kBlueShift),
kLowBitsMask = kLowBits,
// Prevent mask from including padding byte
kHighBitsMask = (~kLowBits) & (kRedMask | kBlueMask | kGreenMask),
qlowBits = kLow2Bits,
qhighBits = (~kLowBits) & (kRedMask | kBlueMask | kGreenMask)
};
typedef uint32 PixelType;
};
template<>
@ -263,8 +286,20 @@ struct ColorMasks<8888> {
kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift,
kRedBlueMask = kRedMask | kBlueMask
kRedBlueMask = kRedMask | kBlueMask,
kLowBits = (1 << kRedShift) | (1 << kGreenShift) | (1 << kBlueShift) | (1 << kAlphaShift),
kLow2Bits = (3 << kRedShift) | (3 << kGreenShift) | (3 << kBlueShift) | (3 << kAlphaShift),
kLow3Bits = (7 << kRedShift) | (7 << kGreenShift) | (7 << kBlueShift) | (7 << kAlphaShift),
kLow4Bits = (15 << kRedShift) | (15 << kGreenShift) | (15 << kBlueShift) | (15 << kAlphaShift),
kLowBitsMask = kLowBits,
kHighBitsMask = ~kLowBits,
qlowBits = kLow2Bits,
qhighBits = ~kLow2Bits
};
typedef uint32 PixelType;
};
#ifdef __WII__
@ -291,6 +326,8 @@ struct ColorMasks<3444> {
kRedBlueMask = kRedMask | kBlueMask
};
typedef uint16 PixelType;
};
#endif

View file

@ -203,6 +203,9 @@ byte *loadCharacter(Common::SeekableReadStream &stream, int &encoding, int &adva
while (true) {
line = stream.readLine();
line.trim(); // BDF files created from unifont tools (make hex)
// have a rogue space character after the "BITMAP" label
if (stream.err() || stream.eos()) {
warning("BdfFont::loadCharacter: Premature end of file");
delete[] bitmap;
@ -412,7 +415,7 @@ BdfFont *BdfFont::loadFont(Common::SeekableReadStream &stream) {
}
} else if (line.hasPrefix("FAMILY_NAME \"")) {
familyName = new char[line.size()];
Common::strlcpy(familyName, line.c_str() + 13, line.size() - 13);
Common::strlcpy(familyName, line.c_str() + 13, line.size() - 12); // strlcpy() copies at most size-1 characters and then add a '\0'
char *p = &familyName[strlen(familyName)];
while (p != familyName && *p != '"')
p--;
@ -429,7 +432,7 @@ BdfFont *BdfFont::loadFont(Common::SeekableReadStream &stream) {
*p = '\0'; // Remove last quote
} else if (line.hasPrefix("SLANT \"")) {
slant = new char[line.size()];
Common::strlcpy(slant, line.c_str() + 7, line.size() - 7);
Common::strlcpy(slant, line.c_str() + 7, line.size() - 6); // strlcpy() copies at most size-1 characters and then add a '\0'
char *p = &slant[strlen(slant)];
while (p != slant && *p != '"')
p--;

View file

@ -32,6 +32,7 @@
#include "graphics/surface.h"
#include "common/file.h"
#include "common/config-manager.h"
#include "common/singleton.h"
#include "common/stream.h"
#include "common/memstream.h"
@ -686,14 +687,24 @@ Font *loadTTFFont(Common::SeekableReadStream &stream, int size, TTFSizeMode size
}
Font *loadTTFFontFromArchive(const Common::String &filename, int size, TTFSizeMode sizeMode, uint dpi, TTFRenderMode renderMode, const uint32 *mapping) {
Common::Archive *archive;
if (!Common::File::exists("fonts.dat") || (archive = Common::makeZipArchive("fonts.dat")) == nullptr) {
return 0;
Common::SeekableReadStream *archiveStream = nullptr;
if (ConfMan.hasKey("extrapath")) {
Common::FSDirectory extrapath(ConfMan.get("extrapath"));
archiveStream = extrapath.createReadStreamForMember("fonts.dat");
}
if (!archiveStream) {
archiveStream = SearchMan.createReadStreamForMember("fonts.dat");
}
Common::Archive *archive = Common::makeZipArchive(archiveStream);
if (!archive) {
return nullptr;
}
Common::File f;
if (!f.open(filename, *archive)) {
return 0;
return nullptr;
}
Font *font = loadTTFFont(f, size, sizeMode, dpi, renderMode, false, mapping);

View file

@ -92,7 +92,7 @@ bool WinFont::loadFromNE(const Common::String &fileName, const WinFontDirEntry &
return false;
// Let's pull out the font directory
Common::SeekableReadStream *fontDirectory = exe.getResource(Common::kNEFontDir, Common::String("FONTDIR"));
Common::SeekableReadStream *fontDirectory = exe.getResource(Common::kWinFontDir, Common::String("FONTDIR"));
if (!fontDirectory) {
warning("No font directory in '%s'", fileName.c_str());
return false;
@ -109,7 +109,7 @@ bool WinFont::loadFromNE(const Common::String &fileName, const WinFontDirEntry &
}
// Actually go get our font now...
Common::SeekableReadStream *fontStream = exe.getResource(Common::kNEFont, fontId);
Common::SeekableReadStream *fontStream = exe.getResource(Common::kWinFont, fontId);
if (!fontStream) {
warning("Could not find font %d in %s", fontId, fileName.c_str());
return false;
@ -129,7 +129,7 @@ bool WinFont::loadFromPE(const Common::String &fileName, const WinFontDirEntry &
}
// Let's pull out the font directory
Common::SeekableReadStream *fontDirectory = exe->getResource(Common::kPEFontDir, Common::String("FONTDIR"));
Common::SeekableReadStream *fontDirectory = exe->getResource(Common::kWinFontDir, Common::String("FONTDIR"));
if (!fontDirectory) {
warning("No font directory in '%s'", fileName.c_str());
delete exe;
@ -148,7 +148,7 @@ bool WinFont::loadFromPE(const Common::String &fileName, const WinFontDirEntry &
}
// Actually go get our font now...
Common::SeekableReadStream *fontStream = exe->getResource(Common::kPEFont, fontId);
Common::SeekableReadStream *fontStream = exe->getResource(Common::kWinFont, fontId);
if (!fontStream) {
warning("Could not find font %d in %s", fontId, fileName.c_str());
delete exe;

View file

@ -124,6 +124,17 @@ void ManagedSurface::free() {
_offsetFromOwner = Common::Point(0, 0);
}
void ManagedSurface::copyFrom(const ManagedSurface &surf) {
// Surface::copyFrom free pixel pointer so let's free up ManagedSurface to be coherent
free();
_innerSurface.copyFrom(surf._innerSurface);
markAllDirty();
// Pixels data is now owned by us
_disposeAfterUse = DisposeAfterUse::YES;
}
bool ManagedSurface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) {
if (destBounds.left >= this->w || destBounds.top >= this->h ||
destBounds.right <= 0 || destBounds.bottom <= 0)

View file

@ -307,17 +307,14 @@ public:
* Copy the data from another Surface, reinitializing the
* surface to match the dimensions of the passed surface
*/
void copyFrom(const ManagedSurface &surf) {
clearDirtyRects();
_innerSurface.copyFrom(surf._innerSurface);
}
void copyFrom(const ManagedSurface &surf);
/**
* Draw a line.
*/
void drawLine(int x0, int y0, int x1, int y1, uint32 color) {
_innerSurface.drawLine(x0, y0, x1, y1, color);
addDirtyRect(Common::Rect(x0, y0, x1, y1));
addDirtyRect(Common::Rect(MIN(x0, x1), MIN(y0, y1), MAX(x0, x1), MAX(y0, y1)));
}
/**
@ -325,7 +322,7 @@ public:
*/
void drawThickLine(int x0, int y0, int x1, int y1, int penX, int penY, uint32 color) {
_innerSurface.drawThickLine(x0, y0, x1, y1, penX, penY, color);
addDirtyRect(Common::Rect(x0, y0, x1 + penX, y1 + penY));
addDirtyRect(Common::Rect(MIN(x0, x1 + penX), MIN(y0, y1 + penY), MAX(x0, x1 + penX), MAX(y0, y1 + penY)));
}
/**

View file

@ -31,9 +31,15 @@
* Interpolate two 16 bit pixel *pairs* at once with equal weights 1.
* In particular, p1 and p2 can contain two pixels each in the upper
* and lower halves.
*
* This also works for 32 bit pixels.
*/
template<typename ColorMask>
static inline uint32 interpolate32_1_1(uint32 p1, uint32 p2) {
// Clear the low bit of each channel,
// divide each channel by 2,
// add the two pixels together,
// add 1 to each channel if the lowbits would have added to 2
return (((p1 & ColorMask::kHighBitsMask) >> 1) +
((p2 & ColorMask::kHighBitsMask) >> 1) +
(p1 & p2 & ColorMask::kLowBitsMask));
@ -43,16 +49,266 @@ static inline uint32 interpolate32_1_1(uint32 p1, uint32 p2) {
* Interpolate two 16 bit pixel *pairs* at once with weights 3 resp. 1.
* In particular, p1 and p2 can contain two pixels/each in the upper
* and lower halves.
*
* This also works for 32 bit pixels.
*/
template<typename ColorMask>
static inline uint32 interpolate32_3_1(uint32 p1, uint32 p2) {
// Clear the 2 lowest bits of each channel,
// divide each channel by 4, multiply p1 by 3
// add the two pixels together,
uint32 x = ((p1 & ColorMask::qhighBits) >> 2) * 3 + ((p2 & ColorMask::qhighBits) >> 2);
// Get 2 lowest bits of each channel,
// multiply p1 by 3, add them together, then divide by 4
uint32 y = ((p1 & ColorMask::qlowBits) * 3 + (p2 & ColorMask::qlowBits)) >> 2;
// Use only the low bits of the second result to add to the first result
y &= ColorMask::qlowBits;
return x + y;
}
/**
* Interpolate two 32 bit pixels with weights 2 and 1 and 1, i.e., (2*p1+p2)/3.
*/
template<typename ColorMask>
uint32 interpolate32_2_1(uint32 pixel1, uint32 pixel2) {
uint32 rsum, gsum, bsum, asum;
rsum = ((pixel1 & ColorMask::kRedMask) >> ColorMask::kRedShift) << 1;
rsum += ((pixel2 & ColorMask::kRedMask) >> ColorMask::kRedShift);
rsum /= 3;
rsum <<= ColorMask::kRedShift;
gsum = ((pixel1 & ColorMask::kGreenMask) >> ColorMask::kGreenShift) << 1;
gsum += ((pixel2 & ColorMask::kGreenMask) >> ColorMask::kGreenShift);
gsum /= 3;
gsum <<= ColorMask::kGreenShift;
bsum = ((pixel1 & ColorMask::kBlueMask) >> ColorMask::kBlueShift) << 1;
bsum += ((pixel2 & ColorMask::kBlueMask) >> ColorMask::kBlueShift);
bsum /= 3;
bsum <<= ColorMask::kBlueShift;
asum = ((pixel1 & ColorMask::kAlphaMask) >> ColorMask::kAlphaShift) << 1;
asum += ((pixel2 & ColorMask::kAlphaMask) >> ColorMask::kAlphaShift);
asum /= 3;
asum <<= ColorMask::kAlphaShift;
return (rsum & ColorMask::kRedMask) | (gsum & ColorMask::kGreenMask) | (bsum & ColorMask::kBlueMask) | (asum & ColorMask::kAlphaMask);
}
/**
* Interpolate two 32 bit pixels with weights 5 and 3 and 1, i.e., (5*p1+3*p2)/8.
* @see interpolate_32_3_1 for similar method
*/
template<typename ColorMask>
static inline uint32 interpolate32_5_3(uint32 p1, uint32 p2) {
uint32 x = ((p1 & ~ColorMask::kLow3Bits) >> 3) * 5 + ((p2 & ~ColorMask::kLow3Bits) >> 3) * 3;
uint32 y = ((p1 & ColorMask::kLow3Bits) * 5 + (p2 & ColorMask::kLow3Bits) * 3) >> 3;
y &= ColorMask::kLow3Bits;
return x + y;
}
/**
* Interpolate two 32 bit pixels with weights 7 and 1, i.e., (7*p1+p2)/8.
*
* @see interpolate32_3_1 for similar method
*/
template<typename ColorMask>
static inline uint32 interpolate32_7_1(uint32 p1, uint32 p2) {
uint32 x = ((p1 & ~ColorMask::kLow3Bits) >> 3) * 7 + ((p2 & ~ColorMask::kLow3Bits) >> 3);
uint32 y = ((p1 & ColorMask::kLow3Bits) * 7 + (p2 & ColorMask::kLow3Bits)) >> 3;
y &= ColorMask::kLow3Bits;
return x + y;
}
/**
* Interpolate three 32 bit pixels with weights 2, 1, and 1, i.e., (2*p1+p2+p3)/4.
*
* @see interpolate32_3_1 for similar method
*/
template<typename ColorMask>
static inline uint32 interpolate32_2_1_1(uint32 p1, uint32 p2, uint32 p3) {
uint32 x = ((p1 & ColorMask::qhighBits) >> 1)
+ ((p2 & ColorMask::qhighBits) >> 2)
+ ((p3 & ColorMask::qhighBits) >> 2);
uint32 y = ((p1 & ColorMask::qlowBits) << 1)
+ (p2 & ColorMask::qlowBits)
+ (p2 & ColorMask::qlowBits);
y >>= 2;
y &= ColorMask::qlowBits;
return x + y;
}
/**
* Interpolate three 32 bit pixels with weights 5, 2, and 1, i.e., (5*p1+2*p2+p3)/8.
*
* @see interpolate32_3_1 for similar method
*/
template<typename ColorMask>
static inline uint32 interpolate32_5_2_1(uint32 p1, uint32 p2, uint32 p3) {
uint32 x = ((p1 & ~ColorMask::kLow3Bits) >> 3) * 5
+ ((p2 & ~ColorMask::kLow3Bits) >> 3) * 2
+ ((p3 & ~ColorMask::kLow3Bits) >> 3);
uint32 y = (p1 & ColorMask::kLow3Bits) * 5
+ (p2 & ColorMask::kLow3Bits) * 2
+ (p2 & ColorMask::kLow3Bits);
y >>= 3;
y &= ColorMask::kLow3Bits;
return x + y;
}
/**
* Interpolate three 32 bit pixels with weights 6, 1, and 1, i.e., (6*p1+p2+p3)/8.
*
* @see interpolate32_3_1 for similar method
*/
template<typename ColorMask>
static inline uint32 interpolate32_6_1_1(uint32 p1, uint32 p2, uint32 p3) {
uint32 x = ((p1 & ~ColorMask::kLow3Bits) >> 3) * 6
+ ((p2 & ~ColorMask::kLow3Bits) >> 3)
+ ((p3 & ~ColorMask::kLow3Bits) >> 3);
uint32 y = (p1 & ColorMask::kLow3Bits) * 6
+ (p2 & ColorMask::kLow3Bits)
+ (p2 & ColorMask::kLow3Bits);
y >>= 3;
y &= ColorMask::kLow3Bits;
return x + y;
}
/**
* Interpolate three 32 bit pixels with weights 2, 3, and 3, i.e., (2*p1+3*(p2+p3))/8.
*
* @see interpolate32_3_1 for similar method
*/
template<typename ColorMask>
static inline uint32 interpolate32_2_3_3(uint32 p1, uint32 p2, uint32 p3) {
uint32 x = ((p1 & ~ColorMask::kLow3Bits) >> 2)
+ (((p2 & ~ColorMask::kLow3Bits) >> 3)
+ ((p3 & ~ColorMask::kLow3Bits) >> 3)) * 3;
uint32 y = (p1 & ColorMask::kLow3Bits) * 2
+ ((p2 & ColorMask::kLow3Bits)
+ (p2 & ColorMask::kLow3Bits)) * 3;
y >>= 3;
y &= ColorMask::kLow3Bits;
return x + y;
}
/**
* Interpolate three 32 bit pixels with weights 2, 7, and 7, i.e., (2*p1+7*(p2+p3))/16.
*
* @see interpolate32_3_1 for similar method
*/
template<typename ColorMask>
inline uint32 interpolate32_2_7_7(uint32 p1, uint32 p2, uint32 p3) {
uint32 x = ((p1 & ~ColorMask::kLow4Bits) >> 3)
+ (((p2 & ~ColorMask::kLow4Bits) >> 4)
+ ((p3 & ~ColorMask::kLow4Bits) >> 4)) * 7;
uint32 y = (p1 & ColorMask::kLow4Bits) * 2
+ ((p2 & ColorMask::kLow4Bits)
+ (p2 & ColorMask::kLow4Bits)) * 7;
y >>= 4;
y &= ColorMask::kLow4Bits;
return x + y;
}
// Dummy specializations.
template<>
inline uint32 interpolate32_2_7_7<Graphics::ColorMasks<555> >(uint32 p1, uint32 p2, uint32 p3) {
assert(0);
return 0;
}
template<>
inline uint32 interpolate32_2_7_7<Graphics::ColorMasks<565> >(uint32 p1, uint32 p2, uint32 p3) {
assert(0);
return 0;
}
/**
* Interpolate three 32 bit pixels with weights 14, 1, and 1, i.e., (14*p1+p2+p3)/16.
*
* @see interpolate32_3_1 for similar method
*/
template<typename ColorMask>
inline uint32 interpolate32_14_1_1(uint32 p1, uint32 p2, uint32 p3) {
uint32 x = ((p1 & ~ColorMask::kLow4Bits) >> 4) * 14
+ ((p2 & ~ColorMask::kLow4Bits) >> 4)
+ ((p3 & ~ColorMask::kLow4Bits) >> 4);
uint32 y = (p1 & ColorMask::kLow4Bits) * 14
+ (p2 & ColorMask::kLow4Bits)
+ (p2 & ColorMask::kLow4Bits);
y >>= 4;
y &= ColorMask::kLow4Bits;
return x + y;
}
// Dummy specializations.
template<>
inline uint32 interpolate32_14_1_1<Graphics::ColorMasks<555> >(uint32 p1, uint32 p2, uint32 p3) {
assert(0);
return 0;
}
template<>
inline uint32 interpolate32_14_1_1<Graphics::ColorMasks<565> >(uint32 p1, uint32 p2, uint32 p3) {
assert(0);
return 0;
}
/**
* Interpolate three 32 bit pixels with weights 1, 1, and 1, i.e., (p1+p2+p3)/3.
*/
template<typename ColorMask>
uint32 interpolate32_1_1_1(uint32 pixel1, uint32 pixel2, uint32 pixel3) {
uint32 rsum, gsum, bsum;
rsum = ((pixel1 & ColorMask::kRedMask) >> ColorMask::kRedShift);
rsum += ((pixel2 & ColorMask::kRedMask) >> ColorMask::kRedShift);
rsum += ((pixel3 & ColorMask::kRedMask) >> ColorMask::kRedShift);
rsum /= 3;
rsum <<= ColorMask::kRedShift;
gsum = ((pixel1 & ColorMask::kGreenMask) >> ColorMask::kGreenShift);
gsum += ((pixel2 & ColorMask::kGreenMask) >> ColorMask::kGreenShift);
gsum += ((pixel3 & ColorMask::kGreenMask) >> ColorMask::kGreenShift);
gsum /= 3;
gsum <<= ColorMask::kGreenShift;
bsum = ((pixel1 & ColorMask::kBlueMask) >> ColorMask::kBlueShift);
bsum += ((pixel2 & ColorMask::kBlueMask) >> ColorMask::kBlueShift);
bsum += ((pixel3 & ColorMask::kBlueMask) >> ColorMask::kBlueShift);
bsum /= 3;
bsum <<= ColorMask::kBlueShift;
return (rsum & ColorMask::kRedMask) | (gsum & ColorMask::kGreenMask) | (bsum & ColorMask::kBlueMask);
}
/**
* Interpolate four 32 bit pixels with weights 1, 1, 1, and 1, i.e., (p1+p2+p3+p4)/4.
*
* @see interpolate32_3_1 for similar method
*/
template<typename ColorMask>
static inline uint32 interpolate32_1_1_1_1(uint32 p1, uint32 p2, uint32 p3, uint32 p4) {
uint32 x = ((p1 & ~ColorMask::kLow2Bits) >> 2)
+ ((p2 & ~ColorMask::kLow2Bits) >> 2)
+ ((p3 & ~ColorMask::kLow2Bits) >> 2)
+ ((p4 & ~ColorMask::kLow2Bits) >> 2);
uint32 y = (p1 & ColorMask::kLow2Bits)
+ (p2 & ColorMask::kLow2Bits)
+ (p3 & ColorMask::kLow2Bits)
+ (p4 & ColorMask::kLow2Bits);
y >>= 2;
y &= ColorMask::kLow2Bits;
return x + y;
}
/**
* Interpolate two 16 bit pixels with weights 1 and 1, i.e., (p1+p2)/2.
* See <http://www.slack.net/~ant/info/rgb_mixing.html> for details on how this works.
@ -73,6 +329,29 @@ static inline unsigned interpolate16_3_1(unsigned p1, unsigned p2) {
return ((p1*3 + p2) - lowbits) >> 2;
}
/**
* Interpolate two 16 bit pixels with weights 2 and 1, i.e., (2*p1+p2)/3.
*/
template<typename ColorMask>
uint16 interpolate16_2_1(uint16 pixel1, uint16 pixel2) {
uint32 rsum;
uint16 gsum, bsum;
rsum = (pixel1 & ColorMask::kRedMask) << 1;
rsum += (pixel2 & ColorMask::kRedMask);
rsum /= 3;
gsum = (pixel1 & ColorMask::kGreenMask) << 1;
gsum += (pixel2 & ColorMask::kGreenMask);
gsum /= 3;
bsum = (pixel1 & ColorMask::kBlueMask) << 1;
bsum += (pixel2 & ColorMask::kBlueMask);
bsum /= 3;
return (rsum & ColorMask::kRedMask) | (gsum & ColorMask::kGreenMask) | (bsum & ColorMask::kBlueMask);
}
/**
* Interpolate two 16 bit pixels with weights 5 and 3 and 1, i.e., (5*p1+3*p2)/8.
*/
@ -167,6 +446,33 @@ static inline unsigned interpolate16_14_1_1(unsigned p1, unsigned p2, unsigned p
return ((rb&(ColorMask::kRedBlueMask<<4)) | (g&(ColorMask::kGreenMask<<4))) >> 4;
}
/**
* Interpolate three 16 bit pixels with weights 1, 1, and 1, i.e., (p1+p2+p3)/3.
*/
template<typename ColorMask>
uint16 interpolate16_1_1_1(uint16 pixel1, uint16 pixel2, uint16 pixel3)
{
uint32 rsum;
uint16 gsum, bsum;
rsum = (pixel1 & ColorMask::kRedMask);
rsum += (pixel2 & ColorMask::kRedMask);
rsum += (pixel3 & ColorMask::kRedMask);
rsum /= 3;
gsum = (pixel1 & ColorMask::kGreenMask);
gsum += (pixel2 & ColorMask::kGreenMask);
gsum += (pixel3 & ColorMask::kGreenMask);
gsum /= 3;
bsum = (pixel1 & ColorMask::kBlueMask);
bsum += (pixel2 & ColorMask::kBlueMask);
bsum += (pixel3 & ColorMask::kBlueMask);
bsum /= 3;
return (rsum & ColorMask::kRedMask) | (gsum & ColorMask::kGreenMask) | (bsum & ColorMask::kBlueMask);
}
/**
* Interpolate four 16 bit pixels with weights 1, 1, 1, and 1, i.e., (p1+p2+p3+p4)/4.
*/

View file

@ -434,8 +434,8 @@ Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte *
if (format.bytesPerPixel == 0 || format.bytesPerPixel > 4)
error("Surface::convertTo(): Can only convert from 1Bpp, 2Bpp, 3Bpp, and 4Bpp");
if (dstFormat.bytesPerPixel != 2 && dstFormat.bytesPerPixel != 4)
error("Surface::convertTo(): Can only convert to 2Bpp and 4Bpp");
if (dstFormat.bytesPerPixel < 2 || dstFormat.bytesPerPixel > 4)
error("Surface::convertTo(): Can only convert to 2Bpp, 3Bpp and 4Bpp");
surface->create(w, h, dstFormat);
@ -457,6 +457,8 @@ Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte *
if (dstFormat.bytesPerPixel == 2)
*((uint16 *)dstRow) = color;
else if (dstFormat.bytesPerPixel == 3)
WRITE_UINT24(dstRow, color);
else
*((uint32 *)dstRow) = color;
@ -487,6 +489,8 @@ Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte *
if (dstFormat.bytesPerPixel == 2)
*((uint16 *)dstRow) = color;
else if (dstFormat.bytesPerPixel == 3)
WRITE_UINT24(dstRow, color);
else
*((uint32 *)dstRow) = color;

View file

@ -177,14 +177,17 @@ void doBlitAlphaBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32
for (uint32 j = 0; j < width; j++) {
uint32 ina = in[kAIndex] * ca >> 8;
out[kAIndex] = 255;
out[kBIndex] = (out[kBIndex] * (255 - ina) >> 8);
out[kGIndex] = (out[kGIndex] * (255 - ina) >> 8);
out[kRIndex] = (out[kRIndex] * (255 - ina) >> 8);
out[kBIndex] = out[kBIndex] + (in[kBIndex] * ina * cb >> 16);
out[kGIndex] = out[kGIndex] + (in[kGIndex] * ina * cg >> 16);
out[kRIndex] = out[kRIndex] + (in[kRIndex] * ina * cr >> 16);
if (ina != 0) {
out[kAIndex] = 255;
out[kBIndex] = (out[kBIndex] * (255 - ina) >> 8);
out[kGIndex] = (out[kGIndex] * (255 - ina) >> 8);
out[kRIndex] = (out[kRIndex] * (255 - ina) >> 8);
out[kBIndex] = out[kBIndex] + (in[kBIndex] * ina * cb >> 16);
out[kGIndex] = out[kGIndex] + (in[kGIndex] * ina * cg >> 16);
out[kRIndex] = out[kRIndex] + (in[kRIndex] * ina * cr >> 16);
}
in += inStep;
out += 4;

View file

@ -243,7 +243,7 @@ WinCursorGroup::~WinCursorGroup() {
}
WinCursorGroup *WinCursorGroup::createCursorGroup(Common::NEResources &exe, const Common::WinResourceID &id) {
Common::ScopedPtr<Common::SeekableReadStream> stream(exe.getResource(Common::kNEGroupCursor, id));
Common::ScopedPtr<Common::SeekableReadStream> stream(exe.getResource(Common::kWinGroupCursor, id));
if (!stream || stream->size() <= 6)
return 0;
@ -276,7 +276,7 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::NEResources &exe, cons
stream->readUint32LE(); // data size
uint32 cursorId = stream->readUint32LE();
Common::ScopedPtr<Common::SeekableReadStream> cursorStream(exe.getResource(Common::kNECursor, cursorId));
Common::ScopedPtr<Common::SeekableReadStream> cursorStream(exe.getResource(Common::kWinCursor, cursorId));
if (!cursorStream) {
delete group;
return 0;
@ -299,7 +299,7 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::NEResources &exe, cons
}
WinCursorGroup *WinCursorGroup::createCursorGroup(Common::PEResources &exe, const Common::WinResourceID &id) {
Common::ScopedPtr<Common::SeekableReadStream> stream(exe.getResource(Common::kPEGroupCursor, id));
Common::ScopedPtr<Common::SeekableReadStream> stream(exe.getResource(Common::kWinGroupCursor, id));
if (!stream || stream->size() <= 6)
return 0;
@ -325,7 +325,7 @@ WinCursorGroup *WinCursorGroup::createCursorGroup(Common::PEResources &exe, cons
stream->readUint32LE(); // data size
uint32 cursorId = stream->readUint16LE();
Common::ScopedPtr<Common::SeekableReadStream> cursorStream(exe.getResource(Common::kPECursor, cursorId));
Common::ScopedPtr<Common::SeekableReadStream> cursorStream(exe.getResource(Common::kWinCursor, cursorId));
if (!cursorStream) {
delete group;
return 0;

Some files were not shown because too many files have changed in this diff Show more