Merge remote-tracking branch 'origin/linux'

This commit is contained in:
Vinyl Darkscratch 2018-10-02 11:25:30 -07:00
commit 220de0c33c
21 changed files with 402 additions and 195 deletions

View file

@ -91,7 +91,12 @@ raiseRbExc(const Exception &exc);
template<rb_data_type_t *rbType>
static VALUE classAllocate(VALUE klass)
{
/* 2.3 has changed the name of this function */
#if RUBY_API_VERSION_MAJOR >= 2 && RUBY_API_VERSION_MINOR >= 3
return rb_data_typed_object_wrap(klass, 0, rbType);
#else
return rb_data_typed_object_alloc(klass, 0, rbType);
#endif
}
template<class C>

View file

@ -48,13 +48,19 @@ int server_thread(void *data)
}
CloseHandle(pipe);
#else
if (FILE *file = fopen(PIPE_PATH, "r")) {
if (FILE *file = fopen(PIPE_PATH, "r"))
{
fclose(file);
out_pipe = open(PIPE_PATH, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
SDL_LockMutex(mutex);
active = true;
if (message_len > 0)
write(out_pipe, (char*)message_buffer, message_len);
{
if (write(out_pipe, (char*)message_buffer, message_len) == -1)
{
Debug() << "Failure writing to journal's pipe!";
}
}
SDL_UnlockMutex(mutex);
}
return 0;

View file

@ -80,7 +80,12 @@ int niko_server_thread(void *data)
SDL_LockMutex(mutex);
active = true;
if (message_len > 0)
write(out_pipe, (char*)message_buffer, message_len);
{
if (write(out_pipe, (char*)message_buffer, message_len) == -1)
{
Debug() << "Failed to write to pipe!";
}
}
SDL_UnlockMutex(mutex);
}
return 0;
@ -89,6 +94,8 @@ int niko_server_thread(void *data)
RB_METHOD(nikoPrepare)
{
RB_UNUSED_PARAM;
// Prime native window info
syswm::SDL_SysWMinfo syswindow;
SDL_VERSION(&syswindow.version);
@ -99,12 +106,14 @@ RB_METHOD(nikoPrepare)
std::string journal;
// Get current path
getcwd(path, sizeof(path));
if (getcwd(path, sizeof(path)) == NULL) {
return Qnil;
}
#ifdef OS_OSX
journal = std::string(path) + std::string("/_______.app/Contents/MacOS/_______");
journal = std::string(path) + "/_______.app/Contents/MacOS/_______";
#else
journal = std::string(path) + std::string("_______");
journal = std::string(path) + "_______";
#endif
// Run the binary

View file

@ -108,6 +108,9 @@ void oneshotBindingInit()
// Constants
rb_const_set(module, rb_intern("OS"), rb_str_new2(shState->oneshot().os().c_str()));
#ifdef __linux__
rb_const_set(module, rb_intern("DE"), rb_str_new2(shState->oneshot().desktopEnv.c_str()));
#endif
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("DOCS_PATH"), rb_str_new2(shState->oneshot().docsPath().c_str()));

View file

@ -1,4 +1,10 @@
#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <boost/algorithm/string/replace.hpp>
#include "etc.h"
#include "sharedstate.h"
@ -6,6 +12,7 @@
#include "binding-types.h"
#include "config.h"
#include "oneshot.h"
#include "debugwriter.h"
#ifdef _WIN32
#include <windows.h>
@ -23,7 +30,7 @@
#include "mac-desktop.h"
static bool isCached = false;
#else
#include <giomm/settings.h>
#include <gio/gio.h>
#include <xfconf/xfconf.h>
#include <unistd.h>
#include <algorithm>
@ -32,7 +39,7 @@
#include <sstream>
static std::string desktop = "uninitialized";
// GNOME settings
static Glib::RefPtr<Gio::Settings> bgsetting;
static GSettings *bgsetting;
static std::string defPictureURI, defPictureOptions, defPrimaryColor, defColorShading;
// XFCE settings
static XfconfChannel* bgchannel;
@ -41,47 +48,122 @@
static GValue defColor = G_VALUE_INIT;
static bool defColorExists;
static std::string optionImage, optionColor, optionImageStyle, optionColorStyle;
// KDE settings
static std::map<std::string, std::string> defPlugins, defPictures, defColors, defModes;
static std::map<std::string, bool> defBlurs;
// Fallback settings
static std::string fallbackPath;
#endif
#endif
#ifdef __linux__
void desktopEnvironmentInit()
{
if (desktop != "uninitialized") {
return;
}
desktop = shState->oneshot().desktopEnv;
if (desktop == "gnome" || desktop == "mate") {
if (desktop == "gnome") {
bgsetting = Gio::Settings::create("org.gnome.desktop.background");
defPictureURI = bgsetting->get_string("picture-uri");
} else {
bgsetting = Gio::Settings::create("org.mate.background");
defPictureURI = bgsetting->get_string("picture-filename");
void desktopEnvironmentInit()
{
if (desktop != "uninitialized") {
return;
}
defPictureOptions = bgsetting->get_string("picture-options");
defPrimaryColor = bgsetting->get_string("primary-color");
defColorShading = bgsetting->get_string("color-shading-type");
} else if (desktop == "xfce") {
GError *xferror = NULL;
if (xfconf_init(&xferror)) {
bgchannel = xfconf_channel_get("xfce4-desktop");
std::string optionPrefix = "/backdrop/screen0/monitor0/workspace0/";
optionImage = optionPrefix + "last-image";
optionColor = optionPrefix + "color1";
optionImageStyle = optionPrefix + "image-style";
optionColorStyle = optionPrefix + "color-style";
defPictureURI = xfconf_channel_get_string(bgchannel, optionImage.c_str(), "");
defPictureStyle = xfconf_channel_get_int(bgchannel, optionImageStyle.c_str(), -1);
defColorExists = xfconf_channel_get_property(bgchannel, optionColor.c_str(), &defColor);
defColorStyle = xfconf_channel_get_int(bgchannel, optionColorStyle.c_str(), -1);
desktop = shState->oneshot().desktopEnv;
if (desktop == "cinnamon" || desktop == "gnome" || desktop == "mate" || desktop == "deepin") {
if (desktop == "cinnamon" || desktop == "gnome" || desktop == "deepin") {
if (desktop == "cinnamon") bgsetting = g_settings_new("org.cinnamon.desktop.background");
else if (desktop == "deepin") bgsetting = g_settings_new("com.deepin.wrap.gnome.desktop.background");
else bgsetting = g_settings_new("org.gnome.desktop.background");
defPictureURI = g_settings_get_string(bgsetting, "picture-uri");
} else {
bgsetting = g_settings_new("org.mate.background");
defPictureURI = g_settings_get_string(bgsetting, "picture-filename");
}
defPictureOptions = g_settings_get_string(bgsetting, "picture-options");
defPrimaryColor = g_settings_get_string(bgsetting, "primary-color");
defColorShading = g_settings_get_string(bgsetting, "color-shading-type");
} else if (desktop == "xfce") {
GError *xferror = NULL;
if (xfconf_init(&xferror)) {
bgchannel = xfconf_channel_get("xfce4-desktop");
std::string optionPrefix = "/backdrop/screen0/monitor0/workspace0/";
optionImage = optionPrefix + "last-image";
optionColor = optionPrefix + "color1";
optionImageStyle = optionPrefix + "image-style";
optionColorStyle = optionPrefix + "color-style";
defPictureURI = xfconf_channel_get_string(bgchannel, optionImage.c_str(), "");
defPictureStyle = xfconf_channel_get_int(bgchannel, optionImageStyle.c_str(), -1);
defColorExists = xfconf_channel_get_property(bgchannel, optionColor.c_str(), &defColor);
defColorStyle = xfconf_channel_get_int(bgchannel, optionColorStyle.c_str(), -1);
} else {
// Configuration failed to initialize, we won't set the wallpaper
desktop = "xfce_error";
g_error_free(xferror);
}
} else if (desktop == "kde") {
std::ifstream configFile;
configFile.open(std::string(getenv("HOME")) + "/.config/plasma-org.kde.plasma.desktop-appletsrc", std::ios::in);
if (configFile.is_open()) {
std::string line;
std::vector<std::string> sections;
std::size_t undefined = 999999999;
bool readPlugin = false, readOther = false;
std::string containment;
while (getline(configFile, line)) {
std::size_t index = undefined, lastIndex = undefined;
if (line.size() == 0) {
readPlugin = false;
readOther = false;
} else if (readPlugin) {
index = line.find('=');
if (line.substr(0, index) == "wallpaperplugin") {
defPlugins[containment] = line.substr(index + 1);
}
} else if (readOther) {
index = line.find('=');
std::string key = line.substr(0, index);
std::string val = line.substr(index + 1);
if (key == "Image") {
defPictures[containment] = val;
} else if (key == "Color") {
defColors[containment] = val;
} else if (key == "FillMode") {
defModes[containment] = val;
} else if (key == "Blur") {
defBlurs[containment] = (val == "true");
}
} else if (line.at(0) == '[') {
sections.clear();
while (true) {
index = line.find(lastIndex == undefined ? '[' : ']', index == undefined ? 0 : index);
if (index == std::string::npos) {
break;
}
if (lastIndex == undefined) {
lastIndex = index;
} else {
sections.push_back(line.substr(lastIndex + 1, index - lastIndex - 1));
lastIndex = undefined;
}
}
if (sections.size() == 2 && sections[0] == "Containments") {
readPlugin = true;
containment = sections[1];
} else if (
sections.size() == 5 &&
sections[0] == "Containments" &&
sections[2] == "Wallpaper" &&
sections[3] == "org.kde.image" &&
sections[4] == "General"
) {
readOther = true;
containment = sections[1];
}
}
}
configFile.close();
} else {
Debug() << "FATAL: Cannot find desktop configuration!";
desktop = "kde_error";
}
} else {
// Configuration failed to initialize, we won't set the wallpaper
desktop = "xfce_error";
g_error_free(xferror);
fallbackPath = std::string(getenv("HOME")) + "/Desktop/hint.png";
}
}
}
#endif
RB_METHOD(wallpaperSet)
@ -93,7 +175,7 @@ RB_METHOD(wallpaperSet)
std::string path;
#ifdef _WIN32
path = shState->config().gameFolder + "\\Wallpaper\\" + name + ".bmp";
std::cout << "Setting wallpaper to " << path << std::endl;
Debug() << "Setting wallpaper to" << path;
// Crapify the slashes
size_t index = 0;
for (;;) {
@ -168,7 +250,7 @@ end:
}
path = "/Wallpaper/" + nameFix + ".png";
std::cout << "Setting wallpaper to " << path << std::endl;
Debug() << "Setting wallpaper to " << path;
#ifdef __APPLE__
if (!isCached) {
@ -183,17 +265,17 @@ end:
}
std::string gameDirStr(gameDir);
desktopEnvironmentInit();
if (desktop == "gnome" || desktop == "mate") {
if (desktop == "cinnamon" || desktop == "gnome" || desktop == "mate" || desktop == "deepin") {
std::stringstream hexColor;
hexColor << "#" << std::hex << color;
if (desktop == "gnome") {
bgsetting->set_string("picture-uri", "file://" + gameDirStr + path);
g_settings_set_string(bgsetting, "picture-options", "scaled");
g_settings_set_string(bgsetting, "primary-color", hexColor.str().c_str());
g_settings_set_string(bgsetting, "color-shading-type", "solid");
if (desktop == "cinnamon" || desktop == "gnome" || desktop == "deepin") {
g_settings_set_string(bgsetting, "picture-uri", ("file://" + gameDirStr + path).c_str());
} else {
bgsetting->set_string("picture-filename", gameDirStr + path);
g_settings_set_string(bgsetting, "picture-filename", (gameDirStr + path).c_str());
}
bgsetting->set_string("picture-options", "scaled");
bgsetting->set_string("primary-color", hexColor.str());
bgsetting->set_string("color-shading-type", "solid");
} else if (desktop == "xfce") {
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
@ -219,7 +301,7 @@ end:
colorArrType = g_type_from_name("GPtrArray_GValue_");
if (!colorArrType) {
// Let's do some debug output here and skip changing the color
std::cout << "WALLPAPER ERROR: xfconf-query call returned" << colorCommandRes;
Debug() << "WALLPAPER ERROR: xfconf-query call returned" << colorCommandRes;
return Qnil;
}
}
@ -242,6 +324,35 @@ end:
g_ptr_array_add(colorArr, va);
g_value_set_boxed(&colorValue, colorArr);
xfconf_channel_set_property(bgchannel, optionColor.c_str(), &colorValue);
} else if (desktop == "kde") {
std::stringstream command;
std::string concatPath(gameDirStr + path);
boost::replace_all(concatPath, "\\", "\\\\");
boost::replace_all(concatPath, "\"", "\\\"");
boost::replace_all(concatPath, "'", "\\x27");
command << "qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript 'string:" <<
"var allDesktops = desktops();" <<
"for (var i = 0, l = allDesktops.length; i < l; ++i) {" <<
"var d = allDesktops[i];" <<
"d.wallpaperPlugin = \"org.kde.image\";" <<
"d.currentConfigGroup = [\"Wallpaper\", \"org.kde.image\", \"General\"];" <<
"d.writeConfig(\"Image\", \"file://" << concatPath << "\");" <<
"d.writeConfig(\"FillMode\", \"6\");" <<
"d.writeConfig(\"Blur\", false);" <<
"d.writeConfig(\"Color\", [\"" <<
std::to_string((color >> 16) & 0xFF) << "\", \"" <<
std::to_string((color >> 8) & 0xFF) << "\", \"" <<
std::to_string(color & 0xFF) <<
"\"]);" <<
"}" <<
"'";
Debug() << "Wallpaper command:" << command.str();
int result = system(command.str().c_str());
Debug() << "Result:" << result;
} else {
std::ifstream srcHint(gameDirStr + path);
std::ofstream dstHint(fallbackPath);
dstHint << srcHint.rdbuf();
}
#endif
#endif
@ -281,15 +392,15 @@ RB_METHOD(wallpaperReset)
MacDesktop::ResetBackground();
#else
desktopEnvironmentInit();
if (desktop == "gnome" || desktop == "mate") {
if (desktop == "gnome") {
bgsetting->set_string("picture-uri", defPictureURI);
if (desktop == "cinnamon" || desktop == "gnome" || desktop == "mate" || desktop == "deepin") {
if (desktop == "cinnamon" || desktop == "gnome" || desktop == "deepin") {
g_settings_set_string(bgsetting, "picture-uri", defPictureURI.c_str());
} else {
bgsetting->set_string("picture-filename", defPictureURI);
g_settings_set_string(bgsetting, "picture-filename", defPictureURI.c_str());
}
bgsetting->set_string("picture-options", defPictureOptions);
bgsetting->set_string("primary-color", defPrimaryColor);
bgsetting->set_string("color-shading-type", defColorShading);
g_settings_set_string(bgsetting, "picture-options", defPictureOptions.c_str());
g_settings_set_string(bgsetting, "primary-color", defPrimaryColor.c_str());
g_settings_set_string(bgsetting, "color-shading-type", defColorShading.c_str());
} else if (desktop == "xfce") {
if (defColorExists) {
xfconf_channel_set_property(bgchannel, optionColor.c_str(), &defColor);
@ -311,6 +422,60 @@ RB_METHOD(wallpaperReset)
} else {
xfconf_channel_set_int(bgchannel, optionColorStyle.c_str(), defColorStyle);
}
} else if (desktop == "kde") {
std::stringstream command;
command << "qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript 'string:" <<
"var allDesktops = desktops();" <<
"var data = {";
// Plugin, picture, color, mode, blur
for (auto const& x : defPlugins) {
command << "\"" + x.first + "\": {"
<< "plugin: \"" << x.second << "\"";
if (defPictures.find(x.first) != defPictures.end()) {
std::string picture = defPictures[x.first];
boost::replace_all(picture, "\\", "\\\\");
boost::replace_all(picture, "\"", "\\\"");
boost::replace_all(picture, "'", "\\x27");
command << ", picture: \"" << picture << "\"";
}
if (defColors.find(x.first) != defColors.end()) {
command << ", color: \"" << defColors[x.first] << "\"";
}
if (defModes.find(x.first) != defModes.end()) {
command << ", mode: \"" << defModes[x.first] << "\"";
}
if (defBlurs.find(x.first) != defBlurs.end() && defBlurs[x.first]) {
command << ", blur: true";
}
command << "},";
}
command << "\"no\": {}};" <<
"for (var i = 0, l = allDesktops.length; i < l; ++i) {" <<
"var d = allDesktops[i];" <<
"var dat = data[d.id];" <<
"d.wallpaperPlugin = dat.plugin;" <<
"d.currentConfigGroup = [\"Wallpaper\", \"org.kde.image\", \"General\"];" <<
"if (dat.picture) {" <<
"d.writeConfig(\"Image\", dat.picture);" <<
"}" <<
"if (dat.color) {" <<
"d.writeConfig(\"Color\", dat.color.split(\",\"));" <<
"}" <<
"if (dat.mode) {" <<
"d.writeConfig(\"FillMode\", dat.mode);" <<
"}" <<
"if (dat.blur) {" <<
"d.writeConfig(\"Blur\", dat.blur);" <<
"}" <<
"}" <<
"'";
Debug() << "Reset wallpaper command:" << command.str();
int result = system(command.str().c_str());
Debug() << "Reset result:" << result;
} else {
if (remove(fallbackPath.c_str()) != 0) {
Debug() << "Failed to delete hint.png!";
}
}
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -19,7 +19,7 @@ echo "${white}Compiling ${bold}SyngleChance v${linux_version} ${white}engine for
# Generate makefile and build main + journal
echo "-> ${cyan}Generate makefile...${color_reset}"
qmake
qmake -qt=5
echo "-> ${cyan}Compile engine...${color_reset}"
make -j${make_threads}
echo "-> ${cyan}Compile steamshim...${color_reset}"

View file

@ -48,7 +48,7 @@ unix {
}
!macx: {
QMAKE_CXXFLAGS += -g
PKGCONFIG += giomm-2.4 gtk+-3.0 gdk-3.0 libxfconf-0
PKGCONFIG += gtk+-3.0 gdk-3.0 libxfconf-0
INCLUDEPATH += /usr/include/AL /usr/local/include/AL
LIBS += -lX11
}

View file

@ -2,6 +2,8 @@ PROTO_TEXT = "put me in the big portal"
CEDRIC_TEXT = "put me in the big portal"
RUE_TEXT = "put me in the big portal"
SUPPORTED_DE = ["cinnamon", "gnome", "mate", "kde", "xfce"]
module Script
def self.px
logpos($game_player.x, $game_player.real_x, $game_player.direction == 6)
@ -373,26 +375,43 @@ module Script
end
def self.copy_journal
# If the required directories don't exist, create them
Dir.mkdir(Oneshot::GAME_PATH) unless File.exists?(Oneshot::GAME_PATH)
Dir.mkdir(Oneshot::GAME_PATH + "/Oneshot") unless File.exists?(Oneshot::GAME_PATH + "/Oneshot")
begin
if File.file?(Oneshot::JOURNAL)
File.open(Oneshot::JOURNAL, "rb") do |input|
File.open(Oneshot::GAME_PATH + "/Oneshot/" + Oneshot::JOURNAL, "wb") do |output|
while buff = input.read(4096)
output.write(buff)
begin
# If we're on a supported Linux DE, make a .desktop file
# so the clover icon can be properly shown
if Oneshot::OS == "linux" and SUPPORTED_DE.include? Oneshot::DE
path = "#{Oneshot::GAME_PATH}/Oneshot/#{Oneshot::JOURNAL}.desktop"
File.open(path, "wb") do |output|
output.write("[Desktop Entry]\n")
output.write("Comment=...\n")
output.write("Terminal=false\n")
output.write("Name=_______\n")
output.write("Exec=#{Dir.pwd}/#{Oneshot::JOURNAL}\n")
output.write("Type=Application\n")
output.write("Icon=#{Dir.pwd}/images/icon.png\n")
end
File.chmod(0777, path)
# If the journal is a file, copy it to Documents
elsif File.file?(Oneshot::JOURNAL)
File.open(Oneshot::JOURNAL, "rb") do |input|
File.open("#{Oneshot::GAME_PATH}/Oneshot/#{Oneshot::JOURNAL}", "wb") do |output|
while buff = input.read(4096)
output.write(buff)
end
end
end
# If the journal isn't a file, symlink it
else
File.symlink "#{Dir.pwd}/#{Oneshot::JOURNAL}", "#{Oneshot::GAME_PATH}/Oneshot/#{Oneshot::JOURNAL}"
end
else
File.symlink Dir.pwd + "/" + Oneshot::JOURNAL, Oneshot::GAME_PATH + "/Oneshot/" + Oneshot::JOURNAL
rescue Errno::EACCES => e
# this probably means the clover.exe already exists and is running, so no need to create it again
rescue Errno::EEXIST => e
# this means that the journal file already exists, so no need to create it again
end
rescue Errno::EACCES => e
#this probably means the clover.exe already exists and is running, so no need to create it again
rescue Errno::EEXIST => e
#this means that the journal file already exists, so no need to create it again
end
if File.exists?("README.txt")
if File.exists?("README.txt")
File.open("README.txt", "rb") do |input|
File.open(Oneshot::GAME_PATH + "/Oneshot/README.txt","wb") do |output|
while buff = input.read(4096)
@ -400,7 +419,7 @@ module Script
end
end
end
end
end
end
def self.create_boxes

View file

@ -78,9 +78,11 @@ void ALStream::close()
case Playing:
case Paused:
stopStream();
/* falls through */
case Stopped:
closeSource();
state = Closed;
/* falls through */
case Closed:
return;
}
@ -95,8 +97,10 @@ void ALStream::open(const std::string &filename)
case Playing:
case Paused:
stopStream();
/* falls through */
case Stopped:
closeSource();
/* falls through */
case Closed:
openSource(filename);
}

View file

@ -119,9 +119,11 @@ void AudioStream::play(const std::string &filename,
case ALStream::Paused :
case ALStream::Playing :
stream.stop();
/* falls through */
case ALStream::Stopped :
if (diffFile)
stream.close();
/* falls through */
case ALStream::Closed :
if (diffFile)
{

View file

@ -166,7 +166,6 @@ void EventThread::process(RGSSThreadData &rtData)
char buffer[128];
char pendingTitle[128];
bool havePendingTitle = false;
bool resetting = false;
@ -330,8 +329,6 @@ void EventThread::process(RGSSThreadData &rtData)
/* Prevent fullscreen flicker */
strncpy(pendingTitle, rtData.config.windowTitle.c_str(),
sizeof(pendingTitle));
havePendingTitle = true;
break;
}
@ -458,6 +455,7 @@ void EventThread::process(RGSSThreadData &rtData)
case SDL_FINGERDOWN :
i = event.tfinger.fingerId;
touchState.fingers[i].down = true;
/* falls through */
case SDL_FINGERMOTION :
i = event.tfinger.fingerId;
@ -510,8 +508,6 @@ void EventThread::process(RGSSThreadData &rtData)
if (fullscreen)
{
strncpy(pendingTitle, buffer, sizeof(pendingTitle));
havePendingTitle = true;
break;
}
@ -598,14 +594,6 @@ int EventThread::eventFilter(void *data, SDL_Event *event)
return 0;
}
return 1;
// case SDL_RENDER_TARGETS_RESET :
// Debug() << "****** SDL_RENDER_TARGETS_RESET";
// return 0;
// case SDL_RENDER_DEVICE_RESET :
// Debug() << "****** SDL_RENDER_DEVICE_RESET";
// return 0;
}
return 1;

View file

@ -503,26 +503,6 @@ fontSetEnumCB (void *data, const char *dir, const char *fname)
return PHYSFS_ENUM_OK;
}
/* Basically just a case-insensitive search
* for the folder "Fonts"... */
static PHYSFS_EnumerateCallbackResult
findFontsFolderCB(void *data, const char *, const char *fname)
{
size_t i = 0;
char buffer[512];
const char *s = fname;
while (*s && i < sizeof(buffer))
buffer[i++] = tolower(*s++);
buffer[i] = '\0';
if (strcmp(buffer, "fonts") == 0)
PHYSFS_enumerate(fname, fontSetEnumCB, data);
return PHYSFS_ENUM_OK;
}
void FileSystem::initFontSets(SharedFontState &sfs)
{
FontSetsCBData d = { p, &sfs };

View file

@ -1,8 +1,7 @@
/*
Really hacked-together naiive implementation of gettext
Really hacked-together naiive implementation of gettext
*/
#include "i18n.h"
#include "debugwriter.h"
#include <stdlib.h>
#include <stdio.h>
@ -13,74 +12,76 @@ const char* LOC_HEADER = "ONELOC\x10";
char** strdict = 0;
unsigned int nStr = 0;
int family = LOCALE_FAMILY_LATIN;
size_t readSize;
int getLocaleFamily() {
Debug() << "Get family:" << family;
return family;
return family;
}
const char* findtext(unsigned int msgid, const char* fallback) {
Debug() << "Looking for msg" << msgid << fallback;
if (msgid >= nStr) {
return fallback;
} else {
Debug() << "found" << strdict[msgid];
return strdict[msgid];
}
if (msgid >= nStr) {
return fallback;
} else {
return strdict[msgid];
}
}
void unloadLocale() {
for (unsigned int i = 0; i < nStr; i++) {
free(strdict[i]);
}
free(strdict);
strdict = 0;
nStr = 0;
for (unsigned int i = 0; i < nStr; i++) {
free(strdict[i]);
}
free(strdict);
strdict = 0;
nStr = 0;
}
void _setLocaleFamily(const char* locale) {
if (!strcmp(locale, "ja")
|| !strcmp(locale, "ko")
|| !strcmp(locale, "zh_CN")) {
family = LOCALE_FAMILY_ASIAN;
} else {
family = LOCALE_FAMILY_LATIN;
}
if (!strcmp(locale, "ja")
|| !strcmp(locale, "ko")
|| !strcmp(locale, "zh_CN")) {
family = LOCALE_FAMILY_ASIAN;
} else {
family = LOCALE_FAMILY_LATIN;
}
}
void _read(void * ptr, size_t size, size_t count, FILE * stream) {
readSize = fread(ptr, size, count, stream);
if (readSize != count) {
}
}
void loadLocale(const char* locale) {
Debug() << "Load locale:" << locale;
char pathbuf[100];
FILE* locfile;
char header[8];
unsigned int i;
int strSize = 0;
char pathbuf[100];
FILE* locfile;
char header[8];
unsigned int i;
int strSize = 0;
unloadLocale();
unloadLocale();
_setLocaleFamily(locale);
_setLocaleFamily(locale);
sprintf(pathbuf, "Languages/internal/%s.loc", locale);
locfile = fopen(pathbuf, "rb");
if (locfile) {
fread(header, 1, 8, locfile);
if (!strcmp(header, LOC_HEADER)) {
//read number of strs in this file
fread(&nStr, 4, 1, locfile);
strdict = (char**)malloc(sizeof(char*) * nStr);
for (i = 0; i < nStr; i++) {
//read the size of the next string
fread(&strSize, 4, 1, locfile);
strdict[i] = (char*)malloc(strSize+1);
if (strSize > 0) {
//read the contents of the next string
fread(strdict[i], 1, strSize, locfile);
strdict[i][strSize] = 0;
Debug() << "localization #" << i << " : " << strdict[i] << "|" << strSize;
}
strdict[i][strSize] = 0;
}
}
fclose(locfile);
}
sprintf(pathbuf, "Languages/internal/%s.loc", locale);
locfile = fopen(pathbuf, "rb");
if (locfile) {
_read(header, 1, 8, locfile);
if (!strcmp(header, LOC_HEADER)) {
// Read number of strs in this file
_read(&nStr, 4, 1, locfile);
strdict = (char**)malloc(sizeof(char*) * nStr);
for (i = 0; i < nStr; i++) {
// Read the size of the next string
_read(&strSize, 4, 1, locfile);
strdict[i] = (char*)malloc(strSize+1);
if (strSize > 0) {
// Read the contents of the next string
_read(strdict[i], 1, strSize, locfile);
strdict[i][strSize] = 0;
}
strdict[i][strSize] = 0;
}
}
fclose(locfile);
}
}

View file

@ -200,6 +200,7 @@ int main(int argc, char *argv[])
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "1");
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
/* initialize SDL first */
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0)

View file

@ -13,7 +13,7 @@
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
//OS-Specific code
// OS-Specific code
#if defined _WIN32
#define OS_W32
#define WIN32_LEAN_AND_MEAN
@ -124,7 +124,7 @@ static int linux_dialog(void *rawData)
}
// Display dialog and get result
GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, gtktype, gtkbuttons, data->body);
GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, gtktype, gtkbuttons, "%s", data->body);
gtk_window_set_title(GTK_WINDOW(dialog), data->title);
int result = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
@ -269,7 +269,7 @@ Oneshot::Oneshot(RGSSThreadData &threadData) :
}
// Get documents path
std::string path = std::string(getenv("HOME")) + std::string("/Documents");
std::string path = std::string(getenv("HOME")) + "/Documents";
p->docsPath = path.c_str();
p->gamePath = path.c_str();
#ifdef OS_OSX
@ -279,11 +279,13 @@ Oneshot::Oneshot(RGSSThreadData &threadData) :
#endif
#endif
#ifdef __linux__
#ifdef OS_LINUX
std::string desktop(getenv("XDG_CURRENT_DESKTOP"));
std::transform(desktop.begin(), desktop.end(), desktop.begin(), ::tolower);
if (
desktop.find("cinnamon") != std::string::npos ||
if (desktop.find("cinnamon") != std::string::npos) {
desktopEnv = "cinnamon";
gtk_init(0, 0);
} else if (
desktop.find("gnome") != std::string::npos ||
desktop.find("unity") != std::string::npos
) {
@ -294,6 +296,13 @@ Oneshot::Oneshot(RGSSThreadData &threadData) :
gtk_init(0, 0);
} else if (desktop.find("xfce") != std::string::npos) {
desktopEnv = "xfce";
gtk_init(0, 0);
} else if (desktop.find("kde") != std::string::npos) {
desktopEnv = "kde";
} else if (desktop.find("lxde") != std::string::npos) {
desktopEnv = "lxde";
} else if (desktop.find("deepin") != std::string::npos) {
desktopEnv = "deepin";
}
#endif
@ -471,7 +480,12 @@ bool Oneshot::msgbox(int type, const char *body, const char *title)
if (!title)
title = "";
#if defined OS_LINUX
if (desktopEnv == "gnome" || desktopEnv == "mate") {
if (
desktopEnv == "gnome" ||
desktopEnv == "mate" ||
desktopEnv == "cinnamon" ||
desktopEnv == "xfce"
) {
linux_DialogData data = {type, body, title, 0};
gdk_threads_add_idle(linux_dialog, &data);
gtk_main();
@ -479,16 +493,15 @@ bool Oneshot::msgbox(int type, const char *body, const char *title)
}
#endif
//SDL message box
//Button data
// 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
// Messagebox data
SDL_MessageBoxData data;
data.window = NULL;//p->window;
data.colorScheme = 0;
@ -523,7 +536,7 @@ bool Oneshot::msgbox(int type, const char *body, const char *title)
break;
}
//Set buttons
// Set buttons
switch (type)
{
case MSG_INFO:
@ -539,7 +552,7 @@ bool Oneshot::msgbox(int type, const char *body, const char *title)
break;
}
//Show messagebox
// Show messagebox
#ifdef OS_W32
PlaySoundW((LPCWSTR)sound, NULL, SND_ALIAS_ID | SND_ASYNC);
#endif
@ -580,20 +593,6 @@ std::string Oneshot::textinput(const char* prompt, int char_limit, const char* f
// Disable text input
SDL_StopTextInput();
// //Free loaded images
// gPromptTextTexture.free();
// gInputTextTexture.free();
// //Free global font
// TTF_CloseFont(gFont);
// gFont = NULL;
// //Destroy renderer
// SDL_DestroyRenderer(gRenderer);
// gRenderer = NULL;
// delete promptBmp;
// delete inputBmp;
return threadData.inputText;
}

View file

@ -35,7 +35,6 @@
#include "util.h"
#include "sharedstate.h"
#include "i18n.h"
#include "debugwriter.h"
#include <algorithm>
@ -539,7 +538,6 @@ struct SettingsMenuPrivate
int x, int y, int alignW,
Justification just, SDL_Color c, bool bold = false)
{
Debug() << "draw text:" << str;
SDL_Surface *txt = createTextSurface(str, c, bold);
if (txt) {
blitTextSurf(surf, x, y, alignW, txt, just);

View file

@ -28,7 +28,9 @@ typedef int PipeType;
#ifdef STEAMSHIM_DEBUG
#define dbgpipe printf
#else
static inline void dbgpipe(const char *fmt, ...) {}
static inline void dbgpipe(const char *fmt, ...) {
(void)fmt;
}
#endif
static int writePipe(PipeType fd, const void *buf, const unsigned int _len);

View file

@ -20,7 +20,7 @@ FLAGS += -lsteam_api
ifeq ($(DEBUG),1)
FLAGS += -DSTEAMSHIM_DEBUG
else
else ifeq ($(HOST),w32)
FLAGS += -mwindows
endif

View file

@ -0,0 +1,22 @@
# Steamshim parent
OneShot uses [steamshim](https://hg.icculus.org/icculus/steamshim/) for GNU GPL v3 and Steam interoperability. There are five components that OneShot uses to communicate with Steam, in order:
1. Steamworks SDK (that can be obtained from [here](https://partner.steamgames.com)) that is used for directly communicating with Steam. It is closed-source, and because of license compatibility issues steamshim must be used as a layer between OneShot and Steamworks SDK to communicate with Steam.
2. steamshim parent (whose source is within this folder) is a separate application that will start up the main OneShot application and can communicate with the Steamworks SDK.
3. steamshim child (whose source is inside the `steamshim` folder) is the client used to communicate with the steamshim parent from the OneShot application through pipes.
4. Steam controller inside OneShot application (`src/steam.cpp`) controls the communication between OneShot and steamshim components.
5. Steam binding (`binding-mri/steam-binding.cpp`) creates Ruby objects so Steam functionalities (like achievements) can be controlled from the game's scripts/events and passes on the handling to the Steam controller
## Building
Download Steamworks SDK from [here](https://partner.steamgames.com) and run
```console
$ export LD_LIBRARY_PATH=/path/to/steamworks/sdk/redistributable_bin/platform
$ STEAMWORKS=/path/to/steamworks/sdk HOST=platform make
```
inside this directory, where `platform` can be `win64`, `osx32`, `linux64` or `linux32`
If you need debug output from the steamshim parent, compile with `DEBUG=1` in command-line arguments for `make`.
## Running
After building the steamshim parent, place it in the same directory as the OneShot application. Note that the OneShot application **must be named "oneshot"**. Changing the case ("OneShot") will make the game not launch.
To run the game with the Steam wrapper, run the steamshim parent.

View file

@ -30,7 +30,9 @@ typedef int PipeType;
#ifdef STEAMSHIM_DEBUG
#define dbgpipe printf
#else
static inline void dbgpipe(const char *fmt, ...) {}
static inline void dbgpipe(const char *fmt, ...) {
(void)fmt;
}
#endif
/* platform-specific mainline calls this. */
@ -245,6 +247,7 @@ static bool launchChild(ProcessType *pid)
// we're the child.
GArgv[0] = strdup("./" GAME_LAUNCH_NAME);
dbgpipe("Starting %s\n", GArgv[0]);
execvp(GArgv[0], GArgv);
// still here? It failed! Terminate, closing child's ends of the pipes.
_exit(1);