aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libjin/Audio/Audio.cpp6
-rw-r--r--src/libjin/Audio/Audio.h68
-rw-r--r--src/libjin/Audio/SDL/SDLAudio.cpp246
-rw-r--r--src/libjin/Audio/SDL/SDLAudio.h90
-rw-r--r--src/libjin/Audio/SDL/SDLSource.cpp756
-rw-r--r--src/libjin/Audio/SDL/SDLSource.h154
-rw-r--r--src/libjin/Audio/Source.cpp30
-rw-r--r--src/libjin/Audio/Source.h68
-rw-r--r--src/libjin/Common/Data.h34
-rw-r--r--src/libjin/Common/data.h34
-rw-r--r--src/libjin/Common/types.h24
-rw-r--r--src/libjin/Filesystem/Buffer.h102
-rw-r--r--src/libjin/Filesystem/Filesystem.cpp96
-rw-r--r--src/libjin/Filesystem/Filesystem.h40
-rw-r--r--src/libjin/Game/Game.cpp112
-rw-r--r--src/libjin/Game/Game.h74
-rw-r--r--src/libjin/Graphics/Bitmap.cpp276
-rw-r--r--src/libjin/Graphics/Bitmap.h74
-rw-r--r--src/libjin/Graphics/Canvas.cpp180
-rw-r--r--src/libjin/Graphics/Canvas.h36
-rw-r--r--src/libjin/Graphics/Color.cpp20
-rw-r--r--src/libjin/Graphics/Color.h114
-rw-r--r--src/libjin/Graphics/Font/Decoder.cpp152
-rw-r--r--src/libjin/Graphics/Font/Decoder.h58
-rw-r--r--src/libjin/Graphics/Font/Font.h42
-rw-r--r--src/libjin/Graphics/Font/Page.h46
-rw-r--r--src/libjin/Graphics/Font/TTF.cpp856
-rw-r--r--src/libjin/Graphics/Font/TTF.h214
-rw-r--r--src/libjin/Graphics/Font/Text.cpp242
-rw-r--r--src/libjin/Graphics/Font/Text.h104
-rw-r--r--src/libjin/Graphics/Font/TextureFont.cpp466
-rw-r--r--src/libjin/Graphics/Font/TextureFont.h66
-rw-r--r--src/libjin/Graphics/Mesh.cpp6
-rw-r--r--src/libjin/Graphics/Mesh.h16
-rw-r--r--src/libjin/Graphics/OpenGL.cpp8
-rw-r--r--src/libjin/Graphics/OpenGL.h24
-rw-r--r--src/libjin/Graphics/Shader.cpp484
-rw-r--r--src/libjin/Graphics/Shader.h80
-rw-r--r--src/libjin/Graphics/Shapes.cpp198
-rw-r--r--src/libjin/Graphics/Shapes.h38
-rw-r--r--src/libjin/Graphics/Texture.cpp32
-rw-r--r--src/libjin/Graphics/Texture.h22
-rw-r--r--src/libjin/Graphics/Window.cpp182
-rw-r--r--src/libjin/Graphics/Window.h78
-rw-r--r--src/libjin/Input/Keyboard.h12
-rw-r--r--src/libjin/Input/Mouse.cpp26
-rw-r--r--src/libjin/Input/Mouse.h26
-rw-r--r--src/libjin/Math/Math.h108
-rw-r--r--src/libjin/Math/Matrix.cpp372
-rw-r--r--src/libjin/Math/Matrix.h302
-rw-r--r--src/libjin/Math/Quad.h14
-rw-r--r--src/libjin/Math/Vector2.hpp54
-rw-r--r--src/libjin/Math/Vector3.hpp56
-rw-r--r--src/libjin/Math/Vector4.hpp64
-rw-r--r--src/libjin/Net/Net.cpp30
-rw-r--r--src/libjin/Net/Net.h26
-rw-r--r--src/libjin/Net/Socket.cpp366
-rw-r--r--src/libjin/Net/Socket.h96
-rw-r--r--src/libjin/Net/net.cpp30
-rw-r--r--src/libjin/Net/net.h26
-rw-r--r--src/libjin/Thread/Thread.cpp576
-rw-r--r--src/libjin/Thread/Thread.h268
-rw-r--r--src/libjin/Thread/thread.cpp576
-rw-r--r--src/libjin/Thread/thread.h268
-rw-r--r--src/libjin/Time/Timer.cpp158
-rw-r--r--src/libjin/Time/Timer.h110
-rw-r--r--src/libjin/audio/audio.cpp6
-rw-r--r--src/libjin/audio/audio.h68
-rw-r--r--src/libjin/audio/source.cpp30
-rw-r--r--src/libjin/audio/source.h68
-rw-r--r--src/libjin/common/data.h34
-rw-r--r--src/libjin/input/keyboard.h12
-rw-r--r--src/libjin/input/mouse.cpp26
-rw-r--r--src/libjin/input/mouse.h26
-rw-r--r--src/libjin/math/math.h108
-rw-r--r--src/libjin/math/matrix.cpp372
-rw-r--r--src/libjin/math/matrix.h302
-rw-r--r--src/libjin/math/quad.h14
-rw-r--r--src/libjin/net/net.cpp30
-rw-r--r--src/libjin/net/net.h26
-rw-r--r--src/libjin/thread/thread.cpp576
-rw-r--r--src/libjin/thread/thread.h268
82 files changed, 5738 insertions, 5840 deletions
diff --git a/src/libjin/Audio/Audio.cpp b/src/libjin/Audio/Audio.cpp
index 798269a..d148467 100644
--- a/src/libjin/Audio/Audio.cpp
+++ b/src/libjin/Audio/Audio.cpp
@@ -6,10 +6,10 @@
namespace jin
{
-namespace audio
-{
+ namespace audio
+ {
-} // audio
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO
diff --git a/src/libjin/Audio/Audio.h b/src/libjin/Audio/Audio.h
index b9812dd..48cbfe4 100644
--- a/src/libjin/Audio/Audio.h
+++ b/src/libjin/Audio/Audio.h
@@ -10,42 +10,42 @@
namespace jin
{
-namespace audio
-{
+ namespace audio
+ {
- class Source;
+ class Source;
- template<class SubAudio>
- class Audio : public Subsystem<SubAudio>
- {
- public:
- enum State
- {
- PLAY ,
- STOP ,
- PAUSE,
- };
-
- virtual void play() = 0;
- virtual void stop() = 0;
- virtual void pause() = 0;
- virtual void resume() = 0;
- virtual void setVolume(float volume) = 0;
-
- protected:
- Audio()
- : volume(1)
- , state(State::PLAY)
- {};
- virtual ~Audio() {};
- SINGLETON(Audio);
-
- float volume;
- State state;
-
- };
-
-} // audio
+ template<class SubAudio>
+ class Audio : public Subsystem<SubAudio>
+ {
+ public:
+ enum State
+ {
+ PLAY ,
+ STOP ,
+ PAUSE,
+ };
+
+ virtual void play() = 0;
+ virtual void stop() = 0;
+ virtual void pause() = 0;
+ virtual void resume() = 0;
+ virtual void setVolume(float volume) = 0;
+
+ protected:
+ Audio()
+ : volume(1)
+ , state(State::PLAY)
+ {};
+ virtual ~Audio() {};
+ SINGLETON(Audio);
+
+ float volume;
+ State state;
+
+ };
+
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO
diff --git a/src/libjin/Audio/SDL/SDLAudio.cpp b/src/libjin/Audio/SDL/SDLAudio.cpp
index 9a256b1..e06979c 100644
--- a/src/libjin/Audio/SDL/SDLAudio.cpp
+++ b/src/libjin/Audio/SDL/SDLAudio.cpp
@@ -9,133 +9,133 @@
namespace jin
{
-namespace audio
-{
-
- using namespace jin::math;
-
- /* עcallbackƵ̵߳ */
- static void defaultCallback(void *userdata, Uint8 *stream, int size)
- {
- static SDLAudio* audio = static_cast<SDLAudio*>(userdata);
- if (!audio->goOnProcess())
- return;
- audio->lock();
- audio->processCommands();
- audio->processSources(stream, size);
- audio->processBuffer(stream, size);
- audio->unlock();
- }
-
- /*call only once*/ bool SDLAudio::initSystem(const SettingBase* s)
- {
-#if LIBJIN_DEBUG
- Loghelper::log(Loglevel::LV_INFO, "Init Audio System");
-#endif
-
- if (SDL_Init(SDL_INIT_AUDIO) < 0)
- return false;
- SDL_AudioSpec spec;
- Setting* setting = (Setting*)s;
- if (setting == nullptr)
- return false;
-
- unsigned int samplerate = setting->samplerate;
- unsigned int samples = clamp<int>(setting->samples, 1, setting->samplerate);
-
- spec.freq = samplerate; // ÿsample,õ 11025, 22050, 44100 and 48000 Hz.
- spec.format = AUDIO_S16SYS; // signed 16-bit samples in native byte order
- spec.channels = SDLAUDIO_CHANNELS; //
- spec.samples = samples; // ÿβʱһã=setting->samplerateÿֻ1
- spec.userdata = this;
- spec.callback = defaultCallback;
-
- audioDevice = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
- if (audioDevice == 0)
- return false;
- /* start audio */
- SDL_PauseAudioDevice(audioDevice, 0);
- return true;
- }
-
- /*call only once*/ void SDLAudio::quitSystem()
- {
- SDL_CloseAudio();
- }
-
- void SDLAudio::lock()
- {
- SDL_LockAudioDevice(audioDevice);
- }
-
- void SDLAudio::unlock()
- {
- SDL_UnlockAudioDevice(audioDevice);
- }
-
- bool SDLAudio::goOnProcess()
- {
- if (state == SDLAudio::State::STOP)
- {
- SDLSourceManager::get()->removeAllSource();
- pause();
- return false;
- }
- else if (state == SDLAudio::State::PAUSE)
- return false;
- else
- return true;
- }
-
- void SDLAudio::processCommands()
- {
- SDLSourceManager::get()->processCommands();
- }
-
- void SDLAudio::processSources(void* buffer, size_t len)
- {
- SDLSourceManager::get()->processSources(buffer, len);
- }
-
- void SDLAudio::processBuffer(void* buff, size_t len)
- {
- short* buffer = (short*)buff;
- int samples = (len / SDLAUDIO_BYTEDEPTH) >> 1; // ˫
- const char L = 0, R = 1;
- for (int i = 0; i < samples; ++i)
- {
- short* clip = buffer + (i << 1);
- clip[L] *= volume;
- clip[R] *= volume;
- }
- }
-
- void SDLAudio::play()
- {
- state = State::PLAY;
- }
+ namespace audio
+ {
+
+ using namespace jin::math;
+
+ /* עcallbackƵ̵߳ */
+ static void defaultCallback(void *userdata, Uint8 *stream, int size)
+ {
+ static SDLAudio* audio = static_cast<SDLAudio*>(userdata);
+ if (!audio->goOnProcess())
+ return;
+ audio->lock();
+ audio->processCommands();
+ audio->processSources(stream, size);
+ audio->processBuffer(stream, size);
+ audio->unlock();
+ }
+
+ /*call only once*/ bool SDLAudio::initSystem(const SettingBase* s)
+ {
+ #if LIBJIN_DEBUG
+ Loghelper::log(Loglevel::LV_INFO, "Init Audio System");
+ #endif
+
+ if (SDL_Init(SDL_INIT_AUDIO) < 0)
+ return false;
+ SDL_AudioSpec spec;
+ Setting* setting = (Setting*)s;
+ if (setting == nullptr)
+ return false;
+
+ unsigned int samplerate = setting->samplerate;
+ unsigned int samples = clamp<int>(setting->samples, 1, setting->samplerate);
+
+ spec.freq = samplerate; // ÿsample,õ 11025, 22050, 44100 and 48000 Hz.
+ spec.format = AUDIO_S16SYS; // signed 16-bit samples in native byte order
+ spec.channels = SDLAUDIO_CHANNELS; //
+ spec.samples = samples; // ÿβʱһã=setting->samplerateÿֻ1
+ spec.userdata = this;
+ spec.callback = defaultCallback;
+
+ audioDevice = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
+ if (audioDevice == 0)
+ return false;
+ /* start audio */
+ SDL_PauseAudioDevice(audioDevice, 0);
+ return true;
+ }
+
+ /*call only once*/ void SDLAudio::quitSystem()
+ {
+ SDL_CloseAudio();
+ }
+
+ void SDLAudio::lock()
+ {
+ SDL_LockAudioDevice(audioDevice);
+ }
+
+ void SDLAudio::unlock()
+ {
+ SDL_UnlockAudioDevice(audioDevice);
+ }
+
+ bool SDLAudio::goOnProcess()
+ {
+ if (state == SDLAudio::State::STOP)
+ {
+ SDLSourceManager::get()->removeAllSource();
+ pause();
+ return false;
+ }
+ else if (state == SDLAudio::State::PAUSE)
+ return false;
+ else
+ return true;
+ }
+
+ void SDLAudio::processCommands()
+ {
+ SDLSourceManager::get()->processCommands();
+ }
+
+ void SDLAudio::processSources(void* buffer, size_t len)
+ {
+ SDLSourceManager::get()->processSources(buffer, len);
+ }
+
+ void SDLAudio::processBuffer(void* buff, size_t len)
+ {
+ short* buffer = (short*)buff;
+ int samples = (len / SDLAUDIO_BYTEDEPTH) >> 1; // ˫
+ const char L = 0, R = 1;
+ for (int i = 0; i < samples; ++i)
+ {
+ short* clip = buffer + (i << 1);
+ clip[L] *= volume;
+ clip[R] *= volume;
+ }
+ }
+
+ void SDLAudio::play()
+ {
+ state = State::PLAY;
+ }
- void SDLAudio::stop()
- {
- state = State::STOP;
- }
+ void SDLAudio::stop()
+ {
+ state = State::STOP;
+ }
- void SDLAudio::pause()
- {
- state = State::PAUSE;
- }
-
- void SDLAudio::resume()
- {
- state = State::PLAY;
- }
+ void SDLAudio::pause()
+ {
+ state = State::PAUSE;
+ }
+
+ void SDLAudio::resume()
+ {
+ state = State::PLAY;
+ }
- void SDLAudio::setVolume(float volume)
- {
- this->volume = clamp(volume, 0.0f, 1.0f);
- }
+ void SDLAudio::setVolume(float volume)
+ {
+ this->volume = clamp(volume, 0.0f, 1.0f);
+ }
-} // audio
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO
diff --git a/src/libjin/Audio/SDL/SDLAudio.h b/src/libjin/Audio/SDL/SDLAudio.h
index db232b7..32519d2 100644
--- a/src/libjin/Audio/SDL/SDLAudio.h
+++ b/src/libjin/Audio/SDL/SDLAudio.h
@@ -9,51 +9,51 @@
namespace jin
{
-namespace audio
-{
-
-#define SDLAUDIO_BITDEPTH 16
-#define SDLAUDIO_BYTEDEPTH (SDLAUDIO_BITDEPTH >> 3)
-#define SDLAUDIO_CHANNELS 2
-
- class SDLAudio : public Audio<SDLAudio>
- {
- public:
- struct Setting : SettingBase
- {
- public:
- int samplerate; // Ƶ
- int samples; // sample<=samplerate
- };
-
- /* IAudio interface */
- void play() override;
- void stop() override;
- void pause() override;
- void resume() override;
- void setVolume(float volume) override;
- /* process functions*/
- void processCommands();
- void processSources(void* buffer, size_t len);
- void processBuffer(void* buffer, size_t len);
- bool goOnProcess();
- /* thread-safe */
- void lock();
- void unlock();
-
- private:
- SINGLETON(SDLAudio);
- SDLAudio() {};
- ~SDLAudio() {};
- /* subsystem interface */
- bool initSystem(const SettingBase* setting) override;
- void quitSystem() override;
-
- unsigned int audioDevice;
-
- };
-
-} // audio
+ namespace audio
+ {
+
+ #define SDLAUDIO_BITDEPTH 16
+ #define SDLAUDIO_BYTEDEPTH (SDLAUDIO_BITDEPTH >> 3)
+ #define SDLAUDIO_CHANNELS 2
+
+ class SDLAudio : public Audio<SDLAudio>
+ {
+ public:
+ struct Setting : SettingBase
+ {
+ public:
+ int samplerate; // Ƶ
+ int samples; // sample<=samplerate
+ };
+
+ /* IAudio interface */
+ void play() override;
+ void stop() override;
+ void pause() override;
+ void resume() override;
+ void setVolume(float volume) override;
+ /* process functions*/
+ void processCommands();
+ void processSources(void* buffer, size_t len);
+ void processBuffer(void* buffer, size_t len);
+ bool goOnProcess();
+ /* thread-safe */
+ void lock();
+ void unlock();
+
+ private:
+ SINGLETON(SDLAudio);
+ SDLAudio() {};
+ ~SDLAudio() {};
+ /* subsystem interface */
+ bool initSystem(const SettingBase* setting) override;
+ void quitSystem() override;
+
+ unsigned int audioDevice;
+
+ };
+
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO
diff --git a/src/libjin/Audio/SDL/SDLSource.cpp b/src/libjin/Audio/SDL/SDLSource.cpp
index 9f4f2fb..12ffb9b 100644
--- a/src/libjin/Audio/SDL/SDLSource.cpp
+++ b/src/libjin/Audio/SDL/SDLSource.cpp
@@ -14,386 +14,386 @@
namespace jin
{
-namespace audio
-{
-
- using namespace jin::math;
-
-#define BITS 8
-
- typedef struct SDLSourceCommand
- {
- typedef enum Action
- {
- Nothing = 0,
- Play,
- Stop,
- Pause,
- Resume,
- Rewind,
- SetVolume,
- SetLoop,
- SetRate,
- };
- Action action;
- union {
- int _integer;
- float _float;
- bool _boolean;
- const char* _string;
- } parameter;
-
- SDLSource* source;
- };
-
- typedef enum CHANNEL
- {
- MONO = 1, //
- STEREO = 2, //
- };
-
- typedef /*mask*/ enum STATUS
- {
- PLAYING = 1,
- PAUSED = 2,
- STOPPED = 4
- };
-
-#define Command SDLSourceCommand
-#define Action Command::Action
-#define Manager SDLSourceManager
-
- ///*class member*/ std::queue<Command*> Manager::commands;
- ///*class member*/ std::stack<Command*> Manager::commandsPool;
- ///*class member*/ std::vector<SDLSource*> Manager::sources;
- /*class member*/ Manager* Manager::manager = nullptr;
-
- SDLSource* SDLSource::createSource(const char* file)
- {
- std::ifstream fs;
- fs.open(file, std::ios::binary);
- if (!fs.is_open())
- {
- fs.close();
- return nullptr;
- }
- fs.seekg(0,std::ios::end);
- int size = fs.tellg();
- fs.seekg(0, std::ios::beg);
- char* buffer = (char*)malloc(size);
- memset(buffer, 0, size);
- fs.read(buffer, size);
- fs.close();
- SDLSource* source = createSource(buffer, size);
- free(buffer);
- return source;
- }
-
- SDLSource* SDLSource::createSource(void* mem, size_t size)
- {
- if (mem == nullptr)
- return nullptr;
- SDLSource* source = new SDLSource();
- try
- {
- SourceType format = getType(mem, size);
- switch (format)
- {
- case OGG: source->decode_ogg(mem, size); break;
- case WAV: source->decode_wav(mem, size); break;
- }
- }
- catch (SourceException& exp)
- {
- delete source;
- return nullptr;
- };
- return source;
- }
-
- SDLSource::SDLSource()
- {
- memset(&status, 0, sizeof(status));
- memset(&raw, 0, sizeof(raw));
- status.volume = 1;
- }
-
- SDLSource::~SDLSource()
- {
- delete raw.data;
- raw.end = 0;
- raw.data = 0;
- }
-
- void SDLSource::decode_wav(void* mem, int size)
- {
- wav_t wav;
- if (wav_read(&wav, mem, size) == 0)
- {
- raw.data = wav.data;
- raw.length = wav.length * wav.channels * wav.bitdepth / 8;
- raw.channels = clamp<int>(wav.channels, CHANNEL::MONO, CHANNEL::STEREO);
- raw.end = (char*)raw.data + raw.length;
- raw.samplerate = wav.samplerate;
- raw.bitdepth = wav.bitdepth;
- raw.samples = wav.length;
- }
- else
- throw SourceException();
- }
-
- void SDLSource::decode_ogg(void* _mem, int size)
- {
- unsigned char* mem = (unsigned char*)_mem;
- int channels;
- int samplerate;
- short* data = (short*)raw.data;
- int samples = stb_vorbis_decode_memory(
- mem,
- size,
- &channels,
- &samplerate,
- &data
- );
- const int bitdepth = sizeof(short) * BITS;
- raw.channels = channels;
- raw.samplerate = samplerate;
- raw.data = data;
- raw.samples = samples; // һsample
- raw.length = samples * channels * sizeof(short); // һsample
- raw.bitdepth = bitdepth;
- raw.end = (char*)data + raw.length;
- }
-
-#define ActionNone(T)\
-do{\
-Command* cmd = Manager::get()->getCommand();\
-cmd->action = Action::T; \
-cmd->source = this; \
-Manager::get()->pushCommand(cmd); \
-} while (0)
-
-#define ActionArg(T, ARGT, ARG)\
-do{\
-Command* cmd = Manager::get()->getCommand();\
-cmd->action = Action::T; \
-cmd->parameter.ARGT = ARG; \
-cmd->source = this; \
-Manager::get()->pushCommand(cmd); \
-}while(0)
-
-#define ActionInt(T, INT) ActionArg(T, _integer, INT)
-#define ActionFloat(T, FLT) ActionArg(T, _float, FLT)
-#define ActionString(T, STR) ActionArg(T, _string, STR)
-#define ActionBool(T, BOL) ActionArg(T, _boolean, BOL)
-
- void SDLSource::play()
- {
- ActionNone(Play);
- }
-
- void SDLSource::stop()
- {
- ActionNone(Stop);
- }
-
- void SDLSource::pause()
- {
- ActionNone(Pause);
- }
-
- void SDLSource::resume()
- {
- ActionNone(Resume);
- }
+ namespace audio
+ {
+
+ using namespace jin::math;
+
+ #define BITS 8
+
+ typedef struct SDLSourceCommand
+ {
+ typedef enum Action
+ {
+ Nothing = 0,
+ Play,
+ Stop,
+ Pause,
+ Resume,
+ Rewind,
+ SetVolume,
+ SetLoop,
+ SetRate,
+ };
+ Action action;
+ union {
+ int _integer;
+ float _float;
+ bool _boolean;
+ const char* _string;
+ } parameter;
+
+ SDLSource* source;
+ };
+
+ typedef enum CHANNEL
+ {
+ MONO = 1, //
+ STEREO = 2, //
+ };
+
+ typedef /*mask*/ enum STATUS
+ {
+ PLAYING = 1,
+ PAUSED = 2,
+ STOPPED = 4
+ };
+
+ #define Command SDLSourceCommand
+ #define Action Command::Action
+ #define Manager SDLSourceManager
+
+ ///*class member*/ std::queue<Command*> Manager::commands;
+ ///*class member*/ std::stack<Command*> Manager::commandsPool;
+ ///*class member*/ std::vector<SDLSource*> Manager::sources;
+ /*class member*/ Manager* Manager::manager = nullptr;
+
+ SDLSource* SDLSource::createSource(const char* file)
+ {
+ std::ifstream fs;
+ fs.open(file, std::ios::binary);
+ if (!fs.is_open())
+ {
+ fs.close();
+ return nullptr;
+ }
+ fs.seekg(0,std::ios::end);
+ int size = fs.tellg();
+ fs.seekg(0, std::ios::beg);
+ char* buffer = (char*)malloc(size);
+ memset(buffer, 0, size);
+ fs.read(buffer, size);
+ fs.close();
+ SDLSource* source = createSource(buffer, size);
+ free(buffer);
+ return source;
+ }
+
+ SDLSource* SDLSource::createSource(void* mem, size_t size)
+ {
+ if (mem == nullptr)
+ return nullptr;
+ SDLSource* source = new SDLSource();
+ try
+ {
+ SourceType format = getType(mem, size);
+ switch (format)
+ {
+ case OGG: source->decode_ogg(mem, size); break;
+ case WAV: source->decode_wav(mem, size); break;
+ }
+ }
+ catch (SourceException& exp)
+ {
+ delete source;
+ return nullptr;
+ };
+ return source;
+ }
+
+ SDLSource::SDLSource()
+ {
+ memset(&status, 0, sizeof(status));
+ memset(&raw, 0, sizeof(raw));
+ status.volume = 1;
+ }
+
+ SDLSource::~SDLSource()
+ {
+ delete raw.data;
+ raw.end = 0;
+ raw.data = 0;
+ }
+
+ void SDLSource::decode_wav(void* mem, int size)
+ {
+ wav_t wav;
+ if (wav_read(&wav, mem, size) == 0)
+ {
+ raw.data = wav.data;
+ raw.length = wav.length * wav.channels * wav.bitdepth / 8;
+ raw.channels = clamp<int>(wav.channels, CHANNEL::MONO, CHANNEL::STEREO);
+ raw.end = (char*)raw.data + raw.length;
+ raw.samplerate = wav.samplerate;
+ raw.bitdepth = wav.bitdepth;
+ raw.samples = wav.length;
+ }
+ else
+ throw SourceException();
+ }
+
+ void SDLSource::decode_ogg(void* _mem, int size)
+ {
+ unsigned char* mem = (unsigned char*)_mem;
+ int channels;
+ int samplerate;
+ short* data = (short*)raw.data;
+ int samples = stb_vorbis_decode_memory(
+ mem,
+ size,
+ &channels,
+ &samplerate,
+ &data
+ );
+ const int bitdepth = sizeof(short) * BITS;
+ raw.channels = channels;
+ raw.samplerate = samplerate;
+ raw.data = data;
+ raw.samples = samples; // һsample
+ raw.length = samples * channels * sizeof(short); // һsample
+ raw.bitdepth = bitdepth;
+ raw.end = (char*)data + raw.length;
+ }
+
+ #define ActionNone(T)\
+ do{\
+ Command* cmd = Manager::get()->getCommand();\
+ cmd->action = Action::T; \
+ cmd->source = this; \
+ Manager::get()->pushCommand(cmd); \
+ } while (0)
+
+ #define ActionArg(T, ARGT, ARG)\
+ do{\
+ Command* cmd = Manager::get()->getCommand();\
+ cmd->action = Action::T; \
+ cmd->parameter.ARGT = ARG; \
+ cmd->source = this; \
+ Manager::get()->pushCommand(cmd); \
+ }while(0)
+
+ #define ActionInt(T, INT) ActionArg(T, _integer, INT)
+ #define ActionFloat(T, FLT) ActionArg(T, _float, FLT)
+ #define ActionString(T, STR) ActionArg(T, _string, STR)
+ #define ActionBool(T, BOL) ActionArg(T, _boolean, BOL)
+
+ void SDLSource::play()
+ {
+ ActionNone(Play);
+ }
+
+ void SDLSource::stop()
+ {
+ ActionNone(Stop);
+ }
+
+ void SDLSource::pause()
+ {
+ ActionNone(Pause);
+ }
+
+ void SDLSource::resume()
+ {
+ ActionNone(Resume);
+ }
- void SDLSource::rewind()
- {
- ActionNone(Rewind);
- }
-
- inline bool SDLSource::isStopped() const
- {
- return is(STOPPED);
- }
-
- bool SDLSource::isPaused() const
- {
- return is(PAUSED);
- }
-
- void SDLSource::setPitch(float pitch)
- {
- }
-
- void SDLSource::setVolume(float volume)
- {
- ActionFloat(SetVolume, clamp(volume, 0.0f, 1.0f));
- }
-
- bool SDLSource::setLoop(bool loop)
- {
- ActionBool(SetLoop, loop);
- return false;
- }
-
- void SDLSource::setRate(float rate)
- {
- ActionFloat(SetRate, rate);
- }
-
- inline void SDLSource::handle(
- SDLSourceManager* manager,
- SDLSourceCommand* cmd
- )
- {
- switch (cmd->action)
- {
- case Command::Action::Play:
- manager->removeSource(this);
- manager->pushSource(this);
- status.state = PLAYING;
- status.pos = 0; // rewind
- break;
- case Command::Action::Stop:
- manager->removeSource(this);
- status.state = STOPPED;
- status.pos = 0; // rewind
- break;
- case Command::Action::Pause:
- manager->removeSource(this);
- status.state = PAUSED;
- break;
- case Command::Action::Resume:
- manager->removeSource(this);
- manager->pushSource(this);
- status.state = PLAYING;
- break;
- case Command::Action::Rewind:
- status.state = PLAYING;
- status.pos = 0;
- break;
- case Command::Action::SetVolume:
- status.volume = cmd->parameter._float;
- break;
- case Command::Action::SetLoop:
- status.loop = cmd->parameter._boolean;
- break;
- }
- }
+ void SDLSource::rewind()
+ {
+ ActionNone(Rewind);
+ }
+
+ inline bool SDLSource::isStopped() const
+ {
+ return is(STOPPED);
+ }
+
+ bool SDLSource::isPaused() const
+ {
+ return is(PAUSED);
+ }
+
+ void SDLSource::setPitch(float pitch)
+ {
+ }
+
+ void SDLSource::setVolume(float volume)
+ {
+ ActionFloat(SetVolume, clamp(volume, 0.0f, 1.0f));
+ }
+
+ bool SDLSource::setLoop(bool loop)
+ {
+ ActionBool(SetLoop, loop);
+ return false;
+ }
+
+ void SDLSource::setRate(float rate)
+ {
+ ActionFloat(SetRate, rate);
+ }
+
+ inline void SDLSource::handle(
+ SDLSourceManager* manager,
+ SDLSourceCommand* cmd
+ )
+ {
+ switch (cmd->action)
+ {
+ case Command::Action::Play:
+ manager->removeSource(this);
+ manager->pushSource(this);
+ status.state = PLAYING;
+ status.pos = 0; // rewind
+ break;
+ case Command::Action::Stop:
+ manager->removeSource(this);
+ status.state = STOPPED;
+ status.pos = 0; // rewind
+ break;
+ case Command::Action::Pause:
+ manager->removeSource(this);
+ status.state = PAUSED;
+ break;
+ case Command::Action::Resume:
+ manager->removeSource(this);
+ manager->pushSource(this);
+ status.state = PLAYING;
+ break;
+ case Command::Action::Rewind:
+ status.state = PLAYING;
+ status.pos = 0;
+ break;
+ case Command::Action::SetVolume:
+ status.volume = cmd->parameter._float;
+ break;
+ case Command::Action::SetLoop:
+ status.loop = cmd->parameter._boolean;
+ break;
+ }
+ }
- inline void SDLSource::process(void* buf, size_t size)
- {
- short* buffer = (short*)buf; // AUDIO_S16SYS
- int samples = (size / SDLAUDIO_BYTEDEPTH) >> 1; // ˫
- const char L = 0, R = 1;
- for (int i = 0; i < samples; ++i)
- {
- char* source = (char*)raw.data + status.pos * (raw.bitdepth / 8) * raw.channels;
- short l = 0;
- short r = 0;
- if (raw.bitdepth == 16)
- {
- l = ((short*)source)[L] * status.volume;
- r = ((short*)source)[L + raw.channels - 1] * status.volume;
- }
- else if (raw.bitdepth == 8)
- {
- l = source[L] << 8; // << 8 Ŵ16bits
- r = source[L + raw.channels - 1] << 8;
- }
- short* sample = buffer + (i << 1);
- sample[L] = clamp(sample[L] + l, SHRT_MIN, SHRT_MAX); //
- sample[R] = clamp(sample[R] + r, SHRT_MIN, SHRT_MAX); //
- ++status.pos;
- if (status.pos > raw.samples && status.loop)
- status.pos = 0; // rewind
- else if (status.pos > raw.samples && !status.loop)
- break;
- }
- }
-
- Manager* Manager::get()
- {
- return (manager == nullptr ? manager = new Manager() : manager);
- }
-
- void Manager::processCommands()
- {
- Command* cmd = nullptr;
- SDLSource* source = nullptr;
- while (!commands.empty())
- {
- cmd = commands.front();
- if (cmd != nullptr)
- {
- source = cmd->source;
- if (source != nullptr)
- source->handle(manager, cmd);
- }
- commands.pop();
- }
- }
-
- /* AUDIO_S16SYS[size>>1] buffer */
- void Manager::processSources(void* buf, size_t size)
- {
- /* clear render buffer */
- memset(buf, 0, size);
- SDLSource* src = nullptr;
- std::vector<SDLSource*>::iterator it = sources.begin();
- for (; it != sources.end();)
- {
- src = *it;
- if (src != nullptr)
- src->process(buf, size);
- ++it;
- }
- }
-
- void Manager::removeSource(SDLSource* source)
- {
- std::vector<SDLSource*>::iterator it = sources.begin();
- for (it = sources.begin(); it != sources.end(); )
- {
- if (*it == source)
- {
- it = sources.erase(it);
- return;
- }
- ++it;
- }
- }
-
- void Manager::removeAllSource()
- {
- sources.clear();
- }
-
- void Manager::pushSource(SDLSource* source)
- {
- if(source != nullptr)
- sources.push_back(source);
- }
-
- void Manager::pushCommand(SDLSourceCommand* cmd)
- {
- commands.push(cmd);
- }
-
- Command* Manager::getCommand()
- {
- if (!commandsPool.empty())
- {
- Command* cmd = commandsPool.top();
- commandsPool.pop();
- return cmd;
- }
- return new Command();
- }
-
-
-} // audio
+ inline void SDLSource::process(void* buf, size_t size)
+ {
+ short* buffer = (short*)buf; // AUDIO_S16SYS
+ int samples = (size / SDLAUDIO_BYTEDEPTH) >> 1; // ˫
+ const char L = 0, R = 1;
+ for (int i = 0; i < samples; ++i)
+ {
+ char* source = (char*)raw.data + status.pos * (raw.bitdepth / 8) * raw.channels;
+ short l = 0;
+ short r = 0;
+ if (raw.bitdepth == 16)
+ {
+ l = ((short*)source)[L] * status.volume;
+ r = ((short*)source)[L + raw.channels - 1] * status.volume;
+ }
+ else if (raw.bitdepth == 8)
+ {
+ l = source[L] << 8; // << 8 Ŵ16bits
+ r = source[L + raw.channels - 1] << 8;
+ }
+ short* sample = buffer + (i << 1);
+ sample[L] = clamp(sample[L] + l, SHRT_MIN, SHRT_MAX); //
+ sample[R] = clamp(sample[R] + r, SHRT_MIN, SHRT_MAX); //
+ ++status.pos;
+ if (status.pos > raw.samples && status.loop)
+ status.pos = 0; // rewind
+ else if (status.pos > raw.samples && !status.loop)
+ break;
+ }
+ }
+
+ Manager* Manager::get()
+ {
+ return (manager == nullptr ? manager = new Manager() : manager);
+ }
+
+ void Manager::processCommands()
+ {
+ Command* cmd = nullptr;
+ SDLSource* source = nullptr;
+ while (!commands.empty())
+ {
+ cmd = commands.front();
+ if (cmd != nullptr)
+ {
+ source = cmd->source;
+ if (source != nullptr)
+ source->handle(manager, cmd);
+ }
+ commands.pop();
+ }
+ }
+
+ /* AUDIO_S16SYS[size>>1] buffer */
+ void Manager::processSources(void* buf, size_t size)
+ {
+ /* clear render buffer */
+ memset(buf, 0, size);
+ SDLSource* src = nullptr;
+ std::vector<SDLSource*>::iterator it = sources.begin();
+ for (; it != sources.end();)
+ {
+ src = *it;
+ if (src != nullptr)
+ src->process(buf, size);
+ ++it;
+ }
+ }
+
+ void Manager::removeSource(SDLSource* source)
+ {
+ std::vector<SDLSource*>::iterator it = sources.begin();
+ for (it = sources.begin(); it != sources.end(); )
+ {
+ if (*it == source)
+ {
+ it = sources.erase(it);
+ return;
+ }
+ ++it;
+ }
+ }
+
+ void Manager::removeAllSource()
+ {
+ sources.clear();
+ }
+
+ void Manager::pushSource(SDLSource* source)
+ {
+ if(source != nullptr)
+ sources.push_back(source);
+ }
+
+ void Manager::pushCommand(SDLSourceCommand* cmd)
+ {
+ commands.push(cmd);
+ }
+
+ Command* Manager::getCommand()
+ {
+ if (!commandsPool.empty())
+ {
+ Command* cmd = commandsPool.top();
+ commandsPool.pop();
+ return cmd;
+ }
+ return new Command();
+ }
+
+
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO
diff --git a/src/libjin/Audio/SDL/SDLSource.h b/src/libjin/Audio/SDL/SDLSource.h
index 3feef9f..d9059cb 100644
--- a/src/libjin/Audio/SDL/SDLSource.h
+++ b/src/libjin/Audio/SDL/SDLSource.h
@@ -12,95 +12,95 @@
namespace jin
{
-namespace audio
-{
+ namespace audio
+ {
- typedef struct SDLSourceCommand;
- class SDLSourceManager;
+ typedef struct SDLSourceCommand;
+ class SDLSourceManager;
- class SDLSource : public Source
- {
- public:
- static SDLSource* createSource(const char* file);
- static SDLSource* createSource(void* mem, size_t size);
+ class SDLSource : public Source
+ {
+ public:
+ static SDLSource* createSource(const char* file);
+ static SDLSource* createSource(void* mem, size_t size);
- ~SDLSource();
- /* ISource interface */
- void play() override;
- void stop() override;
- void pause() override;
- void resume() override;
- void rewind() override;
- bool isStopped() const override;
- bool isPaused() const override;
- void setPitch(float pitch) override;
- void setVolume(float volume) override;
- bool setLoop(bool loop) override;
- void setRate(float rate) override;
- /* handle and process anduio clip */
- inline void handle(SDLSourceManager* manager, SDLSourceCommand* cmd);
- inline void process(void* buffer, size_t size);
+ ~SDLSource();
+ /* ISource interface */
+ void play() override;
+ void stop() override;
+ void pause() override;
+ void resume() override;
+ void rewind() override;
+ bool isStopped() const override;
+ bool isPaused() const override;
+ void setPitch(float pitch) override;
+ void setVolume(float volume) override;
+ bool setLoop(bool loop) override;
+ void setRate(float rate) override;
+ /* handle and process anduio clip */
+ inline void handle(SDLSourceManager* manager, SDLSourceCommand* cmd);
+ inline void process(void* buffer, size_t size);
- protected:
- SDLSource();
- /* decode raw audio data */
- void decode_wav(void* mem, int size);
- void decode_ogg(void* mem, int size);
- /* check state */
- inline bool is(int state) const { return (status.state & state) == state; }
+ protected:
+ SDLSource();
+ /* decode raw audio data */
+ void decode_wav(void* mem, int size);
+ void decode_ogg(void* mem, int size);
+ /* check state */
+ inline bool is(int state) const { return (status.state & state) == state; }
- struct{
- const void* data; // Ƶ
- int length; // dataֽڳ
- const void* end; // dataβ = (unsigned char*)data + size
- int samplerate; // Ƶ
- unsigned char bitdepth; // ÿsampleıس
- int samples; // sample = size / (bitdepth / 8)
- unsigned char channels; // channel1(mono)2(stereo)
- } raw;
- /* Procedure controller variable */
- struct{
- int pos; // ǰŵsample
- int pitch; // pitch
- int state; // ǰ״̬
- bool loop; // loop or not
- float volume; //
- } status;
+ struct{
+ const void* data; // Ƶ
+ int length; // dataֽڳ
+ const void* end; // dataβ = (unsigned char*)data + size
+ int samplerate; // Ƶ
+ unsigned char bitdepth; // ÿsampleıس
+ int samples; // sample = size / (bitdepth / 8)
+ unsigned char channels; // channel1(mono)2(stereo)
+ } raw;
+ /* Procedure controller variable */
+ struct{
+ int pos; // ǰŵsample
+ int pitch; // pitch
+ int state; // ǰ״̬
+ bool loop; // loop or not
+ float volume; //
+ } status;
- };
+ };
- class SDLSourceManager
- {
- public:
- static SDLSourceManager* get();
+ class SDLSourceManager
+ {
+ public:
+ static SDLSourceManager* get();
- /* Process function */
- void processCommands();
- void processSources(void* buffer, size_t size);
- /* control flow */
- void removeAllSource();
- void removeSource(SDLSource* source);
- void pushSource(SDLSource* source);
- SDLSourceCommand* getCommand();
- void pushCommand(SDLSourceCommand* cmd);
+ /* Process function */
+ void processCommands();
+ void processSources(void* buffer, size_t size);
+ /* control flow */
+ void removeAllSource();
+ void removeSource(SDLSource* source);
+ void pushSource(SDLSource* source);
+ SDLSourceCommand* getCommand();
+ void pushCommand(SDLSourceCommand* cmd);
- private :
- std::queue<SDLSourceCommand*> commands;
- std::stack<SDLSourceCommand*> commandsPool;
- std::vector<SDLSource*> sources; // processing sources
- static SDLSourceManager* manager;
+ private :
+ std::queue<SDLSourceCommand*> commands;
+ std::stack<SDLSourceCommand*> commandsPool;
+ std::vector<SDLSource*> sources; // processing sources
+ static SDLSourceManager* manager;
- };
+ };
- class SourceException : public std::exception
- {
- const char * what() const throw ()
- {
- return "Load Source Exception";
- }
- };
+ class SourceException : public std::exception
+ {
+ const char * what() const throw ()
+ {
+ return "Load Source Exception";
+ }
+ };
-} // audio
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO
diff --git a/src/libjin/Audio/Source.cpp b/src/libjin/Audio/Source.cpp
index 1dcd482..306d93f 100644
--- a/src/libjin/Audio/Source.cpp
+++ b/src/libjin/Audio/Source.cpp
@@ -6,24 +6,24 @@
namespace jin
{
-namespace audio
-{
+ namespace audio
+ {
- static int check_header(const void *data, int size, const char *str, int offset) {
- int len = strlen(str);
- return (size >= offset + len) && !memcmp((char*)data + offset, str, len);
- }
+ static int check_header(const void *data, int size, const char *str, int offset) {
+ int len = strlen(str);
+ return (size >= offset + len) && !memcmp((char*)data + offset, str, len);
+ }
- SourceType Source::getType(const void* mem, int size)
- {
- if(check_header(mem, size, "WAVE", 8))
- return SourceType::WAV;
- if(check_header(mem, size, "OggS", 0))
- return SourceType::OGG;
- return SourceType::INVALID;
- }
+ SourceType Source::getType(const void* mem, int size)
+ {
+ if(check_header(mem, size, "WAVE", 8))
+ return SourceType::WAV;
+ if(check_header(mem, size, "OggS", 0))
+ return SourceType::OGG;
+ return SourceType::INVALID;
+ }
-} // audio
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO
diff --git a/src/libjin/Audio/Source.h b/src/libjin/Audio/Source.h
index e1ca6d0..40707de 100644
--- a/src/libjin/Audio/Source.h
+++ b/src/libjin/Audio/Source.h
@@ -7,40 +7,40 @@
namespace jin
{
-namespace audio
-{
-
- enum SourceType
- {
- INVALID = 0,
- WAV,
- OGG,
- };
-
- class Source
- {
- public:
- Source() {};
- virtual ~Source() {};
- /* interface */
- virtual void play() = 0;
- virtual void stop() = 0;
- virtual void pause() = 0;
- virtual void resume() = 0;
- virtual void rewind() = 0;
- virtual bool isStopped() const = 0;
- virtual bool isPaused() const = 0;
- virtual void setPitch(float pitch) = 0;
- virtual void setVolume(float volume) = 0;
- virtual bool setLoop(bool loop) = 0;
- virtual void setRate(float rate) = 0;
-
- protected:
- static SourceType getType(const void* mem, int size);
-
- };
-
-} // audio
+ namespace audio
+ {
+
+ enum SourceType
+ {
+ INVALID = 0,
+ WAV,
+ OGG,
+ };
+
+ class Source
+ {
+ public:
+ Source() {};
+ virtual ~Source() {};
+ /* interface */
+ virtual void play() = 0;
+ virtual void stop() = 0;
+ virtual void pause() = 0;
+ virtual void resume() = 0;
+ virtual void rewind() = 0;
+ virtual bool isStopped() const = 0;
+ virtual bool isPaused() const = 0;
+ virtual void setPitch(float pitch) = 0;
+ virtual void setVolume(float volume) = 0;
+ virtual bool setLoop(bool loop) = 0;
+ virtual void setRate(float rate) = 0;
+
+ protected:
+ static SourceType getType(const void* mem, int size);
+
+ };
+
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO
diff --git a/src/libjin/Common/Data.h b/src/libjin/Common/Data.h
deleted file mode 100644
index 4b0f1ba..0000000
--- a/src/libjin/Common/Data.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __JIN_COMMON_DATA_H
-#define __JIN_COMMON_DATA_H
-
-
-
-namespace jin
-{
-
- class DataBuffer
- {
- public:
- DataBuffer(int n)
- : len(n)
- {
- buffer = new char[len];
- memset(buffer, 0, len);
- }
- ~DataBuffer()
- {
- delete[] buffer;
- }
- char* operator&()
- {
- return buffer;
- }
-
- private:
- char* buffer;
- int len;
- };
-
-} // jin
-
-#endif \ No newline at end of file
diff --git a/src/libjin/Common/data.h b/src/libjin/Common/data.h
deleted file mode 100644
index 4b0f1ba..0000000
--- a/src/libjin/Common/data.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __JIN_COMMON_DATA_H
-#define __JIN_COMMON_DATA_H
-
-
-
-namespace jin
-{
-
- class DataBuffer
- {
- public:
- DataBuffer(int n)
- : len(n)
- {
- buffer = new char[len];
- memset(buffer, 0, len);
- }
- ~DataBuffer()
- {
- delete[] buffer;
- }
- char* operator&()
- {
- return buffer;
- }
-
- private:
- char* buffer;
- int len;
- };
-
-} // jin
-
-#endif \ No newline at end of file
diff --git a/src/libjin/Common/types.h b/src/libjin/Common/types.h
index 7e335c0..2d257c3 100644
--- a/src/libjin/Common/types.h
+++ b/src/libjin/Common/types.h
@@ -4,20 +4,20 @@
namespace jin
{
-namespace common
-{
+ namespace common
+ {
- typedef int8_t int8;
- typedef uint8_t uint8;
- typedef uint8 byte;
- typedef int16_t int16;
- typedef uint16_t uint16;
- typedef int32_t int32;
- typedef uint32_t uint32;
- typedef int64_t int64;
- typedef uint64_t uint64;
+ typedef int8_t int8;
+ typedef uint8_t uint8;
+ typedef uint8 byte;
+ typedef int16_t int16;
+ typedef uint16_t uint16;
+ typedef int32_t int32;
+ typedef uint32_t uint32;
+ typedef int64_t int64;
+ typedef uint64_t uint64;
-}
+ }
}
#endif \ No newline at end of file
diff --git a/src/libjin/Filesystem/Buffer.h b/src/libjin/Filesystem/Buffer.h
index 5598f66..a47b0ef 100644
--- a/src/libjin/Filesystem/Buffer.h
+++ b/src/libjin/Filesystem/Buffer.h
@@ -6,62 +6,62 @@
namespace jin
{
-namespace filesystem
-{
+ namespace filesystem
+ {
- /**
- * ڶϷָռbuffer
- */
- class Buffer
- {
- public:
- Buffer() : data(0), size(0) {}
- Buffer(const Buffer& src)
- {
- delete[] data;
- size = src.size;
- data = new char[size];
- memcpy(data, src.data, size);
- }
- Buffer(void* d, int s)
- {
- data = new char[size];
- memcpy(data, d, size);
- size = s;
- }
- Buffer(size_t s)
- {
- data = new char[s];
- memset(data, 0, s);
- size = s;
- }
- ~Buffer()
- {
- delete[] data;
- size = 0;
- }
- void operator = (const Buffer& buffer)
- {
- delete[] data;
- size = buffer.size;
- data = new char[size];
- memcpy(data, buffer.data, size);
- }
+ /**
+ * ڶϷָռbuffer
+ */
+ class Buffer
+ {
+ public:
+ Buffer() : data(0), size(0) {}
+ Buffer(const Buffer& src)
+ {
+ delete[] data;
+ size = src.size;
+ data = new char[size];
+ memcpy(data, src.data, size);
+ }
+ Buffer(void* d, int s)
+ {
+ data = new char[size];
+ memcpy(data, d, size);
+ size = s;
+ }
+ Buffer(size_t s)
+ {
+ data = new char[s];
+ memset(data, 0, s);
+ size = s;
+ }
+ ~Buffer()
+ {
+ delete[] data;
+ size = 0;
+ }
+ void operator = (const Buffer& buffer)
+ {
+ delete[] data;
+ size = buffer.size;
+ data = new char[size];
+ memcpy(data, buffer.data, size);
+ }
- void clear()
- {
- if (data == nullptr)
- return;
- free(data);
- data = nullptr;
- }
+ void clear()
+ {
+ if (data == nullptr)
+ return;
+ free(data);
+ data = nullptr;
+ }
- void* data;
- unsigned int size;
+ void* data;
+ unsigned int size;
- };
+ };
-} // filesystem
+ } // filesystem
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/Filesystem/Filesystem.cpp b/src/libjin/Filesystem/Filesystem.cpp
index 3f91274..b8faed7 100644
--- a/src/libjin/Filesystem/Filesystem.cpp
+++ b/src/libjin/Filesystem/Filesystem.cpp
@@ -5,63 +5,63 @@
namespace jin
{
-namespace filesystem
-{
+ namespace filesystem
+ {
- Filesystem* Filesystem::fs = 0;
+ Filesystem* Filesystem::fs = 0;
- Filesystem::Filesystem()
- {
- S = smtnewshared();
- }
+ Filesystem::Filesystem()
+ {
+ S = smtnewshared();
+ }
- Filesystem* Filesystem::get()
- {
- return fs ? fs : (fs = new Filesystem());
- }
+ Filesystem* Filesystem::get()
+ {
+ return fs ? fs : (fs = new Filesystem());
+ }
- void Filesystem::mount(const char * path)
- {
- int err = smtmount(S, path);
- if (err)
- {
- printf("%s mounted path %s", smterrstr(err), path);
- exit(1);
- }
- }
+ void Filesystem::mount(const char * path)
+ {
+ int err = smtmount(S, path);
+ if (err)
+ {
+ printf("%s mounted path %s", smterrstr(err), path);
+ exit(1);
+ }
+ }
- int Filesystem::read(const char* path, Buffer* buffer)
- {
- buffer->data = smtread(S, path, &buffer->size);
- if (buffer->data == 0)
- return 0;
- return 1;
- }
+ int Filesystem::read(const char* path, Buffer* buffer)
+ {
+ buffer->data = smtread(S, path, &buffer->size);
+ if (buffer->data == 0)
+ return 0;
+ return 1;
+ }
- void* Filesystem::read(const char* path, unsigned int* len)
- {
- return smtread(S, path, len);
- }
+ void* Filesystem::read(const char* path, unsigned int* len)
+ {
+ return smtread(S, path, len);
+ }
- const char* Filesystem::getFull(const char* path)
- {
- return smtfullpath(S, path);
- }
+ const char* Filesystem::getFull(const char* path)
+ {
+ return smtfullpath(S, path);
+ }
- bool Filesystem::isDir(const char* path)
- {
- return smtisdir(S, path);
- }
+ bool Filesystem::isDir(const char* path)
+ {
+ return smtisdir(S, path);
+ }
- bool Filesystem::isFile(const char* path)
- {
- return smtisreg(S, path);
- }
+ bool Filesystem::isFile(const char* path)
+ {
+ return smtisreg(S, path);
+ }
- bool Filesystem::exists(const char* path)
- {
- return smtexists(S, path) == 0;
- }
+ bool Filesystem::exists(const char* path)
+ {
+ return smtexists(S, path) == 0;
+ }
-} // filesystem
+ } // filesystem
} // jin \ No newline at end of file
diff --git a/src/libjin/Filesystem/Filesystem.h b/src/libjin/Filesystem/Filesystem.h
index 3ae984d..b43d260 100644
--- a/src/libjin/Filesystem/Filesystem.h
+++ b/src/libjin/Filesystem/Filesystem.h
@@ -3,29 +3,29 @@
namespace jin
{
-namespace filesystem
-{
- /* Դ */
- class Filesystem
- {
- public:
- static Filesystem* get();
+ namespace filesystem
+ {
+ /* Դ */
+ class Filesystem
+ {
+ public:
+ static Filesystem* get();
- Filesystem();
+ Filesystem();
- bool isDir(const char* path);
- bool isFile(const char* path);
- bool exists(const char* path);
- int read(const char* path, Buffer* buffer);
- void* read(const char* path, unsigned int* len);
- void mount(const char* root);
- const char* getFull(const char* path);
+ bool isDir(const char* path);
+ bool isFile(const char* path);
+ bool exists(const char* path);
+ int read(const char* path, Buffer* buffer);
+ void* read(const char* path, unsigned int* len);
+ void mount(const char* root);
+ const char* getFull(const char* path);
- private:
- static Filesystem* fs;
- smtShared* S;
+ private:
+ static Filesystem* fs;
+ smtShared* S;
- };
+ };
-} // filesystem
+ } // filesystem
} // jin \ No newline at end of file
diff --git a/src/libjin/Game/Game.cpp b/src/libjin/Game/Game.cpp
index 65baaaa..82597b7 100644
--- a/src/libjin/Game/Game.cpp
+++ b/src/libjin/Game/Game.cpp
@@ -7,66 +7,66 @@
namespace jin
{
-namespace core
-{
+ namespace core
+ {
- using namespace jin::graphics;
- using namespace jin::input;
- using namespace jin::time;
- using namespace jin::math;
+ using namespace jin::graphics;
+ using namespace jin::input;
+ using namespace jin::time;
+ using namespace jin::math;
- Game::Game() :_running(true) {};
+ Game::Game() :_running(true) {};
- /* default game loop */
- void Game::run()
- {
- if (_onLoad != nullptr)
- _onLoad();
- Window* wnd = Window::get();
- const int FPS = wnd ? wnd->getFPS() : 60;
- const int MS_PER_UPDATE = 1000.0f / FPS;
- _running = true;
- Event e;
- int current = getMilliSecond();
- int previous = current;
- int dt = 0;
- while (_running)
- {
- while (jin::input::pollEvent(&e))
- {
- if (_onEvent != nullptr)
- _onEvent(&e);
- if (!_running)
- goto quitloop;
- }
- previous = current;
- current = getMilliSecond();
- dt = current - previous;
- if (_onUpdate != nullptr)
- _onUpdate(dt);
- if (_onDraw != nullptr)
- _onDraw();
- wnd->swapBuffers();
- sleep(1);
- }
- quitloop:;
- }
+ /* default game loop */
+ void Game::run()
+ {
+ if (_onLoad != nullptr)
+ _onLoad();
+ Window* wnd = Window::get();
+ const int FPS = wnd ? wnd->getFPS() : 60;
+ const int MS_PER_UPDATE = 1000.0f / FPS;
+ _running = true;
+ Event e;
+ int current = getMilliSecond();
+ int previous = current;
+ int dt = 0;
+ while (_running)
+ {
+ while (jin::input::pollEvent(&e))
+ {
+ if (_onEvent != nullptr)
+ _onEvent(&e);
+ if (!_running)
+ goto quitloop;
+ }
+ previous = current;
+ current = getMilliSecond();
+ dt = current - previous;
+ if (_onUpdate != nullptr)
+ _onUpdate(dt);
+ if (_onDraw != nullptr)
+ _onDraw();
+ wnd->swapBuffers();
+ sleep(1);
+ }
+ quitloop:;
+ }
- bool Game::initSystem(const SettingBase* setting)
- {
- if (setting == nullptr)
- return false;
- Game::Setting* s = (Game::Setting*) setting;
- _onEvent = s->eventHandler;
- _onUpdate = s->updater;
- _onDraw = s->drawer;
- _onLoad = s->loader;
- return true;
- }
+ bool Game::initSystem(const SettingBase* setting)
+ {
+ if (setting == nullptr)
+ return false;
+ Game::Setting* s = (Game::Setting*) setting;
+ _onEvent = s->eventHandler;
+ _onUpdate = s->updater;
+ _onDraw = s->drawer;
+ _onLoad = s->loader;
+ return true;
+ }
- void Game::quitSystem()
- {
- }
+ void Game::quitSystem()
+ {
+ }
-} // core
+ } // core
} // jin \ No newline at end of file
diff --git a/src/libjin/Game/Game.h b/src/libjin/Game/Game.h
index 725c62c..ede2418 100644
--- a/src/libjin/Game/Game.h
+++ b/src/libjin/Game/Game.h
@@ -9,50 +9,50 @@
namespace jin
{
-namespace core
-{
-
- class Game : public Subsystem<Game>
- {
- public:
-
- typedef void(*onLoad)();
- typedef void(*onEvent)(jin::input::Event* e);
- typedef void(*onUpdate)(int dt);
- typedef void(*onDraw)();
-
- struct Setting : SettingBase
- {
- onEvent eventHandler;
- onUpdate updater;
- onDraw drawer;
- onLoad loader;
- };
-
- void run();
- inline void stop() { _running = false; };
- inline bool running() { return _running; };
-
- private:
+ namespace core
+ {
+
+ class Game : public Subsystem<Game>
+ {
+ public:
+
+ typedef void(*onLoad)();
+ typedef void(*onEvent)(jin::input::Event* e);
+ typedef void(*onUpdate)(int dt);
+ typedef void(*onDraw)();
+
+ struct Setting : SettingBase
+ {
+ onEvent eventHandler;
+ onUpdate updater;
+ onDraw drawer;
+ onLoad loader;
+ };
+
+ void run();
+ inline void stop() { _running = false; };
+ inline bool running() { return _running; };
+
+ private:
- Game();
- ~Game() {};
+ Game();
+ ~Game() {};
- SINGLETON(Game);
+ SINGLETON(Game);
- onEvent _onEvent;
- onUpdate _onUpdate;
- onDraw _onDraw;
- onLoad _onLoad;
+ onEvent _onEvent;
+ onUpdate _onUpdate;
+ onDraw _onDraw;
+ onLoad _onLoad;
- bool _running;
+ bool _running;
- bool initSystem(const SettingBase* setting);
- void quitSystem();
+ bool initSystem(const SettingBase* setting);
+ void quitSystem();
- };
+ };
-} // core
+ } // core
} // jin
#endif // __LIBJIN_CORE_GAME_H
diff --git a/src/libjin/Graphics/Bitmap.cpp b/src/libjin/Graphics/Bitmap.cpp
index 160fda2..8769e8f 100644
--- a/src/libjin/Graphics/Bitmap.cpp
+++ b/src/libjin/Graphics/Bitmap.cpp
@@ -7,144 +7,144 @@ using namespace jin::math;
namespace jin
{
-namespace graphics
-{
-
- /* pixelbitmap */
- Bitmap* Bitmap::createBitmap(const void* pixel, unsigned width, unsigned height)
- {
- Bitmap* bitmap = new Bitmap(width, height);
- memcpy(bitmap->pixels, pixel, width*height * sizeof(Color));
- return bitmap;
- }
-
- /*static*/ Bitmap* Bitmap::createBitmap(const void* imgData, size_t size)
- {
- if (imgData == nullptr)
- return nullptr;
- int w, h;
- void* data = stbi_load_from_memory((unsigned char *)imgData, size, &w, &h, NULL, STBI_rgb_alpha);
- if (data == nullptr)
- return nullptr;
- Bitmap* bitmap = new Bitmap();
- bitmap->pixels = (Color*)data;
- bitmap->width = w;
- bitmap->height = h;
- return bitmap;
- }
-
- /*static*/ Bitmap* Bitmap::createBitmap(int w, int h, Color color)
- {
- Bitmap* bitmap = new Bitmap(w, h);
- if (color != Color::BLACK)
- bitmap->setPixels(color);
- return bitmap;
- }
-
- /*static */ Bitmap* Bitmap::clone(const Bitmap* bitmap)
- {
- Bitmap* b = new Bitmap();
- int w = bitmap->getWidth();
- int h = bitmap->getHeight();
- b->resetPixels(bitmap->getPixels(), w, h);
- return b;
- }
-
- Bitmap::Bitmap()
- : width(0)
- , height(0)
- , pixels(nullptr)
- {
- }
-
- Bitmap::Bitmap(unsigned w, unsigned h)
- {
- width = w;
- height = h;
- pixels = new Color[w*h];
- }
-
- Bitmap::~Bitmap()
- {
- stbi_image_free(pixels);
- }
-
- void Bitmap::bind(Color* p, int w, int h)
- {
- if (pixels != nullptr)
- delete[] pixels;
- pixels = p;
- width = w;
- height = h;
- }
-
- void Bitmap::resetPixels(const Color* p, int w, int h)
- {
- if (pixels != nullptr)
- delete[] pixels;
- pixels = new Color[w*h];
- size_t s = w * h * sizeof(Color);
- memcpy(pixels, p, s);
- width = w;
- height = h;
- }
-
- void Bitmap::setPixel(const Color& c, int x, int y)
- {
- if (pixels == nullptr)
- return;
- if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1))
- return;
- pixels[x + y * width] = c;
- }
-
- void Bitmap::resetPixels(const Color& c, int w, int h)
- {
- if (pixels != nullptr)
- delete[] pixels;
- pixels = new Color[w*h];
- size_t s = w * h * sizeof(Color);
- width = w;
- height = h;
- for (int x = 0; x < w; ++x)
- {
- for (int y = 0; y < h; ++y)
- {
- pixels[x + y * w] = c;
- }
- }
- }
-
- void Bitmap::setPixels(Color* p)
- {
- size_t s = width * height * sizeof(Color);
- memcpy(pixels, p, s);
- }
-
- void Bitmap::setPixels(Color c)
- {
- for (int x = 0; x < width; ++x)
- {
- for (int y = 0; y < height; ++y)
- {
- pixels[x + y * width] = c;
- }
- }
- }
-
- Color Bitmap::getPixel(int x, int y)
- {
- if (pixels == nullptr)
- return Color::BLACK;
- if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1))
- return Color::BLACK;
- return pixels[x + y * width];
- }
+ namespace graphics
+ {
+
+ /* pixelbitmap */
+ Bitmap* Bitmap::createBitmap(const void* pixel, unsigned width, unsigned height)
+ {
+ Bitmap* bitmap = new Bitmap(width, height);
+ memcpy(bitmap->pixels, pixel, width*height * sizeof(Color));
+ return bitmap;
+ }
+
+ /*static*/ Bitmap* Bitmap::createBitmap(const void* imgData, size_t size)
+ {
+ if (imgData == nullptr)
+ return nullptr;
+ int w, h;
+ void* data = stbi_load_from_memory((unsigned char *)imgData, size, &w, &h, NULL, STBI_rgb_alpha);
+ if (data == nullptr)
+ return nullptr;
+ Bitmap* bitmap = new Bitmap();
+ bitmap->pixels = (Color*)data;
+ bitmap->width = w;
+ bitmap->height = h;
+ return bitmap;
+ }
+
+ /*static*/ Bitmap* Bitmap::createBitmap(int w, int h, Color color)
+ {
+ Bitmap* bitmap = new Bitmap(w, h);
+ if (color != Color::BLACK)
+ bitmap->setPixels(color);
+ return bitmap;
+ }
+
+ /*static */ Bitmap* Bitmap::clone(const Bitmap* bitmap)
+ {
+ Bitmap* b = new Bitmap();
+ int w = bitmap->getWidth();
+ int h = bitmap->getHeight();
+ b->resetPixels(bitmap->getPixels(), w, h);
+ return b;
+ }
+
+ Bitmap::Bitmap()
+ : width(0)
+ , height(0)
+ , pixels(nullptr)
+ {
+ }
+
+ Bitmap::Bitmap(unsigned w, unsigned h)
+ {
+ width = w;
+ height = h;
+ pixels = new Color[w*h];
+ }
+
+ Bitmap::~Bitmap()
+ {
+ stbi_image_free(pixels);
+ }
+
+ void Bitmap::bind(Color* p, int w, int h)
+ {
+ if (pixels != nullptr)
+ delete[] pixels;
+ pixels = p;
+ width = w;
+ height = h;
+ }
+
+ void Bitmap::resetPixels(const Color* p, int w, int h)
+ {
+ if (pixels != nullptr)
+ delete[] pixels;
+ pixels = new Color[w*h];
+ size_t s = w * h * sizeof(Color);
+ memcpy(pixels, p, s);
+ width = w;
+ height = h;
+ }
+
+ void Bitmap::setPixel(const Color& c, int x, int y)
+ {
+ if (pixels == nullptr)
+ return;
+ if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1))
+ return;
+ pixels[x + y * width] = c;
+ }
+
+ void Bitmap::resetPixels(const Color& c, int w, int h)
+ {
+ if (pixels != nullptr)
+ delete[] pixels;
+ pixels = new Color[w*h];
+ size_t s = w * h * sizeof(Color);
+ width = w;
+ height = h;
+ for (int x = 0; x < w; ++x)
+ {
+ for (int y = 0; y < h; ++y)
+ {
+ pixels[x + y * w] = c;
+ }
+ }
+ }
+
+ void Bitmap::setPixels(Color* p)
+ {
+ size_t s = width * height * sizeof(Color);
+ memcpy(pixels, p, s);
+ }
+
+ void Bitmap::setPixels(Color c)
+ {
+ for (int x = 0; x < width; ++x)
+ {
+ for (int y = 0; y < height; ++y)
+ {
+ pixels[x + y * width] = c;
+ }
+ }
+ }
+
+ Color Bitmap::getPixel(int x, int y)
+ {
+ if (pixels == nullptr)
+ return Color::BLACK;
+ if (without<int>(x, 0, width - 1) || without<int>(y, 0, height - 1))
+ return Color::BLACK;
+ return pixels[x + y * width];
+ }
- const Color* Bitmap::getPixels() const
- {
- return pixels;
- }
+ const Color* Bitmap::getPixels() const
+ {
+ return pixels;
+ }
-}
+ }
} \ No newline at end of file
diff --git a/src/libjin/Graphics/Bitmap.h b/src/libjin/Graphics/Bitmap.h
index 6264c37..5599521 100644
--- a/src/libjin/Graphics/Bitmap.h
+++ b/src/libjin/Graphics/Bitmap.h
@@ -9,43 +9,43 @@
namespace jin
{
-namespace graphics
-{
-
- class Bitmap
- {
- public:
- static Bitmap* createBitmap(const void* pixel, unsigned width, unsigned height);
- static Bitmap* createBitmap(const void* imgData, size_t size);
- static Bitmap* createBitmap(int w, int h, Color color = Color::BLACK);
- static Bitmap* clone(const Bitmap* bitmap);
-
- virtual ~Bitmap();
- /* init pixels */
- void bind(Color* pixels, int w, int h);
- void resetPixels(const Color* pixels, int w, int h);
- void resetPixels(const Color& pixels, int w, int h);
- /* modify pixels */
- void setPixel(const Color& pixel, int x, int y);
- void setPixels(Color pixels);
- void setPixels(Color* pixels);
- Color getPixel(int x, int y);
- const Color* getPixels() const;
- /* get width and height */
- inline int getWidth() const { return width; }
- inline int getHeight() const { return height; }
- inline math::Vector2<int> getSize() const { return math::Vector2<int>(width, height); }
-
- protected:
- Bitmap();
- Bitmap(unsigned w, unsigned h);
-
- Color * pixels;
- unsigned width, height;
-
- };
-
-} // graphics
+ namespace graphics
+ {
+
+ class Bitmap
+ {
+ public:
+ static Bitmap* createBitmap(const void* pixel, unsigned width, unsigned height);
+ static Bitmap* createBitmap(const void* imgData, size_t size);
+ static Bitmap* createBitmap(int w, int h, Color color = Color::BLACK);
+ static Bitmap* clone(const Bitmap* bitmap);
+
+ virtual ~Bitmap();
+ /* init pixels */
+ void bind(Color* pixels, int w, int h);
+ void resetPixels(const Color* pixels, int w, int h);
+ void resetPixels(const Color& pixels, int w, int h);
+ /* modify pixels */
+ void setPixel(const Color& pixel, int x, int y);
+ void setPixels(Color pixels);
+ void setPixels(Color* pixels);
+ Color getPixel(int x, int y);
+ const Color* getPixels() const;
+ /* get width and height */
+ inline int getWidth() const { return width; }
+ inline int getHeight() const { return height; }
+ inline math::Vector2<int> getSize() const { return math::Vector2<int>(width, height); }
+
+ protected:
+ Bitmap();
+ Bitmap(unsigned w, unsigned h);
+
+ Color * pixels;
+ unsigned width, height;
+
+ };
+
+ } // graphics
} // jin
#endif
diff --git a/src/libjin/Graphics/Canvas.cpp b/src/libjin/Graphics/Canvas.cpp
index d34731a..6db06c6 100644
--- a/src/libjin/Graphics/Canvas.cpp
+++ b/src/libjin/Graphics/Canvas.cpp
@@ -7,96 +7,96 @@
namespace jin
{
-namespace graphics
-{
-
- /*class member*/ const Canvas* Canvas::current = nullptr;
- /*class member*/ const Canvas* const Canvas::DEFAULT_CANVAS = new Canvas(0);
-
- /*class member*/ Canvas* Canvas::createCanvas(int w, int h)
- {
- return new Canvas(w, h);
- }
-
- Canvas::Canvas(GLuint n)
- : fbo(n)
- {
- }
-
- Canvas::Canvas(int w, int h)
- : Drawable(w, h)
- {
- GLint current_fbo;
- glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);
-
- /* generate a new render buffer object */
- fbo = gl.genFrameBuffer();
- gl.bindFrameBuffer(fbo);
-
- /* generate texture save target */
- texture = gl.genTexture();
- gl.bindTexture(texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- gl.bindTexture(0);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
-
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-
- /* unbind framebuffer */
- gl.bindFrameBuffer(current_fbo);
- }
-
- Canvas::~Canvas()
- {
- }
-
- /*class member*/ bool Canvas::isBinded(const Canvas* cvs)
- {
- return current == cvs;
- }
-
- /**
- * bind to canvas
- */
- /*class member*/ void Canvas::bind(Canvas* canvas)
- {
- if (isBinded(canvas)) return;
- current = canvas;
- gl.bindFrameBuffer(canvas->fbo);
- int w = canvas->size.w;
- int h = canvas->size.h;
- /* set view port to canvas */
- glViewport(0, 0, w, h);
- gl.ProjectionMatrix.setOrtho(0, w, 0, h, -1, 1);
- }
-
- /**
- * bind to default screen render buffer.
- * do some coordinates transform work
- * https://blog.csdn.net/liji_digital/article/details/79370841
- * https://blog.csdn.net/lyx2007825/article/details/8792475
- */
- /*class member*/ void Canvas::unbind()
- {
- if (isBinded(DEFAULT_CANVAS)) return;
- current = DEFAULT_CANVAS;
- /* get window size as viewport */
- Window* wnd = Window::get();
- int w = wnd->getW();
- int h = wnd->getH();
-
- glBindFramebuffer(GL_FRAMEBUFFER, DEFAULT_CANVAS->fbo);
-
- /* set viewport on screen */
- glViewport(0, 0, w, h);
-
- gl.ProjectionMatrix.setOrtho(0, w, h, 0, -1, 1);
-
- }
-
-} // render
+ namespace graphics
+ {
+
+ /*class member*/ const Canvas* Canvas::current = nullptr;
+ /*class member*/ const Canvas* const Canvas::DEFAULT_CANVAS = new Canvas(0);
+
+ /*class member*/ Canvas* Canvas::createCanvas(int w, int h)
+ {
+ return new Canvas(w, h);
+ }
+
+ Canvas::Canvas(GLuint n)
+ : fbo(n)
+ {
+ }
+
+ Canvas::Canvas(int w, int h)
+ : Drawable(w, h)
+ {
+ GLint current_fbo;
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);
+
+ /* generate a new render buffer object */
+ fbo = gl.genFrameBuffer();
+ gl.bindFrameBuffer(fbo);
+
+ /* generate texture save target */
+ texture = gl.genTexture();
+ gl.bindTexture(texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ gl.bindTexture(0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+ /* unbind framebuffer */
+ gl.bindFrameBuffer(current_fbo);
+ }
+
+ Canvas::~Canvas()
+ {
+ }
+
+ /*class member*/ bool Canvas::isBinded(const Canvas* cvs)
+ {
+ return current == cvs;
+ }
+
+ /**
+ * bind to canvas
+ */
+ /*class member*/ void Canvas::bind(Canvas* canvas)
+ {
+ if (isBinded(canvas)) return;
+ current = canvas;
+ gl.bindFrameBuffer(canvas->fbo);
+ int w = canvas->size.w;
+ int h = canvas->size.h;
+ /* set view port to canvas */
+ glViewport(0, 0, w, h);
+ gl.ProjectionMatrix.setOrtho(0, w, 0, h, -1, 1);
+ }
+
+ /**
+ * bind to default screen render buffer.
+ * do some coordinates transform work
+ * https://blog.csdn.net/liji_digital/article/details/79370841
+ * https://blog.csdn.net/lyx2007825/article/details/8792475
+ */
+ /*class member*/ void Canvas::unbind()
+ {
+ if (isBinded(DEFAULT_CANVAS)) return;
+ current = DEFAULT_CANVAS;
+ /* get window size as viewport */
+ Window* wnd = Window::get();
+ int w = wnd->getW();
+ int h = wnd->getH();
+
+ glBindFramebuffer(GL_FRAMEBUFFER, DEFAULT_CANVAS->fbo);
+
+ /* set viewport on screen */
+ glViewport(0, 0, w, h);
+
+ gl.ProjectionMatrix.setOrtho(0, w, h, 0, -1, 1);
+
+ }
+
+ } // render
} // jin
#endif // LIBJIN_MODULES_RENDER \ No newline at end of file
diff --git a/src/libjin/Graphics/Canvas.h b/src/libjin/Graphics/Canvas.h
index 09ae7aa..4851c83 100644
--- a/src/libjin/Graphics/Canvas.h
+++ b/src/libjin/Graphics/Canvas.h
@@ -6,33 +6,33 @@
#include "drawable.h"
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- class Canvas: public Drawable
- {
- public:
- static Canvas* createCanvas(int w, int h);
+ class Canvas: public Drawable
+ {
+ public:
+ static Canvas* createCanvas(int w, int h);
- static void bind(Canvas*);
- static void unbind();
- static bool isBinded(const Canvas*);
+ static void bind(Canvas*);
+ static void unbind();
+ static bool isBinded(const Canvas*);
- ~Canvas();
+ ~Canvas();
- protected:
- static const Canvas* const DEFAULT_CANVAS;
- static const Canvas* current;
+ protected:
+ static const Canvas* const DEFAULT_CANVAS;
+ static const Canvas* current;
- Canvas(int w, int h);
- Canvas(GLuint n);
+ Canvas(int w, int h);
+ Canvas(GLuint n);
- GLuint fbo;
+ GLuint fbo;
- };
+ };
-} // render
+ } // render
} // jin
#endif // LIBJIN_MODULES_RENDER
diff --git a/src/libjin/Graphics/Color.cpp b/src/libjin/Graphics/Color.cpp
index 414b248..517af50 100644
--- a/src/libjin/Graphics/Color.cpp
+++ b/src/libjin/Graphics/Color.cpp
@@ -2,16 +2,16 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- const Color Color::WHITE = Color(255, 255, 255);
- const Color Color::BLACK = Color(0, 0, 0);
- const Color Color::RED = Color(255, 0, 0);
- const Color Color::GREEN = Color(0, 255, 0);
- const Color Color::BLUE = Color(0, 0, 255);
- const Color Color::MAGENTA = Color(255, 0, 255);
- const Color Color::YELLOW = Color(255, 255, 0);
+ const Color Color::WHITE = Color(255, 255, 255);
+ const Color Color::BLACK = Color(0, 0, 0);
+ const Color Color::RED = Color(255, 0, 0);
+ const Color Color::GREEN = Color(0, 255, 0);
+ const Color Color::BLUE = Color(0, 0, 255);
+ const Color Color::MAGENTA = Color(255, 0, 255);
+ const Color Color::YELLOW = Color(255, 255, 0);
-}
+ }
} \ No newline at end of file
diff --git a/src/libjin/Graphics/Color.h b/src/libjin/Graphics/Color.h
index 3de49dc..b235a66 100644
--- a/src/libjin/Graphics/Color.h
+++ b/src/libjin/Graphics/Color.h
@@ -10,75 +10,75 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- typedef unsigned char Channel;
+ typedef unsigned char Channel;
- class Color
- {
- public:
- /* Built-in Colors */
- static const Color WHITE;
- static const Color BLACK;
- static const Color RED;
- static const Color GREEN;
- static const Color BLUE;
- static const Color MAGENTA;
- static const Color YELLOW;
+ class Color
+ {
+ public:
+ /* Built-in Colors */
+ static const Color WHITE;
+ static const Color BLACK;
+ static const Color RED;
+ static const Color GREEN;
+ static const Color BLUE;
+ static const Color MAGENTA;
+ static const Color YELLOW;
- Color() { r = g = b = a = 0; };
+ Color() { r = g = b = a = 0; };
- Color(unsigned char _r
- , unsigned char _g
- , unsigned char _b
- , unsigned char _a = 255)
- {
- r = _r;
- g = _g;
- b = _b;
- a = _a;
- }
+ Color(unsigned char _r
+ , unsigned char _g
+ , unsigned char _b
+ , unsigned char _a = 255)
+ {
+ r = _r;
+ g = _g;
+ b = _b;
+ a = _a;
+ }
- Color(const Color& c)
- {
- r = c.r;
- g = c.g;
- b = c.b;
- a = c.a;
- }
+ Color(const Color& c)
+ {
+ r = c.r;
+ g = c.g;
+ b = c.b;
+ a = c.a;
+ }
- void set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a)
- {
- r = _r;
- g = _g;
- b = _b;
- a = _a;
- }
+ void set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a)
+ {
+ r = _r;
+ g = _g;
+ b = _b;
+ a = _a;
+ }
- void operator = (const Color& c)
- {
- r = c.r;
- g = c.g;
- b = c.b;
- a = c.a;
- }
+ void operator = (const Color& c)
+ {
+ r = c.r;
+ g = c.g;
+ b = c.b;
+ a = c.a;
+ }
- bool operator == (const Color& c)
- {
- return r == c.r && g == c.g && b == c.b && a == c.a;
- }
+ bool operator == (const Color& c)
+ {
+ return r == c.r && g == c.g && b == c.b && a == c.a;
+ }
- bool operator != (const Color& c)
- {
- return !(r == c.r && g == c.g && b == c.b && a == c.a);
- }
+ bool operator != (const Color& c)
+ {
+ return !(r == c.r && g == c.g && b == c.b && a == c.a);
+ }
- Channel r, g, b, a;
+ Channel r, g, b, a;
- };
+ };
-} // render
+ } // render
} // jin
#endif // LIBJIN_MODULES_RENDER
diff --git a/src/libjin/Graphics/Font/Decoder.cpp b/src/libjin/Graphics/Font/Decoder.cpp
index 10927f0..856627b 100644
--- a/src/libjin/Graphics/Font/Decoder.cpp
+++ b/src/libjin/Graphics/Font/Decoder.cpp
@@ -4,90 +4,90 @@
namespace jin
{
-namespace graphics
-{
-
- /* utf8 byte string to unicode codepoint */
- static const char *utf8toCodepoint(const char *p, unsigned *res) {
- return nullptr;
+ namespace graphics
+ {
- }
+ /* utf8 byte string to unicode codepoint */
+ static const char *utf8toCodepoint(const char *p, unsigned *res) {
+ return nullptr;
- /////////////////////////////////////////////////////////////////////////////
- // decoders
- /////////////////////////////////////////////////////////////////////////////
+ }
- const void* Utf8::decode(const void* data, Codepoint* res) const
- {
- const char* p = (char*)data;
- unsigned x, mask, shift;
- switch (*p & 0xf0) {
- case 0xf0: mask = 0x07; shift = 18; break;
- case 0xe0: mask = 0x0f; shift = 12; break;
- case 0xc0:
- case 0xd0: mask = 0x1f; shift = 6; break;
- default:
- *res = *p;
- return p + 1;
- }
- x = (*p & mask) << shift;
- do {
- if (*(++p) == '\0') {
- *res = x;
- return p;
- }
- shift -= 6;
- x |= (*p & 0x3f) << shift;
- } while (shift);
- *res = x;
- return p + 1;
- }
+ /////////////////////////////////////////////////////////////////////////////
+ // decoders
+ /////////////////////////////////////////////////////////////////////////////
- const void* Utf8::next(const void* data) const
- {
- const char* p = (char*)data;
- unsigned x, mask, shift;
- switch (*p & 0xf0) {
- case 0xf0: mask = 0x07; shift = 18; break;
- case 0xe0: mask = 0x0f; shift = 12; break;
- case 0xc0:
- case 0xd0: mask = 0x1f; shift = 6; break;
- default:
+ const void* Utf8::decode(const void* data, Codepoint* res) const
+ {
+ const char* p = (char*)data;
+ unsigned x, mask, shift;
+ switch (*p & 0xf0) {
+ case 0xf0: mask = 0x07; shift = 18; break;
+ case 0xe0: mask = 0x0f; shift = 12; break;
+ case 0xc0:
+ case 0xd0: mask = 0x1f; shift = 6; break;
+ default:
+ *res = *p;
+ return p + 1;
+ }
+ x = (*p & mask) << shift;
+ do {
+ if (*(++p) == '\0') {
+ *res = x;
+ return p;
+ }
+ shift -= 6;
+ x |= (*p & 0x3f) << shift;
+ } while (shift);
+ *res = x;
return p + 1;
}
- x = (*p & mask) << shift;
- do {
- if (*(++p) == '\0') {
- return p;
+
+ const void* Utf8::next(const void* data) const
+ {
+ const char* p = (char*)data;
+ unsigned x, mask, shift;
+ switch (*p & 0xf0) {
+ case 0xf0: mask = 0x07; shift = 18; break;
+ case 0xe0: mask = 0x0f; shift = 12; break;
+ case 0xc0:
+ case 0xd0: mask = 0x1f; shift = 6; break;
+ default:
+ return p + 1;
}
- shift -= 6;
- x |= (*p & 0x3f) << shift;
- } while (shift);
- return p + 1;
- }
-/*
- const void* Utf16::decode(const void* data, Codepoint* res) const
- {
- return nullptr;
- }
+ x = (*p & mask) << shift;
+ do {
+ if (*(++p) == '\0') {
+ return p;
+ }
+ shift -= 6;
+ x |= (*p & 0x3f) << shift;
+ } while (shift);
+ return p + 1;
+ }
+ /*
+ const void* Utf16::decode(const void* data, Codepoint* res) const
+ {
+ return nullptr;
+ }
- const void* Utf16::next(const void* data) const
- {
- return nullptr;
- }
-*/
- const void* Ascii::decode(const void* data, Codepoint* res) const
- {
- const char* p = (char*)data;
- *res = *p;
- return p + 1;
- }
+ const void* Utf16::next(const void* data) const
+ {
+ return nullptr;
+ }
+ */
+ const void* Ascii::decode(const void* data, Codepoint* res) const
+ {
+ const char* p = (char*)data;
+ *res = *p;
+ return p + 1;
+ }
- const void* Ascii::next(const void* data) const
- {
- const char* p = (char*)data;
- return p + 1;
- }
+ const void* Ascii::next(const void* data) const
+ {
+ const char* p = (char*)data;
+ return p + 1;
+ }
-} // graphics
+ } // graphics
} // jin \ No newline at end of file
diff --git a/src/libjin/Graphics/Font/Decoder.h b/src/libjin/Graphics/Font/Decoder.h
index 4568d65..e5940a2 100644
--- a/src/libjin/Graphics/Font/Decoder.h
+++ b/src/libjin/Graphics/Font/Decoder.h
@@ -7,38 +7,38 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- class Decoder
- {
- public:
- virtual const void* decode(const void* data, Codepoint* c) const = 0 ;
- virtual const void* next(const void* data) const = 0;
- };
+ class Decoder
+ {
+ public:
+ virtual const void* decode(const void* data, Codepoint* c) const = 0 ;
+ virtual const void* next(const void* data) const = 0;
+ };
- class Utf8 : public Decoder
- {
- public:
- const void* decode(const void* data, Codepoint* c) const override;
- const void* next(const void* data) const override;
- };
-/*
- class Utf16 : public Decoder
- {
- public:
- const void* decode(const void* data, Codepoint* c) const override;
- const void* next(const void* data) const override;
- };
-*/
- class Ascii : public Decoder
- {
- public:
- const void* decode(const void* data, Codepoint* c) const override;
- const void* next(const void* data) const override;
- };
+ class Utf8 : public Decoder
+ {
+ public:
+ const void* decode(const void* data, Codepoint* c) const override;
+ const void* next(const void* data) const override;
+ };
+ /*
+ class Utf16 : public Decoder
+ {
+ public:
+ const void* decode(const void* data, Codepoint* c) const override;
+ const void* next(const void* data) const override;
+ };
+ */
+ class Ascii : public Decoder
+ {
+ public:
+ const void* decode(const void* data, Codepoint* c) const override;
+ const void* next(const void* data) const override;
+ };
-} // graphics
+ } // graphics
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/Graphics/Font/Font.h b/src/libjin/Graphics/Font/Font.h
index fcc559c..9ccef54 100644
--- a/src/libjin/Graphics/Font/Font.h
+++ b/src/libjin/Graphics/Font/Font.h
@@ -5,35 +5,35 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- struct Page;
+ struct Page;
- class Font
- {
- public:
- Font(unsigned fontsize)
- : fontSize(fontsize)
- {
- }
- virtual ~Font() {};
+ class Font
+ {
+ public:
+ Font(unsigned fontsize)
+ : fontSize(fontsize)
+ {
+ }
+ virtual ~Font() {};
- virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0;
- virtual Page* typeset(const Content& text, int lineheight, int spacing = 0) = 0;
+ virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0;
+ virtual Page* typeset(const Content& text, int lineheight, int spacing = 0) = 0;
- virtual void print(const Page* page, int x, int y) = 0;
- virtual void print(const Content& text, int x, int y, int lineheight, int spacing = 0) = 0;
- virtual void print(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0;
+ virtual void print(const Page* page, int x, int y) = 0;
+ virtual void print(const Content& text, int x, int y, int lineheight, int spacing = 0) = 0;
+ virtual void print(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0;
- inline unsigned getFontSize() { return fontSize; };
+ inline unsigned getFontSize() { return fontSize; };
- protected:
- unsigned fontSize;
+ protected:
+ unsigned fontSize;
- };
+ };
-} // graphics
+ } // graphics
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/Graphics/Font/Page.h b/src/libjin/Graphics/Font/Page.h
index 6e7cbdf..e1430e1 100644
--- a/src/libjin/Graphics/Font/Page.h
+++ b/src/libjin/Graphics/Font/Page.h
@@ -5,34 +5,34 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- class Font;
+ class Font;
- struct GlyphVertex
- {
- int x, y; // screen coordinates
- float u, v; // texture uv
- };
+ struct GlyphVertex
+ {
+ int x, y; // screen coordinates
+ float u, v; // texture uv
+ };
- struct GlyphArrayDrawInfo
- {
- GLuint texture; // atlas
- unsigned int start; // glyph vertex indecies
- unsigned int count; // glyph vertex count
- };
+ struct GlyphArrayDrawInfo
+ {
+ GLuint texture; // atlas
+ unsigned int start; // glyph vertex indecies
+ unsigned int count; // glyph vertex count
+ };
- /* for reduce draw call */
- struct Page
- {
- Font* font;
- std::vector<GlyphArrayDrawInfo> glyphinfolist;
- std::vector<GlyphVertex> glyphvertices;
- math::Vector2<int> size;
- };
+ /* for reduce draw call */
+ struct Page
+ {
+ Font* font;
+ std::vector<GlyphArrayDrawInfo> glyphinfolist;
+ std::vector<GlyphVertex> glyphvertices;
+ math::Vector2<int> size;
+ };
-}
+ }
}
#endif \ No newline at end of file
diff --git a/src/libjin/Graphics/Font/TTF.cpp b/src/libjin/Graphics/Font/TTF.cpp
index 105bcfb..7e62485 100644
--- a/src/libjin/Graphics/Font/TTF.cpp
+++ b/src/libjin/Graphics/Font/TTF.cpp
@@ -15,440 +15,440 @@
namespace jin
{
-namespace graphics
-{
-
- /////////////////////////////////////////////////////////////////////////////
- // TTFData
- /////////////////////////////////////////////////////////////////////////////
-
- TTFData* TTFData::createTTFData(const unsigned char* data, unsigned int size)
- {
- TTFData* ttf = nullptr;
- try
- {
- ttf = new TTFData(data, size);
- return ttf;
- }
- catch (...)
- {
- return nullptr;
- }
- }
-
- TTFData::TTFData(const unsigned char* d, unsigned int s)
- {
- raw.size = s;
- raw.data = (unsigned char*)malloc(s);
- memcpy(raw.data, d, s);
- if (!stbtt_InitFont(&info, (const unsigned char*)raw.data, 0))
- {
- delete raw.data;
- throw 0;
- }
- /* push default fontsize */
- pushTTFsize(FONT_SIZE);
- }
-
- TTFData::~TTFData()
- {
- free(raw.data);
- }
-
- TTF* TTFData::createTTF(unsigned fontSize)
+ namespace graphics
{
- TTF* ttf;
- try
+
+ /////////////////////////////////////////////////////////////////////////////
+ // TTFData
+ /////////////////////////////////////////////////////////////////////////////
+
+ TTFData* TTFData::createTTFData(const unsigned char* data, unsigned int size)
+ {
+ TTFData* ttf = nullptr;
+ try
+ {
+ ttf = new TTFData(data, size);
+ return ttf;
+ }
+ catch (...)
+ {
+ return nullptr;
+ }
+ }
+
+ TTFData::TTFData(const unsigned char* d, unsigned int s)
+ {
+ raw.size = s;
+ raw.data = (unsigned char*)malloc(s);
+ memcpy(raw.data, d, s);
+ if (!stbtt_InitFont(&info, (const unsigned char*)raw.data, 0))
+ {
+ delete raw.data;
+ throw 0;
+ }
+ /* push default fontsize */
+ pushTTFsize(FONT_SIZE);
+ }
+
+ TTFData::~TTFData()
+ {
+ free(raw.data);
+ }
+
+ TTF* TTFData::createTTF(unsigned fontSize)
+ {
+ TTF* ttf;
+ try
+ {
+ ttf = new TTF(this, fontSize);
+ }
+ catch (...)
+ {
+ return nullptr;
+ }
+ return ttf;
+ }
+
+ /*
+ * (0, 0)
+ * +--------------+ ascent
+ * | +--------+ |
+ * | | | |
+ * | | bitmap | |
+ * +--|--------|--+ baseline
+ * | +--------+ |
+ * +--|-----------+ decent
+ * | |
+ * leftSideBearing |
+ * advanceWidth
+ */
+ void TTFData::getVMetrics(int* baseline, int* descent)
+ {
+ float scale = scales.back();
+ int ascent;
+ stbtt_GetFontVMetrics(&info, &ascent, descent, 0);
+ *baseline = (int)(ascent*scale) + 1; // slight adjustment
+ *descent = *baseline - (int)(*descent*scale) + 1;
+ }
+
+ void TTFData::getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing)
+ {
+ float scale = scales.back();
+ int adw, lsb;
+ stbtt_GetCodepointHMetrics(&info, codepoint, &adw, &lsb);
+ *advanceWidth = (int)(adw*scale);
+ *leftSideBearing = (int)(lsb*scale);
+ }
+
+ void TTFData::pushTTFsize(unsigned int fs)
+ {
+ float sc = stbtt_ScaleForPixelHeight(&info, fs);
+ scales.push_back(sc);
+ }
+
+ void TTFData::popTTFsize()
+ {
+ /* always keep default ttf size on the bottom of stack */
+ if (scales.size() > 1)
+ scales.pop_back();
+ }
+
+ Channel* TTFData::getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const
+ {
+ float scale = scales.back();
+ Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff);
+ return bitmap;
+ }
+
+ Color* TTFData::getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const
+ {
+ float scale = scales.back();
+ Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff);
+ int w = *width, h = *height;
+ //int xo = *xoff, yo = *yoff;
+ Color* bitmap32 = new Color[w*h];
+ for (int y = 0; y < h; ++y)
+ {
+ for (int x = 0; x < w; ++x)
+ {
+ bitmap32[x + y * w].set(0xff, 0xff, 0xff, bitmap[x + y * w]);
+ }
+ }
+ free(bitmap);
+ return bitmap32;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ // TTF
+ /////////////////////////////////////////////////////////////////////////////
+
+ #include "../Shaders/font.shader.h"
+
+ using namespace std;
+ using namespace jin::math;
+
+ const int TTF::TEXTURE_WIDTHS[] = { 128, 256, 256, 512, 512, 1024, 1024 };
+ const int TTF::TEXTURE_HEIGHTS[] = { 128, 128, 256, 256, 512, 512, 1024 };
+
+ /* little endian unicode */
+ static const char* unicodeLittleEndian(const char* p, unsigned* res)
+ {
+ }
+
+ ///*static*/ TTF* TTF::createTTF(TTFData* fontData, unsigned int fontSzie)
+ //{
+ // TTF* ttf;
+ // try
+ // {
+ // ttf = new TTF(fontData, fontSzie);
+ // }
+ // catch (...)
+ // {
+ // return nullptr;
+ // }
+ // return ttf;
+ //}
+
+ TTF::TTF(TTFData* f, unsigned int fontSize)
+ : Font(fontSize)
+ , cursor(0, 0)
+ , ttf(f)
+ {
+ ttf->pushTTFsize(fontSize);
+ ttf->getVMetrics(&baseline, &descent);
+ estimateSize();
+ ttf->popTTFsize();
+ /* create a default texture */
+ createAtlas();
+ }
+
+ /* estimate the size of atlas texture */
+ void TTF::estimateSize()
+ {
+ for (int level = 0; level <= TEXTURE_SIZE_LEVEL_MAX; ++level)
+ {
+ if (descent * (descent*0.8) * 96 <= TEXTURE_WIDTHS[level] * TEXTURE_HEIGHTS[level])
+ {
+ textureWidth = TEXTURE_WIDTHS[level];
+ textureHeight = TEXTURE_HEIGHTS[level];
+ break;
+ }
+ }
+ }
+
+ TTF::~TTF()
{
- ttf = new TTF(this, fontSize);
}
- catch (...)
+
+ GLuint TTF::createAtlas()
{
- return nullptr;
+ GLuint t;
+ gl.flushError();
+ t = gl.genTexture();
+ gl.bindTexture(t);
+ gl.setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl.setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl.setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl.setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl.texImage(GL_RGBA8, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE);
+ if (glGetError() != GL_NO_ERROR)
+ {
+ glDeleteTextures(1, &t);
+ gl.bindTexture(0);
+ return 0;
+ }
+ atlases.push_back(t);
+ gl.bindTexture(0);
+ return t;
}
- return ttf;
- }
-
- /*
- * (0, 0)
- * +--------------+ ascent
- * | +--------+ |
- * | | | |
- * | | bitmap | |
- * +--|--------|--+ baseline
- * | +--------+ |
- * +--|-----------+ decent
- * | |
- * leftSideBearing |
- * advanceWidth
- */
- void TTFData::getVMetrics(int* baseline, int* descent)
- {
- float scale = scales.back();
- int ascent;
- stbtt_GetFontVMetrics(&info, &ascent, descent, 0);
- *baseline = (int)(ascent*scale) + 1; // slight adjustment
- *descent = *baseline - (int)(*descent*scale) + 1;
- }
-
- void TTFData::getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing)
- {
- float scale = scales.back();
- int adw, lsb;
- stbtt_GetCodepointHMetrics(&info, codepoint, &adw, &lsb);
- *advanceWidth = (int)(adw*scale);
- *leftSideBearing = (int)(lsb*scale);
- }
-
- void TTFData::pushTTFsize(unsigned int fs)
- {
- float sc = stbtt_ScaleForPixelHeight(&info, fs);
- scales.push_back(sc);
- }
-
- void TTFData::popTTFsize()
- {
- /* always keep default ttf size on the bottom of stack */
- if (scales.size() > 1)
- scales.pop_back();
- }
-
- Channel* TTFData::getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const
- {
- float scale = scales.back();
- Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff);
- return bitmap;
- }
-
- Color* TTFData::getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const
- {
- float scale = scales.back();
- Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, xoff, yoff);
- int w = *width, h = *height;
- //int xo = *xoff, yo = *yoff;
- Color* bitmap32 = new Color[w*h];
- for (int y = 0; y < h; ++y)
- {
- for (int x = 0; x < w; ++x)
- {
- bitmap32[x + y * w].set(0xff, 0xff, 0xff, bitmap[x + y * w]);
- }
- }
- free(bitmap);
- return bitmap32;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // TTF
- /////////////////////////////////////////////////////////////////////////////
-
- #include "../Shaders/font.shader.h"
-
- using namespace std;
- using namespace jin::math;
-
- const int TTF::TEXTURE_WIDTHS[] = { 128, 256, 256, 512, 512, 1024, 1024 };
- const int TTF::TEXTURE_HEIGHTS[] = { 128, 128, 256, 256, 512, 512, 1024 };
-
- /* little endian unicode */
- static const char* unicodeLittleEndian(const char* p, unsigned* res)
- {
- }
-
- ///*static*/ TTF* TTF::createTTF(TTFData* fontData, unsigned int fontSzie)
- //{
- // TTF* ttf;
- // try
- // {
- // ttf = new TTF(fontData, fontSzie);
- // }
- // catch (...)
- // {
- // return nullptr;
- // }
- // return ttf;
- //}
-
- TTF::TTF(TTFData* f, unsigned int fontSize)
- : Font(fontSize)
- , cursor(0, 0)
- , ttf(f)
- {
- ttf->pushTTFsize(fontSize);
- ttf->getVMetrics(&baseline, &descent);
- estimateSize();
- ttf->popTTFsize();
- /* create a default texture */
- createAtlas();
- }
-
- /* estimate the size of atlas texture */
- void TTF::estimateSize()
- {
- for (int level = 0; level <= TEXTURE_SIZE_LEVEL_MAX; ++level)
- {
- if (descent * (descent*0.8) * 96 <= TEXTURE_WIDTHS[level] * TEXTURE_HEIGHTS[level])
- {
- textureWidth = TEXTURE_WIDTHS[level];
- textureHeight = TEXTURE_HEIGHTS[level];
- break;
- }
- }
- }
-
- TTF::~TTF()
- {
- }
-
- GLuint TTF::createAtlas()
- {
- GLuint t;
- gl.flushError();
- t = gl.genTexture();
- gl.bindTexture(t);
- gl.setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl.setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl.setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl.setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl.texImage(GL_RGBA8, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE);
- if (glGetError() != GL_NO_ERROR)
- {
- glDeleteTextures(1, &t);
- gl.bindTexture(0);
- return 0;
- }
- atlases.push_back(t);
- gl.bindTexture(0);
- return t;
- }
- void TTF::print(const Content& t, int x, int y, int lineheight, int spacing)
- {
- Page* page = typeset(t, lineheight, spacing);
- print(page, x, y);
- delete page;
- }
-
- Page* TTF::typeset(const Content& text, int lineheight, int spacing)
- {
- Page* page = new Page();
- page->font = this;
- vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
- vector<GlyphVertex>& glyphvertices = page->glyphvertices;
- int texture = -1;
- TTFGlyph* glyph = nullptr;
- GlyphVertex vertex;
- Vector2<int> p(0, 0);
- int i = 0;
-
-#define glyphvertices_push(_x, _y, _u, _v) \
- vertex.x = _x; vertex.y = _y;\
- vertex.u = _u; vertex.v = _v;\
- glyphvertices.push_back(vertex);
-
-#define glyphlize(c)\
- do{\
- glyph = &findGlyph(c); \
- if (texture != glyph->atlas) \
- { \
- GlyphArrayDrawInfo info; \
- info.start = i; \
- info.count = 0; \
- info.texture = glyph->atlas; \
- texture = glyph->atlas; \
- glyphinfolist.push_back(info); \
- } \
- glyphinfolist[glyphinfolist.size() - 1].count += 4; \
- TTFGlyph::Bbox& bbox = glyph->bbox; \
- glyphvertices_push(p.x, p.y, bbox.x, bbox.y); \
- glyphvertices_push(p.x, p.y + glyph->height, bbox.x, bbox.y + bbox.h); \
- glyphvertices_push(p.x + glyph->width, p.y + glyph->height, bbox.x + bbox.w, bbox.y + bbox.h); \
- glyphvertices_push(p.x + glyph->width, p.y, bbox.x + bbox.w, bbox.y); \
- }while(0)
-
- for (Codepoint c : text)
- {
- if (c == 0x0D)
- continue;
- if (c == 0x0A)
- {
- /* new line */
- p.y += lineheight;
- p.x = 0;
- continue;
- }
- glyphlize(c);
- p.x += glyph->width + spacing;
- i += 4;
- }
- getTextBox(text, &page->size.w, &page->size.h, lineheight, spacing);
- return page;
- }
-
- Page* TTF::typeset(const Text& text, int lineheight, int spacing)
- {
- return typeset(*text, lineheight, spacing);
- }
-
- void TTF::print(const Page* page, int x, int y)
- {
- Shader* shader = Shader::getCurrentShader();
- const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
- const vector<GlyphVertex>& glyphvertices = page->glyphvertices;
- gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0);
- shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
- shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
- for (int i = 0; i < glyphinfolist.size(); ++i)
- {
- const GlyphArrayDrawInfo& info = glyphinfolist[i];
- shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x);
- shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u);
- gl.bindTexture(info.texture);
- gl.drawArrays(GL_QUADS, 0, info.count);
- gl.bindTexture(0);
- }
- }
-
- void TTF::print(const Text& text, int x, int y, int lineheight, int spacing /* = 0 */)
- {
- print(*text, x, y, lineheight, spacing);
- }
-
- int TTF::getCharWidth(int c)
- {
- int adw, lsb;
- ttf->pushTTFsize(fontSize);
- ttf->getHMetrics(c, &adw, &lsb);
- ttf->popTTFsize();
- return adw;
- }
-
- int TTF::getCharHeight(int c)
- {
- return descent;
- }
-
- int TTF::getTextWidth(const Content& t, int spacing)
- {
- ttf->pushTTFsize(fontSize);
- int res = 0;
- int tmp = 0;
- for (Codepoint c : t)
- {
- if (c == 0x0D)
- continue;
- if (c == 0x0A)
- {
- tmp = 0;
- continue;
- }
- tmp += getCharWidth(c) + spacing;
- if (tmp > res)
- res = tmp;
- }
- ttf->popTTFsize();
- return res;
- }
-
- int TTF::getTextHeight(const Content& t, int lineheight)
- {
- ttf->pushTTFsize(fontSize);
- int res = 0;
- bool newline = true;
- for (Codepoint c : t)
- {
- if (c == 0x0A)
- newline = true;
- else if (c == 0x0D);
- else if (newline)
- {
- newline = false;
- res += lineheight;
- }
- }
- ttf->popTTFsize();
- return res;
- }
-
- void TTF::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing)
- {
- ttf->pushTTFsize(fontSize);
- *w = 0;
- *h = 0;
- int tmp = 0;
- bool newline = true;
- for (Codepoint c : text)
- {
- if (c == 0x0D)
- continue;
- if (c == 0x0A)
- {
- tmp = 0;
- newline = true;
- continue;
- }
- else if (newline)
- {
- newline = false;
- *h += lineheight;
- }
- tmp += getCharWidth(c) + spacing;
- if (tmp > *w)
- *w = tmp;
- }
- ttf->popTTFsize();
- }
-
- TTF::TTFGlyph& TTF::bakeGlyph(unsigned int character)
- {
- int w, h, xoff, yoff;
- ttf->pushTTFsize(fontSize);
- GLuint atlas = atlases.back();
- const Color* bitmap = ttf->getCodepointBitmap(character, &w, &h, &xoff, &yoff);
- int adw, lsb;
- {
- /* bake glyph */
- ttf->getHMetrics(character, &adw, &lsb);
- ttf->popTTFsize();
- if (cursor.x + adw > textureWidth )
- {
- cursor.x = 0;
- cursor.y += descent;
- if (cursor.y + descent * 2 > textureHeight)
- {
- /* create new atlas */
- atlas = createAtlas();
- cursor.y = 0;
- }
- }
- gl.bindTexture(atlas);
- gl.texSubImage(cursor.x + xoff, cursor.y + yoff + baseline, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
- gl.bindTexture();
- delete[] bitmap;
- }
- TTFGlyph glyph;
- glyph.atlas = atlas;
- glyph.bbox.x = cursor.x / (float)textureWidth;
- glyph.bbox.y = cursor.y / (float)textureHeight;
- glyph.bbox.w = adw / (float)textureWidth;
- glyph.bbox.h = descent / (float)textureHeight;
- glyph.width = adw;
- glyph.height = descent;
- glyphs.insert(std::pair<unsigned int, TTFGlyph>(character, glyph));
- cursor.x += adw;
- return glyphs[character];
- }
-
- TTF::TTFGlyph& TTF::findGlyph(unsigned int character)
- {
- map<unsigned int, TTFGlyph>::iterator it = glyphs.find(character);
- if (it != glyphs.end())
- return it->second;
- else
- return bakeGlyph(character);
- }
-
-} // graphics
+ void TTF::print(const Content& t, int x, int y, int lineheight, int spacing)
+ {
+ Page* page = typeset(t, lineheight, spacing);
+ print(page, x, y);
+ delete page;
+ }
+
+ Page* TTF::typeset(const Content& text, int lineheight, int spacing)
+ {
+ Page* page = new Page();
+ page->font = this;
+ vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
+ vector<GlyphVertex>& glyphvertices = page->glyphvertices;
+ int texture = -1;
+ TTFGlyph* glyph = nullptr;
+ GlyphVertex vertex;
+ Vector2<int> p(0, 0);
+ int i = 0;
+
+ #define glyphvertices_push(_x, _y, _u, _v) \
+ vertex.x = _x; vertex.y = _y;\
+ vertex.u = _u; vertex.v = _v;\
+ glyphvertices.push_back(vertex);
+
+ #define glyphlize(c)\
+ do{\
+ glyph = &findGlyph(c); \
+ if (texture != glyph->atlas) \
+ { \
+ GlyphArrayDrawInfo info; \
+ info.start = i; \
+ info.count = 0; \
+ info.texture = glyph->atlas; \
+ texture = glyph->atlas; \
+ glyphinfolist.push_back(info); \
+ } \
+ glyphinfolist[glyphinfolist.size() - 1].count += 4; \
+ TTFGlyph::Bbox& bbox = glyph->bbox; \
+ glyphvertices_push(p.x, p.y, bbox.x, bbox.y); \
+ glyphvertices_push(p.x, p.y + glyph->height, bbox.x, bbox.y + bbox.h); \
+ glyphvertices_push(p.x + glyph->width, p.y + glyph->height, bbox.x + bbox.w, bbox.y + bbox.h); \
+ glyphvertices_push(p.x + glyph->width, p.y, bbox.x + bbox.w, bbox.y); \
+ }while(0)
+
+ for (Codepoint c : text)
+ {
+ if (c == 0x0D)
+ continue;
+ if (c == 0x0A)
+ {
+ /* new line */
+ p.y += lineheight;
+ p.x = 0;
+ continue;
+ }
+ glyphlize(c);
+ p.x += glyph->width + spacing;
+ i += 4;
+ }
+ getTextBox(text, &page->size.w, &page->size.h, lineheight, spacing);
+ return page;
+ }
+
+ Page* TTF::typeset(const Text& text, int lineheight, int spacing)
+ {
+ return typeset(*text, lineheight, spacing);
+ }
+
+ void TTF::print(const Page* page, int x, int y)
+ {
+ Shader* shader = Shader::getCurrentShader();
+ const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
+ const vector<GlyphVertex>& glyphvertices = page->glyphvertices;
+ gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0);
+ shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
+ shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
+ for (int i = 0; i < glyphinfolist.size(); ++i)
+ {
+ const GlyphArrayDrawInfo& info = glyphinfolist[i];
+ shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x);
+ shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u);
+ gl.bindTexture(info.texture);
+ gl.drawArrays(GL_QUADS, 0, info.count);
+ gl.bindTexture(0);
+ }
+ }
+
+ void TTF::print(const Text& text, int x, int y, int lineheight, int spacing /* = 0 */)
+ {
+ print(*text, x, y, lineheight, spacing);
+ }
+
+ int TTF::getCharWidth(int c)
+ {
+ int adw, lsb;
+ ttf->pushTTFsize(fontSize);
+ ttf->getHMetrics(c, &adw, &lsb);
+ ttf->popTTFsize();
+ return adw;
+ }
+
+ int TTF::getCharHeight(int c)
+ {
+ return descent;
+ }
+
+ int TTF::getTextWidth(const Content& t, int spacing)
+ {
+ ttf->pushTTFsize(fontSize);
+ int res = 0;
+ int tmp = 0;
+ for (Codepoint c : t)
+ {
+ if (c == 0x0D)
+ continue;
+ if (c == 0x0A)
+ {
+ tmp = 0;
+ continue;
+ }
+ tmp += getCharWidth(c) + spacing;
+ if (tmp > res)
+ res = tmp;
+ }
+ ttf->popTTFsize();
+ return res;
+ }
+
+ int TTF::getTextHeight(const Content& t, int lineheight)
+ {
+ ttf->pushTTFsize(fontSize);
+ int res = 0;
+ bool newline = true;
+ for (Codepoint c : t)
+ {
+ if (c == 0x0A)
+ newline = true;
+ else if (c == 0x0D);
+ else if (newline)
+ {
+ newline = false;
+ res += lineheight;
+ }
+ }
+ ttf->popTTFsize();
+ return res;
+ }
+
+ void TTF::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing)
+ {
+ ttf->pushTTFsize(fontSize);
+ *w = 0;
+ *h = 0;
+ int tmp = 0;
+ bool newline = true;
+ for (Codepoint c : text)
+ {
+ if (c == 0x0D)
+ continue;
+ if (c == 0x0A)
+ {
+ tmp = 0;
+ newline = true;
+ continue;
+ }
+ else if (newline)
+ {
+ newline = false;
+ *h += lineheight;
+ }
+ tmp += getCharWidth(c) + spacing;
+ if (tmp > *w)
+ *w = tmp;
+ }
+ ttf->popTTFsize();
+ }
+
+ TTF::TTFGlyph& TTF::bakeGlyph(unsigned int character)
+ {
+ int w, h, xoff, yoff;
+ ttf->pushTTFsize(fontSize);
+ GLuint atlas = atlases.back();
+ const Color* bitmap = ttf->getCodepointBitmap(character, &w, &h, &xoff, &yoff);
+ int adw, lsb;
+ {
+ /* bake glyph */
+ ttf->getHMetrics(character, &adw, &lsb);
+ ttf->popTTFsize();
+ if (cursor.x + adw > textureWidth )
+ {
+ cursor.x = 0;
+ cursor.y += descent;
+ if (cursor.y + descent * 2 > textureHeight)
+ {
+ /* create new atlas */
+ atlas = createAtlas();
+ cursor.y = 0;
+ }
+ }
+ gl.bindTexture(atlas);
+ gl.texSubImage(cursor.x + xoff, cursor.y + yoff + baseline, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap);
+ gl.bindTexture();
+ delete[] bitmap;
+ }
+ TTFGlyph glyph;
+ glyph.atlas = atlas;
+ glyph.bbox.x = cursor.x / (float)textureWidth;
+ glyph.bbox.y = cursor.y / (float)textureHeight;
+ glyph.bbox.w = adw / (float)textureWidth;
+ glyph.bbox.h = descent / (float)textureHeight;
+ glyph.width = adw;
+ glyph.height = descent;
+ glyphs.insert(std::pair<unsigned int, TTFGlyph>(character, glyph));
+ cursor.x += adw;
+ return glyphs[character];
+ }
+
+ TTF::TTFGlyph& TTF::findGlyph(unsigned int character)
+ {
+ map<unsigned int, TTFGlyph>::iterator it = glyphs.find(character);
+ if (it != glyphs.end())
+ return it->second;
+ else
+ return bakeGlyph(character);
+ }
+
+ } // graphics
} // jin
#endif // LIBJIN_MODULES_RENDER \ No newline at end of file
diff --git a/src/libjin/Graphics/Font/TTF.h b/src/libjin/Graphics/Font/TTF.h
index 804cd9d..fc2eca3 100644
--- a/src/libjin/Graphics/Font/TTF.h
+++ b/src/libjin/Graphics/Font/TTF.h
@@ -17,115 +17,115 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- class TTF;
+ class TTF;
- /**
- * TTFData
- * |- TTF(14px)
- * |- TTF(15px)
- * .
- * .
- * .
- */
- class TTFData
- {
- public:
- static TTFData* createTTFData(const unsigned char* data, unsigned int size);
-
- ~TTFData();
-
- TTF* createTTF(unsigned ttfsize);
-
- void pushTTFsize(unsigned ttfsize);
- void popTTFsize();
-
- Channel* getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const;
- Color* getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const;
-
- void getVMetrics(int* baseline, int* descent);
- void getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing);
-
- private:
- static const unsigned int FONT_SIZE = 12;
-
- TTFData(const unsigned char* data, unsigned int size);
-
- stbtt_fontinfo info;
- struct
- {
- unsigned char* data;
- unsigned int size;
- } raw;
- std::vector<float> scales;
-
- };
-
- class TTF : public Font
- {
- public:
- //static TTF* createTTF(TTFData* ttfData, unsigned ttfSzie);
-
- Page* typeset(const Text& text, int lineheight, int spacing = 0) override;
- Page* typeset(const Content& text, int lineheight, int spacing = 0) override;
-
- void print(const Text& text, int x, int y, int lineheight, int spacing = 0) override;
- void print(const Content& text, int x, int y, int lineheight, int spacing = 0) override;
- void print(const Page* page, int x, int y) override;
-
- ~TTF();
-
- private:
- friend class TTFData;
-
- struct TTFGlyph
- {
- GLuint atlas;
- /* normalized coordinates */
- struct Bbox
- {
- float x, y;
- float w, h;
- } bbox;
- /* glyph size in pixel */
- unsigned int width, height;
- };
-
- static const int TEXTURE_SIZE_LEVELS_COUNT = 7;
- static const int TEXTURE_SIZE_LEVEL_MAX = TEXTURE_SIZE_LEVELS_COUNT - 1;
- static const int TEXTURE_WIDTHS[TEXTURE_SIZE_LEVELS_COUNT];
- static const int TEXTURE_HEIGHTS[TEXTURE_SIZE_LEVELS_COUNT];
-
- TTF(TTFData* ttf, Codepoint ttfSize);
-
- void estimateSize();
- GLuint createAtlas();
- TTFGlyph& bakeGlyph(Codepoint character);
- TTFGlyph& findGlyph(Codepoint character);
-
- int getCharWidth(int c);
- int getCharHeight(int c);
-
- int getTextWidth(const Content& text, int spacing = 0);
- int getTextHeight(const Content& text, int lineheight);
- void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0);
-
- int textureWidth;
- int textureHeight;
- std::vector<GLuint> atlases;
- std::map<Codepoint, TTFGlyph> glyphs;
- TTFData* ttf;
- int baseline;
- int descent;
-
- /* cursor helped render to texture */
- math::Vector2<float> cursor;
-
- };
-
-} // graphics
+ /**
+ * TTFData
+ * |- TTF(14px)
+ * |- TTF(15px)
+ * .
+ * .
+ * .
+ */
+ class TTFData
+ {
+ public:
+ static TTFData* createTTFData(const unsigned char* data, unsigned int size);
+
+ ~TTFData();
+
+ TTF* createTTF(unsigned ttfsize);
+
+ void pushTTFsize(unsigned ttfsize);
+ void popTTFsize();
+
+ Channel* getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const;
+ Color* getCodepointBitmap(unsigned int codepoint, int* width, int* height, int* xoff, int* yoff) const;
+
+ void getVMetrics(int* baseline, int* descent);
+ void getHMetrics(unsigned int codepoint, int* advanceWidth, int* leftSideBearing);
+
+ private:
+ static const unsigned int FONT_SIZE = 12;
+
+ TTFData(const unsigned char* data, unsigned int size);
+
+ stbtt_fontinfo info;
+ struct
+ {
+ unsigned char* data;
+ unsigned int size;
+ } raw;
+ std::vector<float> scales;
+
+ };
+
+ class TTF : public Font
+ {
+ public:
+ //static TTF* createTTF(TTFData* ttfData, unsigned ttfSzie);
+
+ Page* typeset(const Text& text, int lineheight, int spacing = 0) override;
+ Page* typeset(const Content& text, int lineheight, int spacing = 0) override;
+
+ void print(const Text& text, int x, int y, int lineheight, int spacing = 0) override;
+ void print(const Content& text, int x, int y, int lineheight, int spacing = 0) override;
+ void print(const Page* page, int x, int y) override;
+
+ ~TTF();
+
+ private:
+ friend class TTFData;
+
+ struct TTFGlyph
+ {
+ GLuint atlas;
+ /* normalized coordinates */
+ struct Bbox
+ {
+ float x, y;
+ float w, h;
+ } bbox;
+ /* glyph size in pixel */
+ unsigned int width, height;
+ };
+
+ static const int TEXTURE_SIZE_LEVELS_COUNT = 7;
+ static const int TEXTURE_SIZE_LEVEL_MAX = TEXTURE_SIZE_LEVELS_COUNT - 1;
+ static const int TEXTURE_WIDTHS[TEXTURE_SIZE_LEVELS_COUNT];
+ static const int TEXTURE_HEIGHTS[TEXTURE_SIZE_LEVELS_COUNT];
+
+ TTF(TTFData* ttf, Codepoint ttfSize);
+
+ void estimateSize();
+ GLuint createAtlas();
+ TTFGlyph& bakeGlyph(Codepoint character);
+ TTFGlyph& findGlyph(Codepoint character);
+
+ int getCharWidth(int c);
+ int getCharHeight(int c);
+
+ int getTextWidth(const Content& text, int spacing = 0);
+ int getTextHeight(const Content& text, int lineheight);
+ void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0);
+
+ int textureWidth;
+ int textureHeight;
+ std::vector<GLuint> atlases;
+ std::map<Codepoint, TTFGlyph> glyphs;
+ TTFData* ttf;
+ int baseline;
+ int descent;
+
+ /* cursor helped render to texture */
+ math::Vector2<float> cursor;
+
+ };
+
+ } // graphics
} // jin
#endif // LIBJIN_MODULES_RENDER
diff --git a/src/libjin/Graphics/Font/Text.cpp b/src/libjin/Graphics/Font/Text.cpp
index f202267..ac0242e 100644
--- a/src/libjin/Graphics/Font/Text.cpp
+++ b/src/libjin/Graphics/Font/Text.cpp
@@ -5,152 +5,152 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- /////////////////////////////////////////////////////////////////////////////
- // iterator
- /////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////
+ // iterator
+ /////////////////////////////////////////////////////////////////////////////
- Text::Iterator::Iterator(const Iterator& itor)
- : data(itor.data)
- , p(itor.p)
- , encode(itor.encode)
- , length(itor.length)
- {
- switch (encode)
+ Text::Iterator::Iterator(const Iterator& itor)
+ : data(itor.data)
+ , p(itor.p)
+ , encode(itor.encode)
+ , length(itor.length)
{
- case Encode::UTF8: decoder = new Utf8(); break;
- //case Encode::UTF16: decoder = new Utf16(); break;
- case Encode::ASCII: decoder = new Ascii(); break;
+ switch (encode)
+ {
+ case Encode::UTF8: decoder = new Utf8(); break;
+ //case Encode::UTF16: decoder = new Utf16(); break;
+ case Encode::ASCII: decoder = new Ascii(); break;
+ }
}
- }
- Text::Iterator::Iterator(const Encode& _encode, const void* _data, unsigned int _length)
- : data(_data)
- , p(_data)
- , encode(_encode)
- , length(_length)
- {
- switch (encode)
+ Text::Iterator::Iterator(const Encode& _encode, const void* _data, unsigned int _length)
+ : data(_data)
+ , p(_data)
+ , encode(_encode)
+ , length(_length)
{
- case Encode::UTF8: decoder = new Utf8(); break;
- //case Encode::UTF16: decoder = new Utf16(); break;
- case Encode::ASCII: decoder = new Ascii(); break;
+ switch (encode)
+ {
+ case Encode::UTF8: decoder = new Utf8(); break;
+ //case Encode::UTF16: decoder = new Utf16(); break;
+ case Encode::ASCII: decoder = new Ascii(); break;
+ }
}
- }
- Text::Iterator::~Iterator()
- {
- delete decoder;
- }
+ Text::Iterator::~Iterator()
+ {
+ delete decoder;
+ }
- Codepoint Text::Iterator::get()
- {
- Codepoint codepoint;
- decoder->decode(p, &codepoint);
- return codepoint;
- }
+ Codepoint Text::Iterator::get()
+ {
+ Codepoint codepoint;
+ decoder->decode(p, &codepoint);
+ return codepoint;
+ }
- Codepoint Text::Iterator::operator*()
- {
- return get();
- }
-/*
- Text::Iterator Text::Iterator::begin()
- {
- Iterator itor(encode, data, length);
- itor.toBegin();
- return itor;
- }
+ Codepoint Text::Iterator::operator*()
+ {
+ return get();
+ }
+ /*
+ Text::Iterator Text::Iterator::begin()
+ {
+ Iterator itor(encode, data, length);
+ itor.toBegin();
+ return itor;
+ }
- Text::Iterator Text::Iterator::end()
- {
- Iterator itor(encode, data, length);
- itor.toEnd();
- return itor;
- }
-*/
- void Text::Iterator::toBegin()
- {
- p = (const unsigned char*)data;
- }
+ Text::Iterator Text::Iterator::end()
+ {
+ Iterator itor(encode, data, length);
+ itor.toEnd();
+ return itor;
+ }
+ */
+ void Text::Iterator::toBegin()
+ {
+ p = (const unsigned char*)data;
+ }
- void Text::Iterator::toEnd()
- {
- p = (const unsigned char*)data + length;
- }
+ void Text::Iterator::toEnd()
+ {
+ p = (const unsigned char*)data + length;
+ }
- Text::Iterator& Text::Iterator::operator ++()
- {
- p = decoder->next(p);
- return *this;
- }
+ Text::Iterator& Text::Iterator::operator ++()
+ {
+ p = decoder->next(p);
+ return *this;
+ }
- Text::Iterator Text::Iterator::operator ++(int)
- {
- p = decoder->next(p);
- Iterator itor(encode, data, length);
- itor.p = p;
- return itor;
- }
+ Text::Iterator Text::Iterator::operator ++(int)
+ {
+ p = decoder->next(p);
+ Iterator itor(encode, data, length);
+ itor.p = p;
+ return itor;
+ }
- bool Text::Iterator::operator !=(const Iterator& itor)
- {
- return !(data == itor.data
- && p == itor.p
- && length == itor.length
- && encode == itor.encode);
- }
+ bool Text::Iterator::operator !=(const Iterator& itor)
+ {
+ return !(data == itor.data
+ && p == itor.p
+ && length == itor.length
+ && encode == itor.encode);
+ }
- bool Text::Iterator::operator ==(const Iterator& itor)
- {
- return data == itor.data
- && p == itor.p
- && length == itor.length
- && encode == itor.encode;
- }
+ bool Text::Iterator::operator ==(const Iterator& itor)
+ {
+ return data == itor.data
+ && p == itor.p
+ && length == itor.length
+ && encode == itor.encode;
+ }
- /////////////////////////////////////////////////////////////////////////////
- // text
- /////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////
+ // text
+ /////////////////////////////////////////////////////////////////////////////
- Text::Text(Encode encode, const void* data)
- {
- unsigned length = strlen((const char*)data);
- Iterator end = Iterator(encode, data, length);
- end.toEnd();
- Iterator it = Iterator(encode, data, length);
- for (; it != end; ++it)
+ Text::Text(Encode encode, const void* data)
{
- content.push_back(*it);
+ unsigned length = strlen((const char*)data);
+ Iterator end = Iterator(encode, data, length);
+ end.toEnd();
+ Iterator it = Iterator(encode, data, length);
+ for (; it != end; ++it)
+ {
+ content.push_back(*it);
+ }
}
- }
- Text::Text(Encode encode, const void* data, unsigned length)
- {
- Iterator end = Iterator(encode, data, length);
- end.toEnd();
- Iterator it = Iterator(encode, data, length);
- for (; it != end; ++it)
+ Text::Text(Encode encode, const void* data, unsigned length)
{
- content.push_back(*it);
+ Iterator end = Iterator(encode, data, length);
+ end.toEnd();
+ Iterator it = Iterator(encode, data, length);
+ for (; it != end; ++it)
+ {
+ content.push_back(*it);
+ }
}
- }
- Text::~Text()
- {
- }
+ Text::~Text()
+ {
+ }
- const Content& Text::getContent() const
- {
- return content;
- }
+ const Content& Text::getContent() const
+ {
+ return content;
+ }
- const Content& Text::operator*() const
- {
- return content;
- }
+ const Content& Text::operator*() const
+ {
+ return content;
+ }
-} // graphics
+ } // graphics
} // jin \ No newline at end of file
diff --git a/src/libjin/Graphics/Font/Text.h b/src/libjin/Graphics/Font/Text.h
index 9fe152d..a4cbcbf 100644
--- a/src/libjin/Graphics/Font/Text.h
+++ b/src/libjin/Graphics/Font/Text.h
@@ -5,70 +5,70 @@
namespace jin
{
-namespace graphics
-{
-
- typedef unsigned int Codepoint;
-
- typedef std::vector<Codepoint> Content;
+ namespace graphics
+ {
- class Text;
- class Decoder;
+ typedef unsigned int Codepoint;
- enum Encode
- {
- UTF8, // utf-8
- //UTF16, // utf-16
- ASCII, // ASCII
- };
+ typedef std::vector<Codepoint> Content;
- /* raw encoded text */
- class Text
- {
- public:
- Text(Encode encode, const void* data);
- Text(Encode encode, const void* data, unsigned int length);
- ~Text();
+ class Text;
+ class Decoder;
- const Content& getContent() const;
- const Content& operator*() const;
+ enum Encode
+ {
+ UTF8, // utf-8
+ //UTF16, // utf-16
+ ASCII, // ASCII
+ };
- private:
- class Iterator
+ /* raw encoded text */
+ class Text
{
public:
- Iterator(const Iterator& itor);
- Iterator(const Encode& encode, const void* data, unsigned int length);
- ~Iterator();
-
- Codepoint get();
- //Iterator begin();
- //Iterator end();
- void toBegin();
- void toEnd();
- Codepoint operator *();
- /* prefix ++ */
- Iterator& operator ++();
- /* postfix ++ */
- Iterator operator ++(int);
- bool operator !=(const Iterator& itor);
- bool operator ==(const Iterator& itor);
+ Text(Encode encode, const void* data);
+ Text(Encode encode, const void* data, unsigned int length);
+ ~Text();
+
+ const Content& getContent() const;
+ const Content& operator*() const;
private:
- void operator = (const Iterator&);
+ class Iterator
+ {
+ public:
+ Iterator(const Iterator& itor);
+ Iterator(const Encode& encode, const void* data, unsigned int length);
+ ~Iterator();
+
+ Codepoint get();
+ //Iterator begin();
+ //Iterator end();
+ void toBegin();
+ void toEnd();
+ Codepoint operator *();
+ /* prefix ++ */
+ Iterator& operator ++();
+ /* postfix ++ */
+ Iterator operator ++(int);
+ bool operator !=(const Iterator& itor);
+ bool operator ==(const Iterator& itor);
+
+ private:
+ void operator = (const Iterator&);
+
+ const Encode encode;
+ const Decoder* decoder;
+ const void* p;
+ const void* const data;
+ unsigned int length;
+ };
+
+ Content content;
- const Encode encode;
- const Decoder* decoder;
- const void* p;
- const void* const data;
- unsigned int length;
};
- Content content;
-
- };
-
-} // graphics
+ } // graphics
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/Graphics/Font/TextureFont.cpp b/src/libjin/Graphics/Font/TextureFont.cpp
index a1f2b27..8c9c4ac 100644
--- a/src/libjin/Graphics/Font/TextureFont.cpp
+++ b/src/libjin/Graphics/Font/TextureFont.cpp
@@ -6,295 +6,295 @@
namespace jin
{
-namespace graphics
-{
-
- using namespace std;
- using namespace math;
-
- TextureFont * TextureFont::createTextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh)
- {
- TextureFont* tf = new TextureFont(bitmap, codepoints, cellw, cellh);
- return tf;
- }
-
- TextureFont * TextureFont::createTextureFont(const Bitmap* bitmap, const Text& codepoints, int cellw, int cellh)
+ namespace graphics
{
- TextureFont* tf = new TextureFont(bitmap, *codepoints, cellw, cellh);
- return tf;
- }
- TextureFont* TextureFont::createTextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh)
- {
- TextureFont* tf = new TextureFont(bitmap, codepoints, mask, cellh);
- return tf;
- }
+ using namespace std;
+ using namespace math;
- TextureFont* TextureFont::createTextureFont(const Bitmap* bitmap, const Text& codepoints, Color mask, int cellh)
- {
- TextureFont* tf = new TextureFont(bitmap, *codepoints, mask, cellh);
- return tf;
- }
+ TextureFont * TextureFont::createTextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh)
+ {
+ TextureFont* tf = new TextureFont(bitmap, codepoints, cellw, cellh);
+ return tf;
+ }
- TextureFont::~TextureFont()
- {
- }
+ TextureFont * TextureFont::createTextureFont(const Bitmap* bitmap, const Text& codepoints, int cellw, int cellh)
+ {
+ TextureFont* tf = new TextureFont(bitmap, *codepoints, cellw, cellh);
+ return tf;
+ }
- const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const
- {
- auto it = glyphs.find(codepoint);
- if (it != glyphs.end())
+ TextureFont* TextureFont::createTextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh)
{
- return &it->second;
+ TextureFont* tf = new TextureFont(bitmap, codepoints, mask, cellh);
+ return tf;
}
- else
- return nullptr;
- }
- Page* TextureFont::typeset(const Content& text, int lineheight, int spacing)
- {
- Page* page = new Page();
- page->font = this;
- vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
- vector<GlyphVertex>& glyphvertices = page->glyphvertices;
- int texture = -1;
- const TextureGlyph* glyph = nullptr;
- GlyphVertex vertex;
- Vector2<int> p(0, 0);
- int i = 0;
+ TextureFont* TextureFont::createTextureFont(const Bitmap* bitmap, const Text& codepoints, Color mask, int cellh)
+ {
+ TextureFont* tf = new TextureFont(bitmap, *codepoints, mask, cellh);
+ return tf;
+ }
-#define glyphvertices_push(_x, _y, _u, _v) \
- vertex.x = _x; vertex.y = _y;\
- vertex.u = _u; vertex.v = _v;\
- glyphvertices.push_back(vertex);\
+ TextureFont::~TextureFont()
+ {
+ }
- for (Codepoint c : text)
+ const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const
{
- if (c == 0x0D) continue;
- if (c == 0x0A)
+ auto it = glyphs.find(codepoint);
+ if (it != glyphs.end())
{
- /* new line */
- p.y += lineheight;
- p.x = 0;
- continue;
+ return &it->second;
}
- glyph = findGlyph(c);
- if (glyph == nullptr) continue;
- if (texture != this->texture)
- {
- texture = this->texture;
- GlyphArrayDrawInfo info;
- info.start = i;
- info.count = 0;
- info.texture = texture;
- glyphinfolist.push_back(info);
- }
- glyphinfolist[glyphinfolist.size() - 1].count += 4;
- // normalized
- float nx = glyph->x / (float)size.w, ny = glyph->y / (float)size.h;
- float nw = glyph->w / (float)size.w, nh = glyph->h / (float)size.h;
- glyphvertices_push(p.x, p.y, nx, ny);
- glyphvertices_push(p.x, p.y + glyph->h, nx, ny + nh);
- glyphvertices_push(p.x + glyph->w, p.y + glyph->h, nx + nw, ny + nh);
- glyphvertices_push(p.x + glyph->w, p.y, nx + nw, ny);
- p.x += glyph->w + spacing;
- i += 4;
+ else
+ return nullptr;
}
- getTextBox(text, &page->size.w, &page->size.h, lineheight, spacing);
- return page;
- }
- int TextureFont::getCharWidth(int c)
- {
- auto it = glyphs.find(c);
- if (it != glyphs.end())
+ Page* TextureFont::typeset(const Content& text, int lineheight, int spacing)
{
- return it->second.w;
+ Page* page = new Page();
+ page->font = this;
+ vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
+ vector<GlyphVertex>& glyphvertices = page->glyphvertices;
+ int texture = -1;
+ const TextureGlyph* glyph = nullptr;
+ GlyphVertex vertex;
+ Vector2<int> p(0, 0);
+ int i = 0;
+
+ #define glyphvertices_push(_x, _y, _u, _v) \
+ vertex.x = _x; vertex.y = _y;\
+ vertex.u = _u; vertex.v = _v;\
+ glyphvertices.push_back(vertex);\
+
+ for (Codepoint c : text)
+ {
+ if (c == 0x0D) continue;
+ if (c == 0x0A)
+ {
+ /* new line */
+ p.y += lineheight;
+ p.x = 0;
+ continue;
+ }
+ glyph = findGlyph(c);
+ if (glyph == nullptr) continue;
+ if (texture != this->texture)
+ {
+ texture = this->texture;
+ GlyphArrayDrawInfo info;
+ info.start = i;
+ info.count = 0;
+ info.texture = texture;
+ glyphinfolist.push_back(info);
+ }
+ glyphinfolist[glyphinfolist.size() - 1].count += 4;
+ // normalized
+ float nx = glyph->x / (float)size.w, ny = glyph->y / (float)size.h;
+ float nw = glyph->w / (float)size.w, nh = glyph->h / (float)size.h;
+ glyphvertices_push(p.x, p.y, nx, ny);
+ glyphvertices_push(p.x, p.y + glyph->h, nx, ny + nh);
+ glyphvertices_push(p.x + glyph->w, p.y + glyph->h, nx + nw, ny + nh);
+ glyphvertices_push(p.x + glyph->w, p.y, nx + nw, ny);
+ p.x += glyph->w + spacing;
+ i += 4;
+ }
+ getTextBox(text, &page->size.w, &page->size.h, lineheight, spacing);
+ return page;
}
- return 0;
- }
- int TextureFont::getCharHeight(int c)
- {
- auto it = glyphs.find(c);
- if (it != glyphs.end())
+ int TextureFont::getCharWidth(int c)
{
- return it->second.h;
+ auto it = glyphs.find(c);
+ if (it != glyphs.end())
+ {
+ return it->second.w;
+ }
+ return 0;
}
- return 0;
- }
- int TextureFont::getTextWidth(const Content& t, int spacing)
- {
- int res = 0;
- int tmp = 0;
- for (Codepoint c : t)
+ int TextureFont::getCharHeight(int c)
{
- if (c == 0x0D)
- continue;
- if (c == 0x0A)
+ auto it = glyphs.find(c);
+ if (it != glyphs.end())
{
- tmp = 0;
- continue;
+ return it->second.h;
}
- tmp += getCharWidth(c) + spacing;
- if (tmp > res)
- res = tmp;
+ return 0;
}
- return res;
- }
- int TextureFont::getTextHeight(const Content& t, int lineheight)
- {
- int res = 0;
- bool newline = true;
- for (Codepoint c : t)
+ int TextureFont::getTextWidth(const Content& t, int spacing)
{
- if (c == 0x0A)
- newline = true;
- else if (c == 0x0D);
- else if (newline)
+ int res = 0;
+ int tmp = 0;
+ for (Codepoint c : t)
{
- newline = false;
- res += lineheight;
+ if (c == 0x0D)
+ continue;
+ if (c == 0x0A)
+ {
+ tmp = 0;
+ continue;
+ }
+ tmp += getCharWidth(c) + spacing;
+ if (tmp > res)
+ res = tmp;
}
+ return res;
}
- return res;
- }
- void TextureFont::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing)
- {
- *w = 0;
- *h = 0;
- int tmp = 0;
- bool newline = true;
- for (Codepoint c : text)
+ int TextureFont::getTextHeight(const Content& t, int lineheight)
{
- if (c == 0x0D)
- continue;
- if (c == 0x0A)
+ int res = 0;
+ bool newline = true;
+ for (Codepoint c : t)
{
- tmp = 0;
- newline = true;
- continue;
+ if (c == 0x0A)
+ newline = true;
+ else if (c == 0x0D);
+ else if (newline)
+ {
+ newline = false;
+ res += lineheight;
+ }
}
- else if (newline)
+ return res;
+ }
+
+ void TextureFont::getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing)
+ {
+ *w = 0;
+ *h = 0;
+ int tmp = 0;
+ bool newline = true;
+ for (Codepoint c : text)
{
- newline = false;
- *h += lineheight;
+ if (c == 0x0D)
+ continue;
+ if (c == 0x0A)
+ {
+ tmp = 0;
+ newline = true;
+ continue;
+ }
+ else if (newline)
+ {
+ newline = false;
+ *h += lineheight;
+ }
+ tmp += getCharWidth(c) + spacing;
+ if (tmp > *w)
+ *w = tmp;
}
- tmp += getCharWidth(c) + spacing;
- if (tmp > *w)
- *w = tmp;
}
- }
-
- Page* TextureFont::typeset(const Text& text, int lineheight, int spacing)
- {
- return typeset(*text, lineheight, spacing);
- }
- void TextureFont::print(const Page* page, int x, int y)
- {
- Shader* shader = Shader::getCurrentShader();
- const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
- const vector<GlyphVertex>& glyphvertices = page->glyphvertices;
- gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0);
- shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
- shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
- for (int i = 0; i < glyphinfolist.size(); ++i)
+ Page* TextureFont::typeset(const Text& text, int lineheight, int spacing)
{
- const GlyphArrayDrawInfo& info = glyphinfolist[i];
- shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x);
- shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u);
- gl.bindTexture(info.texture);
- gl.drawArrays(GL_QUADS, 0, info.count);
- gl.bindTexture(0);
+ return typeset(*text, lineheight, spacing);
}
- }
-
- void TextureFont::print(const Content& text, int x, int y, int lineheight, int spacing)
- {
- Page* page = typeset(text, lineheight, spacing);
- print(page, x, y);
- delete page;
- }
-
- void TextureFont::print(const Text& text, int x, int y, int lineheight, int spacing)
- {
- Page* page = typeset(text, lineheight, spacing);
- print(page, x, y);
- delete page;
- }
- TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh)
- : Drawable(bitmap)
- , Font(cellh)
- {
- TextureGlyph glyph;
- Vector2<int> count(bitmap->getWidth() / cellw, bitmap->getHeight() / cellh);
- glyph.w = cellw;
- glyph.h = cellh;
- for (int y = 0; y < count.row; ++y)
+ void TextureFont::print(const Page* page, int x, int y)
{
- glyph.y = y * cellh;
- for (int x = 0; x < count.colum; ++x)
+ Shader* shader = Shader::getCurrentShader();
+ const vector<GlyphArrayDrawInfo>& glyphinfolist = page->glyphinfolist;
+ const vector<GlyphVertex>& glyphvertices = page->glyphvertices;
+ gl.ModelMatrix.setTransformation(x, y, 0, 1, 1, 0, 0);
+ shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
+ shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
+ for (int i = 0; i < glyphinfolist.size(); ++i)
{
- glyph.x = x * cellw;
- if (x + y * count.colum >= codepoints.size())
- return;
- glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[x + y * count.colum], glyph));
+ const GlyphArrayDrawInfo& info = glyphinfolist[i];
+ shader->bindVertexPointer(2, GL_INT, sizeof(GlyphVertex), &glyphvertices[info.start].x);
+ shader->bindUVPointer(2, GL_FLOAT, sizeof(GlyphVertex), &glyphvertices[info.start].u);
+ gl.bindTexture(info.texture);
+ gl.drawArrays(GL_QUADS, 0, info.count);
+ gl.bindTexture(0);
}
}
- }
- TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh)
- : Drawable(bitmap)
- , Font(cellh)
- {
- TextureGlyph glyph;
- glyph.h = cellh;
- int w = bitmap->getWidth();
- int h = bitmap->getHeight();
- int i = 0;
- for (int y = 0; y < h; y += cellh)
+ void TextureFont::print(const Content& text, int x, int y, int lineheight, int spacing)
{
- glyph.y = y;
- bool newc = false;
- for (int x = 0; x <= w; ++x)
+ Page* page = typeset(text, lineheight, spacing);
+ print(page, x, y);
+ delete page;
+ }
+
+ void TextureFont::print(const Text& text, int x, int y, int lineheight, int spacing)
+ {
+ Page* page = typeset(text, lineheight, spacing);
+ print(page, x, y);
+ delete page;
+ }
+
+ TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh)
+ : Drawable(bitmap)
+ , Font(cellh)
+ {
+ TextureGlyph glyph;
+ Vector2<int> count(bitmap->getWidth() / cellw, bitmap->getHeight() / cellh);
+ glyph.w = cellw;
+ glyph.h = cellh;
+ for (int y = 0; y < count.row; ++y)
{
- if (x == w && newc)
+ glyph.y = y * cellh;
+ for (int x = 0; x < count.colum; ++x)
{
- glyph.w = x - glyph.x;
- if (i >= codepoints.size())
+ glyph.x = x * cellw;
+ if (x + y * count.colum >= codepoints.size())
return;
- glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph));
- ++i;
- newc = false;
- break;
- }
- Color c = bitmap->getPixels()[x + y * w];
- if (!newc && c != mask)
- {
- glyph.x = x;
- newc = true;
+ glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[x + y * count.colum], glyph));
}
- else if (newc && c == mask)
+ }
+ }
+
+ TextureFont::TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh)
+ : Drawable(bitmap)
+ , Font(cellh)
+ {
+ TextureGlyph glyph;
+ glyph.h = cellh;
+ int w = bitmap->getWidth();
+ int h = bitmap->getHeight();
+ int i = 0;
+ for (int y = 0; y < h; y += cellh)
+ {
+ glyph.y = y;
+ bool newc = false;
+ for (int x = 0; x <= w; ++x)
{
- glyph.w = x - glyph.x;
- if (i >= codepoints.size())
- return;
- glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph));
- if (codepoints[i] == 't')
+ if (x == w && newc)
{
- int a = 10;
+ glyph.w = x - glyph.x;
+ if (i >= codepoints.size())
+ return;
+ glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph));
+ ++i;
+ newc = false;
+ break;
+ }
+ Color c = bitmap->getPixels()[x + y * w];
+ if (!newc && c != mask)
+ {
+ glyph.x = x;
+ newc = true;
+ }
+ else if (newc && c == mask)
+ {
+ glyph.w = x - glyph.x;
+ if (i >= codepoints.size())
+ return;
+ glyphs.insert(std::pair<Codepoint, TextureGlyph>(codepoints[i], glyph));
+ if (codepoints[i] == 't')
+ {
+ int a = 10;
+ }
+ ++i;
+ newc = false;
}
- ++i;
- newc = false;
}
}
}
- }
-}
+ }
} \ No newline at end of file
diff --git a/src/libjin/Graphics/Font/TextureFont.h b/src/libjin/Graphics/Font/TextureFont.h
index 0d0d091..a1d1a37 100644
--- a/src/libjin/Graphics/Font/TextureFont.h
+++ b/src/libjin/Graphics/Font/TextureFont.h
@@ -14,49 +14,49 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- /* Texture font */
- class TextureFont : public Font
- , public Drawable
- {
- public:
- static TextureFont* createTextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh);
- static TextureFont* createTextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh);
- static TextureFont* createTextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh);
- static TextureFont* createTextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh);
+ /* Texture font */
+ class TextureFont : public Font
+ , public Drawable
+ {
+ public:
+ static TextureFont* createTextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh);
+ static TextureFont* createTextureFont(const Bitmap* bitmap, const Text& text, int cellw, int cellh);
+ static TextureFont* createTextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh);
+ static TextureFont* createTextureFont(const Bitmap* bitmap, const Text& text, Color mask, int cellh);
- ~TextureFont();
+ ~TextureFont();
- Page* typeset(const Text& text, int lineheight, int spacing = 0) override;
- Page* typeset(const Content& text, int lineheight, int spacing = 0) override ;
+ Page* typeset(const Text& text, int lineheight, int spacing = 0) override;
+ Page* typeset(const Content& text, int lineheight, int spacing = 0) override ;
- void print(const Page* page, int x, int y) override;
- void print(const Content& text, int x, int y, int linehgiht, int spacing = 0) override;
- void print(const Text& text, int x, int y, int lineheight, int spacing = 0)override;
+ void print(const Page* page, int x, int y) override;
+ void print(const Content& text, int x, int y, int linehgiht, int spacing = 0) override;
+ void print(const Text& text, int x, int y, int lineheight, int spacing = 0)override;
- private:
- struct TextureGlyph
- {
- float x, y, w, h;
- };
+ private:
+ struct TextureGlyph
+ {
+ float x, y, w, h;
+ };
- TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh);
- TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh);
+ TextureFont(const Bitmap* bitmap, const Content& codepoints, int cellw, int cellh);
+ TextureFont(const Bitmap* bitmap, const Content& codepoints, Color mask, int cellh);
- int getCharWidth(int c);
- int getCharHeight(int c);
- int getTextWidth(const Content& text, int spacing = 0);
- int getTextHeight(const Content& text, int lineheight);
- void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0);
- const TextureGlyph* findGlyph(Codepoint codepoint) const;
+ int getCharWidth(int c);
+ int getCharHeight(int c);
+ int getTextWidth(const Content& text, int spacing = 0);
+ int getTextHeight(const Content& text, int lineheight);
+ void getTextBox(const Content& text, int* w, int* h, int lineheight, int spacing = 0);
+ const TextureGlyph* findGlyph(Codepoint codepoint) const;
- std::map<Codepoint, TextureGlyph> glyphs;
+ std::map<Codepoint, TextureGlyph> glyphs;
- };
+ };
-}
+ }
}
#endif \ No newline at end of file
diff --git a/src/libjin/Graphics/Mesh.cpp b/src/libjin/Graphics/Mesh.cpp
index 503a189..3142894 100644
--- a/src/libjin/Graphics/Mesh.cpp
+++ b/src/libjin/Graphics/Mesh.cpp
@@ -2,10 +2,10 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
-}
+ }
} \ No newline at end of file
diff --git a/src/libjin/Graphics/Mesh.h b/src/libjin/Graphics/Mesh.h
index c14af89..66727e4 100644
--- a/src/libjin/Graphics/Mesh.h
+++ b/src/libjin/Graphics/Mesh.h
@@ -3,19 +3,19 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- class Mesh
- {
- public:
+ class Mesh
+ {
+ public:
- private:
+ private:
- };
+ };
-}
+ }
}
#endif \ No newline at end of file
diff --git a/src/libjin/Graphics/OpenGL.cpp b/src/libjin/Graphics/OpenGL.cpp
index f7bed9f..6bc176e 100644
--- a/src/libjin/Graphics/OpenGL.cpp
+++ b/src/libjin/Graphics/OpenGL.cpp
@@ -3,10 +3,10 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- OpenGL gl;
+ OpenGL gl;
-}
+ }
}
diff --git a/src/libjin/Graphics/OpenGL.h b/src/libjin/Graphics/OpenGL.h
index 51395ba..47011a2 100644
--- a/src/libjin/Graphics/OpenGL.h
+++ b/src/libjin/Graphics/OpenGL.h
@@ -6,24 +6,24 @@
namespace jin
{
-namespace graphics
-{
-
- class OpenGL : public ogl2d::OpenGL
+ namespace graphics
{
- public:
- math::Matrix ProjectionMatrix;
- math::Matrix ModelMatrix;
- OpenGL() : ogl2d::OpenGL()
+ class OpenGL : public ogl2d::OpenGL
{
- }
+ public:
+ math::Matrix ProjectionMatrix;
+ math::Matrix ModelMatrix;
- };
+ OpenGL() : ogl2d::OpenGL()
+ {
+ }
- extern OpenGL gl;
+ };
-}
+ extern OpenGL gl;
+
+ }
}
#endif \ No newline at end of file
diff --git a/src/libjin/Graphics/Shader.cpp b/src/libjin/Graphics/Shader.cpp
index 688fa51..8788900 100644
--- a/src/libjin/Graphics/Shader.cpp
+++ b/src/libjin/Graphics/Shader.cpp
@@ -9,274 +9,274 @@
#include "../Filesystem/Buffer.h"
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- using namespace jin::filesystem;
- using namespace std;
+ using namespace jin::filesystem;
+ using namespace std;
- /**
- * default_texture
- * base_shader
- * SHADER_FORMAT_SIZE
- * formatShader
- */
- #include "Shaders/default.shader.h"
+ /**
+ * default_texture
+ * base_shader
+ * SHADER_FORMAT_SIZE
+ * formatShader
+ */
+ #include "Shaders/default.shader.h"
- /**
- * https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value
- * The default value of a sampler variable is 0. From the GLSL 3.30 spec,
- * section "4.3.5 Uniforms":
- *
- * The link time initial value is either the value of the variable's
- * initializer, if present, or 0 if no initializer is present.Sampler
- * types cannot have initializers.
- *
- * Since a value of 0 means that it's sampling from texture unit 0, it will
- * work without ever setting the value as long as you bind your textures to
- * unit 0. This is well defined behavior.
- *
- * Since texture unit 0 is also the default until you call glActiveTexture()
- * with a value other than GL_TEXTURE0, it's very common to always use unit
- * 0 as long as shaders do not need more than one texture.Which means that
- * often times, setting the sampler uniforms is redundant for simple
- * applications.
- *
- * I would still prefer to always set the values.If nothing else, it makes
- * it clear to anybody reading your code that you really mean to sample from
- * texture unit 0, and did not just forget to set the value.
- */
- const int DEFAULT_TEXTURE_UNIT = 0;
+ /**
+ * https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value
+ * The default value of a sampler variable is 0. From the GLSL 3.30 spec,
+ * section "4.3.5 Uniforms":
+ *
+ * The link time initial value is either the value of the variable's
+ * initializer, if present, or 0 if no initializer is present.Sampler
+ * types cannot have initializers.
+ *
+ * Since a value of 0 means that it's sampling from texture unit 0, it will
+ * work without ever setting the value as long as you bind your textures to
+ * unit 0. This is well defined behavior.
+ *
+ * Since texture unit 0 is also the default until you call glActiveTexture()
+ * with a value other than GL_TEXTURE0, it's very common to always use unit
+ * 0 as long as shaders do not need more than one texture.Which means that
+ * often times, setting the sampler uniforms is redundant for simple
+ * applications.
+ *
+ * I would still prefer to always set the values.If nothing else, it makes
+ * it clear to anybody reading your code that you really mean to sample from
+ * texture unit 0, and did not just forget to set the value.
+ */
+ const int DEFAULT_TEXTURE_UNIT = 0;
- /*static*/ Shader* Shader::currentShader = nullptr;
+ /*static*/ Shader* Shader::currentShader = nullptr;
- Shader* Shader::createShader(const string& program)
- {
- Shader* shader = nullptr;
- try
- {
- shader = new Shader(program);
- }
- catch(...)
- {
- return nullptr;
- }
- return shader;
- }
+ Shader* Shader::createShader(const string& program)
+ {
+ Shader* shader = nullptr;
+ try
+ {
+ shader = new Shader(program);
+ }
+ catch(...)
+ {
+ return nullptr;
+ }
+ return shader;
+ }
- Shader::Shader(const string& program)
- : currentTextureUnit(DEFAULT_TEXTURE_UNIT)
- {
- if (!compile(program))
- throw 0;
- }
+ Shader::Shader(const string& program)
+ : currentTextureUnit(DEFAULT_TEXTURE_UNIT)
+ {
+ if (!compile(program))
+ throw 0;
+ }
- Shader::~Shader()
- {
- if (currentShader == this)
- unuse();
- }
+ Shader::~Shader()
+ {
+ if (currentShader == this)
+ unuse();
+ }
- bool Shader::compile(const string& program)
- {
- /* parse shader source, need some optimizations */
- int loc_VERTEX_SHADER = program.find("#VERTEX_SHADER");
- int loc_END_VERTEX_SHADER = program.find("#END_VERTEX_SHADER");
- int loc_FRAGMENT_SHADER = program.find("#FRAGMENT_SHADER");
- int loc_END_FRAGMENT_SHADER = program.find("#END_FRAGMENT_SHADER");
- if (loc_VERTEX_SHADER == string::npos
- || loc_END_VERTEX_SHADER == string::npos
- || loc_FRAGMENT_SHADER == string::npos
- || loc_END_FRAGMENT_SHADER == string::npos
- )
- return false;
- /* load vertex and fragment shader source into buffers */
- int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER");
- string vertex_shader = program.substr(start, loc_END_VERTEX_SHADER - start);
- Buffer vbuffer = Buffer(vertex_shader.length() + BASE_VERTEX_SHADER_SIZE);
- formatVertexShader((char*)vbuffer.data, vertex_shader.c_str());
- start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER");
- string fragment_shader = program.substr(start, loc_END_FRAGMENT_SHADER - start);
- Buffer fbuffer = Buffer(fragment_shader.length() + BASE_FRAGMENT_SHADER_SIZE);
- formatFragmentShader((char*)fbuffer.data, fragment_shader.c_str());
- /* compile */
- GLint success;
- GLuint vshader = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vshader, 1, (const GLchar**)&vbuffer.data, NULL);
- glCompileShader(vshader);
- glGetShaderiv(vshader, GL_COMPILE_STATUS, &success);
- if (success == GL_FALSE)
- return false;
- GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fshader, 1, (const GLchar**)&fbuffer.data, NULL);
- glCompileShader(fshader);
- glGetShaderiv(fshader, GL_COMPILE_STATUS, &success);
- if (success == GL_FALSE)
- return false;
- pid = glCreateProgram();
- glAttachShader(pid, vshader);
- glAttachShader(pid, fshader);
- glLinkProgram(pid);
- glGetProgramiv(pid, GL_LINK_STATUS, &success);
- if (success == GL_FALSE)
- throw false;
- }
+ bool Shader::compile(const string& program)
+ {
+ /* parse shader source, need some optimizations */
+ int loc_VERTEX_SHADER = program.find("#VERTEX_SHADER");
+ int loc_END_VERTEX_SHADER = program.find("#END_VERTEX_SHADER");
+ int loc_FRAGMENT_SHADER = program.find("#FRAGMENT_SHADER");
+ int loc_END_FRAGMENT_SHADER = program.find("#END_FRAGMENT_SHADER");
+ if (loc_VERTEX_SHADER == string::npos
+ || loc_END_VERTEX_SHADER == string::npos
+ || loc_FRAGMENT_SHADER == string::npos
+ || loc_END_FRAGMENT_SHADER == string::npos
+ )
+ return false;
+ /* load vertex and fragment shader source into buffers */
+ int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER");
+ string vertex_shader = program.substr(start, loc_END_VERTEX_SHADER - start);
+ Buffer vbuffer = Buffer(vertex_shader.length() + BASE_VERTEX_SHADER_SIZE);
+ formatVertexShader((char*)vbuffer.data, vertex_shader.c_str());
+ start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER");
+ string fragment_shader = program.substr(start, loc_END_FRAGMENT_SHADER - start);
+ Buffer fbuffer = Buffer(fragment_shader.length() + BASE_FRAGMENT_SHADER_SIZE);
+ formatFragmentShader((char*)fbuffer.data, fragment_shader.c_str());
+ /* compile */
+ GLint success;
+ GLuint vshader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vshader, 1, (const GLchar**)&vbuffer.data, NULL);
+ glCompileShader(vshader);
+ glGetShaderiv(vshader, GL_COMPILE_STATUS, &success);
+ if (success == GL_FALSE)
+ return false;
+ GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fshader, 1, (const GLchar**)&fbuffer.data, NULL);
+ glCompileShader(fshader);
+ glGetShaderiv(fshader, GL_COMPILE_STATUS, &success);
+ if (success == GL_FALSE)
+ return false;
+ pid = glCreateProgram();
+ glAttachShader(pid, vshader);
+ glAttachShader(pid, fshader);
+ glLinkProgram(pid);
+ glGetProgramiv(pid, GL_LINK_STATUS, &success);
+ if (success == GL_FALSE)
+ throw false;
+ }
- static inline GLint getMaxTextureUnits()
- {
- GLint maxTextureUnits = 0;
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
- return maxTextureUnits;
- }
+ static inline GLint getMaxTextureUnits()
+ {
+ GLint maxTextureUnits = 0;
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
+ return maxTextureUnits;
+ }
- void Shader::use()
- {
- glUseProgram(pid);
- currentShader = this;
- sendInt(SHADER_MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT);
- }
+ void Shader::use()
+ {
+ glUseProgram(pid);
+ currentShader = this;
+ sendInt(SHADER_MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT);
+ }
- /*static*/ void Shader::unuse()
- {
- glUseProgram(0);
- currentShader = nullptr;
- }
+ /*static*/ void Shader::unuse()
+ {
+ glUseProgram(0);
+ currentShader = nullptr;
+ }
- GLint Shader::claimTextureUnit(const std::string& name)
- {
- std::map<std::string, GLint>::iterator unit = textureUnits.find(name);
- if (unit != textureUnits.end())
- return unit->second;
- static GLint MAX_TEXTURE_UNITS = getMaxTextureUnits();
- if (++currentTextureUnit >= MAX_TEXTURE_UNITS)
- return 0;
- textureUnits[name] = currentTextureUnit;
- return currentTextureUnit;
- }
+ GLint Shader::claimTextureUnit(const std::string& name)
+ {
+ std::map<std::string, GLint>::iterator unit = textureUnits.find(name);
+ if (unit != textureUnits.end())
+ return unit->second;
+ static GLint MAX_TEXTURE_UNITS = getMaxTextureUnits();
+ if (++currentTextureUnit >= MAX_TEXTURE_UNITS)
+ return 0;
+ textureUnits[name] = currentTextureUnit;
+ return currentTextureUnit;
+ }
-#define checkJSL() \
- if (currentShader != this) \
- return
+ #define checkJSL() \
+ if (currentShader != this) \
+ return
- void Shader::sendInt(const char* name, int value)
- {
- checkJSL();
- int loc = glGetUniformLocation(pid, name);
- glUniform1i(loc, value);
- }
+ void Shader::sendInt(const char* name, int value)
+ {
+ checkJSL();
+ int loc = glGetUniformLocation(pid, name);
+ glUniform1i(loc, value);
+ }
- void Shader::sendFloat(const char* variable, float number)
- {
- checkJSL();
- int loc = glGetUniformLocation(pid, variable);
- glUniform1f(loc, number);
- }
+ void Shader::sendFloat(const char* variable, float number)
+ {
+ checkJSL();
+ int loc = glGetUniformLocation(pid, variable);
+ glUniform1f(loc, number);
+ }
- /**
- * https://www.douban.com/note/627332677/
- * struct TextureUnit
- * {
- * GLuint targetTexture1D;
- * GLuint targetTexture2D;
- * GLuint targetTexture3D;
- * GLuint targetTextureCube;
- * ...
- * };
- *
- * TextureUnit textureUnits[GL_MAX_TEXTURE_IMAGE_UNITS]
- * GLuint currentTextureUnit = 0;
- */
- void Shader::sendTexture(const char* variable, const Texture* tex)
- {
- checkJSL();
- GLint location = glGetUniformLocation(pid, variable);
- if (location == -1)
- return;
- GLint unit = claimTextureUnit(variable);
- if (unit == 0)
- {
- // TODO: 쳣󶨵
- return;
- }
- gl.activeTexUnit(unit);
- glUniform1i(location, unit);
- gl.bindTexture(tex->getTexture());
- gl.activeTexUnit(0);
- }
+ /**
+ * https://www.douban.com/note/627332677/
+ * struct TextureUnit
+ * {
+ * GLuint targetTexture1D;
+ * GLuint targetTexture2D;
+ * GLuint targetTexture3D;
+ * GLuint targetTextureCube;
+ * ...
+ * };
+ *
+ * TextureUnit textureUnits[GL_MAX_TEXTURE_IMAGE_UNITS]
+ * GLuint currentTextureUnit = 0;
+ */
+ void Shader::sendTexture(const char* variable, const Texture* tex)
+ {
+ checkJSL();
+ GLint location = glGetUniformLocation(pid, variable);
+ if (location == -1)
+ return;
+ GLint unit = claimTextureUnit(variable);
+ if (unit == 0)
+ {
+ // TODO: 쳣󶨵
+ return;
+ }
+ gl.activeTexUnit(unit);
+ glUniform1i(location, unit);
+ gl.bindTexture(tex->getTexture());
+ gl.activeTexUnit(0);
+ }
- void Shader::sendCanvas(const char* variable, const Canvas* canvas)
- {
- checkJSL();
- GLint location = glGetUniformLocation(pid, variable);
- if (location == -1)
- return;
- GLint unit = claimTextureUnit(variable);
- if (unit == 0)
- {
- // TODO: 쳣󶨵
- return;
- }
- glUniform1i(location, unit);
- glActiveTexture(GL_TEXTURE0 + unit);
- gl.bindTexture(canvas->getTexture());
+ void Shader::sendCanvas(const char* variable, const Canvas* canvas)
+ {
+ checkJSL();
+ GLint location = glGetUniformLocation(pid, variable);
+ if (location == -1)
+ return;
+ GLint unit = claimTextureUnit(variable);
+ if (unit == 0)
+ {
+ // TODO: 쳣󶨵
+ return;
+ }
+ glUniform1i(location, unit);
+ glActiveTexture(GL_TEXTURE0 + unit);
+ gl.bindTexture(canvas->getTexture());
- glActiveTexture(GL_TEXTURE0);
- }
+ glActiveTexture(GL_TEXTURE0);
+ }
- void Shader::sendVec2(const char* name, float x, float y)
- {
- checkJSL();
- int loc = glGetUniformLocation(pid, name);
- glUniform2f(loc, x, y);
- }
+ void Shader::sendVec2(const char* name, float x, float y)
+ {
+ checkJSL();
+ int loc = glGetUniformLocation(pid, name);
+ glUniform2f(loc, x, y);
+ }
- void Shader::sendVec3(const char* name, float x, float y, float z)
- {
- checkJSL();
- int loc = glGetUniformLocation(pid, name);
- glUniform3f(loc, x, y, z);
- }
+ void Shader::sendVec3(const char* name, float x, float y, float z)
+ {
+ checkJSL();
+ int loc = glGetUniformLocation(pid, name);
+ glUniform3f(loc, x, y, z);
+ }
- void Shader::sendVec4(const char* name, float x, float y, float z, float w)
- {
- checkJSL();
- int loc = glGetUniformLocation(pid, name);
- glUniform4f(loc, x, y, z, w);
- }
+ void Shader::sendVec4(const char* name, float x, float y, float z, float w)
+ {
+ checkJSL();
+ int loc = glGetUniformLocation(pid, name);
+ glUniform4f(loc, x, y, z, w);
+ }
- void Shader::sendColor(const char* name, const Color* col)
- {
- checkJSL();
- int loc = glGetUniformLocation(pid, name);
- glUniform4f(loc,
- col->r / 255.f,
- col->g / 255.f,
- col->b / 255.f,
- col->a / 255.f
- );
- }
+ void Shader::sendColor(const char* name, const Color* col)
+ {
+ checkJSL();
+ int loc = glGetUniformLocation(pid, name);
+ glUniform4f(loc,
+ col->r / 255.f,
+ col->g / 255.f,
+ col->b / 255.f,
+ col->a / 255.f
+ );
+ }
- void Shader::sendMatrix4(const char* name, const math::Matrix* mat4)
- {
- int loc = glGetUniformLocation(pid, name);
- glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements());
- }
+ void Shader::sendMatrix4(const char* name, const math::Matrix* mat4)
+ {
+ int loc = glGetUniformLocation(pid, name);
+ glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements());
+ }
- void Shader::bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers)
- {
- GLint loc = glGetAttribLocation(pid, SHADER_VERTEX_COORDS);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers);
- }
+ void Shader::bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers)
+ {
+ GLint loc = glGetAttribLocation(pid, SHADER_VERTEX_COORDS);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers);
+ }
- void Shader::bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers)
- {
- GLint loc = glGetAttribLocation(pid, SHADER_TEXTURE_COORDS);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers);
- }
+ void Shader::bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers)
+ {
+ GLint loc = glGetAttribLocation(pid, SHADER_TEXTURE_COORDS);
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers);
+ }
-} // graphics
+ } // graphics
} // jin
#endif // LIBJIN_MODULES_RENDER \ No newline at end of file
diff --git a/src/libjin/Graphics/Shader.h b/src/libjin/Graphics/Shader.h
index dcd0b62..6339883 100644
--- a/src/libjin/Graphics/Shader.h
+++ b/src/libjin/Graphics/Shader.h
@@ -13,46 +13,46 @@
namespace jin
{
-namespace graphics
-{
-
- class Shader
- {
- public:
- static Shader* createShader(const std::string& program);
- static inline Shader* getCurrentShader() { return currentShader; }
- static void unuse();
-
- virtual ~Shader();
-
- void use();
- void sendFloat(const char* name, float number);
- void sendTexture(const char* name, const Texture* image);
- void sendInt(const char* name, int value);
- void sendVec2(const char* name, float x, float y);
- void sendVec3(const char* name, float x, float y, float z);
- void sendVec4(const char* name, float x, float y, float z, float w);
- void sendCanvas(const char* name, const Canvas* canvas);
- void sendColor(const char* name, const Color* col);
- void sendMatrix4(const char* name, const math::Matrix* mat4);
-
- void bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers);
- void bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers);
-
- protected:
- static Shader* currentShader;
-
- GLint claimTextureUnit(const std::string& name);
- Shader(const std::string& program);
- bool compile(const std::string& program);
-
- GLuint pid;
- GLint currentTextureUnit;
- std::map<std::string, GLint> textureUnits;
-
- };
-
-} // graphics
+ namespace graphics
+ {
+
+ class Shader
+ {
+ public:
+ static Shader* createShader(const std::string& program);
+ static inline Shader* getCurrentShader() { return currentShader; }
+ static void unuse();
+
+ virtual ~Shader();
+
+ void use();
+ void sendFloat(const char* name, float number);
+ void sendTexture(const char* name, const Texture* image);
+ void sendInt(const char* name, int value);
+ void sendVec2(const char* name, float x, float y);
+ void sendVec3(const char* name, float x, float y, float z);
+ void sendVec4(const char* name, float x, float y, float z, float w);
+ void sendCanvas(const char* name, const Canvas* canvas);
+ void sendColor(const char* name, const Color* col);
+ void sendMatrix4(const char* name, const math::Matrix* mat4);
+
+ void bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers);
+ void bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers);
+
+ protected:
+ static Shader* currentShader;
+
+ GLint claimTextureUnit(const std::string& name);
+ Shader(const std::string& program);
+ bool compile(const std::string& program);
+
+ GLuint pid;
+ GLint currentTextureUnit;
+ std::map<std::string, GLint> textureUnits;
+
+ };
+
+ } // graphics
} // jin
#endif // LIBJIN_MODULES_RENDER
diff --git a/src/libjin/Graphics/Shapes.cpp b/src/libjin/Graphics/Shapes.cpp
index f5aedd4..5e87473 100644
--- a/src/libjin/Graphics/Shapes.cpp
+++ b/src/libjin/Graphics/Shapes.cpp
@@ -9,118 +9,118 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- using namespace math;
+ using namespace math;
- void point(int x, int y)
- {
- float verts[] = { x + 0.5f , y + 0.5f };
+ void point(int x, int y)
+ {
+ float verts[] = { x + 0.5f , y + 0.5f };
- Shader* shader = Shader::getCurrentShader();
- shader->bindVertexPointer(2, GL_FLOAT, 0, verts);
- gl.ModelMatrix.setIdentity();
- shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
- shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
+ Shader* shader = Shader::getCurrentShader();
+ shader->bindVertexPointer(2, GL_FLOAT, 0, verts);
+ gl.ModelMatrix.setIdentity();
+ shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
+ shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
- glDrawArrays(GL_POINTS, 0, 1);
- }
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
- void points(int n, GLshort* p)
- {
- Shader* shader = Shader::getCurrentShader();
- shader->bindVertexPointer(2, GL_SHORT, 0, p);
- gl.ModelMatrix.setIdentity();
- shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
- shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
+ void points(int n, GLshort* p)
+ {
+ Shader* shader = Shader::getCurrentShader();
+ shader->bindVertexPointer(2, GL_SHORT, 0, p);
+ gl.ModelMatrix.setIdentity();
+ shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
+ shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
- glDrawArrays(GL_POINTS, 0, n);
- }
-
- void line(int x1, int y1, int x2, int y2)
- {
- float verts[] = {
- x1, y1,
- x2, y2
- };
+ glDrawArrays(GL_POINTS, 0, n);
+ }
+
+ void line(int x1, int y1, int x2, int y2)
+ {
+ float verts[] = {
+ x1, y1,
+ x2, y2
+ };
- Shader* shader = Shader::getCurrentShader();
- shader->bindVertexPointer(2, GL_FLOAT, 0, verts);
- gl.ModelMatrix.setIdentity();
- shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
- shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
+ Shader* shader = Shader::getCurrentShader();
+ shader->bindVertexPointer(2, GL_FLOAT, 0, verts);
+ gl.ModelMatrix.setIdentity();
+ shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
+ shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
- glDrawArrays(GL_LINES, 0, 2);
- }
-
- void circle(RenderMode mode, int x, int y, int r)
- {
- r = r < 0 ? 0 : r;
-
- int points = 40;
- float two_pi = static_cast<float>(PI * 2);
- if (points <= 0) points = 1;
- float angle_shift = (two_pi / points);
- float phi = .0f;
-
- float *coords = new float[2 * (points + 1)];
- for (int i = 0; i < points; ++i, phi += angle_shift)
- {
- coords[2 * i] = x + r * cos(phi);
- coords[2 * i + 1] = y + r * sin(phi);
- }
-
- coords[2 * points] = coords[0];
- coords[2 * points + 1] = coords[1];
-
- polygon(mode, coords, points);
-
- delete[] coords;
- }
-
- void rect(RenderMode mode, int x, int y, int w, int h)
- {
- float coords[] = { x, y, x + w, y, x + w, y + h, x, y + h };
- polygon(mode, coords, 4);
- }
-
- void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3)
- {
- float coords[] = { x1, y1, x2, y2, x3, y3 };
- polygon(mode, coords, 3);
- }
-
- void polygon_line(float* p, int count)
- {
- Shader* shader = Shader::getCurrentShader();
- gl.ModelMatrix.setIdentity();
- shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
- shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
- shader->bindVertexPointer(2, GL_FLOAT, 0, p);
-
- glDrawArrays(GL_LINE_LOOP, 0, count);
- }
-
- void polygon(RenderMode mode, float* p, int count)
- {
- if (mode == LINE)
- {
- polygon_line(p, count);
- }
- else if (mode == FILL)
- {
+ glDrawArrays(GL_LINES, 0, 2);
+ }
+
+ void circle(RenderMode mode, int x, int y, int r)
+ {
+ r = r < 0 ? 0 : r;
+
+ int points = 40;
+ float two_pi = static_cast<float>(PI * 2);
+ if (points <= 0) points = 1;
+ float angle_shift = (two_pi / points);
+ float phi = .0f;
+
+ float *coords = new float[2 * (points + 1)];
+ for (int i = 0; i < points; ++i, phi += angle_shift)
+ {
+ coords[2 * i] = x + r * cos(phi);
+ coords[2 * i + 1] = y + r * sin(phi);
+ }
+
+ coords[2 * points] = coords[0];
+ coords[2 * points + 1] = coords[1];
+
+ polygon(mode, coords, points);
+
+ delete[] coords;
+ }
+
+ void rect(RenderMode mode, int x, int y, int w, int h)
+ {
+ float coords[] = { x, y, x + w, y, x + w, y + h, x, y + h };
+ polygon(mode, coords, 4);
+ }
+
+ void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3)
+ {
+ float coords[] = { x1, y1, x2, y2, x3, y3 };
+ polygon(mode, coords, 3);
+ }
+
+ void polygon_line(float* p, int count)
+ {
Shader* shader = Shader::getCurrentShader();
- gl.ModelMatrix.setIdentity();
+ gl.ModelMatrix.setIdentity();
shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
shader->bindVertexPointer(2, GL_FLOAT, 0, p);
- glDrawArrays(GL_POLYGON, 0, count);
- }
- }
-
-} // graphics
+ glDrawArrays(GL_LINE_LOOP, 0, count);
+ }
+
+ void polygon(RenderMode mode, float* p, int count)
+ {
+ if (mode == LINE)
+ {
+ polygon_line(p, count);
+ }
+ else if (mode == FILL)
+ {
+ Shader* shader = Shader::getCurrentShader();
+ gl.ModelMatrix.setIdentity();
+ shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix);
+ shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix);
+ shader->bindVertexPointer(2, GL_FLOAT, 0, p);
+
+ glDrawArrays(GL_POLYGON, 0, count);
+ }
+ }
+
+ } // graphics
} // jin
#endif // LIBJIN_MODULES_RENDER \ No newline at end of file
diff --git a/src/libjin/Graphics/Shapes.h b/src/libjin/Graphics/Shapes.h
index b248cca..93cde6d 100644
--- a/src/libjin/Graphics/Shapes.h
+++ b/src/libjin/Graphics/Shapes.h
@@ -9,28 +9,28 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- typedef enum {
- NONE = 0,
- FILL ,
- LINE
- }RenderMode;
+ typedef enum {
+ NONE = 0,
+ FILL ,
+ LINE
+ }RenderMode;
- /**
- * TODO:
- * drawPixels(int n, points)
- */
- extern void line(int x1, int y1, int x2, int y2);
- extern void rect(RenderMode mode, int x, int y, int w, int h);
- extern void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3);
- extern void circle(RenderMode mode, int x, int y, int r);
- extern void point(int x, int y);
- extern void points(int n, GLshort* p, GLubyte* c);
- extern void polygon(RenderMode mode, float* p, int count);
+ /**
+ * TODO:
+ * drawPixels(int n, points)
+ */
+ extern void line(int x1, int y1, int x2, int y2);
+ extern void rect(RenderMode mode, int x, int y, int w, int h);
+ extern void triangle(RenderMode mode, int x1, int y1, int x2, int y2, int x3, int y3);
+ extern void circle(RenderMode mode, int x, int y, int r);
+ extern void point(int x, int y);
+ extern void points(int n, GLshort* p, GLubyte* c);
+ extern void polygon(RenderMode mode, float* p, int count);
-} // graphics
+ } // graphics
} // jin
#endif // LIBJIN_MODULES_RENDER
diff --git a/src/libjin/Graphics/Texture.cpp b/src/libjin/Graphics/Texture.cpp
index a42e796..915fe54 100644
--- a/src/libjin/Graphics/Texture.cpp
+++ b/src/libjin/Graphics/Texture.cpp
@@ -8,27 +8,27 @@
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- using namespace jin::math;
+ using namespace jin::math;
- /*static*/ Texture* Texture::createTexture(Bitmap* bitmap)
- {
- Texture* tex = new Texture(bitmap);
- return tex;
- }
+ /*static*/ Texture* Texture::createTexture(Bitmap* bitmap)
+ {
+ Texture* tex = new Texture(bitmap);
+ return tex;
+ }
- Texture::Texture(const Bitmap* bitmap)
- : Drawable(bitmap)
- {
- }
+ Texture::Texture(const Bitmap* bitmap)
+ : Drawable(bitmap)
+ {
+ }
- Texture::~Texture()
- {
- }
+ Texture::~Texture()
+ {
+ }
-} // graphics
+ } // graphics
} // jin
#endif // LIBJIN_MODULES_RENDER \ No newline at end of file
diff --git a/src/libjin/Graphics/Texture.h b/src/libjin/Graphics/Texture.h
index 1704ee7..eb16519 100644
--- a/src/libjin/Graphics/Texture.h
+++ b/src/libjin/Graphics/Texture.h
@@ -9,22 +9,22 @@
#include "Bitmap.h"
namespace jin
{
-namespace graphics
-{
+ namespace graphics
+ {
- class Texture: public Drawable
- {
- public:
- static Texture* createTexture(Bitmap* bitmap);
+ class Texture: public Drawable
+ {
+ public:
+ static Texture* createTexture(Bitmap* bitmap);
- ~Texture();
+ ~Texture();
- private:
- Texture(const Bitmap* bitmap);
+ private:
+ Texture(const Bitmap* bitmap);
- };
+ };
-} // graphics
+ } // graphics
} // jin
#endif // LIBJIN_MODULES_RENDER
diff --git a/src/libjin/Graphics/Window.cpp b/src/libjin/Graphics/Window.cpp
index 6ebc9f9..140ef36 100644
--- a/src/libjin/Graphics/Window.cpp
+++ b/src/libjin/Graphics/Window.cpp
@@ -12,98 +12,98 @@
namespace jin
{
-namespace graphics
-{
-
- bool Window::initSystem(const SettingBase* s)
- {
-#if LIBJIN_DEBUG
- Loghelper::log(Loglevel::LV_INFO, "Init window system");
-#endif
-
- if (SDL_Init(SDL_INIT_VIDEO) < 0)
- return false;
-
- const Setting* setting = (Setting*)s;
- size.w = setting->width;
- size.h = setting->height;
- fps = setting->fps;
- bool vsync = setting->vsync;
- const char* title = setting->title;
-
- if (wnd)
- {
- SDL_DestroyWindow(wnd);
- SDL_FlushEvent(SDL_WINDOWEVENT);
- }
-
- SDL_GLContext ctx = NULL;
-
- if (ctx)
- {
- SDL_GL_DeleteContext(ctx);
- }
-
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
- int wx = SDL_WINDOWPOS_UNDEFINED,
- wy = SDL_WINDOWPOS_UNDEFINED;
+ namespace graphics
+ {
+
+ bool Window::initSystem(const SettingBase* s)
+ {
+ #if LIBJIN_DEBUG
+ Loghelper::log(Loglevel::LV_INFO, "Init window system");
+ #endif
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0)
+ return false;
+
+ const Setting* setting = (Setting*)s;
+ size.w = setting->width;
+ size.h = setting->height;
+ fps = setting->fps;
+ bool vsync = setting->vsync;
+ const char* title = setting->title;
+
+ if (wnd)
+ {
+ SDL_DestroyWindow(wnd);
+ SDL_FlushEvent(SDL_WINDOWEVENT);
+ }
+
+ SDL_GLContext ctx = NULL;
+
+ if (ctx)
+ {
+ SDL_GL_DeleteContext(ctx);
+ }
+
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ int wx = SDL_WINDOWPOS_UNDEFINED,
+ wy = SDL_WINDOWPOS_UNDEFINED;
- int flag = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
- if (setting->fullscreen) flag |= SDL_WINDOW_FULLSCREEN;
- if (setting->resizable) flag |= SDL_WINDOW_RESIZABLE;
-
- wnd = SDL_CreateWindow(title, wx, wy, size.w, size.h, flag);
- if (wnd == NULL)
- return false;
- ctx = SDL_GL_CreateContext(wnd);
- if (ctx == NULL)
- return false;
- SDL_GL_SetSwapInterval(vsync ? 1 : 0);
- SDL_GL_MakeCurrent(wnd, ctx);
- /* default configuration */
- gl.setClearColor(0, 0, 0, 0xff);
- gl.pushColor(0xff, 0xff, 0xff, 0xff);
- gl.enable(GL_BLEND);
- gl.enable(GL_TEXTURE_2D);
- gl.setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- /* avoid white screen blink on windows */
- swapBuffers();
- /* bind to default canvas */
- Canvas::unbind();
- Shader::unuse();
- return true;
- }
-
- void Window::quitSystem()
- {
- /* disable opengl */
- gl.disable(GL_BLEND);
- gl.disable(GL_TEXTURE_2D);
- /* close window */
- SDL_DestroyWindow(wnd);
- SDL_Quit();
- }
-
- void Window::swapBuffers()
- {
- if (wnd)
- SDL_GL_SwapWindow(wnd);
- }
-
- void Window::setTitle(const char* title)
- {
- SDL_SetWindowTitle(wnd, title);
- };
-
-} // graphics
+ int flag = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL;
+ if (setting->fullscreen) flag |= SDL_WINDOW_FULLSCREEN;
+ if (setting->resizable) flag |= SDL_WINDOW_RESIZABLE;
+
+ wnd = SDL_CreateWindow(title, wx, wy, size.w, size.h, flag);
+ if (wnd == NULL)
+ return false;
+ ctx = SDL_GL_CreateContext(wnd);
+ if (ctx == NULL)
+ return false;
+ SDL_GL_SetSwapInterval(vsync ? 1 : 0);
+ SDL_GL_MakeCurrent(wnd, ctx);
+ /* default configuration */
+ gl.setClearColor(0, 0, 0, 0xff);
+ gl.pushColor(0xff, 0xff, 0xff, 0xff);
+ gl.enable(GL_BLEND);
+ gl.enable(GL_TEXTURE_2D);
+ gl.setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ /* avoid white screen blink on windows */
+ swapBuffers();
+ /* bind to default canvas */
+ Canvas::unbind();
+ Shader::unuse();
+ return true;
+ }
+
+ void Window::quitSystem()
+ {
+ /* disable opengl */
+ gl.disable(GL_BLEND);
+ gl.disable(GL_TEXTURE_2D);
+ /* close window */
+ SDL_DestroyWindow(wnd);
+ SDL_Quit();
+ }
+
+ void Window::swapBuffers()
+ {
+ if (wnd)
+ SDL_GL_SwapWindow(wnd);
+ }
+
+ void Window::setTitle(const char* title)
+ {
+ SDL_SetWindowTitle(wnd, title);
+ };
+
+ } // graphics
} // jin
#endif // LIBJIN_MODULES_RENDER \ No newline at end of file
diff --git a/src/libjin/Graphics/Window.h b/src/libjin/Graphics/Window.h
index 301b0b5..3734ee3 100644
--- a/src/libjin/Graphics/Window.h
+++ b/src/libjin/Graphics/Window.h
@@ -10,45 +10,45 @@
namespace jin
{
-namespace graphics
-{
-
- class Window : public Subsystem<Window>
- {
- public:
- struct Setting : SettingBase
- {
- public:
- const char* title; //
- bool fullscreen; // ȫ
- int width, height; // ڴС
- bool vsync; // ֱͬ
- int fps; // FPS
- bool resizable; // resize
- };
-
- void setTitle(const char* title);
- inline int getW(){ return size.w; }
- inline int getH(){ return size.h; }
- inline int getFPS(){ return fps; }
- void swapBuffers();
-
- private:
- SINGLETON(Window);
-
- Window() {};
-
- virtual ~Window() {};
- bool initSystem(const SettingBase* setting) override;
- void quitSystem() override;
-
- SDL_Window* wnd;
- jin::math::Vector2<unsigned int> size;
- int fps;
-
- };
-
-} // render
+ namespace graphics
+ {
+
+ class Window : public Subsystem<Window>
+ {
+ public:
+ struct Setting : SettingBase
+ {
+ public:
+ const char* title; //
+ bool fullscreen; // ȫ
+ int width, height; // ڴС
+ bool vsync; // ֱͬ
+ int fps; // FPS
+ bool resizable; // resize
+ };
+
+ void setTitle(const char* title);
+ inline int getW(){ return size.w; }
+ inline int getH(){ return size.h; }
+ inline int getFPS(){ return fps; }
+ void swapBuffers();
+
+ private:
+ SINGLETON(Window);
+
+ Window() {};
+
+ virtual ~Window() {};
+ bool initSystem(const SettingBase* setting) override;
+ void quitSystem() override;
+
+ SDL_Window* wnd;
+ jin::math::Vector2<unsigned int> size;
+ int fps;
+
+ };
+
+ } // render
} // jin
#endif // LIBJIN_MODULES_RENDER
diff --git a/src/libjin/Input/Keyboard.h b/src/libjin/Input/Keyboard.h
index 250e8f0..b50302c 100644
--- a/src/libjin/Input/Keyboard.h
+++ b/src/libjin/Input/Keyboard.h
@@ -3,15 +3,15 @@
namespace jin
{
-namespace input
-{
+ namespace input
+ {
- class Keyboard
- {
+ class Keyboard
+ {
- };
+ };
-} // input
+ } // input
} // jin
#endif // __LIBJIN_KEYBOARD_H \ No newline at end of file
diff --git a/src/libjin/Input/Mouse.cpp b/src/libjin/Input/Mouse.cpp
index 31c29f9..3869337 100644
--- a/src/libjin/Input/Mouse.cpp
+++ b/src/libjin/Input/Mouse.cpp
@@ -6,22 +6,22 @@
namespace jin
{
-namespace input
-{
+ namespace input
+ {
- void Mouse::getState(int* x, int* y)
- {
- #ifdef LIBJIN_INPUT_SDL
- SDL_GetMouseState(x, y);
- #endif // LIBJIN_INPUT_SDL
- }
+ void Mouse::getState(int* x, int* y)
+ {
+ #ifdef LIBJIN_INPUT_SDL
+ SDL_GetMouseState(x, y);
+ #endif // LIBJIN_INPUT_SDL
+ }
- void Mouse::setVisible(bool visible)
- {
- SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
- }
+ void Mouse::setVisible(bool visible)
+ {
+ SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
+ }
-} // input
+ } // input
} // jin
#endif // LIBJIN_MODULES_INPUT \ No newline at end of file
diff --git a/src/libjin/Input/Mouse.h b/src/libjin/Input/Mouse.h
index 09db5d2..29d730b 100644
--- a/src/libjin/Input/Mouse.h
+++ b/src/libjin/Input/Mouse.h
@@ -7,24 +7,24 @@
namespace jin
{
-namespace input
-{
+ namespace input
+ {
- class Mouse : public Singleton<Mouse>
- {
- public:
- void getState(int* x, int* y);
- void setVisible(bool visible);
+ class Mouse : public Singleton<Mouse>
+ {
+ public:
+ void getState(int* x, int* y);
+ void setVisible(bool visible);
- private:
- SINGLETON(Mouse);
+ private:
+ SINGLETON(Mouse);
- Mouse() {};
- ~Mouse() {};
+ Mouse() {};
+ ~Mouse() {};
- };
+ };
-} // input
+ } // input
} // jin
#endif // LIBJIN_MODULES_INPUT
diff --git a/src/libjin/Math/Math.h b/src/libjin/Math/Math.h
index 6eb4367..98f9cd8 100644
--- a/src/libjin/Math/Math.h
+++ b/src/libjin/Math/Math.h
@@ -7,71 +7,71 @@
namespace jin
{
-namespace math
-{
+ namespace math
+ {
-#ifdef min
-# undef min
-#endif // min
-#ifdef max
-# undef max
-#endif // max
+ #ifdef min
+ # undef min
+ #endif // min
+ #ifdef max
+ # undef max
+ #endif // max
- template<typename T>
- inline T min(T a, T b)
- {
- return a < b ? a : b;
- }
+ template<typename T>
+ inline T min(T a, T b)
+ {
+ return a < b ? a : b;
+ }
- template<typename T>
- inline T max(T a, T b)
- {
- return a > b ? a : b;
- }
+ template<typename T>
+ inline T max(T a, T b)
+ {
+ return a > b ? a : b;
+ }
- template<typename T>
- inline T clamp(T a, T mi, T ma)
- {
- return min<T>(max<T>(a, mi), ma);
- }
+ template<typename T>
+ inline T clamp(T a, T mi, T ma)
+ {
+ return min<T>(max<T>(a, mi), ma);
+ }
- template<typename T>
- inline bool within(T a, T mi, T ma)
- {
- return a >= mi && a <= ma;
- }
+ template<typename T>
+ inline bool within(T a, T mi, T ma)
+ {
+ return a >= mi && a <= ma;
+ }
- template<typename T>
- inline bool without(T a, T mi, T ma)
- {
- return a < mi || a > ma;
- }
+ template<typename T>
+ inline bool without(T a, T mi, T ma)
+ {
+ return a < mi || a > ma;
+ }
- template<typename T>
- inline T abs(T a)
- {
- return a > 0 ? a : -a;
- }
+ template<typename T>
+ inline T abs(T a)
+ {
+ return a > 0 ? a : -a;
+ }
- template<typename T>
- inline T lowerBound(T a, T lower)
- {
- return a < lower ? lower : a;
- }
+ template<typename T>
+ inline T lowerBound(T a, T lower)
+ {
+ return a < lower ? lower : a;
+ }
- template<typename T>
- inline T upperBound(T a, T upper)
- {
- return a > upper ? upper : a;
- }
+ template<typename T>
+ inline T upperBound(T a, T upper)
+ {
+ return a > upper ? upper : a;
+ }
- template<typename T>
- inline T lerp(T a, T b, float t)
- {
- return a + t * (b - a);
- }
+ template<typename T>
+ inline T lerp(T a, T b, float t)
+ {
+ return a + t * (b - a);
+ }
-} // math
+ } // math
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/Math/Matrix.cpp b/src/libjin/Math/Matrix.cpp
index a6e2491..74d3a58 100644
--- a/src/libjin/Math/Matrix.cpp
+++ b/src/libjin/Math/Matrix.cpp
@@ -5,190 +5,190 @@
namespace jin
{
-namespace math
-{
-
- const Matrix Matrix::Identity;
-
- // | e0 e4 e8 e12 |
- // | e1 e5 e9 e13 |
- // | e2 e6 e10 e14 |
- // | e3 e7 e11 e15 |
-
- Matrix::Matrix()
- {
- setIdentity();
- }
-
- Matrix::~Matrix()
- {
- }
-
- void Matrix::setOrtho(float l, float r, float b, float t, float n, float f)
- {
- setIdentity();
- float w = r - l;
- float h = t - b;
- float z = f - n;
- e[0] = 2 / w;
- e[5] = 2 / h;
- e[10] = -2 / z;
- e[12] = -(r + l) / w;
- e[13] = -(t + b) / h;
- e[14] = -(f + n) / z;
- e[15] = 1;
- }
-
- // | e0 e4 e8 e12 |
- // | e1 e5 e9 e13 |
- // | e2 e6 e10 e14 |
- // | e3 e7 e11 e15 |
- // | e0 e4 e8 e12 |
- // | e1 e5 e9 e13 |
- // | e2 e6 e10 e14 |
- // | e3 e7 e11 e15 |
-
- Matrix Matrix::operator * (const Matrix & m) const
- {
- Matrix t;
-
- t.e[0] = (e[0] * m.e[0]) + (e[4] * m.e[1]) + (e[8] * m.e[2]) + (e[12] * m.e[3]);
- t.e[4] = (e[0] * m.e[4]) + (e[4] * m.e[5]) + (e[8] * m.e[6]) + (e[12] * m.e[7]);
- t.e[8] = (e[0] * m.e[8]) + (e[4] * m.e[9]) + (e[8] * m.e[10]) + (e[12] * m.e[11]);
- t.e[12] = (e[0] * m.e[12]) + (e[4] * m.e[13]) + (e[8] * m.e[14]) + (e[12] * m.e[15]);
-
- t.e[1] = (e[1] * m.e[0]) + (e[5] * m.e[1]) + (e[9] * m.e[2]) + (e[13] * m.e[3]);
- t.e[5] = (e[1] * m.e[4]) + (e[5] * m.e[5]) + (e[9] * m.e[6]) + (e[13] * m.e[7]);
- t.e[9] = (e[1] * m.e[8]) + (e[5] * m.e[9]) + (e[9] * m.e[10]) + (e[13] * m.e[11]);
- t.e[13] = (e[1] * m.e[12]) + (e[5] * m.e[13]) + (e[9] * m.e[14]) + (e[13] * m.e[15]);
-
- t.e[2] = (e[2] * m.e[0]) + (e[6] * m.e[1]) + (e[10] * m.e[2]) + (e[14] * m.e[3]);
- t.e[6] = (e[2] * m.e[4]) + (e[6] * m.e[5]) + (e[10] * m.e[6]) + (e[14] * m.e[7]);
- t.e[10] = (e[2] * m.e[8]) + (e[6] * m.e[9]) + (e[10] * m.e[10]) + (e[14] * m.e[11]);
- t.e[14] = (e[2] * m.e[12]) + (e[6] * m.e[13]) + (e[10] * m.e[14]) + (e[14] * m.e[15]);
-
- t.e[3] = (e[3] * m.e[0]) + (e[7] * m.e[1]) + (e[11] * m.e[2]) + (e[15] * m.e[3]);
- t.e[7] = (e[3] * m.e[4]) + (e[7] * m.e[5]) + (e[11] * m.e[6]) + (e[15] * m.e[7]);
- t.e[11] = (e[3] * m.e[8]) + (e[7] * m.e[9]) + (e[11] * m.e[10]) + (e[15] * m.e[11]);
- t.e[15] = (e[3] * m.e[12]) + (e[7] * m.e[13]) + (e[11] * m.e[14]) + (e[15] * m.e[15]);
-
- return t;
- }
-
- void Matrix::operator *= (const Matrix & m)
- {
- Matrix t = (*this) * m;
- memcpy((void*)this->e, (void*)t.e, sizeof(float) * 16);
- }
-
- const float * Matrix::getElements() const
- {
- return e;
- }
-
- void Matrix::setIdentity()
- {
- memset(e, 0, sizeof(float) * 16);
- e[0] = e[5] = e[10] = e[15] = 1;
- }
-
- void Matrix::setTranslation(float x, float y)
- {
- setIdentity();
- e[12] = x;
- e[13] = y;
- }
-
- void Matrix::setRotation(float rad)
- {
- setIdentity();
- float c = cos(rad), s = sin(rad);
- e[0] = c; e[4] = -s;
- e[1] = s; e[5] = c;
- }
-
- void Matrix::setScale(float sx, float sy)
- {
- setIdentity();
- e[0] = sx;
- e[5] = sy;
- }
-
- void Matrix::setShear(float kx, float ky)
- {
- setIdentity();
- e[1] = ky;
- e[4] = kx;
- }
-
- void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy)
- {
- memset(e, 0, sizeof(float) * 16); // zero out matrix
- float c = cos(angle), s = sin(angle);
- // matrix multiplication carried out on paper:
- // |1 x| |c -s | |sx | |1 -ox|
- // | 1 y| |s c | | sy | | 1 -oy|
- // | 1 | | 1 | | 1 | | 1 |
- // | 1| | 1| | 1| | 1 |
- // move rotate scale origin
- e[10] = e[15] = 1.0f;
- e[0] = c * sx ; // = a
- e[1] = s * sx ; // = b
- e[4] = - s * sy; // = c
- e[5] = c * sy; // = d
- e[12] = x - ox * e[0] - oy * e[4];
- e[13] = y - ox * e[1] - oy * e[5];
- }
-
- void Matrix::translate(float x, float y)
- {
- Matrix t;
- t.setTranslation(x, y);
- this->operator *=(t);
- }
-
- void Matrix::rotate(float rad)
- {
- Matrix t;
- t.setRotation(rad);
- this->operator *=(t);
- }
-
- void Matrix::scale(float sx, float sy)
- {
- Matrix t;
- t.setScale(sx, sy);
- this->operator *=(t);
- }
-
- void Matrix::shear(float kx, float ky)
- {
- Matrix t;
- t.setShear(kx, ky);
- this->operator *=(t);
- }
-
- // | x |
- // | y |
- // | 0 |
- // | 1 |
- // | e0 e4 e8 e12 |
- // | e1 e5 e9 e13 |
- // | e2 e6 e10 e14 |
- // | e3 e7 e11 e15 |
-
- void Matrix::transform(vertex * dst, const vertex * src, int size) const
- {
- for (int i = 0; i<size; ++i)
- {
- // Store in temp variables in case src = dst
- float x = (e[0] * src[i].x) + (e[4] * src[i].y) + (0) + (e[12]);
- float y = (e[1] * src[i].x) + (e[5] * src[i].y) + (0) + (e[13]);
-
- dst[i].x = x;
- dst[i].y = y;
- }
- }
-
-} // math
+ namespace math
+ {
+
+ const Matrix Matrix::Identity;
+
+ // | e0 e4 e8 e12 |
+ // | e1 e5 e9 e13 |
+ // | e2 e6 e10 e14 |
+ // | e3 e7 e11 e15 |
+
+ Matrix::Matrix()
+ {
+ setIdentity();
+ }
+
+ Matrix::~Matrix()
+ {
+ }
+
+ void Matrix::setOrtho(float l, float r, float b, float t, float n, float f)
+ {
+ setIdentity();
+ float w = r - l;
+ float h = t - b;
+ float z = f - n;
+ e[0] = 2 / w;
+ e[5] = 2 / h;
+ e[10] = -2 / z;
+ e[12] = -(r + l) / w;
+ e[13] = -(t + b) / h;
+ e[14] = -(f + n) / z;
+ e[15] = 1;
+ }
+
+ // | e0 e4 e8 e12 |
+ // | e1 e5 e9 e13 |
+ // | e2 e6 e10 e14 |
+ // | e3 e7 e11 e15 |
+ // | e0 e4 e8 e12 |
+ // | e1 e5 e9 e13 |
+ // | e2 e6 e10 e14 |
+ // | e3 e7 e11 e15 |
+
+ Matrix Matrix::operator * (const Matrix & m) const
+ {
+ Matrix t;
+
+ t.e[0] = (e[0] * m.e[0]) + (e[4] * m.e[1]) + (e[8] * m.e[2]) + (e[12] * m.e[3]);
+ t.e[4] = (e[0] * m.e[4]) + (e[4] * m.e[5]) + (e[8] * m.e[6]) + (e[12] * m.e[7]);
+ t.e[8] = (e[0] * m.e[8]) + (e[4] * m.e[9]) + (e[8] * m.e[10]) + (e[12] * m.e[11]);
+ t.e[12] = (e[0] * m.e[12]) + (e[4] * m.e[13]) + (e[8] * m.e[14]) + (e[12] * m.e[15]);
+
+ t.e[1] = (e[1] * m.e[0]) + (e[5] * m.e[1]) + (e[9] * m.e[2]) + (e[13] * m.e[3]);
+ t.e[5] = (e[1] * m.e[4]) + (e[5] * m.e[5]) + (e[9] * m.e[6]) + (e[13] * m.e[7]);
+ t.e[9] = (e[1] * m.e[8]) + (e[5] * m.e[9]) + (e[9] * m.e[10]) + (e[13] * m.e[11]);
+ t.e[13] = (e[1] * m.e[12]) + (e[5] * m.e[13]) + (e[9] * m.e[14]) + (e[13] * m.e[15]);
+
+ t.e[2] = (e[2] * m.e[0]) + (e[6] * m.e[1]) + (e[10] * m.e[2]) + (e[14] * m.e[3]);
+ t.e[6] = (e[2] * m.e[4]) + (e[6] * m.e[5]) + (e[10] * m.e[6]) + (e[14] * m.e[7]);
+ t.e[10] = (e[2] * m.e[8]) + (e[6] * m.e[9]) + (e[10] * m.e[10]) + (e[14] * m.e[11]);
+ t.e[14] = (e[2] * m.e[12]) + (e[6] * m.e[13]) + (e[10] * m.e[14]) + (e[14] * m.e[15]);
+
+ t.e[3] = (e[3] * m.e[0]) + (e[7] * m.e[1]) + (e[11] * m.e[2]) + (e[15] * m.e[3]);
+ t.e[7] = (e[3] * m.e[4]) + (e[7] * m.e[5]) + (e[11] * m.e[6]) + (e[15] * m.e[7]);
+ t.e[11] = (e[3] * m.e[8]) + (e[7] * m.e[9]) + (e[11] * m.e[10]) + (e[15] * m.e[11]);
+ t.e[15] = (e[3] * m.e[12]) + (e[7] * m.e[13]) + (e[11] * m.e[14]) + (e[15] * m.e[15]);
+
+ return t;
+ }
+
+ void Matrix::operator *= (const Matrix & m)
+ {
+ Matrix t = (*this) * m;
+ memcpy((void*)this->e, (void*)t.e, sizeof(float) * 16);
+ }
+
+ const float * Matrix::getElements() const
+ {
+ return e;
+ }
+
+ void Matrix::setIdentity()
+ {
+ memset(e, 0, sizeof(float) * 16);
+ e[0] = e[5] = e[10] = e[15] = 1;
+ }
+
+ void Matrix::setTranslation(float x, float y)
+ {
+ setIdentity();
+ e[12] = x;
+ e[13] = y;
+ }
+
+ void Matrix::setRotation(float rad)
+ {
+ setIdentity();
+ float c = cos(rad), s = sin(rad);
+ e[0] = c; e[4] = -s;
+ e[1] = s; e[5] = c;
+ }
+
+ void Matrix::setScale(float sx, float sy)
+ {
+ setIdentity();
+ e[0] = sx;
+ e[5] = sy;
+ }
+
+ void Matrix::setShear(float kx, float ky)
+ {
+ setIdentity();
+ e[1] = ky;
+ e[4] = kx;
+ }
+
+ void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy)
+ {
+ memset(e, 0, sizeof(float) * 16); // zero out matrix
+ float c = cos(angle), s = sin(angle);
+ // matrix multiplication carried out on paper:
+ // |1 x| |c -s | |sx | |1 -ox|
+ // | 1 y| |s c | | sy | | 1 -oy|
+ // | 1 | | 1 | | 1 | | 1 |
+ // | 1| | 1| | 1| | 1 |
+ // move rotate scale origin
+ e[10] = e[15] = 1.0f;
+ e[0] = c * sx ; // = a
+ e[1] = s * sx ; // = b
+ e[4] = - s * sy; // = c
+ e[5] = c * sy; // = d
+ e[12] = x - ox * e[0] - oy * e[4];
+ e[13] = y - ox * e[1] - oy * e[5];
+ }
+
+ void Matrix::translate(float x, float y)
+ {
+ Matrix t;
+ t.setTranslation(x, y);
+ this->operator *=(t);
+ }
+
+ void Matrix::rotate(float rad)
+ {
+ Matrix t;
+ t.setRotation(rad);
+ this->operator *=(t);
+ }
+
+ void Matrix::scale(float sx, float sy)
+ {
+ Matrix t;
+ t.setScale(sx, sy);
+ this->operator *=(t);
+ }
+
+ void Matrix::shear(float kx, float ky)
+ {
+ Matrix t;
+ t.setShear(kx, ky);
+ this->operator *=(t);
+ }
+
+ // | x |
+ // | y |
+ // | 0 |
+ // | 1 |
+ // | e0 e4 e8 e12 |
+ // | e1 e5 e9 e13 |
+ // | e2 e6 e10 e14 |
+ // | e3 e7 e11 e15 |
+
+ void Matrix::transform(vertex * dst, const vertex * src, int size) const
+ {
+ for (int i = 0; i<size; ++i)
+ {
+ // Store in temp variables in case src = dst
+ float x = (e[0] * src[i].x) + (e[4] * src[i].y) + (0) + (e[12]);
+ float y = (e[1] * src[i].x) + (e[5] * src[i].y) + (0) + (e[13]);
+
+ dst[i].x = x;
+ dst[i].y = y;
+ }
+ }
+
+ } // math
} // jin \ No newline at end of file
diff --git a/src/libjin/Math/Matrix.h b/src/libjin/Math/Matrix.h
index 52fc9c8..c1f903a 100644
--- a/src/libjin/Math/Matrix.h
+++ b/src/libjin/Math/Matrix.h
@@ -3,157 +3,157 @@
namespace jin
{
-namespace math
-{
-
- struct vertex
- {
- unsigned char r, g, b, a;
- float x, y;
- float s, t;
- };
- /**
- * This class is the basis for all transformations in LOVE. Althought not
- * really needed for 2D, it contains 4x4 elements to be compatible with
- * OpenGL without conversions.
- * Ҫתõľ
- * https://blog.csdn.net/candycat1992/article/details/8830894
- **/
- class Matrix
- {
- private:
-
- /**
- * | e0 e4 e8 e12 |
- * | e1 e5 e9 e13 |
- * | e2 e6 e10 e14 |
- * | e3 e7 e11 e15 |
- **/
- float e[16];
-
- public:
-
- static const Matrix Identity;
-
- /**
- * Creates a new identity matrix.
- **/
- Matrix();
-
- /**
- * Destructor.
- **/
- ~Matrix();
-
- void setOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far);
-
- /**
- * Multiplies this Matrix with another Matrix, changing neither.
- * @param m The Matrix to multiply with this Matrix.
- * @return The combined matrix.
- **/
- Matrix operator * (const Matrix & m) const;
-
- /**
- * Multiplies a Matrix into this Matrix.
- * @param m The Matrix to combine into this Matrix.
- **/
- void operator *= (const Matrix & m);
-
- /**
- * Gets a pointer to the 16 array elements.
- * @return The array elements.
- **/
- const float * getElements() const;
-
- /**
- * Resets this Matrix to the identity matrix.
- **/
- void setIdentity();
-
- /**
- * Resets this Matrix to a translation.
- * @param x Translation along x-axis.
- * @param y Translation along y-axis.
- **/
- void setTranslation(float x, float y);
-
- /**
- * Resets this Matrix to a rotation.
- * @param r The angle in radians.
- **/
- void setRotation(float r);
-
- /**
- * Resets this Matrix to a scale transformation.
- * @param sx Scale factor along the x-axis.
- * @param sy Scale factor along the y-axis.
- **/
- void setScale(float sx, float sy);
-
- /**
- * Resets this Matrix to a shear transformation.
- * @param kx Shear along x-axis.
- * @param ky Shear along y-axis.
- **/
- void setShear(float kx, float ky);
-
- /**
- * Creates a transformation with a certain position, orientation, scale
- * and offset. Perfect for Drawables -- what a coincidence!
- *
- * @param x The translation along the x-axis.
- * @param y The translation along the y-axis.
- * @param angle The rotation (rad) around the center with offset (ox,oy).
- * @param sx Scale along x-axis.
- * @param sy Scale along y-axis.
- * @param ox The offset for rotation along the x-axis.
- * @param oy The offset for rotation along the y-axis.
- * @param kx Shear along x-axis
- * @param ky Shear along y-axis
- **/
- void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy);
-
- /**
- * Multiplies this Matrix with a translation.
- * @param x Translation along x-axis.
- * @param y Translation along y-axis.
- **/
- void translate(float x, float y);
-
- /**
- * Multiplies this Matrix with a rotation.
- * @param r Angle in radians.
- **/
- void rotate(float r);
-
- /**
- * Multiplies this Matrix with a scale transformation.
- * @param sx Scale factor along the x-axis.
- * @param sy Scale factor along the y-axis.
- **/
- void scale(float sx, float sy);
-
- /**
- * Multiplies this Matrix with a shear transformation.
- * @param kx Shear along the x-axis.
- * @param ky Shear along the y-axis.
- **/
- void shear(float kx, float ky);
-
- /**
- * Transforms an array of vertices by this Matrix. The sources and
- * destination arrays may be the same.
- *
- * @param dst Storage for the transformed vertices.
- * @param src The source vertices.
- * @param size The number of vertices.
- **/
- void transform(vertex * dst, const vertex * src, int size) const;
-
- };
-
-} // math
+ namespace math
+ {
+
+ struct vertex
+ {
+ unsigned char r, g, b, a;
+ float x, y;
+ float s, t;
+ };
+ /**
+ * This class is the basis for all transformations in LOVE. Althought not
+ * really needed for 2D, it contains 4x4 elements to be compatible with
+ * OpenGL without conversions.
+ * Ҫתõľ
+ * https://blog.csdn.net/candycat1992/article/details/8830894
+ **/
+ class Matrix
+ {
+ private:
+
+ /**
+ * | e0 e4 e8 e12 |
+ * | e1 e5 e9 e13 |
+ * | e2 e6 e10 e14 |
+ * | e3 e7 e11 e15 |
+ **/
+ float e[16];
+
+ public:
+
+ static const Matrix Identity;
+
+ /**
+ * Creates a new identity matrix.
+ **/
+ Matrix();
+
+ /**
+ * Destructor.
+ **/
+ ~Matrix();
+
+ void setOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far);
+
+ /**
+ * Multiplies this Matrix with another Matrix, changing neither.
+ * @param m The Matrix to multiply with this Matrix.
+ * @return The combined matrix.
+ **/
+ Matrix operator * (const Matrix & m) const;
+
+ /**
+ * Multiplies a Matrix into this Matrix.
+ * @param m The Matrix to combine into this Matrix.
+ **/
+ void operator *= (const Matrix & m);
+
+ /**
+ * Gets a pointer to the 16 array elements.
+ * @return The array elements.
+ **/
+ const float * getElements() const;
+
+ /**
+ * Resets this Matrix to the identity matrix.
+ **/
+ void setIdentity();
+
+ /**
+ * Resets this Matrix to a translation.
+ * @param x Translation along x-axis.
+ * @param y Translation along y-axis.
+ **/
+ void setTranslation(float x, float y);
+
+ /**
+ * Resets this Matrix to a rotation.
+ * @param r The angle in radians.
+ **/
+ void setRotation(float r);
+
+ /**
+ * Resets this Matrix to a scale transformation.
+ * @param sx Scale factor along the x-axis.
+ * @param sy Scale factor along the y-axis.
+ **/
+ void setScale(float sx, float sy);
+
+ /**
+ * Resets this Matrix to a shear transformation.
+ * @param kx Shear along x-axis.
+ * @param ky Shear along y-axis.
+ **/
+ void setShear(float kx, float ky);
+
+ /**
+ * Creates a transformation with a certain position, orientation, scale
+ * and offset. Perfect for Drawables -- what a coincidence!
+ *
+ * @param x The translation along the x-axis.
+ * @param y The translation along the y-axis.
+ * @param angle The rotation (rad) around the center with offset (ox,oy).
+ * @param sx Scale along x-axis.
+ * @param sy Scale along y-axis.
+ * @param ox The offset for rotation along the x-axis.
+ * @param oy The offset for rotation along the y-axis.
+ * @param kx Shear along x-axis
+ * @param ky Shear along y-axis
+ **/
+ void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy);
+
+ /**
+ * Multiplies this Matrix with a translation.
+ * @param x Translation along x-axis.
+ * @param y Translation along y-axis.
+ **/
+ void translate(float x, float y);
+
+ /**
+ * Multiplies this Matrix with a rotation.
+ * @param r Angle in radians.
+ **/
+ void rotate(float r);
+
+ /**
+ * Multiplies this Matrix with a scale transformation.
+ * @param sx Scale factor along the x-axis.
+ * @param sy Scale factor along the y-axis.
+ **/
+ void scale(float sx, float sy);
+
+ /**
+ * Multiplies this Matrix with a shear transformation.
+ * @param kx Shear along the x-axis.
+ * @param ky Shear along the y-axis.
+ **/
+ void shear(float kx, float ky);
+
+ /**
+ * Transforms an array of vertices by this Matrix. The sources and
+ * destination arrays may be the same.
+ *
+ * @param dst Storage for the transformed vertices.
+ * @param src The source vertices.
+ * @param size The number of vertices.
+ **/
+ void transform(vertex * dst, const vertex * src, int size) const;
+
+ };
+
+ } // math
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/Math/Quad.h b/src/libjin/Math/Quad.h
index ed41270..c649cf7 100644
--- a/src/libjin/Math/Quad.h
+++ b/src/libjin/Math/Quad.h
@@ -3,15 +3,15 @@
namespace jin
{
-namespace math
-{
+ namespace math
+ {
- struct Quad
- {
- float x, y, w, h;
- };
+ struct Quad
+ {
+ float x, y, w, h;
+ };
-} // math
+ } // math
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/Math/Vector2.hpp b/src/libjin/Math/Vector2.hpp
index ddb8221..f0bbfc7 100644
--- a/src/libjin/Math/Vector2.hpp
+++ b/src/libjin/Math/Vector2.hpp
@@ -3,38 +3,38 @@
namespace jin
{
-namespace math
-{
+ namespace math
+ {
- template<typename T>
- class Vector2
- {
- public:
- Vector2()
- {
- data[0] = data[1] = 0;
- }
- Vector2(T _x, T _y)
- {
- data[0] = _x;
- data[1] = _y;
- }
- Vector2(const Vector2<T>& v)
- {
- data[0] = v.data[0];
- data[1] = v.data[1];
- }
+ template<typename T>
+ class Vector2
+ {
+ public:
+ Vector2()
+ {
+ data[0] = data[1] = 0;
+ }
+ Vector2(T _x, T _y)
+ {
+ data[0] = _x;
+ data[1] = _y;
+ }
+ Vector2(const Vector2<T>& v)
+ {
+ data[0] = v.data[0];
+ data[1] = v.data[1];
+ }
- T &x = data[0], &y = data[1]; // xy
- T &w = data[0], &h = data[1]; // wh
- T &colum = data[0], &row = data[1]; // colum row
+ T &x = data[0], &y = data[1]; // xy
+ T &w = data[0], &h = data[1]; // wh
+ T &colum = data[0], &row = data[1]; // colum row
- private:
- T data[2];
+ private:
+ T data[2];
- };
+ };
-} // math
+ } // math
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/Math/Vector3.hpp b/src/libjin/Math/Vector3.hpp
index 77fa006..9b38cad 100644
--- a/src/libjin/Math/Vector3.hpp
+++ b/src/libjin/Math/Vector3.hpp
@@ -3,39 +3,39 @@
namespace jin
{
-namespace math
-{
+ namespace math
+ {
- template<typename T>
- class Vector3
- {
- public:
- Vector3()
- {
- data[0] = data[1] = data[2] = 0;
- }
- Vector3(T _x, T _y, T _z)
- {
- data[0] = _x;
- data[1] = _y;
- data[2] = _z;
- }
- Vector3(const Vector3<T>& v)
- {
- data[0] = v.data[0];
- data[1] = v.data[1];
- data[2] = v.data[2];
- }
+ template<typename T>
+ class Vector3
+ {
+ public:
+ Vector3()
+ {
+ data[0] = data[1] = data[2] = 0;
+ }
+ Vector3(T _x, T _y, T _z)
+ {
+ data[0] = _x;
+ data[1] = _y;
+ data[2] = _z;
+ }
+ Vector3(const Vector3<T>& v)
+ {
+ data[0] = v.data[0];
+ data[1] = v.data[1];
+ data[2] = v.data[2];
+ }
- T &x = data[0], &y = data[1], &z = data[2]; // xyz
- T &r = data[0], &g = data[1], &b = data[2]; // rgb
+ T &x = data[0], &y = data[1], &z = data[2]; // xyz
+ T &r = data[0], &g = data[1], &b = data[2]; // rgb
- private:
- T data[3];
+ private:
+ T data[3];
- };
+ };
-} // math
+ } // math
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/Math/Vector4.hpp b/src/libjin/Math/Vector4.hpp
index da4110f..e2978d4 100644
--- a/src/libjin/Math/Vector4.hpp
+++ b/src/libjin/Math/Vector4.hpp
@@ -3,43 +3,43 @@
namespace jin
{
-namespace math
-{
+ namespace math
+ {
- template<typename T>
- class Vector4
- {
- public:
- Vector4()
- {
- data[0] = data[1] = data[2] = data[3] = 0;
- }
- Vector4(T _x, T _y, T _z, T _t)
- {
- data[0] = _x;
- data[1] = _y;
- data[2] = _z;
- data[3] = _t;
- }
- Vector4(const Vector4<T>& v)
- {
- data[0] = v.data[0];
- data[1] = v.data[1];
- data[2] = v.data[2];
- data[3] = v.data[3];
- }
+ template<typename T>
+ class Vector4
+ {
+ public:
+ Vector4()
+ {
+ data[0] = data[1] = data[2] = data[3] = 0;
+ }
+ Vector4(T _x, T _y, T _z, T _t)
+ {
+ data[0] = _x;
+ data[1] = _y;
+ data[2] = _z;
+ data[3] = _t;
+ }
+ Vector4(const Vector4<T>& v)
+ {
+ data[0] = v.data[0];
+ data[1] = v.data[1];
+ data[2] = v.data[2];
+ data[3] = v.data[3];
+ }
- T &x = data[0], &y = data[1], &z = data[2], &t = data[3]; // xyzt
- T &w = data[2], &h = data[3]; // xywh
- T &r = data[0], &g = data[1], &b = data[2], &a = data[3]; // rgb
- T &left = data[0], &right = data[1], &top = data[2], &bottom = data[3]; // lrtb
+ T &x = data[0], &y = data[1], &z = data[2], &t = data[3]; // xyzt
+ T &w = data[2], &h = data[3]; // xywh
+ T &r = data[0], &g = data[1], &b = data[2], &a = data[3]; // rgb
+ T &left = data[0], &right = data[1], &top = data[2], &bottom = data[3]; // lrtb
- private:
- T data[4];
+ private:
+ T data[4];
- };
+ };
-} // math
+ } // math
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/Net/Net.cpp b/src/libjin/Net/Net.cpp
index e6c3d98..8fd4256 100644
--- a/src/libjin/Net/Net.cpp
+++ b/src/libjin/Net/Net.cpp
@@ -2,23 +2,23 @@
namespace jin
{
-namespace net
-{
+ namespace net
+ {
- bool Net::initSystem(const SettingBase* setting)
- {
- #ifdef _WIN32
- #if LIBJIN_NET_TEKCOS
- tk_init();
- #endif
- #endif
- return true;
- }
+ bool Net::initSystem(const SettingBase* setting)
+ {
+ #ifdef _WIN32
+ #if LIBJIN_NET_TEKCOS
+ tk_init();
+ #endif
+ #endif
+ return true;
+ }
- void Net::quitSystem()
- {
+ void Net::quitSystem()
+ {
- }
+ }
-} // net
+ } // net
} // jin \ No newline at end of file
diff --git a/src/libjin/Net/Net.h b/src/libjin/Net/Net.h
index 27353dc..b5f999f 100644
--- a/src/libjin/Net/Net.h
+++ b/src/libjin/Net/Net.h
@@ -8,23 +8,23 @@
namespace jin
{
-namespace net
-{
+ namespace net
+ {
- class Net : public Subsystem<Net>
- {
- public:
+ class Net : public Subsystem<Net>
+ {
+ public:
- protected:
- SINGLETON(Net);
- Net() {};
- ~Net() {};
- bool initSystem(const SettingBase* setting) override;
- void quitSystem() override;
+ protected:
+ SINGLETON(Net);
+ Net() {};
+ ~Net() {};
+ bool initSystem(const SettingBase* setting) override;
+ void quitSystem() override;
- };
+ };
-} // net
+ } // net
} // jin
#endif // LIBJIN_MODULES_NET
diff --git a/src/libjin/Net/Socket.cpp b/src/libjin/Net/Socket.cpp
index 32d160c..2a1454b 100644
--- a/src/libjin/Net/Socket.cpp
+++ b/src/libjin/Net/Socket.cpp
@@ -2,189 +2,189 @@
namespace jin
{
-namespace net
-{
- Socket::Socket(const Socket& socket)
- : handle(socket.handle)
- , type(socket.type)
- {
- }
-
- Socket::Socket(const SocketInformation& info)
- : type(info.type)
- {
- if (type == SocketType::TCP)
- {
- tk_IPaddress ip;
- ip.host = info.address;
- ip.port = info.port;
- handle.tcpHandle = tk_tcp_open(ip);
- }
- else if (type == SocketType::UDP)
- {
- handle.udpHandle = tk_udp_open(info.port);
- }
- }
-
- Socket::Socket(SocketType type, const char* address, unsigned short port)
- {
- this->type = type;
- if (type == SocketType::TCP)
- {
- tk_IPaddress ip;
- #if LIBJIN_NET_TEKCOS
- ip.host = tk_strtohl(address);
- ip.port = port;
- handle.tcpHandle = tk_tcp_open(ip);
- #endif
- }
- else if (type == SocketType::UDP)
- {
- handle.udpHandle = tk_udp_open(port);
- }
- }
-
- Socket::Socket(SocketType type, unsigned int address, unsigned short port)
- {
- this->type = type;
- if (type == SocketType::TCP)
- {
- tk_IPaddress ip;
- ip.host = address;
- ip.port = port;
- handle.tcpHandle = tk_tcp_open(ip);
- }
- else if (type == SocketType::UDP)
- {
- handle.udpHandle = tk_udp_open(port);
- }
- }
-
- Socket::Socket(SocketType type, unsigned short port)
- {
- this->type = type;
- if (type == SocketType::TCP)
- {
- tk_IPaddress ip;
- ip.host = 0;
- ip.port = port;
- handle.tcpHandle = tk_tcp_open(ip);
- }
- else if (type == SocketType::UDP)
- {
- handle.udpHandle = tk_udp_open(port);
- }
- }
-
-#if LIBJIN_NET_TEKCOS
-
- Socket::Socket(const tk_TCPsocket& tcphandle)
- {
- handle.tcpHandle = tcphandle;
- }
-
- Socket::Socket(const tk_UDPsocket& udphandle)
- {
- handle.udpHandle = udphandle;
- }
-
-#endif // LIBJIN_NET_TEKCOS
-
- Socket::~Socket()
- {
- }
-
- void Socket::configureBlocking(bool blocking)
- {
- if (type != SocketType::TCP)
- return;
- #if LIBJIN_NET_TEKCOS
- if (blocking)
- tk_tcp_blocking(&handle.tcpHandle);
- else
- tk_tcp_nonblocking(&handle.tcpHandle);
- #endif
- }
-
- Socket* Socket::accept()
- {
- if (type != SocketType::TCP)
- return nullptr;
- Socket* client;
- #if LIBJIN_NET_TEKCOS
- tk_TCPsocket socket = tk_tcp_accept(&handle.tcpHandle);
- client = new Socket(socket);
- #endif
- return client;
- }
-
- int Socket::receive(char* buffer, int size)
- {
- if (type != SocketType::TCP)
- return 0;
- #if LIBJIN_NET_TEKCOS
- int len;
- tk_tcp_recv(&handle.tcpHandle, buffer, size, &len);
- return len;
- #endif
- }
+ namespace net
+ {
+ Socket::Socket(const Socket& socket)
+ : handle(socket.handle)
+ , type(socket.type)
+ {
+ }
+
+ Socket::Socket(const SocketInformation& info)
+ : type(info.type)
+ {
+ if (type == SocketType::TCP)
+ {
+ tk_IPaddress ip;
+ ip.host = info.address;
+ ip.port = info.port;
+ handle.tcpHandle = tk_tcp_open(ip);
+ }
+ else if (type == SocketType::UDP)
+ {
+ handle.udpHandle = tk_udp_open(info.port);
+ }
+ }
+
+ Socket::Socket(SocketType type, const char* address, unsigned short port)
+ {
+ this->type = type;
+ if (type == SocketType::TCP)
+ {
+ tk_IPaddress ip;
+ #if LIBJIN_NET_TEKCOS
+ ip.host = tk_strtohl(address);
+ ip.port = port;
+ handle.tcpHandle = tk_tcp_open(ip);
+ #endif
+ }
+ else if (type == SocketType::UDP)
+ {
+ handle.udpHandle = tk_udp_open(port);
+ }
+ }
+
+ Socket::Socket(SocketType type, unsigned int address, unsigned short port)
+ {
+ this->type = type;
+ if (type == SocketType::TCP)
+ {
+ tk_IPaddress ip;
+ ip.host = address;
+ ip.port = port;
+ handle.tcpHandle = tk_tcp_open(ip);
+ }
+ else if (type == SocketType::UDP)
+ {
+ handle.udpHandle = tk_udp_open(port);
+ }
+ }
+
+ Socket::Socket(SocketType type, unsigned short port)
+ {
+ this->type = type;
+ if (type == SocketType::TCP)
+ {
+ tk_IPaddress ip;
+ ip.host = 0;
+ ip.port = port;
+ handle.tcpHandle = tk_tcp_open(ip);
+ }
+ else if (type == SocketType::UDP)
+ {
+ handle.udpHandle = tk_udp_open(port);
+ }
+ }
+
+ #if LIBJIN_NET_TEKCOS
+
+ Socket::Socket(const tk_TCPsocket& tcphandle)
+ {
+ handle.tcpHandle = tcphandle;
+ }
+
+ Socket::Socket(const tk_UDPsocket& udphandle)
+ {
+ handle.udpHandle = udphandle;
+ }
+
+ #endif // LIBJIN_NET_TEKCOS
+
+ Socket::~Socket()
+ {
+ }
+
+ void Socket::configureBlocking(bool blocking)
+ {
+ if (type != SocketType::TCP)
+ return;
+ #if LIBJIN_NET_TEKCOS
+ if (blocking)
+ tk_tcp_blocking(&handle.tcpHandle);
+ else
+ tk_tcp_nonblocking(&handle.tcpHandle);
+ #endif
+ }
+
+ Socket* Socket::accept()
+ {
+ if (type != SocketType::TCP)
+ return nullptr;
+ Socket* client;
+ #if LIBJIN_NET_TEKCOS
+ tk_TCPsocket socket = tk_tcp_accept(&handle.tcpHandle);
+ client = new Socket(socket);
+ #endif
+ return client;
+ }
+
+ int Socket::receive(char* buffer, int size)
+ {
+ if (type != SocketType::TCP)
+ return 0;
+ #if LIBJIN_NET_TEKCOS
+ int len;
+ tk_tcp_recv(&handle.tcpHandle, buffer, size, &len);
+ return len;
+ #endif
+ }
- int Socket::send(char* buffer, int size)
- {
- if (type != SocketType::TCP)
- return 0;
- #if LIBJIN_NET_TEKCOS
- int len;
- tk_tcp_send(&handle.tcpHandle, buffer, size, &len);
- return len;
- #endif
- }
-
- void Socket::sendTo(char* buffer, int size, unsigned int address, unsigned int port)
- {
- if (type != SocketType::UDP)
- return;
- #if LIBJIN_NET_TEKCOS
- tk_UDPpack pack;
- pack.data = buffer;
- pack.len = size;
- pack.ip.host = address;
- pack.ip.port = port;
- tk_udp_sendto(&handle.udpHandle, &pack);
- #endif
- }
+ int Socket::send(char* buffer, int size)
+ {
+ if (type != SocketType::TCP)
+ return 0;
+ #if LIBJIN_NET_TEKCOS
+ int len;
+ tk_tcp_send(&handle.tcpHandle, buffer, size, &len);
+ return len;
+ #endif
+ }
+
+ void Socket::sendTo(char* buffer, int size, unsigned int address, unsigned int port)
+ {
+ if (type != SocketType::UDP)
+ return;
+ #if LIBJIN_NET_TEKCOS
+ tk_UDPpack pack;
+ pack.data = buffer;
+ pack.len = size;
+ pack.ip.host = address;
+ pack.ip.port = port;
+ tk_udp_sendto(&handle.udpHandle, &pack);
+ #endif
+ }
- int Socket::receiveFrom(char* buffer, int size, unsigned int address, unsigned int port)
- {
- if (type != SocketType::UDP)
- return 0;
- int len;
- #if LIBJIN_NET_TEKCOS
- tk_UDPpack pack;
- pack.data = buffer;
- pack.len = size;
- pack.ip.host = address;
- pack.ip.port = port;
- tk_udp_recvfrom(&handle.udpHandle, &pack);
- return pack.len;
- #endif
- }
-
- void Socket::close()
- {
- if (type == SocketType::TCP)
- {
- #if LIBJIN_NET_TEKCOS
- tk_tcp_close(&handle.tcpHandle);
- #endif
- }
- else if (type == SocketType::UDP)
- {
- #if LIBJIN_NET_TEKCOS
- tk_udp_close(&handle.udpHandle);
- #endif
- }
- }
-
-} // net
+ int Socket::receiveFrom(char* buffer, int size, unsigned int address, unsigned int port)
+ {
+ if (type != SocketType::UDP)
+ return 0;
+ int len;
+ #if LIBJIN_NET_TEKCOS
+ tk_UDPpack pack;
+ pack.data = buffer;
+ pack.len = size;
+ pack.ip.host = address;
+ pack.ip.port = port;
+ tk_udp_recvfrom(&handle.udpHandle, &pack);
+ return pack.len;
+ #endif
+ }
+
+ void Socket::close()
+ {
+ if (type == SocketType::TCP)
+ {
+ #if LIBJIN_NET_TEKCOS
+ tk_tcp_close(&handle.tcpHandle);
+ #endif
+ }
+ else if (type == SocketType::UDP)
+ {
+ #if LIBJIN_NET_TEKCOS
+ tk_udp_close(&handle.udpHandle);
+ #endif
+ }
+ }
+
+ } // net
} // jin \ No newline at end of file
diff --git a/src/libjin/Net/Socket.h b/src/libjin/Net/Socket.h
index 32ef86f..ad2ce60 100644
--- a/src/libjin/Net/Socket.h
+++ b/src/libjin/Net/Socket.h
@@ -7,55 +7,55 @@
namespace jin
{
-namespace net
-{
-
- enum SocketType
- {
- TCP,
- UDP
- };
-
- struct SocketInformation
- {
- unsigned int address;
- unsigned short port;
- SocketType type;
- };
-
- class Socket
- {
- public:
- Socket() {};
- Socket(const Socket& socket);
- Socket(const SocketInformation& socketInformation);
- Socket(SocketType type, unsigned short port);
- Socket(SocketType type, unsigned int address, unsigned short port);
- Socket(SocketType type, const char* address, unsigned short port);
- ~Socket();
- void configureBlocking(bool bocking);
- Socket* accept();
- int receive(char* buffer, int size);
- int send(char* buffer, int size);
- void sendTo(char* buffer, int size, unsigned int address, unsigned int port);
- int receiveFrom(char* buffer, int size, unsigned int address, unsigned int port);
- void close();
+ namespace net
+ {
+
+ enum SocketType
+ {
+ TCP,
+ UDP
+ };
+
+ struct SocketInformation
+ {
+ unsigned int address;
+ unsigned short port;
+ SocketType type;
+ };
+
+ class Socket
+ {
+ public:
+ Socket() {};
+ Socket(const Socket& socket);
+ Socket(const SocketInformation& socketInformation);
+ Socket(SocketType type, unsigned short port);
+ Socket(SocketType type, unsigned int address, unsigned short port);
+ Socket(SocketType type, const char* address, unsigned short port);
+ ~Socket();
+ void configureBlocking(bool bocking);
+ Socket* accept();
+ int receive(char* buffer, int size);
+ int send(char* buffer, int size);
+ void sendTo(char* buffer, int size, unsigned int address, unsigned int port);
+ int receiveFrom(char* buffer, int size, unsigned int address, unsigned int port);
+ void close();
- protected:
- #if LIBJIN_NET_TEKCOS
- Socket(const tk_TCPsocket& tcpHandle);
- Socket(const tk_UDPsocket& udpHandle);
- union
- {
- tk_TCPsocket tcpHandle;
- tk_UDPsocket udpHandle;
- } handle;
- #endif
- SocketType type;
-
- };
-
-} // net
+ protected:
+ #if LIBJIN_NET_TEKCOS
+ Socket(const tk_TCPsocket& tcpHandle);
+ Socket(const tk_UDPsocket& udpHandle);
+ union
+ {
+ tk_TCPsocket tcpHandle;
+ tk_UDPsocket udpHandle;
+ } handle;
+ #endif
+ SocketType type;
+
+ };
+
+ } // net
} // jin
#endif // LIBJIN_MODULES_NET
diff --git a/src/libjin/Net/net.cpp b/src/libjin/Net/net.cpp
index e6c3d98..8fd4256 100644
--- a/src/libjin/Net/net.cpp
+++ b/src/libjin/Net/net.cpp
@@ -2,23 +2,23 @@
namespace jin
{
-namespace net
-{
+ namespace net
+ {
- bool Net::initSystem(const SettingBase* setting)
- {
- #ifdef _WIN32
- #if LIBJIN_NET_TEKCOS
- tk_init();
- #endif
- #endif
- return true;
- }
+ bool Net::initSystem(const SettingBase* setting)
+ {
+ #ifdef _WIN32
+ #if LIBJIN_NET_TEKCOS
+ tk_init();
+ #endif
+ #endif
+ return true;
+ }
- void Net::quitSystem()
- {
+ void Net::quitSystem()
+ {
- }
+ }
-} // net
+ } // net
} // jin \ No newline at end of file
diff --git a/src/libjin/Net/net.h b/src/libjin/Net/net.h
index 27353dc..b5f999f 100644
--- a/src/libjin/Net/net.h
+++ b/src/libjin/Net/net.h
@@ -8,23 +8,23 @@
namespace jin
{
-namespace net
-{
+ namespace net
+ {
- class Net : public Subsystem<Net>
- {
- public:
+ class Net : public Subsystem<Net>
+ {
+ public:
- protected:
- SINGLETON(Net);
- Net() {};
- ~Net() {};
- bool initSystem(const SettingBase* setting) override;
- void quitSystem() override;
+ protected:
+ SINGLETON(Net);
+ Net() {};
+ ~Net() {};
+ bool initSystem(const SettingBase* setting) override;
+ void quitSystem() override;
- };
+ };
-} // net
+ } // net
} // jin
#endif // LIBJIN_MODULES_NET
diff --git a/src/libjin/Thread/Thread.cpp b/src/libjin/Thread/Thread.cpp
index 971fc03..0703f1b 100644
--- a/src/libjin/Thread/Thread.cpp
+++ b/src/libjin/Thread/Thread.cpp
@@ -5,297 +5,297 @@
namespace jin
{
-namespace thread
-{
-
- class Mutex
- {
- public:
- Mutex();
- ~Mutex();
-
- void lock();
- void unlock();
- private:
- #if LIBJIN_THREAD_SDL
- SDL_mutex* mutex;
- #endif
- friend class Conditional;
- };
-
- // ̼߳signal wait
- class Conditional
- {
- public:
- Conditional();
- ~Conditional();
- void signal();
- void broadcast();
- bool wait(Mutex* mutex, int timeout = -1);
- private:
- #if LIBJIN_THREAD_SDL
- SDL_cond* cond;
- #endif
- };
-
- class Lock
- {
- public:
- Lock(Mutex* m) : mutex(m) {
- mutex->lock();
- }
-
- Lock(Mutex& m) : mutex(&m) {
- mutex->lock();
- }
-
- ~Lock() {
- mutex->unlock();
- }
- private:
- Mutex* mutex;
-
- Lock(Lock&) {}
-
- };
-
- //////////////////////////////////////////////////////////////////////
+ namespace thread
+ {
+
+ class Mutex
+ {
+ public:
+ Mutex();
+ ~Mutex();
+
+ void lock();
+ void unlock();
+ private:
+ #if LIBJIN_THREAD_SDL
+ SDL_mutex* mutex;
+ #endif
+ friend class Conditional;
+ };
+
+ // ̼߳signal wait
+ class Conditional
+ {
+ public:
+ Conditional();
+ ~Conditional();
+ void signal();
+ void broadcast();
+ bool wait(Mutex* mutex, int timeout = -1);
+ private:
+ #if LIBJIN_THREAD_SDL
+ SDL_cond* cond;
+ #endif
+ };
+
+ class Lock
+ {
+ public:
+ Lock(Mutex* m) : mutex(m) {
+ mutex->lock();
+ }
+
+ Lock(Mutex& m) : mutex(&m) {
+ mutex->lock();
+ }
+
+ ~Lock() {
+ mutex->unlock();
+ }
+ private:
+ Mutex* mutex;
+
+ Lock(Lock&) {}
+
+ };
+
+ //////////////////////////////////////////////////////////////////////
- Mutex::Mutex()
- {
- #if LIBJIN_THREAD_SDL
- mutex = SDL_CreateMutex();
- #endif
- }
-
- Mutex::~Mutex()
- {
- #if LIBJIN_THREAD_SDL
- SDL_DestroyMutex(mutex);
- #endif
- }
-
- void Mutex::lock()
- {
- #if LIBJIN_THREAD_SDL
- SDL_LockMutex(mutex);
- #endif
- }
-
- void Mutex::unlock()
- {
- #if LIBJIN_THREAD_SDL
- SDL_UnlockMutex(mutex);
- #endif
- }
-
- //////////////////////////////////////////////////////////////////////
-
- Conditional::Conditional()
- {
- #if LIBJIN_THREAD_SDL
- cond = SDL_CreateCond();
- #endif
- }
-
- Conditional::~Conditional()
- {
- #if LIBJIN_THREAD_SDL
- SDL_DestroyCond(cond);
- #endif
- }
-
- void Conditional::signal()
- {
- #if LIBJIN_THREAD_SDL
- SDL_CondSignal(cond);
- #endif
- }
-
- void Conditional::broadcast()
- {
- #if LIBJIN_THREAD_SDL
- SDL_CondBroadcast(cond);
- #endif
- }
-
- bool Conditional::wait(Mutex* mutex, int timeout)
- {
- #if LIBJIN_THREAD_SDL
- if (timeout < 0)
- return !SDL_CondWait(cond, mutex->mutex);
- else
- return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0);
- #endif
- }
+ Mutex::Mutex()
+ {
+ #if LIBJIN_THREAD_SDL
+ mutex = SDL_CreateMutex();
+ #endif
+ }
+
+ Mutex::~Mutex()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_DestroyMutex(mutex);
+ #endif
+ }
+
+ void Mutex::lock()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_LockMutex(mutex);
+ #endif
+ }
+
+ void Mutex::unlock()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_UnlockMutex(mutex);
+ #endif
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ Conditional::Conditional()
+ {
+ #if LIBJIN_THREAD_SDL
+ cond = SDL_CreateCond();
+ #endif
+ }
+
+ Conditional::~Conditional()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_DestroyCond(cond);
+ #endif
+ }
+
+ void Conditional::signal()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_CondSignal(cond);
+ #endif
+ }
+
+ void Conditional::broadcast()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_CondBroadcast(cond);
+ #endif
+ }
+
+ bool Conditional::wait(Mutex* mutex, int timeout)
+ {
+ #if LIBJIN_THREAD_SDL
+ if (timeout < 0)
+ return !SDL_CondWait(cond, mutex->mutex);
+ else
+ return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0);
+ #endif
+ }
- //////////////////////////////////////////////////////////////////////
-
- Thread::ThreadData::ThreadData(Mutex* m, Conditional* c)
- : mutex(m)
- , condition(c)
- , share()
- {
- }
-
- Thread::ThreadData::~ThreadData()
- {
- }
-
- void Thread::ThreadData::set(int slot, Variant value)
- {
- Lock l(mutex);
- share[slot] = value;
- }
-
- Thread::Variant Thread::ThreadData::get(int slot)
- {
- Lock l(mutex);
- return share[slot];
- }
-
- bool Thread::ThreadData::exist(int slot)
- {
- Lock l(mutex);
- return share.count(slot) == 1;
- }
-
- void Thread::ThreadData::remove(int slot)
- {
- Lock l(mutex);
- if (exist(slot))
- {
- share.erase(slot);
- }
- }
-
- //////////////////////////////////////////////////////////////////////
-
- Thread::Thread(const std::string tname, ThreadRunner runner)
- : name(tname)
- , running(false)
- , threadRunner(runner)
- {
- mutex = new Mutex();
- condition = new Conditional();
- common = new Thread::ThreadData(mutex, condition);
- }
-
- Thread::~Thread()
- {
- #if LIBJIN_THREAD_SDL
- #endif
- }
-
- const char* Thread::getName()
- {
- Lock l(mutex);
- return name.c_str();
- };
+ //////////////////////////////////////////////////////////////////////
+
+ Thread::ThreadData::ThreadData(Mutex* m, Conditional* c)
+ : mutex(m)
+ , condition(c)
+ , share()
+ {
+ }
+
+ Thread::ThreadData::~ThreadData()
+ {
+ }
+
+ void Thread::ThreadData::set(int slot, Variant value)
+ {
+ Lock l(mutex);
+ share[slot] = value;
+ }
+
+ Thread::Variant Thread::ThreadData::get(int slot)
+ {
+ Lock l(mutex);
+ return share[slot];
+ }
+
+ bool Thread::ThreadData::exist(int slot)
+ {
+ Lock l(mutex);
+ return share.count(slot) == 1;
+ }
+
+ void Thread::ThreadData::remove(int slot)
+ {
+ Lock l(mutex);
+ if (exist(slot))
+ {
+ share.erase(slot);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ Thread::Thread(const std::string tname, ThreadRunner runner)
+ : name(tname)
+ , running(false)
+ , threadRunner(runner)
+ {
+ mutex = new Mutex();
+ condition = new Conditional();
+ common = new Thread::ThreadData(mutex, condition);
+ }
+
+ Thread::~Thread()
+ {
+ #if LIBJIN_THREAD_SDL
+ #endif
+ }
+
+ const char* Thread::getName()
+ {
+ Lock l(mutex);
+ return name.c_str();
+ };
- bool Thread::isRunning()
- {
- Lock l(mutex);
- return running;
- };
-
- bool Thread::start(void* p)
- {
- Lock l(mutex);
- if (running)
- return false;
- if (handle)
- {
- #if LIBJIN_THREAD_SDL
- SDL_WaitThread(handle, nullptr);
- #endif
- }
- #if LIBJIN_THREAD_SDL
- handle = SDL_CreateThread(threadRunner, name.c_str(), p);
- #elif LIBJIN_THREAD_CPP
- handle = new std::thread();
- #endif
- return (running = (handle != nullptr));
- }
-
- void Thread::wait()
- {
- {
- Lock l(mutex);
- if (!handle)
- return;
- }
- #if LIBJIN_THREAD_SDL
- SDL_WaitThread(handle, nullptr);
- #endif
- Lock l(mutex);
- running = false;
- handle = nullptr;
- }
-
- void Thread::lock()
- {
- if (mutex != nullptr)
- mutex->lock();
- }
-
- void Thread::unlock()
- {
- if (mutex != nullptr)
- mutex->unlock();
- }
-
- void Thread::send(int slot, const Variant& value)
- {
- lock();
- common->set(slot, value);
- unlock();
- condition->broadcast();
- }
-
- bool Thread::receive(int slot)
- {
- return common->exist(slot);
- }
-
- Thread::Variant Thread::fetch(int slot)
- {
- Thread::Variant v = common->get(slot);
- return v;
- }
-
- Thread::Variant Thread::demand(int slot)
- {
- /**
- * pthread_mutex_lock(mtx);
- * while(pass == 0)
- * {
- * pthread_mutex_unlock(mtx);
- * pthread_cond_just_wait(cv);
- * pthread_mutex_lock(mtx);
- * }
- * pthread_mutex_unlock(mtx);
- */
- lock();
- while (!common->exist(slot))
- {
- if (common->exist(ThreadData::SLOT_ERROR))
- return 0;
- condition->wait(mutex);
- }
- Thread::Variant v = common->get(slot);
- unlock();
- return v;
- }
-
- void Thread::remove(int slot)
- {
- lock();
- common->remove(slot);
- unlock();
- }
-
-} // thread
+ bool Thread::isRunning()
+ {
+ Lock l(mutex);
+ return running;
+ };
+
+ bool Thread::start(void* p)
+ {
+ Lock l(mutex);
+ if (running)
+ return false;
+ if (handle)
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_WaitThread(handle, nullptr);
+ #endif
+ }
+ #if LIBJIN_THREAD_SDL
+ handle = SDL_CreateThread(threadRunner, name.c_str(), p);
+ #elif LIBJIN_THREAD_CPP
+ handle = new std::thread();
+ #endif
+ return (running = (handle != nullptr));
+ }
+
+ void Thread::wait()
+ {
+ {
+ Lock l(mutex);
+ if (!handle)
+ return;
+ }
+ #if LIBJIN_THREAD_SDL
+ SDL_WaitThread(handle, nullptr);
+ #endif
+ Lock l(mutex);
+ running = false;
+ handle = nullptr;
+ }
+
+ void Thread::lock()
+ {
+ if (mutex != nullptr)
+ mutex->lock();
+ }
+
+ void Thread::unlock()
+ {
+ if (mutex != nullptr)
+ mutex->unlock();
+ }
+
+ void Thread::send(int slot, const Variant& value)
+ {
+ lock();
+ common->set(slot, value);
+ unlock();
+ condition->broadcast();
+ }
+
+ bool Thread::receive(int slot)
+ {
+ return common->exist(slot);
+ }
+
+ Thread::Variant Thread::fetch(int slot)
+ {
+ Thread::Variant v = common->get(slot);
+ return v;
+ }
+
+ Thread::Variant Thread::demand(int slot)
+ {
+ /**
+ * pthread_mutex_lock(mtx);
+ * while(pass == 0)
+ * {
+ * pthread_mutex_unlock(mtx);
+ * pthread_cond_just_wait(cv);
+ * pthread_mutex_lock(mtx);
+ * }
+ * pthread_mutex_unlock(mtx);
+ */
+ lock();
+ while (!common->exist(slot))
+ {
+ if (common->exist(ThreadData::SLOT_ERROR))
+ return 0;
+ condition->wait(mutex);
+ }
+ Thread::Variant v = common->get(slot);
+ unlock();
+ return v;
+ }
+
+ void Thread::remove(int slot)
+ {
+ lock();
+ common->remove(slot);
+ unlock();
+ }
+
+ } // thread
} // jin
#endif // LIBJIN_MODULES_THREAD \ No newline at end of file
diff --git a/src/libjin/Thread/Thread.h b/src/libjin/Thread/Thread.h
index 3a7b4ba..d6d0a19 100644
--- a/src/libjin/Thread/Thread.h
+++ b/src/libjin/Thread/Thread.h
@@ -15,151 +15,151 @@
namespace jin
{
-namespace thread
-{
- /**
- * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ
- * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ
- * ָһԹԴзʵĴ룬һֻƻ㷨һ򡢽̡߳̿ӵжٽ򣬵Dz
- * һӦûҪ˻ƵԴУꡢСжϴڶеĴ
- * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ
- * ߣ߻ָѣ
- */
- class Mutex;
- class Conditional;
+ namespace thread
+ {
+ /**
+ * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ
+ * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ
+ * ָһԹԴзʵĴ룬һֻƻ㷨һ򡢽̡߳̿ӵжٽ򣬵Dz
+ * һӦûҪ˻ƵԴУꡢСжϴڶеĴ
+ * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ
+ * ߣ߻ָѣ
+ */
+ class Mutex;
+ class Conditional;
- /**
- * Thread::demand Receive a message from a thread. Wait for the message to exist before returning.
- * Thread::getName Get the name of a thread.
- * Thread::kill Forcefully terminate the thread.
- * Thread::peek Receive a message from a thread, but leave it in the message box.
- * Thread::receive Receive a message from a thread.
- * Thread::send Send a message.
- * Thread::set Set a value.
- * Thread::start Starts the thread.
- * Thread::wait Wait for a thread to finish.
- */
- class Thread
- {
- public:
- struct Variant
- {
- enum Type
- {
- NONE = 0,
- INTERGER,
- BOOLEAN,
- CHARACTER,
- CSTRING,
- POINTER,
- REAL,
- };
- Type type;
- union
- {
- int integer;
- bool boolean;
- char character;
- const char* cstring;
- void* pointer;
- float real;
- };
- Variant() :type(NONE) {};
- Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); }
- Variant(int i) : integer(i), type(INTERGER) {};
- Variant(float f) : real(f), type(REAL) {};
- Variant(bool b) : boolean(b), type(BOOLEAN) {};
- Variant(char c) : character(c), type(CHARACTER) {};
- Variant(const char* s) : cstring(s), type(CSTRING) {};
- Variant(void* p) : pointer(p), type(POINTER) {};
- };
+ /**
+ * Thread::demand Receive a message from a thread. Wait for the message to exist before returning.
+ * Thread::getName Get the name of a thread.
+ * Thread::kill Forcefully terminate the thread.
+ * Thread::peek Receive a message from a thread, but leave it in the message box.
+ * Thread::receive Receive a message from a thread.
+ * Thread::send Send a message.
+ * Thread::set Set a value.
+ * Thread::start Starts the thread.
+ * Thread::wait Wait for a thread to finish.
+ */
+ class Thread
+ {
+ public:
+ struct Variant
+ {
+ enum Type
+ {
+ NONE = 0,
+ INTERGER,
+ BOOLEAN,
+ CHARACTER,
+ CSTRING,
+ POINTER,
+ REAL,
+ };
+ Type type;
+ union
+ {
+ int integer;
+ bool boolean;
+ char character;
+ const char* cstring;
+ void* pointer;
+ float real;
+ };
+ Variant() :type(NONE) {};
+ Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); }
+ Variant(int i) : integer(i), type(INTERGER) {};
+ Variant(float f) : real(f), type(REAL) {};
+ Variant(bool b) : boolean(b), type(BOOLEAN) {};
+ Variant(char c) : character(c), type(CHARACTER) {};
+ Variant(const char* s) : cstring(s), type(CSTRING) {};
+ Variant(void* p) : pointer(p), type(POINTER) {};
+ };
- private:
- class ThreadData
- {
- public:
- static const int SLOT_ERROR = -1;
- static const int SLOT_WARN = -2;
- static const int SLOT_INFO = -3;
- static const int SLOT_DEBUG = -4;
+ private:
+ class ThreadData
+ {
+ public:
+ static const int SLOT_ERROR = -1;
+ static const int SLOT_WARN = -2;
+ static const int SLOT_INFO = -3;
+ static const int SLOT_DEBUG = -4;
- ThreadData(Mutex*, Conditional*);
- ~ThreadData();
- bool exist(int slot);
- void set(int slot, Variant value);
- Variant get(int slot);
- void remove(int slot);
+ ThreadData(Mutex*, Conditional*);
+ ~ThreadData();
+ bool exist(int slot);
+ void set(int slot, Variant value);
+ Variant get(int slot);
+ void remove(int slot);
- Conditional* condition;
- Mutex* mutex;
+ Conditional* condition;
+ Mutex* mutex;
- private:
- std::map<int, Variant> share; // threads shared value
+ private:
+ std::map<int, Variant> share; // threads shared value
- };
+ };
- public:
- typedef int(*ThreadRunner)(void* obj);
+ public:
+ typedef int(*ThreadRunner)(void* obj);
- Thread(const std::string name, ThreadRunner threadfuncs);
- ~Thread();
- bool start(void* p);
- void wait();
- void send(int slot, const Variant& value);
- bool receive(int slot);
- Variant fetch(int slot);
- Variant demand(int slot);
- void remove(int slot);
- const char* getName();
- bool isRunning();
- void lock();
- void unlock();
+ Thread(const std::string name, ThreadRunner threadfuncs);
+ ~Thread();
+ bool start(void* p);
+ void wait();
+ void send(int slot, const Variant& value);
+ bool receive(int slot);
+ Variant fetch(int slot);
+ Variant demand(int slot);
+ void remove(int slot);
+ const char* getName();
+ bool isRunning();
+ void lock();
+ void unlock();
- protected:
- #if LIBJIN_THREAD_SDL
- SDL_Thread* handle; // SDL thread
- #elif LIBJIN_THREAD_CPP
- std::thread* handle; // cpp thread
- #endif
- Mutex* mutex; // mutex variable
- Conditional* condition; // condition variable
- ThreadRunner threadRunner; // thread function
- ThreadData* common; // threads common data
- const std::string name; // thread name, for debugging purposes
- /**
- * https://stackoverflow.com/questions/149932/naming-conventions-for-threads
- *
- * Use short names because they don't make the lines in a log file too long.
- *
- * Create names where the important part is at the beginning. Log viewers in a
- * graphical user interface tend to have tables with columns, and the thread
- * column is usually small or will be made small by you to read everything else.
- *
- * Do not use the word "thread" in the thread name because it is obvious.
- *
- * Make the thread names easily grep-able. Avoid similar sounding thread names
- *
- * If you have several threads of the same nature, enumerate them with IDs that
- * are unique to one execution of the application or one log file, whichever fits
- * your logging habits.
- *
- * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker
- * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or
- * "Calculation" (what does it calculate?).
- *
- * If you have a test group that uses thread names to grep your application's log
- * files, do not rename your threads after some time. Your testers will hate you for
- * doing so. Thread names in well-tested applications should be there to stay.
- *
- * When you have threads that service a network connection, try to include the target
- * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about
- * enumeration though if there are multiple connections to the same host.
- */
- bool running; // running
+ protected:
+ #if LIBJIN_THREAD_SDL
+ SDL_Thread* handle; // SDL thread
+ #elif LIBJIN_THREAD_CPP
+ std::thread* handle; // cpp thread
+ #endif
+ Mutex* mutex; // mutex variable
+ Conditional* condition; // condition variable
+ ThreadRunner threadRunner; // thread function
+ ThreadData* common; // threads common data
+ const std::string name; // thread name, for debugging purposes
+ /**
+ * https://stackoverflow.com/questions/149932/naming-conventions-for-threads
+ *
+ * Use short names because they don't make the lines in a log file too long.
+ *
+ * Create names where the important part is at the beginning. Log viewers in a
+ * graphical user interface tend to have tables with columns, and the thread
+ * column is usually small or will be made small by you to read everything else.
+ *
+ * Do not use the word "thread" in the thread name because it is obvious.
+ *
+ * Make the thread names easily grep-able. Avoid similar sounding thread names
+ *
+ * If you have several threads of the same nature, enumerate them with IDs that
+ * are unique to one execution of the application or one log file, whichever fits
+ * your logging habits.
+ *
+ * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker
+ * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or
+ * "Calculation" (what does it calculate?).
+ *
+ * If you have a test group that uses thread names to grep your application's log
+ * files, do not rename your threads after some time. Your testers will hate you for
+ * doing so. Thread names in well-tested applications should be there to stay.
+ *
+ * When you have threads that service a network connection, try to include the target
+ * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about
+ * enumeration though if there are multiple connections to the same host.
+ */
+ bool running; // running
- };
+ };
-} // thread
+ } // thread
} // jin
#endif // LIBJIN_MODULES_THREAD
diff --git a/src/libjin/Thread/thread.cpp b/src/libjin/Thread/thread.cpp
index 971fc03..0703f1b 100644
--- a/src/libjin/Thread/thread.cpp
+++ b/src/libjin/Thread/thread.cpp
@@ -5,297 +5,297 @@
namespace jin
{
-namespace thread
-{
-
- class Mutex
- {
- public:
- Mutex();
- ~Mutex();
-
- void lock();
- void unlock();
- private:
- #if LIBJIN_THREAD_SDL
- SDL_mutex* mutex;
- #endif
- friend class Conditional;
- };
-
- // ̼߳signal wait
- class Conditional
- {
- public:
- Conditional();
- ~Conditional();
- void signal();
- void broadcast();
- bool wait(Mutex* mutex, int timeout = -1);
- private:
- #if LIBJIN_THREAD_SDL
- SDL_cond* cond;
- #endif
- };
-
- class Lock
- {
- public:
- Lock(Mutex* m) : mutex(m) {
- mutex->lock();
- }
-
- Lock(Mutex& m) : mutex(&m) {
- mutex->lock();
- }
-
- ~Lock() {
- mutex->unlock();
- }
- private:
- Mutex* mutex;
-
- Lock(Lock&) {}
-
- };
-
- //////////////////////////////////////////////////////////////////////
+ namespace thread
+ {
+
+ class Mutex
+ {
+ public:
+ Mutex();
+ ~Mutex();
+
+ void lock();
+ void unlock();
+ private:
+ #if LIBJIN_THREAD_SDL
+ SDL_mutex* mutex;
+ #endif
+ friend class Conditional;
+ };
+
+ // ̼߳signal wait
+ class Conditional
+ {
+ public:
+ Conditional();
+ ~Conditional();
+ void signal();
+ void broadcast();
+ bool wait(Mutex* mutex, int timeout = -1);
+ private:
+ #if LIBJIN_THREAD_SDL
+ SDL_cond* cond;
+ #endif
+ };
+
+ class Lock
+ {
+ public:
+ Lock(Mutex* m) : mutex(m) {
+ mutex->lock();
+ }
+
+ Lock(Mutex& m) : mutex(&m) {
+ mutex->lock();
+ }
+
+ ~Lock() {
+ mutex->unlock();
+ }
+ private:
+ Mutex* mutex;
+
+ Lock(Lock&) {}
+
+ };
+
+ //////////////////////////////////////////////////////////////////////
- Mutex::Mutex()
- {
- #if LIBJIN_THREAD_SDL
- mutex = SDL_CreateMutex();
- #endif
- }
-
- Mutex::~Mutex()
- {
- #if LIBJIN_THREAD_SDL
- SDL_DestroyMutex(mutex);
- #endif
- }
-
- void Mutex::lock()
- {
- #if LIBJIN_THREAD_SDL
- SDL_LockMutex(mutex);
- #endif
- }
-
- void Mutex::unlock()
- {
- #if LIBJIN_THREAD_SDL
- SDL_UnlockMutex(mutex);
- #endif
- }
-
- //////////////////////////////////////////////////////////////////////
-
- Conditional::Conditional()
- {
- #if LIBJIN_THREAD_SDL
- cond = SDL_CreateCond();
- #endif
- }
-
- Conditional::~Conditional()
- {
- #if LIBJIN_THREAD_SDL
- SDL_DestroyCond(cond);
- #endif
- }
-
- void Conditional::signal()
- {
- #if LIBJIN_THREAD_SDL
- SDL_CondSignal(cond);
- #endif
- }
-
- void Conditional::broadcast()
- {
- #if LIBJIN_THREAD_SDL
- SDL_CondBroadcast(cond);
- #endif
- }
-
- bool Conditional::wait(Mutex* mutex, int timeout)
- {
- #if LIBJIN_THREAD_SDL
- if (timeout < 0)
- return !SDL_CondWait(cond, mutex->mutex);
- else
- return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0);
- #endif
- }
+ Mutex::Mutex()
+ {
+ #if LIBJIN_THREAD_SDL
+ mutex = SDL_CreateMutex();
+ #endif
+ }
+
+ Mutex::~Mutex()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_DestroyMutex(mutex);
+ #endif
+ }
+
+ void Mutex::lock()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_LockMutex(mutex);
+ #endif
+ }
+
+ void Mutex::unlock()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_UnlockMutex(mutex);
+ #endif
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ Conditional::Conditional()
+ {
+ #if LIBJIN_THREAD_SDL
+ cond = SDL_CreateCond();
+ #endif
+ }
+
+ Conditional::~Conditional()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_DestroyCond(cond);
+ #endif
+ }
+
+ void Conditional::signal()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_CondSignal(cond);
+ #endif
+ }
+
+ void Conditional::broadcast()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_CondBroadcast(cond);
+ #endif
+ }
+
+ bool Conditional::wait(Mutex* mutex, int timeout)
+ {
+ #if LIBJIN_THREAD_SDL
+ if (timeout < 0)
+ return !SDL_CondWait(cond, mutex->mutex);
+ else
+ return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0);
+ #endif
+ }
- //////////////////////////////////////////////////////////////////////
-
- Thread::ThreadData::ThreadData(Mutex* m, Conditional* c)
- : mutex(m)
- , condition(c)
- , share()
- {
- }
-
- Thread::ThreadData::~ThreadData()
- {
- }
-
- void Thread::ThreadData::set(int slot, Variant value)
- {
- Lock l(mutex);
- share[slot] = value;
- }
-
- Thread::Variant Thread::ThreadData::get(int slot)
- {
- Lock l(mutex);
- return share[slot];
- }
-
- bool Thread::ThreadData::exist(int slot)
- {
- Lock l(mutex);
- return share.count(slot) == 1;
- }
-
- void Thread::ThreadData::remove(int slot)
- {
- Lock l(mutex);
- if (exist(slot))
- {
- share.erase(slot);
- }
- }
-
- //////////////////////////////////////////////////////////////////////
-
- Thread::Thread(const std::string tname, ThreadRunner runner)
- : name(tname)
- , running(false)
- , threadRunner(runner)
- {
- mutex = new Mutex();
- condition = new Conditional();
- common = new Thread::ThreadData(mutex, condition);
- }
-
- Thread::~Thread()
- {
- #if LIBJIN_THREAD_SDL
- #endif
- }
-
- const char* Thread::getName()
- {
- Lock l(mutex);
- return name.c_str();
- };
+ //////////////////////////////////////////////////////////////////////
+
+ Thread::ThreadData::ThreadData(Mutex* m, Conditional* c)
+ : mutex(m)
+ , condition(c)
+ , share()
+ {
+ }
+
+ Thread::ThreadData::~ThreadData()
+ {
+ }
+
+ void Thread::ThreadData::set(int slot, Variant value)
+ {
+ Lock l(mutex);
+ share[slot] = value;
+ }
+
+ Thread::Variant Thread::ThreadData::get(int slot)
+ {
+ Lock l(mutex);
+ return share[slot];
+ }
+
+ bool Thread::ThreadData::exist(int slot)
+ {
+ Lock l(mutex);
+ return share.count(slot) == 1;
+ }
+
+ void Thread::ThreadData::remove(int slot)
+ {
+ Lock l(mutex);
+ if (exist(slot))
+ {
+ share.erase(slot);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ Thread::Thread(const std::string tname, ThreadRunner runner)
+ : name(tname)
+ , running(false)
+ , threadRunner(runner)
+ {
+ mutex = new Mutex();
+ condition = new Conditional();
+ common = new Thread::ThreadData(mutex, condition);
+ }
+
+ Thread::~Thread()
+ {
+ #if LIBJIN_THREAD_SDL
+ #endif
+ }
+
+ const char* Thread::getName()
+ {
+ Lock l(mutex);
+ return name.c_str();
+ };
- bool Thread::isRunning()
- {
- Lock l(mutex);
- return running;
- };
-
- bool Thread::start(void* p)
- {
- Lock l(mutex);
- if (running)
- return false;
- if (handle)
- {
- #if LIBJIN_THREAD_SDL
- SDL_WaitThread(handle, nullptr);
- #endif
- }
- #if LIBJIN_THREAD_SDL
- handle = SDL_CreateThread(threadRunner, name.c_str(), p);
- #elif LIBJIN_THREAD_CPP
- handle = new std::thread();
- #endif
- return (running = (handle != nullptr));
- }
-
- void Thread::wait()
- {
- {
- Lock l(mutex);
- if (!handle)
- return;
- }
- #if LIBJIN_THREAD_SDL
- SDL_WaitThread(handle, nullptr);
- #endif
- Lock l(mutex);
- running = false;
- handle = nullptr;
- }
-
- void Thread::lock()
- {
- if (mutex != nullptr)
- mutex->lock();
- }
-
- void Thread::unlock()
- {
- if (mutex != nullptr)
- mutex->unlock();
- }
-
- void Thread::send(int slot, const Variant& value)
- {
- lock();
- common->set(slot, value);
- unlock();
- condition->broadcast();
- }
-
- bool Thread::receive(int slot)
- {
- return common->exist(slot);
- }
-
- Thread::Variant Thread::fetch(int slot)
- {
- Thread::Variant v = common->get(slot);
- return v;
- }
-
- Thread::Variant Thread::demand(int slot)
- {
- /**
- * pthread_mutex_lock(mtx);
- * while(pass == 0)
- * {
- * pthread_mutex_unlock(mtx);
- * pthread_cond_just_wait(cv);
- * pthread_mutex_lock(mtx);
- * }
- * pthread_mutex_unlock(mtx);
- */
- lock();
- while (!common->exist(slot))
- {
- if (common->exist(ThreadData::SLOT_ERROR))
- return 0;
- condition->wait(mutex);
- }
- Thread::Variant v = common->get(slot);
- unlock();
- return v;
- }
-
- void Thread::remove(int slot)
- {
- lock();
- common->remove(slot);
- unlock();
- }
-
-} // thread
+ bool Thread::isRunning()
+ {
+ Lock l(mutex);
+ return running;
+ };
+
+ bool Thread::start(void* p)
+ {
+ Lock l(mutex);
+ if (running)
+ return false;
+ if (handle)
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_WaitThread(handle, nullptr);
+ #endif
+ }
+ #if LIBJIN_THREAD_SDL
+ handle = SDL_CreateThread(threadRunner, name.c_str(), p);
+ #elif LIBJIN_THREAD_CPP
+ handle = new std::thread();
+ #endif
+ return (running = (handle != nullptr));
+ }
+
+ void Thread::wait()
+ {
+ {
+ Lock l(mutex);
+ if (!handle)
+ return;
+ }
+ #if LIBJIN_THREAD_SDL
+ SDL_WaitThread(handle, nullptr);
+ #endif
+ Lock l(mutex);
+ running = false;
+ handle = nullptr;
+ }
+
+ void Thread::lock()
+ {
+ if (mutex != nullptr)
+ mutex->lock();
+ }
+
+ void Thread::unlock()
+ {
+ if (mutex != nullptr)
+ mutex->unlock();
+ }
+
+ void Thread::send(int slot, const Variant& value)
+ {
+ lock();
+ common->set(slot, value);
+ unlock();
+ condition->broadcast();
+ }
+
+ bool Thread::receive(int slot)
+ {
+ return common->exist(slot);
+ }
+
+ Thread::Variant Thread::fetch(int slot)
+ {
+ Thread::Variant v = common->get(slot);
+ return v;
+ }
+
+ Thread::Variant Thread::demand(int slot)
+ {
+ /**
+ * pthread_mutex_lock(mtx);
+ * while(pass == 0)
+ * {
+ * pthread_mutex_unlock(mtx);
+ * pthread_cond_just_wait(cv);
+ * pthread_mutex_lock(mtx);
+ * }
+ * pthread_mutex_unlock(mtx);
+ */
+ lock();
+ while (!common->exist(slot))
+ {
+ if (common->exist(ThreadData::SLOT_ERROR))
+ return 0;
+ condition->wait(mutex);
+ }
+ Thread::Variant v = common->get(slot);
+ unlock();
+ return v;
+ }
+
+ void Thread::remove(int slot)
+ {
+ lock();
+ common->remove(slot);
+ unlock();
+ }
+
+ } // thread
} // jin
#endif // LIBJIN_MODULES_THREAD \ No newline at end of file
diff --git a/src/libjin/Thread/thread.h b/src/libjin/Thread/thread.h
index 3a7b4ba..d6d0a19 100644
--- a/src/libjin/Thread/thread.h
+++ b/src/libjin/Thread/thread.h
@@ -15,151 +15,151 @@
namespace jin
{
-namespace thread
-{
- /**
- * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ
- * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ
- * ָһԹԴзʵĴ룬һֻƻ㷨һ򡢽̡߳̿ӵжٽ򣬵Dz
- * һӦûҪ˻ƵԴУꡢСжϴڶеĴ
- * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ
- * ߣ߻ָѣ
- */
- class Mutex;
- class Conditional;
+ namespace thread
+ {
+ /**
+ * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ
+ * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ
+ * ָһԹԴзʵĴ룬һֻƻ㷨һ򡢽̡߳̿ӵжٽ򣬵Dz
+ * һӦûҪ˻ƵԴУꡢСжϴڶеĴ
+ * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ
+ * ߣ߻ָѣ
+ */
+ class Mutex;
+ class Conditional;
- /**
- * Thread::demand Receive a message from a thread. Wait for the message to exist before returning.
- * Thread::getName Get the name of a thread.
- * Thread::kill Forcefully terminate the thread.
- * Thread::peek Receive a message from a thread, but leave it in the message box.
- * Thread::receive Receive a message from a thread.
- * Thread::send Send a message.
- * Thread::set Set a value.
- * Thread::start Starts the thread.
- * Thread::wait Wait for a thread to finish.
- */
- class Thread
- {
- public:
- struct Variant
- {
- enum Type
- {
- NONE = 0,
- INTERGER,
- BOOLEAN,
- CHARACTER,
- CSTRING,
- POINTER,
- REAL,
- };
- Type type;
- union
- {
- int integer;
- bool boolean;
- char character;
- const char* cstring;
- void* pointer;
- float real;
- };
- Variant() :type(NONE) {};
- Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); }
- Variant(int i) : integer(i), type(INTERGER) {};
- Variant(float f) : real(f), type(REAL) {};
- Variant(bool b) : boolean(b), type(BOOLEAN) {};
- Variant(char c) : character(c), type(CHARACTER) {};
- Variant(const char* s) : cstring(s), type(CSTRING) {};
- Variant(void* p) : pointer(p), type(POINTER) {};
- };
+ /**
+ * Thread::demand Receive a message from a thread. Wait for the message to exist before returning.
+ * Thread::getName Get the name of a thread.
+ * Thread::kill Forcefully terminate the thread.
+ * Thread::peek Receive a message from a thread, but leave it in the message box.
+ * Thread::receive Receive a message from a thread.
+ * Thread::send Send a message.
+ * Thread::set Set a value.
+ * Thread::start Starts the thread.
+ * Thread::wait Wait for a thread to finish.
+ */
+ class Thread
+ {
+ public:
+ struct Variant
+ {
+ enum Type
+ {
+ NONE = 0,
+ INTERGER,
+ BOOLEAN,
+ CHARACTER,
+ CSTRING,
+ POINTER,
+ REAL,
+ };
+ Type type;
+ union
+ {
+ int integer;
+ bool boolean;
+ char character;
+ const char* cstring;
+ void* pointer;
+ float real;
+ };
+ Variant() :type(NONE) {};
+ Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); }
+ Variant(int i) : integer(i), type(INTERGER) {};
+ Variant(float f) : real(f), type(REAL) {};
+ Variant(bool b) : boolean(b), type(BOOLEAN) {};
+ Variant(char c) : character(c), type(CHARACTER) {};
+ Variant(const char* s) : cstring(s), type(CSTRING) {};
+ Variant(void* p) : pointer(p), type(POINTER) {};
+ };
- private:
- class ThreadData
- {
- public:
- static const int SLOT_ERROR = -1;
- static const int SLOT_WARN = -2;
- static const int SLOT_INFO = -3;
- static const int SLOT_DEBUG = -4;
+ private:
+ class ThreadData
+ {
+ public:
+ static const int SLOT_ERROR = -1;
+ static const int SLOT_WARN = -2;
+ static const int SLOT_INFO = -3;
+ static const int SLOT_DEBUG = -4;
- ThreadData(Mutex*, Conditional*);
- ~ThreadData();
- bool exist(int slot);
- void set(int slot, Variant value);
- Variant get(int slot);
- void remove(int slot);
+ ThreadData(Mutex*, Conditional*);
+ ~ThreadData();
+ bool exist(int slot);
+ void set(int slot, Variant value);
+ Variant get(int slot);
+ void remove(int slot);
- Conditional* condition;
- Mutex* mutex;
+ Conditional* condition;
+ Mutex* mutex;
- private:
- std::map<int, Variant> share; // threads shared value
+ private:
+ std::map<int, Variant> share; // threads shared value
- };
+ };
- public:
- typedef int(*ThreadRunner)(void* obj);
+ public:
+ typedef int(*ThreadRunner)(void* obj);
- Thread(const std::string name, ThreadRunner threadfuncs);
- ~Thread();
- bool start(void* p);
- void wait();
- void send(int slot, const Variant& value);
- bool receive(int slot);
- Variant fetch(int slot);
- Variant demand(int slot);
- void remove(int slot);
- const char* getName();
- bool isRunning();
- void lock();
- void unlock();
+ Thread(const std::string name, ThreadRunner threadfuncs);
+ ~Thread();
+ bool start(void* p);
+ void wait();
+ void send(int slot, const Variant& value);
+ bool receive(int slot);
+ Variant fetch(int slot);
+ Variant demand(int slot);
+ void remove(int slot);
+ const char* getName();
+ bool isRunning();
+ void lock();
+ void unlock();
- protected:
- #if LIBJIN_THREAD_SDL
- SDL_Thread* handle; // SDL thread
- #elif LIBJIN_THREAD_CPP
- std::thread* handle; // cpp thread
- #endif
- Mutex* mutex; // mutex variable
- Conditional* condition; // condition variable
- ThreadRunner threadRunner; // thread function
- ThreadData* common; // threads common data
- const std::string name; // thread name, for debugging purposes
- /**
- * https://stackoverflow.com/questions/149932/naming-conventions-for-threads
- *
- * Use short names because they don't make the lines in a log file too long.
- *
- * Create names where the important part is at the beginning. Log viewers in a
- * graphical user interface tend to have tables with columns, and the thread
- * column is usually small or will be made small by you to read everything else.
- *
- * Do not use the word "thread" in the thread name because it is obvious.
- *
- * Make the thread names easily grep-able. Avoid similar sounding thread names
- *
- * If you have several threads of the same nature, enumerate them with IDs that
- * are unique to one execution of the application or one log file, whichever fits
- * your logging habits.
- *
- * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker
- * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or
- * "Calculation" (what does it calculate?).
- *
- * If you have a test group that uses thread names to grep your application's log
- * files, do not rename your threads after some time. Your testers will hate you for
- * doing so. Thread names in well-tested applications should be there to stay.
- *
- * When you have threads that service a network connection, try to include the target
- * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about
- * enumeration though if there are multiple connections to the same host.
- */
- bool running; // running
+ protected:
+ #if LIBJIN_THREAD_SDL
+ SDL_Thread* handle; // SDL thread
+ #elif LIBJIN_THREAD_CPP
+ std::thread* handle; // cpp thread
+ #endif
+ Mutex* mutex; // mutex variable
+ Conditional* condition; // condition variable
+ ThreadRunner threadRunner; // thread function
+ ThreadData* common; // threads common data
+ const std::string name; // thread name, for debugging purposes
+ /**
+ * https://stackoverflow.com/questions/149932/naming-conventions-for-threads
+ *
+ * Use short names because they don't make the lines in a log file too long.
+ *
+ * Create names where the important part is at the beginning. Log viewers in a
+ * graphical user interface tend to have tables with columns, and the thread
+ * column is usually small or will be made small by you to read everything else.
+ *
+ * Do not use the word "thread" in the thread name because it is obvious.
+ *
+ * Make the thread names easily grep-able. Avoid similar sounding thread names
+ *
+ * If you have several threads of the same nature, enumerate them with IDs that
+ * are unique to one execution of the application or one log file, whichever fits
+ * your logging habits.
+ *
+ * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker
+ * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or
+ * "Calculation" (what does it calculate?).
+ *
+ * If you have a test group that uses thread names to grep your application's log
+ * files, do not rename your threads after some time. Your testers will hate you for
+ * doing so. Thread names in well-tested applications should be there to stay.
+ *
+ * When you have threads that service a network connection, try to include the target
+ * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about
+ * enumeration though if there are multiple connections to the same host.
+ */
+ bool running; // running
- };
+ };
-} // thread
+ } // thread
} // jin
#endif // LIBJIN_MODULES_THREAD
diff --git a/src/libjin/Time/Timer.cpp b/src/libjin/Time/Timer.cpp
index 94d790d..426f2d5 100644
--- a/src/libjin/Time/Timer.cpp
+++ b/src/libjin/Time/Timer.cpp
@@ -5,96 +5,96 @@
namespace jin
{
-namespace time
-{
+ namespace time
+ {
- Timers::Timers()
- : timers()
- {
- }
+ Timers::Timers()
+ : timers()
+ {
+ }
- Timers::~Timers()
- {
- for (int i = 0; i < timers.size(); ++i)
- delete timers[i];
- }
+ Timers::~Timers()
+ {
+ for (int i = 0; i < timers.size(); ++i)
+ delete timers[i];
+ }
- void Timers::update(int ms)
- {
- std::vector<Timer*>::iterator it = timers.begin();
- for (; it != timers.end(); )
- {
- if (!(*it)->process(ms))
- {
- Timer* t = *it;
- timers.erase(it);
- delete t;
- return;
- }
- ++it;
- }
- }
+ void Timers::update(int ms)
+ {
+ std::vector<Timer*>::iterator it = timers.begin();
+ for (; it != timers.end(); )
+ {
+ if (!(*it)->process(ms))
+ {
+ Timer* t = *it;
+ timers.erase(it);
+ delete t;
+ return;
+ }
+ ++it;
+ }
+ }
- void Timers::every(int ms, timer_callback callback, void* p)
- {
- Timer* t = new Timer(Timer::EVERY, ms, 0, callback, p);
- timers.push_back(t);
- }
+ void Timers::every(int ms, timer_callback callback, void* p)
+ {
+ Timer* t = new Timer(Timer::EVERY, ms, 0, callback, p);
+ timers.push_back(t);
+ }
- void Timers::after(int ms, timer_callback callback, void* p)
- {
- Timer* t = new Timer(Timer::AFTER, ms, 0, callback, p);
- timers.push_back(t);
- }
+ void Timers::after(int ms, timer_callback callback, void* p)
+ {
+ Timer* t = new Timer(Timer::AFTER, ms, 0, callback, p);
+ timers.push_back(t);
+ }
- void Timers::repeat(int ms, int count, timer_callback callback, void* p)
- {
- Timer* t = new Timer(Timer::REPEAT, ms, count, callback, p);
- timers.push_back(t);
- }
+ void Timers::repeat(int ms, int count, timer_callback callback, void* p)
+ {
+ Timer* t = new Timer(Timer::REPEAT, ms, count, callback, p);
+ timers.push_back(t);
+ }
- Timers::Timer::Timer(Type t, int d, int c, timer_callback f, void* p)
- : type(t)
- , duration(d)
- , count(c)
- , tickdown(d)
- , countdown(c)
- , callback(f)
- , paramters(p)
- {
- }
+ Timers::Timer::Timer(Type t, int d, int c, timer_callback f, void* p)
+ : type(t)
+ , duration(d)
+ , count(c)
+ , tickdown(d)
+ , countdown(c)
+ , callback(f)
+ , paramters(p)
+ {
+ }
- Timers::Timer::~Timer()
- {
- }
+ Timers::Timer::~Timer()
+ {
+ }
- bool Timers::Timer::process(int ms)
- {
- tickdown -= ms;
- if (tickdown <= 0)
- {
- tickdown = duration;
- if (callback != nullptr)
- callback(paramters);
- if (type == EVERY)
- {
- }
- else if (type == AFTER)
- {
- return false;
- }
- else if (type == REPEAT)
- {
- --countdown;
- if (countdown <= 0)
- return false;
- }
- }
- return true;
- }
+ bool Timers::Timer::process(int ms)
+ {
+ tickdown -= ms;
+ if (tickdown <= 0)
+ {
+ tickdown = duration;
+ if (callback != nullptr)
+ callback(paramters);
+ if (type == EVERY)
+ {
+ }
+ else if (type == AFTER)
+ {
+ return false;
+ }
+ else if (type == REPEAT)
+ {
+ --countdown;
+ if (countdown <= 0)
+ return false;
+ }
+ }
+ return true;
+ }
-} // time
+ } // time
} // jin
#endif // LIBJIN_MODULES_TIME
diff --git a/src/libjin/Time/Timer.h b/src/libjin/Time/Timer.h
index 7a58e14..93a90ae 100644
--- a/src/libjin/Time/Timer.h
+++ b/src/libjin/Time/Timer.h
@@ -8,69 +8,69 @@
namespace jin
{
-namespace time
-{
+ namespace time
+ {
- class Timers
- {
- public:
- typedef void(*timer_callback)(void* prameters);
+ class Timers
+ {
+ public:
+ typedef void(*timer_callback)(void* prameters);
- Timers();
- ~Timers();
- void update(int ms);
- void every(int ms, timer_callback callback, void* paramters);
- void after(int ms, timer_callback callback, void* paramters);
- void repeat(int ms, int count, timer_callback callback, void* paramters);
+ Timers();
+ ~Timers();
+ void update(int ms);
+ void every(int ms, timer_callback callback, void* paramters);
+ void after(int ms, timer_callback callback, void* paramters);
+ void repeat(int ms, int count, timer_callback callback, void* paramters);
- private:
- class Timer
- {
- public:
- enum Type
- {
- EVERY,
- AFTER,
- REPEAT,
- };
- Timer(Type type, int duration, int count = 0, timer_callback callback = nullptr, void* paramters = nullptr);
- virtual ~Timer();
- bool process(int ms);
- private:
- int duration;
- int count;
- int tickdown;
- int countdown;
- Type type;
- timer_callback callback;
- void* paramters;
- };
- std::vector<Timer*> timers;
+ private:
+ class Timer
+ {
+ public:
+ enum Type
+ {
+ EVERY,
+ AFTER,
+ REPEAT,
+ };
+ Timer(Type type, int duration, int count = 0, timer_callback callback = nullptr, void* paramters = nullptr);
+ virtual ~Timer();
+ bool process(int ms);
+ private:
+ int duration;
+ int count;
+ int tickdown;
+ int countdown;
+ Type type;
+ timer_callback callback;
+ void* paramters;
+ };
+ std::vector<Timer*> timers;
- };
+ };
- inline void sleep(int ms)
- {
- #if LIBJIN_TIME_SDL
- SDL_Delay(ms);
- #endif
- }
+ inline void sleep(int ms)
+ {
+ #if LIBJIN_TIME_SDL
+ SDL_Delay(ms);
+ #endif
+ }
- inline double getSecond()
- {
- #if LIBJIN_TIME_SDL
- return SDL_GetTicks() / 1000.f;
- #endif
- }
+ inline double getSecond()
+ {
+ #if LIBJIN_TIME_SDL
+ return SDL_GetTicks() / 1000.f;
+ #endif
+ }
- inline double getMilliSecond()
- {
- #if LIBJIN_TIME_SDL
- return SDL_GetTicks();
- #endif
- }
+ inline double getMilliSecond()
+ {
+ #if LIBJIN_TIME_SDL
+ return SDL_GetTicks();
+ #endif
+ }
-} // time
+ } // time
} // jin
#endif // LIBJIN_MODULES_TIME
diff --git a/src/libjin/audio/audio.cpp b/src/libjin/audio/audio.cpp
index 798269a..d148467 100644
--- a/src/libjin/audio/audio.cpp
+++ b/src/libjin/audio/audio.cpp
@@ -6,10 +6,10 @@
namespace jin
{
-namespace audio
-{
+ namespace audio
+ {
-} // audio
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO
diff --git a/src/libjin/audio/audio.h b/src/libjin/audio/audio.h
index b9812dd..48cbfe4 100644
--- a/src/libjin/audio/audio.h
+++ b/src/libjin/audio/audio.h
@@ -10,42 +10,42 @@
namespace jin
{
-namespace audio
-{
+ namespace audio
+ {
- class Source;
+ class Source;
- template<class SubAudio>
- class Audio : public Subsystem<SubAudio>
- {
- public:
- enum State
- {
- PLAY ,
- STOP ,
- PAUSE,
- };
-
- virtual void play() = 0;
- virtual void stop() = 0;
- virtual void pause() = 0;
- virtual void resume() = 0;
- virtual void setVolume(float volume) = 0;
-
- protected:
- Audio()
- : volume(1)
- , state(State::PLAY)
- {};
- virtual ~Audio() {};
- SINGLETON(Audio);
-
- float volume;
- State state;
-
- };
-
-} // audio
+ template<class SubAudio>
+ class Audio : public Subsystem<SubAudio>
+ {
+ public:
+ enum State
+ {
+ PLAY ,
+ STOP ,
+ PAUSE,
+ };
+
+ virtual void play() = 0;
+ virtual void stop() = 0;
+ virtual void pause() = 0;
+ virtual void resume() = 0;
+ virtual void setVolume(float volume) = 0;
+
+ protected:
+ Audio()
+ : volume(1)
+ , state(State::PLAY)
+ {};
+ virtual ~Audio() {};
+ SINGLETON(Audio);
+
+ float volume;
+ State state;
+
+ };
+
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO
diff --git a/src/libjin/audio/source.cpp b/src/libjin/audio/source.cpp
index 1dcd482..306d93f 100644
--- a/src/libjin/audio/source.cpp
+++ b/src/libjin/audio/source.cpp
@@ -6,24 +6,24 @@
namespace jin
{
-namespace audio
-{
+ namespace audio
+ {
- static int check_header(const void *data, int size, const char *str, int offset) {
- int len = strlen(str);
- return (size >= offset + len) && !memcmp((char*)data + offset, str, len);
- }
+ static int check_header(const void *data, int size, const char *str, int offset) {
+ int len = strlen(str);
+ return (size >= offset + len) && !memcmp((char*)data + offset, str, len);
+ }
- SourceType Source::getType(const void* mem, int size)
- {
- if(check_header(mem, size, "WAVE", 8))
- return SourceType::WAV;
- if(check_header(mem, size, "OggS", 0))
- return SourceType::OGG;
- return SourceType::INVALID;
- }
+ SourceType Source::getType(const void* mem, int size)
+ {
+ if(check_header(mem, size, "WAVE", 8))
+ return SourceType::WAV;
+ if(check_header(mem, size, "OggS", 0))
+ return SourceType::OGG;
+ return SourceType::INVALID;
+ }
-} // audio
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO
diff --git a/src/libjin/audio/source.h b/src/libjin/audio/source.h
index e1ca6d0..40707de 100644
--- a/src/libjin/audio/source.h
+++ b/src/libjin/audio/source.h
@@ -7,40 +7,40 @@
namespace jin
{
-namespace audio
-{
-
- enum SourceType
- {
- INVALID = 0,
- WAV,
- OGG,
- };
-
- class Source
- {
- public:
- Source() {};
- virtual ~Source() {};
- /* interface */
- virtual void play() = 0;
- virtual void stop() = 0;
- virtual void pause() = 0;
- virtual void resume() = 0;
- virtual void rewind() = 0;
- virtual bool isStopped() const = 0;
- virtual bool isPaused() const = 0;
- virtual void setPitch(float pitch) = 0;
- virtual void setVolume(float volume) = 0;
- virtual bool setLoop(bool loop) = 0;
- virtual void setRate(float rate) = 0;
-
- protected:
- static SourceType getType(const void* mem, int size);
-
- };
-
-} // audio
+ namespace audio
+ {
+
+ enum SourceType
+ {
+ INVALID = 0,
+ WAV,
+ OGG,
+ };
+
+ class Source
+ {
+ public:
+ Source() {};
+ virtual ~Source() {};
+ /* interface */
+ virtual void play() = 0;
+ virtual void stop() = 0;
+ virtual void pause() = 0;
+ virtual void resume() = 0;
+ virtual void rewind() = 0;
+ virtual bool isStopped() const = 0;
+ virtual bool isPaused() const = 0;
+ virtual void setPitch(float pitch) = 0;
+ virtual void setVolume(float volume) = 0;
+ virtual bool setLoop(bool loop) = 0;
+ virtual void setRate(float rate) = 0;
+
+ protected:
+ static SourceType getType(const void* mem, int size);
+
+ };
+
+ } // audio
} // jin
#endif // LIBJIN_MODULES_AUDIO
diff --git a/src/libjin/common/data.h b/src/libjin/common/data.h
deleted file mode 100644
index 4b0f1ba..0000000
--- a/src/libjin/common/data.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __JIN_COMMON_DATA_H
-#define __JIN_COMMON_DATA_H
-
-
-
-namespace jin
-{
-
- class DataBuffer
- {
- public:
- DataBuffer(int n)
- : len(n)
- {
- buffer = new char[len];
- memset(buffer, 0, len);
- }
- ~DataBuffer()
- {
- delete[] buffer;
- }
- char* operator&()
- {
- return buffer;
- }
-
- private:
- char* buffer;
- int len;
- };
-
-} // jin
-
-#endif \ No newline at end of file
diff --git a/src/libjin/input/keyboard.h b/src/libjin/input/keyboard.h
index 250e8f0..b50302c 100644
--- a/src/libjin/input/keyboard.h
+++ b/src/libjin/input/keyboard.h
@@ -3,15 +3,15 @@
namespace jin
{
-namespace input
-{
+ namespace input
+ {
- class Keyboard
- {
+ class Keyboard
+ {
- };
+ };
-} // input
+ } // input
} // jin
#endif // __LIBJIN_KEYBOARD_H \ No newline at end of file
diff --git a/src/libjin/input/mouse.cpp b/src/libjin/input/mouse.cpp
index 31c29f9..3869337 100644
--- a/src/libjin/input/mouse.cpp
+++ b/src/libjin/input/mouse.cpp
@@ -6,22 +6,22 @@
namespace jin
{
-namespace input
-{
+ namespace input
+ {
- void Mouse::getState(int* x, int* y)
- {
- #ifdef LIBJIN_INPUT_SDL
- SDL_GetMouseState(x, y);
- #endif // LIBJIN_INPUT_SDL
- }
+ void Mouse::getState(int* x, int* y)
+ {
+ #ifdef LIBJIN_INPUT_SDL
+ SDL_GetMouseState(x, y);
+ #endif // LIBJIN_INPUT_SDL
+ }
- void Mouse::setVisible(bool visible)
- {
- SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
- }
+ void Mouse::setVisible(bool visible)
+ {
+ SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
+ }
-} // input
+ } // input
} // jin
#endif // LIBJIN_MODULES_INPUT \ No newline at end of file
diff --git a/src/libjin/input/mouse.h b/src/libjin/input/mouse.h
index 09db5d2..29d730b 100644
--- a/src/libjin/input/mouse.h
+++ b/src/libjin/input/mouse.h
@@ -7,24 +7,24 @@
namespace jin
{
-namespace input
-{
+ namespace input
+ {
- class Mouse : public Singleton<Mouse>
- {
- public:
- void getState(int* x, int* y);
- void setVisible(bool visible);
+ class Mouse : public Singleton<Mouse>
+ {
+ public:
+ void getState(int* x, int* y);
+ void setVisible(bool visible);
- private:
- SINGLETON(Mouse);
+ private:
+ SINGLETON(Mouse);
- Mouse() {};
- ~Mouse() {};
+ Mouse() {};
+ ~Mouse() {};
- };
+ };
-} // input
+ } // input
} // jin
#endif // LIBJIN_MODULES_INPUT
diff --git a/src/libjin/math/math.h b/src/libjin/math/math.h
index 6eb4367..98f9cd8 100644
--- a/src/libjin/math/math.h
+++ b/src/libjin/math/math.h
@@ -7,71 +7,71 @@
namespace jin
{
-namespace math
-{
+ namespace math
+ {
-#ifdef min
-# undef min
-#endif // min
-#ifdef max
-# undef max
-#endif // max
+ #ifdef min
+ # undef min
+ #endif // min
+ #ifdef max
+ # undef max
+ #endif // max
- template<typename T>
- inline T min(T a, T b)
- {
- return a < b ? a : b;
- }
+ template<typename T>
+ inline T min(T a, T b)
+ {
+ return a < b ? a : b;
+ }
- template<typename T>
- inline T max(T a, T b)
- {
- return a > b ? a : b;
- }
+ template<typename T>
+ inline T max(T a, T b)
+ {
+ return a > b ? a : b;
+ }
- template<typename T>
- inline T clamp(T a, T mi, T ma)
- {
- return min<T>(max<T>(a, mi), ma);
- }
+ template<typename T>
+ inline T clamp(T a, T mi, T ma)
+ {
+ return min<T>(max<T>(a, mi), ma);
+ }
- template<typename T>
- inline bool within(T a, T mi, T ma)
- {
- return a >= mi && a <= ma;
- }
+ template<typename T>
+ inline bool within(T a, T mi, T ma)
+ {
+ return a >= mi && a <= ma;
+ }
- template<typename T>
- inline bool without(T a, T mi, T ma)
- {
- return a < mi || a > ma;
- }
+ template<typename T>
+ inline bool without(T a, T mi, T ma)
+ {
+ return a < mi || a > ma;
+ }
- template<typename T>
- inline T abs(T a)
- {
- return a > 0 ? a : -a;
- }
+ template<typename T>
+ inline T abs(T a)
+ {
+ return a > 0 ? a : -a;
+ }
- template<typename T>
- inline T lowerBound(T a, T lower)
- {
- return a < lower ? lower : a;
- }
+ template<typename T>
+ inline T lowerBound(T a, T lower)
+ {
+ return a < lower ? lower : a;
+ }
- template<typename T>
- inline T upperBound(T a, T upper)
- {
- return a > upper ? upper : a;
- }
+ template<typename T>
+ inline T upperBound(T a, T upper)
+ {
+ return a > upper ? upper : a;
+ }
- template<typename T>
- inline T lerp(T a, T b, float t)
- {
- return a + t * (b - a);
- }
+ template<typename T>
+ inline T lerp(T a, T b, float t)
+ {
+ return a + t * (b - a);
+ }
-} // math
+ } // math
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/math/matrix.cpp b/src/libjin/math/matrix.cpp
index a6e2491..74d3a58 100644
--- a/src/libjin/math/matrix.cpp
+++ b/src/libjin/math/matrix.cpp
@@ -5,190 +5,190 @@
namespace jin
{
-namespace math
-{
-
- const Matrix Matrix::Identity;
-
- // | e0 e4 e8 e12 |
- // | e1 e5 e9 e13 |
- // | e2 e6 e10 e14 |
- // | e3 e7 e11 e15 |
-
- Matrix::Matrix()
- {
- setIdentity();
- }
-
- Matrix::~Matrix()
- {
- }
-
- void Matrix::setOrtho(float l, float r, float b, float t, float n, float f)
- {
- setIdentity();
- float w = r - l;
- float h = t - b;
- float z = f - n;
- e[0] = 2 / w;
- e[5] = 2 / h;
- e[10] = -2 / z;
- e[12] = -(r + l) / w;
- e[13] = -(t + b) / h;
- e[14] = -(f + n) / z;
- e[15] = 1;
- }
-
- // | e0 e4 e8 e12 |
- // | e1 e5 e9 e13 |
- // | e2 e6 e10 e14 |
- // | e3 e7 e11 e15 |
- // | e0 e4 e8 e12 |
- // | e1 e5 e9 e13 |
- // | e2 e6 e10 e14 |
- // | e3 e7 e11 e15 |
-
- Matrix Matrix::operator * (const Matrix & m) const
- {
- Matrix t;
-
- t.e[0] = (e[0] * m.e[0]) + (e[4] * m.e[1]) + (e[8] * m.e[2]) + (e[12] * m.e[3]);
- t.e[4] = (e[0] * m.e[4]) + (e[4] * m.e[5]) + (e[8] * m.e[6]) + (e[12] * m.e[7]);
- t.e[8] = (e[0] * m.e[8]) + (e[4] * m.e[9]) + (e[8] * m.e[10]) + (e[12] * m.e[11]);
- t.e[12] = (e[0] * m.e[12]) + (e[4] * m.e[13]) + (e[8] * m.e[14]) + (e[12] * m.e[15]);
-
- t.e[1] = (e[1] * m.e[0]) + (e[5] * m.e[1]) + (e[9] * m.e[2]) + (e[13] * m.e[3]);
- t.e[5] = (e[1] * m.e[4]) + (e[5] * m.e[5]) + (e[9] * m.e[6]) + (e[13] * m.e[7]);
- t.e[9] = (e[1] * m.e[8]) + (e[5] * m.e[9]) + (e[9] * m.e[10]) + (e[13] * m.e[11]);
- t.e[13] = (e[1] * m.e[12]) + (e[5] * m.e[13]) + (e[9] * m.e[14]) + (e[13] * m.e[15]);
-
- t.e[2] = (e[2] * m.e[0]) + (e[6] * m.e[1]) + (e[10] * m.e[2]) + (e[14] * m.e[3]);
- t.e[6] = (e[2] * m.e[4]) + (e[6] * m.e[5]) + (e[10] * m.e[6]) + (e[14] * m.e[7]);
- t.e[10] = (e[2] * m.e[8]) + (e[6] * m.e[9]) + (e[10] * m.e[10]) + (e[14] * m.e[11]);
- t.e[14] = (e[2] * m.e[12]) + (e[6] * m.e[13]) + (e[10] * m.e[14]) + (e[14] * m.e[15]);
-
- t.e[3] = (e[3] * m.e[0]) + (e[7] * m.e[1]) + (e[11] * m.e[2]) + (e[15] * m.e[3]);
- t.e[7] = (e[3] * m.e[4]) + (e[7] * m.e[5]) + (e[11] * m.e[6]) + (e[15] * m.e[7]);
- t.e[11] = (e[3] * m.e[8]) + (e[7] * m.e[9]) + (e[11] * m.e[10]) + (e[15] * m.e[11]);
- t.e[15] = (e[3] * m.e[12]) + (e[7] * m.e[13]) + (e[11] * m.e[14]) + (e[15] * m.e[15]);
-
- return t;
- }
-
- void Matrix::operator *= (const Matrix & m)
- {
- Matrix t = (*this) * m;
- memcpy((void*)this->e, (void*)t.e, sizeof(float) * 16);
- }
-
- const float * Matrix::getElements() const
- {
- return e;
- }
-
- void Matrix::setIdentity()
- {
- memset(e, 0, sizeof(float) * 16);
- e[0] = e[5] = e[10] = e[15] = 1;
- }
-
- void Matrix::setTranslation(float x, float y)
- {
- setIdentity();
- e[12] = x;
- e[13] = y;
- }
-
- void Matrix::setRotation(float rad)
- {
- setIdentity();
- float c = cos(rad), s = sin(rad);
- e[0] = c; e[4] = -s;
- e[1] = s; e[5] = c;
- }
-
- void Matrix::setScale(float sx, float sy)
- {
- setIdentity();
- e[0] = sx;
- e[5] = sy;
- }
-
- void Matrix::setShear(float kx, float ky)
- {
- setIdentity();
- e[1] = ky;
- e[4] = kx;
- }
-
- void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy)
- {
- memset(e, 0, sizeof(float) * 16); // zero out matrix
- float c = cos(angle), s = sin(angle);
- // matrix multiplication carried out on paper:
- // |1 x| |c -s | |sx | |1 -ox|
- // | 1 y| |s c | | sy | | 1 -oy|
- // | 1 | | 1 | | 1 | | 1 |
- // | 1| | 1| | 1| | 1 |
- // move rotate scale origin
- e[10] = e[15] = 1.0f;
- e[0] = c * sx ; // = a
- e[1] = s * sx ; // = b
- e[4] = - s * sy; // = c
- e[5] = c * sy; // = d
- e[12] = x - ox * e[0] - oy * e[4];
- e[13] = y - ox * e[1] - oy * e[5];
- }
-
- void Matrix::translate(float x, float y)
- {
- Matrix t;
- t.setTranslation(x, y);
- this->operator *=(t);
- }
-
- void Matrix::rotate(float rad)
- {
- Matrix t;
- t.setRotation(rad);
- this->operator *=(t);
- }
-
- void Matrix::scale(float sx, float sy)
- {
- Matrix t;
- t.setScale(sx, sy);
- this->operator *=(t);
- }
-
- void Matrix::shear(float kx, float ky)
- {
- Matrix t;
- t.setShear(kx, ky);
- this->operator *=(t);
- }
-
- // | x |
- // | y |
- // | 0 |
- // | 1 |
- // | e0 e4 e8 e12 |
- // | e1 e5 e9 e13 |
- // | e2 e6 e10 e14 |
- // | e3 e7 e11 e15 |
-
- void Matrix::transform(vertex * dst, const vertex * src, int size) const
- {
- for (int i = 0; i<size; ++i)
- {
- // Store in temp variables in case src = dst
- float x = (e[0] * src[i].x) + (e[4] * src[i].y) + (0) + (e[12]);
- float y = (e[1] * src[i].x) + (e[5] * src[i].y) + (0) + (e[13]);
-
- dst[i].x = x;
- dst[i].y = y;
- }
- }
-
-} // math
+ namespace math
+ {
+
+ const Matrix Matrix::Identity;
+
+ // | e0 e4 e8 e12 |
+ // | e1 e5 e9 e13 |
+ // | e2 e6 e10 e14 |
+ // | e3 e7 e11 e15 |
+
+ Matrix::Matrix()
+ {
+ setIdentity();
+ }
+
+ Matrix::~Matrix()
+ {
+ }
+
+ void Matrix::setOrtho(float l, float r, float b, float t, float n, float f)
+ {
+ setIdentity();
+ float w = r - l;
+ float h = t - b;
+ float z = f - n;
+ e[0] = 2 / w;
+ e[5] = 2 / h;
+ e[10] = -2 / z;
+ e[12] = -(r + l) / w;
+ e[13] = -(t + b) / h;
+ e[14] = -(f + n) / z;
+ e[15] = 1;
+ }
+
+ // | e0 e4 e8 e12 |
+ // | e1 e5 e9 e13 |
+ // | e2 e6 e10 e14 |
+ // | e3 e7 e11 e15 |
+ // | e0 e4 e8 e12 |
+ // | e1 e5 e9 e13 |
+ // | e2 e6 e10 e14 |
+ // | e3 e7 e11 e15 |
+
+ Matrix Matrix::operator * (const Matrix & m) const
+ {
+ Matrix t;
+
+ t.e[0] = (e[0] * m.e[0]) + (e[4] * m.e[1]) + (e[8] * m.e[2]) + (e[12] * m.e[3]);
+ t.e[4] = (e[0] * m.e[4]) + (e[4] * m.e[5]) + (e[8] * m.e[6]) + (e[12] * m.e[7]);
+ t.e[8] = (e[0] * m.e[8]) + (e[4] * m.e[9]) + (e[8] * m.e[10]) + (e[12] * m.e[11]);
+ t.e[12] = (e[0] * m.e[12]) + (e[4] * m.e[13]) + (e[8] * m.e[14]) + (e[12] * m.e[15]);
+
+ t.e[1] = (e[1] * m.e[0]) + (e[5] * m.e[1]) + (e[9] * m.e[2]) + (e[13] * m.e[3]);
+ t.e[5] = (e[1] * m.e[4]) + (e[5] * m.e[5]) + (e[9] * m.e[6]) + (e[13] * m.e[7]);
+ t.e[9] = (e[1] * m.e[8]) + (e[5] * m.e[9]) + (e[9] * m.e[10]) + (e[13] * m.e[11]);
+ t.e[13] = (e[1] * m.e[12]) + (e[5] * m.e[13]) + (e[9] * m.e[14]) + (e[13] * m.e[15]);
+
+ t.e[2] = (e[2] * m.e[0]) + (e[6] * m.e[1]) + (e[10] * m.e[2]) + (e[14] * m.e[3]);
+ t.e[6] = (e[2] * m.e[4]) + (e[6] * m.e[5]) + (e[10] * m.e[6]) + (e[14] * m.e[7]);
+ t.e[10] = (e[2] * m.e[8]) + (e[6] * m.e[9]) + (e[10] * m.e[10]) + (e[14] * m.e[11]);
+ t.e[14] = (e[2] * m.e[12]) + (e[6] * m.e[13]) + (e[10] * m.e[14]) + (e[14] * m.e[15]);
+
+ t.e[3] = (e[3] * m.e[0]) + (e[7] * m.e[1]) + (e[11] * m.e[2]) + (e[15] * m.e[3]);
+ t.e[7] = (e[3] * m.e[4]) + (e[7] * m.e[5]) + (e[11] * m.e[6]) + (e[15] * m.e[7]);
+ t.e[11] = (e[3] * m.e[8]) + (e[7] * m.e[9]) + (e[11] * m.e[10]) + (e[15] * m.e[11]);
+ t.e[15] = (e[3] * m.e[12]) + (e[7] * m.e[13]) + (e[11] * m.e[14]) + (e[15] * m.e[15]);
+
+ return t;
+ }
+
+ void Matrix::operator *= (const Matrix & m)
+ {
+ Matrix t = (*this) * m;
+ memcpy((void*)this->e, (void*)t.e, sizeof(float) * 16);
+ }
+
+ const float * Matrix::getElements() const
+ {
+ return e;
+ }
+
+ void Matrix::setIdentity()
+ {
+ memset(e, 0, sizeof(float) * 16);
+ e[0] = e[5] = e[10] = e[15] = 1;
+ }
+
+ void Matrix::setTranslation(float x, float y)
+ {
+ setIdentity();
+ e[12] = x;
+ e[13] = y;
+ }
+
+ void Matrix::setRotation(float rad)
+ {
+ setIdentity();
+ float c = cos(rad), s = sin(rad);
+ e[0] = c; e[4] = -s;
+ e[1] = s; e[5] = c;
+ }
+
+ void Matrix::setScale(float sx, float sy)
+ {
+ setIdentity();
+ e[0] = sx;
+ e[5] = sy;
+ }
+
+ void Matrix::setShear(float kx, float ky)
+ {
+ setIdentity();
+ e[1] = ky;
+ e[4] = kx;
+ }
+
+ void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy)
+ {
+ memset(e, 0, sizeof(float) * 16); // zero out matrix
+ float c = cos(angle), s = sin(angle);
+ // matrix multiplication carried out on paper:
+ // |1 x| |c -s | |sx | |1 -ox|
+ // | 1 y| |s c | | sy | | 1 -oy|
+ // | 1 | | 1 | | 1 | | 1 |
+ // | 1| | 1| | 1| | 1 |
+ // move rotate scale origin
+ e[10] = e[15] = 1.0f;
+ e[0] = c * sx ; // = a
+ e[1] = s * sx ; // = b
+ e[4] = - s * sy; // = c
+ e[5] = c * sy; // = d
+ e[12] = x - ox * e[0] - oy * e[4];
+ e[13] = y - ox * e[1] - oy * e[5];
+ }
+
+ void Matrix::translate(float x, float y)
+ {
+ Matrix t;
+ t.setTranslation(x, y);
+ this->operator *=(t);
+ }
+
+ void Matrix::rotate(float rad)
+ {
+ Matrix t;
+ t.setRotation(rad);
+ this->operator *=(t);
+ }
+
+ void Matrix::scale(float sx, float sy)
+ {
+ Matrix t;
+ t.setScale(sx, sy);
+ this->operator *=(t);
+ }
+
+ void Matrix::shear(float kx, float ky)
+ {
+ Matrix t;
+ t.setShear(kx, ky);
+ this->operator *=(t);
+ }
+
+ // | x |
+ // | y |
+ // | 0 |
+ // | 1 |
+ // | e0 e4 e8 e12 |
+ // | e1 e5 e9 e13 |
+ // | e2 e6 e10 e14 |
+ // | e3 e7 e11 e15 |
+
+ void Matrix::transform(vertex * dst, const vertex * src, int size) const
+ {
+ for (int i = 0; i<size; ++i)
+ {
+ // Store in temp variables in case src = dst
+ float x = (e[0] * src[i].x) + (e[4] * src[i].y) + (0) + (e[12]);
+ float y = (e[1] * src[i].x) + (e[5] * src[i].y) + (0) + (e[13]);
+
+ dst[i].x = x;
+ dst[i].y = y;
+ }
+ }
+
+ } // math
} // jin \ No newline at end of file
diff --git a/src/libjin/math/matrix.h b/src/libjin/math/matrix.h
index 52fc9c8..c1f903a 100644
--- a/src/libjin/math/matrix.h
+++ b/src/libjin/math/matrix.h
@@ -3,157 +3,157 @@
namespace jin
{
-namespace math
-{
-
- struct vertex
- {
- unsigned char r, g, b, a;
- float x, y;
- float s, t;
- };
- /**
- * This class is the basis for all transformations in LOVE. Althought not
- * really needed for 2D, it contains 4x4 elements to be compatible with
- * OpenGL without conversions.
- * Ҫתõľ
- * https://blog.csdn.net/candycat1992/article/details/8830894
- **/
- class Matrix
- {
- private:
-
- /**
- * | e0 e4 e8 e12 |
- * | e1 e5 e9 e13 |
- * | e2 e6 e10 e14 |
- * | e3 e7 e11 e15 |
- **/
- float e[16];
-
- public:
-
- static const Matrix Identity;
-
- /**
- * Creates a new identity matrix.
- **/
- Matrix();
-
- /**
- * Destructor.
- **/
- ~Matrix();
-
- void setOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far);
-
- /**
- * Multiplies this Matrix with another Matrix, changing neither.
- * @param m The Matrix to multiply with this Matrix.
- * @return The combined matrix.
- **/
- Matrix operator * (const Matrix & m) const;
-
- /**
- * Multiplies a Matrix into this Matrix.
- * @param m The Matrix to combine into this Matrix.
- **/
- void operator *= (const Matrix & m);
-
- /**
- * Gets a pointer to the 16 array elements.
- * @return The array elements.
- **/
- const float * getElements() const;
-
- /**
- * Resets this Matrix to the identity matrix.
- **/
- void setIdentity();
-
- /**
- * Resets this Matrix to a translation.
- * @param x Translation along x-axis.
- * @param y Translation along y-axis.
- **/
- void setTranslation(float x, float y);
-
- /**
- * Resets this Matrix to a rotation.
- * @param r The angle in radians.
- **/
- void setRotation(float r);
-
- /**
- * Resets this Matrix to a scale transformation.
- * @param sx Scale factor along the x-axis.
- * @param sy Scale factor along the y-axis.
- **/
- void setScale(float sx, float sy);
-
- /**
- * Resets this Matrix to a shear transformation.
- * @param kx Shear along x-axis.
- * @param ky Shear along y-axis.
- **/
- void setShear(float kx, float ky);
-
- /**
- * Creates a transformation with a certain position, orientation, scale
- * and offset. Perfect for Drawables -- what a coincidence!
- *
- * @param x The translation along the x-axis.
- * @param y The translation along the y-axis.
- * @param angle The rotation (rad) around the center with offset (ox,oy).
- * @param sx Scale along x-axis.
- * @param sy Scale along y-axis.
- * @param ox The offset for rotation along the x-axis.
- * @param oy The offset for rotation along the y-axis.
- * @param kx Shear along x-axis
- * @param ky Shear along y-axis
- **/
- void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy);
-
- /**
- * Multiplies this Matrix with a translation.
- * @param x Translation along x-axis.
- * @param y Translation along y-axis.
- **/
- void translate(float x, float y);
-
- /**
- * Multiplies this Matrix with a rotation.
- * @param r Angle in radians.
- **/
- void rotate(float r);
-
- /**
- * Multiplies this Matrix with a scale transformation.
- * @param sx Scale factor along the x-axis.
- * @param sy Scale factor along the y-axis.
- **/
- void scale(float sx, float sy);
-
- /**
- * Multiplies this Matrix with a shear transformation.
- * @param kx Shear along the x-axis.
- * @param ky Shear along the y-axis.
- **/
- void shear(float kx, float ky);
-
- /**
- * Transforms an array of vertices by this Matrix. The sources and
- * destination arrays may be the same.
- *
- * @param dst Storage for the transformed vertices.
- * @param src The source vertices.
- * @param size The number of vertices.
- **/
- void transform(vertex * dst, const vertex * src, int size) const;
-
- };
-
-} // math
+ namespace math
+ {
+
+ struct vertex
+ {
+ unsigned char r, g, b, a;
+ float x, y;
+ float s, t;
+ };
+ /**
+ * This class is the basis for all transformations in LOVE. Althought not
+ * really needed for 2D, it contains 4x4 elements to be compatible with
+ * OpenGL without conversions.
+ * Ҫתõľ
+ * https://blog.csdn.net/candycat1992/article/details/8830894
+ **/
+ class Matrix
+ {
+ private:
+
+ /**
+ * | e0 e4 e8 e12 |
+ * | e1 e5 e9 e13 |
+ * | e2 e6 e10 e14 |
+ * | e3 e7 e11 e15 |
+ **/
+ float e[16];
+
+ public:
+
+ static const Matrix Identity;
+
+ /**
+ * Creates a new identity matrix.
+ **/
+ Matrix();
+
+ /**
+ * Destructor.
+ **/
+ ~Matrix();
+
+ void setOrtho(float _left, float _right, float _bottom, float _top, float _near, float _far);
+
+ /**
+ * Multiplies this Matrix with another Matrix, changing neither.
+ * @param m The Matrix to multiply with this Matrix.
+ * @return The combined matrix.
+ **/
+ Matrix operator * (const Matrix & m) const;
+
+ /**
+ * Multiplies a Matrix into this Matrix.
+ * @param m The Matrix to combine into this Matrix.
+ **/
+ void operator *= (const Matrix & m);
+
+ /**
+ * Gets a pointer to the 16 array elements.
+ * @return The array elements.
+ **/
+ const float * getElements() const;
+
+ /**
+ * Resets this Matrix to the identity matrix.
+ **/
+ void setIdentity();
+
+ /**
+ * Resets this Matrix to a translation.
+ * @param x Translation along x-axis.
+ * @param y Translation along y-axis.
+ **/
+ void setTranslation(float x, float y);
+
+ /**
+ * Resets this Matrix to a rotation.
+ * @param r The angle in radians.
+ **/
+ void setRotation(float r);
+
+ /**
+ * Resets this Matrix to a scale transformation.
+ * @param sx Scale factor along the x-axis.
+ * @param sy Scale factor along the y-axis.
+ **/
+ void setScale(float sx, float sy);
+
+ /**
+ * Resets this Matrix to a shear transformation.
+ * @param kx Shear along x-axis.
+ * @param ky Shear along y-axis.
+ **/
+ void setShear(float kx, float ky);
+
+ /**
+ * Creates a transformation with a certain position, orientation, scale
+ * and offset. Perfect for Drawables -- what a coincidence!
+ *
+ * @param x The translation along the x-axis.
+ * @param y The translation along the y-axis.
+ * @param angle The rotation (rad) around the center with offset (ox,oy).
+ * @param sx Scale along x-axis.
+ * @param sy Scale along y-axis.
+ * @param ox The offset for rotation along the x-axis.
+ * @param oy The offset for rotation along the y-axis.
+ * @param kx Shear along x-axis
+ * @param ky Shear along y-axis
+ **/
+ void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy);
+
+ /**
+ * Multiplies this Matrix with a translation.
+ * @param x Translation along x-axis.
+ * @param y Translation along y-axis.
+ **/
+ void translate(float x, float y);
+
+ /**
+ * Multiplies this Matrix with a rotation.
+ * @param r Angle in radians.
+ **/
+ void rotate(float r);
+
+ /**
+ * Multiplies this Matrix with a scale transformation.
+ * @param sx Scale factor along the x-axis.
+ * @param sy Scale factor along the y-axis.
+ **/
+ void scale(float sx, float sy);
+
+ /**
+ * Multiplies this Matrix with a shear transformation.
+ * @param kx Shear along the x-axis.
+ * @param ky Shear along the y-axis.
+ **/
+ void shear(float kx, float ky);
+
+ /**
+ * Transforms an array of vertices by this Matrix. The sources and
+ * destination arrays may be the same.
+ *
+ * @param dst Storage for the transformed vertices.
+ * @param src The source vertices.
+ * @param size The number of vertices.
+ **/
+ void transform(vertex * dst, const vertex * src, int size) const;
+
+ };
+
+ } // math
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/math/quad.h b/src/libjin/math/quad.h
index ed41270..c649cf7 100644
--- a/src/libjin/math/quad.h
+++ b/src/libjin/math/quad.h
@@ -3,15 +3,15 @@
namespace jin
{
-namespace math
-{
+ namespace math
+ {
- struct Quad
- {
- float x, y, w, h;
- };
+ struct Quad
+ {
+ float x, y, w, h;
+ };
-} // math
+ } // math
} // jin
#endif \ No newline at end of file
diff --git a/src/libjin/net/net.cpp b/src/libjin/net/net.cpp
index e6c3d98..8fd4256 100644
--- a/src/libjin/net/net.cpp
+++ b/src/libjin/net/net.cpp
@@ -2,23 +2,23 @@
namespace jin
{
-namespace net
-{
+ namespace net
+ {
- bool Net::initSystem(const SettingBase* setting)
- {
- #ifdef _WIN32
- #if LIBJIN_NET_TEKCOS
- tk_init();
- #endif
- #endif
- return true;
- }
+ bool Net::initSystem(const SettingBase* setting)
+ {
+ #ifdef _WIN32
+ #if LIBJIN_NET_TEKCOS
+ tk_init();
+ #endif
+ #endif
+ return true;
+ }
- void Net::quitSystem()
- {
+ void Net::quitSystem()
+ {
- }
+ }
-} // net
+ } // net
} // jin \ No newline at end of file
diff --git a/src/libjin/net/net.h b/src/libjin/net/net.h
index 27353dc..b5f999f 100644
--- a/src/libjin/net/net.h
+++ b/src/libjin/net/net.h
@@ -8,23 +8,23 @@
namespace jin
{
-namespace net
-{
+ namespace net
+ {
- class Net : public Subsystem<Net>
- {
- public:
+ class Net : public Subsystem<Net>
+ {
+ public:
- protected:
- SINGLETON(Net);
- Net() {};
- ~Net() {};
- bool initSystem(const SettingBase* setting) override;
- void quitSystem() override;
+ protected:
+ SINGLETON(Net);
+ Net() {};
+ ~Net() {};
+ bool initSystem(const SettingBase* setting) override;
+ void quitSystem() override;
- };
+ };
-} // net
+ } // net
} // jin
#endif // LIBJIN_MODULES_NET
diff --git a/src/libjin/thread/thread.cpp b/src/libjin/thread/thread.cpp
index 971fc03..0703f1b 100644
--- a/src/libjin/thread/thread.cpp
+++ b/src/libjin/thread/thread.cpp
@@ -5,297 +5,297 @@
namespace jin
{
-namespace thread
-{
-
- class Mutex
- {
- public:
- Mutex();
- ~Mutex();
-
- void lock();
- void unlock();
- private:
- #if LIBJIN_THREAD_SDL
- SDL_mutex* mutex;
- #endif
- friend class Conditional;
- };
-
- // ̼߳signal wait
- class Conditional
- {
- public:
- Conditional();
- ~Conditional();
- void signal();
- void broadcast();
- bool wait(Mutex* mutex, int timeout = -1);
- private:
- #if LIBJIN_THREAD_SDL
- SDL_cond* cond;
- #endif
- };
-
- class Lock
- {
- public:
- Lock(Mutex* m) : mutex(m) {
- mutex->lock();
- }
-
- Lock(Mutex& m) : mutex(&m) {
- mutex->lock();
- }
-
- ~Lock() {
- mutex->unlock();
- }
- private:
- Mutex* mutex;
-
- Lock(Lock&) {}
-
- };
-
- //////////////////////////////////////////////////////////////////////
+ namespace thread
+ {
+
+ class Mutex
+ {
+ public:
+ Mutex();
+ ~Mutex();
+
+ void lock();
+ void unlock();
+ private:
+ #if LIBJIN_THREAD_SDL
+ SDL_mutex* mutex;
+ #endif
+ friend class Conditional;
+ };
+
+ // ̼߳signal wait
+ class Conditional
+ {
+ public:
+ Conditional();
+ ~Conditional();
+ void signal();
+ void broadcast();
+ bool wait(Mutex* mutex, int timeout = -1);
+ private:
+ #if LIBJIN_THREAD_SDL
+ SDL_cond* cond;
+ #endif
+ };
+
+ class Lock
+ {
+ public:
+ Lock(Mutex* m) : mutex(m) {
+ mutex->lock();
+ }
+
+ Lock(Mutex& m) : mutex(&m) {
+ mutex->lock();
+ }
+
+ ~Lock() {
+ mutex->unlock();
+ }
+ private:
+ Mutex* mutex;
+
+ Lock(Lock&) {}
+
+ };
+
+ //////////////////////////////////////////////////////////////////////
- Mutex::Mutex()
- {
- #if LIBJIN_THREAD_SDL
- mutex = SDL_CreateMutex();
- #endif
- }
-
- Mutex::~Mutex()
- {
- #if LIBJIN_THREAD_SDL
- SDL_DestroyMutex(mutex);
- #endif
- }
-
- void Mutex::lock()
- {
- #if LIBJIN_THREAD_SDL
- SDL_LockMutex(mutex);
- #endif
- }
-
- void Mutex::unlock()
- {
- #if LIBJIN_THREAD_SDL
- SDL_UnlockMutex(mutex);
- #endif
- }
-
- //////////////////////////////////////////////////////////////////////
-
- Conditional::Conditional()
- {
- #if LIBJIN_THREAD_SDL
- cond = SDL_CreateCond();
- #endif
- }
-
- Conditional::~Conditional()
- {
- #if LIBJIN_THREAD_SDL
- SDL_DestroyCond(cond);
- #endif
- }
-
- void Conditional::signal()
- {
- #if LIBJIN_THREAD_SDL
- SDL_CondSignal(cond);
- #endif
- }
-
- void Conditional::broadcast()
- {
- #if LIBJIN_THREAD_SDL
- SDL_CondBroadcast(cond);
- #endif
- }
-
- bool Conditional::wait(Mutex* mutex, int timeout)
- {
- #if LIBJIN_THREAD_SDL
- if (timeout < 0)
- return !SDL_CondWait(cond, mutex->mutex);
- else
- return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0);
- #endif
- }
+ Mutex::Mutex()
+ {
+ #if LIBJIN_THREAD_SDL
+ mutex = SDL_CreateMutex();
+ #endif
+ }
+
+ Mutex::~Mutex()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_DestroyMutex(mutex);
+ #endif
+ }
+
+ void Mutex::lock()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_LockMutex(mutex);
+ #endif
+ }
+
+ void Mutex::unlock()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_UnlockMutex(mutex);
+ #endif
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ Conditional::Conditional()
+ {
+ #if LIBJIN_THREAD_SDL
+ cond = SDL_CreateCond();
+ #endif
+ }
+
+ Conditional::~Conditional()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_DestroyCond(cond);
+ #endif
+ }
+
+ void Conditional::signal()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_CondSignal(cond);
+ #endif
+ }
+
+ void Conditional::broadcast()
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_CondBroadcast(cond);
+ #endif
+ }
+
+ bool Conditional::wait(Mutex* mutex, int timeout)
+ {
+ #if LIBJIN_THREAD_SDL
+ if (timeout < 0)
+ return !SDL_CondWait(cond, mutex->mutex);
+ else
+ return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0);
+ #endif
+ }
- //////////////////////////////////////////////////////////////////////
-
- Thread::ThreadData::ThreadData(Mutex* m, Conditional* c)
- : mutex(m)
- , condition(c)
- , share()
- {
- }
-
- Thread::ThreadData::~ThreadData()
- {
- }
-
- void Thread::ThreadData::set(int slot, Variant value)
- {
- Lock l(mutex);
- share[slot] = value;
- }
-
- Thread::Variant Thread::ThreadData::get(int slot)
- {
- Lock l(mutex);
- return share[slot];
- }
-
- bool Thread::ThreadData::exist(int slot)
- {
- Lock l(mutex);
- return share.count(slot) == 1;
- }
-
- void Thread::ThreadData::remove(int slot)
- {
- Lock l(mutex);
- if (exist(slot))
- {
- share.erase(slot);
- }
- }
-
- //////////////////////////////////////////////////////////////////////
-
- Thread::Thread(const std::string tname, ThreadRunner runner)
- : name(tname)
- , running(false)
- , threadRunner(runner)
- {
- mutex = new Mutex();
- condition = new Conditional();
- common = new Thread::ThreadData(mutex, condition);
- }
-
- Thread::~Thread()
- {
- #if LIBJIN_THREAD_SDL
- #endif
- }
-
- const char* Thread::getName()
- {
- Lock l(mutex);
- return name.c_str();
- };
+ //////////////////////////////////////////////////////////////////////
+
+ Thread::ThreadData::ThreadData(Mutex* m, Conditional* c)
+ : mutex(m)
+ , condition(c)
+ , share()
+ {
+ }
+
+ Thread::ThreadData::~ThreadData()
+ {
+ }
+
+ void Thread::ThreadData::set(int slot, Variant value)
+ {
+ Lock l(mutex);
+ share[slot] = value;
+ }
+
+ Thread::Variant Thread::ThreadData::get(int slot)
+ {
+ Lock l(mutex);
+ return share[slot];
+ }
+
+ bool Thread::ThreadData::exist(int slot)
+ {
+ Lock l(mutex);
+ return share.count(slot) == 1;
+ }
+
+ void Thread::ThreadData::remove(int slot)
+ {
+ Lock l(mutex);
+ if (exist(slot))
+ {
+ share.erase(slot);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ Thread::Thread(const std::string tname, ThreadRunner runner)
+ : name(tname)
+ , running(false)
+ , threadRunner(runner)
+ {
+ mutex = new Mutex();
+ condition = new Conditional();
+ common = new Thread::ThreadData(mutex, condition);
+ }
+
+ Thread::~Thread()
+ {
+ #if LIBJIN_THREAD_SDL
+ #endif
+ }
+
+ const char* Thread::getName()
+ {
+ Lock l(mutex);
+ return name.c_str();
+ };
- bool Thread::isRunning()
- {
- Lock l(mutex);
- return running;
- };
-
- bool Thread::start(void* p)
- {
- Lock l(mutex);
- if (running)
- return false;
- if (handle)
- {
- #if LIBJIN_THREAD_SDL
- SDL_WaitThread(handle, nullptr);
- #endif
- }
- #if LIBJIN_THREAD_SDL
- handle = SDL_CreateThread(threadRunner, name.c_str(), p);
- #elif LIBJIN_THREAD_CPP
- handle = new std::thread();
- #endif
- return (running = (handle != nullptr));
- }
-
- void Thread::wait()
- {
- {
- Lock l(mutex);
- if (!handle)
- return;
- }
- #if LIBJIN_THREAD_SDL
- SDL_WaitThread(handle, nullptr);
- #endif
- Lock l(mutex);
- running = false;
- handle = nullptr;
- }
-
- void Thread::lock()
- {
- if (mutex != nullptr)
- mutex->lock();
- }
-
- void Thread::unlock()
- {
- if (mutex != nullptr)
- mutex->unlock();
- }
-
- void Thread::send(int slot, const Variant& value)
- {
- lock();
- common->set(slot, value);
- unlock();
- condition->broadcast();
- }
-
- bool Thread::receive(int slot)
- {
- return common->exist(slot);
- }
-
- Thread::Variant Thread::fetch(int slot)
- {
- Thread::Variant v = common->get(slot);
- return v;
- }
-
- Thread::Variant Thread::demand(int slot)
- {
- /**
- * pthread_mutex_lock(mtx);
- * while(pass == 0)
- * {
- * pthread_mutex_unlock(mtx);
- * pthread_cond_just_wait(cv);
- * pthread_mutex_lock(mtx);
- * }
- * pthread_mutex_unlock(mtx);
- */
- lock();
- while (!common->exist(slot))
- {
- if (common->exist(ThreadData::SLOT_ERROR))
- return 0;
- condition->wait(mutex);
- }
- Thread::Variant v = common->get(slot);
- unlock();
- return v;
- }
-
- void Thread::remove(int slot)
- {
- lock();
- common->remove(slot);
- unlock();
- }
-
-} // thread
+ bool Thread::isRunning()
+ {
+ Lock l(mutex);
+ return running;
+ };
+
+ bool Thread::start(void* p)
+ {
+ Lock l(mutex);
+ if (running)
+ return false;
+ if (handle)
+ {
+ #if LIBJIN_THREAD_SDL
+ SDL_WaitThread(handle, nullptr);
+ #endif
+ }
+ #if LIBJIN_THREAD_SDL
+ handle = SDL_CreateThread(threadRunner, name.c_str(), p);
+ #elif LIBJIN_THREAD_CPP
+ handle = new std::thread();
+ #endif
+ return (running = (handle != nullptr));
+ }
+
+ void Thread::wait()
+ {
+ {
+ Lock l(mutex);
+ if (!handle)
+ return;
+ }
+ #if LIBJIN_THREAD_SDL
+ SDL_WaitThread(handle, nullptr);
+ #endif
+ Lock l(mutex);
+ running = false;
+ handle = nullptr;
+ }
+
+ void Thread::lock()
+ {
+ if (mutex != nullptr)
+ mutex->lock();
+ }
+
+ void Thread::unlock()
+ {
+ if (mutex != nullptr)
+ mutex->unlock();
+ }
+
+ void Thread::send(int slot, const Variant& value)
+ {
+ lock();
+ common->set(slot, value);
+ unlock();
+ condition->broadcast();
+ }
+
+ bool Thread::receive(int slot)
+ {
+ return common->exist(slot);
+ }
+
+ Thread::Variant Thread::fetch(int slot)
+ {
+ Thread::Variant v = common->get(slot);
+ return v;
+ }
+
+ Thread::Variant Thread::demand(int slot)
+ {
+ /**
+ * pthread_mutex_lock(mtx);
+ * while(pass == 0)
+ * {
+ * pthread_mutex_unlock(mtx);
+ * pthread_cond_just_wait(cv);
+ * pthread_mutex_lock(mtx);
+ * }
+ * pthread_mutex_unlock(mtx);
+ */
+ lock();
+ while (!common->exist(slot))
+ {
+ if (common->exist(ThreadData::SLOT_ERROR))
+ return 0;
+ condition->wait(mutex);
+ }
+ Thread::Variant v = common->get(slot);
+ unlock();
+ return v;
+ }
+
+ void Thread::remove(int slot)
+ {
+ lock();
+ common->remove(slot);
+ unlock();
+ }
+
+ } // thread
} // jin
#endif // LIBJIN_MODULES_THREAD \ No newline at end of file
diff --git a/src/libjin/thread/thread.h b/src/libjin/thread/thread.h
index 3a7b4ba..d6d0a19 100644
--- a/src/libjin/thread/thread.h
+++ b/src/libjin/thread/thread.h
@@ -15,151 +15,151 @@
namespace jin
{
-namespace thread
-{
- /**
- * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ
- * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ
- * ָһԹԴзʵĴ룬һֻƻ㷨һ򡢽̡߳̿ӵжٽ򣬵Dz
- * һӦûҪ˻ƵԴУꡢСжϴڶеĴ
- * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ
- * ߣ߻ָѣ
- */
- class Mutex;
- class Conditional;
+ namespace thread
+ {
+ /**
+ * ӢӢMutual exclusionд Mutexһڶ̱߳Уֹ߳ͬʱͬһԴ
+ * ȫֱждĻơĿͨƬһһٽcritical sectionɡٽ
+ * ָһԹԴзʵĴ룬һֻƻ㷨һ򡢽̡߳̿ӵжٽ򣬵Dz
+ * һӦûҪ˻ƵԴУꡢСжϴڶеĴ
+ * ݡͬ״̬ȵԴάЩԴͬһºǺѵģΪһ߳̿κһʱ̱ͣ
+ * ߣ߻ָѣ
+ */
+ class Mutex;
+ class Conditional;
- /**
- * Thread::demand Receive a message from a thread. Wait for the message to exist before returning.
- * Thread::getName Get the name of a thread.
- * Thread::kill Forcefully terminate the thread.
- * Thread::peek Receive a message from a thread, but leave it in the message box.
- * Thread::receive Receive a message from a thread.
- * Thread::send Send a message.
- * Thread::set Set a value.
- * Thread::start Starts the thread.
- * Thread::wait Wait for a thread to finish.
- */
- class Thread
- {
- public:
- struct Variant
- {
- enum Type
- {
- NONE = 0,
- INTERGER,
- BOOLEAN,
- CHARACTER,
- CSTRING,
- POINTER,
- REAL,
- };
- Type type;
- union
- {
- int integer;
- bool boolean;
- char character;
- const char* cstring;
- void* pointer;
- float real;
- };
- Variant() :type(NONE) {};
- Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); }
- Variant(int i) : integer(i), type(INTERGER) {};
- Variant(float f) : real(f), type(REAL) {};
- Variant(bool b) : boolean(b), type(BOOLEAN) {};
- Variant(char c) : character(c), type(CHARACTER) {};
- Variant(const char* s) : cstring(s), type(CSTRING) {};
- Variant(void* p) : pointer(p), type(POINTER) {};
- };
+ /**
+ * Thread::demand Receive a message from a thread. Wait for the message to exist before returning.
+ * Thread::getName Get the name of a thread.
+ * Thread::kill Forcefully terminate the thread.
+ * Thread::peek Receive a message from a thread, but leave it in the message box.
+ * Thread::receive Receive a message from a thread.
+ * Thread::send Send a message.
+ * Thread::set Set a value.
+ * Thread::start Starts the thread.
+ * Thread::wait Wait for a thread to finish.
+ */
+ class Thread
+ {
+ public:
+ struct Variant
+ {
+ enum Type
+ {
+ NONE = 0,
+ INTERGER,
+ BOOLEAN,
+ CHARACTER,
+ CSTRING,
+ POINTER,
+ REAL,
+ };
+ Type type;
+ union
+ {
+ int integer;
+ bool boolean;
+ char character;
+ const char* cstring;
+ void* pointer;
+ float real;
+ };
+ Variant() :type(NONE) {};
+ Variant(const Variant& v){ memcpy(this, &v, sizeof(v)); }
+ Variant(int i) : integer(i), type(INTERGER) {};
+ Variant(float f) : real(f), type(REAL) {};
+ Variant(bool b) : boolean(b), type(BOOLEAN) {};
+ Variant(char c) : character(c), type(CHARACTER) {};
+ Variant(const char* s) : cstring(s), type(CSTRING) {};
+ Variant(void* p) : pointer(p), type(POINTER) {};
+ };
- private:
- class ThreadData
- {
- public:
- static const int SLOT_ERROR = -1;
- static const int SLOT_WARN = -2;
- static const int SLOT_INFO = -3;
- static const int SLOT_DEBUG = -4;
+ private:
+ class ThreadData
+ {
+ public:
+ static const int SLOT_ERROR = -1;
+ static const int SLOT_WARN = -2;
+ static const int SLOT_INFO = -3;
+ static const int SLOT_DEBUG = -4;
- ThreadData(Mutex*, Conditional*);
- ~ThreadData();
- bool exist(int slot);
- void set(int slot, Variant value);
- Variant get(int slot);
- void remove(int slot);
+ ThreadData(Mutex*, Conditional*);
+ ~ThreadData();
+ bool exist(int slot);
+ void set(int slot, Variant value);
+ Variant get(int slot);
+ void remove(int slot);
- Conditional* condition;
- Mutex* mutex;
+ Conditional* condition;
+ Mutex* mutex;
- private:
- std::map<int, Variant> share; // threads shared value
+ private:
+ std::map<int, Variant> share; // threads shared value
- };
+ };
- public:
- typedef int(*ThreadRunner)(void* obj);
+ public:
+ typedef int(*ThreadRunner)(void* obj);
- Thread(const std::string name, ThreadRunner threadfuncs);
- ~Thread();
- bool start(void* p);
- void wait();
- void send(int slot, const Variant& value);
- bool receive(int slot);
- Variant fetch(int slot);
- Variant demand(int slot);
- void remove(int slot);
- const char* getName();
- bool isRunning();
- void lock();
- void unlock();
+ Thread(const std::string name, ThreadRunner threadfuncs);
+ ~Thread();
+ bool start(void* p);
+ void wait();
+ void send(int slot, const Variant& value);
+ bool receive(int slot);
+ Variant fetch(int slot);
+ Variant demand(int slot);
+ void remove(int slot);
+ const char* getName();
+ bool isRunning();
+ void lock();
+ void unlock();
- protected:
- #if LIBJIN_THREAD_SDL
- SDL_Thread* handle; // SDL thread
- #elif LIBJIN_THREAD_CPP
- std::thread* handle; // cpp thread
- #endif
- Mutex* mutex; // mutex variable
- Conditional* condition; // condition variable
- ThreadRunner threadRunner; // thread function
- ThreadData* common; // threads common data
- const std::string name; // thread name, for debugging purposes
- /**
- * https://stackoverflow.com/questions/149932/naming-conventions-for-threads
- *
- * Use short names because they don't make the lines in a log file too long.
- *
- * Create names where the important part is at the beginning. Log viewers in a
- * graphical user interface tend to have tables with columns, and the thread
- * column is usually small or will be made small by you to read everything else.
- *
- * Do not use the word "thread" in the thread name because it is obvious.
- *
- * Make the thread names easily grep-able. Avoid similar sounding thread names
- *
- * If you have several threads of the same nature, enumerate them with IDs that
- * are unique to one execution of the application or one log file, whichever fits
- * your logging habits.
- *
- * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker
- * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or
- * "Calculation" (what does it calculate?).
- *
- * If you have a test group that uses thread names to grep your application's log
- * files, do not rename your threads after some time. Your testers will hate you for
- * doing so. Thread names in well-tested applications should be there to stay.
- *
- * When you have threads that service a network connection, try to include the target
- * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about
- * enumeration though if there are multiple connections to the same host.
- */
- bool running; // running
+ protected:
+ #if LIBJIN_THREAD_SDL
+ SDL_Thread* handle; // SDL thread
+ #elif LIBJIN_THREAD_CPP
+ std::thread* handle; // cpp thread
+ #endif
+ Mutex* mutex; // mutex variable
+ Conditional* condition; // condition variable
+ ThreadRunner threadRunner; // thread function
+ ThreadData* common; // threads common data
+ const std::string name; // thread name, for debugging purposes
+ /**
+ * https://stackoverflow.com/questions/149932/naming-conventions-for-threads
+ *
+ * Use short names because they don't make the lines in a log file too long.
+ *
+ * Create names where the important part is at the beginning. Log viewers in a
+ * graphical user interface tend to have tables with columns, and the thread
+ * column is usually small or will be made small by you to read everything else.
+ *
+ * Do not use the word "thread" in the thread name because it is obvious.
+ *
+ * Make the thread names easily grep-able. Avoid similar sounding thread names
+ *
+ * If you have several threads of the same nature, enumerate them with IDs that
+ * are unique to one execution of the application or one log file, whichever fits
+ * your logging habits.
+ *
+ * Avoid generalizations like "WorkerThread" (how do you name the next 5 worker
+ * threads?), "GUIThread" (which GUI? is it for one window? for everything?) or
+ * "Calculation" (what does it calculate?).
+ *
+ * If you have a test group that uses thread names to grep your application's log
+ * files, do not rename your threads after some time. Your testers will hate you for
+ * doing so. Thread names in well-tested applications should be there to stay.
+ *
+ * When you have threads that service a network connection, try to include the target
+ * network address in the thread name (e.g. channel_123.212.123.3). Don't forget about
+ * enumeration though if there are multiple connections to the same host.
+ */
+ bool running; // running
- };
+ };
-} // thread
+ } // thread
} // jin
#endif // LIBJIN_MODULES_THREAD