mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-13 16:44:50 +02:00
Merge branch 'master' of https://github.com/XProger/OpenLara
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
set -e
|
||||
clang++ -std=c++11 -Os -s -g -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -Wl,--gc-sections -DNDEBUG -D__RPI__ main.cpp ../../libs/stb_vorbis/stb_vorbis.c -I/opt/vc/include -I../../ -o../../../bin/OpenLara.bin -L/opt/vc/lib/ -lbrcmGLESv2 -lbrcmEGL -lX11 -lm -lrt -lpthread -lpulse-simple -lpulse -lbcm_host -ludev
|
||||
clang++ -std=c++11 -Os -s -g -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -Wl,--gc-sections -DNDEBUG -D__RPI__ main.cpp ../../libs/stb_vorbis/stb_vorbis.c -I/opt/vc/include -I../../ -o../../../bin/OpenLara -L/opt/vc/lib/ -lbrcmGLESv2 -lbrcmEGL -lX11 -lm -lrt -lpthread -lasound -lbcm_host -ludev
|
||||
strip ../../../bin/OpenLara --strip-all --remove-section=.comment --remove-section=.note
|
||||
|
@@ -9,72 +9,13 @@
|
||||
#include <fcntl.h>
|
||||
#include <linux/input.h>
|
||||
#include <libudev.h>
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include <pulse/simple.h>
|
||||
#include <alsa/asoundlib.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("! sound: pa_simple_new() %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);
|
||||
}
|
||||
|
||||
// Time
|
||||
unsigned int startTime;
|
||||
|
||||
int getTime() {
|
||||
@@ -83,6 +24,90 @@ int getTime() {
|
||||
return int((t.tv_sec - startTime) * 1000 + t.tv_usec / 1000);
|
||||
}
|
||||
|
||||
// Sound
|
||||
snd_pcm_uframes_t SND_FRAMES = 512;
|
||||
snd_pcm_t *sndOut;
|
||||
Sound::Frame *sndData;
|
||||
pthread_t sndThread;
|
||||
pthread_mutex_t sndMutex;
|
||||
|
||||
void* sndFill(void *arg) {
|
||||
while (sndOut) {
|
||||
pthread_mutex_lock(&sndMutex);
|
||||
Sound::fill(sndData, SND_FRAMES);
|
||||
pthread_mutex_unlock(&sndMutex);
|
||||
|
||||
int err = snd_pcm_writei(sndOut, sndData, SND_FRAMES);
|
||||
if (err < 0) {
|
||||
LOG("! sound: write %s\n", snd_strerror(err));;
|
||||
if (err != -EPIPE)
|
||||
break;
|
||||
|
||||
err = snd_pcm_recover(sndOut, err, 0);
|
||||
if (err < 0) {
|
||||
LOG("! sound: failed to recover\n");
|
||||
break;
|
||||
}
|
||||
snd_pcm_prepare(sndOut);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool sndInit() {
|
||||
unsigned int freq = 44100;
|
||||
|
||||
pthread_mutex_init(&sndMutex, NULL);
|
||||
|
||||
int err;
|
||||
if ((err = snd_pcm_open(&sndOut, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
|
||||
LOG("! sound: open %s\n", snd_strerror(err));\
|
||||
sndOut = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
snd_pcm_hw_params_t *params;
|
||||
|
||||
snd_pcm_hw_params_alloca(¶ms);
|
||||
snd_pcm_hw_params_any(sndOut, params);
|
||||
snd_pcm_hw_params_set_access(sndOut, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
|
||||
snd_pcm_hw_params_set_channels(sndOut, params, 2);
|
||||
snd_pcm_hw_params_set_format(sndOut, params, SND_PCM_FORMAT_S16_LE);
|
||||
snd_pcm_hw_params_set_rate_near(sndOut, params, &freq, NULL);
|
||||
|
||||
snd_pcm_hw_params_set_periods(sndOut, params, 4, 0);
|
||||
snd_pcm_hw_params_set_period_size_near(sndOut, params, &SND_FRAMES, NULL);
|
||||
snd_pcm_hw_params_get_period_size(params, &SND_FRAMES, 0);
|
||||
|
||||
snd_pcm_hw_params(sndOut, params);
|
||||
snd_pcm_prepare(sndOut);
|
||||
|
||||
sndData = new Sound::Frame[SND_FRAMES];
|
||||
memset(sndData, 0, SND_FRAMES * sizeof(Sound::Frame));
|
||||
if ((err = snd_pcm_writei(sndOut, sndData, SND_FRAMES)) < 0) {
|
||||
LOG("! sound: write %s\n", snd_strerror(err));\
|
||||
sndOut = NULL;
|
||||
}
|
||||
|
||||
snd_pcm_start(sndOut);
|
||||
pthread_create(&sndThread, NULL, sndFill, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void sndFree() {
|
||||
pthread_cancel(sndThread);
|
||||
pthread_mutex_lock(&sndMutex);
|
||||
snd_pcm_drop(sndOut);
|
||||
snd_pcm_drain(sndOut);
|
||||
snd_pcm_close(sndOut);
|
||||
pthread_mutex_unlock(&sndMutex);
|
||||
pthread_mutex_destroy(&sndMutex);
|
||||
delete[] sndData;
|
||||
}
|
||||
|
||||
// Window
|
||||
bool wndInit(DISPMANX_DISPLAY_HANDLE_T &display, EGL_DISPMANX_WINDOW_T &window) {
|
||||
if (graphics_get_display_size(0, (uint32_t*)&window.width, (uint32_t*)&window.height) < 0) {
|
||||
LOG("! can't get display size\n");
|
||||
@@ -270,8 +295,8 @@ void inputDevAdd(const char *node) {
|
||||
int index = inputDevIndex(node);
|
||||
if (index != -1) {
|
||||
inputDevices[index] = open(node, O_RDONLY | O_NONBLOCK);
|
||||
//ioctl(inputDevices[index], EVIOCGRAB, (void*)1);
|
||||
LOG("input: add %s\n", node);
|
||||
ioctl(inputDevices[index], EVIOCGRAB, 1);
|
||||
//LOG("input: add %s\n", node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +304,7 @@ void inputDevRemove(const char *node) {
|
||||
int index = inputDevIndex(node);
|
||||
if (index != -1 && inputDevices[index] != -1) {
|
||||
close(inputDevices[index]);
|
||||
LOG("input: remove %s\n", node);
|
||||
//LOG("input: remove %s\n", node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,7 +423,7 @@ void inputUpdate() {
|
||||
char Stream::cacheDir[255];
|
||||
char Stream::contentDir[255];
|
||||
|
||||
int main() {
|
||||
int main(int argc, char **argv) {
|
||||
bcm_host_init();
|
||||
|
||||
DISPMANX_DISPLAY_HANDLE_T dmDisplay;
|
||||
@@ -416,8 +441,6 @@ int main() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
inputInit();
|
||||
|
||||
Stream::contentDir[0] = Stream::cacheDir[0] = 0;
|
||||
|
||||
const char *home;
|
||||
@@ -435,7 +458,13 @@ int main() {
|
||||
startTime = t.tv_sec;
|
||||
|
||||
sndInit();
|
||||
Game::init();
|
||||
|
||||
char *lvlName = argc > 1 ? argv[1] : NULL;
|
||||
char *sndName = argc > 2 ? argv[2] : NULL;
|
||||
|
||||
Game::init(lvlName, sndName);
|
||||
|
||||
inputInit(); // initialize and grab input devices
|
||||
|
||||
int lastTime = getTime();
|
||||
|
||||
|
Reference in New Issue
Block a user