Manually rebased over latest mkxp commit. Some features, such as lighting, are not reimplemented yet.
This commit is contained in:
parent
5a7480a406
commit
3b64e7871b
|
@ -1,18 +1,13 @@
|
|||
*.o
|
||||
*.pro.*
|
||||
*.bak
|
||||
*.vert.xxd
|
||||
*.frag.xxd
|
||||
*.ttf.xxd
|
||||
*.xxd
|
||||
|
||||
Makefile
|
||||
Makefile*
|
||||
|
||||
mkxp
|
||||
xxd+
|
||||
Game
|
||||
Game.exe
|
||||
qmake-win.sh
|
||||
|
||||
/build
|
||||
|
||||
# Codeblocks
|
||||
mkxp.layout
|
||||
mkxp.cbp
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/icon.png
BIN
assets/icon.png
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 616 B |
|
@ -0,0 +1,11 @@
|
|||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32"
|
||||
name="System"
|
||||
version="1.0.0.0"
|
||||
language="*"
|
||||
processorArchitecture="x86" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
|
@ -0,0 +1,3 @@
|
|||
#include <winuser.h>
|
||||
1 RT_MANIFEST "assets/manifest.xml"
|
||||
MAINICON ICON "assets/icon.ico"
|
|
@ -75,6 +75,8 @@ void graphicsBindingInit();
|
|||
|
||||
void fileIntBindingInit();
|
||||
|
||||
void oneshotBindingInit();
|
||||
|
||||
RB_METHOD(mriPrint);
|
||||
RB_METHOD(mriP);
|
||||
RB_METHOD(mkxpDataDirectory);
|
||||
|
@ -111,6 +113,7 @@ static void mriBindingInit()
|
|||
graphicsBindingInit();
|
||||
|
||||
fileIntBindingInit();
|
||||
oneshotBindingInit();
|
||||
|
||||
if (rgssVer >= 3)
|
||||
{
|
||||
|
@ -151,7 +154,11 @@ static void mriBindingInit()
|
|||
static void
|
||||
showMsg(const std::string &msg)
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
shState->eThread().showMessageBox(msg.c_str());
|
||||
#else
|
||||
Debug() << msg.c_str();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printP(int argc, VALUE *argv,
|
||||
|
@ -193,7 +200,7 @@ RB_METHOD(mriP)
|
|||
RB_METHOD(mkxpDataDirectory)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
|
||||
const std::string &path = shState->config().customDataPath;
|
||||
const char *s = path.empty() ? "." : path.c_str();
|
||||
|
||||
|
@ -473,10 +480,7 @@ static void runRMXPScripts(BacktraceData &btData)
|
|||
char buf[512];
|
||||
int len;
|
||||
|
||||
if (conf.useScriptNames)
|
||||
len = snprintf(buf, sizeof(buf), "%03ld:%s", i, scriptName);
|
||||
else
|
||||
len = snprintf(buf, sizeof(buf), SCRIPT_SECTION_FMT, i);
|
||||
len = snprintf(buf, sizeof(buf), "%03ld:%s", i, scriptName);
|
||||
|
||||
fname = newStringUTF8(buf, len);
|
||||
btData.scriptNames.insert(buf, scriptName);
|
||||
|
@ -588,11 +592,7 @@ static void mriBindingExecute()
|
|||
|
||||
mriBindingInit();
|
||||
|
||||
std::string &customScript = conf.customScript;
|
||||
if (!customScript.empty())
|
||||
runCustomScript(customScript);
|
||||
else
|
||||
runRMXPScripts(btData);
|
||||
runRMXPScripts(btData);
|
||||
|
||||
VALUE exc = rb_errinfo();
|
||||
if (!NIL_P(exc) && !rb_obj_is_kind_of(exc, rb_eSystemExit))
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#include "oneshot.h"
|
||||
#include "etc.h"
|
||||
#include "sharedstate.h"
|
||||
#include "binding-util.h"
|
||||
#include "binding-types.h"
|
||||
|
||||
RB_METHOD(oneshotSetYesNo)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
const char *yes;
|
||||
const char *no;
|
||||
rb_get_args(argc, argv, "zz", &yes, &no RB_ARG_END);
|
||||
shState->oneshot().setYesNo(yes, no);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
RB_METHOD(oneshotMsgBox)
|
||||
{
|
||||
RB_UNUSED_PARAM;
|
||||
|
||||
int type;
|
||||
const char *body;
|
||||
const char *title = 0;
|
||||
rb_get_args(argc, argv, "iz|z", &type, &body, &title RB_ARG_END);
|
||||
return rb_bool_new(shState->oneshot().msgbox(type, body, title));
|
||||
}
|
||||
|
||||
void oneshotBindingInit()
|
||||
{
|
||||
VALUE module = rb_define_module("Oneshot");
|
||||
VALUE msg = rb_define_module_under(module, "Msg");
|
||||
|
||||
//Constants
|
||||
rb_const_set(module, rb_intern("USER_NAME"), rb_str_new2(shState->oneshot().userName().c_str()));
|
||||
rb_const_set(module, rb_intern("SAVE_PATH"), rb_str_new2(shState->oneshot().savePath().c_str()));
|
||||
rb_const_set(module, rb_intern("LANG"), ID2SYM(rb_intern(shState->oneshot().lang().c_str())));
|
||||
rb_const_set(msg, rb_intern("INFO"), INT2FIX(Oneshot::MSG_INFO));
|
||||
rb_const_set(msg, rb_intern("YESNO"), INT2FIX(Oneshot::MSG_YESNO));
|
||||
rb_const_set(msg, rb_intern("WARN"), INT2FIX(Oneshot::MSG_WARN));
|
||||
rb_const_set(msg, rb_intern("ERR"), INT2FIX(Oneshot::MSG_ERR));
|
||||
|
||||
//Functions
|
||||
_rb_define_module_function(module, "set_yes_no", oneshotSetYesNo);
|
||||
_rb_define_module_function(module, "msgbox", oneshotMsgBox);
|
||||
}
|
|
@ -2,24 +2,14 @@
|
|||
#
|
||||
# About filesystem paths specified in this config:
|
||||
# The "gameFolder" path is resolved either relative
|
||||
# to the directory containing the mkxp executable
|
||||
# to the directory containing the Oneshot executable
|
||||
# (the default behavior), or relative to the current
|
||||
# working directory (when compiled with
|
||||
# working directory (when compiled with
|
||||
# -DWORKDIR_CURRENT). All other paths are resolved
|
||||
# relative to gameFolder and ignoring both RTPs and
|
||||
# encrypted archives.
|
||||
|
||||
|
||||
# Specify the RGSS version to run under.
|
||||
# Possible values are 0, 1, 2, 3. If set to 0,
|
||||
# mkxp will try to guess the required version
|
||||
# based on the game files found in gameFolder.
|
||||
# If this fails, the version defaults to 1.
|
||||
# (default: 0)
|
||||
#
|
||||
# rgssVersion=1
|
||||
|
||||
|
||||
# Create a debug context and log
|
||||
# OpenGL debug information to the console
|
||||
# (default: disabled)
|
||||
|
@ -36,9 +26,9 @@
|
|||
|
||||
|
||||
# Game window is resizable
|
||||
# (default: disabled)
|
||||
# (default: enabled)
|
||||
#
|
||||
# winResizable=false
|
||||
# winResizable=true
|
||||
|
||||
|
||||
# Start game in fullscreen (this can
|
||||
|
@ -57,9 +47,9 @@
|
|||
|
||||
# Apply linear interpolation when game screen
|
||||
# is upscaled
|
||||
# (default: enabled)
|
||||
# (default: disabled)
|
||||
#
|
||||
# smoothScaling=true
|
||||
# smoothScaling=false
|
||||
|
||||
|
||||
# Sync screen redraws to the monitor refresh rate
|
||||
|
@ -133,14 +123,14 @@
|
|||
# Use either right or left Alt + Enter to toggle
|
||||
# fullscreen
|
||||
# (default: disabled)
|
||||
#
|
||||
#
|
||||
# anyAltToggleFS=false
|
||||
|
||||
|
||||
# Enable F12 game reset
|
||||
# (default: enabled)
|
||||
# (default: disabled)
|
||||
#
|
||||
# enableReset=true
|
||||
# enableReset=false
|
||||
|
||||
|
||||
# Allow symlinks for game assets to be followed
|
||||
|
@ -168,13 +158,6 @@
|
|||
# iconPath=/path/to/icon.png
|
||||
|
||||
|
||||
# Instead of playing an RPG Maker game,
|
||||
# execute a single plain text script instead
|
||||
# (default: none)
|
||||
#
|
||||
# customScript=/path/to/script.rb
|
||||
|
||||
|
||||
# Define raw scripts to be executed before the
|
||||
# actual Scripts.rxdata execution starts
|
||||
# (default: none)
|
||||
|
@ -199,12 +182,6 @@
|
|||
# RTP=/path/to/game.rgssad
|
||||
|
||||
|
||||
# Use the script's name as filename in warnings and error messages
|
||||
# (default: disabled)
|
||||
#
|
||||
# useScriptNames=false
|
||||
|
||||
|
||||
# Font substitutions allow drop-in replacements of fonts
|
||||
# to be used without changing the RGSS scripts,
|
||||
# eg. providing 'Open Sans' when the game thinkgs it's
|
||||
|
@ -254,25 +231,3 @@
|
|||
# this number. Maximum: 64.
|
||||
#
|
||||
# SE.sourceCount=6
|
||||
|
||||
|
||||
# The Windows game executable name minus ".exe". By default
|
||||
# this is "Game", but some developers manually rename it.
|
||||
# mkxp needs this name because both the .ini (game
|
||||
# configuration) and .rgssad (encrypted data archive) must
|
||||
# carry the same name minus their extension, and we cannot
|
||||
# guess the executable's name.
|
||||
# You could just as well rename them both to "Game.ini" and
|
||||
# "Game.rgssad", but specifying the executable name here
|
||||
# is a tiny bit less intrusive.
|
||||
#
|
||||
# execName=Game
|
||||
|
||||
|
||||
# Give a hint on which language the game title as
|
||||
# specified in the Game.ini is, useful if the encoding
|
||||
# is being falsely detected. Relevant only if mkxp was
|
||||
# built with automatic encoding conversion (INI_ENCODING).
|
||||
# (default: none)
|
||||
#
|
||||
# titleLanguage=japanese
|
||||
|
|
50
mkxp.pro
50
mkxp.pro
|
@ -2,12 +2,14 @@
|
|||
|
||||
TEMPLATE = app
|
||||
QT =
|
||||
TARGET = mkxp
|
||||
TARGET = Game
|
||||
DEPENDPATH += src shader assets
|
||||
INCLUDEPATH += . src
|
||||
|
||||
CONFIG(release, debug|release): DEFINES += NDEBUG
|
||||
|
||||
CONFIG -= INI_ENCODING
|
||||
|
||||
isEmpty(BINDING) {
|
||||
BINDING = MRI
|
||||
}
|
||||
|
@ -43,6 +45,7 @@ unix {
|
|||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG += sigc++-2.0 pixman-1 zlib physfs vorbisfile \
|
||||
sdl2 SDL2_image SDL2_ttf SDL_sound openal
|
||||
LIBS += -ldl
|
||||
|
||||
SHARED_FLUID {
|
||||
PKGCONFIG += fluidsynth
|
||||
|
@ -76,6 +79,39 @@ unix {
|
|||
LIBS += -lboost_program_options$$BOOST_LIB_SUFFIX
|
||||
}
|
||||
|
||||
win32 {
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG += sigc++-2.0 pixman-1 zlib \
|
||||
sdl2 SDL2_image SDL2_ttf openal SDL_sound vorbisfile
|
||||
LIBS += -lphysfs -lboost_program_options-mt -lsecur32
|
||||
|
||||
# Deal with boost paths...
|
||||
isEmpty(BOOST_I) {
|
||||
BOOST_I = $$(BOOST_I)
|
||||
}
|
||||
isEmpty(BOOST_I) {}
|
||||
else {
|
||||
INCLUDEPATH += $$BOOST_I
|
||||
}
|
||||
|
||||
isEmpty(BOOST_L) {
|
||||
BOOST_L = $$(BOOST_L)
|
||||
}
|
||||
isEmpty(BOOST_L) {}
|
||||
else {
|
||||
LIBS += -L$$BOOST_L
|
||||
}
|
||||
|
||||
# Ruby console bug
|
||||
!console {
|
||||
DEFINES += NOCONSOLE
|
||||
}
|
||||
|
||||
release {
|
||||
RC_FILE = assets/resources.rc
|
||||
}
|
||||
}
|
||||
|
||||
# Input
|
||||
HEADERS += \
|
||||
src/quadarray.h \
|
||||
|
@ -135,7 +171,8 @@ HEADERS += \
|
|||
src/tileatlasvx.h \
|
||||
src/sharedmidistate.h \
|
||||
src/fluid-fun.h \
|
||||
src/sdl-util.h
|
||||
src/sdl-util.h \
|
||||
src/oneshot.h
|
||||
|
||||
SOURCES += \
|
||||
src/main.cpp \
|
||||
|
@ -180,7 +217,8 @@ SOURCES += \
|
|||
src/tileatlasvx.cpp \
|
||||
src/autotilesvx.cpp \
|
||||
src/midisource.cpp \
|
||||
src/fluid-fun.cpp
|
||||
src/fluid-fun.cpp \
|
||||
src/oneshot.cpp
|
||||
|
||||
EMBED = \
|
||||
shader/common.h \
|
||||
|
@ -279,7 +317,8 @@ BINDING_MRUBY {
|
|||
|
||||
BINDING_MRI {
|
||||
isEmpty(MRIVERSION) {
|
||||
MRIVERSION = 2.1
|
||||
win32:MRIVERSION = 2.1
|
||||
unix:MRIVERSION = 2.2
|
||||
}
|
||||
|
||||
PKGCONFIG += ruby-$$MRIVERSION
|
||||
|
@ -320,7 +359,8 @@ BINDING_MRI {
|
|||
binding-mri/module_rpg.cpp \
|
||||
binding-mri/filesystem-binding.cpp \
|
||||
binding-mri/windowvx-binding.cpp \
|
||||
binding-mri/tilemapvx-binding.cpp
|
||||
binding-mri/tilemapvx-binding.cpp \
|
||||
binding-mri/oneshot-binding.cpp
|
||||
}
|
||||
|
||||
OTHER_FILES += $$EMBED
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
|
||||
#include "al-util.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
struct ALDataSource
|
||||
{
|
||||
enum Status
|
||||
|
|
|
@ -98,14 +98,15 @@ void AudioStream::play(const std::string &filename,
|
|||
return;
|
||||
}
|
||||
|
||||
/* If all parameters except volume match the current ones,
|
||||
* we update the volume and continue streaming */
|
||||
/* If the filenames are equal,
|
||||
* we update the volume and pitch and continue streaming */
|
||||
if (filename == current.filename
|
||||
&& _pitch == current.pitch
|
||||
&& (sState == ALStream::Playing || sState == ALStream::Paused))
|
||||
{
|
||||
setVolume(Base, _volume);
|
||||
stream.setPitch(_pitch);
|
||||
current.volume = _volume;
|
||||
current.pitch = _pitch;
|
||||
unlockStream();
|
||||
return;
|
||||
}
|
||||
|
|
165
src/config.cpp
165
src/config.cpp
|
@ -145,13 +145,12 @@ Config::Config()
|
|||
void Config::read(int argc, char *argv[])
|
||||
{
|
||||
#define PO_DESC_ALL \
|
||||
PO_DESC(rgssVersion, int, 0) \
|
||||
PO_DESC(debugMode, bool, false) \
|
||||
PO_DESC(printFPS, bool, false) \
|
||||
PO_DESC(winResizable, bool, false) \
|
||||
PO_DESC(winResizable, bool, true) \
|
||||
PO_DESC(fullscreen, bool, false) \
|
||||
PO_DESC(fixedAspectRatio, bool, true) \
|
||||
PO_DESC(smoothScaling, bool, true) \
|
||||
PO_DESC(smoothScaling, bool, false) \
|
||||
PO_DESC(vsync, bool, false) \
|
||||
PO_DESC(defScreenW, int, 0) \
|
||||
PO_DESC(defScreenH, int, 0) \
|
||||
|
@ -162,20 +161,17 @@ void Config::read(int argc, char *argv[])
|
|||
PO_DESC(subImageFix, bool, false) \
|
||||
PO_DESC(gameFolder, std::string, ".") \
|
||||
PO_DESC(anyAltToggleFS, bool, false) \
|
||||
PO_DESC(enableReset, bool, true) \
|
||||
PO_DESC(enableReset, bool, false) \
|
||||
PO_DESC(allowSymlinks, bool, false) \
|
||||
PO_DESC(dataPathOrg, std::string, "") \
|
||||
PO_DESC(dataPathApp, std::string, "") \
|
||||
PO_DESC(iconPath, std::string, "") \
|
||||
PO_DESC(execName, std::string, "Game") \
|
||||
PO_DESC(titleLanguage, std::string, "") \
|
||||
PO_DESC(midi.soundFont, std::string, "") \
|
||||
PO_DESC(midi.chorus, bool, false) \
|
||||
PO_DESC(midi.reverb, bool, false) \
|
||||
PO_DESC(SE.sourceCount, int, 6) \
|
||||
PO_DESC(customScript, std::string, "") \
|
||||
PO_DESC(pathCache, bool, true) \
|
||||
PO_DESC(useScriptNames, bool, false)
|
||||
PO_DESC(pathCache, bool, true)
|
||||
|
||||
// Not gonna take your shit boost
|
||||
#define GUARD_ALL( exp ) try { exp } catch(...) {}
|
||||
|
@ -244,7 +240,16 @@ void Config::read(int argc, char *argv[])
|
|||
if (!dataPathOrg.empty() && !dataPathApp.empty())
|
||||
customDataPath = prefPath(dataPathOrg.c_str(), dataPathApp.c_str());
|
||||
|
||||
commonDataPath = prefPath(".", "mkxp");
|
||||
commonDataPath = prefPath(".", "Oneshot");
|
||||
|
||||
//Hardcode some ini/version settings
|
||||
rgssVersion = 1;
|
||||
game.title = "Oneshot";
|
||||
game.scripts = "Data/Scripts.rxdata";
|
||||
if (defScreenW <= 0)
|
||||
defScreenW = 640;
|
||||
if (defScreenH <= 0)
|
||||
defScreenH = 480;
|
||||
}
|
||||
|
||||
static std::string baseName(const std::string &path)
|
||||
|
@ -256,145 +261,3 @@ static std::string baseName(const std::string &path)
|
|||
|
||||
return path.substr(pos + 1);
|
||||
}
|
||||
|
||||
static void setupScreenSize(Config &conf)
|
||||
{
|
||||
if (conf.defScreenW <= 0)
|
||||
conf.defScreenW = (conf.rgssVersion == 1 ? 640 : 544);
|
||||
|
||||
if (conf.defScreenH <= 0)
|
||||
conf.defScreenH = (conf.rgssVersion == 1 ? 480 : 416);
|
||||
}
|
||||
|
||||
void Config::readGameINI()
|
||||
{
|
||||
if (!customScript.empty())
|
||||
{
|
||||
game.title = baseName(customScript);
|
||||
|
||||
if (rgssVersion == 0)
|
||||
rgssVersion = 1;
|
||||
|
||||
setupScreenSize(*this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
po::options_description podesc;
|
||||
podesc.add_options()
|
||||
("Game.Title", po::value<std::string>())
|
||||
("Game.Scripts", po::value<std::string>())
|
||||
;
|
||||
|
||||
po::variables_map vm;
|
||||
std::string iniFilename = execName + ".ini";
|
||||
SDLRWStream iniFile(iniFilename.c_str(), "r");
|
||||
|
||||
if (iniFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
po::store(po::parse_config_file(iniFile.stream(), podesc, true), vm);
|
||||
po::notify(vm);
|
||||
}
|
||||
catch (po::error &error)
|
||||
{
|
||||
Debug() << iniFilename + ":" << error.what();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug() << "FAILED to open" << iniFilename;
|
||||
}
|
||||
|
||||
GUARD_ALL( game.title = vm["Game.Title"].as<std::string>(); );
|
||||
GUARD_ALL( game.scripts = vm["Game.Scripts"].as<std::string>(); );
|
||||
|
||||
strReplace(game.scripts, '\\', '/');
|
||||
|
||||
#ifdef INI_ENCODING
|
||||
/* Can add more later */
|
||||
const char *languages[] =
|
||||
{
|
||||
titleLanguage.c_str(),
|
||||
GUESS_REGION_JP, /* Japanese */
|
||||
GUESS_REGION_KR, /* Korean */
|
||||
GUESS_REGION_CN, /* Chinese */
|
||||
0
|
||||
};
|
||||
|
||||
bool convSuccess = true;
|
||||
|
||||
/* Verify that the game title is UTF-8, and if not,
|
||||
* try to determine the encoding and convert to UTF-8 */
|
||||
if (!validUtf8(game.title.c_str()))
|
||||
{
|
||||
const char *encoding = 0;
|
||||
convSuccess = false;
|
||||
|
||||
for (size_t i = 0; languages[i]; ++i)
|
||||
{
|
||||
encoding = libguess_determine_encoding(game.title.c_str(),
|
||||
game.title.size(),
|
||||
languages[i]);
|
||||
if (encoding)
|
||||
break;
|
||||
}
|
||||
|
||||
if (encoding)
|
||||
{
|
||||
iconv_t cd = iconv_open("UTF-8", encoding);
|
||||
|
||||
size_t inLen = game.title.size();
|
||||
size_t outLen = inLen * 4;
|
||||
std::string buf(outLen, '\0');
|
||||
char *inPtr = const_cast<char*>(game.title.c_str());
|
||||
char *outPtr = const_cast<char*>(buf.c_str());
|
||||
|
||||
errno = 0;
|
||||
size_t result = iconv(cd, &inPtr, &inLen, &outPtr, &outLen);
|
||||
|
||||
iconv_close(cd);
|
||||
|
||||
if (result != (size_t) -1 && errno == 0)
|
||||
{
|
||||
buf.resize(buf.size()-outLen);
|
||||
game.title = buf;
|
||||
convSuccess = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!convSuccess)
|
||||
game.title.clear();
|
||||
#else
|
||||
if (!validUtf8(game.title.c_str()))
|
||||
game.title.clear();
|
||||
#endif
|
||||
|
||||
if (game.title.empty())
|
||||
game.title = baseName(gameFolder);
|
||||
|
||||
if (rgssVersion == 0)
|
||||
{
|
||||
/* Try to guess RGSS version based on Data/Scripts extension */
|
||||
rgssVersion = 1;
|
||||
|
||||
if (!game.scripts.empty())
|
||||
{
|
||||
const char *p = &game.scripts[game.scripts.size()];
|
||||
const char *head = &game.scripts[0];
|
||||
|
||||
while (--p != head)
|
||||
if (*p == '.')
|
||||
break;
|
||||
|
||||
if (!strcmp(p, ".rvdata"))
|
||||
rgssVersion = 2;
|
||||
else if (!strcmp(p, ".rvdata2"))
|
||||
rgssVersion = 3;
|
||||
}
|
||||
}
|
||||
|
||||
setupScreenSize(*this);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,6 @@ struct Config
|
|||
|
||||
std::string iconPath;
|
||||
std::string execName;
|
||||
std::string titleLanguage;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -74,9 +73,6 @@ struct Config
|
|||
int sourceCount;
|
||||
} SE;
|
||||
|
||||
bool useScriptNames;
|
||||
|
||||
std::string customScript;
|
||||
std::vector<std::string> preloadScripts;
|
||||
std::vector<std::string> rtps;
|
||||
|
||||
|
@ -97,7 +93,6 @@ struct Config
|
|||
Config();
|
||||
|
||||
void read(int argc, char *argv[]);
|
||||
void readGameINI();
|
||||
};
|
||||
|
||||
#endif // CONFIG_H
|
||||
|
|
|
@ -171,10 +171,7 @@ _TTF_Font *SharedFontState::getFont(std::string family,
|
|||
shState->fileSystem().openReadRaw(*ops, path, true);
|
||||
}
|
||||
|
||||
// FIXME 0.9 is guesswork at this point
|
||||
// float gamma = (96.0/45.0)*(5.0/14.0)*(size-5);
|
||||
// font = TTF_OpenFontRW(ops, 1, gamma /** .90*/);
|
||||
font = TTF_OpenFontRW(ops, 1, size* 0.90f);
|
||||
font = TTF_OpenFontRW(ops, 1, size);
|
||||
|
||||
if (!font)
|
||||
throw Exception(Exception::SDLError, "%s", SDL_GetError());
|
||||
|
|
|
@ -753,6 +753,8 @@ void Graphics::transition(int duration,
|
|||
|
||||
for (int i = 0; i < duration; ++i)
|
||||
{
|
||||
shState->input().update();
|
||||
|
||||
/* We need to clean up transMap properly before
|
||||
* a possible longjmp, so we manually test for
|
||||
* shutdown/reset here */
|
||||
|
|
|
@ -71,46 +71,28 @@ static const KbBindingData defaultKbBindings[] =
|
|||
{ SDL_SCANCODE_RIGHT, Input::Right },
|
||||
{ SDL_SCANCODE_UP, Input::Up },
|
||||
{ SDL_SCANCODE_DOWN, Input::Down },
|
||||
{ SDL_SCANCODE_H, Input::Left },
|
||||
{ SDL_SCANCODE_L, Input::Right },
|
||||
{ SDL_SCANCODE_K, Input::Up },
|
||||
{ SDL_SCANCODE_J, Input::Down },
|
||||
{ SDL_SCANCODE_Z, Input::C },
|
||||
{ SDL_SCANCODE_SPACE, Input::C },
|
||||
{ SDL_SCANCODE_RETURN, Input::C },
|
||||
{ SDL_SCANCODE_X, Input::B },
|
||||
{ SDL_SCANCODE_ESCAPE, Input::B },
|
||||
{ SDL_SCANCODE_KP_0, Input::B },
|
||||
{ SDL_SCANCODE_LSHIFT, Input::A },
|
||||
{ SDL_SCANCODE_X, Input::B },
|
||||
{ SDL_SCANCODE_D, Input::Z },
|
||||
{ SDL_SCANCODE_Q, Input::L },
|
||||
{ SDL_SCANCODE_W, Input::R },
|
||||
{ SDL_SCANCODE_A, Input::X },
|
||||
{ SDL_SCANCODE_S, Input::Y }
|
||||
};
|
||||
|
||||
/* RGSS1 */
|
||||
static const KbBindingData defaultKbBindings1[] =
|
||||
{
|
||||
{ SDL_SCANCODE_Z, Input::A },
|
||||
{ SDL_SCANCODE_C, Input::C },
|
||||
};
|
||||
|
||||
/* RGSS2 and higher */
|
||||
static const KbBindingData defaultKbBindings2[] =
|
||||
{
|
||||
{ SDL_SCANCODE_Z, Input::C }
|
||||
{ SDL_SCANCODE_LCTRL, Input::X },
|
||||
};
|
||||
|
||||
static elementsN(defaultKbBindings);
|
||||
static elementsN(defaultKbBindings1);
|
||||
static elementsN(defaultKbBindings2);
|
||||
|
||||
static const JsBindingData defaultJsBindings[] =
|
||||
{
|
||||
{ 0, Input::A },
|
||||
{ 0, Input::C },
|
||||
{ 1, Input::B },
|
||||
{ 2, Input::C },
|
||||
{ 2, Input::A },
|
||||
{ 3, Input::X },
|
||||
{ 4, Input::Y },
|
||||
{ 5, Input::Z },
|
||||
{ 6, Input::L },
|
||||
{ 7, Input::R }
|
||||
};
|
||||
|
||||
static elementsN(defaultJsBindings);
|
||||
|
@ -143,20 +125,13 @@ static void addHatBinding(BDescVec &d, uint8_t hat, uint8_t pos, Input::ButtonCo
|
|||
d.push_back(desc);
|
||||
}
|
||||
|
||||
BDescVec genDefaultBindings(const Config &conf)
|
||||
BDescVec genDefaultBindings()
|
||||
{
|
||||
BDescVec d;
|
||||
|
||||
for (size_t i = 0; i < defaultKbBindingsN; ++i)
|
||||
defaultKbBindings[i].add(d);
|
||||
|
||||
if (conf.rgssVersion == 1)
|
||||
for (size_t i = 0; i < defaultKbBindings1N; ++i)
|
||||
defaultKbBindings1[i].add(d);
|
||||
else
|
||||
for (size_t i = 0; i < defaultKbBindings2N; ++i)
|
||||
defaultKbBindings2[i].add(d);
|
||||
|
||||
for (size_t i = 0; i < defaultJsBindingsN; ++i)
|
||||
defaultJsBindings[i].add(d);
|
||||
|
||||
|
@ -164,7 +139,7 @@ BDescVec genDefaultBindings(const Config &conf)
|
|||
addAxisBinding(d, 0, Positive, Input::Right);
|
||||
addAxisBinding(d, 1, Negative, Input::Up );
|
||||
addAxisBinding(d, 1, Positive, Input::Down );
|
||||
|
||||
|
||||
addHatBinding(d, 0, SDL_HAT_LEFT, Input::Left );
|
||||
addHatBinding(d, 0, SDL_HAT_RIGHT, Input::Right);
|
||||
addHatBinding(d, 0, SDL_HAT_UP, Input::Up );
|
||||
|
@ -178,24 +153,21 @@ BDescVec genDefaultBindings(const Config &conf)
|
|||
struct Header
|
||||
{
|
||||
uint32_t formVer;
|
||||
uint32_t rgssVer;
|
||||
uint32_t count;
|
||||
};
|
||||
|
||||
static void buildPath(const std::string &dir, uint32_t rgssVersion,
|
||||
char *out, size_t outSize)
|
||||
static void buildPath(const std::string &dir, char *out, size_t outSize)
|
||||
{
|
||||
snprintf(out, outSize, "%skeybindings.mkxp%u", dir.c_str(), rgssVersion);
|
||||
snprintf(out, outSize, "%skeybindings", dir.c_str());
|
||||
}
|
||||
|
||||
static bool writeBindings(const BDescVec &d, const std::string &dir,
|
||||
uint32_t rgssVersion)
|
||||
static bool writeBindings(const BDescVec &d, const std::string &dir)
|
||||
{
|
||||
if (dir.empty())
|
||||
return false;
|
||||
|
||||
char path[1024];
|
||||
buildPath(dir, rgssVersion, path, sizeof(path));
|
||||
buildPath(dir, path, sizeof(path));
|
||||
|
||||
FILE *f = fopen(path, "wb");
|
||||
|
||||
|
@ -204,7 +176,6 @@ static bool writeBindings(const BDescVec &d, const std::string &dir,
|
|||
|
||||
Header hd;
|
||||
hd.formVer = FORMAT_VER;
|
||||
hd.rgssVer = rgssVersion;
|
||||
hd.count = d.size();
|
||||
|
||||
if (fwrite(&hd, sizeof(hd), 1, f) < 1)
|
||||
|
@ -225,10 +196,10 @@ static bool writeBindings(const BDescVec &d, const std::string &dir,
|
|||
|
||||
void storeBindings(const BDescVec &d, const Config &conf)
|
||||
{
|
||||
if (writeBindings(d, conf.customDataPath, conf.rgssVersion))
|
||||
if (writeBindings(d, conf.customDataPath))
|
||||
return;
|
||||
|
||||
writeBindings(d, conf.commonDataPath, conf.rgssVersion);
|
||||
writeBindings(d, conf.commonDataPath);
|
||||
}
|
||||
|
||||
#define READ(ptr, size, n, f) if (fread(ptr, size, n, f) < n) return false
|
||||
|
@ -277,14 +248,13 @@ static bool verifyDesc(const BindingDesc &desc)
|
|||
}
|
||||
}
|
||||
|
||||
static bool readBindings(BDescVec &out, const std::string &dir,
|
||||
uint32_t rgssVersion)
|
||||
static bool readBindings(BDescVec &out, const std::string &dir)
|
||||
{
|
||||
if (dir.empty())
|
||||
return false;
|
||||
|
||||
char path[1024];
|
||||
buildPath(dir, rgssVersion, path, sizeof(path));
|
||||
buildPath(dir, path, sizeof(path));
|
||||
|
||||
FILE *f = fopen(path, "rb");
|
||||
|
||||
|
@ -300,8 +270,6 @@ static bool readBindings(BDescVec &out, const std::string &dir,
|
|||
|
||||
if (hd.formVer != FORMAT_VER)
|
||||
return false;
|
||||
if (hd.rgssVer != rgssVersion)
|
||||
return false;
|
||||
/* Arbitrary max value */
|
||||
if (hd.count > 1024)
|
||||
return false;
|
||||
|
@ -324,11 +292,11 @@ BDescVec loadBindings(const Config &conf)
|
|||
{
|
||||
BDescVec d;
|
||||
|
||||
if (readBindings(d, conf.customDataPath, conf.rgssVersion))
|
||||
if (readBindings(d, conf.customDataPath))
|
||||
return d;
|
||||
|
||||
if (readBindings(d, conf.commonDataPath, conf.rgssVersion))
|
||||
if (readBindings(d, conf.commonDataPath))
|
||||
return d;
|
||||
|
||||
return genDefaultBindings(conf);
|
||||
return genDefaultBindings();
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ struct BindingDesc
|
|||
typedef std::vector<BindingDesc> BDescVec;
|
||||
struct Config;
|
||||
|
||||
BDescVec genDefaultBindings(const Config &conf);
|
||||
BDescVec genDefaultBindings();
|
||||
|
||||
void storeBindings(const BDescVec &d, const Config &conf);
|
||||
BDescVec loadBindings(const Config &conf);
|
||||
|
|
|
@ -206,8 +206,6 @@ int main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
conf.readGameINI();
|
||||
|
||||
assert(conf.rgssVersion >= 1 && conf.rgssVersion <= 3);
|
||||
printRgssVersion(conf.rgssVersion);
|
||||
|
||||
|
|
|
@ -0,0 +1,459 @@
|
|||
#include "oneshot.h"
|
||||
|
||||
/******************
|
||||
* HERE BE DRAGONS
|
||||
******************/
|
||||
|
||||
#include "eventthread.h"
|
||||
#include "debugwriter.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
//OS-Specific code
|
||||
#if defined _WIN32
|
||||
#define OS_W32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define SECURITY_WIN32
|
||||
#include <windows.h>
|
||||
#include <security.h>
|
||||
#include <shlobj.h>
|
||||
#include <SDL2/SDL_syswm.h>
|
||||
#elif defined __APPLE__
|
||||
#define OS_OSX
|
||||
#elif defined __linux__
|
||||
#define OS_LINUX
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
class GtkWidget;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_MESSAGE_WARNING,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_MESSAGE_ERROR
|
||||
} GtkMessageType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GTK_BUTTONS_NONE,
|
||||
GTK_BUTTONS_OK,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
GTK_BUTTONS_CANCEL,
|
||||
GTK_BUTTONS_YES_NO,
|
||||
GTK_BUTTONS_OK_CANCEL
|
||||
} GtkButtonsType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GTK_RESPONSE_NONE = -1,
|
||||
GTK_RESPONSE_REJECT = -2,
|
||||
GTK_RESPONSE_ACCEPT = -3,
|
||||
GTK_RESPONSE_DELETE_EVENT = -4,
|
||||
GTK_RESPONSE_OK = -5,
|
||||
GTK_RESPONSE_CANCEL = -6,
|
||||
GTK_RESPONSE_CLOSE = -7,
|
||||
GTK_RESPONSE_YES = -8,
|
||||
GTK_RESPONSE_NO = -9,
|
||||
GTK_RESPONSE_APPLY = -10,
|
||||
GTK_RESPONSE_HELP = -11
|
||||
} GtkResponseType;
|
||||
#else
|
||||
#error "Operating system not detected."
|
||||
#endif
|
||||
|
||||
struct OneshotPrivate
|
||||
{
|
||||
//Main SDL window
|
||||
SDL_Window *window;
|
||||
|
||||
//String data
|
||||
std::string lang;
|
||||
std::string userName;
|
||||
std::string savePath;
|
||||
|
||||
//Dialog text
|
||||
std::string txtYes;
|
||||
std::string txtNo;
|
||||
|
||||
#if defined OS_LINUX
|
||||
//GTK+
|
||||
void *libgtk;
|
||||
void (*gtk_init)(int *argc, char ***argv);
|
||||
GtkWidget *(*gtk_message_dialog_new)(void *parent, int flags, GtkMessageType type, GtkButtonsType buttons, const char *message_format, ...);
|
||||
void (*gtk_window_set_title)(GtkWidget *window, const char *title);
|
||||
GtkResponseType (*gtk_dialog_run)(GtkWidget *dialog);
|
||||
void (*gtk_widget_destroy)(GtkWidget *widget);
|
||||
void (*gtk_main_quit)();
|
||||
void (*gtk_main)();
|
||||
unsigned int (*gdk_threads_add_idle)(int (*function)(void *data), void *data);
|
||||
#endif
|
||||
|
||||
OneshotPrivate()
|
||||
: window(0)
|
||||
#if defined OS_LINUX
|
||||
,libgtk(0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
~OneshotPrivate()
|
||||
{
|
||||
#ifdef OS_LINUX
|
||||
if (libgtk)
|
||||
dlclose(libgtk);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
//OS-SPECIFIC FUNCTIONS
|
||||
#if defined OS_LINUX
|
||||
struct linux_DialogData
|
||||
{
|
||||
//Input
|
||||
OneshotPrivate *p;
|
||||
int type;
|
||||
const char *body;
|
||||
const char *title;
|
||||
|
||||
//Output
|
||||
bool result;
|
||||
};
|
||||
|
||||
static int linux_dialog(void *rawData)
|
||||
{
|
||||
linux_DialogData *data = reinterpret_cast<linux_DialogData*>(rawData);
|
||||
OneshotPrivate *p = data->p;
|
||||
|
||||
//Determine correct flags
|
||||
GtkMessageType gtktype;
|
||||
GtkButtonsType gtkbuttons = GTK_BUTTONS_OK;
|
||||
switch (data->type)
|
||||
{
|
||||
case Oneshot::MSG_INFO:
|
||||
gtktype = GTK_MESSAGE_INFO;
|
||||
break;
|
||||
case Oneshot::MSG_YESNO:
|
||||
gtktype = GTK_MESSAGE_QUESTION;
|
||||
gtkbuttons = GTK_BUTTONS_YES_NO;
|
||||
break;
|
||||
case Oneshot::MSG_WARN:
|
||||
gtktype = GTK_MESSAGE_WARNING;
|
||||
break;
|
||||
case Oneshot::MSG_ERR:
|
||||
gtktype = GTK_MESSAGE_ERROR;
|
||||
break;
|
||||
default:
|
||||
p->gtk_main_quit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Display dialog and get result
|
||||
GtkWidget *dialog = p->gtk_message_dialog_new(0, 0, gtktype, gtkbuttons, data->body);
|
||||
p->gtk_window_set_title(dialog, data->title);
|
||||
int result = p->gtk_dialog_run(dialog);
|
||||
p->gtk_widget_destroy(dialog);
|
||||
|
||||
//Interpret result and return
|
||||
data->result = (result == GTK_RESPONSE_OK || result == GTK_RESPONSE_YES);
|
||||
p->gtk_main_quit();
|
||||
return 0;
|
||||
}
|
||||
#elif defined OS_W32
|
||||
/* Convert WCHAR pointer to std::string */
|
||||
static std::string w32_fromWide(const WCHAR *ustr)
|
||||
{
|
||||
std::string result;
|
||||
int size = WideCharToMultiByte(CP_UTF8, 0, ustr, -1, 0, 0, 0, 0);
|
||||
if (size > 0)
|
||||
{
|
||||
CHAR *str = new CHAR[size];
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, ustr, -1, str, size, 0, 0) == size)
|
||||
result = str;
|
||||
delete [] str;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/* Convert WCHAR pointer from const char* */
|
||||
static WCHAR *w32_toWide(const char *str)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
int size = MultiByteToWideChar(CP_UTF8, 0, str, -1, 0, 0);
|
||||
if (size > 0)
|
||||
{
|
||||
WCHAR *ustr = new WCHAR[size];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, str, -1, ustr, size) == size)
|
||||
return ustr;
|
||||
delete [] ustr;
|
||||
}
|
||||
}
|
||||
|
||||
//Return empty string
|
||||
WCHAR *ustr = new WCHAR[1];
|
||||
*ustr = 0;
|
||||
return ustr;
|
||||
}
|
||||
#endif
|
||||
|
||||
Oneshot::Oneshot(const RGSSThreadData &threadData)
|
||||
{
|
||||
p = new OneshotPrivate();
|
||||
p->window = threadData.window;
|
||||
p->savePath = threadData.config.commonDataPath.substr(0, threadData.config.commonDataPath.size() - 1);
|
||||
|
||||
/********************
|
||||
* USERNAME/SAVE PATH
|
||||
********************/
|
||||
#if defined OS_W32
|
||||
//Get language code
|
||||
WCHAR wlang[9];
|
||||
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, wlang, sizeof(wlang) / sizeof(WCHAR));
|
||||
p->lang = w32_fromWide(wlang);
|
||||
|
||||
//Get user's name
|
||||
ULONG size = 0;
|
||||
GetUserNameEx(NameDisplay, 0, &size);
|
||||
if (GetLastError() == ERROR_MORE_DATA)
|
||||
{
|
||||
//Get their full (display) name
|
||||
WCHAR *name = new WCHAR[size];
|
||||
GetUserNameEx(NameDisplay, name, &size);
|
||||
p->userName = w32_fromWide(name);
|
||||
delete [] name;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Get their login name
|
||||
DWORD size2 = 0;
|
||||
GetUserName(0, &size2);
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
WCHAR *name = new WCHAR[size2];
|
||||
GetUserName(name, &size2);
|
||||
p->userName = w32_fromWide(name);
|
||||
delete [] name;
|
||||
}
|
||||
}
|
||||
#else
|
||||
//Get language code
|
||||
const char *lc_all = getenv("LC_ALL");
|
||||
const char *lang = getenv("LANG");
|
||||
const char *code = (lc_all ? lc_all : lang);
|
||||
if (code)
|
||||
{
|
||||
//find first non alphanumeric character, copy language code
|
||||
int end = 0;
|
||||
for (; code[end] && (code[end] >= 'a' && code[end] <= 'z'); ++end) {}
|
||||
p->lang = std::string(code, end);
|
||||
}
|
||||
else
|
||||
p->lang = "en";
|
||||
|
||||
//Get user's name
|
||||
struct passwd *pwd = getpwuid(getuid());
|
||||
if (pwd)
|
||||
{
|
||||
if (pwd->pw_gecos && pwd->pw_gecos[0] != ',')
|
||||
{
|
||||
//Get the user's full name
|
||||
int comma = 0;
|
||||
for (; pwd->pw_gecos[comma] && pwd->pw_gecos[comma] != ','; ++comma) {}
|
||||
p->userName = std::string(pwd->pw_gecos, comma);
|
||||
}
|
||||
else
|
||||
p->userName = pwd->pw_name;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********
|
||||
* MSGBOX
|
||||
**********/
|
||||
#ifdef OS_LINUX
|
||||
#define LOAD_FUNC(name) *reinterpret_cast<void**>(&p->name) = dlsym(p->libgtk, #name)
|
||||
//Attempt to link to gtk (prefer gtk2 over gtk3 until I can figure that message box icon out)
|
||||
static const char *gtklibs[] =
|
||||
{
|
||||
"libgtk-x11-2.0.so",
|
||||
"libgtk-3.0.so",
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(gtklibs); ++i)
|
||||
{
|
||||
if (!(p->libgtk = dlopen("libgtk-x11-2.0.so", RTLD_NOW)))
|
||||
p->libgtk = dlopen("libgtk-3.0.so", RTLD_NOW);
|
||||
if (p->libgtk)
|
||||
{
|
||||
//Load functions
|
||||
LOAD_FUNC(gtk_init);
|
||||
LOAD_FUNC(gtk_message_dialog_new);
|
||||
LOAD_FUNC(gtk_window_set_title);
|
||||
LOAD_FUNC(gtk_dialog_run);
|
||||
LOAD_FUNC(gtk_widget_destroy);
|
||||
LOAD_FUNC(gtk_main_quit);
|
||||
LOAD_FUNC(gtk_main);
|
||||
LOAD_FUNC(gdk_threads_add_idle);
|
||||
|
||||
if (p->gtk_init
|
||||
&& p->gtk_message_dialog_new
|
||||
&& p->gtk_window_set_title
|
||||
&& p->gtk_dialog_run
|
||||
&& p->gtk_widget_destroy
|
||||
&& p->gtk_main_quit
|
||||
&& p->gtk_main
|
||||
&& p->gdk_threads_add_idle)
|
||||
{
|
||||
p->gtk_init(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
dlclose(p->libgtk);
|
||||
p->libgtk = 0;
|
||||
}
|
||||
}
|
||||
if (p->libgtk)
|
||||
break;
|
||||
}
|
||||
#undef LOAD_FUNC
|
||||
#endif
|
||||
/********
|
||||
* MISC
|
||||
********/
|
||||
#if defined OS_W32
|
||||
//Get windows version
|
||||
OSVERSIONINFOW version;
|
||||
ZeroMemory(&version, sizeof(version));
|
||||
version.dwOSVersionInfoSize = sizeof(version);
|
||||
GetVersionEx(&version);
|
||||
#endif
|
||||
}
|
||||
|
||||
Oneshot::~Oneshot()
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
|
||||
const std::string &Oneshot::lang() const
|
||||
{
|
||||
return p->lang;
|
||||
}
|
||||
|
||||
const std::string &Oneshot::userName() const
|
||||
{
|
||||
return p->userName;
|
||||
}
|
||||
|
||||
const std::string &Oneshot::savePath() const
|
||||
{
|
||||
return p->savePath;
|
||||
}
|
||||
|
||||
void Oneshot::setYesNo(const char *yes, const char *no)
|
||||
{
|
||||
p->txtYes = yes;
|
||||
p->txtNo = no;
|
||||
}
|
||||
|
||||
bool Oneshot::msgbox(int type, const char *body, const char *title)
|
||||
{
|
||||
#if defined OS_W32
|
||||
//Get native window handle
|
||||
SDL_SysWMinfo wminfo;
|
||||
SDL_version version;
|
||||
SDL_VERSION(&version);
|
||||
wminfo.version = version;
|
||||
SDL_GetWindowWMInfo(p->window, &wminfo);
|
||||
HWND hwnd = wminfo.info.win.window;
|
||||
|
||||
//Construct flags
|
||||
UINT flags = 0;
|
||||
switch (type)
|
||||
{
|
||||
case MSG_INFO:
|
||||
flags = MB_ICONINFORMATION;
|
||||
break;
|
||||
case MSG_YESNO:
|
||||
flags = MB_ICONQUESTION | MB_YESNO;
|
||||
break;
|
||||
case MSG_WARN:
|
||||
flags = MB_ICONWARNING;
|
||||
break;
|
||||
case MSG_ERR:
|
||||
flags = MB_ICONERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
//Create message box
|
||||
WCHAR *wbody = w32_toWide(body);
|
||||
WCHAR *wtitle = w32_toWide(title);
|
||||
int result = MessageBoxW(hwnd, wbody, wtitle, flags);
|
||||
delete [] title;
|
||||
delete [] body;
|
||||
|
||||
//Interpret result
|
||||
return (result == IDOK || result == IDYES);
|
||||
#else
|
||||
#if defined OS_LINUX
|
||||
if (p->libgtk)
|
||||
{
|
||||
linux_DialogData data = {p, type, body, title, 0};
|
||||
p->gdk_threads_add_idle(linux_dialog, &data);
|
||||
p->gtk_main();
|
||||
return data.result;
|
||||
}
|
||||
#endif
|
||||
//SDL message box
|
||||
|
||||
//Button data
|
||||
static const SDL_MessageBoxButtonData buttonOk = {SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "OK"};
|
||||
static const SDL_MessageBoxButtonData buttonsOk[] = {buttonOk};
|
||||
SDL_MessageBoxButtonData buttonYes = {SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, p->txtYes.c_str()};
|
||||
SDL_MessageBoxButtonData buttonNo = {SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, p->txtNo.c_str()};
|
||||
SDL_MessageBoxButtonData buttonsYesNo[] = {buttonNo, buttonYes};
|
||||
|
||||
//Messagebox data
|
||||
SDL_MessageBoxData data;
|
||||
data.window = p->window;
|
||||
data.colorScheme = 0;
|
||||
data.title = title;
|
||||
data.message = body;
|
||||
|
||||
//Set type
|
||||
switch (type)
|
||||
{
|
||||
case MSG_INFO:
|
||||
case MSG_YESNO:
|
||||
data.flags = SDL_MESSAGEBOX_INFORMATION;
|
||||
break;
|
||||
case MSG_WARN:
|
||||
data.flags = SDL_MESSAGEBOX_WARNING;
|
||||
break;
|
||||
case MSG_ERR:
|
||||
data.flags = SDL_MESSAGEBOX_WARNING;
|
||||
break;
|
||||
}
|
||||
|
||||
//Set buttons
|
||||
switch (type)
|
||||
{
|
||||
case MSG_INFO:
|
||||
case MSG_WARN:
|
||||
case MSG_ERR:
|
||||
data.numbuttons = 1;
|
||||
data.buttons = buttonsOk;
|
||||
break;
|
||||
case MSG_YESNO:
|
||||
data.numbuttons = 2;
|
||||
data.buttons = buttonsYesNo;
|
||||
break;
|
||||
}
|
||||
|
||||
//Show messagebox
|
||||
int button;
|
||||
SDL_ShowMessageBox(&data, &button);
|
||||
return button ? true : false;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef ONESHOT_H
|
||||
#define ONESHOT_H
|
||||
|
||||
#include "etc-internal.h"
|
||||
#include <string>
|
||||
|
||||
struct OneshotPrivate;
|
||||
struct RGSSThreadData;
|
||||
|
||||
class Oneshot
|
||||
{
|
||||
public:
|
||||
Oneshot(const RGSSThreadData &threadData);
|
||||
~Oneshot();
|
||||
|
||||
//msgbox type codes
|
||||
enum
|
||||
{
|
||||
MSG_INFO,
|
||||
MSG_YESNO,
|
||||
MSG_WARN,
|
||||
MSG_ERR,
|
||||
};
|
||||
|
||||
//Wallpaper style
|
||||
enum
|
||||
{
|
||||
STYLE_NONE,
|
||||
STYLE_TILE,
|
||||
STYLE_CENTER,
|
||||
STYLE_STRETCH,
|
||||
STYLE_FIT,
|
||||
STYLE_FILL,
|
||||
STYLE_SPAN,
|
||||
};
|
||||
|
||||
//Wallpaper gradient
|
||||
enum
|
||||
{
|
||||
GRADIENT_NONE,
|
||||
GRADIENT_HORIZONTAL,
|
||||
GRADIENT_VERTICAL,
|
||||
};
|
||||
|
||||
//Accessors
|
||||
const std::string &lang() const;
|
||||
const std::string &userName() const;
|
||||
const std::string &savePath() const;
|
||||
|
||||
//Mutators
|
||||
void setYesNo(const char *yes, const char *no);
|
||||
|
||||
//Functions
|
||||
bool msgbox(int type, const char *body, const char *title);
|
||||
|
||||
private:
|
||||
OneshotPrivate *p;
|
||||
};
|
||||
|
||||
#endif // ONESHOT_H
|
|
@ -37,7 +37,7 @@
|
|||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
const Vec2i winSize(540, 356);
|
||||
const Vec2i winSize(700, 316);
|
||||
|
||||
const uint8_t cBgNorm = 50;
|
||||
const uint8_t cBgDark = 20;
|
||||
|
@ -63,16 +63,12 @@ struct VButton
|
|||
{
|
||||
BTN_STRING(Up),
|
||||
BTN_STRING(Down),
|
||||
BTN_STRING(L),
|
||||
BTN_STRING(Left),
|
||||
BTN_STRING(Right),
|
||||
BTN_STRING(R),
|
||||
BTN_STRING(A),
|
||||
BTN_STRING(B),
|
||||
BTN_STRING(C),
|
||||
BTN_STRING(X),
|
||||
BTN_STRING(Y),
|
||||
BTN_STRING(Z)
|
||||
{ Input::C, "Action" },
|
||||
{ Input::B, "Menu" },
|
||||
{ Input::A, "Run/Misc" },
|
||||
{ Input::X, "Deactivate" },
|
||||
};
|
||||
|
||||
static elementsN(vButtons);
|
||||
|
@ -432,7 +428,7 @@ struct SettingsMenuPrivate
|
|||
else
|
||||
{
|
||||
dstRect.w = alignW;
|
||||
dstRect.x = x;
|
||||
dstRect.x = drawOff.x + x;
|
||||
SDL_BlitScaled(txtSurf, 0, surf, &dstRect);
|
||||
}
|
||||
}
|
||||
|
@ -520,6 +516,7 @@ struct SettingsMenuPrivate
|
|||
}
|
||||
|
||||
dupWarnLabel.setVisible(haveDup);
|
||||
infoLabel.setVisible(!haveDup);
|
||||
}
|
||||
|
||||
void redraw()
|
||||
|
@ -705,7 +702,7 @@ struct SettingsMenuPrivate
|
|||
|
||||
void onResetToDefault()
|
||||
{
|
||||
setupBindingData(genDefaultBindings(rtData.config));
|
||||
setupBindingData(genDefaultBindings());
|
||||
updateDuplicateStatus();
|
||||
redraw();
|
||||
}
|
||||
|
@ -964,18 +961,18 @@ SettingsMenu::SettingsMenu(RGSSThreadData &rtData)
|
|||
|
||||
p->rgb = p->winSurf->format;
|
||||
|
||||
const size_t layoutW = 4;
|
||||
const size_t layoutH = 3;
|
||||
const size_t layoutW = 2;
|
||||
const size_t layoutH = 4;
|
||||
assert(layoutW*layoutH == vButtonsN);
|
||||
|
||||
const int bWidgetW = winSize.x / layoutH;
|
||||
const int bWidgetW = winSize.x / layoutW;
|
||||
const int bWidgetH = 64;
|
||||
const int bWidgetY = winSize.y - layoutW*bWidgetH - 48;
|
||||
const int bWidgetY = winSize.y - layoutH*bWidgetH - 48;
|
||||
|
||||
for (int y = 0; y < 4; ++y)
|
||||
for (int x = 0; x < 3; ++x)
|
||||
for (int y = 0; y < layoutH; ++y)
|
||||
for (int x = 0; x < layoutW; ++x)
|
||||
{
|
||||
int i = y*3+x;
|
||||
int i = x*layoutH+y;
|
||||
BindingWidget w(i, p, IntRect(x*bWidgetW, bWidgetY+y*bWidgetH,
|
||||
bWidgetW, bWidgetH));
|
||||
p->bWidgets.push_back(w);
|
||||
|
@ -1008,10 +1005,10 @@ SettingsMenu::SettingsMenu(RGSSThreadData &rtData)
|
|||
|
||||
/* Labels */
|
||||
const char *info = "Use left click to bind a slot, right click to clear its binding";
|
||||
p->infoLabel = Label(p, IntRect(16, 6, winSize.x, 16), info, cText, cText, cText);
|
||||
p->infoLabel = Label(p, IntRect(112 + 32, buttonY + 8, winSize.x, 16), info, cText, cText, cText);
|
||||
|
||||
const char *warn = "Warning: Same physical key bound to multiple slots";
|
||||
p->dupWarnLabel = Label(p, IntRect(16, 26, winSize.x, 16), warn, 255, 0, 0);
|
||||
p->dupWarnLabel = Label(p, IntRect(112 + 32, buttonY + 8, winSize.x, 16), warn, 255, 0, 0);
|
||||
|
||||
p->widgets.push_back(&p->infoLabel);
|
||||
p->widgets.push_back(&p->dupWarnLabel);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "graphics.h"
|
||||
#include "input.h"
|
||||
#include "audio.h"
|
||||
#include "oneshot.h"
|
||||
#include "glstate.h"
|
||||
#include "shader.h"
|
||||
#include "texpool.h"
|
||||
|
@ -77,6 +78,8 @@ struct SharedStatePrivate
|
|||
Input input;
|
||||
Audio audio;
|
||||
|
||||
Oneshot oneshot;
|
||||
|
||||
GLState _glState;
|
||||
|
||||
ShaderSet shaders;
|
||||
|
@ -109,6 +112,7 @@ struct SharedStatePrivate
|
|||
graphics(threadData),
|
||||
input(*threadData),
|
||||
audio(*threadData),
|
||||
oneshot(*threadData),
|
||||
fontState(threadData->config),
|
||||
stampCounter(0)
|
||||
{
|
||||
|
@ -227,6 +231,7 @@ GSATT(Config&, config)
|
|||
GSATT(Graphics&, graphics)
|
||||
GSATT(Input&, input)
|
||||
GSATT(Audio&, audio)
|
||||
GSATT(Oneshot&, oneshot)
|
||||
GSATT(GLState&, _glState)
|
||||
GSATT(ShaderSet&, shaders)
|
||||
GSATT(TexPool&, texPool)
|
||||
|
|
|
@ -42,6 +42,7 @@ class EventThread;
|
|||
class Graphics;
|
||||
class Input;
|
||||
class Audio;
|
||||
class Oneshot;
|
||||
class GLState;
|
||||
class TexPool;
|
||||
class Font;
|
||||
|
@ -71,6 +72,8 @@ struct SharedState
|
|||
Input &input() const;
|
||||
Audio &audio() const;
|
||||
|
||||
Oneshot &oneshot() const;
|
||||
|
||||
GLState &_glState() const;
|
||||
|
||||
ShaderSet &shaders() const;
|
||||
|
|
|
@ -158,7 +158,7 @@ static const size_t zlayersMax = viewpH + 5;
|
|||
static const uint8_t atAnimation[16*4] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue