mirror of
https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1.git
synced 2026-03-19 22:43:32 +00:00
the whole game
This commit is contained in:
72
src/platform/CThread.cpp
Executable file
72
src/platform/CThread.cpp
Executable file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* CThread.cpp
|
||||
* oxeye
|
||||
*
|
||||
* Created by aegzorz on 2007-02-09.
|
||||
* Copyright 2007 Mojang AB. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "CThread.h"
|
||||
|
||||
|
||||
|
||||
CThread::CThread( pthread_fn threadFunc, void* threadParam )
|
||||
{
|
||||
#ifdef WIN32
|
||||
mp_threadFunc = (LPTHREAD_START_ROUTINE) threadFunc;
|
||||
|
||||
m_threadHandle = CreateThread(
|
||||
NULL, // pointer to security attributes
|
||||
NULL, // initial thread stack size
|
||||
mp_threadFunc, // pointer to thread function
|
||||
threadParam, // argument for new thread
|
||||
NULL, // creation flags
|
||||
&m_threadID // pointer to receive thread ID
|
||||
);
|
||||
#endif
|
||||
#if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX)
|
||||
mp_threadFunc = (pthread_fn)threadFunc;
|
||||
|
||||
pthread_attr_init(&m_attributes);
|
||||
pthread_attr_setdetachstate( &m_attributes, PTHREAD_CREATE_DETACHED );
|
||||
/*int error =*/ pthread_create(&m_thread, &m_attributes, mp_threadFunc,threadParam);
|
||||
#endif
|
||||
#ifdef MACOSX
|
||||
mp_threadFunc = (TaskProc) threadFunc;
|
||||
|
||||
MPCreateTask(
|
||||
mp_threadFunc, // pointer to thread function
|
||||
threadParam, // argument for new thread
|
||||
0, // initial thread stack size
|
||||
NULL, // queue id
|
||||
NULL, // termination param 1
|
||||
NULL, // termination param 2
|
||||
0, // task options
|
||||
&m_threadID // pointer to receive task ID
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CThread::sleep( const unsigned int millis )
|
||||
{
|
||||
#ifdef WIN32
|
||||
Sleep( millis );
|
||||
#endif
|
||||
#if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX)
|
||||
usleep(millis * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
CThread::~CThread()
|
||||
{
|
||||
#ifdef WIN32
|
||||
TerminateThread(m_threadHandle, 0);
|
||||
#endif
|
||||
#if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX)
|
||||
pthread_join(m_thread, NULL);
|
||||
pthread_attr_destroy(&m_attributes);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
55
src/platform/CThread.h
Executable file
55
src/platform/CThread.h
Executable file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* CThread.h
|
||||
* Created by aegzorz on 2007-02-09.
|
||||
* Copyright 2007 Oxeye. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _OX_CORE_CTHREAD_H_
|
||||
#define _OX_CORE_CTHREAD_H_
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
typedef void *( * pthread_fn )( void * );
|
||||
|
||||
#if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX)
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#endif
|
||||
#ifdef MACOSX
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
class CThread
|
||||
{
|
||||
public:
|
||||
CThread( pthread_fn threadFunc, void* threadParam );
|
||||
|
||||
virtual ~CThread();
|
||||
|
||||
static void sleep( const unsigned int millis );
|
||||
|
||||
private:
|
||||
#ifdef WIN32
|
||||
LPTHREAD_START_ROUTINE mp_threadFunc;
|
||||
DWORD m_threadID;
|
||||
HANDLE m_threadHandle;
|
||||
#endif
|
||||
#if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX)
|
||||
pthread_fn mp_threadFunc;
|
||||
pthread_t m_thread;
|
||||
pthread_attr_t m_attributes;
|
||||
#endif
|
||||
#ifdef MACOSX
|
||||
TaskProc mp_threadFunc;
|
||||
MPTaskID m_threadID;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // _OX_CORE_CTHREAD_H_
|
||||
29
src/platform/audio/SoundSystem.h
Executable file
29
src/platform/audio/SoundSystem.h
Executable file
@@ -0,0 +1,29 @@
|
||||
#ifndef SoundSystem_H__
|
||||
#define SoundSystem_H__
|
||||
|
||||
#include "../../world/level/tile/Tile.h"
|
||||
#include <string>
|
||||
|
||||
class SoundDesc;
|
||||
|
||||
class SoundSystem
|
||||
{
|
||||
public:
|
||||
SoundSystem() {}
|
||||
virtual ~SoundSystem() {}
|
||||
|
||||
virtual bool isAvailable() { return false; }
|
||||
virtual void enable(bool status) {}
|
||||
|
||||
virtual void setListenerPos(float x, float y, float z){}
|
||||
virtual void setListenerAngle(float deg){}
|
||||
|
||||
virtual void load(const std::string& name){}
|
||||
virtual void play(const std::string& name){}
|
||||
virtual void pause(const std::string& name){}
|
||||
virtual void stop(const std::string& name){}
|
||||
|
||||
virtual void playAt(const SoundDesc& desc, float x, float y, float z, float volume, float pitch){}
|
||||
};
|
||||
|
||||
#endif /*SoundSystem_H__ */
|
||||
253
src/platform/audio/SoundSystemAL.cpp
Executable file
253
src/platform/audio/SoundSystemAL.cpp
Executable file
@@ -0,0 +1,253 @@
|
||||
//#include "ios/OpenALSupport.h"
|
||||
#include "SoundSystemAL.h"
|
||||
#include "../../util/Mth.h"
|
||||
#include "../../world/level/tile/Tile.h"
|
||||
#include "../../world/phys/Vec3.h"
|
||||
#include "../../client/sound/Sound.h"
|
||||
|
||||
#include "../log.h"
|
||||
|
||||
static const char* errIdString = 0;
|
||||
|
||||
void checkError() {
|
||||
|
||||
while (1) {
|
||||
ALenum err = alGetError();
|
||||
if(err == AL_NO_ERROR) return;
|
||||
|
||||
LOGI("### SoundSystemAL error: %d ####: %s\n", err, errIdString==0?"(none)":errIdString);
|
||||
}
|
||||
}
|
||||
|
||||
//typedef ALvoid AL_APIENTRY (*alBufferDataStaticProcPtr) (const ALint bid, ALenum format, ALvoid *data, ALsizei size, ALsizei freq);
|
||||
//ALvoid alBufferDataStaticProc(const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq)
|
||||
//{
|
||||
// static alBufferDataStaticProcPtr proc = NULL;
|
||||
//
|
||||
// if (proc == NULL) {
|
||||
// proc = (alBufferDataStaticProcPtr) alcGetProcAddress(NULL, (const ALCchar*) "alBufferDataStatic");
|
||||
// }
|
||||
//
|
||||
// if (proc)
|
||||
// proc(bid, format, data, size, freq);
|
||||
//
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
SoundSystemAL::SoundSystemAL()
|
||||
: available(true),
|
||||
context(0),
|
||||
device(0),
|
||||
_rotation(-9999.9f)
|
||||
{
|
||||
_buffers.reserve(64);
|
||||
init();
|
||||
}
|
||||
|
||||
SoundSystemAL::~SoundSystemAL()
|
||||
{
|
||||
alDeleteSources(MaxNumSources, _sources);
|
||||
|
||||
for (int i = 0; i < (int)_buffers.size(); ++i)
|
||||
if (_buffers[i].inited) alDeleteBuffers(1, &_buffers[i].bufferID);
|
||||
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(context);
|
||||
|
||||
// Close the device
|
||||
alcCloseDevice(device);
|
||||
}
|
||||
|
||||
void SoundSystemAL::init()
|
||||
{
|
||||
device = alcOpenDevice(NULL);
|
||||
if(device) {
|
||||
context = alcCreateContext(device, NULL);
|
||||
alcMakeContextCurrent(context);
|
||||
|
||||
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
|
||||
|
||||
alGenSources(MaxNumSources, _sources);
|
||||
for(int index = 0; index < MaxNumSources; index++) {
|
||||
ALuint sourceID = _sources[index];
|
||||
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, 5.0f);
|
||||
alSourcef(sourceID, AL_MAX_DISTANCE, 16.0f);
|
||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, 6.0f);
|
||||
}
|
||||
|
||||
float listenerPos[] = {0, 0, 0};
|
||||
float listenerOri[] = {0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
|
||||
float listenerVel[] = {0, 0, 0};
|
||||
alListenerfv(AL_POSITION, listenerPos);
|
||||
alListenerfv(AL_ORIENTATION, listenerOri);
|
||||
alListenerfv(AL_VELOCITY, listenerVel);
|
||||
|
||||
errIdString = "Init audio";
|
||||
checkError();
|
||||
}
|
||||
}
|
||||
|
||||
void SoundSystemAL::enable(bool status) {
|
||||
LOGI("Enabling? audio: %d (context %p)\n", status, context);
|
||||
if (status) {
|
||||
alcMakeContextCurrent(context);
|
||||
errIdString = "Enable audio";
|
||||
}
|
||||
else {
|
||||
alcMakeContextCurrent(NULL);
|
||||
errIdString = "Disable audio";
|
||||
}
|
||||
|
||||
checkError();
|
||||
}
|
||||
|
||||
void SoundSystemAL::destroy() {}
|
||||
|
||||
void SoundSystemAL::setListenerPos( float x, float y, float z )
|
||||
{
|
||||
// Note: listener position is thought to be 0,0,0 now
|
||||
|
||||
/*
|
||||
if (_listenerPos.x != x || _listenerPos.y != y || _listenerPos.z != z) {
|
||||
_listenerPos.set(x, y, z);
|
||||
alListener3f(AL_POSITION, x, y, z);
|
||||
|
||||
static int _n = 0;
|
||||
if (++_n == 20) {
|
||||
_n = 0;
|
||||
LOGI("Setting position for listener: %f, %f, %f\n", _listenerPos.x, _listenerPos.y, _listenerPos.z);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void SoundSystemAL::setListenerAngle( float deg )
|
||||
{
|
||||
if (_rotation != deg) {
|
||||
_rotation = deg;
|
||||
|
||||
float rad = deg * Mth::DEGRAD;
|
||||
|
||||
static ALfloat orientation[] = {0, 0, 0, 0, 1, 0};
|
||||
orientation[0] = -Mth::sin( rad );
|
||||
orientation[2] = Mth::cos( rad );
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}
|
||||
}
|
||||
|
||||
void SoundSystemAL::playAt( const SoundDesc& sound, float x, float y, float z, float volume, float pitch )
|
||||
{
|
||||
if (pitch < 0.01f) pitch = 1;
|
||||
|
||||
//LOGI("playing sound '%s' with volume/pitch: %f, %f @ %f, %f, %f\n", sound.name.c_str(), volume, pitch, x, y, z);
|
||||
|
||||
ALuint bufferID;
|
||||
if (!getBufferId(sound, &bufferID)) {
|
||||
errIdString = "Get buffer (failed)";
|
||||
checkError();
|
||||
LOGE("getBufferId returned false!\n");
|
||||
return;
|
||||
}
|
||||
errIdString = "Get buffer";
|
||||
checkError();
|
||||
//LOGI("playing sound %d - '%s' with volume/pitch: %f, %f @ %f, %f, %f\n", bufferID, sound.name.c_str(), volume, pitch, x, y, z);
|
||||
|
||||
int sourceIndex;
|
||||
errIdString = "Get free index";
|
||||
if (!getFreeSourceIndex(&sourceIndex)) {
|
||||
LOGI("No free sound sources left @ SoundSystemAL::playAt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ALuint sourceID = _sources[sourceIndex];
|
||||
checkError();
|
||||
|
||||
alSourcei(sourceID, AL_BUFFER, 0);
|
||||
errIdString = "unbind";
|
||||
checkError();
|
||||
alSourcei(sourceID, AL_BUFFER, bufferID);
|
||||
errIdString = "bind";
|
||||
checkError();
|
||||
|
||||
alSourcef(sourceID, AL_PITCH, pitch);
|
||||
errIdString = "pitch";
|
||||
checkError();
|
||||
alSourcef(sourceID, AL_GAIN, volume);
|
||||
errIdString = "gain";
|
||||
checkError();
|
||||
|
||||
alSourcei(sourceID, AL_LOOPING, AL_FALSE);
|
||||
errIdString = "looping";
|
||||
checkError();
|
||||
alSource3f(sourceID, AL_POSITION, x, y, z);
|
||||
errIdString = "position";
|
||||
checkError();
|
||||
|
||||
alSourcePlay(sourceID);
|
||||
errIdString = "source play";
|
||||
|
||||
checkError();
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void SoundSystemAL::removeStoppedSounds()
|
||||
{
|
||||
}
|
||||
|
||||
bool SoundSystemAL::getFreeSourceIndex(int* sourceIndex) {
|
||||
for (int i = 0; i < MaxNumSources; ++i) {
|
||||
ALint state;
|
||||
alGetSourcei(_sources[i], AL_SOURCE_STATE, &state);
|
||||
if(state != AL_PLAYING) {
|
||||
*sourceIndex = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SoundSystemAL::getBufferId(const SoundDesc& sound, ALuint* buf) {
|
||||
for (int i = 0; i < (int)_buffers.size(); ++i) {
|
||||
// Points to the same data buffer -> sounds equal
|
||||
if (_buffers[i].framePtr == sound.frames) {
|
||||
//LOGI("Found %p for %s!\n", sound.frames, sound.name.c_str());
|
||||
*buf = _buffers[i].bufferID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sound.isValid()) {
|
||||
LOGE("Err: sound is invalid @ getBufferId! %s\n", sound.name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
ALuint bufferID;
|
||||
alGenBuffers(1, &bufferID);
|
||||
errIdString = "Gen buffer";
|
||||
checkError();
|
||||
|
||||
ALenum format = (sound.byteWidth==2) ?
|
||||
(sound.channels==2? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16)
|
||||
: (sound.channels==2? AL_FORMAT_STEREO8 : AL_FORMAT_MONO8);
|
||||
|
||||
alBufferData(bufferID, format, sound.frames, sound.size, sound.frameRate);
|
||||
//LOGI("Creating %d (%p) from sound: '%s'\n", bufferID, sound.frames, sound.name.c_str());
|
||||
errIdString = "Buffer data";
|
||||
//LOGI("Creating buffer with data: %d (%d), %p, %d, %d\n", format, sound.byteWidth, sound.frames, sound.size, sound.frameRate);
|
||||
checkError();
|
||||
|
||||
//LOGI("Sound ch: %d, fmt: %d, frames: %p, len: %f, fr: %d, sz: %d, numfr: %d\n", sound.channels, format, sound.frames, sound.length(), sound.frameRate, sound.size, sound.numFrames);
|
||||
|
||||
|
||||
Buffer buffer;
|
||||
buffer.inited = true;
|
||||
buffer.framePtr = sound.frames;
|
||||
buffer.bufferID = bufferID;
|
||||
*buf = bufferID;
|
||||
_buffers.push_back(buffer);
|
||||
|
||||
// @huge @attn @note @fix: The original data is free'd
|
||||
sound.destroy();
|
||||
return true;
|
||||
}
|
||||
73
src/platform/audio/SoundSystemAL.h
Executable file
73
src/platform/audio/SoundSystemAL.h
Executable file
@@ -0,0 +1,73 @@
|
||||
#ifndef SoundSystemAL_H__
|
||||
#define SoundSystemAL_H__
|
||||
|
||||
#include "SoundSystem.h"
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
//
|
||||
// NOTE: This class is only the core OpenAL part of the sound engine.
|
||||
// Some audio setup code can still be managed from respective app
|
||||
// setup code (e.g. the main app delegate for iOS).
|
||||
//
|
||||
|
||||
class SoundSystemAL: public SoundSystem
|
||||
{
|
||||
//typedef std::list<SLObjectItf> SoundList;
|
||||
public:
|
||||
SoundSystemAL();
|
||||
~SoundSystemAL();
|
||||
|
||||
virtual void init();
|
||||
virtual void destroy();
|
||||
|
||||
virtual void enable(bool status);
|
||||
|
||||
virtual void setListenerPos(float x, float y, float z);
|
||||
virtual void setListenerAngle(float deg);
|
||||
|
||||
virtual void load(const std::string& name){}
|
||||
virtual void play(const std::string& name){}
|
||||
virtual void pause(const std::string& name){}
|
||||
virtual void stop(const std::string& name){}
|
||||
virtual void playAt(const SoundDesc& sound, float x, float y, float z, float volume, float pitch);
|
||||
|
||||
private:
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer()
|
||||
: inited(false)
|
||||
{}
|
||||
bool inited;
|
||||
ALuint bufferID;
|
||||
char* framePtr;
|
||||
};
|
||||
|
||||
void removeStoppedSounds();
|
||||
|
||||
static const int MaxNumSources = 12;
|
||||
|
||||
//SoundList playingBuffers;
|
||||
|
||||
Vec3 _listenerPos;
|
||||
float _rotation;
|
||||
|
||||
bool available;
|
||||
|
||||
ALCcontext* context;
|
||||
ALCdevice* device;
|
||||
|
||||
ALuint _sources[MaxNumSources];
|
||||
std::vector<Buffer> _buffers;
|
||||
|
||||
bool getFreeSourceIndex(int* src);
|
||||
bool getBufferId(const SoundDesc& sound, ALuint* buf);
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
#endif /*SoundSystemAL_H__ */
|
||||
243
src/platform/audio/SoundSystemSL.cpp
Executable file
243
src/platform/audio/SoundSystemSL.cpp
Executable file
@@ -0,0 +1,243 @@
|
||||
#include "SoundSystemSL.h"
|
||||
#include <SLES/OpenSLES_Platform.h>
|
||||
#include <SLES/OpenSLES_AndroidConfiguration.h>
|
||||
#include "../../util/Mth.h"
|
||||
#include "../../world/level/tile/Tile.h"
|
||||
#include "../../world/phys/Vec3.h"
|
||||
#include "../../client/sound/Sound.h"
|
||||
|
||||
#include "../log.h"
|
||||
|
||||
// Only one engine can be created at once. You CAN (if you really want)
|
||||
// start two games at once, then it will crash without objEngine being static.
|
||||
/*static*/ SLObjectItf SoundSystemSL::objEngine = 0;
|
||||
|
||||
typedef struct t_context {
|
||||
SLObjectItf obj;
|
||||
Mutex* mutex;
|
||||
} t_context;
|
||||
|
||||
Mutex SoundSystemSL::toRemoveMutex;
|
||||
std::vector<SLObjectItf> SoundSystemSL::toRemove;
|
||||
|
||||
SoundSystemSL::SoundSystemSL()
|
||||
: available(true),
|
||||
listener(NULL),
|
||||
numBuffersPlaying(0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
SoundSystemSL::~SoundSystemSL()
|
||||
{
|
||||
toRemoveMutex.unlock();
|
||||
for (SoundList::iterator it = playingBuffers.begin(); it != playingBuffers.end(); ++it)
|
||||
(**it)->Destroy(*it);
|
||||
(*objOutput)->Destroy(objOutput);
|
||||
|
||||
if (SoundSystemSL::objEngine != 0) {
|
||||
(*SoundSystemSL::objEngine)->Destroy(SoundSystemSL::objEngine);
|
||||
SoundSystemSL::objEngine = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundSystemSL::init()
|
||||
{
|
||||
SoundSystemSL::toRemove.clear();
|
||||
SoundSystemSL::toRemove.reserve(MAX_BUFFERS_PLAYING);
|
||||
toRemoveCopy.resize(MAX_BUFFERS_PLAYING);
|
||||
|
||||
SLresult res;
|
||||
const int MAX_NUMBER_INTERFACES = 2;
|
||||
SLboolean required[MAX_NUMBER_INTERFACES];
|
||||
SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
|
||||
|
||||
SLEngineOption EngineOption[] = {(SLuint32)
|
||||
SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE};
|
||||
|
||||
/* Create OpenSL ES (destroy first if needed)*/
|
||||
if (SoundSystemSL::objEngine != 0)
|
||||
(*SoundSystemSL::objEngine)->Destroy(SoundSystemSL::objEngine);
|
||||
|
||||
res = slCreateEngine( &SoundSystemSL::objEngine, 1, EngineOption, 0, NULL, NULL);
|
||||
checkErr(res);
|
||||
|
||||
/* Realizing the SL Engine in synchronous mode. */
|
||||
res = (*SoundSystemSL::objEngine)->Realize(SoundSystemSL::objEngine, SL_BOOLEAN_FALSE);
|
||||
if (checkErr(res)) {
|
||||
available = false;
|
||||
return;
|
||||
}
|
||||
|
||||
(*SoundSystemSL::objEngine)->GetInterface(SoundSystemSL::objEngine, SL_IID_ENGINE, (void*)&engEngine);
|
||||
checkErr(res);
|
||||
|
||||
/* Create Output Mix object to be used by player - no interfaces
|
||||
required */
|
||||
res = (*engEngine)->CreateOutputMix(engEngine, &objOutput, 0, iidArray, required);
|
||||
checkErr(res);
|
||||
|
||||
/* Realizing the Output Mix object in synchronous mode. */
|
||||
res = (*objOutput)->Realize(objOutput, SL_BOOLEAN_FALSE);
|
||||
checkErr(res);
|
||||
}
|
||||
|
||||
void SoundSystemSL::destroy() {}
|
||||
|
||||
void SoundSystemSL::setListenerPos( float x, float y, float z )
|
||||
{
|
||||
if (!listener) {
|
||||
listenerPos = Vec3(x, y, z);
|
||||
return;
|
||||
}
|
||||
|
||||
SLVec3D pos = {1000.0f * x, 1000.0f * y, 1000.0f * z};
|
||||
SLresult res = (*listener)->SetLocationCartesian(listener, &pos);
|
||||
checkErr(res);
|
||||
}
|
||||
|
||||
void SoundSystemSL::setListenerAngle( float deg )
|
||||
{
|
||||
if (!listener) return;
|
||||
|
||||
SLresult res = (*listener)->SetOrientationAngles(listener, deg*1000.0f, 0, 0);
|
||||
checkErr(res);
|
||||
}
|
||||
|
||||
void SoundSystemSL::playAt( const SoundDesc& sound, float x, float y, float z, float volume, float pitch )
|
||||
{
|
||||
removeStoppedSounds();
|
||||
|
||||
if (numBuffersPlaying >= MAX_BUFFERS_PLAYING)
|
||||
return;
|
||||
|
||||
/* Setup the data source structure for the player */
|
||||
SLDataLocator_AndroidSimpleBufferQueue uri = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
|
||||
SLDataFormat_PCM mime = {
|
||||
SL_DATAFORMAT_PCM,
|
||||
sound.channels,
|
||||
sound.frameRate * 1000,
|
||||
sound.byteWidth << 3,
|
||||
sound.byteWidth << 3,
|
||||
sound.channels==1? SL_SPEAKER_FRONT_CENTER :
|
||||
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
|
||||
SL_BYTEORDER_LITTLEENDIAN
|
||||
};
|
||||
SLDataSource audioSource = {&uri, &mime};
|
||||
SLDataLocator_OutputMix locator_outputmix;
|
||||
SLDataSink audioSink;
|
||||
SLObjectItf player;
|
||||
SLPlayItf playItf;
|
||||
//SL3DLocationItf locationItf;
|
||||
SLVolumeItf volumeItf;
|
||||
|
||||
/* Setup the data sink structure */
|
||||
locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
|
||||
locator_outputmix.outputMix = objOutput;
|
||||
audioSink.pLocator = (void *)&locator_outputmix;
|
||||
audioSink.pFormat = NULL;
|
||||
|
||||
/* Buffer queue-able */
|
||||
static SLboolean required[2];
|
||||
static SLInterfaceID iidArray[2];
|
||||
required[0] = SL_BOOLEAN_TRUE;
|
||||
iidArray[0] = SL_IID_BUFFERQUEUE;
|
||||
required[1] = SL_BOOLEAN_TRUE;
|
||||
iidArray[1] = SL_IID_VOLUME;
|
||||
|
||||
/* Create the 3D player */
|
||||
SLresult res = (*engEngine)->CreateAudioPlayer(engEngine, &player,
|
||||
&audioSource, &audioSink, 2, iidArray, required);
|
||||
//printf("SL: Created audio player\n");
|
||||
checkErr(res);
|
||||
|
||||
/* Realizing the player in synchronous mode. */
|
||||
res = (*player)->Realize(player, SL_BOOLEAN_FALSE);
|
||||
//LOGI("SL: Realize audio player\n");
|
||||
checkErr(res);
|
||||
|
||||
/* Get the play and volume interfaces */
|
||||
res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
|
||||
//LOGI("SL: Get Player interface\n");
|
||||
checkErr(res);
|
||||
|
||||
res = (*player)->GetInterface(player, SL_IID_VOLUME, (void*)&volumeItf);
|
||||
//LOGI("SL: Get Player interface\n");
|
||||
checkErr(res);
|
||||
|
||||
SLmillibel maxVolume;
|
||||
res = (*volumeItf)->GetMaxVolumeLevel(volumeItf, &maxVolume);
|
||||
SLmillibel mbelVolume = maxVolume - 2000 * (1-volume);//Mth::lerp(SL_MILLIBEL_MIN, maxVolume, 0.95f + 0.05f*volume);
|
||||
LOGI("min: %d, max: %d, current: %d (%f)\n", SL_MILLIBEL_MIN, maxVolume, mbelVolume, volume);
|
||||
res = (*volumeItf)->SetVolumeLevel(volumeItf, mbelVolume);
|
||||
checkErr(res);
|
||||
|
||||
SLAndroidSimpleBufferQueueItf buffer1;
|
||||
res = (*player)->GetInterface(player, SL_IID_BUFFERQUEUE, &buffer1);
|
||||
checkErr(res);
|
||||
|
||||
//t_context* context = new t_context(); //{ player, &toRemoveMutex };
|
||||
//context->obj = player;
|
||||
//context->mutex = &toRemoveMutex;
|
||||
res = (*buffer1)->RegisterCallback(buffer1, SoundSystemSL::removePlayer, (void*)player);
|
||||
checkErr(res);
|
||||
|
||||
res = (*buffer1)->Enqueue(buffer1, sound.frames, sound.size);
|
||||
checkErr(res);
|
||||
|
||||
/* Start playing the 3D source */
|
||||
res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
|
||||
//LOGI("SL: Set play state\n");
|
||||
checkErr(res);
|
||||
|
||||
playingBuffers.push_back(player);
|
||||
++numBuffersPlaying;
|
||||
}
|
||||
|
||||
bool SoundSystemSL::checkErr( SLresult res )
|
||||
{
|
||||
if ( res != SL_RESULT_SUCCESS ) {
|
||||
LOGI("OpenSL error: %d\n", res);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void SoundSystemSL::removeStoppedSounds()
|
||||
{
|
||||
toRemoveMutex.lock();
|
||||
const int numBuffersToRemove = toRemove.size();
|
||||
for (int i = 0; i < numBuffersToRemove; ++i)
|
||||
toRemoveCopy[i] = toRemove[i];
|
||||
SoundSystemSL::toRemove.clear();
|
||||
toRemoveMutex.unlock();
|
||||
|
||||
for (int i = 0; i < numBuffersToRemove; ++i) {
|
||||
SLObjectItf obj = toRemoveCopy[i];
|
||||
|
||||
SoundList::iterator it = playingBuffers.begin();
|
||||
while (it != playingBuffers.end()) {
|
||||
if (*it == obj) {
|
||||
playingBuffers.erase(it);
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
(*obj)->Destroy(obj);
|
||||
--numBuffersPlaying;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundSystemSL::removePlayer( SLAndroidSimpleBufferQueueItf bq, void *context_ )
|
||||
{
|
||||
//t_context* context = (t_context*) context_;
|
||||
//context->mutex->lock();
|
||||
//SoundSystemSL::toRemove.push_back( context->obj );
|
||||
//context->mutex->unlock();
|
||||
//delete context;
|
||||
|
||||
SoundSystemSL::toRemoveMutex.lock();
|
||||
SoundSystemSL::toRemove.push_back( (SLObjectItf) context_ );
|
||||
SoundSystemSL::toRemoveMutex.unlock();
|
||||
}
|
||||
79
src/platform/audio/SoundSystemSL.h
Executable file
79
src/platform/audio/SoundSystemSL.h
Executable file
@@ -0,0 +1,79 @@
|
||||
#ifndef SoundSystemSL_H__
|
||||
#define SoundSystemSL_H__
|
||||
|
||||
#include "SoundSystem.h"
|
||||
#include <SLES/OpenSLES.h>
|
||||
#include <SLES/OpenSLES_Android.h>
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <pthread.h>
|
||||
class Mutex {
|
||||
pthread_mutex_t _mutex;
|
||||
public:
|
||||
Mutex() { pthread_mutex_init(&_mutex, NULL); }
|
||||
~Mutex() { pthread_mutex_destroy(&_mutex); }
|
||||
void lock() { pthread_mutex_lock(&_mutex); }
|
||||
void unlock() { pthread_mutex_unlock(&_mutex); }
|
||||
};
|
||||
#else
|
||||
class Mutex {
|
||||
public:
|
||||
Mutex() {}
|
||||
void lock() {}
|
||||
void unlock() {};
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
class SoundSystemSL: public SoundSystem
|
||||
{
|
||||
typedef std::list<SLObjectItf> SoundList;
|
||||
public:
|
||||
SoundSystemSL();
|
||||
~SoundSystemSL();
|
||||
|
||||
virtual void init();
|
||||
virtual void destroy();
|
||||
|
||||
virtual void setListenerPos(float x, float y, float z);
|
||||
virtual void setListenerAngle(float deg);
|
||||
|
||||
virtual void load(const std::string& name){}
|
||||
virtual void play(const std::string& name){}
|
||||
virtual void pause(const std::string& name){}
|
||||
virtual void stop(const std::string& name){}
|
||||
virtual void playAt(const SoundDesc& sound, float x, float y, float z, float volume, float pitch);
|
||||
|
||||
private:
|
||||
bool checkErr( SLresult res );
|
||||
|
||||
void removeStoppedSounds();
|
||||
|
||||
SoundList playingBuffers;
|
||||
|
||||
static SLObjectItf objEngine;
|
||||
SLEngineItf engEngine;
|
||||
|
||||
SLObjectItf objListener;
|
||||
SL3DLocationItf listener;
|
||||
|
||||
SLObjectItf objOutput;
|
||||
|
||||
Vec3 listenerPos;
|
||||
int numBuffersPlaying;
|
||||
|
||||
bool available;
|
||||
std::vector<SLObjectItf> toRemoveCopy;
|
||||
|
||||
static Mutex toRemoveMutex;
|
||||
static std::vector<SLObjectItf> toRemove;
|
||||
static const int MAX_BUFFERS_PLAYING = 4;
|
||||
|
||||
public:
|
||||
static void removePlayer(SLAndroidSimpleBufferQueueItf bq, void *context);
|
||||
};
|
||||
|
||||
#endif /*SoundSystemSL_H__ */
|
||||
68
src/platform/file.h
Executable file
68
src/platform/file.h
Executable file
@@ -0,0 +1,68 @@
|
||||
#ifndef FILE_H__
|
||||
#define FILE_H__
|
||||
|
||||
bool DeleteDirectory(const std::string&, bool noRecycleBin = true);
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <shellapi.h>
|
||||
#include <string>
|
||||
|
||||
bool DeleteDirectory(const std::string& dir, bool noRecycleBin /*true*/)
|
||||
{
|
||||
int len = strlen(dir.c_str());
|
||||
//TCHAR *pszFrom = new TCHAR[len+2];
|
||||
char* pszFrom = new char[len+2];
|
||||
strncpy(pszFrom, dir.c_str(), len);
|
||||
pszFrom[len] = 0;
|
||||
pszFrom[len+1] = 0;
|
||||
|
||||
SHFILEOPSTRUCT fileop;
|
||||
fileop.hwnd = NULL; // no status display
|
||||
fileop.wFunc = FO_DELETE; // delete operation
|
||||
fileop.pFrom = pszFrom; // source file name as double null terminated string
|
||||
fileop.pTo = NULL; // no destination needed
|
||||
fileop.fFlags = FOF_NOCONFIRMATION|FOF_SILENT; // do not prompt the user
|
||||
|
||||
if(!noRecycleBin)
|
||||
fileop.fFlags |= FOF_ALLOWUNDO;
|
||||
|
||||
fileop.fAnyOperationsAborted = FALSE;
|
||||
fileop.lpszProgressTitle = NULL;
|
||||
fileop.hNameMappings = NULL;
|
||||
|
||||
int ret = SHFileOperation(&fileop);
|
||||
delete [] pszFrom;
|
||||
return (ret == 0);
|
||||
}
|
||||
#else
|
||||
#include <cstdio>
|
||||
#include <dirent.h>
|
||||
|
||||
bool DeleteDirectory(const std::string& d, bool noRecycleBin /*true*/)
|
||||
{
|
||||
const char* folder = d.c_str();
|
||||
|
||||
const size_t CMAX = 1024;
|
||||
char fullPath[CMAX];
|
||||
DIR* dir = opendir(folder);
|
||||
if (!dir)
|
||||
return false;
|
||||
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir))) {
|
||||
if (strcmp(".", entry->d_name) && strcmp("..", entry->d_name)) {
|
||||
snprintf(fullPath, CMAX, "%s/%s", folder, entry->d_name);
|
||||
remove(fullPath);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return remove(folder) == 0;
|
||||
}
|
||||
|
||||
#endif /*(ELSE) WIN32*/
|
||||
|
||||
#endif /*FILE_H__*/
|
||||
75
src/platform/input/Controller.cpp
Executable file
75
src/platform/input/Controller.cpp
Executable file
@@ -0,0 +1,75 @@
|
||||
#include "Controller.h"
|
||||
|
||||
static int _abs(int x) { return x>=0? x:-x; }
|
||||
static float _abs(float x) { return x>=0? x:-x; }
|
||||
|
||||
/*static*/ float Controller::stickValuesX[NUM_STICKS] = {0};
|
||||
/*static*/ float Controller::stickValuesY[NUM_STICKS] = {0};
|
||||
/*static*/ bool Controller::isTouchedValues[NUM_STICKS] = {0};
|
||||
|
||||
bool Controller::isTouched( int stickIndex )
|
||||
{
|
||||
if (!isValidStick(stickIndex)) return false;
|
||||
|
||||
return isTouchedValues[stickIndex-1];
|
||||
}
|
||||
|
||||
void Controller::feed( int stickIndex, int state, float dx, float dy )
|
||||
{
|
||||
if (!isValidStick(stickIndex)) return;
|
||||
|
||||
if (NUM_STICKS == 2)
|
||||
stickIndex = dx<0? 1 : 2;
|
||||
|
||||
isTouchedValues[stickIndex-1] = (state != STATE_RELEASE);
|
||||
|
||||
// @note: Since I don't know where to put the Xperia Play specific
|
||||
// calculations, I put them here! (normally I would probably have
|
||||
// some kind of (XperiaPlay)ControllerReader but it doesn't make much
|
||||
// more sense as long as we cant figure out (in code) whether or not
|
||||
// we actually use an Xperia -> hardcode it here (Note#2, we CAN figure
|
||||
// figure this out, at least by JNI/java-call but we arent doing it)
|
||||
static float offsets[3] = {0, 0.64f, -0.64f};
|
||||
dx = linearTransform(dx + offsets[stickIndex], 0, 2.78f, true);
|
||||
|
||||
stickValuesX[stickIndex-1] = dx;
|
||||
stickValuesY[stickIndex-1] = dy;
|
||||
}
|
||||
|
||||
float Controller::getX( int stickIndex )
|
||||
{
|
||||
if (!isValidStick(stickIndex)) return 0;
|
||||
return stickValuesX[stickIndex-1];
|
||||
}
|
||||
|
||||
float Controller::getY( int stickIndex )
|
||||
{
|
||||
if (!isValidStick(stickIndex)) return 0;
|
||||
return stickValuesY[stickIndex-1];
|
||||
}
|
||||
|
||||
float Controller::getTransformedX( int stickIndex, float deadZone, float scale/*=1.0f*/, bool limit1/*=false*/ )
|
||||
{
|
||||
if (!isValidStick(stickIndex)) return 0;
|
||||
return linearTransform(stickValuesX[stickIndex-1], deadZone, scale, limit1);
|
||||
}
|
||||
|
||||
float Controller::getTransformedY( int stickIndex, float deadZone, float scale/*=1.0f*/, bool limit1/*=false*/ )
|
||||
{
|
||||
if (!isValidStick(stickIndex)) return 0;
|
||||
return linearTransform(stickValuesY[stickIndex-1], deadZone, scale, limit1);
|
||||
}
|
||||
|
||||
float Controller::linearTransform( float value, float deadZone, float scale/*=1.0f*/, bool limit1/*=false*/ )
|
||||
{
|
||||
float deadSigned = value >= 0? deadZone : -deadZone;
|
||||
if (_abs(deadSigned) >= _abs(value)) return 0;
|
||||
float ret = (value - deadSigned) * scale;
|
||||
if (limit1 && _abs(ret) > 1) ret = ret>0.0f? 1.0f : -1.0f;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool Controller::isValidStick(int stick) {
|
||||
return stick > 0 && stick <= NUM_STICKS;
|
||||
}
|
||||
33
src/platform/input/Controller.h
Executable file
33
src/platform/input/Controller.h
Executable file
@@ -0,0 +1,33 @@
|
||||
#ifndef CONTROLLER_H__
|
||||
#define CONTROLLER_H__
|
||||
|
||||
#include "../log.h"
|
||||
|
||||
class Controller
|
||||
{
|
||||
public:
|
||||
static const int NUM_STICKS = 2;
|
||||
static const int STATE_TOUCH = 1;
|
||||
static const int STATE_RELEASE = 0;
|
||||
static const int STATE_MOVE =-1;
|
||||
|
||||
static bool isTouched(int stickIndex);
|
||||
|
||||
static void feed(int stickIndex, int state, float dx, float dy);
|
||||
|
||||
static float getX(int stickIndex);
|
||||
static float getY(int stickIndex);
|
||||
|
||||
static float getTransformedX(int stickIndex, float deadZone, float scale=1.0f, bool limit1=false);
|
||||
static float getTransformedY(int stickIndex, float deadZone, float scale=1.0f, bool limit1=false);
|
||||
|
||||
private:
|
||||
static bool isValidStick(int stick);
|
||||
static float linearTransform(float value, float deadZone, float scale=1.0f, bool limit1=false);
|
||||
|
||||
static float stickValuesX[NUM_STICKS];
|
||||
static float stickValuesY[NUM_STICKS];
|
||||
static bool isTouchedValues[NUM_STICKS];
|
||||
};
|
||||
|
||||
#endif /*CONTROLLER_H__*/
|
||||
20
src/platform/input/Keyboard.cpp
Executable file
20
src/platform/input/Keyboard.cpp
Executable file
@@ -0,0 +1,20 @@
|
||||
#include "Keyboard.h"
|
||||
|
||||
/*
|
||||
const int KeyboardAction::KEYUP = 0;
|
||||
const int KeyboardAction::KEYDOWN = 1;
|
||||
*/
|
||||
|
||||
int
|
||||
Keyboard::_states[256] = {0};
|
||||
|
||||
std::vector<KeyboardAction>
|
||||
Keyboard::_inputs;
|
||||
std::vector<char>
|
||||
Keyboard::_inputText;
|
||||
|
||||
int
|
||||
Keyboard::_index = -1;
|
||||
|
||||
int
|
||||
Keyboard::_textIndex = -1;
|
||||
137
src/platform/input/Keyboard.h
Executable file
137
src/platform/input/Keyboard.h
Executable file
@@ -0,0 +1,137 @@
|
||||
#ifndef KEYBOARD_H__
|
||||
#define KEYBOARD_H__
|
||||
|
||||
#include <vector>
|
||||
|
||||
/** A keyboard action; key-down or key-up */
|
||||
class KeyboardAction
|
||||
{
|
||||
public:
|
||||
static const int KEYUP = 0;
|
||||
static const int KEYDOWN = 1;
|
||||
|
||||
KeyboardAction(unsigned char keyCode, int state) {
|
||||
this->key = keyCode;
|
||||
this->state = state;
|
||||
}
|
||||
|
||||
int state;
|
||||
unsigned char key;
|
||||
};
|
||||
|
||||
/* Iterators */
|
||||
typedef std::vector<KeyboardAction> KeyboardActionVec;
|
||||
typedef KeyboardActionVec::iterator KeyboardActionIt;
|
||||
typedef KeyboardActionVec::const_iterator KeyboardActionCIt;
|
||||
|
||||
/** A static keyboard class, written to resemble the one in lwjgl somewhat */
|
||||
class Keyboard
|
||||
{
|
||||
public:
|
||||
static const int KEY_A = 65;
|
||||
static const int KEY_B = 66;
|
||||
static const int KEY_C = 67;
|
||||
static const int KEY_D = 68;
|
||||
static const int KEY_E = 69;
|
||||
static const int KEY_F = 70;
|
||||
static const int KEY_G = 71;
|
||||
static const int KEY_H = 72;
|
||||
static const int KEY_I = 73;
|
||||
static const int KEY_J = 74;
|
||||
static const int KEY_K = 75;
|
||||
static const int KEY_L = 76;
|
||||
static const int KEY_M = 77;
|
||||
static const int KEY_N = 78;
|
||||
static const int KEY_O = 79;
|
||||
static const int KEY_P = 80;
|
||||
static const int KEY_Q = 81;
|
||||
static const int KEY_R = 82;
|
||||
static const int KEY_S = 83;
|
||||
static const int KEY_T = 84;
|
||||
static const int KEY_U = 85;
|
||||
static const int KEY_V = 86;
|
||||
static const int KEY_W = 87;
|
||||
static const int KEY_X = 88;
|
||||
static const int KEY_Y = 89;
|
||||
static const int KEY_Z = 90;
|
||||
|
||||
static const int KEY_BACKSPACE = 8;
|
||||
static const int KEY_RETURN = 13;
|
||||
|
||||
static const int KEY_F1 = 112;
|
||||
static const int KEY_F2 = 113;
|
||||
static const int KEY_F3 = 114;
|
||||
static const int KEY_F4 = 115;
|
||||
static const int KEY_F5 = 116;
|
||||
static const int KEY_F6 = 117;
|
||||
static const int KEY_F7 = 118;
|
||||
static const int KEY_F8 = 119;
|
||||
static const int KEY_F9 = 120;
|
||||
static const int KEY_F10 = 121;
|
||||
static const int KEY_F11 = 122;
|
||||
static const int KEY_F12 = 123;
|
||||
|
||||
static const int KEY_ESCAPE = 27;
|
||||
static const int KEY_SPACE = 32;
|
||||
static const int KEY_LSHIFT = 10;
|
||||
|
||||
static bool isKeyDown(int keyCode) {
|
||||
return _states[keyCode] == KeyboardAction::KEYDOWN;
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
_inputs.clear();
|
||||
_inputText.clear();
|
||||
_index = -1;
|
||||
_textIndex = -1;
|
||||
}
|
||||
|
||||
static void feed(unsigned char keyCode, int state) {
|
||||
_inputs.push_back(KeyboardAction(keyCode, state));
|
||||
|
||||
_states[keyCode] = state;
|
||||
}
|
||||
static void feedText(char character) {
|
||||
_inputText.push_back(character);
|
||||
}
|
||||
|
||||
static bool next() {
|
||||
if (_index + 1 >= (int)_inputs.size())
|
||||
return false;
|
||||
|
||||
++_index;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool nextTextChar() {
|
||||
if(_textIndex + 1 >= (int)_inputText.size())
|
||||
return false;
|
||||
++_textIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rewind() {
|
||||
_index = -1;
|
||||
_textIndex = -1;
|
||||
}
|
||||
|
||||
static int getEventKey() {
|
||||
return _inputs[_index].key;
|
||||
}
|
||||
|
||||
static int getEventKeyState() {
|
||||
return _inputs[_index].state;
|
||||
}
|
||||
static char getChar() {
|
||||
return _inputText[_textIndex];
|
||||
}
|
||||
private:
|
||||
static int _index;
|
||||
static int _textIndex;
|
||||
static int _states[256];
|
||||
static std::vector<KeyboardAction> _inputs;
|
||||
static std::vector<char> _inputText;
|
||||
static bool _inited;
|
||||
};
|
||||
|
||||
#endif//KEYBOARD_H__
|
||||
169
src/platform/input/Mouse.cpp
Executable file
169
src/platform/input/Mouse.cpp
Executable file
@@ -0,0 +1,169 @@
|
||||
#include "Mouse.h"
|
||||
|
||||
//
|
||||
// MouseAction
|
||||
//
|
||||
MouseAction::MouseAction(char actionButtonId, char buttonData, short x, short y, char pointerId)
|
||||
{
|
||||
this->action = actionButtonId;
|
||||
this->data = buttonData;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->dx = this->dy = 0;
|
||||
this->pointerId = pointerId;
|
||||
}
|
||||
|
||||
MouseAction::MouseAction(char actionButtonId, char buttonData, short x, short y, short dx, short dy, char pointerId)
|
||||
{
|
||||
this->action = actionButtonId;
|
||||
this->data = buttonData;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->dx = dx;
|
||||
this->dy = dy;
|
||||
this->pointerId = pointerId;
|
||||
}
|
||||
|
||||
bool MouseAction::isButton() const
|
||||
{
|
||||
return action == ACTION_LEFT || action == ACTION_RIGHT;
|
||||
}
|
||||
|
||||
//
|
||||
// MouseDevice
|
||||
//
|
||||
MouseDevice::MouseDevice()
|
||||
: _index(-1),
|
||||
_x(0), _xOld(0),
|
||||
_y(0), _yOld(0),
|
||||
_dx(DELTA_NOTSET), _dy(DELTA_NOTSET),
|
||||
_firstMovementType(0)
|
||||
{
|
||||
for (int i = 0; i < MAX_NUM_BUTTONS; ++i)
|
||||
_buttonStates[i] = 0;
|
||||
}
|
||||
|
||||
void MouseDevice::reset() {
|
||||
_index = -1;
|
||||
_inputs.clear();
|
||||
_buttonStates[MouseAction::ACTION_WHEEL] = 0;
|
||||
}
|
||||
|
||||
char MouseDevice::getButtonState(int buttonId) {
|
||||
if (buttonId < MouseAction::ACTION_LEFT || buttonId > MouseAction::ACTION_WHEEL)
|
||||
return 0;
|
||||
return _buttonStates[buttonId];
|
||||
}
|
||||
|
||||
bool MouseDevice::isButtonDown(int buttonId) {
|
||||
return getButtonState(buttonId) != 0;
|
||||
}
|
||||
|
||||
/// Was the current movement the first movement after mouse down?
|
||||
bool MouseDevice::wasFirstMovement() {
|
||||
return _firstMovementType == 1;
|
||||
}
|
||||
|
||||
short MouseDevice::getX() { return _x; }
|
||||
short MouseDevice::getY() { return _y; }
|
||||
|
||||
short MouseDevice::getDX() { return (DELTA_NOTSET != _dx)? _dx : _x - _xOld; }
|
||||
short MouseDevice::getDY() { return (DELTA_NOTSET != _dy)? _dy : _y - _yOld; }
|
||||
|
||||
void MouseDevice::reset2() {
|
||||
_xOld = _x;
|
||||
_yOld = _y;
|
||||
_dx = _dy = DELTA_NOTSET;
|
||||
}
|
||||
|
||||
bool MouseDevice::next() {
|
||||
if (_index + 1 >= (int)_inputs.size())
|
||||
return false;
|
||||
|
||||
++_index;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MouseDevice::rewind() {
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
bool MouseDevice::getEventButtonState() {
|
||||
return _inputs[_index].data == MouseAction::DATA_DOWN;
|
||||
}
|
||||
|
||||
char MouseDevice::getEventButton() {
|
||||
return _inputs[_index].action;
|
||||
}
|
||||
|
||||
const MouseAction& MouseDevice::getEvent() { return _inputs[_index]; }
|
||||
|
||||
void MouseDevice::feed(char actionButtonId, char buttonData, short x, short y) {
|
||||
feed(actionButtonId, buttonData, x, y, 0, 0);
|
||||
}
|
||||
|
||||
void MouseDevice::feed(char actionButtonId, char buttonData, short x, short y, short dx, short dy) {
|
||||
|
||||
_inputs.push_back(MouseAction(actionButtonId, buttonData, x, y, dx, dy, 0));
|
||||
|
||||
if (actionButtonId != MouseAction::ACTION_MOVE) {
|
||||
_buttonStates[actionButtonId] = buttonData;
|
||||
|
||||
if (actionButtonId == MouseAction::ACTION_LEFT)
|
||||
_firstMovementType = -1;
|
||||
} else {
|
||||
if (_dx == DELTA_NOTSET) {
|
||||
_dx = _dy = 0;
|
||||
}
|
||||
_dx += dx;
|
||||
_dy += dy;
|
||||
|
||||
if (_firstMovementType == -1)
|
||||
_firstMovementType = 1;
|
||||
else
|
||||
_firstMovementType = 0;
|
||||
}
|
||||
|
||||
_xOld = _x;
|
||||
_yOld = _y;
|
||||
_x = x;
|
||||
_y = y;
|
||||
}
|
||||
|
||||
//
|
||||
// Mouse - static class wrapping a MouseDevice
|
||||
//
|
||||
void Mouse::reset() { _instance.reset(); }
|
||||
|
||||
char Mouse::getButtonState(int buttonId) { return _instance.getButtonState(buttonId); }
|
||||
|
||||
bool Mouse::isButtonDown(int buttonId) { return _instance.isButtonDown(buttonId); }
|
||||
|
||||
short Mouse::getX() { return _instance.getX(); }
|
||||
short Mouse::getY() { return _instance.getY(); }
|
||||
|
||||
short Mouse::getDX() { return _instance.getDX(); }
|
||||
short Mouse::getDY() { return _instance.getDY(); }
|
||||
|
||||
void Mouse::reset2() { _instance.reset2(); }
|
||||
|
||||
bool Mouse::next() { return _instance.next(); }
|
||||
void Mouse::rewind() { _instance.rewind(); }
|
||||
|
||||
bool Mouse::getEventButtonState() { return _instance.getEventButtonState(); }
|
||||
|
||||
char Mouse::getEventButton() { return _instance.getEventButton(); }
|
||||
|
||||
const MouseAction& Mouse::getEvent() { return _instance.getEvent(); }
|
||||
|
||||
void Mouse::feed(char actionButtonId, char buttonData, short x, short y) {
|
||||
feed(actionButtonId, buttonData, x, y, 0, 0);
|
||||
}
|
||||
void Mouse::feed(char actionButtonId, char buttonData, short x, short y, short dx, short dy) {
|
||||
//LOGI("Mouse::feed: %d, %d, xy: %d, %d\n", actionButtonId, buttonData, x, y);
|
||||
return _instance.feed(actionButtonId, buttonData, x, y, dx, dy);
|
||||
}
|
||||
|
||||
|
||||
MouseDevice Mouse::_instance;
|
||||
|
||||
112
src/platform/input/Mouse.h
Executable file
112
src/platform/input/Mouse.h
Executable file
@@ -0,0 +1,112 @@
|
||||
#ifndef MOUSE_H__
|
||||
#define MOUSE_H__
|
||||
|
||||
#include <vector>
|
||||
#include "../log.h"
|
||||
|
||||
|
||||
/** A mouse action such as a button press, release or mouse movement */
|
||||
class MouseAction
|
||||
{
|
||||
public:
|
||||
static const char ACTION_MOVE = 0;
|
||||
static const char ACTION_LEFT = 1;
|
||||
static const char ACTION_RIGHT = 2;
|
||||
static const char ACTION_WHEEL = 3;
|
||||
|
||||
static const char DATA_UP = 0;
|
||||
static const char DATA_DOWN = 1;
|
||||
|
||||
MouseAction(char actionButtonId, char buttonData, short x, short y, char pointerId);
|
||||
MouseAction(char actionButtonId, char buttonData, short x, short y, short dx, short dy, char pointerId);
|
||||
|
||||
bool isButton() const;
|
||||
|
||||
short x, y;
|
||||
short dx, dy;
|
||||
char action;
|
||||
char data;
|
||||
char pointerId;
|
||||
};
|
||||
|
||||
/* Iterators */
|
||||
typedef std::vector<MouseAction> MouseActionVec;
|
||||
typedef MouseActionVec::iterator MouseActionIt;
|
||||
typedef MouseActionVec::const_iterator MouseActionCIt;
|
||||
|
||||
|
||||
class MouseDevice
|
||||
{
|
||||
public:
|
||||
static const int MAX_NUM_BUTTONS = 4;
|
||||
|
||||
MouseDevice();
|
||||
|
||||
char getButtonState(int buttonId);
|
||||
bool isButtonDown(int buttonId);
|
||||
|
||||
/// Was the current movement the first movement after mouse down?
|
||||
bool wasFirstMovement();
|
||||
|
||||
short getX();
|
||||
short getY();
|
||||
|
||||
short getDX();
|
||||
short getDY();
|
||||
|
||||
void reset();
|
||||
void reset2();
|
||||
|
||||
bool next();
|
||||
void rewind();
|
||||
|
||||
bool getEventButtonState();
|
||||
char getEventButton();
|
||||
const MouseAction& getEvent();
|
||||
|
||||
void feed(char actionButtonId, char buttonData, short x, short y);
|
||||
void feed(char actionButtonId, char buttonData, short x, short y, short dx, short dy);
|
||||
|
||||
private:
|
||||
int _index;
|
||||
short _x, _y;
|
||||
short _dx, _dy;
|
||||
short _xOld, _yOld;
|
||||
char _buttonStates[MAX_NUM_BUTTONS];
|
||||
std::vector<MouseAction> _inputs;
|
||||
int _firstMovementType;
|
||||
static const int DELTA_NOTSET = -9999;
|
||||
};
|
||||
|
||||
/** A static mouse class, written to resemble the one in lwjgl somewhat
|
||||
UPDATE: which is very silly, since it doesn't support multi touch... */
|
||||
class Mouse
|
||||
{
|
||||
public:
|
||||
static char getButtonState(int buttonId);
|
||||
static bool isButtonDown(int buttonId);
|
||||
|
||||
static short getX();
|
||||
static short getY();
|
||||
|
||||
static short getDX();
|
||||
static short getDY();
|
||||
|
||||
static void reset();
|
||||
static void reset2();
|
||||
|
||||
static bool next();
|
||||
static void rewind();
|
||||
|
||||
static bool getEventButtonState();
|
||||
static char getEventButton();
|
||||
static const MouseAction& getEvent();
|
||||
|
||||
static void feed(char actionButtonId, char buttonData, short x, short y);
|
||||
static void feed(char actionButtonId, char buttonData, short x, short y, short dx, short dy);
|
||||
|
||||
private:
|
||||
static MouseDevice _instance;
|
||||
};
|
||||
|
||||
#endif//MOUSE_H__
|
||||
20
src/platform/input/Multitouch.cpp
Executable file
20
src/platform/input/Multitouch.cpp
Executable file
@@ -0,0 +1,20 @@
|
||||
#include "Multitouch.h"
|
||||
|
||||
int
|
||||
Multitouch::_index = -1,
|
||||
Multitouch::_activePointerCount = 0,
|
||||
Multitouch::_activePointerList[Multitouch::MAX_POINTERS] = {-1},
|
||||
Multitouch::_activePointerThisUpdateCount = 0,
|
||||
Multitouch::_activePointerThisUpdateList[Multitouch::MAX_POINTERS] = {-1};
|
||||
|
||||
bool
|
||||
Multitouch::_wasPressed[Multitouch::MAX_POINTERS] = {false},
|
||||
Multitouch::_wasReleased[Multitouch::MAX_POINTERS] = {false},
|
||||
Multitouch::_wasPressedThisUpdate[Multitouch::MAX_POINTERS] = {false},
|
||||
Multitouch::_wasReleasedThisUpdate[Multitouch::MAX_POINTERS] = {false};
|
||||
|
||||
TouchPointer
|
||||
Multitouch::_pointers[Multitouch::MAX_POINTERS];
|
||||
|
||||
std::vector<MouseAction>
|
||||
Multitouch::_inputs;
|
||||
176
src/platform/input/Multitouch.h
Executable file
176
src/platform/input/Multitouch.h
Executable file
@@ -0,0 +1,176 @@
|
||||
#ifndef MULTITOUCH_H__
|
||||
#define MULTITOUCH_H__
|
||||
|
||||
#include "Mouse.h"
|
||||
#include "../log.h"
|
||||
|
||||
typedef MouseDevice TouchPointer;
|
||||
|
||||
class Multitouch
|
||||
{
|
||||
public:
|
||||
static const int MAX_POINTERS = 12;
|
||||
|
||||
static bool isPointerDown(int pointerId) {
|
||||
return g(pointerId).isButtonDown(1);
|
||||
}
|
||||
|
||||
// Returns the first activeExtended (down OR released) pointer id
|
||||
static int getFirstActivePointerIdEx() {
|
||||
for (int i = 0; i < MAX_POINTERS; ++i)
|
||||
if (_pointers[i].isButtonDown(1)) return i;
|
||||
for (int i = 0; i < MAX_POINTERS; ++i)
|
||||
if (_wasReleased[i]) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Returns the first activeExtended (down OR released) pointer id
|
||||
// Compared to getFirstActivePointerIdEx, this method keeps the state the
|
||||
// tick/render loop, while the former keeps it for a tick.
|
||||
static int getFirstActivePointerIdExThisUpdate() {
|
||||
for (int i = 0; i < MAX_POINTERS; ++i)
|
||||
if (_pointers[i].isButtonDown(1)) return i;
|
||||
for (int i = 0; i < MAX_POINTERS; ++i)
|
||||
if (_wasReleasedThisUpdate[i]) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get a list of all active (i.e. marked as touched/down) pointer ids
|
||||
static int getActivePointerIds(const int** const ids) {
|
||||
*ids = _activePointerList;
|
||||
return _activePointerCount;
|
||||
}
|
||||
|
||||
// Get a list of all active (i.e. marked as touched/down) pointer ids
|
||||
static int getActivePointerIdsThisUpdate(const int** const ids) {
|
||||
*ids = _activePointerThisUpdateList;
|
||||
return _activePointerThisUpdateCount;
|
||||
}
|
||||
|
||||
// Called when no more events will be pushed this update
|
||||
static void commit() {
|
||||
_activePointerCount = 0;
|
||||
_activePointerThisUpdateCount = 0;
|
||||
for (int i = 0; i < MAX_POINTERS; ++i) {
|
||||
bool isDown = _pointers[i].isButtonDown(1);
|
||||
if (isDown) {
|
||||
_activePointerList[_activePointerCount++] = i;
|
||||
_activePointerThisUpdateList[_activePointerThisUpdateCount++] = i;
|
||||
} else if (_wasReleased[i]) {
|
||||
_activePointerThisUpdateList[_activePointerThisUpdateCount++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static short getX(int pointerId) { return g(pointerId).getX(); }
|
||||
static short getY(int pointerId) { return g(pointerId).getY(); }
|
||||
|
||||
static short getDX(int pointerId) { return g(pointerId).getDX(); }
|
||||
static short getDY(int pointerId) { return g(pointerId).getDY(); }
|
||||
|
||||
static bool wasFirstMovement(int pointerId) { return g(pointerId).wasFirstMovement(); }
|
||||
|
||||
static bool isPressed(int pointerId) {
|
||||
return _wasPressed[_clampPointerId(pointerId)];
|
||||
}
|
||||
static bool isReleased(int pointerId) {
|
||||
return _wasReleased[_clampPointerId(pointerId)];
|
||||
}
|
||||
static bool isPressedThisUpdate(int pointerId) {
|
||||
return _wasPressedThisUpdate[_clampPointerId(pointerId)];
|
||||
}
|
||||
static bool isReleasedThisUpdate(int pointerId) {
|
||||
return _wasReleasedThisUpdate[_clampPointerId(pointerId)];
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
//LOGI("mtouch is reset\n");
|
||||
_inputs.clear();
|
||||
_index = -1;
|
||||
|
||||
for (int i = 0; i < MAX_POINTERS; ++i) {
|
||||
g(i).reset();
|
||||
|
||||
_wasPressed[i] = false;
|
||||
_wasReleased[i] = false;
|
||||
}
|
||||
}
|
||||
static void resetThisUpdate() {
|
||||
for (int i = 0; i < MAX_POINTERS; ++i) {
|
||||
_wasPressedThisUpdate[i] = false;
|
||||
_wasReleasedThisUpdate[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool next() {
|
||||
if (_index + 1 >= (int)_inputs.size())
|
||||
return false;
|
||||
|
||||
++_index;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rewind() {
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
static MouseAction& getEvent() {
|
||||
return _inputs[_index];
|
||||
}
|
||||
|
||||
static void feed(char actionButtonId, char buttonData, short x, short y, char pointerId) {
|
||||
pointerId = _clampPointerId(pointerId);
|
||||
|
||||
_inputs.push_back(MouseAction(actionButtonId, buttonData, x, y, pointerId));
|
||||
g(pointerId).feed(actionButtonId, buttonData, x, y);
|
||||
|
||||
if (actionButtonId > 0) {
|
||||
if (buttonData == MouseAction::DATA_DOWN) {
|
||||
_wasPressed[pointerId] = true;
|
||||
_wasPressedThisUpdate[pointerId] = true;
|
||||
//LOGI("isPressed %d %d\n", pointerId, isPressed(pointerId));
|
||||
}
|
||||
else if (buttonData == MouseAction::DATA_UP) {
|
||||
_wasReleased[pointerId] = true;
|
||||
_wasReleasedThisUpdate[pointerId] = true;
|
||||
//LOGI("isReleased %d %d\n", pointerId, isReleased(pointerId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int getMaxPointers() {
|
||||
return MAX_POINTERS;
|
||||
}
|
||||
|
||||
private:
|
||||
static TouchPointer& g(int pointerId) {
|
||||
return _pointers[_clampPointerId(pointerId)];
|
||||
}
|
||||
|
||||
static int _clampPointerId(int p) {
|
||||
if (p < 0) return p;
|
||||
if (p >= MAX_POINTERS) return MAX_POINTERS-1;
|
||||
return p;
|
||||
}
|
||||
|
||||
// Between calls to reset()
|
||||
static bool _wasPressed[MAX_POINTERS];
|
||||
static bool _wasReleased[MAX_POINTERS];
|
||||
|
||||
// Between calls to resetThisUpdate()
|
||||
static bool _wasPressedThisUpdate[MAX_POINTERS];
|
||||
static bool _wasReleasedThisUpdate[MAX_POINTERS];
|
||||
|
||||
static TouchPointer _pointers[MAX_POINTERS];
|
||||
static std::vector<MouseAction> _inputs;
|
||||
|
||||
static int _activePointerList[MAX_POINTERS];
|
||||
static int _activePointerCount;
|
||||
|
||||
static int _activePointerThisUpdateList[MAX_POINTERS];
|
||||
static int _activePointerThisUpdateCount;
|
||||
|
||||
static int _index;
|
||||
};
|
||||
|
||||
#endif /*MULTITOUCH_H__*/
|
||||
47
src/platform/log.h
Executable file
47
src/platform/log.h
Executable file
@@ -0,0 +1,47 @@
|
||||
#ifndef LOG_H__
|
||||
#define LOG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdio>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define __LOG_PUBLISH(...) do { __VA_ARGS__; } while(0)
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <android/log.h>
|
||||
#ifdef ANDROID_PUBLISH
|
||||
#define LOGV(fmt, ...) __LOG_PUBLISH(__VA_ARGS__)
|
||||
#define LOGI(fmt, ...) __LOG_PUBLISH(__VA_ARGS__)
|
||||
#define LOGW(fmt, ...) __LOG_PUBLISH(__VA_ARGS__)
|
||||
#define LOGE(fmt, ...) __LOG_PUBLISH(__VA_ARGS__)
|
||||
#else
|
||||
// @todo @fix; Obiously the tag shouldn't be hardcoded in here..
|
||||
#define LOGV(...) ((void)__android_log_print( ANDROID_LOG_VERBOSE, "MinecraftPE", __VA_ARGS__ ))
|
||||
#define LOGI(...) ((void)__android_log_print( ANDROID_LOG_INFO, "MinecraftPE", __VA_ARGS__ ))
|
||||
#define LOGW(...) ((void)__android_log_print( ANDROID_LOG_WARN, "MinecraftPE", __VA_ARGS__ ))
|
||||
#define LOGE(...) ((void)__android_log_print( ANDROID_LOG_ERROR, "MinecraftPE", __VA_ARGS__ ))
|
||||
#define printf LOGI
|
||||
#endif
|
||||
#else
|
||||
#ifdef PUBLISH
|
||||
#define LOGV(fmt, ...) __LOG_PUBLISH(__VA_ARGS__)
|
||||
#define LOGI(fmt, ...) __LOG_PUBLISH(__VA_ARGS__)
|
||||
#define LOGW(fmt, ...) __LOG_PUBLISH(__VA_ARGS__)
|
||||
#define LOGE(fmt, ...) __LOG_PUBLISH(__VA_ARGS__)
|
||||
#else
|
||||
#define LOGV(...) (printf(__VA_ARGS__))
|
||||
#define LOGI(...) (printf(__VA_ARGS__))
|
||||
#define LOGW(...) (printf(__VA_ARGS__))
|
||||
#define LOGE(...) (printf(__VA_ARGS__))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define LOGVV LOGV
|
||||
#else
|
||||
#define LOGVV(fmt, ...) __LOG_PUBLISH(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#endif /*LOG_H__*/
|
||||
224
src/platform/time.cpp
Executable file
224
src/platform/time.cpp
Executable file
@@ -0,0 +1,224 @@
|
||||
#include "time.h"
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
// Ugly ass temporary solution;
|
||||
// since gettimeofday() returns seconds & microseconds since
|
||||
// Epoch(1970) rather than since computer started, getTimeMs()
|
||||
// would overflow if just using an int -> subtract the number
|
||||
// of seconds that had passed when starting the app before
|
||||
// doing any calculations.
|
||||
#ifdef WIN32
|
||||
static long long getStartTime() {
|
||||
LARGE_INTEGER ts;
|
||||
QueryPerformanceCounter(&ts);
|
||||
return ts.QuadPart;
|
||||
}
|
||||
static unsigned long long _t_start = getStartTime();
|
||||
|
||||
#else
|
||||
static int getStartTime() {
|
||||
timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
return now.tv_sec;
|
||||
}
|
||||
static unsigned int _t_start = getStartTime();
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
/// Returns a platform dependent time in seconds
|
||||
/// This is allowed to be here, since getTimeS and getTimeMs both have t(0)
|
||||
/// as base (and obviously not good for an initial random seed)
|
||||
int getRawTimeS() {
|
||||
#ifdef WIN32
|
||||
return (int)(GetTickCount() / 1000);
|
||||
#else
|
||||
timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
return (int)now.tv_sec;
|
||||
#endif
|
||||
}
|
||||
|
||||
float getTimeS() {
|
||||
#ifdef WIN32
|
||||
// If the game seems to go with different speeds, this might most
|
||||
// possibly be the cause. QueryPerformanceCounter has indeed high
|
||||
// resolution, but (imho) only guaranteed to be correct for (short)
|
||||
// deltas between consecutive calls
|
||||
LARGE_INTEGER freq, ts;
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceCounter(&ts);
|
||||
return (ts.QuadPart - _t_start) / (float)freq.QuadPart;
|
||||
#else
|
||||
timeval now;
|
||||
gettimeofday(&now, 0);
|
||||
return (float)(now.tv_sec - _t_start) + now.tv_usec / 1000000.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
int getTimeMs() {
|
||||
return (int)(getTimeS() * 1000.0f);
|
||||
}
|
||||
|
||||
void sleepMs(int ms) {
|
||||
#ifdef WIN32
|
||||
Sleep(ms);
|
||||
#else
|
||||
usleep(ms * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
#include <ctime>
|
||||
int getEpochTimeS() {
|
||||
return (int)std::time (NULL);
|
||||
}
|
||||
|
||||
|
||||
StopwatchNLast::StopwatchNLast( int numMeasurements )
|
||||
: n(numMeasurements),
|
||||
k(0),
|
||||
sum(0)
|
||||
{
|
||||
t = new float[n];
|
||||
memset(t, 0, n * sizeof(float));
|
||||
}
|
||||
|
||||
StopwatchNLast::~StopwatchNLast() {
|
||||
delete[] t;
|
||||
}
|
||||
|
||||
float StopwatchNLast::stop() {
|
||||
float total = Stopwatch::stop();
|
||||
float curr = Stopwatch::getLast();
|
||||
|
||||
float toDelete = t[k];
|
||||
if (++k == n) k = 0;
|
||||
t[k] = curr;
|
||||
|
||||
sum += (curr - toDelete);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
void StopwatchNLast::print( const std::string& prepend /*= ""*/ ) {
|
||||
LOGI("%s\tTime (AVGms for the last %d runs): %f (Max: %f)\n",
|
||||
prepend.c_str(), n, (1000.0f*sum/n), 1000.0f * getMax());
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Stopwatch
|
||||
//
|
||||
Stopwatch::Stopwatch()
|
||||
: _count(0),
|
||||
_printcounter(0)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void Stopwatch::start() {
|
||||
_st = getTimeS();
|
||||
}
|
||||
|
||||
float Stopwatch::stop() {
|
||||
if (_st == -1) return 0;
|
||||
_last = getTimeS() - _st;
|
||||
if (_last > _max) _max = _last;
|
||||
_tt += _last;
|
||||
_st = -1;
|
||||
++_count;
|
||||
return _tt;
|
||||
}
|
||||
|
||||
float Stopwatch::stopContinue() {
|
||||
if (_st == -1) return 0;
|
||||
const float now = getTimeS();
|
||||
_last = now - _st;
|
||||
if (_last > _max) _max = _last;
|
||||
_tt += _last;
|
||||
_st = now;
|
||||
++_count;
|
||||
return _tt;
|
||||
}
|
||||
|
||||
float Stopwatch::getLast() {
|
||||
return _last;
|
||||
}
|
||||
|
||||
float Stopwatch::getTotal() {
|
||||
return _tt;
|
||||
}
|
||||
|
||||
float Stopwatch::getMax() {
|
||||
return _max;
|
||||
}
|
||||
|
||||
int Stopwatch::getCount() {
|
||||
return _count;
|
||||
}
|
||||
|
||||
void Stopwatch::reset() {
|
||||
_st = -1;
|
||||
_tt = 0;
|
||||
_max = 0;
|
||||
}
|
||||
|
||||
void Stopwatch::printEvery( int n, const std::string& prepend /*= ""*/ ) {
|
||||
if (++_printcounter >= n) {
|
||||
_printcounter = 0;
|
||||
print(prepend);
|
||||
}
|
||||
}
|
||||
|
||||
void Stopwatch::print( const std::string& prepend /*= ""*/ ) {
|
||||
if (!_count) return;
|
||||
LOGI("%s\tTime (AVGms/LTs(MAXs)/TTs, C) : %.3f/%.6f(%.6f)/%.4f, %d\n",
|
||||
prepend.c_str(), (1000.0f*_tt/_count), _last, _max, _tt, _count);
|
||||
}
|
||||
|
||||
//
|
||||
// StopwatchHandler - a collection of StopWatch:es
|
||||
//
|
||||
Stopwatch& StopwatchHandler::get( const std::string& s ) {
|
||||
Map::iterator it = _map.find(s);
|
||||
if (it != _map.end())
|
||||
return *it->second;
|
||||
|
||||
Stopwatch* watch = new Stopwatch;
|
||||
_map.insert(make_pair(s, watch));
|
||||
return *watch;
|
||||
}
|
||||
|
||||
void StopwatchHandler::clear( const std::string& s ) {
|
||||
Map::iterator it = _map.find(s);
|
||||
if (it != _map.end()) {
|
||||
delete it->second;
|
||||
}
|
||||
_map.erase(s);
|
||||
}
|
||||
|
||||
void StopwatchHandler::clearAll() {
|
||||
for (Map::iterator it = _map.begin(); it != _map.end(); ++it)
|
||||
delete it->second;
|
||||
_map.clear();
|
||||
}
|
||||
|
||||
void StopwatchHandler::print() {
|
||||
for (Map::iterator it = _map.begin(); it != _map.end(); ++it) {
|
||||
it->second->print(it->first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void StopwatchHandler::printEvery( int n ) {
|
||||
if (++_printcounter >= n) {
|
||||
_printcounter = 0;
|
||||
print();
|
||||
}
|
||||
}
|
||||
111
src/platform/time.h
Executable file
111
src/platform/time.h
Executable file
@@ -0,0 +1,111 @@
|
||||
#ifndef TIME_H__
|
||||
#define TIME_H__
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "log.h"
|
||||
|
||||
float getTimeS();
|
||||
int getTimeMs();
|
||||
int getRawTimeS();
|
||||
int getEpochTimeS();
|
||||
|
||||
void sleepMs(int ms);
|
||||
|
||||
class Stopwatch {
|
||||
public:
|
||||
Stopwatch();
|
||||
virtual ~Stopwatch() {}
|
||||
|
||||
void start();
|
||||
/** Returns the total number of seconds and stops the clock */
|
||||
virtual float stop();
|
||||
/* Returns the total number of seconds, but wont stop the clock */
|
||||
virtual float stopContinue();
|
||||
/** Returns the last measured time interval in seconds */
|
||||
float getLast();
|
||||
/** Returns the total measured time in seconds */
|
||||
float getTotal();
|
||||
/** Returns the maximum time between start() and stop() */
|
||||
float getMax();
|
||||
/** Returns the number of times the watch has been started and stopped */
|
||||
int getCount();
|
||||
|
||||
void reset();
|
||||
void printEvery(int n, const std::string& prepend = "");
|
||||
virtual void print(const std::string& prepend = "");
|
||||
private:
|
||||
float _st;
|
||||
float _tt;
|
||||
float _last;
|
||||
float _max;
|
||||
int _count;
|
||||
int _printcounter;
|
||||
};
|
||||
|
||||
class SwStartStopper {
|
||||
public:
|
||||
SwStartStopper(Stopwatch& stopwatch)
|
||||
: _stopwatch(stopwatch)
|
||||
{
|
||||
_stopwatch.start();
|
||||
}
|
||||
|
||||
~SwStartStopper() {
|
||||
_stopwatch.stop();
|
||||
}
|
||||
private:
|
||||
Stopwatch& _stopwatch;
|
||||
};
|
||||
|
||||
class SwStopper {
|
||||
public:
|
||||
SwStopper(Stopwatch& stopwatch)
|
||||
: _stopwatch(stopwatch)
|
||||
{}
|
||||
|
||||
~SwStopper() {
|
||||
_stopwatch.stop();
|
||||
}
|
||||
private:
|
||||
Stopwatch& _stopwatch;
|
||||
};
|
||||
|
||||
class StopwatchHandler {
|
||||
typedef std::map<std::string, Stopwatch*> Map;
|
||||
public:
|
||||
StopwatchHandler()
|
||||
: _printcounter(0)
|
||||
{}
|
||||
~StopwatchHandler() {
|
||||
clearAll();
|
||||
}
|
||||
Stopwatch& get(const std::string& s);
|
||||
void clear(const std::string& s);
|
||||
void clearAll();
|
||||
void print();
|
||||
void printEvery(int n);
|
||||
|
||||
private:
|
||||
Map _map;
|
||||
int _printcounter;
|
||||
};
|
||||
|
||||
class StopwatchNLast: public Stopwatch {
|
||||
public:
|
||||
StopwatchNLast(int numMeasurements);
|
||||
~StopwatchNLast();
|
||||
|
||||
float stop();
|
||||
|
||||
virtual void print(const std::string& prepend = "");
|
||||
private:
|
||||
int n;
|
||||
int k;
|
||||
float* t;
|
||||
float sum;
|
||||
|
||||
Stopwatch sw;
|
||||
};
|
||||
|
||||
#endif /*TIME_H__*/
|
||||
Reference in New Issue
Block a user