Lots of stuff

This commit is contained in:
Mathew Velasquez 2016-12-06 23:49:17 -05:00
parent cce13d8d01
commit aa7818847c
14 changed files with 531 additions and 47 deletions

View file

@ -5,50 +5,74 @@
#include <SDL.h>
#define OUT_BUFFER_SIZE 256
#if defined __linux
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>
#endif
#define BUFFER_SIZE 256
static SDL_Thread *thread = NULL;
static SDL_mutex *mutex = NULL;
static volatile char message_buffer[OUT_BUFFER_SIZE];
static volatile int message_len = 0;
static volatile char message_buffer[BUFFER_SIZE];
static volatile bool active = false;
#if defined __linux
#define PIPE_PATH "/tmp/oneshot-pipe"
static volatile int message_len = 0;
static volatile int out_pipe = -1;
void cleanup_pipe()
{
unlink(PIPE_PATH);
}
#endif
int server_thread(void *data)
{
(void)data;
#if defined _WIN32
HANDLE pipe = CreateNamedPipeW(L"\\\\.\\pipe\\oneshot-journal-to-game",
PIPE_ACCESS_OUTBOUND,
PIPE_TYPE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
OUT_BUFFER_SIZE,
OUT_BUFFER_SIZE,
BUFFER_SIZE,
BUFFER_SIZE,
0,
NULL);
for (;;) {
ConnectNamedPipe(pipe, NULL);
SDL_LockMutex(mutex);
WriteFile(pipe, (const void*)message_buffer, OUT_BUFFER_SIZE, NULL, NULL);
DWORD written;
WriteFile(pipe, (const void*)message_buffer, BUFFER_SIZE, &written, NULL);
active = true;
SDL_UnlockMutex(mutex);
FlushFileBuffers(pipe);
DisconnectNamedPipe(pipe);
}
CloseHandle(pipe);
#elif defined __linux
out_pipe = open(PIPE_PATH, O_WRONLY);
active = true;
SDL_LockMutex(mutex);
if (message_len > 0)
write(out_pipe, (char*)message_buffer, message_len);
SDL_UnlockMutex(mutex);
return 0;
#endif
}
RB_METHOD(journalSet)
{
RB_UNUSED_PARAM;
const char *name;
int len;
rb_get_args(argc, argv, "s", &name, &len RB_ARG_END);
#ifdef _WIN32
if (thread == NULL) {
thread = SDL_CreateThread(server_thread, "journal", NULL);
}
rb_get_args(argc, argv, "z", &name RB_ARG_END);
#if defined _WIN32
SDL_LockMutex(mutex);
strcpy((char*)message_buffer, name);
SDL_UnlockMutex(mutex);
HANDLE pipe = CreateFileW(L"\\\\.\\pipe\\oneshot-game-to-journal",
GENERIC_WRITE,
0,
@ -56,28 +80,60 @@ RB_METHOD(journalSet)
OPEN_EXISTING,
0,
NULL);
SDL_LockMutex(mutex);
strcpy((char*)message_buffer, name);
message_len = len;
SDL_UnlockMutex(mutex);
if (pipe != INVALID_HANDLE_VALUE) {
active = true;
WriteFile(pipe, (const void*)message_buffer, OUT_BUFFER_SIZE, NULL, NULL);
DWORD written;
WriteFile(pipe, (const void*)message_buffer, BUFFER_SIZE, &written, NULL);
FlushFileBuffers(pipe);
CloseHandle(pipe);
}
if (thread == NULL) {
thread = SDL_CreateThread(server_thread, "journal", NULL);
}
#elif defined __linux
// Clean up connection thread
if (thread != NULL && out_pipe != -1) {
SDL_WaitThread(thread, NULL);
thread = NULL;
}
// Record message
SDL_LockMutex(mutex);
message_len = strlen(name);
memcpy((char*)message_buffer, name, message_len);
SDL_UnlockMutex(mutex);
// Attempt to send it over the tubes
if (out_pipe != -1) {
// We have a connection, so send it over
if (write(out_pipe, (char*)message_buffer, message_len) <= 0) {
// In the case of an error, close
close(out_pipe);
out_pipe = -1;
}
}
if (out_pipe == -1) {
// We don't have a pipe open, so spawn the connection thread
thread = SDL_CreateThread(server_thread, "journal", NULL);
}
#else
#error "not yet implemented"
#endif
return Qnil;
}
RB_METHOD(journalActive)
{
RB_UNUSED_PARAM;
return active ? Qtrue : Qfalse;
}
void journalBindingInit()
{
mutex = SDL_CreateMutex();
#if defined __linux
mkfifo(PIPE_PATH, 0666);
atexit(cleanup_pipe);
#endif
VALUE module = rb_define_module("Journal");
_rb_define_module_function(module, "set", journalSet);

View file

@ -4,26 +4,34 @@
#include "eventthread.h"
#include "debugwriter.h"
#ifdef _WIN32
#if defined _WIN32
#include <shlwapi.h>
#endif
#include <SDL.h>
namespace syswm {
#include <SDL_syswm.h>
}
#define NIKO_X (320 - 16)
#define NIKO_Y ((13 * 16) * 2)
RB_METHOD(nikoStart)
{
RB_UNUSED_PARAM;
// Calculate where to stick the window
POINT pos;
pos.x = 320 - 16;
pos.y = (13 * 16) * 2;
SDL_SysWMinfo syswindow;
// Prime native window info
syswm::SDL_SysWMinfo syswindow;
SDL_VERSION(&syswindow.version);
SDL_GetWindowWMInfo(shState->rtData().window, &syswindow);
#if defined _WIN32
// Calculate where to stick the window
POINT pos;
pos.x = NIKO_X;
pos.y = NIKO_Y;
ClientToScreen(syswindow.info.win.window, &pos);
// Start process
#ifdef _WIN32
WCHAR path[MAX_PATH];
WCHAR args[MAX_PATH];
GetModuleFileNameW(NULL, path, MAX_PATH);
@ -35,10 +43,36 @@ RB_METHOD(nikoStart)
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
CreateProcessW(path, args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
#elif defined __linux
// Calculate where to stick the window
int x, y; // Top-left area of client (hopefully)
SDL_GetWindowPosition(shState->rtData().window, &x, &y);
x += NIKO_X;
y += NIKO_Y;
char path[PATH_MAX];
ssize_t len = readlink("/proc/self/exe", path, PATH_MAX);
if (len > 0) {
// Replace filename
for (size_t i = len; i > 0; --i) {
if (path[i-1] == '/') {
strcpy(path + i, "_______");
break;
}
}
// X and Y string arguments
char x_str[16];
char y_str[16];
sprintf(x_str, "%d", x);
sprintf(y_str, "%d", y);
// Assume that was a success and run the binary
pid_t pid = fork();
if (pid == 0) {
execl(path, "_______", x_str, y_str, NULL);
exit(1);
}
}
#else
#ifdef linux
#else
#endif
#error "not yet implemented"
#endif
return Qnil;
}

View file

@ -46,7 +46,9 @@ unix:!macx {
linux/display.h \
linux/image.h
LIBS += -lxcb -lxcb-util -lxcb-image -lxcb-shape
QMAKE_CFLAGS += -pthread
LIBS += -pthread -lxcb -lxcb-util -lxcb-image -lxcb-shape -lxcb-icccm -lxcb-ewmh
}
# OS X

View file

@ -11,5 +11,7 @@ struct Display {
};
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define STRING(x) sizeof(x) - 1, (x)
#define ARRAY(x) sizeof(x), (x)
#endif // DISPLAY_H

View file

@ -1,6 +1,235 @@
#include <xcb/xcb_ewmh.h>
#include <xcb/xcb_icccm.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include "display.h"
#include "image.h"
#define PIPE_DIR "/tmp"
#define PIPE_NAME "oneshot-pipe"
#define PIPE_PATH PIPE_DIR "/" PIPE_NAME
#define MESSAGE_BUF_SIZE 256
#define PAGES \
PAGE(default) \
PAGE(c1) \
PAGE(c2) \
PAGE(c3) \
PAGE(c4) \
PAGE(c5) \
PAGE(c6) \
PAGE(c7) \
PAGE(s1) \
PAGE(s2) \
PAGE(s3) \
PAGE(s4) \
PAGE(t1) \
PAGE(t2) \
PAGE(t3) \
PAGE(t4) \
PAGE(t5) \
PAGE(t6) \
PAGE(t7) \
PAGE(t8) \
PAGE(t9) \
PAGE(t10) \
PAGE(t11) \
PAGE(t12) \
PAGE(t13) \
PAGE(t14) \
PAGE(t15) \
PAGE(t16) \
PAGE(final) \
PAGE(save)
struct ThreadData {
struct Display *dpy;
xcb_window_t window;
xcb_gcontext_t gc;
xcb_pixmap_t *masks;
xcb_pixmap_t *images;
volatile int page;
};
void set_page(struct ThreadData *threaddata, const char *name)
{
int page = 0;
#define PAGE(x) if (strncmp(name, #x, MESSAGE_BUF_SIZE) == 0) { goto end; } else { ++page; }
PAGES
#undef PAGE
end:
threaddata->page = page;
xcb_shape_mask(threaddata->dpy->c, ShapeSet, ShapeBounding,
threaddata->window, 0, 0, threaddata->masks[page]);
xcb_copy_area(threaddata->dpy->c,
threaddata->images[page],
threaddata->window,
threaddata->gc,
0, 0, 0, 0, JOURNAL_WIDTH, JOURNAL_HEIGHT);
xcb_flush(threaddata->dpy->c);
}
static void *ipc_thread(void *data)
{
struct ThreadData *threaddata = (struct ThreadData*)data;
for (;;) {
// Try to open pipe
int pipe = open(PIPE_PATH, O_RDONLY);
if (pipe == -1) {
// Use the default image for now
set_page(threaddata, "default");
// Wait until the pipe appears to try again
int inotify = inotify_init();
inotify_add_watch(inotify, PIPE_DIR, IN_CREATE);
char inotify_buf[sizeof(struct inotify_event) + NAME_MAX + 1];
for (;;) {
ssize_t result = read(inotify, inotify_buf, sizeof(inotify_buf));
if (result > 0) {
struct inotify_event *e = (struct inotify_event*)inotify_buf;
if (strcmp(e->name, PIPE_NAME) == 0)
break;
} else {
break;
}
}
close(inotify);
} else {
// Message loop
char message[MESSAGE_BUF_SIZE];
for (;;) {
ssize_t len = read(pipe, message, sizeof(message));
if (len > 0) {
set_page(threaddata, message);
} else if (len == 0) {
exit(0); // empty string
} else {
// End of the line
break;
}
}
close(pipe);
}
}
return NULL;
}
int do_journal(struct Display *dpy)
{
// Connect EWMH
xcb_ewmh_connection_t ewmh;
xcb_ewmh_init_atoms_replies(&ewmh, xcb_ewmh_init_atoms(dpy->c, &ewmh), NULL);
// Request some atoms
xcb_intern_atom_cookie_t WM_DELETE_WINDOW_cookie = xcb_intern_atom(dpy->c, false, STRING("WM_DELETE_WINDOW"));
xcb_intern_atom_cookie_t _NET_WM_PING_cookie = xcb_intern_atom(dpy->c, false, STRING("_NET_WM_PING"));
xcb_intern_atom_cookie_t WM_PROTOCOLS_cookie = xcb_intern_atom(dpy->c, false, STRING("WM_PROTOCOLS"));
xcb_atom_t WM_DELETE_WINDOW = xcb_intern_atom_reply(dpy->c, WM_DELETE_WINDOW_cookie, NULL)->atom;
xcb_atom_t _NET_WM_PING = xcb_intern_atom_reply(dpy->c, _NET_WM_PING_cookie, NULL)->atom;
xcb_atom_t WM_PROTOCOLS = xcb_intern_atom_reply(dpy->c, WM_PROTOCOLS_cookie, NULL)->atom;
// Create window
uint32_t values[] = {
XCB_EVENT_MASK_EXPOSURE, // event mask
};
xcb_window_t window = xcb_generate_id(dpy->c);
xcb_create_window(dpy->c, XCB_COPY_FROM_PARENT, window, dpy->screen->root,
0, 0, JOURNAL_WIDTH, JOURNAL_HEIGHT,
0, XCB_WINDOW_CLASS_INPUT_OUTPUT, dpy->screen->root_visual,
XCB_CW_EVENT_MASK, &values);
xcb_atom_t protocols[] = {
WM_DELETE_WINDOW,
_NET_WM_PING,
};
xcb_icccm_set_wm_protocols(dpy->c, window, WM_PROTOCOLS, ARRAY(protocols));
xcb_icccm_set_wm_name(dpy->c, window, XCB_ATOM_STRING, 8, STRING(""));
xcb_icccm_set_wm_class(dpy->c, window, ARRAY("_______\0OneshotJournal"));
xcb_ewmh_set_wm_window_type(&ewmh, window, 1, &ewmh._NET_WM_WINDOW_TYPE_NORMAL);
xcb_size_hints_t size_hints;
xcb_icccm_size_hints_set_min_size(&size_hints, JOURNAL_WIDTH, JOURNAL_HEIGHT);
xcb_icccm_size_hints_set_max_size(&size_hints, JOURNAL_WIDTH, JOURNAL_HEIGHT);
xcb_icccm_set_wm_size_hints(dpy->c, window, XCB_ATOM_WM_NORMAL_HINTS, &size_hints);
// Create pixmaps
xcb_pixmap_t masks[] = {
#define PAGE(x) create_mask(dpy->c, window, x##_mask, JOURNAL_WIDTH, JOURNAL_HEIGHT),
PAGES
#undef PAGE
};
xcb_pixmap_t images[] = {
#define PAGE(x) create_image(dpy->c, window, x##_rgb, JOURNAL_WIDTH, JOURNAL_HEIGHT),
PAGES
#undef PAGE
};
// Create graphics context
xcb_gcontext_t gc = xcb_generate_id(dpy->c);
xcb_create_gc(dpy->c, gc, window, 0, NULL);
// Start IPC thread
struct ThreadData threaddata = {
dpy,
window,
gc,
masks,
images,
0,
};
pthread_t thread;
if (pthread_create(&thread, NULL, ipc_thread, &threaddata) != 0)
return 1;
// Map!
xcb_map_window(dpy->c, window);
xcb_flush(dpy->c);
// Handle events
xcb_generic_event_t *e;
while ((e = xcb_wait_for_event(dpy->c))) {
switch (e->response_type & ~0x80) {
case XCB_EXPOSE: {
xcb_expose_event_t *ee = (xcb_expose_event_t*)e;
xcb_copy_area(dpy->c, images[threaddata.page],
window, gc,
ee->x, ee->y, ee->x, ee->y,
ee->width, ee->height);
xcb_flush(dpy->c);
} break;
case XCB_CLIENT_MESSAGE: {
xcb_client_message_event_t *ce = (xcb_client_message_event_t*)e;
if (ce->type == WM_PROTOCOLS && ce->format == 32) {
xcb_atom_t atom = ce->data.data32[0];
if (atom == WM_DELETE_WINDOW) {
goto end;
} else if (atom == _NET_WM_PING) {
ce->window = dpy->screen->root;
xcb_send_event(dpy->c, false, dpy->screen->root,
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
(const char*)e);
}
}
} break;
}
free(e);
}
end:
xcb_free_gc(dpy->c, gc);
for (size_t i = 0; i < ARRAY_SIZE(masks); ++i) {
xcb_free_pixmap(dpy->c, masks[i]);
xcb_free_pixmap(dpy->c, images[i]);
}
return 0;
}

View file

@ -86,6 +86,7 @@ int do_niko(struct Display *dpy, int x, int y)
xcb_flush(dpy->c);
} break;
}
free(e);
} else if (getticks() - ticks >= 1000 / 60) {
break;
}

View file

@ -6,6 +6,8 @@
#define DEFAULT_HEIGHT 600
#define IN_BUFFER_SIZE 256
#define WINDOW_STYLE (WS_OVERLAPPEDWINDOW ^ (WS_THICKFRAME | WS_MAXIMIZEBOX))
static const WCHAR journal_classname[] = L"journal";
static HBITMAP image_handle = NULL;
@ -132,7 +134,7 @@ int do_journal()
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = module;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIcon = LoadIcon(NULL, "MAINICON");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
@ -142,12 +144,19 @@ int do_journal()
if (!RegisterClassEx(&wc))
return 1;
RECT winrect;
winrect.left = 0;
winrect.top = 0;
winrect.right = DEFAULT_WIDTH;
winrect.bottom = DEFAULT_HEIGHT;
AdjustWindowRectEx(&winrect, WINDOW_STYLE, FALSE, 0);
if (!(window = CreateWindowExW(WS_EX_COMPOSITED | WS_EX_LAYERED,
journal_classname,
L"",
WS_OVERLAPPEDWINDOW ^ (WS_THICKFRAME | WS_MAXIMIZEBOX),
WINDOW_STYLE,
CW_USEDEFAULT, CW_USEDEFAULT,
DEFAULT_WIDTH, DEFAULT_HEIGHT,
winrect.right - winrect.left, winrect.bottom - winrect.top,
NULL, NULL, module, NULL))) {
return 1;
}

View file

@ -56,6 +56,7 @@ unix {
PKGCONFIG += openal zlib
INCLUDEPATH += /usr/include/AL /usr/local/include/AL
SOURCES += src/xdg-user-dir-lookup.c
LIBS += -lX11
}
}

View file

@ -106,7 +106,7 @@ bool EventThread::allocUserEvents()
EventThread::EventThread()
: fullscreen(false),
showCursor(false)
showCursor(true)
{}
void EventThread::process(RGSSThreadData &rtData)

View file

@ -65,7 +65,7 @@ void subRectImageEnd()
}
}
#define HAVE_NATIVE_VAO gl.GenVertexArrays
#define HAVE_NATIVE_VAO false //gl.GenVertexArrays
static void vaoBindRes(VAO &vao)
{

View file

@ -42,7 +42,7 @@ struct GLProperty
}
void push() { stack.push(current); }
void pop() { set(stack.top()); stack.pop(); }
void pop() { if (!stack.empty()) { set(stack.top()); stack.pop(); } }
const T &get() { return current; }
void set(const T &value)
{

View file

@ -7,8 +7,17 @@
/* Achievements */
static const char *const achievementNames[] = {
"SaveWorld",
"SaveNiko",
"CHAOTIC_EVIL",
"SHOCK",
"EXTREME_BARTENDING",
"RAM_WHISPERER",
"PANCAKES",
"WE_RIDE_AT_DAWN",
"SECRET",
"BOOKWORM",
"REBIRTH",
"ONESHOT",
"RETURN",
};
#define NUM_ACHIEVEMENTS (sizeof(achievementNames) / sizeof(achievementNames[0]))

View file

@ -10,10 +10,10 @@
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
@ -29,7 +29,146 @@
#include <stdlib.h>
#include <string.h>
/**
* xdg_user_dir_lookup_with_fallback:
* @type: a string specifying the type of directory
* @fallback: value to use if the directory isn't specified by the user
* @returns: a newly allocated absolute pathname
*
* Looks up a XDG user directory of the specified type.
* Example of types are "DESKTOP" and "DOWNLOAD".
*
* In case the user hasn't specified any directory for the specified
* type the value returned is @fallback.
*
* The return value is newly allocated and must be freed with
* free(). The return value is never NULL if @fallback != NULL, unless
* out of memory.
**/
static char *
xdg_user_dir_lookup_with_fallback (const char *type, const char *fallback)
{
FILE *file;
char *home_dir, *config_home, *config_file;
char buffer[512];
char *user_dir;
char *p, *d;
int len;
int relative;
home_dir = getenv ("HOME");
if (home_dir == NULL)
goto error;
config_home = getenv ("XDG_CONFIG_HOME");
if (config_home == NULL || config_home[0] == 0)
{
config_file = (char*) malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1);
if (config_file == NULL)
goto error;
strcpy (config_file, home_dir);
strcat (config_file, "/.config/user-dirs.dirs");
}
else
{
config_file = (char*) malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1);
if (config_file == NULL)
goto error;
strcpy (config_file, config_home);
strcat (config_file, "/user-dirs.dirs");
}
file = fopen (config_file, "r");
free (config_file);
if (file == NULL)
goto error;
user_dir = NULL;
while (fgets (buffer, sizeof (buffer), file))
{
/* Remove newline at end */
len = strlen (buffer);
if (len > 0 && buffer[len-1] == '\n')
buffer[len-1] = 0;
p = buffer;
while (*p == ' ' || *p == '\t')
p++;
if (strncmp (p, "XDG_", 4) != 0)
continue;
p += 4;
if (strncmp (p, type, strlen (type)) != 0)
continue;
p += strlen (type);
if (strncmp (p, "_DIR", 4) != 0)
continue;
p += 4;
while (*p == ' ' || *p == '\t')
p++;
if (*p != '=')
continue;
p++;
while (*p == ' ' || *p == '\t')
p++;
if (*p != '"')
continue;
p++;
relative = 0;
if (strncmp (p, "$HOME/", 6) == 0)
{
p += 6;
relative = 1;
}
else if (*p != '/')
continue;
if (relative)
{
user_dir = (char*) malloc (strlen (home_dir) + 1 + strlen (p) + 1);
if (user_dir == NULL)
goto error2;
strcpy (user_dir, home_dir);
strcat (user_dir, "/");
}
else
{
user_dir = (char*) malloc (strlen (p) + 1);
if (user_dir == NULL)
goto error2;
*user_dir = 0;
}
d = user_dir + strlen (user_dir);
while (*p && *p != '"')
{
if ((*p == '\\') && (*(p+1) != 0))
p++;
*d++ = *p++;
}
*d = 0;
}
error2:
fclose (file);
if (user_dir)
return user_dir;
error:
if (fallback)
return strdup (fallback);
return NULL;
}
/**
* xdg_user_dir_lookup:
@ -52,16 +191,16 @@ static char *
xdg_user_dir_lookup (const char *type)
{
char *dir, *home_dir, *user_dir;
dir = xdg_user_dir_lookup_with_fallback (type, NULL);
if (dir != NULL)
return dir;
home_dir = getenv ("HOME");
if (home_dir == NULL)
return strdup ("/tmp");
/* Special case desktop for historical compatibility */
if (strcmp (type, "DESKTOP") == 0)
{
@ -73,7 +212,7 @@ xdg_user_dir_lookup (const char *type)
strcat (user_dir, "/Desktop");
return user_dir;
}
return strdup (home_dir);
}
@ -86,7 +225,7 @@ main (int argc, char *argv[])
fprintf (stderr, "Usage %s <dir-type>\n", argv[0]);
exit (1);
}
printf ("%s\n", xdg_user_dir_lookup (argv[1]));
return 0;
}

View file

@ -7,7 +7,7 @@ HOST ?= linux64
FLAGS := -I$(STEAMWORKS)/public -DGAME_LAUNCH_NAME=\"$(GAME_LAUNCH_NAME)\" -Wall
ifeq ($(HOST),w32)
FLAGS += -L$(STEAMWORKS)/redistributable_bin -mwindows
FLAGS += -L$(STEAMWORKS)/redistributable_bin
else ifeq ($(HOST),linux32)
FLAGS += -L$(STEAMWORKS)/redistributable_bin/linux32 -m32
else ifeq ($(HOST),linux64)
@ -20,6 +20,8 @@ FLAGS += -lsteam_api
ifeq ($(DEBUG),1)
FLAGS += -DSTEAMSHIM_DEBUG
else
FLAGS += -mwindows
endif
SRC := steamshim_parent.cpp