mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-06 13:16:52 +02:00
#15 reduce executable size, fix keyboard input, turn off LOG in release config
This commit is contained in:
@@ -1,2 +0,0 @@
|
|||||||
clang++ -std=c++11 -Os -s -fno-exceptions -fno-rtti main.cpp ../libs/stb_vorbis/stb_vorbis.c -I../ -o../../bin/OpenLara -lX11 -lGL -lm -lpthread -lpulse-simple -lpulse -ffunction-sections -fdata-sections -Wl,--gc-sections
|
|
||||||
|
|
@@ -1,202 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <pulse/pulseaudio.h>
|
|
||||||
#include <pulse/simple.h>
|
|
||||||
|
|
||||||
#include "game.h"
|
|
||||||
|
|
||||||
#define WND_TITLE "OpenLara"
|
|
||||||
|
|
||||||
#define SND_FRAME_SIZE 4
|
|
||||||
#define SND_DATA_SIZE (1024 * SND_FRAME_SIZE)
|
|
||||||
|
|
||||||
pa_simple *sndOut;
|
|
||||||
pthread_t sndThread;
|
|
||||||
pthread_mutex_t sndMutex;
|
|
||||||
|
|
||||||
Sound::Frame *sndData;
|
|
||||||
|
|
||||||
void* sndFill(void *arg) {
|
|
||||||
while (1) {
|
|
||||||
pthread_mutex_lock(&sndMutex);
|
|
||||||
Sound::fill(sndData, SND_DATA_SIZE / SND_FRAME_SIZE);
|
|
||||||
pthread_mutex_unlock(&sndMutex);
|
|
||||||
pa_simple_write(sndOut, sndData, SND_DATA_SIZE, NULL);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sndInit() {
|
|
||||||
static const pa_sample_spec spec = {
|
|
||||||
.format = PA_SAMPLE_S16LE,
|
|
||||||
.rate = 44100,
|
|
||||||
.channels = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
static const pa_buffer_attr attr = {
|
|
||||||
.maxlength = SND_DATA_SIZE * 2,
|
|
||||||
.tlength = 0xFFFFFFFF,
|
|
||||||
.prebuf = 0xFFFFFFFF,
|
|
||||||
.minreq = SND_DATA_SIZE,
|
|
||||||
.fragsize = 0xFFFFFFFF,
|
|
||||||
};
|
|
||||||
|
|
||||||
pthread_mutex_init(&sndMutex, NULL);
|
|
||||||
|
|
||||||
int error;
|
|
||||||
if (!(sndOut = pa_simple_new(NULL, WND_TITLE, PA_STREAM_PLAYBACK, NULL, "game", &spec, NULL, &attr, &error))) {
|
|
||||||
LOG("pa_simple_new() failed: %s\n", pa_strerror(error));
|
|
||||||
sndData = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sndData = new Sound::Frame[SND_DATA_SIZE / SND_FRAME_SIZE];
|
|
||||||
pthread_create(&sndThread, NULL, sndFill, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sndFree() {
|
|
||||||
if (sndOut) {
|
|
||||||
pthread_cancel(sndThread);
|
|
||||||
pthread_mutex_lock(&sndMutex);
|
|
||||||
// pa_simple_flush(sndOut, NULL);
|
|
||||||
// pa_simple_free(sndOut);
|
|
||||||
pthread_mutex_unlock(&sndMutex);
|
|
||||||
delete[] sndData;
|
|
||||||
}
|
|
||||||
pthread_mutex_destroy(&sndMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getTime() {
|
|
||||||
timeval t;
|
|
||||||
gettimeofday(&t, NULL);
|
|
||||||
return (t.tv_sec * 1000 + t.tv_usec / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
InputKey keyToInputKey(int code) {
|
|
||||||
int codes[] = {
|
|
||||||
113, 114, 111, 116, 65, 36, 9, 50, 37, 64,
|
|
||||||
19, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
|
||||||
38, 56, 54, 40, 26, 41, 42, 43, 31, 44, 45, 46, 58,
|
|
||||||
57, 32, 33, 24, 27, 39, 28, 30, 55, 25, 53, 29, 52,
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(codes) / sizeof(codes[0]); i++)
|
|
||||||
if (codes[i] == code)
|
|
||||||
return (InputKey)(ikLeft + i);
|
|
||||||
return ikNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputKey mouseToInputKey(int btn) {
|
|
||||||
return btn == 0 ? ikMouseL : (btn == 1 ? ikMouseR : ikMouseM);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WndProc(const XEvent &e) {
|
|
||||||
switch (e.type) {
|
|
||||||
case ConfigureNotify :
|
|
||||||
Core::width = e.xconfigure.width;
|
|
||||||
Core::height = e.xconfigure.height;
|
|
||||||
break;
|
|
||||||
case KeyPress :
|
|
||||||
case KeyRelease :
|
|
||||||
Input::setDown(keyToInputKey(e.xkey.keycode), e.type == KeyPress);
|
|
||||||
break;
|
|
||||||
case ButtonPress :
|
|
||||||
case ButtonRelease : {
|
|
||||||
InputKey key = mouseToInputKey(e.xbutton.button);
|
|
||||||
Input::setPos(key, Input::mouse.pos);
|
|
||||||
Input::setDown(key, e.type == ButtonPress);
|
|
||||||
printf("%d\n", (int)e.xbutton.button);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MotionNotify :
|
|
||||||
Input::setPos(ikMouseL, vec2((float)e.xmotion.x, (float)e.xmotion.y));
|
|
||||||
printf("mouse: %d %d\n", (int)e.xmotion.x, (int)e.xmotion.y);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
static int XGLAttr[] = {
|
|
||||||
GLX_RGBA,
|
|
||||||
GLX_DOUBLEBUFFER,
|
|
||||||
GLX_DEPTH_SIZE, 24,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
Display *dpy = XOpenDisplay(NULL);
|
|
||||||
XVisualInfo *vis = glXChooseVisual(dpy, XDefaultScreen(dpy), XGLAttr);
|
|
||||||
|
|
||||||
XSetWindowAttributes attr;
|
|
||||||
attr.colormap = XCreateColormap(dpy, RootWindow(dpy, vis->screen), vis->visual, AllocNone);
|
|
||||||
attr.border_pixel = 0;
|
|
||||||
attr.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask |
|
|
||||||
ButtonPressMask | ButtonReleaseMask |
|
|
||||||
ButtonMotionMask | PointerMotionMask;
|
|
||||||
|
|
||||||
Window wnd = XCreateWindow(dpy, RootWindow(dpy, vis->screen),
|
|
||||||
0, 0, 1280, 720, 0,
|
|
||||||
vis->depth, InputOutput, vis->visual,
|
|
||||||
CWColormap | CWBorderPixel | CWEventMask, &attr);
|
|
||||||
XStoreName(dpy, wnd, WND_TITLE);
|
|
||||||
|
|
||||||
GLXContext ctx = glXCreateContext(dpy, vis, NULL, true);
|
|
||||||
glXMakeCurrent(dpy, wnd, ctx);
|
|
||||||
XMapWindow(dpy, wnd);
|
|
||||||
|
|
||||||
Atom WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", 0);
|
|
||||||
XSetWMProtocols(dpy, wnd, &WM_DELETE_WINDOW, 1);
|
|
||||||
|
|
||||||
// XGrabPointer(dpy, wnd, false,
|
|
||||||
// ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ButtonMotionMask,
|
|
||||||
// GrabModeAsync, GrabModeAsync, wnd, None, CurrentTime);
|
|
||||||
XGrabKeyboard(dpy, wnd, false, 1, 1, 0);
|
|
||||||
|
|
||||||
sndInit();
|
|
||||||
Game::init();
|
|
||||||
|
|
||||||
int lastTime = getTime(), fpsTime = lastTime + 1000, fps = 0;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (XPending(dpy)) {
|
|
||||||
XEvent event;
|
|
||||||
XNextEvent(dpy, &event);
|
|
||||||
if (event.type == ClientMessage && *event.xclient.data.l == WM_DELETE_WINDOW)
|
|
||||||
break;
|
|
||||||
WndProc(event);
|
|
||||||
} else {
|
|
||||||
int time = getTime();
|
|
||||||
if (time <= lastTime)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float delta = (time - lastTime) * 0.001f;
|
|
||||||
pthread_mutex_lock(&sndMutex);
|
|
||||||
while (delta > EPS) {
|
|
||||||
Core::deltaTime = min(delta, 1.0f / 30.0f);
|
|
||||||
Game::update();
|
|
||||||
delta -= Core::deltaTime;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&sndMutex);
|
|
||||||
lastTime = time;
|
|
||||||
|
|
||||||
Core::stats.dips = 0;
|
|
||||||
Core::stats.tris = 0;
|
|
||||||
Game::render();
|
|
||||||
glXSwapBuffers(dpy, wnd);
|
|
||||||
|
|
||||||
if (fpsTime < getTime()) {
|
|
||||||
LOG("FPS: %d DIP: %d TRI: %d\n", fps, Core::stats.dips, Core::stats.tris);
|
|
||||||
fps = 0;
|
|
||||||
fpsTime = getTime() + 1000;
|
|
||||||
} else
|
|
||||||
fps++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
sndFree();
|
|
||||||
Game::free();
|
|
||||||
|
|
||||||
glXMakeCurrent(dpy, 0, 0);
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
return 0;
|
|
||||||
}
|
|
Reference in New Issue
Block a user