From 7d5f055547e70fa93ee9ac944e62f8d657b9dc55 Mon Sep 17 00:00:00 2001 From: chai Date: Fri, 19 Oct 2018 08:36:44 +0800 Subject: =?UTF-8?q?*=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libjin/Audio/Audio.cpp | 15 - src/libjin/Audio/Audio.h | 52 --- src/libjin/Audio/SDL/SDLAudio.cpp | 141 -------- src/libjin/Audio/SDL/SDLAudio.h | 60 ---- src/libjin/Audio/SDL/SDLSource.cpp | 399 ---------------------- src/libjin/Audio/SDL/SDLSource.h | 107 ------ src/libjin/Audio/SDL/je_sdl_audio.cpp | 143 ++++++++ src/libjin/Audio/SDL/je_sdl_audio.h | 62 ++++ src/libjin/Audio/SDL/je_sdl_source.cpp | 401 ++++++++++++++++++++++ src/libjin/Audio/SDL/je_sdl_source.h | 107 ++++++ src/libjin/Audio/Source.cpp | 29 -- src/libjin/Audio/Source.h | 47 --- src/libjin/Audio/je_audio.cpp | 15 + src/libjin/Audio/je_audio.h | 53 +++ src/libjin/Audio/je_source.cpp | 30 ++ src/libjin/Audio/je_source.h | 47 +++ src/libjin/Common/Array.hpp | 83 ----- src/libjin/Common/Exception.cpp | 0 src/libjin/Common/Exception.h | 0 src/libjin/Common/Object.cpp | 32 -- src/libjin/Common/Object.h | 49 --- src/libjin/Common/Singleton.hpp | 37 -- src/libjin/Common/StringMap.hpp | 143 -------- src/libjin/Common/Subsystem.hpp | 43 --- src/libjin/Common/common.h | 6 - src/libjin/Common/je_array.hpp | 86 +++++ src/libjin/Common/je_common.h | 6 + src/libjin/Common/je_exception.cpp | 0 src/libjin/Common/je_exception.h | 0 src/libjin/Common/je_object.cpp | 32 ++ src/libjin/Common/je_object.h | 49 +++ src/libjin/Common/je_singleton.hpp | 37 ++ src/libjin/Common/je_stringmap.hpp | 143 ++++++++ src/libjin/Common/je_subsystem.hpp | 44 +++ src/libjin/Common/je_types.h | 23 ++ src/libjin/Common/je_utf8.cpp | 42 +++ src/libjin/Common/je_utf8.h | 31 ++ src/libjin/Common/types.h | 23 -- src/libjin/Common/utf8.cpp | 42 --- src/libjin/Common/utf8.h | 31 -- src/libjin/Filesystem/Buffer.h | 67 ---- src/libjin/Filesystem/Filesystem.cpp | 67 ---- src/libjin/Filesystem/Filesystem.h | 31 -- src/libjin/Filesystem/je_buffer.h | 67 ++++ src/libjin/Filesystem/je_filesystem.cpp | 68 ++++ src/libjin/Filesystem/je_filesystem.h | 31 ++ src/libjin/Game/Game.cpp | 72 ---- src/libjin/Game/Game.h | 58 ---- src/libjin/Game/je_game.cpp | 74 ++++ src/libjin/Game/je_game.h | 58 ++++ src/libjin/Graphics/Bitmap.cpp | 150 -------- src/libjin/Graphics/Bitmap.h | 173 ---------- src/libjin/Graphics/Canvas.cpp | 102 ------ src/libjin/Graphics/Canvas.h | 66 ---- src/libjin/Graphics/Color.cpp | 17 - src/libjin/Graphics/Color.h | 85 ----- src/libjin/Graphics/Drawable.cpp | 123 ------- src/libjin/Graphics/Drawable.h | 89 ----- src/libjin/Graphics/Font/Decoder.cpp | 93 ----- src/libjin/Graphics/Font/Decoder.h | 44 --- src/libjin/Graphics/Font/Font.h | 95 ------ src/libjin/Graphics/Font/Page.h | 38 --- src/libjin/Graphics/Font/TTF.cpp | 454 ------------------------ src/libjin/Graphics/Font/TTF.h | 132 ------- src/libjin/Graphics/Font/Text.cpp | 156 --------- src/libjin/Graphics/Font/Text.h | 74 ---- src/libjin/Graphics/Font/TextureFont.cpp | 300 ---------------- src/libjin/Graphics/Font/TextureFont.h | 62 ---- src/libjin/Graphics/Font/je_decoder.cpp | 93 +++++ src/libjin/Graphics/Font/je_decoder.h | 88 +++++ src/libjin/Graphics/Font/je_font.h | 99 ++++++ src/libjin/Graphics/Font/je_page.h | 51 +++ src/libjin/Graphics/Font/je_text.cpp | 156 +++++++++ src/libjin/Graphics/Font/je_text.h | 79 +++++ src/libjin/Graphics/Font/je_texture_font.cpp | 302 ++++++++++++++++ src/libjin/Graphics/Font/je_texture_font.h | 65 ++++ src/libjin/Graphics/Font/je_ttf.cpp | 456 +++++++++++++++++++++++++ src/libjin/Graphics/Font/je_ttf.h | 134 ++++++++ src/libjin/Graphics/Graphics.h | 21 -- src/libjin/Graphics/Image.cpp | 45 --- src/libjin/Graphics/Image.h | 60 ---- src/libjin/Graphics/Mesh.cpp | 11 - src/libjin/Graphics/Mesh.h | 21 -- src/libjin/Graphics/OpenGL.cpp | 12 - src/libjin/Graphics/OpenGL.h | 29 -- src/libjin/Graphics/Shader/Shader.cpp | 282 --------------- src/libjin/Graphics/Shader/Shader.h | 197 ----------- src/libjin/Graphics/Shader/base.shader.h | 88 ----- src/libjin/Graphics/Shader/default.shader.h | 21 -- src/libjin/Graphics/Shader/font.shader.h | 21 -- src/libjin/Graphics/Shader/je_base.shader.h | 88 +++++ src/libjin/Graphics/Shader/je_default.shader.h | 21 ++ src/libjin/Graphics/Shader/je_font.shader.h | 21 ++ src/libjin/Graphics/Shader/je_shader.cpp | 284 +++++++++++++++ src/libjin/Graphics/Shader/je_shader.h | 200 +++++++++++ src/libjin/Graphics/Shader/je_texture.shader.h | 21 ++ src/libjin/Graphics/Shader/texture.shader.h | 21 -- src/libjin/Graphics/Shapes.cpp | 126 ------- src/libjin/Graphics/Shapes.h | 37 -- src/libjin/Graphics/Sprite.cpp | 0 src/libjin/Graphics/Sprite.h | 20 -- src/libjin/Graphics/Texture.cpp | 34 -- src/libjin/Graphics/Texture.h | 43 --- src/libjin/Graphics/Window.cpp | 109 ------ src/libjin/Graphics/Window.h | 56 --- src/libjin/Graphics/je_bitmap.cpp | 151 ++++++++ src/libjin/Graphics/je_bitmap.h | 173 ++++++++++ src/libjin/Graphics/je_canvas.cpp | 102 ++++++ src/libjin/Graphics/je_canvas.h | 66 ++++ src/libjin/Graphics/je_color.cpp | 17 + src/libjin/Graphics/je_color.h | 85 +++++ src/libjin/Graphics/je_drawable.cpp | 125 +++++++ src/libjin/Graphics/je_drawable.h | 90 +++++ src/libjin/Graphics/je_gl.cpp | 12 + src/libjin/Graphics/je_gl.h | 30 ++ src/libjin/Graphics/je_graphics.h | 21 ++ src/libjin/Graphics/je_image.cpp | 46 +++ src/libjin/Graphics/je_image.h | 60 ++++ src/libjin/Graphics/je_mesh.cpp | 11 + src/libjin/Graphics/je_mesh.h | 21 ++ src/libjin/Graphics/je_shapes.cpp | 128 +++++++ src/libjin/Graphics/je_shapes.h | 37 ++ src/libjin/Graphics/je_sprite.cpp | 0 src/libjin/Graphics/je_sprite.h | 20 ++ src/libjin/Graphics/je_texture.cpp | 36 ++ src/libjin/Graphics/je_texture.h | 45 +++ src/libjin/Graphics/je_window.cpp | 111 ++++++ src/libjin/Graphics/je_window.h | 96 ++++++ src/libjin/Input/Event.cpp | 7 - src/libjin/Input/Event.h | 105 ------ src/libjin/Input/Input.h | 9 - src/libjin/Input/Joypad.cpp | 0 src/libjin/Input/Joypad.h | 50 --- src/libjin/Input/Keyboard.cpp | 0 src/libjin/Input/Keyboard.h | 17 - src/libjin/Input/Mouse.cpp | 27 -- src/libjin/Input/Mouse.h | 31 -- src/libjin/Input/je_event.cpp | 8 + src/libjin/Input/je_event.h | 105 ++++++ src/libjin/Input/je_input.h | 9 + src/libjin/Input/je_joypad.cpp | 0 src/libjin/Input/je_joypad.h | 50 +++ src/libjin/Input/je_keyboard.cpp | 0 src/libjin/Input/je_keyboard.h | 17 + src/libjin/Input/je_mouse.cpp | 28 ++ src/libjin/Input/je_mouse.h | 31 ++ src/libjin/Math/Math.h | 77 ----- src/libjin/Math/Matrix.cpp | 194 ----------- src/libjin/Math/Matrix.h | 159 --------- src/libjin/Math/Quad.h | 17 - src/libjin/Math/Vector2.hpp | 40 --- src/libjin/Math/Vector3.hpp | 41 --- src/libjin/Math/Vector4.hpp | 45 --- src/libjin/Math/constant.h | 10 - src/libjin/Math/je_constant.h | 10 + src/libjin/Math/je_math.h | 77 +++++ src/libjin/Math/je_matrix.cpp | 194 +++++++++++ src/libjin/Math/je_matrix.h | 159 +++++++++ src/libjin/Math/je_quad.h | 17 + src/libjin/Math/je_vector2.hpp | 40 +++ src/libjin/Math/je_vector3.hpp | 41 +++ src/libjin/Math/je_vector4.hpp | 45 +++ src/libjin/Net/Net.cpp | 24 -- src/libjin/Net/Net.h | 31 -- src/libjin/Net/Socket.cpp | 190 ----------- src/libjin/Net/Socket.h | 62 ---- src/libjin/Net/je_net.cpp | 24 ++ src/libjin/Net/je_net.h | 32 ++ src/libjin/Net/je_socket.cpp | 190 +++++++++++ src/libjin/Net/je_socket.h | 62 ++++ src/libjin/Net/net.cpp | 24 -- src/libjin/Net/net.h | 31 -- src/libjin/Thread/Thread.cpp | 301 ---------------- src/libjin/Thread/Thread.h | 166 --------- src/libjin/Thread/je_thread.cpp | 301 ++++++++++++++++ src/libjin/Thread/je_thread.h | 166 +++++++++ src/libjin/Thread/thread.cpp | 301 ---------------- src/libjin/Thread/thread.h | 166 --------- src/libjin/Time/Timer.cpp | 100 ------ src/libjin/Time/Timer.h | 77 ----- src/libjin/Time/je_timer.cpp | 100 ++++++ src/libjin/Time/je_timer.h | 77 +++++ src/libjin/Utils/Log.cpp | 2 - src/libjin/Utils/Log.h | 134 -------- src/libjin/Utils/endian.h | 23 -- src/libjin/Utils/je_endian.h | 23 ++ src/libjin/Utils/je_log.cpp | 2 + src/libjin/Utils/je_log.h | 135 ++++++++ src/libjin/Utils/je_macros.h | 17 + src/libjin/Utils/je_unittest.cpp | 108 ++++++ src/libjin/Utils/je_utils.h | 9 + src/libjin/Utils/log.h | 134 -------- src/libjin/Utils/macros.h | 17 - src/libjin/Utils/unittest.cpp | 108 ------ src/libjin/Utils/utils.h | 9 - src/libjin/audio/audio.cpp | 15 - src/libjin/audio/audio.h | 52 --- src/libjin/audio/source.cpp | 29 -- src/libjin/audio/source.h | 47 --- src/libjin/configuration.h | 69 ---- src/libjin/core/je_configuration.h | 69 ++++ src/libjin/core/je_types.h | 24 ++ src/libjin/input/event.cpp | 7 - src/libjin/input/event.h | 105 ------ src/libjin/input/input.h | 9 - src/libjin/input/joypad.cpp | 0 src/libjin/input/joypad.h | 50 --- src/libjin/input/keyboard.cpp | 0 src/libjin/input/keyboard.h | 17 - src/libjin/input/mouse.cpp | 27 -- src/libjin/input/mouse.h | 31 -- src/libjin/jin.h | 24 +- src/libjin/math/constant.h | 10 - src/libjin/math/math.h | 77 ----- src/libjin/math/matrix.cpp | 194 ----------- src/libjin/math/matrix.h | 159 --------- src/libjin/math/quad.h | 17 - src/libjin/net/net.cpp | 24 -- src/libjin/net/net.h | 31 -- src/libjin/thread/thread.cpp | 301 ---------------- src/libjin/thread/thread.h | 166 --------- src/libjin/utils/endian.h | 23 -- src/libjin/utils/log.cpp | 2 - src/libjin/utils/log.h | 134 -------- src/libjin/utils/macros.h | 17 - src/libjin/utils/unittest.cpp | 108 ------ src/libjin/utils/utils.h | 9 - 227 files changed, 7472 insertions(+), 9612 deletions(-) delete mode 100644 src/libjin/Audio/Audio.cpp delete mode 100644 src/libjin/Audio/Audio.h delete mode 100644 src/libjin/Audio/SDL/SDLAudio.cpp delete mode 100644 src/libjin/Audio/SDL/SDLAudio.h delete mode 100644 src/libjin/Audio/SDL/SDLSource.cpp delete mode 100644 src/libjin/Audio/SDL/SDLSource.h create mode 100644 src/libjin/Audio/SDL/je_sdl_audio.cpp create mode 100644 src/libjin/Audio/SDL/je_sdl_audio.h create mode 100644 src/libjin/Audio/SDL/je_sdl_source.cpp create mode 100644 src/libjin/Audio/SDL/je_sdl_source.h delete mode 100644 src/libjin/Audio/Source.cpp delete mode 100644 src/libjin/Audio/Source.h create mode 100644 src/libjin/Audio/je_audio.cpp create mode 100644 src/libjin/Audio/je_audio.h create mode 100644 src/libjin/Audio/je_source.cpp create mode 100644 src/libjin/Audio/je_source.h delete mode 100644 src/libjin/Common/Array.hpp delete mode 100644 src/libjin/Common/Exception.cpp delete mode 100644 src/libjin/Common/Exception.h delete mode 100644 src/libjin/Common/Object.cpp delete mode 100644 src/libjin/Common/Object.h delete mode 100644 src/libjin/Common/Singleton.hpp delete mode 100644 src/libjin/Common/StringMap.hpp delete mode 100644 src/libjin/Common/Subsystem.hpp delete mode 100644 src/libjin/Common/common.h create mode 100644 src/libjin/Common/je_array.hpp create mode 100644 src/libjin/Common/je_common.h create mode 100644 src/libjin/Common/je_exception.cpp create mode 100644 src/libjin/Common/je_exception.h create mode 100644 src/libjin/Common/je_object.cpp create mode 100644 src/libjin/Common/je_object.h create mode 100644 src/libjin/Common/je_singleton.hpp create mode 100644 src/libjin/Common/je_stringmap.hpp create mode 100644 src/libjin/Common/je_subsystem.hpp create mode 100644 src/libjin/Common/je_types.h create mode 100644 src/libjin/Common/je_utf8.cpp create mode 100644 src/libjin/Common/je_utf8.h delete mode 100644 src/libjin/Common/types.h delete mode 100644 src/libjin/Common/utf8.cpp delete mode 100644 src/libjin/Common/utf8.h delete mode 100644 src/libjin/Filesystem/Buffer.h delete mode 100644 src/libjin/Filesystem/Filesystem.cpp delete mode 100644 src/libjin/Filesystem/Filesystem.h create mode 100644 src/libjin/Filesystem/je_buffer.h create mode 100644 src/libjin/Filesystem/je_filesystem.cpp create mode 100644 src/libjin/Filesystem/je_filesystem.h delete mode 100644 src/libjin/Game/Game.cpp delete mode 100644 src/libjin/Game/Game.h create mode 100644 src/libjin/Game/je_game.cpp create mode 100644 src/libjin/Game/je_game.h delete mode 100644 src/libjin/Graphics/Bitmap.cpp delete mode 100644 src/libjin/Graphics/Bitmap.h delete mode 100644 src/libjin/Graphics/Canvas.cpp delete mode 100644 src/libjin/Graphics/Canvas.h delete mode 100644 src/libjin/Graphics/Color.cpp delete mode 100644 src/libjin/Graphics/Color.h delete mode 100644 src/libjin/Graphics/Drawable.cpp delete mode 100644 src/libjin/Graphics/Drawable.h delete mode 100644 src/libjin/Graphics/Font/Decoder.cpp delete mode 100644 src/libjin/Graphics/Font/Decoder.h delete mode 100644 src/libjin/Graphics/Font/Font.h delete mode 100644 src/libjin/Graphics/Font/Page.h delete mode 100644 src/libjin/Graphics/Font/TTF.cpp delete mode 100644 src/libjin/Graphics/Font/TTF.h delete mode 100644 src/libjin/Graphics/Font/Text.cpp delete mode 100644 src/libjin/Graphics/Font/Text.h delete mode 100644 src/libjin/Graphics/Font/TextureFont.cpp delete mode 100644 src/libjin/Graphics/Font/TextureFont.h create mode 100644 src/libjin/Graphics/Font/je_decoder.cpp create mode 100644 src/libjin/Graphics/Font/je_decoder.h create mode 100644 src/libjin/Graphics/Font/je_font.h create mode 100644 src/libjin/Graphics/Font/je_page.h create mode 100644 src/libjin/Graphics/Font/je_text.cpp create mode 100644 src/libjin/Graphics/Font/je_text.h create mode 100644 src/libjin/Graphics/Font/je_texture_font.cpp create mode 100644 src/libjin/Graphics/Font/je_texture_font.h create mode 100644 src/libjin/Graphics/Font/je_ttf.cpp create mode 100644 src/libjin/Graphics/Font/je_ttf.h delete mode 100644 src/libjin/Graphics/Graphics.h delete mode 100644 src/libjin/Graphics/Image.cpp delete mode 100644 src/libjin/Graphics/Image.h delete mode 100644 src/libjin/Graphics/Mesh.cpp delete mode 100644 src/libjin/Graphics/Mesh.h delete mode 100644 src/libjin/Graphics/OpenGL.cpp delete mode 100644 src/libjin/Graphics/OpenGL.h delete mode 100644 src/libjin/Graphics/Shader/Shader.cpp delete mode 100644 src/libjin/Graphics/Shader/Shader.h delete mode 100644 src/libjin/Graphics/Shader/base.shader.h delete mode 100644 src/libjin/Graphics/Shader/default.shader.h delete mode 100644 src/libjin/Graphics/Shader/font.shader.h create mode 100644 src/libjin/Graphics/Shader/je_base.shader.h create mode 100644 src/libjin/Graphics/Shader/je_default.shader.h create mode 100644 src/libjin/Graphics/Shader/je_font.shader.h create mode 100644 src/libjin/Graphics/Shader/je_shader.cpp create mode 100644 src/libjin/Graphics/Shader/je_shader.h create mode 100644 src/libjin/Graphics/Shader/je_texture.shader.h delete mode 100644 src/libjin/Graphics/Shader/texture.shader.h delete mode 100644 src/libjin/Graphics/Shapes.cpp delete mode 100644 src/libjin/Graphics/Shapes.h delete mode 100644 src/libjin/Graphics/Sprite.cpp delete mode 100644 src/libjin/Graphics/Sprite.h delete mode 100644 src/libjin/Graphics/Texture.cpp delete mode 100644 src/libjin/Graphics/Texture.h delete mode 100644 src/libjin/Graphics/Window.cpp delete mode 100644 src/libjin/Graphics/Window.h create mode 100644 src/libjin/Graphics/je_bitmap.cpp create mode 100644 src/libjin/Graphics/je_bitmap.h create mode 100644 src/libjin/Graphics/je_canvas.cpp create mode 100644 src/libjin/Graphics/je_canvas.h create mode 100644 src/libjin/Graphics/je_color.cpp create mode 100644 src/libjin/Graphics/je_color.h create mode 100644 src/libjin/Graphics/je_drawable.cpp create mode 100644 src/libjin/Graphics/je_drawable.h create mode 100644 src/libjin/Graphics/je_gl.cpp create mode 100644 src/libjin/Graphics/je_gl.h create mode 100644 src/libjin/Graphics/je_graphics.h create mode 100644 src/libjin/Graphics/je_image.cpp create mode 100644 src/libjin/Graphics/je_image.h create mode 100644 src/libjin/Graphics/je_mesh.cpp create mode 100644 src/libjin/Graphics/je_mesh.h create mode 100644 src/libjin/Graphics/je_shapes.cpp create mode 100644 src/libjin/Graphics/je_shapes.h create mode 100644 src/libjin/Graphics/je_sprite.cpp create mode 100644 src/libjin/Graphics/je_sprite.h create mode 100644 src/libjin/Graphics/je_texture.cpp create mode 100644 src/libjin/Graphics/je_texture.h create mode 100644 src/libjin/Graphics/je_window.cpp create mode 100644 src/libjin/Graphics/je_window.h delete mode 100644 src/libjin/Input/Event.cpp delete mode 100644 src/libjin/Input/Event.h delete mode 100644 src/libjin/Input/Input.h delete mode 100644 src/libjin/Input/Joypad.cpp delete mode 100644 src/libjin/Input/Joypad.h delete mode 100644 src/libjin/Input/Keyboard.cpp delete mode 100644 src/libjin/Input/Keyboard.h delete mode 100644 src/libjin/Input/Mouse.cpp delete mode 100644 src/libjin/Input/Mouse.h create mode 100644 src/libjin/Input/je_event.cpp create mode 100644 src/libjin/Input/je_event.h create mode 100644 src/libjin/Input/je_input.h create mode 100644 src/libjin/Input/je_joypad.cpp create mode 100644 src/libjin/Input/je_joypad.h create mode 100644 src/libjin/Input/je_keyboard.cpp create mode 100644 src/libjin/Input/je_keyboard.h create mode 100644 src/libjin/Input/je_mouse.cpp create mode 100644 src/libjin/Input/je_mouse.h delete mode 100644 src/libjin/Math/Math.h delete mode 100644 src/libjin/Math/Matrix.cpp delete mode 100644 src/libjin/Math/Matrix.h delete mode 100644 src/libjin/Math/Quad.h delete mode 100644 src/libjin/Math/Vector2.hpp delete mode 100644 src/libjin/Math/Vector3.hpp delete mode 100644 src/libjin/Math/Vector4.hpp delete mode 100644 src/libjin/Math/constant.h create mode 100644 src/libjin/Math/je_constant.h create mode 100644 src/libjin/Math/je_math.h create mode 100644 src/libjin/Math/je_matrix.cpp create mode 100644 src/libjin/Math/je_matrix.h create mode 100644 src/libjin/Math/je_quad.h create mode 100644 src/libjin/Math/je_vector2.hpp create mode 100644 src/libjin/Math/je_vector3.hpp create mode 100644 src/libjin/Math/je_vector4.hpp delete mode 100644 src/libjin/Net/Net.cpp delete mode 100644 src/libjin/Net/Net.h delete mode 100644 src/libjin/Net/Socket.cpp delete mode 100644 src/libjin/Net/Socket.h create mode 100644 src/libjin/Net/je_net.cpp create mode 100644 src/libjin/Net/je_net.h create mode 100644 src/libjin/Net/je_socket.cpp create mode 100644 src/libjin/Net/je_socket.h delete mode 100644 src/libjin/Net/net.cpp delete mode 100644 src/libjin/Net/net.h delete mode 100644 src/libjin/Thread/Thread.cpp delete mode 100644 src/libjin/Thread/Thread.h create mode 100644 src/libjin/Thread/je_thread.cpp create mode 100644 src/libjin/Thread/je_thread.h delete mode 100644 src/libjin/Thread/thread.cpp delete mode 100644 src/libjin/Thread/thread.h delete mode 100644 src/libjin/Time/Timer.cpp delete mode 100644 src/libjin/Time/Timer.h create mode 100644 src/libjin/Time/je_timer.cpp create mode 100644 src/libjin/Time/je_timer.h delete mode 100644 src/libjin/Utils/Log.cpp delete mode 100644 src/libjin/Utils/Log.h delete mode 100644 src/libjin/Utils/endian.h create mode 100644 src/libjin/Utils/je_endian.h create mode 100644 src/libjin/Utils/je_log.cpp create mode 100644 src/libjin/Utils/je_log.h create mode 100644 src/libjin/Utils/je_macros.h create mode 100644 src/libjin/Utils/je_unittest.cpp create mode 100644 src/libjin/Utils/je_utils.h delete mode 100644 src/libjin/Utils/log.h delete mode 100644 src/libjin/Utils/macros.h delete mode 100644 src/libjin/Utils/unittest.cpp delete mode 100644 src/libjin/Utils/utils.h delete mode 100644 src/libjin/audio/audio.cpp delete mode 100644 src/libjin/audio/audio.h delete mode 100644 src/libjin/audio/source.cpp delete mode 100644 src/libjin/audio/source.h delete mode 100644 src/libjin/configuration.h create mode 100644 src/libjin/core/je_configuration.h create mode 100644 src/libjin/core/je_types.h delete mode 100644 src/libjin/input/event.cpp delete mode 100644 src/libjin/input/event.h delete mode 100644 src/libjin/input/input.h delete mode 100644 src/libjin/input/joypad.cpp delete mode 100644 src/libjin/input/joypad.h delete mode 100644 src/libjin/input/keyboard.cpp delete mode 100644 src/libjin/input/keyboard.h delete mode 100644 src/libjin/input/mouse.cpp delete mode 100644 src/libjin/input/mouse.h delete mode 100644 src/libjin/math/constant.h delete mode 100644 src/libjin/math/math.h delete mode 100644 src/libjin/math/matrix.cpp delete mode 100644 src/libjin/math/matrix.h delete mode 100644 src/libjin/math/quad.h delete mode 100644 src/libjin/net/net.cpp delete mode 100644 src/libjin/net/net.h delete mode 100644 src/libjin/thread/thread.cpp delete mode 100644 src/libjin/thread/thread.h delete mode 100644 src/libjin/utils/endian.h delete mode 100644 src/libjin/utils/log.cpp delete mode 100644 src/libjin/utils/log.h delete mode 100644 src/libjin/utils/macros.h delete mode 100644 src/libjin/utils/unittest.cpp delete mode 100644 src/libjin/utils/utils.h (limited to 'src') diff --git a/src/libjin/Audio/Audio.cpp b/src/libjin/Audio/Audio.cpp deleted file mode 100644 index 928f01a..0000000 --- a/src/libjin/Audio/Audio.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_AUDIO - -#include "SDL2/SDL.h" -#include "audio.h" - -namespace jin -{ - namespace audio - { - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO diff --git a/src/libjin/Audio/Audio.h b/src/libjin/Audio/Audio.h deleted file mode 100644 index fd391aa..0000000 --- a/src/libjin/Audio/Audio.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __LIBJIN_AUDIO_H -#define __LIBJIN_AUDIO_H -#include "../configuration.h" -#if LIBJIN_MODULES_AUDIO - -#include "SDL2/SDL.h" - -#include "../utils/macros.h" -#include "../common/Subsystem.hpp" - -namespace jin -{ - namespace audio - { - - class Source; - - template - class Audio : public Subsystem - { - 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; - - }; - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO -#endif // __LIBJIN_AUDIO_H diff --git a/src/libjin/Audio/SDL/SDLAudio.cpp b/src/libjin/Audio/SDL/SDLAudio.cpp deleted file mode 100644 index 96bb304..0000000 --- a/src/libjin/Audio/SDL/SDLAudio.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include "../../configuration.h" -#if LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO - -#include -#include "SDLAudio.h" -#include "SDLSource.h" -#include "../../math/math.h" -#include "../../utils/log.h" - -namespace jin -{ - namespace audio - { - - using namespace jin::math; - - /* ×¢ÒâcallbackÊÇÔÚÒôƵÏ̵߳÷Óà */ - static void defaultCallback(void *userdata, Uint8 *stream, int size) - { - static SDLAudio* audio = static_cast(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(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::pause() - { - state = State::PAUSE; - } - - void SDLAudio::resume() - { - state = State::PLAY; - } - - void SDLAudio::setVolume(float volume) - { - this->volume = clamp(volume, 0.0f, 1.0f); - } - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO diff --git a/src/libjin/Audio/SDL/SDLAudio.h b/src/libjin/Audio/SDL/SDLAudio.h deleted file mode 100644 index 1a29595..0000000 --- a/src/libjin/Audio/SDL/SDLAudio.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __LIBJIN_AUDIO_SDL_H -#define __LIBJIN_AUDIO_SDL_H -#include "../../configuration.h" -#if LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO - -#include "SDLSource.h" -#include -#include "../audio.h" - -namespace jin -{ - namespace audio - { - - #define SDLAUDIO_BITDEPTH 16 - #define SDLAUDIO_BYTEDEPTH (SDLAUDIO_BITDEPTH >> 3) - #define SDLAUDIO_CHANNELS 2 - - class SDLAudio : public Audio - { - 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; - - }; - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO -#endif // __LIBJIN_AUDIO_SDL_H diff --git a/src/libjin/Audio/SDL/SDLSource.cpp b/src/libjin/Audio/SDL/SDLSource.cpp deleted file mode 100644 index 34fc0f5..0000000 --- a/src/libjin/Audio/SDL/SDLSource.cpp +++ /dev/null @@ -1,399 +0,0 @@ -#include "../../configuration.h" -#if LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO - -#include -#include -#include -#include "../../math/math.h" -#include "../../utils/macros.h" -#include "SDLSource.h" -#include "../../3rdparty/wav/wav.h" -#define STB_VORBIS_HEADER_ONLY -#include "../../3rdparty/stb/stb_vorbis.c" -#include "SDLAudio.h" - -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 Manager::commands; - ///*class member*/ std::stack Manager::commandsPool; - ///*class member*/ std::vector 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(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; - } - } - - 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::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::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(); - } - - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO diff --git a/src/libjin/Audio/SDL/SDLSource.h b/src/libjin/Audio/SDL/SDLSource.h deleted file mode 100644 index 4977ec8..0000000 --- a/src/libjin/Audio/SDL/SDLSource.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef __LIBJIN_SOURCE_SDL_H -#define __LIBJIN_SOURCE_SDL_H -#include "../../configuration.h" -#if LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO - -#include -#include -#include -#include - -#include "../source.h" - -namespace jin -{ - namespace audio - { - - typedef struct SDLSourceCommand; - class SDLSourceManager; - - 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); - - 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; // channelÊý1(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(); - - /* 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 commands; - std::stack commandsPool; - std::vector sources; // processing sources - static SDLSourceManager* manager; - - }; - - class SourceException : public std::exception - { - const char * what() const throw () - { - return "Load Source Exception"; - } - }; - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO -#endif // __LIBJIN_SOURCE_SDL_H diff --git a/src/libjin/Audio/SDL/je_sdl_audio.cpp b/src/libjin/Audio/SDL/je_sdl_audio.cpp new file mode 100644 index 0000000..0cc8380 --- /dev/null +++ b/src/libjin/Audio/SDL/je_sdl_audio.cpp @@ -0,0 +1,143 @@ +#include "../../core/je_configuration.h" +#if LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO + +#include + +#include "../../math/je_math.h" +#include "../../utils/je_log.h" + +#include "je_sdl_audio.h" +#include "je_sdl_source.h" + +namespace jin +{ + namespace audio + { + + using namespace jin::math; + + /* ×¢ÒâcallbackÊÇÔÚÒôƵÏ̵߳÷Óà */ + static void defaultCallback(void *userdata, Uint8 *stream, int size) + { + static SDLAudio* audio = static_cast(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(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::pause() + { + state = State::PAUSE; + } + + void SDLAudio::resume() + { + state = State::PLAY; + } + + void SDLAudio::setVolume(float volume) + { + this->volume = clamp(volume, 0.0f, 1.0f); + } + + } // namespace audio +} // namespace jin + +#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO diff --git a/src/libjin/Audio/SDL/je_sdl_audio.h b/src/libjin/Audio/SDL/je_sdl_audio.h new file mode 100644 index 0000000..c64b109 --- /dev/null +++ b/src/libjin/Audio/SDL/je_sdl_audio.h @@ -0,0 +1,62 @@ +#ifndef __LIBJIN_AUDIO_SDL_H +#define __LIBJIN_AUDIO_SDL_H +#include "../../core/je_configuration.h" +#if LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO + +#include + +#include "../je_audio.h" + +#include "je_sdl_source.h" + +namespace jin +{ + namespace audio + { + + #define SDLAUDIO_BITDEPTH 16 + #define SDLAUDIO_BYTEDEPTH (SDLAUDIO_BITDEPTH >> 3) + #define SDLAUDIO_CHANNELS 2 + + class SDLAudio : public Audio + { + 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; + + }; + + } // namespace audio +} // namespace jin + +#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO +#endif // __LIBJIN_AUDIO_SDL_H diff --git a/src/libjin/Audio/SDL/je_sdl_source.cpp b/src/libjin/Audio/SDL/je_sdl_source.cpp new file mode 100644 index 0000000..5fbce49 --- /dev/null +++ b/src/libjin/Audio/SDL/je_sdl_source.cpp @@ -0,0 +1,401 @@ +#include "../../core/je_configuration.h" +#if LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO + +#include +#include +#include + +#define STB_VORBIS_HEADER_ONLY +#include "../../3rdparty/stb/stb_vorbis.c" +#include "../../math/je_math.h" +#include "../../utils/je_macros.h" +#include "../../3rdparty/wav/wav.h" + +#include "je_sdl_audio.h" +#include "je_sdl_source.h" + +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 Manager::commands; + ///*class member*/ std::stack Manager::commandsPool; + ///*class member*/ std::vector 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(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; + } + } + + 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::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::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(); + } + + + } // namespace audio +} // namespace jin + +#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO diff --git a/src/libjin/Audio/SDL/je_sdl_source.h b/src/libjin/Audio/SDL/je_sdl_source.h new file mode 100644 index 0000000..15676d6 --- /dev/null +++ b/src/libjin/Audio/SDL/je_sdl_source.h @@ -0,0 +1,107 @@ +#ifndef __LIBJIN_SOURCE_SDL_H +#define __LIBJIN_SOURCE_SDL_H +#include "../../core/je_configuration.h" +#if LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO + +#include +#include +#include +#include + +#include "../je_source.h" + +namespace jin +{ + namespace audio + { + + typedef struct SDLSourceCommand; + class SDLSourceManager; + + 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); + + 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; // channelÊý1(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(); + + /* 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 commands; + std::stack commandsPool; + std::vector sources; // processing sources + static SDLSourceManager* manager; + + }; + + class SourceException : public std::exception + { + const char * what() const throw () + { + return "Load Source Exception"; + } + }; + + } // namespace audio +} // namespace jin + +#endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO +#endif // __LIBJIN_SOURCE_SDL_H diff --git a/src/libjin/Audio/Source.cpp b/src/libjin/Audio/Source.cpp deleted file mode 100644 index 646e5ef..0000000 --- a/src/libjin/Audio/Source.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_AUDIO - -#include -#include "source.h" - -namespace jin -{ - 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); - } - - 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; - } - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO diff --git a/src/libjin/Audio/Source.h b/src/libjin/Audio/Source.h deleted file mode 100644 index 6dfc86c..0000000 --- a/src/libjin/Audio/Source.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __LIBJIN_AUDIO_SOURCE_H -#define __LIBJIN_AUDIO_SOURCE_H -#include "../configuration.h" -#if LIBJIN_MODULES_AUDIO - -#include "SDL2/SDL.h" - -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); - - }; - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO -#endif // __LIBJIN_AUDIO_SOURCE_H diff --git a/src/libjin/Audio/je_audio.cpp b/src/libjin/Audio/je_audio.cpp new file mode 100644 index 0000000..81201b7 --- /dev/null +++ b/src/libjin/Audio/je_audio.cpp @@ -0,0 +1,15 @@ +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_AUDIO + +#include "SDL2/SDL.h" +#include "je_audio.h" + +namespace jin +{ + namespace audio + { + + } // namespace audio +} // namespace jin + +#endif // LIBJIN_MODULES_AUDIO diff --git a/src/libjin/Audio/je_audio.h b/src/libjin/Audio/je_audio.h new file mode 100644 index 0000000..341e4c9 --- /dev/null +++ b/src/libjin/Audio/je_audio.h @@ -0,0 +1,53 @@ +#ifndef __LIBJIN_AUDIO_H +#define __LIBJIN_AUDIO_H + +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_AUDIO + +#include "../utils/je_macros.h" +#include "../common/je_subsystem.hpp" + +#include "SDL2/SDL.h" + +namespace jin +{ + namespace audio + { + + class Source; + + template + class Audio : public Subsystem + { + 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; + + }; + + } // namespace audio +} // namespace jin + +#endif // LIBJIN_MODULES_AUDIO +#endif // __LIBJIN_AUDIO_H diff --git a/src/libjin/Audio/je_source.cpp b/src/libjin/Audio/je_source.cpp new file mode 100644 index 0000000..e20cd69 --- /dev/null +++ b/src/libjin/Audio/je_source.cpp @@ -0,0 +1,30 @@ +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_AUDIO + +#include + +#include "je_source.h" + +namespace jin +{ + 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); + } + + 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; + } + + } // namespace audio +} // namespace jin + +#endif // LIBJIN_MODULES_AUDIO diff --git a/src/libjin/Audio/je_source.h b/src/libjin/Audio/je_source.h new file mode 100644 index 0000000..bcac214 --- /dev/null +++ b/src/libjin/Audio/je_source.h @@ -0,0 +1,47 @@ +#ifndef __LIBJIN_AUDIO_SOURCE_H +#define __LIBJIN_AUDIO_SOURCE_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_AUDIO + +#include "SDL2/SDL.h" + +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); + + }; + + } // namespace audio +} // namespace jin + +#endif // LIBJIN_MODULES_AUDIO +#endif // __LIBJIN_AUDIO_SOURCE_H diff --git a/src/libjin/Common/Array.hpp b/src/libjin/Common/Array.hpp deleted file mode 100644 index 45082db..0000000 --- a/src/libjin/Common/Array.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef __LIBJIN_COMMON_ARRAY_H -#define __LIBJIN_COMMON_ARRAY_H - -namespace jin -{ - - /* ×Ô¶¯ÊͷŶÑÄÚ´æµÄÔÚÕ»ÉÏ´´½¨µÄ¶¯Ì¬Êý×é */ - template - class Array - { - public: - Array() : length(0), data(nullptr) {} - - Array(int l) - { - length = l; - data = new T[l]; - } - - ~Array() - { - delete[] data; - length = 0; - } - - T* operator &() - { - return data; - } - - T& operator[](int index) - { - return data[index]; - } - - /* °ó¶¨ÄÚ´æ */ - void bind(T* d, int len) - { - if (data != nullptr) - delete data; - data = d; - length = len; - } - - void add(T v) - { - int len = length + 1; - T* d = new T[len]; - memcpy(d, data, size()); - d[length] = v; - bind(d, len); - } - - int size() - { - return sizeof(T) * length; - } - - int count() - { - return length; - } - - private: - /** - * http://blog.jobbole.com/106923/ - * new ¶ÑÄÚ´æ´´½¨¶ÔÏó¹ý³Ì - * 1. µ÷Óà new ·ÖÅäÄÚ´æ - * 2. µ÷Óù¹Ô캯Êý - * - * new, delete·½·¨ÓÃÓÚ·ÖÅäºÍÊÍ·ÅÄڴ棬²»¸ºÔð¹¹ÔìºÍÎö¹¹ - */ - void* operator new(size_t t); - void operator delete(void* ptr); - - T * data; - unsigned int length; - - }; - -} - -#endif \ No newline at end of file diff --git a/src/libjin/Common/Exception.cpp b/src/libjin/Common/Exception.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/libjin/Common/Exception.h b/src/libjin/Common/Exception.h deleted file mode 100644 index e69de29..0000000 diff --git a/src/libjin/Common/Object.cpp b/src/libjin/Common/Object.cpp deleted file mode 100644 index 6c3b667..0000000 --- a/src/libjin/Common/Object.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// LOVE -#include "Object.h" - -namespace jin -{ - - Object::Object() - : count(1) - { - } - - Object::~Object() - { - } - - int Object::getReferenceCount() const - { - return count; - } - - void Object::retain() - { - ++count; - } - - void Object::release() - { - if (--count <= 0) - delete this; - } - -} // love diff --git a/src/libjin/Common/Object.h b/src/libjin/Common/Object.h deleted file mode 100644 index c4bf225..0000000 --- a/src/libjin/Common/Object.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __LIBJIN_COMMON_OBJECT_H -#define __LIBJIN_COMMON_OBJECT_H - -namespace jin -{ - - class Object - { - private: - - // The reference count. - int count; - - public: - - /** - * Constructor. Sets reference count to one. - **/ - Object(); - - /** - * Destructor. - **/ - virtual ~Object() = 0; - - /** - * Gets the reference count of this Object. - * @returns The reference count. - **/ - int getReferenceCount() const; - - /** - * Retains the Object, i.e. increases the - * reference count by one. - **/ - void retain(); - - /** - * Releases one reference to the Object, i.e. decrements the - * reference count by one, and potentially deletes the Object - * if there are no more references. - **/ - void release(); - - }; // Object - -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Common/Singleton.hpp b/src/libjin/Common/Singleton.hpp deleted file mode 100644 index 12b1450..0000000 --- a/src/libjin/Common/Singleton.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __LIBJIN_SINGLETON_H -#define __LIBJIN_SINGLETON_H - -namespace jin -{ - - template - class Singleton - { - public: - static T* get() - { - if (_instance == nullptr) - _instance = new T; - return _instance; - } - static void destroy() - { - delete _instance; - _instance = nullptr; - } - protected: - Singleton() {}; - virtual ~Singleton() {}; - static T* _instance; - private: - Singleton(const Singleton&); - Singleton& operator = (const Singleton&); - }; - - template T* Singleton::_instance = nullptr; - -#define singleton(T) friend Singleton - -} // namespace jin - -#endif // __LIBJIN_SINGLETON_H \ No newline at end of file diff --git a/src/libjin/Common/StringMap.hpp b/src/libjin/Common/StringMap.hpp deleted file mode 100644 index 641e32d..0000000 --- a/src/libjin/Common/StringMap.hpp +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef __LIBJIN_COMMON_SREINGMAP_H -#define __LIBJIN_COMMON_SREINGMAP_H - -namespace jin -{ - - template - class StringMap - { - private: - - struct Record - { - const char * key; - T value; - bool set; - Record() : set(false) {} - }; - - const static unsigned MAX = SIZE * 2; - - Record records[MAX]; - const char * reverse[SIZE]; - - public: - - struct Entry - { - const char * key; - T value; - }; - - StringMap(Entry * entries, unsigned num) - { - - for (unsigned i = 0; i < SIZE; ++i) - reverse[i] = 0; - - unsigned n = num / sizeof(Entry); - - for (unsigned i = 0; i < n; ++i) - { - add(entries[i].key, entries[i].value); - } - } - - bool streq(const char * a, const char * b) - { - while (*a != 0 && *b != 0) - { - if (*a != *b) - return false; - ++a; - ++b; - } - - return (*a == 0 && *b == 0); - } - - bool find(const char * key, T & t) - { - //unsigned str_hash = djb2(key); - - for (unsigned i = 0; i < MAX; ++i) - { - //unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional? - - if (records[i].set && streq(records[i].key, key)) - { - t = records[i].value; - return true; - } - } - - return false; - } - - bool find(T key, const char *& str) - { - unsigned index = (unsigned)key; - - if (index >= SIZE) - return false; - - if (reverse[index] != 0) - { - str = reverse[index]; - return true; - } - else - { - return false; - } - } - - bool add(const char * key, T value) - { - unsigned str_hash = djb2(key); - bool inserted = false; - - for (unsigned i = 0; i < MAX; ++i) - { - unsigned str_i = (str_hash + i) % MAX; - - if (!records[str_i].set) - { - inserted = true; - records[str_i].set = true; - records[str_i].key = key; - records[str_i].value = value; - break; - } - } - - unsigned index = (unsigned)value; - - if (index >= SIZE) - { - printf("\nConstant %s out of bounds with %i!\n", key, index); - return false; - } - - reverse[index] = key; - - return inserted; - } - - unsigned djb2(const char * key) - { - unsigned hash = 5381; - int c; - - while ((c = *key++)) - hash = ((hash << 5) + hash) + c; - - return hash; - } - - }; // StringMap - -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Common/Subsystem.hpp b/src/libjin/Common/Subsystem.hpp deleted file mode 100644 index 293b88d..0000000 --- a/src/libjin/Common/Subsystem.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __LIBJIN_COMMON_SUBSYSTEM_H -#define __LIBJIN_COMMON_SUBSYSTEM_H - -#include "singleton.hpp" -#include "../utils/macros.h" - -namespace jin -{ - - template - class Subsystem : public Singleton - { - public: - struct Setting {}; - typedef Setting SettingBase; - - bool init(const SettingBase* setting = nullptr) - { - static bool success = initSystem(setting); - return success; - } - - void quit() - { - /*call only once*/ - static char __dummy__ = (quitSystem(), 1); - Singleton::destroy(); - } - - protected: - singleton(System); - - Subsystem() {}; - virtual ~Subsystem() {}; - - /*onlyonce*/ virtual bool initSystem(const Setting* setting) = 0; - /*onlyonce*/ virtual void quitSystem() = 0; - - }; - -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Common/common.h b/src/libjin/Common/common.h deleted file mode 100644 index 9586c82..0000000 --- a/src/libjin/Common/common.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LIBJIN_COMMON_H -#define __LIBJIN_COMMON_H - -#include "Array.hpp" - -#endif \ No newline at end of file diff --git a/src/libjin/Common/je_array.hpp b/src/libjin/Common/je_array.hpp new file mode 100644 index 0000000..eadd36f --- /dev/null +++ b/src/libjin/Common/je_array.hpp @@ -0,0 +1,86 @@ +#ifndef __LIBJIN_COMMON_ARRAY_H +#define __LIBJIN_COMMON_ARRAY_H + +namespace jin +{ + /* ×Ô¶¯ÊͷŶÑÄÚ´æµÄÔÚÕ»ÉÏ´´½¨µÄ¶¯Ì¬Êý×é */ + template + class Array + { + public: + Array() : length(0), data(nullptr) {} + + Array(int l) + { + length = l; + data = new T[l]; + } + + ~Array() + { + delete[] data; + length = 0; + } + + T* operator &() + { + return data; + } + + T& operator[](int index) + { + return data[index]; + } + + /* °ó¶¨ÄÚ´æ */ + void bind(T* d, int len) + { + if (data != nullptr) + delete data; + data = d; + length = len; + } + + void add(T v) + { + int len = length + 1; + T* d = new T[len]; + memcpy(d, data, size()); + d[length] = v; + bind(d, len); + } + + int size() + { + return sizeof(T) * length; + } + + int count() + { + return length; + } + + private: + /// + /// http://blog.jobbole.com/106923/ + /// new ¶ÑÄÚ´æ´´½¨¶ÔÏó¹ý³Ì + /// 1. µ÷Óà new ·ÖÅäÄÚ´æ + /// 2. µ÷Óù¹Ô캯Êý + /// + /// new, delete·½·¨ÓÃÓÚ·ÖÅäºÍÊÍ·ÅÄڴ棬²»¸ºÔð¹¹ÔìºÍÎö¹¹ + /// + void* operator new(size_t t); + + /// + /// Disable delete. + /// + void operator delete(void* ptr); + + T * data; + unsigned int length; + + }; + +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Common/je_common.h b/src/libjin/Common/je_common.h new file mode 100644 index 0000000..63528b0 --- /dev/null +++ b/src/libjin/Common/je_common.h @@ -0,0 +1,6 @@ +#ifndef __LIBJIN_COMMON_H +#define __LIBJIN_COMMON_H + +#include "je_array.hpp" + +#endif \ No newline at end of file diff --git a/src/libjin/Common/je_exception.cpp b/src/libjin/Common/je_exception.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libjin/Common/je_exception.h b/src/libjin/Common/je_exception.h new file mode 100644 index 0000000..e69de29 diff --git a/src/libjin/Common/je_object.cpp b/src/libjin/Common/je_object.cpp new file mode 100644 index 0000000..e3b4ca5 --- /dev/null +++ b/src/libjin/Common/je_object.cpp @@ -0,0 +1,32 @@ +// LOVE +#include "je_object.h" + +namespace jin +{ + + Object::Object() + : count(1) + { + } + + Object::~Object() + { + } + + int Object::getReferenceCount() const + { + return count; + } + + void Object::retain() + { + ++count; + } + + void Object::release() + { + if (--count <= 0) + delete this; + } + +} // love diff --git a/src/libjin/Common/je_object.h b/src/libjin/Common/je_object.h new file mode 100644 index 0000000..c4bf225 --- /dev/null +++ b/src/libjin/Common/je_object.h @@ -0,0 +1,49 @@ +#ifndef __LIBJIN_COMMON_OBJECT_H +#define __LIBJIN_COMMON_OBJECT_H + +namespace jin +{ + + class Object + { + private: + + // The reference count. + int count; + + public: + + /** + * Constructor. Sets reference count to one. + **/ + Object(); + + /** + * Destructor. + **/ + virtual ~Object() = 0; + + /** + * Gets the reference count of this Object. + * @returns The reference count. + **/ + int getReferenceCount() const; + + /** + * Retains the Object, i.e. increases the + * reference count by one. + **/ + void retain(); + + /** + * Releases one reference to the Object, i.e. decrements the + * reference count by one, and potentially deletes the Object + * if there are no more references. + **/ + void release(); + + }; // Object + +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Common/je_singleton.hpp b/src/libjin/Common/je_singleton.hpp new file mode 100644 index 0000000..12b1450 --- /dev/null +++ b/src/libjin/Common/je_singleton.hpp @@ -0,0 +1,37 @@ +#ifndef __LIBJIN_SINGLETON_H +#define __LIBJIN_SINGLETON_H + +namespace jin +{ + + template + class Singleton + { + public: + static T* get() + { + if (_instance == nullptr) + _instance = new T; + return _instance; + } + static void destroy() + { + delete _instance; + _instance = nullptr; + } + protected: + Singleton() {}; + virtual ~Singleton() {}; + static T* _instance; + private: + Singleton(const Singleton&); + Singleton& operator = (const Singleton&); + }; + + template T* Singleton::_instance = nullptr; + +#define singleton(T) friend Singleton + +} // namespace jin + +#endif // __LIBJIN_SINGLETON_H \ No newline at end of file diff --git a/src/libjin/Common/je_stringmap.hpp b/src/libjin/Common/je_stringmap.hpp new file mode 100644 index 0000000..641e32d --- /dev/null +++ b/src/libjin/Common/je_stringmap.hpp @@ -0,0 +1,143 @@ +#ifndef __LIBJIN_COMMON_SREINGMAP_H +#define __LIBJIN_COMMON_SREINGMAP_H + +namespace jin +{ + + template + class StringMap + { + private: + + struct Record + { + const char * key; + T value; + bool set; + Record() : set(false) {} + }; + + const static unsigned MAX = SIZE * 2; + + Record records[MAX]; + const char * reverse[SIZE]; + + public: + + struct Entry + { + const char * key; + T value; + }; + + StringMap(Entry * entries, unsigned num) + { + + for (unsigned i = 0; i < SIZE; ++i) + reverse[i] = 0; + + unsigned n = num / sizeof(Entry); + + for (unsigned i = 0; i < n; ++i) + { + add(entries[i].key, entries[i].value); + } + } + + bool streq(const char * a, const char * b) + { + while (*a != 0 && *b != 0) + { + if (*a != *b) + return false; + ++a; + ++b; + } + + return (*a == 0 && *b == 0); + } + + bool find(const char * key, T & t) + { + //unsigned str_hash = djb2(key); + + for (unsigned i = 0; i < MAX; ++i) + { + //unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional? + + if (records[i].set && streq(records[i].key, key)) + { + t = records[i].value; + return true; + } + } + + return false; + } + + bool find(T key, const char *& str) + { + unsigned index = (unsigned)key; + + if (index >= SIZE) + return false; + + if (reverse[index] != 0) + { + str = reverse[index]; + return true; + } + else + { + return false; + } + } + + bool add(const char * key, T value) + { + unsigned str_hash = djb2(key); + bool inserted = false; + + for (unsigned i = 0; i < MAX; ++i) + { + unsigned str_i = (str_hash + i) % MAX; + + if (!records[str_i].set) + { + inserted = true; + records[str_i].set = true; + records[str_i].key = key; + records[str_i].value = value; + break; + } + } + + unsigned index = (unsigned)value; + + if (index >= SIZE) + { + printf("\nConstant %s out of bounds with %i!\n", key, index); + return false; + } + + reverse[index] = key; + + return inserted; + } + + unsigned djb2(const char * key) + { + unsigned hash = 5381; + int c; + + while ((c = *key++)) + hash = ((hash << 5) + hash) + c; + + return hash; + } + + }; // StringMap + +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Common/je_subsystem.hpp b/src/libjin/Common/je_subsystem.hpp new file mode 100644 index 0000000..2875058 --- /dev/null +++ b/src/libjin/Common/je_subsystem.hpp @@ -0,0 +1,44 @@ +#ifndef __LIBJIN_COMMON_SUBSYSTEM_H +#define __LIBJIN_COMMON_SUBSYSTEM_H + +#include "../utils/je_macros.h" + +#include "je_singleton.hpp" + +namespace jin +{ + + template + class Subsystem : public Singleton + { + public: + struct Setting {}; + typedef Setting SettingBase; + + bool init(const SettingBase* setting = nullptr) + { + static bool success = initSystem(setting); + return success; + } + + void quit() + { + /*call only once*/ + static char __dummy__ = (quitSystem(), 1); + Singleton::destroy(); + } + + protected: + singleton(System); + + Subsystem() {}; + virtual ~Subsystem() {}; + + /*onlyonce*/ virtual bool initSystem(const Setting* setting) = 0; + /*onlyonce*/ virtual void quitSystem() = 0; + + }; + +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Common/je_types.h b/src/libjin/Common/je_types.h new file mode 100644 index 0000000..2d257c3 --- /dev/null +++ b/src/libjin/Common/je_types.h @@ -0,0 +1,23 @@ +#ifndef __LIBJIN_TYPES_H +#define __LIBJIN_TYPES_H +#include + +namespace jin +{ + 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; + + } +} + +#endif \ No newline at end of file diff --git a/src/libjin/Common/je_utf8.cpp b/src/libjin/Common/je_utf8.cpp new file mode 100644 index 0000000..de539c7 --- /dev/null +++ b/src/libjin/Common/je_utf8.cpp @@ -0,0 +1,42 @@ +#include "../core/je_configuration.h" +#if LIBJIN_OS == LIBJIN_WINDOWS + +#include "je_utf8.h" + +namespace jin +{ + + std::string to_utf8(LPCWSTR wstr) + { + size_t wide_len = wcslen(wstr) + 1; + + // Get size in UTF-8. + int utf8_size = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, 0, 0, 0, 0); + + char * utf8_str = new char[utf8_size]; + + // Convert to UTF-8. + int ok = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, utf8_str, utf8_size, 0, 0); + + if (!ok) + { + delete[] utf8_str; + } + + return ok ? std::string(utf8_str) : std::string(); + } + + void replace_char(std::string & str, char find, char replace) + { + int length = str.length(); + + for (int i = 0; i +#include + +namespace jin +{ + + /** + * Convert the wide string to a UTF-8 encoded string. + * @param wstr The wide-char string. + * @return A UTF-8 string. + **/ + std::string to_utf8(LPCWSTR wstr); + + /** + * Replace all occurences of 'find' with 'replace' in a string. + * @param str The string to modify. + * @param find The character to match. + * @param replace The character to replace matches. + **/ + void replace_char(std::string & str, char find, char replace); + +} // namespace jin + +#endif // LIBJIN_OS == LIBJIN_WINDOWS +#endif // __LIBJIN_COMMON_UTF8_H diff --git a/src/libjin/Common/types.h b/src/libjin/Common/types.h deleted file mode 100644 index 2d257c3..0000000 --- a/src/libjin/Common/types.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __LIBJIN_TYPES_H -#define __LIBJIN_TYPES_H -#include - -namespace jin -{ - 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; - - } -} - -#endif \ No newline at end of file diff --git a/src/libjin/Common/utf8.cpp b/src/libjin/Common/utf8.cpp deleted file mode 100644 index b912a51..0000000 --- a/src/libjin/Common/utf8.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_OS == LIBJIN_WINDOWS - -#include "utf8.h" - -namespace jin -{ - - std::string to_utf8(LPCWSTR wstr) - { - size_t wide_len = wcslen(wstr) + 1; - - // Get size in UTF-8. - int utf8_size = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, 0, 0, 0, 0); - - char * utf8_str = new char[utf8_size]; - - // Convert to UTF-8. - int ok = WideCharToMultiByte(CP_UTF8, 0, wstr, wide_len, utf8_str, utf8_size, 0, 0); - - if (!ok) - { - delete[] utf8_str; - } - - return ok ? std::string(utf8_str) : std::string(); - } - - void replace_char(std::string & str, char find, char replace) - { - int length = str.length(); - - for (int i = 0; i -#include - -namespace jin -{ - - /** - * Convert the wide string to a UTF-8 encoded string. - * @param wstr The wide-char string. - * @return A UTF-8 string. - **/ - std::string to_utf8(LPCWSTR wstr); - - /** - * Replace all occurences of 'find' with 'replace' in a string. - * @param str The string to modify. - * @param find The character to match. - * @param replace The character to replace matches. - **/ - void replace_char(std::string & str, char find, char replace); - -} // namespace jin - -#endif // LIBJIN_OS == LIBJIN_WINDOWS -#endif // __LIBJIN_COMMON_UTF8_H diff --git a/src/libjin/Filesystem/Buffer.h b/src/libjin/Filesystem/Buffer.h deleted file mode 100644 index f0d987a..0000000 --- a/src/libjin/Filesystem/Buffer.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef __LIBJIN_BUFFER_H -#define __LIBJIN_BUFFER_H - -#include -#include - -namespace jin -{ - 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); - } - - void clear() - { - if (data == nullptr) - return; - free(data); - data = nullptr; - } - - void* data; - unsigned int size; - - }; - - } // namespace filesystem -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Filesystem/Filesystem.cpp b/src/libjin/Filesystem/Filesystem.cpp deleted file mode 100644 index 8dce5a3..0000000 --- a/src/libjin/Filesystem/Filesystem.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "filesystem.h" -#include -#include -#include /* defines FILENAME_MAX */ - -namespace jin -{ - namespace filesystem - { - - Filesystem* Filesystem::fs = 0; - - Filesystem::Filesystem() - { - S = smtnewshared(); - } - - 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); - } - } - - 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); - } - - const char* Filesystem::getFull(const char* path) - { - return smtfullpath(S, path); - } - - bool Filesystem::isDir(const char* path) - { - return smtisdir(S, path); - } - - bool Filesystem::isFile(const char* path) - { - return smtisreg(S, path); - } - - bool Filesystem::exists(const char* path) - { - return smtexists(S, path) == 0; - } - - } // namespace filesystem -} // namespace jin \ No newline at end of file diff --git a/src/libjin/Filesystem/Filesystem.h b/src/libjin/Filesystem/Filesystem.h deleted file mode 100644 index b13e207..0000000 --- a/src/libjin/Filesystem/Filesystem.h +++ /dev/null @@ -1,31 +0,0 @@ -#include "buffer.h" -#include "../3rdparty/smount/smount.h" - -namespace jin -{ - namespace filesystem - { - /* ×ÊÔ´¹ÜÀí */ - class Filesystem - { - public: - static Filesystem* get(); - - 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); - - private: - static Filesystem* fs; - smtShared* S; - - }; - - } // namespace filesystem -} // namespace jin \ No newline at end of file diff --git a/src/libjin/Filesystem/je_buffer.h b/src/libjin/Filesystem/je_buffer.h new file mode 100644 index 0000000..f0d987a --- /dev/null +++ b/src/libjin/Filesystem/je_buffer.h @@ -0,0 +1,67 @@ +#ifndef __LIBJIN_BUFFER_H +#define __LIBJIN_BUFFER_H + +#include +#include + +namespace jin +{ + 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); + } + + void clear() + { + if (data == nullptr) + return; + free(data); + data = nullptr; + } + + void* data; + unsigned int size; + + }; + + } // namespace filesystem +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Filesystem/je_filesystem.cpp b/src/libjin/Filesystem/je_filesystem.cpp new file mode 100644 index 0000000..339d470 --- /dev/null +++ b/src/libjin/Filesystem/je_filesystem.cpp @@ -0,0 +1,68 @@ +#include +#include +#include /* defines FILENAME_MAX */ + +#include "je_filesystem.h" + +namespace jin +{ + namespace filesystem + { + + Filesystem* Filesystem::fs = 0; + + Filesystem::Filesystem() + { + S = smtnewshared(); + } + + 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); + } + } + + 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); + } + + const char* Filesystem::getFull(const char* path) + { + return smtfullpath(S, path); + } + + bool Filesystem::isDir(const char* path) + { + return smtisdir(S, path); + } + + bool Filesystem::isFile(const char* path) + { + return smtisreg(S, path); + } + + bool Filesystem::exists(const char* path) + { + return smtexists(S, path) == 0; + } + + } // namespace filesystem +} // namespace jin \ No newline at end of file diff --git a/src/libjin/Filesystem/je_filesystem.h b/src/libjin/Filesystem/je_filesystem.h new file mode 100644 index 0000000..5d65fea --- /dev/null +++ b/src/libjin/Filesystem/je_filesystem.h @@ -0,0 +1,31 @@ +#include "je_buffer.h" +#include "../3rdparty/smount/smount.h" + +namespace jin +{ + namespace filesystem + { + /* ×ÊÔ´¹ÜÀí */ + class Filesystem + { + public: + static Filesystem* get(); + + 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); + + private: + static Filesystem* fs; + smtShared* S; + + }; + + } // namespace filesystem +} // namespace jin \ No newline at end of file diff --git a/src/libjin/Game/Game.cpp b/src/libjin/Game/Game.cpp deleted file mode 100644 index b04661f..0000000 --- a/src/libjin/Game/Game.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "game.h" -#include "../Time/Timer.h" -#include "../input/Event.h" -#include "../Graphics/Window.h" -#include "../Math/Math.h" -#include - -namespace jin -{ - namespace core - { - - using namespace jin::graphics; - using namespace jin::input; - using namespace jin::time; - using namespace jin::math; - - 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:; - } - - 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() - { - } - - } // namespace core -} // namespace jin \ No newline at end of file diff --git a/src/libjin/Game/Game.h b/src/libjin/Game/Game.h deleted file mode 100644 index c7607a1..0000000 --- a/src/libjin/Game/Game.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __LIBJIN_CORE_GAME_H -#define __LIBJIN_CORE_GAME_H - -#include "SDL2/SDL.h" - -#include "../Common/Subsystem.hpp" -#include "../utils/macros.h" -#include "../Input/Event.h" - -namespace jin -{ - namespace core - { - - class Game : public Subsystem - { - 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() {}; - - singleton(Game); - - onEvent _onEvent; - onUpdate _onUpdate; - onDraw _onDraw; - onLoad _onLoad; - - bool _running; - - bool initSystem(const SettingBase* setting); - void quitSystem(); - - }; - - } // namespace core -} // namespace jin - -#endif // __LIBJIN_CORE_GAME_H diff --git a/src/libjin/Game/je_game.cpp b/src/libjin/Game/je_game.cpp new file mode 100644 index 0000000..10e9e44 --- /dev/null +++ b/src/libjin/Game/je_game.cpp @@ -0,0 +1,74 @@ +#include + +#include "../time/je_timer.h" +#include "../input/je_event.h" +#include "../graphics/je_window.h" +#include "../math/je_math.h" + +#include "je_game.h" + +namespace jin +{ + namespace core + { + + using namespace jin::graphics; + using namespace jin::input; + using namespace jin::time; + using namespace jin::math; + + 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:; + } + + 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() + { + } + + } // namespace core +} // namespace jin \ No newline at end of file diff --git a/src/libjin/Game/je_game.h b/src/libjin/Game/je_game.h new file mode 100644 index 0000000..9323177 --- /dev/null +++ b/src/libjin/Game/je_game.h @@ -0,0 +1,58 @@ +#ifndef __LIBJIN_CORE_GAME_H +#define __LIBJIN_CORE_GAME_H + +#include "../common/je_subsystem.hpp" +#include "../utils/je_macros.h" +#include "../input/je_Event.h" + +#include "SDL2/SDL.h" + +namespace jin +{ + namespace core + { + + class Game : public Subsystem + { + 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() {}; + + singleton(Game); + + onEvent _onEvent; + onUpdate _onUpdate; + onDraw _onDraw; + onLoad _onLoad; + + bool _running; + + bool initSystem(const SettingBase* setting); + void quitSystem(); + + }; + + } // namespace core +} // namespace jin + +#endif // __LIBJIN_CORE_GAME_H diff --git a/src/libjin/Graphics/Bitmap.cpp b/src/libjin/Graphics/Bitmap.cpp deleted file mode 100644 index 8769e8f..0000000 --- a/src/libjin/Graphics/Bitmap.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include "Bitmap.h" -#define STB_IMAGE_IMPLEMENTATION -#include "../3rdparty/stb/stb_image.h" -#include "../Math/math.h" - -using namespace jin::math; - -namespace jin -{ - namespace graphics - { - - /* ´Ópixel´´½¨bitmap */ - 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(x, 0, width - 1) || without(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(x, 0, width - 1) || without(y, 0, height - 1)) - return Color::BLACK; - return pixels[x + y * width]; - } - - 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 deleted file mode 100644 index 4341256..0000000 --- a/src/libjin/Graphics/Bitmap.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef __LIBJIN_BITMAP_H -#define __LIBJIN_BITMAP_H -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "../Math/Vector2.hpp" -#include "../3rdparty/GLee/GLee.h" -#include "Color.h" - -namespace jin -{ - namespace graphics - { - /// - /// A RGBA32 bitmap. - /// - /// A bitmap keeps pixels and can't render directly onto screen. To render bitmap, - /// a texture is required. A texture is create from specific bitmap. - /// - class Bitmap - { - public: - /// - /// Create bitmap by pixels data. - /// - /// @param pixels Pixels data. - /// @param width Width of bitmap. - /// @param height Height of bitmap. - /// @return Return bitmap pointer if created, otherwise return null. - /// - static Bitmap* createBitmap(const void* pixels, unsigned width, unsigned height); - - /// - /// Create bitmap from compressed image data. - /// - /// @param imgData Compressed image data. - /// @param size Size of image data. - /// @return Return bitmap pointer if created, otherwise return null. - /// - static Bitmap* createBitmap(const void* imgData, size_t size); - - /// - /// Create bitmap with specific color and size. - /// - /// @param width Width of bitmap. - /// @param height Height of bitmap. - /// @param color Color of bitmap, black by default. - /// @return Return bitmap pointer if created, otherwise return null. - /// - static Bitmap* createBitmap(int width, int height, Color color = Color::BLACK); - - /// - /// Create bitmap with another one. - /// - /// @param bitmap Bitmap be cloned. - /// @return Return bitmap pointer if created, otherwise return null. - /// - static Bitmap* clone(const Bitmap* bitmap); - - /// - /// Destructor of bitmap - /// - virtual ~Bitmap(); - - /// - /// Directly bind pixels with given pixels data - /// - /// @param pixels Pixels to be binded. - /// @param width Width of bitmap - /// @param height Height of bitmap - /// - void bind(Color* pixels, int width, int height); - - /// - /// Reset pixel data with given pixels data. - /// - /// @param pixels Pixels to be set. - /// @param width Width of bitmap - /// @param height Height of bitmap - /// - void resetPixels(const Color* pixels, int width, int height); - - /// - /// Reset pixel data with given color. - /// - /// @param color Color to be set. - /// @param width Width of bitmap - /// @param height Height of bitmap - /// - void resetPixels(const Color& color, int width, int height); - - /// - /// Set pixel with given color. - /// - /// @param color Color to be set. - /// @param x X value of pixel. - /// @param y Y value of pixel. - /// - void setPixel(const Color& color, int x, int y); - - /// - /// Set pixels with given color. - /// - /// @param color Color to be set. - /// - void setPixels(Color color); - - /// - /// Set pixels with given color data. - /// - /// @param colors New pixels' colors. - /// - void setPixels(Color* colors); - - /// - /// Get pixel in given position. - /// - /// @param x X value of position. - /// @param y Y value of position. - /// - Color getPixel(int x, int y); - - /// - /// Get pixels. - /// @return Colors of the bitmap. - /// - const Color* getPixels() const; - - /// - /// Get bitmap width. - /// - /// @return Width of bitmap. - /// - inline int getWidth() const { return width; } - - /// - /// Get bitmap height. - /// - /// @return Height of bitmap. - /// - inline int getHeight() const { return height; } - - /// - /// Get bitmap size. - /// - /// @return Size of bitmap. - /// - inline math::Vector2 getSize() const { return math::Vector2(width, height); } - - protected: - /// - /// Constructor of bitmap. - /// - Bitmap(); - - /// - /// Constructor of bitmap. - /// - /// @param width Width of bitmap. - /// @param height Height of bitmap. - /// - Bitmap(unsigned w, unsigned h); - - Color * pixels; - unsigned width, height; - - }; - - } // namespace graphics -} // namespace jin - -#endif -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Canvas.cpp b/src/libjin/Graphics/Canvas.cpp deleted file mode 100644 index f222721..0000000 --- a/src/libjin/Graphics/Canvas.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "../utils/macros.h" -#include "canvas.h" -#include "window.h" - -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, ¤t_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); - - } - - } // namespace graphics -} // namespace 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 deleted file mode 100644 index 53070bf..0000000 --- a/src/libjin/Graphics/Canvas.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __LIBJIN_CANVAS_H -#define __LIBJIN_CANVAS_H -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "drawable.h" -namespace jin -{ - namespace graphics - { - /// - /// Renderable canvas. - /// - /// A canvas is a rendering target. - /// - class Canvas: public Drawable - { - public: - /// - /// - /// - static Canvas* createCanvas(int w, int h); - - /// - /// - /// - static void bind(Canvas*); - - /// - /// - /// - static void unbind(); - - /// - /// - /// - static bool isBinded(const Canvas*); - - /// - /// - /// - ~Canvas(); - - protected: - static const Canvas* const DEFAULT_CANVAS; - static const Canvas* current; - - /// - /// - /// - Canvas(int w, int h); - - /// - /// - /// - Canvas(GLuint n); - - GLuint fbo; - - }; - - } // namespace graphics -} // namespace jin - -#endif // LIBJIN_MODULES_RENDER -#endif // __LIBJIN_CANVAS_H \ No newline at end of file diff --git a/src/libjin/Graphics/Color.cpp b/src/libjin/Graphics/Color.cpp deleted file mode 100644 index 517af50..0000000 --- a/src/libjin/Graphics/Color.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "Color.h" - -namespace jin -{ - 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); - - } -} \ No newline at end of file diff --git a/src/libjin/Graphics/Color.h b/src/libjin/Graphics/Color.h deleted file mode 100644 index 2a6feca..0000000 --- a/src/libjin/Graphics/Color.h +++ /dev/null @@ -1,85 +0,0 @@ -/** -* Some color operating here. -*/ -#ifndef __LIBJIN_COLOR_H -#define __LIBJIN_COLOR_H -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "../utils/endian.h" - -namespace jin -{ - namespace graphics - { - - 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; - - 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(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 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); - } - - Channel r, g, b, a; - - }; - - } // namespace graphics -} // namespace jin - -#endif // LIBJIN_MODULES_RENDER -#endif // __LIBJIN_COLOR_H \ No newline at end of file diff --git a/src/libjin/Graphics/Drawable.cpp b/src/libjin/Graphics/Drawable.cpp deleted file mode 100644 index f819c9c..0000000 --- a/src/libjin/Graphics/Drawable.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "./Shader/Shader.h" -#include "drawable.h" -#include "../math/matrix.h" -#include - -namespace jin -{ - namespace graphics - { - - Drawable::Drawable(int w, int h) - : texture(0) - , size(w, h) - , anchor(0, 0) - { - vertex_coords[0] = 0; vertex_coords[1] = 0; - vertex_coords[2] = 0; vertex_coords[3] = h; - vertex_coords[4] = w; vertex_coords[5] = h; - vertex_coords[6] = w; vertex_coords[7] = 0; - - texture_coords[0] = 0; texture_coords[1] = 0; - texture_coords[2] = 0; texture_coords[3] = 1; - texture_coords[4] = 1; texture_coords[5] = 1; - texture_coords[6] = 1; texture_coords[7] = 0; - } - - Drawable::Drawable(const Bitmap* bitmap) - : texture(0) - , anchor(0, 0) - { - unsigned int w = size.w = bitmap->getWidth(); - unsigned int h = size.h = bitmap->getHeight(); - - vertex_coords[0] = 0; vertex_coords[1] = 0; - vertex_coords[2] = 0; vertex_coords[3] = h; - vertex_coords[4] = w; vertex_coords[5] = h; - vertex_coords[6] = w; vertex_coords[7] = 0; - - texture_coords[0] = 0; texture_coords[1] = 0; - texture_coords[2] = 0; texture_coords[3] = 1; - texture_coords[4] = 1; texture_coords[5] = 1; - texture_coords[6] = 1; texture_coords[7] = 0; - - const Color* pixels = bitmap->getPixels(); - - texture = gl.genTexture(); - gl.bindTexture(texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - gl.bindTexture(0); - } - - Drawable::~Drawable() - { - glDeleteTextures(1, &texture); - } - - void Drawable::setAnchor(int x, int y) - { - anchor.x = x; - anchor.y = y; - } - - void Drawable::draw(int x, int y, float sx, float sy, float r) - { - gl.ModelMatrix.setTransformation(x, y, r, sx, sy, anchor.x, anchor.y); - - Shader* shader = Shader::getCurrentShader(); - shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); - shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); - shader->bindVertexPointer(2, GL_FLOAT, 0, vertex_coords); - shader->bindUVPointer(2, GL_FLOAT, 0, texture_coords); - - gl.bindTexture(texture); - gl.drawArrays(GL_QUADS, 0, 4); - gl.bindTexture(0); - } - - void Drawable::draw(const math::Quad& slice, int x, int y, float sx, float sy, float r, float ax, float ay) - { - float vertCoords[8] = { - 0, 0, - 0, slice.h, - slice.w, slice.h, - slice.w, 0 - }; - float slx = slice.x / size.w; - float sly = slice.y / size.h; - float slw = slice.w / size.w; - float slh = slice.h / size.h; - float texCoords[8] = { - slx, sly, - slx, sly + slh, - slx + slw, sly + slh, - slx + slw, sly - }; - - gl.ModelMatrix.setTransformation(x, y, r, sx, sy, ax, ay); - - Shader* shader = Shader::getCurrentShader(); - shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); - shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); - shader->bindVertexPointer(2, GL_FLOAT, 0, vertCoords); - shader->bindUVPointer(2, GL_FLOAT, 0, texCoords); - - gl.bindTexture(texture); - gl.drawArrays(GL_QUADS, 0, 4); - gl.bindTexture(0); - } - - //void Drawable::setFilter(GLint min, GLint max) - //{ - // glTexParameteri(GL_) - //} - - } // namespace graphics -} // namespace jin - -#endif // LIBJIN_MODULES_RENDER \ No newline at end of file diff --git a/src/libjin/Graphics/Drawable.h b/src/libjin/Graphics/Drawable.h deleted file mode 100644 index 007a9a1..0000000 --- a/src/libjin/Graphics/Drawable.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef __LIBJIN_DRAWABLE -#define __LIBJIN_DRAWABLE -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "../math/Quad.h" -#include "../math/Vector2.hpp" -#include "OpenGL.h" -#include "Bitmap.h" - -namespace jin -{ - namespace graphics - { - /// - /// - /// - class Drawable - { - public: - /// - /// - /// - Drawable(int w = 0, int h = 0); - - /// - /// - /// - Drawable(const Bitmap* bitmap); - - /// - /// - /// - virtual ~Drawable(); - - /// - /// - /// - void setAnchor(int x, int y); - - /// - /// - /// - void draw(int x, int y, float sx = 1, float sy = 1, float r = 0); - - /// - /// - /// - void draw(const math::Quad& slice, int x, int y, float sx = 1, float sy = 1, float r = 0, float ax = 0, float ay = 0); - - /// - /// - /// - inline int getWidth() const { return size.w; } - - /// - /// - /// - inline int getHeight() const { return size.h; } - - /// - /// - /// - inline GLuint getTexture() const { return texture; } - - /// - /// - /// - void setFilter(GLint min, GLint max); - - protected: - static const int DRAWABLE_V_SIZE = 8; - - GLuint texture; - GLuint vbo; - /* TODO: vertex buffer object */ - /* GLuint vbo; */ - jin::math::Vector2 size; - jin::math::Vector2 anchor; - float vertex_coords[DRAWABLE_V_SIZE]; - float texture_coords[DRAWABLE_V_SIZE]; - - }; - - } // namespace render -} // namespace jin - -#endif // LIBJIN_MODULES_RENDER -#endif // __LIBJIN_DRAWABLE \ No newline at end of file diff --git a/src/libjin/Graphics/Font/Decoder.cpp b/src/libjin/Graphics/Font/Decoder.cpp deleted file mode 100644 index 362fd2a..0000000 --- a/src/libjin/Graphics/Font/Decoder.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include "Decoder.h" - -namespace jin -{ - 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; - } - - 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; - } - 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* Ascii::next(const void* data) const - { - const char* p = (char*)data; - return p + 1; - } - - } // namespace graphics -} // namespace jin \ No newline at end of file diff --git a/src/libjin/Graphics/Font/Decoder.h b/src/libjin/Graphics/Font/Decoder.h deleted file mode 100644 index 533f60b..0000000 --- a/src/libjin/Graphics/Font/Decoder.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __LIBJIN_UTF8_H -#define __LIBJIN_UTF8_H - -#include - -#include "Text.h" - -namespace jin -{ - 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 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; - }; - - } // namespace graphics -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Font/Font.h b/src/libjin/Graphics/Font/Font.h deleted file mode 100644 index 1d09cfc..0000000 --- a/src/libjin/Graphics/Font/Font.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef __LIBJIN_FONT_H -#define __LIBJIN_FONT_H -#include -#include "Text.h" - -namespace jin -{ - namespace graphics - { - - struct Page; - - class Font - { - public: - /// - /// Font constructor. - /// - Font(unsigned fontsize) - : mFontSize(fontsize) - { - } - - /// - /// Font destructor. - /// - virtual ~Font() {}; - - /// - /// Create page with given text. - /// - /// @param text Text to be typesetted. - /// @param lineheight Line height of text. - /// @param spacing Spacing between characters. 0 by default. - /// @return Page if created successfully, otherwise return null. - /// - virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0; - - /// - /// Create page with given unicode codepoints. - /// - /// @param content Unicode codepoints to be typesetted. - /// @param lineheight Line height of text. - /// @param spacing Spacing between characters. 0 by default. - /// @return Page if created successfully, otherwise return null. - /// - virtual Page* typeset(const Content& content, int lineheight, int spacing = 0) = 0; - - /// - /// Render page to given position. - /// - /// @param page Page to be rendered. - /// @param x X value of the position. - /// @param y Y value of the position. - /// - virtual void print(const Page* page, int x, int y) = 0; - - /// - /// Render unicode codepoints to given position. - /// - /// @param content Unicode codepoints to be typesetted. - /// @param x X value of the position. - /// @param y Y value of the position. - /// @param lineheight Line height of the content. - /// @param spacing Spacing between characters. - /// - virtual void print(const Content& content, int x, int y, int lineheight, int spacing = 0) = 0; - - /// - /// Render text to given position. - /// - /// @param text Text to be rendered. - /// @param x X value of the position. - /// @param y Y value of the position. - /// @param lineheight Line height of the text. - /// @param spacing Spacing between characters. - /// - virtual void print(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0; - - /// - /// Get font size. - /// - /// @return Font size. - /// - inline unsigned getFontSize() { return mFontSize; }; - - protected: - unsigned mFontSize; - - }; - - } // namespace graphics -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Font/Page.h b/src/libjin/Graphics/Font/Page.h deleted file mode 100644 index e1430e1..0000000 --- a/src/libjin/Graphics/Font/Page.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __LIBJIN_PAGE_H -#define __LIBJIN_PAGE_H -#include "../../math/Vector2.hpp" -#include "Font.h" - -namespace jin -{ - namespace graphics - { - - class Font; - - 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 - }; - - /* for reduce draw call */ - struct Page - { - Font* font; - std::vector glyphinfolist; - std::vector glyphvertices; - math::Vector2 size; - }; - - } -} - -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Font/TTF.cpp b/src/libjin/Graphics/Font/TTF.cpp deleted file mode 100644 index fe47630..0000000 --- a/src/libjin/Graphics/Font/TTF.cpp +++ /dev/null @@ -1,454 +0,0 @@ -#include "../../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include - -#include "../../Common/Array.hpp" -#include "../OpenGL.h" -#include "../Color.h" -#include "../Shader/Shader.h" -#include "TTF.h" -#include "Page.h" - -#define STB_TRUETYPE_IMPLEMENTATION -#include "../../3rdparty/stb/stb_truetype.h" - -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) - { - 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 "../Shader/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& glyphinfolist = page->glyphinfolist; - vector& glyphvertices = page->glyphvertices; - int texture = -1; - TTFGlyph* glyph = nullptr; - GlyphVertex vertex; - Vector2 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& glyphinfolist = page->glyphinfolist; - const vector& 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(mFontSize); - 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(mFontSize); - 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(mFontSize); - 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(mFontSize); - *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(mFontSize); - 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(character, glyph)); - cursor.x += adw; - return glyphs[character]; - } - - TTF::TTFGlyph& TTF::findGlyph(unsigned int character) - { - map::iterator it = glyphs.find(character); - if (it != glyphs.end()) - return it->second; - else - return bakeGlyph(character); - } - - } // namespace graphics -} // namespace 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 deleted file mode 100644 index 88ddfd6..0000000 --- a/src/libjin/Graphics/Font/TTF.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef __LIBJINTTF_H -#define __LIBJIN_TTF_H -#include "../../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include -#include - -#include "../../3rdparty/stb/stb_truetype.h" -#include "../../math/quad.h" -#include "../Color.h" -#include "../drawable.h" - -#include "Page.h" -#include "Font.h" -#include "Text.h" - -namespace jin -{ - namespace graphics - { - - 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 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 atlases; - std::map glyphs; - TTFData* ttf; - int baseline; - int descent; - - /* cursor helped render to texture */ - math::Vector2 cursor; - - }; - - } // namespace graphics -} // namespace jin - -#endif // LIBJIN_MODULES_RENDER -#endif // __LIBJIN_FONT_H \ No newline at end of file diff --git a/src/libjin/Graphics/Font/Text.cpp b/src/libjin/Graphics/Font/Text.cpp deleted file mode 100644 index f2231f8..0000000 --- a/src/libjin/Graphics/Font/Text.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include - -#include "Text.h" -#include "Decoder.h" - -namespace jin -{ - namespace graphics - { - - ///////////////////////////////////////////////////////////////////////////// - // iterator - ///////////////////////////////////////////////////////////////////////////// - - Text::Iterator::Iterator(const Iterator& itor) - : data(itor.data) - , p(itor.p) - , encode(itor.encode) - , length(itor.length) - { - 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) - { - 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; - } - - 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; - } - - 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; - } - - 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; - } - - 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(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) - { - 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) - { - content.push_back(*it); - } - } - - Text::~Text() - { - } - - const Content& Text::getContent() const - { - return content; - } - - const Content& Text::operator*() const - { - return content; - } - - } // namespace graphics -} // namespace jin \ No newline at end of file diff --git a/src/libjin/Graphics/Font/Text.h b/src/libjin/Graphics/Font/Text.h deleted file mode 100644 index 7256a52..0000000 --- a/src/libjin/Graphics/Font/Text.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef __LIBJIN_TEXT_H -#define __LIBJIN_TEXT_H - -#include - -namespace jin -{ - namespace graphics - { - - typedef unsigned int Codepoint; - - typedef std::vector Content; - - class Text; - class Decoder; - - enum Encode - { - UTF8, // utf-8 - //UTF16, // utf-16 - ASCII, // ASCII - }; - - /* raw encoded text */ - class Text - { - public: - 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: - 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; - - }; - - } // namespace graphics -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Font/TextureFont.cpp b/src/libjin/Graphics/Font/TextureFont.cpp deleted file mode 100644 index 4f6f5d6..0000000 --- a/src/libjin/Graphics/Font/TextureFont.cpp +++ /dev/null @@ -1,300 +0,0 @@ -#include - -#include "../../Math/Vector2.hpp" -#include "../Shader/Shader.h" -#include "TextureFont.h" - -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) - { - 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; - } - - 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() - { - } - - const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const - { - auto it = glyphs.find(codepoint); - if (it != glyphs.end()) - { - return &it->second; - } - else - return nullptr; - } - - Page* TextureFont::typeset(const Content& text, int lineheight, int spacing) - { - Page* page = new Page(); - page->font = this; - vector& glyphinfolist = page->glyphinfolist; - vector& glyphvertices = page->glyphvertices; - int texture = -1; - const TextureGlyph* glyph = nullptr; - GlyphVertex vertex; - Vector2 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; - } - - int TextureFont::getCharWidth(int c) - { - auto it = glyphs.find(c); - if (it != glyphs.end()) - { - return it->second.w; - } - return 0; - } - - int TextureFont::getCharHeight(int c) - { - auto it = glyphs.find(c); - if (it != glyphs.end()) - { - return it->second.h; - } - return 0; - } - - int TextureFont::getTextWidth(const Content& t, int spacing) - { - 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; - } - return res; - } - - int TextureFont::getTextHeight(const Content& t, int lineheight) - { - 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; - } - } - 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) - { - 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; - } - } - - 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& glyphinfolist = page->glyphinfolist; - const vector& 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 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 count(bitmap->getWidth() / cellw, bitmap->getHeight() / cellh); - glyph.w = cellw; - glyph.h = cellh; - for (int y = 0; y < count.row; ++y) - { - glyph.y = y * cellh; - for (int x = 0; x < count.colum; ++x) - { - glyph.x = x * cellw; - if (x + y * count.colum >= codepoints.size()) - return; - glyphs.insert(std::pair(codepoints[x + y * count.colum], glyph)); - } - } - } - - 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) - { - if (x == w && newc) - { - glyph.w = x - glyph.x; - if (i >= codepoints.size()) - return; - glyphs.insert(std::pair(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(codepoints[i], glyph)); - if (codepoints[i] == 't') - { - int a = 10; - } - ++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 deleted file mode 100644 index a1d1a37..0000000 --- a/src/libjin/Graphics/Font/TextureFont.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef __LIBJIN_TEXTURE_FONT_H -#define __LIBJIN_TEXTURE_FONT_H - -#include -#include - -#include "../../Math/Vector4.hpp" -#include "../Drawable.h" -#include "../Bitmap.h" - -#include "Page.h" -#include "Font.h" -#include "Text.h" - -namespace jin -{ - 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); - - ~TextureFont(); - - 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; - - 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); - - 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 glyphs; - - }; - - } -} - -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_decoder.cpp b/src/libjin/Graphics/Font/je_decoder.cpp new file mode 100644 index 0000000..20695e7 --- /dev/null +++ b/src/libjin/Graphics/Font/je_decoder.cpp @@ -0,0 +1,93 @@ +#include +#include +#include "je_decoder.h" + +namespace jin +{ + 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; + } + + 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; + } + 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* Ascii::next(const void* data) const + { + const char* p = (char*)data; + return p + 1; + } + + } // namespace graphics +} // namespace jin \ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_decoder.h b/src/libjin/Graphics/Font/je_decoder.h new file mode 100644 index 0000000..e95f7c3 --- /dev/null +++ b/src/libjin/Graphics/Font/je_decoder.h @@ -0,0 +1,88 @@ +#ifndef __LIBJIN_UTF8_H +#define __LIBJIN_UTF8_H + +#include + +#include "je_text.h" + +namespace jin +{ + namespace graphics + { + + /// + /// Text decoder. + /// + class Decoder + { + public: + /// + /// Decode a code unit. + /// + /// @param data Code units. + /// @param codepoint Value of code point. + /// @return Next code unit location. + /// + virtual const void* decode(const void* data, Codepoint* codepoint) const = 0 ; + + /// + /// Get next code unit location. + /// + /// @param data Code units. + /// @return Next code unit location. + /// + virtual const void* next(const void* data) const = 0; + }; + + /// + /// Utf-8 decoder. + /// + class Utf8 : public Decoder + { + public: + /// + /// Decode a code unit. + /// + /// @param data Code units. + /// @param codepoint Value of code point. + /// @return Next code unit location. + /// + const void* decode(const void* data, Codepoint* codepoint) const override; + + /// + /// Get next code unit location. + /// + /// @param data Code units. + /// @return Next code unit location. + /// + const void* next(const void* data) const override; + }; + + /// + /// Ascii decoder. + /// + class Ascii : public Decoder + { + public: + /// + /// Decode a code unit. + /// + /// @param data Code units. + /// @param codepoint Value of code point. + /// @return Next code unit location. + /// + const void* decode(const void* data, Codepoint* codepoint) const override; + + /// + /// Get next code unit location. + /// + /// @param data Code units. + /// @return Next code unit location. + /// + const void* next(const void* data) const override; + }; + + } // namespace graphics +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_font.h b/src/libjin/Graphics/Font/je_font.h new file mode 100644 index 0000000..9fde723 --- /dev/null +++ b/src/libjin/Graphics/Font/je_font.h @@ -0,0 +1,99 @@ +#ifndef __LIBJIN_FONT_H +#define __LIBJIN_FONT_H + +#include +#include "je_text.h" + +namespace jin +{ + namespace graphics + { + + struct Page; + + /// + /// Base Font class. + /// + class Font + { + public: + /// + /// Font constructor. + /// + Font(unsigned fontsize) + : mFontSize(fontsize) + { + } + + /// + /// Font destructor. + /// + virtual ~Font() {}; + + /// + /// Create page with given text. + /// + /// @param text Text to be typesetted. + /// @param lineheight Line height of text. + /// @param spacing Spacing between characters. 0 by default. + /// @return Page if created successfully, otherwise return null. + /// + virtual Page* typeset(const Text& text, int lineheight, int spacing = 0) = 0; + + /// + /// Create page with given unicode codepoints. + /// + /// @param content Unicode codepoints to be typesetted. + /// @param lineheight Line height of text. + /// @param spacing Spacing between characters. 0 by default. + /// @return Page if created successfully, otherwise return null. + /// + virtual Page* typeset(const Content& content, int lineheight, int spacing = 0) = 0; + + /// + /// Render page to given position. + /// + /// @param page Page to be rendered. + /// @param x X value of the position. + /// @param y Y value of the position. + /// + virtual void print(const Page* page, int x, int y) = 0; + + /// + /// Render unicode codepoints to given position. + /// + /// @param content Unicode codepoints to be typesetted. + /// @param x X value of the position. + /// @param y Y value of the position. + /// @param lineheight Line height of the content. + /// @param spacing Spacing between characters. + /// + virtual void print(const Content& content, int x, int y, int lineheight, int spacing = 0) = 0; + + /// + /// Render text to given position. + /// + /// @param text Text to be rendered. + /// @param x X value of the position. + /// @param y Y value of the position. + /// @param lineheight Line height of the text. + /// @param spacing Spacing between characters. + /// + virtual void print(const Text& text, int x, int y, int lineheight, int spacing = 0) = 0; + + /// + /// Get font size. + /// + /// @return Font size. + /// + inline unsigned getFontSize() { return mFontSize; }; + + protected: + unsigned mFontSize; + + }; + + } // namespace graphics +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_page.h b/src/libjin/Graphics/Font/je_page.h new file mode 100644 index 0000000..d887c9b --- /dev/null +++ b/src/libjin/Graphics/Font/je_page.h @@ -0,0 +1,51 @@ +#ifndef __LIBJIN_PAGE_H +#define __LIBJIN_PAGE_H + +#include "../../math/je_vector2.hpp" + +#include "je_font.h" + +namespace jin +{ + namespace graphics + { + + class Font; + + /// + /// Glyphs data to be rendered. + /// + struct GlyphVertex + { + int x, y; ///< screen coordinates + float u, v; ///< normalized texture uv + }; + + /// + /// Glyphs info for reducing draw call. + /// + struct GlyphArrayDrawInfo + { + GLuint texture; ///< atlas + unsigned int start; ///< glyph vertex indecies + unsigned int count; ///< glyph vertex count + }; + + /// + /// Page to be rendered. + /// + /// A page is a pre-rendered text struct for reducing draw call. Each page + /// keeps a font pointer which should not be changed. + /// + struct Page + { + Font* font; + std::vector glyphinfolist; + std::vector glyphvertices; + math::Vector2 size; + }; + + } // namespace graphics +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_text.cpp b/src/libjin/Graphics/Font/je_text.cpp new file mode 100644 index 0000000..aa5cbda --- /dev/null +++ b/src/libjin/Graphics/Font/je_text.cpp @@ -0,0 +1,156 @@ +#include + +#include "je_text.h" +#include "je_decoder.h" + +namespace jin +{ + namespace graphics + { + + ///////////////////////////////////////////////////////////////////////////// + // iterator + ///////////////////////////////////////////////////////////////////////////// + + Text::Iterator::Iterator(const Iterator& itor) + : data(itor.data) + , p(itor.p) + , encode(itor.encode) + , length(itor.length) + { + 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) + { + 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; + } + + 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; + } + + 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; + } + + 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; + } + + 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(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) + { + 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) + { + content.push_back(*it); + } + } + + Text::~Text() + { + } + + const Content& Text::getContent() const + { + return content; + } + + const Content& Text::operator*() const + { + return content; + } + + } // namespace graphics +} // namespace jin \ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_text.h b/src/libjin/Graphics/Font/je_text.h new file mode 100644 index 0000000..38e60ca --- /dev/null +++ b/src/libjin/Graphics/Font/je_text.h @@ -0,0 +1,79 @@ +#ifndef __LIBJIN_TEXT_H +#define __LIBJIN_TEXT_H + +#include + +namespace jin +{ + namespace graphics + { + + typedef unsigned int Codepoint; + + typedef std::vector Content; + + class Text; + + class Decoder; + + /// + /// Supported text encoding. + /// + enum Encode + { + UTF8, ///< utf-8 + ASCII, ///< ASCII + }; + + /// + /// Decoded text. Saved as unicode codepoints. + /// + class Text + { + public: + 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: + 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; + + }; + + } // namespace graphics +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_texture_font.cpp b/src/libjin/Graphics/Font/je_texture_font.cpp new file mode 100644 index 0000000..3df77e5 --- /dev/null +++ b/src/libjin/Graphics/Font/je_texture_font.cpp @@ -0,0 +1,302 @@ +#include + +#include "../../math/je_vector2.hpp" + +#include "../shader/je_shader.h" + +#include "je_texture_font.h" + +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) + { + 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; + } + + 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() + { + } + + const TextureFont::TextureGlyph* TextureFont::findGlyph(Codepoint codepoint) const + { + auto it = glyphs.find(codepoint); + if (it != glyphs.end()) + { + return &it->second; + } + else + return nullptr; + } + + Page* TextureFont::typeset(const Content& text, int lineheight, int spacing) + { + Page* page = new Page(); + page->font = this; + vector& glyphinfolist = page->glyphinfolist; + vector& glyphvertices = page->glyphvertices; + int texture = -1; + const TextureGlyph* glyph = nullptr; + GlyphVertex vertex; + Vector2 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; + } + + int TextureFont::getCharWidth(int c) + { + auto it = glyphs.find(c); + if (it != glyphs.end()) + { + return it->second.w; + } + return 0; + } + + int TextureFont::getCharHeight(int c) + { + auto it = glyphs.find(c); + if (it != glyphs.end()) + { + return it->second.h; + } + return 0; + } + + int TextureFont::getTextWidth(const Content& t, int spacing) + { + 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; + } + return res; + } + + int TextureFont::getTextHeight(const Content& t, int lineheight) + { + 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; + } + } + 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) + { + 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; + } + } + + 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& glyphinfolist = page->glyphinfolist; + const vector& 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 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 count(bitmap->getWidth() / cellw, bitmap->getHeight() / cellh); + glyph.w = cellw; + glyph.h = cellh; + for (int y = 0; y < count.row; ++y) + { + glyph.y = y * cellh; + for (int x = 0; x < count.colum; ++x) + { + glyph.x = x * cellw; + if (x + y * count.colum >= codepoints.size()) + return; + glyphs.insert(std::pair(codepoints[x + y * count.colum], glyph)); + } + } + } + + 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) + { + if (x == w && newc) + { + glyph.w = x - glyph.x; + if (i >= codepoints.size()) + return; + glyphs.insert(std::pair(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(codepoints[i], glyph)); + if (codepoints[i] == 't') + { + int a = 10; + } + ++i; + newc = false; + } + } + } + } + + } +} \ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_texture_font.h b/src/libjin/Graphics/Font/je_texture_font.h new file mode 100644 index 0000000..fa3f72e --- /dev/null +++ b/src/libjin/Graphics/Font/je_texture_font.h @@ -0,0 +1,65 @@ +#ifndef __LIBJIN_TEXTURE_FONT_H +#define __LIBJIN_TEXTURE_FONT_H + +#include +#include + +#include "../../math/je_vector4.hpp" + +#include "../je_drawable.h" +#include "../je_bitmap.h" + +#include "je_page.h" +#include "je_font.h" +#include "je_text.h" + +namespace jin +{ + namespace graphics + { + + /// + /// + /// + 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(); + + 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; + + 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); + + 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 glyphs; + + }; + + } // namespace graphics +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_ttf.cpp b/src/libjin/Graphics/Font/je_ttf.cpp new file mode 100644 index 0000000..d44b2c7 --- /dev/null +++ b/src/libjin/Graphics/Font/je_ttf.cpp @@ -0,0 +1,456 @@ +#include "../../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include + +#include "../../common/je_array.hpp" + +#include "../je_gl.h" +#include "../je_color.h" +#include "../shader/je_shader.h" + +#include "je_ttf.h" +#include "je_page.h" + +#define STB_TRUETYPE_IMPLEMENTATION +#include "../../3rdparty/stb/stb_truetype.h" + +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) + { + 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 "../shader/je_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& glyphinfolist = page->glyphinfolist; + vector& glyphvertices = page->glyphvertices; + int texture = -1; + TTFGlyph* glyph = nullptr; + GlyphVertex vertex; + Vector2 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& glyphinfolist = page->glyphinfolist; + const vector& 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(mFontSize); + 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(mFontSize); + 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(mFontSize); + 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(mFontSize); + *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(mFontSize); + 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(character, glyph)); + cursor.x += adw; + return glyphs[character]; + } + + TTF::TTFGlyph& TTF::findGlyph(unsigned int character) + { + map::iterator it = glyphs.find(character); + if (it != glyphs.end()) + return it->second; + else + return bakeGlyph(character); + } + + } // namespace graphics +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER \ No newline at end of file diff --git a/src/libjin/Graphics/Font/je_ttf.h b/src/libjin/Graphics/Font/je_ttf.h new file mode 100644 index 0000000..f3761ac --- /dev/null +++ b/src/libjin/Graphics/Font/je_ttf.h @@ -0,0 +1,134 @@ +#ifndef __LIBJINTTF_H +#define __LIBJIN_TTF_H +#include "../../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include +#include + +#include "../../3rdparty/stb/stb_truetype.h" +#include "../../math/je_quad.h" + +#include "../je_color.h" +#include "../je_drawable.h" + +#include "je_page.h" +#include "je_font.h" +#include "je_text.h" + +namespace jin +{ + namespace graphics + { + + 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 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 atlases; + std::map glyphs; + TTFData* ttf; + int baseline; + int descent; + + /* cursor helped render to texture */ + math::Vector2 cursor; + + }; + + } // namespace graphics +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER + +#endif // __LIBJIN_FONT_H \ No newline at end of file diff --git a/src/libjin/Graphics/Graphics.h b/src/libjin/Graphics/Graphics.h deleted file mode 100644 index 68579e5..0000000 --- a/src/libjin/Graphics/Graphics.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __LIBJIN_GRAPHICS_H -#define __LIBJIN_GRAPHICS_H -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "canvas.h" -#include "color.h" -#include "Shapes.h" -#include "texture.h" -#include "window.h" -#include "Bitmap.h" -#include "Image.h" - -#include "./Shader/Shader.h" - -#include "./Font/TTF.h" -#include "./Font/Text.h" -#include "./Font/TextureFont.h" - -#endif // LIBJIN_MODULES_RENDER -#endif // __LIBJIN_GRAPHICS_H \ No newline at end of file diff --git a/src/libjin/Graphics/Image.cpp b/src/libjin/Graphics/Image.cpp deleted file mode 100644 index 358a144..0000000 --- a/src/libjin/Graphics/Image.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "../3rdparty/stb/stb_image.h" -#include "../Filesystem/Filesystem.h" -#include "Image.h" - -namespace jin -{ - namespace graphics - { - - using namespace filesystem; - - /*static*/ Image* Image::createImage(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; - Image* image = new Image(); - image->pixels = (Color*)data; - image->width = w; - image->height = h; - return image; - } - - Image* Image::createImage(const char* path) - { - Filesystem* fs = Filesystem::get(); - Buffer buffer; - fs->read(path, &buffer); - return createImage(buffer.data, buffer.size); - } - - Image::Image() - : Bitmap() - { - } - - Image::~Image() - { - } - - } // namespace graphics -} // namespace jin diff --git a/src/libjin/Graphics/Image.h b/src/libjin/Graphics/Image.h deleted file mode 100644 index 55798be..0000000 --- a/src/libjin/Graphics/Image.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __LIBJIN_IMAGE_H -#define __LIBJIN_IMAGE_H - -#include "Bitmap.h" - -namespace jin -{ - namespace graphics - { - - /// - /// A readonly bitmap. - /// - /// Just like bitmap but only from image file. The pixels data is readonly. - /// - class Image : public Bitmap - { - public: - /// - /// Create image from image file. - /// - /// @param path Image path. - /// @return Image if created successfully, otherwise return null. - /// - static Image* createImage(const char* path); - - /// - /// Create image from image data. - /// - /// @param imgData Image data to create image. - /// @param size Size of image data. - /// @return Image if created successfully, otherwise return null. - /// - static Image* createImage(const void* imgData, size_t size); - - /// - /// Image destructor. - /// - ~Image(); - - private: - /// - /// Image constructor. - /// - Image(); - - // Disable setters inherited from Bitmap. - 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); - void setPixel(const Color& pixel, int x, int y); - void setPixels(Color pixels); - void setPixels(Color* pixels); - - }; - - } // namespace graphics -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Mesh.cpp b/src/libjin/Graphics/Mesh.cpp deleted file mode 100644 index 3142894..0000000 --- a/src/libjin/Graphics/Mesh.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "Mesh.h" - -namespace jin -{ - namespace graphics - { - - - - } -} \ No newline at end of file diff --git a/src/libjin/Graphics/Mesh.h b/src/libjin/Graphics/Mesh.h deleted file mode 100644 index 66727e4..0000000 --- a/src/libjin/Graphics/Mesh.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __LIBJIN_MESH_H -#define __LIBJIN_MESH_H - -namespace jin -{ - namespace graphics - { - - class Mesh - { - public: - - private: - - - }; - - } -} - -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/OpenGL.cpp b/src/libjin/Graphics/OpenGL.cpp deleted file mode 100644 index 6bc176e..0000000 --- a/src/libjin/Graphics/OpenGL.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#define OGL2D_IMPLEMENT -#include "OpenGL.h" - -namespace jin -{ - namespace graphics - { - - OpenGL gl; - - } -} diff --git a/src/libjin/Graphics/OpenGL.h b/src/libjin/Graphics/OpenGL.h deleted file mode 100644 index 47011a2..0000000 --- a/src/libjin/Graphics/OpenGL.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __LIBJIN_OPENGL_H -#define __LIBJIN_OPENGL_H -#include "../3rdparty/GLee/GLee.h" -#include "../3rdparty/ogl/OpenGL.h" -#include "../Math/Matrix.h" - -namespace jin -{ - namespace graphics - { - - class OpenGL : public ogl2d::OpenGL - { - public: - math::Matrix ProjectionMatrix; - math::Matrix ModelMatrix; - - OpenGL() : ogl2d::OpenGL() - { - } - - }; - - extern OpenGL gl; - - } -} - -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/Shader.cpp b/src/libjin/Graphics/Shader/Shader.cpp deleted file mode 100644 index a075d7d..0000000 --- a/src/libjin/Graphics/Shader/Shader.cpp +++ /dev/null @@ -1,282 +0,0 @@ -#include -#include "../../configuration.h" -#if defined(jin_graphics_shader) - -#include - -#include "../../Filesystem/Buffer.h" -#include "../../utils/macros.h" -#include "Shader.h" -namespace jin -{ - namespace graphics - { - - using namespace jin::filesystem; - using namespace std; - - // - // default_texture - // base_shader - // SHADER_FORMAT_SIZE - // formatShader - // - #include "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; - - /*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(const string& program) - : mCurrentTextureUnit(DEFAULT_TEXTURE_UNIT) - { - if (!compile(program)) - throw 0; - } - - 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; - mPID = glCreateProgram(); - glAttachShader(mPID, vshader); - glAttachShader(mPID, fshader); - glLinkProgram(mPID); - glGetProgramiv(mPID, 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; - } - - void Shader::use() - { - glUseProgram(mPID); - CurrentShader = this; - sendInt(SHADER_MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT); - } - - /*static*/ void Shader::unuse() - { - glUseProgram(0); - CurrentShader = nullptr; - } - - GLint Shader::claimTextureUnit(const std::string& name) - { - std::map::iterator unit = mTextureUnits.find(name); - if (unit != mTextureUnits.end()) - return unit->second; - static GLint MAX_TEXTURE_UNITS = getMaxTextureUnits(); - if (++mCurrentTextureUnit >= MAX_TEXTURE_UNITS) - return 0; - mTextureUnits[name] = mCurrentTextureUnit; - return mCurrentTextureUnit; - } - - #define checkJSL() \ - if (CurrentShader != this) \ - return - - void Shader::sendInt(const char* name, int value) - { - checkJSL(); - int loc = glGetUniformLocation(mPID, name); - glUniform1i(loc, value); - } - - void Shader::sendFloat(const char* variable, float number) - { - checkJSL(); - int loc = glGetUniformLocation(mPID, variable); - glUniform1f(loc, number); - } - - // - // https://www.douban.com/note/627332677/ - // struct TextureUnit - // { - // GLuint targetTexture1D; - // GLuint targetTexture2D; - // GLuint targetTexture3D; - // GLuint targetTextureCube; - // ... - // }; - // - // TextureUnit mTextureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] - // GLuint mCurrentTextureUnit = 0; - // - void Shader::sendTexture(const char* variable, const Texture* tex) - { - checkJSL(); - GLint location = glGetUniformLocation(mPID, 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(mPID, 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); - } - - void Shader::sendVec2(const char* name, float x, float y) - { - checkJSL(); - int loc = glGetUniformLocation(mPID, name); - glUniform2f(loc, x, y); - } - - void Shader::sendVec3(const char* name, float x, float y, float z) - { - checkJSL(); - int loc = glGetUniformLocation(mPID, name); - glUniform3f(loc, x, y, z); - } - - void Shader::sendVec4(const char* name, float x, float y, float z, float w) - { - checkJSL(); - int loc = glGetUniformLocation(mPID, name); - glUniform4f(loc, x, y, z, w); - } - - void Shader::sendColor(const char* name, const Color* col) - { - checkJSL(); - int loc = glGetUniformLocation(mPID, 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(mPID, name); - glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements()); - } - - void Shader::bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) - { - GLint loc = glGetAttribLocation(mPID, 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(mPID, SHADER_TEXTURE_COORDS); - glEnableVertexAttribArray(1); - glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); - } - - } // namespace graphics -} // namespace jin - -#endif // jin_graphics_shader \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/Shader.h b/src/libjin/Graphics/Shader/Shader.h deleted file mode 100644 index 71579a9..0000000 --- a/src/libjin/Graphics/Shader/Shader.h +++ /dev/null @@ -1,197 +0,0 @@ -#ifndef __LIBJIN_SHADER_H -#define __LIBJIN_SHADER_H - -#include "../../configuration.h" -#if defined(jin_graphics) && defined(jin_graphics_shader) - -#include -#include - -#include "../../3rdparty/GLee/GLee.h" -#include "../color.h" -#include "../texture.h" -#include "../canvas.h" -#include "base.shader.h" - -namespace jin -{ - namespace graphics - { - /// - /// Built in shader program. - /// - /// Built in shader program written with custom shading language called JSL (jin - /// shading language). A JSL program is compiled into glsl, so most glsl built in - /// functions and structs are available in JSL. - /// - class Shader - { - public: - /// - /// Create shader program from source code. - /// - /// @param source The shader source code. - /// - static Shader* createShader(const std::string& source); - - /// - /// Get current shader. - /// - /// @return Current used shader program. - /// - static inline Shader* getCurrentShader() { return CurrentShader; } - - /// - /// Unuse current shader. - /// - static void unuse(); - - /// - /// Destructor of shader. - /// - virtual ~Shader(); - - /// - /// Use specific shader. - /// - void use(); - - /// - /// Send float value to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param number Value of uniform variable to be sent. - /// - void sendFloat(const char* name, float number); - - /// - /// Send texture to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param texture Texture to be sent. - /// - void sendTexture(const char* name, const Texture* texture); - - /// - /// Send integer value to shader - /// - /// @param name Name of the uniform variable to be assigned. - /// @param value Value to be sent. - /// - void sendInt(const char* name, int value); - - /// - /// Send 2D vector to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param x X value of the vector to be sent. - /// @param y Y value of the vector to be sent. - /// - void sendVec2(const char* name, float x, float y); - - /// - /// Send 3D vector to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param x X value of the vector to be sent. - /// @param y Y value of the vector to be sent. - /// @param z Z value of the vector to be sent. - /// - void sendVec3(const char* name, float x, float y, float z); - - /// - /// Send 4D vector to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param x X value of the vector to be sent. - /// @param y Y value of the vector to be sent. - /// @param z Z value of the vector to be sent. - /// @param w W value of the vector to be sent. - /// - void sendVec4(const char* name, float x, float y, float z, float w); - - /// - /// Send canvas to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param canvas Canvas to be sent. - /// - void sendCanvas(const char* name, const Canvas* canvas); - - /// - /// Send color to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param color Color to be sent. - /// - void sendColor(const char* name, const Color* color); - - /// - /// Send 4 by 4 matrix to shader. - /// - /// @param name Name of the uniform variable to be assigned. - /// @param mat4 Matrix to be sent. - /// - void sendMatrix4(const char* name, const math::Matrix* mat4); - - /// - /// Set vertices value. - /// - /// @param n Number of vertices. - /// @param type Data type of each component in the array. - /// @param stride Byte offset between consecutive generic vertex attributes. - /// @param pointers Pointer to the first component of the first generic vertex - /// attribute in the array. - /// - void bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers); - - /// - /// Set texture UV coordinates. - /// - /// @param n Number of vertices. - /// @param type Data type of each component in the array. - /// @param stride Byte offset between consecutive generic vertex attributes. - /// @param pointers Pointer to the first component of the first generic vertex - /// attribute in the array. - /// - void bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers); - - protected: - /// - /// Reference of current used shader. - /// - static Shader* CurrentShader; - - /// - /// Get texture unit of the uniform texture. If not, assign one. - /// - /// @param name Name of the texture uniform variable. - /// @return Texture unit which texture variable be assigned. - /// - GLint claimTextureUnit(const std::string& name); - - /// - /// Shader constructor. - /// - Shader(const std::string& program); - - /// - /// Compile JSL program into GLSL source. - /// - /// @param program JSL source code. - /// @return Return true if compile successed, otherwise return false. - /// - bool compile(const std::string& program); - - GLuint mPID; - GLint mCurrentTextureUnit; - std::map mTextureUnits; - - }; - - } // namespace graphics -} // namespace jin - -#endif // jin_graphics && jin_graphics_shader - -#endif // __LIBJIN_SHADER_H \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/base.shader.h b/src/libjin/Graphics/Shader/base.shader.h deleted file mode 100644 index 45b63cd..0000000 --- a/src/libjin/Graphics/Shader/base.shader.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef __LIBJIN_BASE_SHADER_H -#define __LIBJIN_BASE_SHADER_H - -static const char* base_shared = R"( -#define Number float -#define Texture sampler2D -#define Canvas sampler2D -#define Color vec4 -#define Vec2 vec2 -#define Vec3 vec3 -#define Vec4 vec4 - -#define texel texture2D - -struct Vertex -{ - vec2 xy; - vec2 uv; -}; - -)"; - -static const int BASE_SHARED_SIZE = strlen(base_shared); - -static const char* base_vertex = R"( -#version 130 core - -%s - -uniform mat4 jin_ProjectionMatrix; -uniform mat4 jin_ModelMatrix; - -in vec2 jin_VertexCoords; -in vec2 jin_TextureCoords; - -out vec4 jin_Color; -out vec2 jin_XY; -out vec2 jin_UV; - -%s - -void main() -{ - vec4 v = jin_ModelMatrix * vec4(jin_VertexCoords, 0, 1.0); - Vertex _v = vert(Vertex(v.xy, jin_TextureCoords)); - gl_Position = jin_ProjectionMatrix * vec4(_v.xy, 0, 1.0f); - jin_Color = gl_Color; - jin_XY = _v.xy; - jin_UV = _v.uv; -} -)"; - -static const int BASE_VERTEX_SHADER_SIZE = strlen(base_vertex) + BASE_SHARED_SIZE; - -#define formatVertexShader(buf, program) sprintf(buf,base_vertex, base_shared, program) - -static const char* base_fragment = R"( -#version 130 core - -%s - -uniform Texture jin_MainTexture; - -in vec4 jin_Color; -in vec2 jin_XY; -in vec2 jin_UV; - -out vec4 jin_OutColor; - -%s - -void main() -{ - jin_OutColor = frag(jin_Color, jin_MainTexture, Vertex(jin_XY, jin_UV)); -} -)"; - -static const int BASE_FRAGMENT_SHADER_SIZE = strlen(base_fragment) + BASE_SHARED_SIZE; - -#define formatFragmentShader(buf, program) sprintf(buf, base_fragment, base_shared, program) - -static const char* SHADER_PROJECTION_MATRIX = "jin_ProjectionMatrix"; -static const char* SHADER_MODEL_MATRIX = "jin_ModelMatrix"; -static const char* SHADER_MAIN_TEXTURE = "jin_MainTexture"; -static const char* SHADER_VERTEX_COORDS = "jin_VertexCoords"; -static const char* SHADER_TEXTURE_COORDS = "jin_TextureCoords"; - -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/default.shader.h b/src/libjin/Graphics/Shader/default.shader.h deleted file mode 100644 index f0175d7..0000000 --- a/src/libjin/Graphics/Shader/default.shader.h +++ /dev/null @@ -1,21 +0,0 @@ -// ĬÈÏshader -static const char* default_shader = R"( - -#VERTEX_SHADER - -Vertex vert(Vertex v) -{ - return v; -} - -#END_VERTEX_SHADER - -#FRAGMENT_SHADER - -Color frag(Color col, Texture tex, Vertex v) -{ - return col; -} - -#END_FRAGMENT_SHADER -)"; \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/font.shader.h b/src/libjin/Graphics/Shader/font.shader.h deleted file mode 100644 index e04c225..0000000 --- a/src/libjin/Graphics/Shader/font.shader.h +++ /dev/null @@ -1,21 +0,0 @@ -// ×ÖÌåshader -static const char* font_shader = R"( - -#VERTEX_SHADER - -Vertex vert(Vertex v) -{ - return v; -} - -#END_VERTEX_SHADER - -#FRAGMENT_SHADER - -Color frag(Color col, Texture tex, Vertex v) -{ - return Color(col.rgb, texel(tex, v.uv).a); -} - -#END_FRAGMENT_SHADER -)"; \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_base.shader.h b/src/libjin/Graphics/Shader/je_base.shader.h new file mode 100644 index 0000000..45b63cd --- /dev/null +++ b/src/libjin/Graphics/Shader/je_base.shader.h @@ -0,0 +1,88 @@ +#ifndef __LIBJIN_BASE_SHADER_H +#define __LIBJIN_BASE_SHADER_H + +static const char* base_shared = R"( +#define Number float +#define Texture sampler2D +#define Canvas sampler2D +#define Color vec4 +#define Vec2 vec2 +#define Vec3 vec3 +#define Vec4 vec4 + +#define texel texture2D + +struct Vertex +{ + vec2 xy; + vec2 uv; +}; + +)"; + +static const int BASE_SHARED_SIZE = strlen(base_shared); + +static const char* base_vertex = R"( +#version 130 core + +%s + +uniform mat4 jin_ProjectionMatrix; +uniform mat4 jin_ModelMatrix; + +in vec2 jin_VertexCoords; +in vec2 jin_TextureCoords; + +out vec4 jin_Color; +out vec2 jin_XY; +out vec2 jin_UV; + +%s + +void main() +{ + vec4 v = jin_ModelMatrix * vec4(jin_VertexCoords, 0, 1.0); + Vertex _v = vert(Vertex(v.xy, jin_TextureCoords)); + gl_Position = jin_ProjectionMatrix * vec4(_v.xy, 0, 1.0f); + jin_Color = gl_Color; + jin_XY = _v.xy; + jin_UV = _v.uv; +} +)"; + +static const int BASE_VERTEX_SHADER_SIZE = strlen(base_vertex) + BASE_SHARED_SIZE; + +#define formatVertexShader(buf, program) sprintf(buf,base_vertex, base_shared, program) + +static const char* base_fragment = R"( +#version 130 core + +%s + +uniform Texture jin_MainTexture; + +in vec4 jin_Color; +in vec2 jin_XY; +in vec2 jin_UV; + +out vec4 jin_OutColor; + +%s + +void main() +{ + jin_OutColor = frag(jin_Color, jin_MainTexture, Vertex(jin_XY, jin_UV)); +} +)"; + +static const int BASE_FRAGMENT_SHADER_SIZE = strlen(base_fragment) + BASE_SHARED_SIZE; + +#define formatFragmentShader(buf, program) sprintf(buf, base_fragment, base_shared, program) + +static const char* SHADER_PROJECTION_MATRIX = "jin_ProjectionMatrix"; +static const char* SHADER_MODEL_MATRIX = "jin_ModelMatrix"; +static const char* SHADER_MAIN_TEXTURE = "jin_MainTexture"; +static const char* SHADER_VERTEX_COORDS = "jin_VertexCoords"; +static const char* SHADER_TEXTURE_COORDS = "jin_TextureCoords"; + +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_default.shader.h b/src/libjin/Graphics/Shader/je_default.shader.h new file mode 100644 index 0000000..f0175d7 --- /dev/null +++ b/src/libjin/Graphics/Shader/je_default.shader.h @@ -0,0 +1,21 @@ +// ĬÈÏshader +static const char* default_shader = R"( + +#VERTEX_SHADER + +Vertex vert(Vertex v) +{ + return v; +} + +#END_VERTEX_SHADER + +#FRAGMENT_SHADER + +Color frag(Color col, Texture tex, Vertex v) +{ + return col; +} + +#END_FRAGMENT_SHADER +)"; \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_font.shader.h b/src/libjin/Graphics/Shader/je_font.shader.h new file mode 100644 index 0000000..e04c225 --- /dev/null +++ b/src/libjin/Graphics/Shader/je_font.shader.h @@ -0,0 +1,21 @@ +// ×ÖÌåshader +static const char* font_shader = R"( + +#VERTEX_SHADER + +Vertex vert(Vertex v) +{ + return v; +} + +#END_VERTEX_SHADER + +#FRAGMENT_SHADER + +Color frag(Color col, Texture tex, Vertex v) +{ + return Color(col.rgb, texel(tex, v.uv).a); +} + +#END_FRAGMENT_SHADER +)"; \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_shader.cpp b/src/libjin/Graphics/Shader/je_shader.cpp new file mode 100644 index 0000000..686f2b9 --- /dev/null +++ b/src/libjin/Graphics/Shader/je_shader.cpp @@ -0,0 +1,284 @@ +#include +#include "../../core/je_configuration.h" +#if defined(jin_graphics_shader) + +#include + +#include "../../filesystem/je_buffer.h" +#include "../../utils/je_macros.h" + +#include "je_shader.h" + +namespace jin +{ + namespace graphics + { + + using namespace jin::filesystem; + using namespace std; + + // + // default_texture + // base_shader + // SHADER_FORMAT_SIZE + // formatShader + // + #include "je_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; + + /*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(const string& program) + : mCurrentTextureUnit(DEFAULT_TEXTURE_UNIT) + { + if (!compile(program)) + throw 0; + } + + 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; + mPID = glCreateProgram(); + glAttachShader(mPID, vshader); + glAttachShader(mPID, fshader); + glLinkProgram(mPID); + glGetProgramiv(mPID, 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; + } + + void Shader::use() + { + glUseProgram(mPID); + CurrentShader = this; + sendInt(SHADER_MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT); + } + + /*static*/ void Shader::unuse() + { + glUseProgram(0); + CurrentShader = nullptr; + } + + GLint Shader::claimTextureUnit(const std::string& name) + { + std::map::iterator unit = mTextureUnits.find(name); + if (unit != mTextureUnits.end()) + return unit->second; + static GLint MAX_TEXTURE_UNITS = getMaxTextureUnits(); + if (++mCurrentTextureUnit >= MAX_TEXTURE_UNITS) + return 0; + mTextureUnits[name] = mCurrentTextureUnit; + return mCurrentTextureUnit; + } + + #define checkJSL() \ + if (CurrentShader != this) \ + return + + void Shader::sendInt(const char* name, int value) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, name); + glUniform1i(loc, value); + } + + void Shader::sendFloat(const char* variable, float number) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, variable); + glUniform1f(loc, number); + } + + // + // https://www.douban.com/note/627332677/ + // struct TextureUnit + // { + // GLuint targetTexture1D; + // GLuint targetTexture2D; + // GLuint targetTexture3D; + // GLuint targetTextureCube; + // ... + // }; + // + // TextureUnit mTextureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] + // GLuint mCurrentTextureUnit = 0; + // + void Shader::sendTexture(const char* variable, const Texture* tex) + { + checkJSL(); + GLint location = glGetUniformLocation(mPID, 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(mPID, 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); + } + + void Shader::sendVec2(const char* name, float x, float y) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, name); + glUniform2f(loc, x, y); + } + + void Shader::sendVec3(const char* name, float x, float y, float z) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, name); + glUniform3f(loc, x, y, z); + } + + void Shader::sendVec4(const char* name, float x, float y, float z, float w) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, name); + glUniform4f(loc, x, y, z, w); + } + + void Shader::sendColor(const char* name, const Color* col) + { + checkJSL(); + int loc = glGetUniformLocation(mPID, 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(mPID, name); + glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements()); + } + + void Shader::bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) + { + GLint loc = glGetAttribLocation(mPID, 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(mPID, SHADER_TEXTURE_COORDS); + glEnableVertexAttribArray(1); + glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); + } + + } // namespace graphics +} // namespace jin + +#endif // jin_graphics_shader \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_shader.h b/src/libjin/Graphics/Shader/je_shader.h new file mode 100644 index 0000000..bcee584 --- /dev/null +++ b/src/libjin/Graphics/Shader/je_shader.h @@ -0,0 +1,200 @@ +#ifndef __LIBJIN_SHADER_H +#define __LIBJIN_SHADER_H + +#include "../../core/je_configuration.h" +#if defined(jin_graphics) && defined(jin_graphics_shader) + +#include +#include + +#include "../../3rdparty/GLee/GLee.h" + +#include "../je_color.h" +#include "../je_texture.h" +#include "../je_canvas.h" + +#include "je_base.shader.h" + +namespace jin +{ + namespace graphics + { + + /// + /// Built in shader program. + /// + /// Built in shader program written with custom shading language called JSL (jin + /// shading language). A JSL program is compiled into glsl, so most glsl built in + /// functions and structs are available in JSL. + /// + class Shader + { + public: + /// + /// Create shader program from source code. + /// + /// @param source The shader source code. + /// + static Shader* createShader(const std::string& source); + + /// + /// Get current shader. + /// + /// @return Current used shader program. + /// + static inline Shader* getCurrentShader() { return CurrentShader; } + + /// + /// Unuse current shader. + /// + static void unuse(); + + /// + /// Destructor of shader. + /// + virtual ~Shader(); + + /// + /// Use specific shader. + /// + void use(); + + /// + /// Send float value to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param number Value of uniform variable to be sent. + /// + void sendFloat(const char* name, float number); + + /// + /// Send texture to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param texture Texture to be sent. + /// + void sendTexture(const char* name, const Texture* texture); + + /// + /// Send integer value to shader + /// + /// @param name Name of the uniform variable to be assigned. + /// @param value Value to be sent. + /// + void sendInt(const char* name, int value); + + /// + /// Send 2D vector to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param x X value of the vector to be sent. + /// @param y Y value of the vector to be sent. + /// + void sendVec2(const char* name, float x, float y); + + /// + /// Send 3D vector to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param x X value of the vector to be sent. + /// @param y Y value of the vector to be sent. + /// @param z Z value of the vector to be sent. + /// + void sendVec3(const char* name, float x, float y, float z); + + /// + /// Send 4D vector to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param x X value of the vector to be sent. + /// @param y Y value of the vector to be sent. + /// @param z Z value of the vector to be sent. + /// @param w W value of the vector to be sent. + /// + void sendVec4(const char* name, float x, float y, float z, float w); + + /// + /// Send canvas to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param canvas Canvas to be sent. + /// + void sendCanvas(const char* name, const Canvas* canvas); + + /// + /// Send color to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param color Color to be sent. + /// + void sendColor(const char* name, const Color* color); + + /// + /// Send 4 by 4 matrix to shader. + /// + /// @param name Name of the uniform variable to be assigned. + /// @param mat4 Matrix to be sent. + /// + void sendMatrix4(const char* name, const math::Matrix* mat4); + + /// + /// Set vertices value. + /// + /// @param n Number of vertices. + /// @param type Data type of each component in the array. + /// @param stride Byte offset between consecutive generic vertex attributes. + /// @param pointers Pointer to the first component of the first generic vertex + /// attribute in the array. + /// + void bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers); + + /// + /// Set texture UV coordinates. + /// + /// @param n Number of vertices. + /// @param type Data type of each component in the array. + /// @param stride Byte offset between consecutive generic vertex attributes. + /// @param pointers Pointer to the first component of the first generic vertex + /// attribute in the array. + /// + void bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers); + + protected: + /// + /// Reference of current used shader. + /// + static Shader* CurrentShader; + + /// + /// Get texture unit of the uniform texture. If not, assign one. + /// + /// @param name Name of the texture uniform variable. + /// @return Texture unit which texture variable be assigned. + /// + GLint claimTextureUnit(const std::string& name); + + /// + /// Shader constructor. + /// + Shader(const std::string& program); + + /// + /// Compile JSL program into GLSL source. + /// + /// @param program JSL source code. + /// @return Return true if compile successed, otherwise return false. + /// + bool compile(const std::string& program); + + GLuint mPID; + GLint mCurrentTextureUnit; + std::map mTextureUnits; + + }; + + } // namespace graphics +} // namespace jin + +#endif // jin_graphics && jin_graphics_shader + +#endif // __LIBJIN_SHADER_H \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/je_texture.shader.h b/src/libjin/Graphics/Shader/je_texture.shader.h new file mode 100644 index 0000000..d1fc86f --- /dev/null +++ b/src/libjin/Graphics/Shader/je_texture.shader.h @@ -0,0 +1,21 @@ +// Ìùͼshader +static const char* texture_shader = R"( + +#VERTEX_SHADER + +Vertex vert(Vertex v) +{ + return v; +} + +#END_VERTEX_SHADER + +#FRAGMENT_SHADER + +Color frag(Color col, Texture tex, Vertex v) +{ + return col * texel(tex, v.uv); +} + +#END_FRAGMENT_SHADER +)"; \ No newline at end of file diff --git a/src/libjin/Graphics/Shader/texture.shader.h b/src/libjin/Graphics/Shader/texture.shader.h deleted file mode 100644 index d1fc86f..0000000 --- a/src/libjin/Graphics/Shader/texture.shader.h +++ /dev/null @@ -1,21 +0,0 @@ -// Ìùͼshader -static const char* texture_shader = R"( - -#VERTEX_SHADER - -Vertex vert(Vertex v) -{ - return v; -} - -#END_VERTEX_SHADER - -#FRAGMENT_SHADER - -Color frag(Color col, Texture tex, Vertex v) -{ - return col * texel(tex, v.uv); -} - -#END_FRAGMENT_SHADER -)"; \ No newline at end of file diff --git a/src/libjin/Graphics/Shapes.cpp b/src/libjin/Graphics/Shapes.cpp deleted file mode 100644 index 69eda70..0000000 --- a/src/libjin/Graphics/Shapes.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "./Shader/Shader.h" -#include "Shapes.h" -#include "../math/matrix.h" -#include "../math/constant.h" -#include - -namespace jin -{ - namespace graphics - { - - using namespace math; - - 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); - - 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); - - 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); - - 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(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) - { - 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); - } - } - - } // namespace graphics -} // namespace 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 deleted file mode 100644 index 07e7567..0000000 --- a/src/libjin/Graphics/Shapes.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __LIBJIN_GEOMETRY_H -#define __LIBJIN_GEOMETRY_H -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "color.h" -#include "canvas.h" -#include "texture.h" - -namespace jin -{ - namespace graphics - { - - 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); - - } // namespace graphics -} // namespace jin - -#endif // LIBJIN_MODULES_RENDER -#endif // __LIBJIN_GEOMETRY_H \ No newline at end of file diff --git a/src/libjin/Graphics/Sprite.cpp b/src/libjin/Graphics/Sprite.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/libjin/Graphics/Sprite.h b/src/libjin/Graphics/Sprite.h deleted file mode 100644 index 7a4e53a..0000000 --- a/src/libjin/Graphics/Sprite.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __LIBJIN_SPRITE_H -#define __LIBJIN_SPRITE_H - -namespace jin -{ - namespace graphics - { - /// - /// A sprite is a transformable texture. - /// - class Sprite - { - public: - - }; - - } -} - -#endif \ No newline at end of file diff --git a/src/libjin/Graphics/Texture.cpp b/src/libjin/Graphics/Texture.cpp deleted file mode 100644 index 226187d..0000000 --- a/src/libjin/Graphics/Texture.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include -#include "texture.h" -#include "../utils/utils.h" -#include "../Math/Math.h" - -namespace jin -{ - namespace graphics - { - - using namespace jin::math; - - /*static*/ Texture* Texture::createTexture(Bitmap* bitmap) - { - Texture* tex = new Texture(bitmap); - return tex; - } - - Texture::Texture(const Bitmap* bitmap) - : Drawable(bitmap) - { - } - - Texture::~Texture() - { - } - - } // namespace graphics -} // namespace 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 deleted file mode 100644 index 3e0161c..0000000 --- a/src/libjin/Graphics/Texture.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __LIBJIN_TEXTURE_H -#define __LIBJIN_TEXTURE_H -#include "../configuration.h" -#if defined(jin_graphics) - -#include "../3rdparty/GLee/GLee.h" -#include "Color.h" -#include "Drawable.h" -#include "Bitmap.h" -namespace jin -{ - namespace graphics - { - /// - /// - /// - class Texture: public Drawable - { - public: - /// - /// - /// - static Texture* createTexture(Bitmap* bitmap); - - /// - /// - /// - ~Texture(); - - private: - /// - /// - /// - Texture(const Bitmap* bitmap); - - }; - - } // namespace graphics -} // namespace jin - -#endif // jin_graphics - -#endif // __LIBJIN_TEXTURE_H \ No newline at end of file diff --git a/src/libjin/Graphics/Window.cpp b/src/libjin/Graphics/Window.cpp deleted file mode 100644 index 1fd1f90..0000000 --- a/src/libjin/Graphics/Window.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include -#include "window.h" -#include "OpenGL.h" -#include "canvas.h" -#include "./Shader/Shader.h" -#include "../utils/utils.h" -#include "../audio/sdl/SDLAudio.h" -#include "../utils/log.h" - -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; - - 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); - }; - - } // namespace graphics -} // namespace 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 deleted file mode 100644 index 8d6c4f5..0000000 --- a/src/libjin/Graphics/Window.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __LIBJIN_RENDER_WINDOW -#define __LIBJIN_RENDER_WINDOW -#include "../configuration.h" -#if LIBJIN_MODULES_RENDER - -#include "SDL2/SDL.h" -#include "../utils/utils.h" -#include "../math/Vector2.hpp" -#include "../common/Subsystem.hpp" - -namespace jin -{ - namespace graphics - { - - class Window : public Subsystem - { - 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: - // declare a singleton - singleton(Window); - - Window() {}; - - virtual ~Window() {}; - bool initSystem(const SettingBase* setting) override; - void quitSystem() override; - - SDL_Window* wnd; - jin::math::Vector2 size; - int fps; - - }; - - } // namespace graphics -} // namespace jin - -#endif // LIBJIN_MODULES_RENDER -#endif // __LIBJIN_RENDER_WINDOW \ No newline at end of file diff --git a/src/libjin/Graphics/je_bitmap.cpp b/src/libjin/Graphics/je_bitmap.cpp new file mode 100644 index 0000000..2a619ac --- /dev/null +++ b/src/libjin/Graphics/je_bitmap.cpp @@ -0,0 +1,151 @@ +#define STB_IMAGE_IMPLEMENTATION +#include "../3rdparty/stb/stb_image.h" +#include "../math/je_math.h" + +#include "je_bitmap.h" + +using namespace jin::math; + +namespace jin +{ + namespace graphics + { + + /* ´Ópixel´´½¨bitmap */ + 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(x, 0, width - 1) || without(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(x, 0, width - 1) || without(y, 0, height - 1)) + return Color::BLACK; + return pixels[x + y * width]; + } + + const Color* Bitmap::getPixels() const + { + return pixels; + } + + } +} \ No newline at end of file diff --git a/src/libjin/Graphics/je_bitmap.h b/src/libjin/Graphics/je_bitmap.h new file mode 100644 index 0000000..b9747f2 --- /dev/null +++ b/src/libjin/Graphics/je_bitmap.h @@ -0,0 +1,173 @@ +#ifndef __LIBJIN_BITMAP_H +#define __LIBJIN_BITMAP_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include "../3rdparty/GLee/GLee.h" +#include "../math/je_vector2.hpp" +#include "je_color.h" + +namespace jin +{ + namespace graphics + { + /// + /// A RGBA32 bitmap. + /// + /// A bitmap keeps pixels and can't render directly onto screen. To render bitmap, + /// a texture is required. A texture is create from specific bitmap. + /// + class Bitmap + { + public: + /// + /// Create bitmap by pixels data. + /// + /// @param pixels Pixels data. + /// @param width Width of bitmap. + /// @param height Height of bitmap. + /// @return Return bitmap pointer if created, otherwise return null. + /// + static Bitmap* createBitmap(const void* pixels, unsigned width, unsigned height); + + /// + /// Create bitmap from compressed image data. + /// + /// @param imgData Compressed image data. + /// @param size Size of image data. + /// @return Return bitmap pointer if created, otherwise return null. + /// + static Bitmap* createBitmap(const void* imgData, size_t size); + + /// + /// Create bitmap with specific color and size. + /// + /// @param width Width of bitmap. + /// @param height Height of bitmap. + /// @param color Color of bitmap, black by default. + /// @return Return bitmap pointer if created, otherwise return null. + /// + static Bitmap* createBitmap(int width, int height, Color color = Color::BLACK); + + /// + /// Create bitmap with another one. + /// + /// @param bitmap Bitmap be cloned. + /// @return Return bitmap pointer if created, otherwise return null. + /// + static Bitmap* clone(const Bitmap* bitmap); + + /// + /// Destructor of bitmap + /// + virtual ~Bitmap(); + + /// + /// Directly bind pixels with given pixels data + /// + /// @param pixels Pixels to be binded. + /// @param width Width of bitmap + /// @param height Height of bitmap + /// + void bind(Color* pixels, int width, int height); + + /// + /// Reset pixel data with given pixels data. + /// + /// @param pixels Pixels to be set. + /// @param width Width of bitmap + /// @param height Height of bitmap + /// + void resetPixels(const Color* pixels, int width, int height); + + /// + /// Reset pixel data with given color. + /// + /// @param color Color to be set. + /// @param width Width of bitmap + /// @param height Height of bitmap + /// + void resetPixels(const Color& color, int width, int height); + + /// + /// Set pixel with given color. + /// + /// @param color Color to be set. + /// @param x X value of pixel. + /// @param y Y value of pixel. + /// + void setPixel(const Color& color, int x, int y); + + /// + /// Set pixels with given color. + /// + /// @param color Color to be set. + /// + void setPixels(Color color); + + /// + /// Set pixels with given color data. + /// + /// @param colors New pixels' colors. + /// + void setPixels(Color* colors); + + /// + /// Get pixel in given position. + /// + /// @param x X value of position. + /// @param y Y value of position. + /// + Color getPixel(int x, int y); + + /// + /// Get pixels. + /// @return Colors of the bitmap. + /// + const Color* getPixels() const; + + /// + /// Get bitmap width. + /// + /// @return Width of bitmap. + /// + inline int getWidth() const { return width; } + + /// + /// Get bitmap height. + /// + /// @return Height of bitmap. + /// + inline int getHeight() const { return height; } + + /// + /// Get bitmap size. + /// + /// @return Size of bitmap. + /// + inline math::Vector2 getSize() const { return math::Vector2(width, height); } + + protected: + /// + /// Constructor of bitmap. + /// + Bitmap(); + + /// + /// Constructor of bitmap. + /// + /// @param width Width of bitmap. + /// @param height Height of bitmap. + /// + Bitmap(unsigned w, unsigned h); + + Color * pixels; + unsigned width, height; + + }; + + } // namespace graphics +} // namespace jin + +#endif +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/je_canvas.cpp b/src/libjin/Graphics/je_canvas.cpp new file mode 100644 index 0000000..af9868b --- /dev/null +++ b/src/libjin/Graphics/je_canvas.cpp @@ -0,0 +1,102 @@ +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include "../utils/je_macros.h" +#include "je_canvas.h" +#include "je_window.h" + +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, ¤t_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); + + } + + } // namespace graphics +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER \ No newline at end of file diff --git a/src/libjin/Graphics/je_canvas.h b/src/libjin/Graphics/je_canvas.h new file mode 100644 index 0000000..12611d9 --- /dev/null +++ b/src/libjin/Graphics/je_canvas.h @@ -0,0 +1,66 @@ +#ifndef __LIBJIN_CANVAS_H +#define __LIBJIN_CANVAS_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include "je_drawable.h" +namespace jin +{ + namespace graphics + { + /// + /// Renderable canvas. + /// + /// A canvas is a rendering target. + /// + class Canvas: public Drawable + { + public: + /// + /// + /// + static Canvas* createCanvas(int w, int h); + + /// + /// + /// + static void bind(Canvas*); + + /// + /// + /// + static void unbind(); + + /// + /// + /// + static bool isBinded(const Canvas*); + + /// + /// + /// + ~Canvas(); + + protected: + static const Canvas* const DEFAULT_CANVAS; + static const Canvas* current; + + /// + /// + /// + Canvas(int w, int h); + + /// + /// + /// + Canvas(GLuint n); + + GLuint fbo; + + }; + + } // namespace graphics +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER +#endif // __LIBJIN_CANVAS_H \ No newline at end of file diff --git a/src/libjin/Graphics/je_color.cpp b/src/libjin/Graphics/je_color.cpp new file mode 100644 index 0000000..821f19e --- /dev/null +++ b/src/libjin/Graphics/je_color.cpp @@ -0,0 +1,17 @@ +#include "je_color.h" + +namespace jin +{ + 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); + + } +} \ No newline at end of file diff --git a/src/libjin/Graphics/je_color.h b/src/libjin/Graphics/je_color.h new file mode 100644 index 0000000..b13d882 --- /dev/null +++ b/src/libjin/Graphics/je_color.h @@ -0,0 +1,85 @@ +/** +* Some color operating here. +*/ +#ifndef __LIBJIN_COLOR_H +#define __LIBJIN_COLOR_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include "../utils/je_endian.h" + +namespace jin +{ + namespace graphics + { + + 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; + + 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(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 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); + } + + Channel r, g, b, a; + + }; + + } // namespace graphics +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER +#endif // __LIBJIN_COLOR_H \ No newline at end of file diff --git a/src/libjin/Graphics/je_drawable.cpp b/src/libjin/Graphics/je_drawable.cpp new file mode 100644 index 0000000..9b5746a --- /dev/null +++ b/src/libjin/Graphics/je_drawable.cpp @@ -0,0 +1,125 @@ +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include + +#include "../math/je_matrix.h" + +#include "shader/je_shader.h" +#include "je_drawable.h" + +namespace jin +{ + namespace graphics + { + + Drawable::Drawable(int w, int h) + : texture(0) + , size(w, h) + , anchor(0, 0) + { + vertex_coords[0] = 0; vertex_coords[1] = 0; + vertex_coords[2] = 0; vertex_coords[3] = h; + vertex_coords[4] = w; vertex_coords[5] = h; + vertex_coords[6] = w; vertex_coords[7] = 0; + + texture_coords[0] = 0; texture_coords[1] = 0; + texture_coords[2] = 0; texture_coords[3] = 1; + texture_coords[4] = 1; texture_coords[5] = 1; + texture_coords[6] = 1; texture_coords[7] = 0; + } + + Drawable::Drawable(const Bitmap* bitmap) + : texture(0) + , anchor(0, 0) + { + unsigned int w = size.w = bitmap->getWidth(); + unsigned int h = size.h = bitmap->getHeight(); + + vertex_coords[0] = 0; vertex_coords[1] = 0; + vertex_coords[2] = 0; vertex_coords[3] = h; + vertex_coords[4] = w; vertex_coords[5] = h; + vertex_coords[6] = w; vertex_coords[7] = 0; + + texture_coords[0] = 0; texture_coords[1] = 0; + texture_coords[2] = 0; texture_coords[3] = 1; + texture_coords[4] = 1; texture_coords[5] = 1; + texture_coords[6] = 1; texture_coords[7] = 0; + + const Color* pixels = bitmap->getPixels(); + + texture = gl.genTexture(); + gl.bindTexture(texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl.texImage(GL_RGBA8, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + gl.bindTexture(0); + } + + Drawable::~Drawable() + { + glDeleteTextures(1, &texture); + } + + void Drawable::setAnchor(int x, int y) + { + anchor.x = x; + anchor.y = y; + } + + void Drawable::draw(int x, int y, float sx, float sy, float r) + { + gl.ModelMatrix.setTransformation(x, y, r, sx, sy, anchor.x, anchor.y); + + Shader* shader = Shader::getCurrentShader(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + shader->bindVertexPointer(2, GL_FLOAT, 0, vertex_coords); + shader->bindUVPointer(2, GL_FLOAT, 0, texture_coords); + + gl.bindTexture(texture); + gl.drawArrays(GL_QUADS, 0, 4); + gl.bindTexture(0); + } + + void Drawable::draw(const math::Quad& slice, int x, int y, float sx, float sy, float r, float ax, float ay) + { + float vertCoords[8] = { + 0, 0, + 0, slice.h, + slice.w, slice.h, + slice.w, 0 + }; + float slx = slice.x / size.w; + float sly = slice.y / size.h; + float slw = slice.w / size.w; + float slh = slice.h / size.h; + float texCoords[8] = { + slx, sly, + slx, sly + slh, + slx + slw, sly + slh, + slx + slw, sly + }; + + gl.ModelMatrix.setTransformation(x, y, r, sx, sy, ax, ay); + + Shader* shader = Shader::getCurrentShader(); + shader->sendMatrix4(SHADER_MODEL_MATRIX, &gl.ModelMatrix); + shader->sendMatrix4(SHADER_PROJECTION_MATRIX, &gl.ProjectionMatrix); + shader->bindVertexPointer(2, GL_FLOAT, 0, vertCoords); + shader->bindUVPointer(2, GL_FLOAT, 0, texCoords); + + gl.bindTexture(texture); + gl.drawArrays(GL_QUADS, 0, 4); + gl.bindTexture(0); + } + + //void Drawable::setFilter(GLint min, GLint max) + //{ + // glTexParameteri(GL_) + //} + + } // namespace graphics +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER \ No newline at end of file diff --git a/src/libjin/Graphics/je_drawable.h b/src/libjin/Graphics/je_drawable.h new file mode 100644 index 0000000..13464f0 --- /dev/null +++ b/src/libjin/Graphics/je_drawable.h @@ -0,0 +1,90 @@ +#ifndef __LIBJIN_DRAWABLE +#define __LIBJIN_DRAWABLE +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include "../math/je_quad.h" +#include "../math/je_vector2.hpp" + +#include "je_gl.h" +#include "je_bitmap.h" + +namespace jin +{ + namespace graphics + { + /// + /// + /// + class Drawable + { + public: + /// + /// + /// + Drawable(int w = 0, int h = 0); + + /// + /// + /// + Drawable(const Bitmap* bitmap); + + /// + /// + /// + virtual ~Drawable(); + + /// + /// + /// + void setAnchor(int x, int y); + + /// + /// + /// + void draw(int x, int y, float sx = 1, float sy = 1, float r = 0); + + /// + /// + /// + void draw(const math::Quad& slice, int x, int y, float sx = 1, float sy = 1, float r = 0, float ax = 0, float ay = 0); + + /// + /// + /// + inline int getWidth() const { return size.w; } + + /// + /// + /// + inline int getHeight() const { return size.h; } + + /// + /// + /// + inline GLuint getTexture() const { return texture; } + + /// + /// + /// + void setFilter(GLint min, GLint max); + + protected: + static const int DRAWABLE_V_SIZE = 8; + + GLuint texture; + GLuint vbo; + /* TODO: vertex buffer object */ + /* GLuint vbo; */ + jin::math::Vector2 size; + jin::math::Vector2 anchor; + float vertex_coords[DRAWABLE_V_SIZE]; + float texture_coords[DRAWABLE_V_SIZE]; + + }; + + } // namespace render +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER +#endif // __LIBJIN_DRAWABLE \ No newline at end of file diff --git a/src/libjin/Graphics/je_gl.cpp b/src/libjin/Graphics/je_gl.cpp new file mode 100644 index 0000000..d228bb5 --- /dev/null +++ b/src/libjin/Graphics/je_gl.cpp @@ -0,0 +1,12 @@ +#define OGL2D_IMPLEMENT +#include "je_gl.h" + +namespace jin +{ + namespace graphics + { + + OpenGL gl; + + } +} diff --git a/src/libjin/Graphics/je_gl.h b/src/libjin/Graphics/je_gl.h new file mode 100644 index 0000000..296b8aa --- /dev/null +++ b/src/libjin/Graphics/je_gl.h @@ -0,0 +1,30 @@ +#ifndef __LIBJIN_OPENGL_H +#define __LIBJIN_OPENGL_H + +#include "../3rdparty/GLee/GLee.h" +#include "../3rdparty/ogl/OpenGL.h" +#include "../math/je_matrix.h" + +namespace jin +{ + namespace graphics + { + + class OpenGL : public ogl2d::OpenGL + { + public: + math::Matrix ProjectionMatrix; + math::Matrix ModelMatrix; + + OpenGL() : ogl2d::OpenGL() + { + } + + }; + + extern OpenGL gl; + + } +} + +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/je_graphics.h b/src/libjin/Graphics/je_graphics.h new file mode 100644 index 0000000..6f099cd --- /dev/null +++ b/src/libjin/Graphics/je_graphics.h @@ -0,0 +1,21 @@ +#ifndef __LIBJIN_GRAPHICS_H +#define __LIBJIN_GRAPHICS_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include "je_canvas.h" +#include "je_color.h" +#include "je_shapes.h" +#include "je_texture.h" +#include "je_window.h" +#include "je_bitmap.h" +#include "je_image.h" + +#include "shader/je_shader.h" + +#include "font/je_ttf.h" +#include "font/je_text.h" +#include "font/je_texture_font.h" + +#endif // LIBJIN_MODULES_RENDER +#endif // __LIBJIN_GRAPHICS_H \ No newline at end of file diff --git a/src/libjin/Graphics/je_image.cpp b/src/libjin/Graphics/je_image.cpp new file mode 100644 index 0000000..cca78a3 --- /dev/null +++ b/src/libjin/Graphics/je_image.cpp @@ -0,0 +1,46 @@ +#include "../3rdparty/stb/stb_image.h" +#include "../filesystem/je_filesystem.h" + +#include "je_image.h" + +namespace jin +{ + namespace graphics + { + + using namespace filesystem; + + /*static*/ Image* Image::createImage(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; + Image* image = new Image(); + image->pixels = (Color*)data; + image->width = w; + image->height = h; + return image; + } + + Image* Image::createImage(const char* path) + { + Filesystem* fs = Filesystem::get(); + Buffer buffer; + fs->read(path, &buffer); + return createImage(buffer.data, buffer.size); + } + + Image::Image() + : Bitmap() + { + } + + Image::~Image() + { + } + + } // namespace graphics +} // namespace jin diff --git a/src/libjin/Graphics/je_image.h b/src/libjin/Graphics/je_image.h new file mode 100644 index 0000000..5c06258 --- /dev/null +++ b/src/libjin/Graphics/je_image.h @@ -0,0 +1,60 @@ +#ifndef __LIBJIN_IMAGE_H +#define __LIBJIN_IMAGE_H + +#include "je_bitmap.h" + +namespace jin +{ + namespace graphics + { + + /// + /// A readonly bitmap. + /// + /// Just like bitmap but only from image file. The pixels data is readonly. + /// + class Image : public Bitmap + { + public: + /// + /// Create image from image file. + /// + /// @param path Image path. + /// @return Image if created successfully, otherwise return null. + /// + static Image* createImage(const char* path); + + /// + /// Create image from image data. + /// + /// @param imgData Image data to create image. + /// @param size Size of image data. + /// @return Image if created successfully, otherwise return null. + /// + static Image* createImage(const void* imgData, size_t size); + + /// + /// Image destructor. + /// + ~Image(); + + private: + /// + /// Image constructor. + /// + Image(); + + // Disable setters inherited from Bitmap. + 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); + void setPixel(const Color& pixel, int x, int y); + void setPixels(Color pixels); + void setPixels(Color* pixels); + + }; + + } // namespace graphics +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/je_mesh.cpp b/src/libjin/Graphics/je_mesh.cpp new file mode 100644 index 0000000..1047e7e --- /dev/null +++ b/src/libjin/Graphics/je_mesh.cpp @@ -0,0 +1,11 @@ +#include "je_mesh.h" + +namespace jin +{ + namespace graphics + { + + + + } +} \ No newline at end of file diff --git a/src/libjin/Graphics/je_mesh.h b/src/libjin/Graphics/je_mesh.h new file mode 100644 index 0000000..66727e4 --- /dev/null +++ b/src/libjin/Graphics/je_mesh.h @@ -0,0 +1,21 @@ +#ifndef __LIBJIN_MESH_H +#define __LIBJIN_MESH_H + +namespace jin +{ + namespace graphics + { + + class Mesh + { + public: + + private: + + + }; + + } +} + +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/je_shapes.cpp b/src/libjin/Graphics/je_shapes.cpp new file mode 100644 index 0000000..31c793f --- /dev/null +++ b/src/libjin/Graphics/je_shapes.cpp @@ -0,0 +1,128 @@ +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include + +#include "../math/je_matrix.h" +#include "../math/je_constant.h" + +#include "shader/je_shader.h" +#include "je_shapes.h" + +namespace jin +{ + namespace graphics + { + + using namespace math; + + 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); + + 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); + + 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); + + 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(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) + { + 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); + } + } + + } // namespace graphics +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER \ No newline at end of file diff --git a/src/libjin/Graphics/je_shapes.h b/src/libjin/Graphics/je_shapes.h new file mode 100644 index 0000000..32b5284 --- /dev/null +++ b/src/libjin/Graphics/je_shapes.h @@ -0,0 +1,37 @@ +#ifndef __LIBJIN_GEOMETRY_H +#define __LIBJIN_GEOMETRY_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include "je_color.h" +#include "je_canvas.h" +#include "je_texture.h" + +namespace jin +{ + namespace graphics + { + + 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); + + } // namespace graphics +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER +#endif // __LIBJIN_GEOMETRY_H \ No newline at end of file diff --git a/src/libjin/Graphics/je_sprite.cpp b/src/libjin/Graphics/je_sprite.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libjin/Graphics/je_sprite.h b/src/libjin/Graphics/je_sprite.h new file mode 100644 index 0000000..7a4e53a --- /dev/null +++ b/src/libjin/Graphics/je_sprite.h @@ -0,0 +1,20 @@ +#ifndef __LIBJIN_SPRITE_H +#define __LIBJIN_SPRITE_H + +namespace jin +{ + namespace graphics + { + /// + /// A sprite is a transformable texture. + /// + class Sprite + { + public: + + }; + + } +} + +#endif \ No newline at end of file diff --git a/src/libjin/Graphics/je_texture.cpp b/src/libjin/Graphics/je_texture.cpp new file mode 100644 index 0000000..d2e53e2 --- /dev/null +++ b/src/libjin/Graphics/je_texture.cpp @@ -0,0 +1,36 @@ +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include + +#include "../utils/je_utils.h" +#include "../math/je_math.h" + +#include "je_texture.h" + +namespace jin +{ + namespace graphics + { + + using namespace jin::math; + + /*static*/ Texture* Texture::createTexture(Bitmap* bitmap) + { + Texture* tex = new Texture(bitmap); + return tex; + } + + Texture::Texture(const Bitmap* bitmap) + : Drawable(bitmap) + { + } + + Texture::~Texture() + { + } + + } // namespace graphics +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER \ No newline at end of file diff --git a/src/libjin/Graphics/je_texture.h b/src/libjin/Graphics/je_texture.h new file mode 100644 index 0000000..30c5063 --- /dev/null +++ b/src/libjin/Graphics/je_texture.h @@ -0,0 +1,45 @@ +#ifndef __LIBJIN_TEXTURE_H +#define __LIBJIN_TEXTURE_H +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "../3rdparty/GLee/GLee.h" + +#include "je_color.h" +#include "je_drawable.h" +#include "je_bitmap.h" + +namespace jin +{ + namespace graphics + { + /// + /// + /// + class Texture: public Drawable + { + public: + /// + /// + /// + static Texture* createTexture(Bitmap* bitmap); + + /// + /// + /// + ~Texture(); + + private: + /// + /// + /// + Texture(const Bitmap* bitmap); + + }; + + } // namespace graphics +} // namespace jin + +#endif // jin_graphics + +#endif // __LIBJIN_TEXTURE_H \ No newline at end of file diff --git a/src/libjin/Graphics/je_window.cpp b/src/libjin/Graphics/je_window.cpp new file mode 100644 index 0000000..680dd0e --- /dev/null +++ b/src/libjin/Graphics/je_window.cpp @@ -0,0 +1,111 @@ +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_RENDER + +#include + +#include "../utils/je_utils.h" +#include "../audio/sdl/je_sdl_audio.h" +#include "../utils/je_log.h" + +#include "shader/je_shader.h" +#include "je_window.h" +#include "je_gl.h" +#include "je_canvas.h" + +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; + + 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); + }; + + } // namespace graphics +} // namespace jin + +#endif // LIBJIN_MODULES_RENDER \ No newline at end of file diff --git a/src/libjin/Graphics/je_window.h b/src/libjin/Graphics/je_window.h new file mode 100644 index 0000000..995d8b0 --- /dev/null +++ b/src/libjin/Graphics/je_window.h @@ -0,0 +1,96 @@ +#ifndef __LIBJIN_RENDER_WINDOW +#define __LIBJIN_RENDER_WINDOW +#include "../core/je_configuration.h" +#if defined(jin_graphics) + +#include "SDL2/SDL.h" + +#include "../utils/je_utils.h" +#include "../math/je_vector2.hpp" +#include "../common/je_subsystem.hpp" + +namespace jin +{ + namespace graphics + { + /// + /// + /// + class Window : public Subsystem + { + public: + /// + /// + /// + struct Setting : SettingBase + { + public: + const char* title; ///< window title + bool fullscreen; ///< full screen + int width, height; ///< window size + bool vsync; ///< vsync + int fps; ///< frame per second + bool resizable; ///< resizable + }; + + /// + /// + /// + 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: + // declare a singleton + singleton(Window); + + /// + /// + /// + Window() {}; + + /// + /// + /// + virtual ~Window() {}; + + /// + /// + /// + bool initSystem(const SettingBase* setting) override; + + /// + /// + /// + void quitSystem() override; + + SDL_Window* wnd; + jin::math::Vector2 size; + int fps; + + }; + + } // namespace graphics +} // namespace jin + +#endif // jin_graphics + +#endif // __LIBJIN_RENDER_WINDOW \ No newline at end of file diff --git a/src/libjin/Input/Event.cpp b/src/libjin/Input/Event.cpp deleted file mode 100644 index c8eb78c..0000000 --- a/src/libjin/Input/Event.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "event.h" -#include "SDL2\SDL.h" - -namespace jin -{ - -} // namespace jin \ No newline at end of file diff --git a/src/libjin/Input/Event.h b/src/libjin/Input/Event.h deleted file mode 100644 index 3f2bc8e..0000000 --- a/src/libjin/Input/Event.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef __LIBJIN_EVENT_H -#define __LIBJIN_EVENT_H -#include "../configuration.h" -#if LIBJIN_MODULES_INPUT - -namespace jin -{ - namespace input - { - #if LIBJIN_INPUT_SDL - #include "SDL.h" - - typedef SDL_Event Event; - typedef SDL_Keycode Key; - typedef SDL_MouseWheelEvent Wheel; - - enum EventType { - QUIT = SDL_QUIT, - /* keyboard events */ - KEY_DOWN = SDL_KEYDOWN, - KEY_UP = SDL_KEYUP, - /* mouse events */ - MOUSE_MOTION = SDL_MOUSEMOTION, - MOUSE_BUTTON_DOWN = SDL_MOUSEBUTTONDOWN, - MOUSE_BUTTON_UP = SDL_MOUSEBUTTONUP, - MOUSE_WHEEL = SDL_MOUSEWHEEL, - /* joypad events */ - JOYBUTTONDOWN = SDL_JOYBUTTONDOWN, - JOYBUTTONUP = SDL_JOYBUTTONUP, - JOYAXISMOTION = SDL_JOYAXISMOTION, - JOYBALLMOTION = SDL_JOYBALLMOTION, - JOYHATMOTION = SDL_JOYHATMOTION, - JOYDEVICEADDED = SDL_JOYDEVICEADDED, - JOYDEVICEREMOVED = SDL_JOYDEVICEREMOVED, - CONTROLLERBUTTONDOWN = SDL_CONTROLLERBUTTONDOWN, - CONTROLLERBUTTONUP = SDL_CONTROLLERBUTTONUP, - CONTROLLERAXISMOTION = SDL_CONTROLLERAXISMOTION, - /* window evnets */ - WINDOW_EVENT = SDL_WINDOWEVENT, - }; - - enum WindowEvent { - WINDOW_SHOWN = SDL_WINDOWEVENT_SHOWN , - WINDOW_HIDDEN = SDL_WINDOWEVENT_HIDDEN , - WINDOW_EXPOSED = SDL_WINDOWEVENT_EXPOSED , - WINDOW_MOVED = SDL_WINDOWEVENT_MOVED , - WINDOW_RESIZED = SDL_WINDOWEVENT_RESIZED , - WINDOW_SIZE_CAHNGE = SDL_WINDOWEVENT_SIZE_CHANGED , - WINDOW_MINIMIZED = SDL_WINDOWEVENT_MINIMIZED , - WINDOW_MAXIMIZED = SDL_WINDOWEVENT_MAXIMIZED , - WINDOW_RESTORED = SDL_WINDOWEVENT_RESTORED , - WINDOW_ENTER = SDL_WINDOWEVENT_ENTER , - WINDOW_LEAVE = SDL_WINDOWEVENT_LEAVE , - WINDOW_FOCUS_GAINED = SDL_WINDOWEVENT_FOCUS_GAINED, - WINDOW_FOCUS_LOST = SDL_WINDOWEVENT_FOCUS_LOST , - WINDOW_CLOSE = SDL_WINDOWEVENT_CLOSE , - WINDOW_TAKE_FOCUS = SDL_WINDOWEVENT_TAKE_FOCUS , - WINDOW_HIT_TEST = SDL_WINDOWEVENT_HIT_TEST , - }; - - inline int pollEvent(Event* e) - { - return SDL_PollEvent(e); - } - - inline const char* getKeyName(Key key) - { - return SDL_GetKeyName(key); - } - - inline const char* getButtonName(int button) - { - switch (button) - { - case 1: return "Left"; - case 2: return "Middle"; - case 3: return "Right"; - case 4: return "WheelUp"; - case 5: return "WheelDown"; - default: return "?"; - } - } - - /* - inline const char* getWheelName(Wheel wheel) - { - if (wheel.x == -1) - return "left"; - else if (wheel.x == 1) - return "right"; - else if (wheel.y == -1) - return "near"; - else if (wheel.y == 1) - return "far"; - else - return "none"; - } - */ - - #endif // LIBJIN_INPUT_SDL - } // namespace input -} // namespace jin - -#endif // LIBJIN_MODULES_INPUT -#endif \ No newline at end of file diff --git a/src/libjin/Input/Input.h b/src/libjin/Input/Input.h deleted file mode 100644 index a828ac7..0000000 --- a/src/libjin/Input/Input.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __LIBJIN_INPUT_H -#define __LIBJIN_INPUT_H - -#include "event.h" -#include "keyboard.h" -#include "mouse.h" -#include "joypad.h" - -#endif \ No newline at end of file diff --git a/src/libjin/Input/Joypad.cpp b/src/libjin/Input/Joypad.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/libjin/Input/Joypad.h b/src/libjin/Input/Joypad.h deleted file mode 100644 index 570699e..0000000 --- a/src/libjin/Input/Joypad.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __LIBJIN_JOYPAD_H -#define __LIBJIN_JOYPAD_H - -#include - -namespace jin -{ - namespace input - { - - inline const char* getJoyButtonName(int button) - { - switch (button) - { - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A: return "A"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B : return "B"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X : return "X"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y: return "Y"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK: return "Back"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE: return "Guide"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START: return "Start"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK: return "LeftStick"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK: return "RightStick"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return "LeftShoulder"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return "RightShoulder"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP: return "DpadUp"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN: return "DpadDown"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT: return "DpadLeft"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return "DpadRight"; break; - default: return NULL; - } - } - - inline const char* getJoyAxisName(int axis) - { - switch (axis) - { - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX: return "LeftX"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY: return "LeftY"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX: return "RightX"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY: return "RightY"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT: return "TriggerLeft"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT: return "TriggerRight"; break; - } - } - - } // namespace input -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Input/Keyboard.cpp b/src/libjin/Input/Keyboard.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/libjin/Input/Keyboard.h b/src/libjin/Input/Keyboard.h deleted file mode 100644 index 60f1169..0000000 --- a/src/libjin/Input/Keyboard.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __LIBJIN_KEYBOARD_H -#define __LIBJIN_KEYBOARD_H - -namespace jin -{ - namespace input - { - - class Keyboard - { - - }; - - } // namespace input -} // namespace 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 deleted file mode 100644 index dcaa771..0000000 --- a/src/libjin/Input/Mouse.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "../configuration.h" -#ifdef LIBJIN_MODULES_INPUT - -#include "SDL.h" -#include "Mouse.h" - -namespace jin -{ - namespace input - { - - 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); - } - - } // namespace input -} // namespace 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 deleted file mode 100644 index 7e93792..0000000 --- a/src/libjin/Input/Mouse.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __LIBJIN_MOUSE_H -#define __LIBJIN_MOUSE_H -#include "../configuration.h" -#ifdef LIBJIN_MODULES_INPUT - -#include "../Common/Singleton.hpp" - -namespace jin -{ - namespace input - { - - class Mouse : public Singleton - { - public: - void getState(int* x, int* y); - void setVisible(bool visible); - - private: - singleton(Mouse); - - Mouse() {}; - ~Mouse() {}; - - }; - - } // namespace input -} // namespace jin - -#endif // LIBJIN_MODULES_INPUT -#endif // __LIBJIN_MOUSE_H \ No newline at end of file diff --git a/src/libjin/Input/je_event.cpp b/src/libjin/Input/je_event.cpp new file mode 100644 index 0000000..4f55839 --- /dev/null +++ b/src/libjin/Input/je_event.cpp @@ -0,0 +1,8 @@ +#include "SDL2\SDL.h" + +#include "je_event.h" + +namespace jin +{ + +} // namespace jin \ No newline at end of file diff --git a/src/libjin/Input/je_event.h b/src/libjin/Input/je_event.h new file mode 100644 index 0000000..d8ceda0 --- /dev/null +++ b/src/libjin/Input/je_event.h @@ -0,0 +1,105 @@ +#ifndef __LIBJIN_EVENT_H +#define __LIBJIN_EVENT_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_INPUT + +namespace jin +{ + namespace input + { + #if LIBJIN_INPUT_SDL + #include "SDL.h" + + typedef SDL_Event Event; + typedef SDL_Keycode Key; + typedef SDL_MouseWheelEvent Wheel; + + enum EventType { + QUIT = SDL_QUIT, + /* keyboard events */ + KEY_DOWN = SDL_KEYDOWN, + KEY_UP = SDL_KEYUP, + /* mouse events */ + MOUSE_MOTION = SDL_MOUSEMOTION, + MOUSE_BUTTON_DOWN = SDL_MOUSEBUTTONDOWN, + MOUSE_BUTTON_UP = SDL_MOUSEBUTTONUP, + MOUSE_WHEEL = SDL_MOUSEWHEEL, + /* joypad events */ + JOYBUTTONDOWN = SDL_JOYBUTTONDOWN, + JOYBUTTONUP = SDL_JOYBUTTONUP, + JOYAXISMOTION = SDL_JOYAXISMOTION, + JOYBALLMOTION = SDL_JOYBALLMOTION, + JOYHATMOTION = SDL_JOYHATMOTION, + JOYDEVICEADDED = SDL_JOYDEVICEADDED, + JOYDEVICEREMOVED = SDL_JOYDEVICEREMOVED, + CONTROLLERBUTTONDOWN = SDL_CONTROLLERBUTTONDOWN, + CONTROLLERBUTTONUP = SDL_CONTROLLERBUTTONUP, + CONTROLLERAXISMOTION = SDL_CONTROLLERAXISMOTION, + /* window evnets */ + WINDOW_EVENT = SDL_WINDOWEVENT, + }; + + enum WindowEvent { + WINDOW_SHOWN = SDL_WINDOWEVENT_SHOWN , + WINDOW_HIDDEN = SDL_WINDOWEVENT_HIDDEN , + WINDOW_EXPOSED = SDL_WINDOWEVENT_EXPOSED , + WINDOW_MOVED = SDL_WINDOWEVENT_MOVED , + WINDOW_RESIZED = SDL_WINDOWEVENT_RESIZED , + WINDOW_SIZE_CAHNGE = SDL_WINDOWEVENT_SIZE_CHANGED , + WINDOW_MINIMIZED = SDL_WINDOWEVENT_MINIMIZED , + WINDOW_MAXIMIZED = SDL_WINDOWEVENT_MAXIMIZED , + WINDOW_RESTORED = SDL_WINDOWEVENT_RESTORED , + WINDOW_ENTER = SDL_WINDOWEVENT_ENTER , + WINDOW_LEAVE = SDL_WINDOWEVENT_LEAVE , + WINDOW_FOCUS_GAINED = SDL_WINDOWEVENT_FOCUS_GAINED, + WINDOW_FOCUS_LOST = SDL_WINDOWEVENT_FOCUS_LOST , + WINDOW_CLOSE = SDL_WINDOWEVENT_CLOSE , + WINDOW_TAKE_FOCUS = SDL_WINDOWEVENT_TAKE_FOCUS , + WINDOW_HIT_TEST = SDL_WINDOWEVENT_HIT_TEST , + }; + + inline int pollEvent(Event* e) + { + return SDL_PollEvent(e); + } + + inline const char* getKeyName(Key key) + { + return SDL_GetKeyName(key); + } + + inline const char* getButtonName(int button) + { + switch (button) + { + case 1: return "Left"; + case 2: return "Middle"; + case 3: return "Right"; + case 4: return "WheelUp"; + case 5: return "WheelDown"; + default: return "?"; + } + } + + /* + inline const char* getWheelName(Wheel wheel) + { + if (wheel.x == -1) + return "left"; + else if (wheel.x == 1) + return "right"; + else if (wheel.y == -1) + return "near"; + else if (wheel.y == 1) + return "far"; + else + return "none"; + } + */ + + #endif // LIBJIN_INPUT_SDL + } // namespace input +} // namespace jin + +#endif // LIBJIN_MODULES_INPUT +#endif \ No newline at end of file diff --git a/src/libjin/Input/je_input.h b/src/libjin/Input/je_input.h new file mode 100644 index 0000000..2f6a895 --- /dev/null +++ b/src/libjin/Input/je_input.h @@ -0,0 +1,9 @@ +#ifndef __LIBJIN_INPUT_H +#define __LIBJIN_INPUT_H + +#include "je_event.h" +#include "je_keyboard.h" +#include "je_mouse.h" +#include "je_joypad.h" + +#endif \ No newline at end of file diff --git a/src/libjin/Input/je_joypad.cpp b/src/libjin/Input/je_joypad.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libjin/Input/je_joypad.h b/src/libjin/Input/je_joypad.h new file mode 100644 index 0000000..570699e --- /dev/null +++ b/src/libjin/Input/je_joypad.h @@ -0,0 +1,50 @@ +#ifndef __LIBJIN_JOYPAD_H +#define __LIBJIN_JOYPAD_H + +#include + +namespace jin +{ + namespace input + { + + inline const char* getJoyButtonName(int button) + { + switch (button) + { + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A: return "A"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B : return "B"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X : return "X"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y: return "Y"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK: return "Back"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE: return "Guide"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START: return "Start"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK: return "LeftStick"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK: return "RightStick"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return "LeftShoulder"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return "RightShoulder"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP: return "DpadUp"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN: return "DpadDown"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT: return "DpadLeft"; break; + case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return "DpadRight"; break; + default: return NULL; + } + } + + inline const char* getJoyAxisName(int axis) + { + switch (axis) + { + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX: return "LeftX"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY: return "LeftY"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX: return "RightX"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY: return "RightY"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT: return "TriggerLeft"; break; + case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT: return "TriggerRight"; break; + } + } + + } // namespace input +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Input/je_keyboard.cpp b/src/libjin/Input/je_keyboard.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/libjin/Input/je_keyboard.h b/src/libjin/Input/je_keyboard.h new file mode 100644 index 0000000..60f1169 --- /dev/null +++ b/src/libjin/Input/je_keyboard.h @@ -0,0 +1,17 @@ +#ifndef __LIBJIN_KEYBOARD_H +#define __LIBJIN_KEYBOARD_H + +namespace jin +{ + namespace input + { + + class Keyboard + { + + }; + + } // namespace input +} // namespace jin + +#endif // __LIBJIN_KEYBOARD_H \ No newline at end of file diff --git a/src/libjin/Input/je_mouse.cpp b/src/libjin/Input/je_mouse.cpp new file mode 100644 index 0000000..21e59fb --- /dev/null +++ b/src/libjin/Input/je_mouse.cpp @@ -0,0 +1,28 @@ +#include "../core/je_configuration.h" +#ifdef LIBJIN_MODULES_INPUT + +#include "SDL.h" + +#include "je_mouse.h" + +namespace jin +{ + namespace input + { + + 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); + } + + } // namespace input +} // namespace jin + +#endif // LIBJIN_MODULES_INPUT \ No newline at end of file diff --git a/src/libjin/Input/je_mouse.h b/src/libjin/Input/je_mouse.h new file mode 100644 index 0000000..e9fab42 --- /dev/null +++ b/src/libjin/Input/je_mouse.h @@ -0,0 +1,31 @@ +#ifndef __LIBJIN_MOUSE_H +#define __LIBJIN_MOUSE_H +#include "../core/je_configuration.h" +#ifdef LIBJIN_MODULES_INPUT + +#include "../common/je_singleton.hpp" + +namespace jin +{ + namespace input + { + + class Mouse : public Singleton + { + public: + void getState(int* x, int* y); + void setVisible(bool visible); + + private: + singleton(Mouse); + + Mouse() {}; + ~Mouse() {}; + + }; + + } // namespace input +} // namespace jin + +#endif // LIBJIN_MODULES_INPUT +#endif // __LIBJIN_MOUSE_H \ No newline at end of file diff --git a/src/libjin/Math/Math.h b/src/libjin/Math/Math.h deleted file mode 100644 index c1b5084..0000000 --- a/src/libjin/Math/Math.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __LIBJIN_UTILS_MATH_H -#define __LIBJIN_UTILS_MATH_H - -#include "constant.h" -#include "matrix.h" -#include "quad.h" - -namespace jin -{ - namespace math - { - - #ifdef min - # undef min - #endif // min - #ifdef max - # undef max - #endif // max - - template - inline T min(T a, T b) - { - return a < b ? a : b; - } - - template - inline T max(T a, T b) - { - return a > b ? a : b; - } - - template - inline T clamp(T a, T mi, T ma) - { - return min(max(a, mi), ma); - } - - template - inline bool within(T a, T mi, T ma) - { - return a >= mi && a <= ma; - } - - template - inline bool without(T a, T mi, T ma) - { - return a < mi || a > ma; - } - - template - inline T abs(T a) - { - return a > 0 ? a : -a; - } - - template - inline T lowerBound(T a, T lower) - { - return a < lower ? lower : a; - } - - template - inline T upperBound(T a, T upper) - { - return a > upper ? upper : a; - } - - template - inline T lerp(T a, T b, float t) - { - return a + t * (b - a); - } - - } // namespace math -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Math/Matrix.cpp b/src/libjin/Math/Matrix.cpp deleted file mode 100644 index 9f933f8..0000000 --- a/src/libjin/Math/Matrix.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include "Matrix.h" - -#include // memcpy -#include - -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 - class Vector2 - { - public: - Vector2() - { - data[0] = data[1] = 0; - } - Vector2(T _x, T _y) - { - data[0] = _x; - data[1] = _y; - } - Vector2(const Vector2& 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 - - private: - T data[2]; - - }; - - } // namespace math -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Math/Vector3.hpp b/src/libjin/Math/Vector3.hpp deleted file mode 100644 index 96d4e9a..0000000 --- a/src/libjin/Math/Vector3.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __LIBJIN_VECTOR3_H -#define __LIBJIN_VECTOR3_H - -namespace jin -{ - namespace math - { - - template - 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& 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 - - private: - T data[3]; - - }; - - } // namespace math -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Math/Vector4.hpp b/src/libjin/Math/Vector4.hpp deleted file mode 100644 index 35be056..0000000 --- a/src/libjin/Math/Vector4.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __LIBJIN_VECTOR4_H -#define __LIBJIN_VECTOR4_H - -namespace jin -{ - namespace math - { - - template - 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& 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 - - private: - T data[4]; - - }; - - } // namespace math -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/Math/constant.h b/src/libjin/Math/constant.h deleted file mode 100644 index f8e0f5a..0000000 --- a/src/libjin/Math/constant.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __LIBJIN_MATH_CONSTANT_H -#define __LIBJIN_MATH_CONSTANT_H - -#define PI 3.1415926f - -// int16 ·¶Î§ -#define INT16_RANGE_LEFT -32768 -#define INT16_RANGE_RIGHT 32767 - -#endif \ No newline at end of file diff --git a/src/libjin/Math/je_constant.h b/src/libjin/Math/je_constant.h new file mode 100644 index 0000000..f8e0f5a --- /dev/null +++ b/src/libjin/Math/je_constant.h @@ -0,0 +1,10 @@ +#ifndef __LIBJIN_MATH_CONSTANT_H +#define __LIBJIN_MATH_CONSTANT_H + +#define PI 3.1415926f + +// int16 ·¶Î§ +#define INT16_RANGE_LEFT -32768 +#define INT16_RANGE_RIGHT 32767 + +#endif \ No newline at end of file diff --git a/src/libjin/Math/je_math.h b/src/libjin/Math/je_math.h new file mode 100644 index 0000000..b6a2ffd --- /dev/null +++ b/src/libjin/Math/je_math.h @@ -0,0 +1,77 @@ +#ifndef __LIBJIN_UTILS_MATH_H +#define __LIBJIN_UTILS_MATH_H + +#include "je_constant.h" +#include "je_matrix.h" +#include "je_quad.h" + +namespace jin +{ + namespace math + { + + #ifdef min + # undef min + #endif // min + #ifdef max + # undef max + #endif // max + + template + inline T min(T a, T b) + { + return a < b ? a : b; + } + + template + inline T max(T a, T b) + { + return a > b ? a : b; + } + + template + inline T clamp(T a, T mi, T ma) + { + return min(max(a, mi), ma); + } + + template + inline bool within(T a, T mi, T ma) + { + return a >= mi && a <= ma; + } + + template + inline bool without(T a, T mi, T ma) + { + return a < mi || a > ma; + } + + template + inline T abs(T a) + { + return a > 0 ? a : -a; + } + + template + inline T lowerBound(T a, T lower) + { + return a < lower ? lower : a; + } + + template + inline T upperBound(T a, T upper) + { + return a > upper ? upper : a; + } + + template + inline T lerp(T a, T b, float t) + { + return a + t * (b - a); + } + + } // namespace math +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Math/je_matrix.cpp b/src/libjin/Math/je_matrix.cpp new file mode 100644 index 0000000..3a878a0 --- /dev/null +++ b/src/libjin/Math/je_matrix.cpp @@ -0,0 +1,194 @@ +#include "je_matrix.h" + +#include // memcpy +#include + +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 + class Vector2 + { + public: + Vector2() + { + data[0] = data[1] = 0; + } + Vector2(T _x, T _y) + { + data[0] = _x; + data[1] = _y; + } + Vector2(const Vector2& 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 + + private: + T data[2]; + + }; + + } // namespace math +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Math/je_vector3.hpp b/src/libjin/Math/je_vector3.hpp new file mode 100644 index 0000000..96d4e9a --- /dev/null +++ b/src/libjin/Math/je_vector3.hpp @@ -0,0 +1,41 @@ +#ifndef __LIBJIN_VECTOR3_H +#define __LIBJIN_VECTOR3_H + +namespace jin +{ + namespace math + { + + template + 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& 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 + + private: + T data[3]; + + }; + + } // namespace math +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Math/je_vector4.hpp b/src/libjin/Math/je_vector4.hpp new file mode 100644 index 0000000..35be056 --- /dev/null +++ b/src/libjin/Math/je_vector4.hpp @@ -0,0 +1,45 @@ +#ifndef __LIBJIN_VECTOR4_H +#define __LIBJIN_VECTOR4_H + +namespace jin +{ + namespace math + { + + template + 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& 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 + + private: + T data[4]; + + }; + + } // namespace math +} // namespace jin + +#endif \ No newline at end of file diff --git a/src/libjin/Net/Net.cpp b/src/libjin/Net/Net.cpp deleted file mode 100644 index 940b239..0000000 --- a/src/libjin/Net/Net.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "Net.h" - -namespace jin -{ - namespace net - { - - bool Net::initSystem(const SettingBase* setting) - { - #ifdef _WIN32 - #if LIBJIN_NET_TEKCOS - tk_init(); - #endif - #endif - return true; - } - - void Net::quitSystem() - { - - } - - } // namespace net -} // namespace jin \ No newline at end of file diff --git a/src/libjin/Net/Net.h b/src/libjin/Net/Net.h deleted file mode 100644 index 3324d11..0000000 --- a/src/libjin/Net/Net.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __LIBJIN_NET_H -#define __LIBJIN_NET_H -#include "../configuration.h" -#if LIBJIN_MODULES_NET - -#include "../Common/Subsystem.hpp" -#include "Socket.h" - -namespace jin -{ - namespace net - { - - class Net : public Subsystem - { - public: - - protected: - singleton(Net); - Net() {}; - ~Net() {}; - bool initSystem(const SettingBase* setting) override; - void quitSystem() override; - - }; - - } // namespace net -} // namespace jin - -#endif // LIBJIN_MODULES_NET -#endif // __LIBJIN_NET_H diff --git a/src/libjin/Net/Socket.cpp b/src/libjin/Net/Socket.cpp deleted file mode 100644 index 770b47d..0000000 --- a/src/libjin/Net/Socket.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include "Socket.h" - -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 - } - - 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 - } - } - - } // namespace net -} // namespace jin \ No newline at end of file diff --git a/src/libjin/Net/Socket.h b/src/libjin/Net/Socket.h deleted file mode 100644 index 04d3ab0..0000000 --- a/src/libjin/Net/Socket.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef __LIBJIN_NET_SOCKET_H -#define __LIBJIN_NET_SOCKET_H -#include "../configuration.h" -#if LIBJIN_MODULES_NET - -#include "../3rdparty/tekcos/tekcos.h" - -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(); - - 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; - - }; - - } // namespace net -} // namespace jin - -#endif // LIBJIN_MODULES_NET -#endif // __LIBJIN_NET_SOCKET_H diff --git a/src/libjin/Net/je_net.cpp b/src/libjin/Net/je_net.cpp new file mode 100644 index 0000000..c417108 --- /dev/null +++ b/src/libjin/Net/je_net.cpp @@ -0,0 +1,24 @@ +#include "je_net.h" + +namespace jin +{ + namespace net + { + + bool Net::initSystem(const SettingBase* setting) + { + #ifdef _WIN32 + #if LIBJIN_NET_TEKCOS + tk_init(); + #endif + #endif + return true; + } + + void Net::quitSystem() + { + + } + + } // namespace net +} // namespace jin \ No newline at end of file diff --git a/src/libjin/Net/je_net.h b/src/libjin/Net/je_net.h new file mode 100644 index 0000000..7718085 --- /dev/null +++ b/src/libjin/Net/je_net.h @@ -0,0 +1,32 @@ +#ifndef __LIBJIN_NET_H +#define __LIBJIN_NET_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_NET + +#include "../common/je_subsystem.hpp" + +#include "je_socket.h" + +namespace jin +{ + namespace net + { + + class Net : public Subsystem + { + public: + + protected: + singleton(Net); + Net() {}; + ~Net() {}; + bool initSystem(const SettingBase* setting) override; + void quitSystem() override; + + }; + + } // namespace net +} // namespace jin + +#endif // LIBJIN_MODULES_NET +#endif // __LIBJIN_NET_H diff --git a/src/libjin/Net/je_socket.cpp b/src/libjin/Net/je_socket.cpp new file mode 100644 index 0000000..3a8be7f --- /dev/null +++ b/src/libjin/Net/je_socket.cpp @@ -0,0 +1,190 @@ +#include "je_socket.h" + +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 + } + + 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 + } + } + + } // namespace net +} // namespace jin \ No newline at end of file diff --git a/src/libjin/Net/je_socket.h b/src/libjin/Net/je_socket.h new file mode 100644 index 0000000..ab6a561 --- /dev/null +++ b/src/libjin/Net/je_socket.h @@ -0,0 +1,62 @@ +#ifndef __LIBJIN_NET_SOCKET_H +#define __LIBJIN_NET_SOCKET_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_NET + +#include "../3rdparty/tekcos/tekcos.h" + +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(); + + 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; + + }; + + } // namespace net +} // namespace jin + +#endif // LIBJIN_MODULES_NET +#endif // __LIBJIN_NET_SOCKET_H diff --git a/src/libjin/Net/net.cpp b/src/libjin/Net/net.cpp deleted file mode 100644 index 940b239..0000000 --- a/src/libjin/Net/net.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "Net.h" - -namespace jin -{ - namespace net - { - - bool Net::initSystem(const SettingBase* setting) - { - #ifdef _WIN32 - #if LIBJIN_NET_TEKCOS - tk_init(); - #endif - #endif - return true; - } - - void Net::quitSystem() - { - - } - - } // namespace net -} // namespace jin \ No newline at end of file diff --git a/src/libjin/Net/net.h b/src/libjin/Net/net.h deleted file mode 100644 index 3324d11..0000000 --- a/src/libjin/Net/net.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __LIBJIN_NET_H -#define __LIBJIN_NET_H -#include "../configuration.h" -#if LIBJIN_MODULES_NET - -#include "../Common/Subsystem.hpp" -#include "Socket.h" - -namespace jin -{ - namespace net - { - - class Net : public Subsystem - { - public: - - protected: - singleton(Net); - Net() {}; - ~Net() {}; - bool initSystem(const SettingBase* setting) override; - void quitSystem() override; - - }; - - } // namespace net -} // namespace jin - -#endif // LIBJIN_MODULES_NET -#endif // __LIBJIN_NET_H diff --git a/src/libjin/Thread/Thread.cpp b/src/libjin/Thread/Thread.cpp deleted file mode 100644 index 3f2a50d..0000000 --- a/src/libjin/Thread/Thread.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_THREAD - -#include "Thread.h" - -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&) {} - - }; - - ////////////////////////////////////////////////////////////////////// - - 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(); - }; - - 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(); - } - - } // namespace thread -} // namespace 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 deleted file mode 100644 index ea50444..0000000 --- a/src/libjin/Thread/Thread.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef __LIBJIN_THREAD_H -#define __LIBJIN_THREAD_H -#include "../configuration.h" -#if LIBJIN_MODULES_THREAD - -#include -#include -#if LIBJIN_THREAD_SDL -# include "SDL2/SDL_thread.h" -#elif LIBJIN_THREAD_CPP -# include -# include -# include -#endif - -namespace jin -{ - 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) {}; - }; - - 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); - - Conditional* condition; - Mutex* mutex; - - private: - std::map share; // threads shared value - - }; - - 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(); - - 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 - - }; - - } // namespace thread -} // namespace jin - -#endif // LIBJIN_MODULES_THREAD -#endif // __LIBJIN_THREAD_H \ No newline at end of file diff --git a/src/libjin/Thread/je_thread.cpp b/src/libjin/Thread/je_thread.cpp new file mode 100644 index 0000000..6bf6f46 --- /dev/null +++ b/src/libjin/Thread/je_thread.cpp @@ -0,0 +1,301 @@ +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_THREAD + +#include "je_thread.h" + +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&) {} + + }; + + ////////////////////////////////////////////////////////////////////// + + 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(); + }; + + 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(); + } + + } // namespace thread +} // namespace jin + +#endif // LIBJIN_MODULES_THREAD \ No newline at end of file diff --git a/src/libjin/Thread/je_thread.h b/src/libjin/Thread/je_thread.h new file mode 100644 index 0000000..bdbc093 --- /dev/null +++ b/src/libjin/Thread/je_thread.h @@ -0,0 +1,166 @@ +#ifndef __LIBJIN_THREAD_H +#define __LIBJIN_THREAD_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_THREAD + +#include +#include +#if LIBJIN_THREAD_SDL + #include "SDL2/SDL_thread.h" +#elif LIBJIN_THREAD_CPP + #include + #include + #include +#endif + +namespace jin +{ + 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) {}; + }; + + 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); + + Conditional* condition; + Mutex* mutex; + + private: + std::map share; // threads shared value + + }; + + 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(); + + 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 + + }; + + } // namespace thread +} // namespace jin + +#endif // LIBJIN_MODULES_THREAD +#endif // __LIBJIN_THREAD_H \ No newline at end of file diff --git a/src/libjin/Thread/thread.cpp b/src/libjin/Thread/thread.cpp deleted file mode 100644 index 3f2a50d..0000000 --- a/src/libjin/Thread/thread.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_THREAD - -#include "Thread.h" - -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&) {} - - }; - - ////////////////////////////////////////////////////////////////////// - - 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(); - }; - - 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(); - } - - } // namespace thread -} // namespace 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 deleted file mode 100644 index ea50444..0000000 --- a/src/libjin/Thread/thread.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef __LIBJIN_THREAD_H -#define __LIBJIN_THREAD_H -#include "../configuration.h" -#if LIBJIN_MODULES_THREAD - -#include -#include -#if LIBJIN_THREAD_SDL -# include "SDL2/SDL_thread.h" -#elif LIBJIN_THREAD_CPP -# include -# include -# include -#endif - -namespace jin -{ - 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) {}; - }; - - 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); - - Conditional* condition; - Mutex* mutex; - - private: - std::map share; // threads shared value - - }; - - 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(); - - 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 - - }; - - } // namespace thread -} // namespace jin - -#endif // LIBJIN_MODULES_THREAD -#endif // __LIBJIN_THREAD_H \ No newline at end of file diff --git a/src/libjin/Time/Timer.cpp b/src/libjin/Time/Timer.cpp deleted file mode 100644 index 6f3bc80..0000000 --- a/src/libjin/Time/Timer.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_TIME - -#include "Timer.h" - -namespace jin -{ - namespace time - { - - - Timers::Timers() - : timers() - { - } - - Timers::~Timers() - { - for (int i = 0; i < timers.size(); ++i) - delete timers[i]; - } - - void Timers::update(int ms) - { - std::vector::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::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); - } - - 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() - { - } - - 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; - } - - } // namespace time -} // namespace jin - -#endif // LIBJIN_MODULES_TIME diff --git a/src/libjin/Time/Timer.h b/src/libjin/Time/Timer.h deleted file mode 100644 index ff67590..0000000 --- a/src/libjin/Time/Timer.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __LIBJIN_TIMER_H -#define __LIBJIN_TIMER_H -#include "../configuration.h" -#if LIBJIN_MODULES_TIME - -#include "SDL2/SDL.h" -#include - -namespace jin -{ - namespace time - { - - 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); - - 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 timers; - - }; - - 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 getMilliSecond() - { - #if LIBJIN_TIME_SDL - return SDL_GetTicks(); - #endif - } - - } // namespace time -} // namespace jin - -#endif // LIBJIN_MODULES_TIME -#endif // __LIBJIN_TIMER_H diff --git a/src/libjin/Time/je_timer.cpp b/src/libjin/Time/je_timer.cpp new file mode 100644 index 0000000..ac66de1 --- /dev/null +++ b/src/libjin/Time/je_timer.cpp @@ -0,0 +1,100 @@ +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_TIME + +#include "je_timer.h" + +namespace jin +{ + namespace time + { + + + Timers::Timers() + : timers() + { + } + + Timers::~Timers() + { + for (int i = 0; i < timers.size(); ++i) + delete timers[i]; + } + + void Timers::update(int ms) + { + std::vector::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::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); + } + + 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() + { + } + + 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; + } + + } // namespace time +} // namespace jin + +#endif // LIBJIN_MODULES_TIME diff --git a/src/libjin/Time/je_timer.h b/src/libjin/Time/je_timer.h new file mode 100644 index 0000000..c31de42 --- /dev/null +++ b/src/libjin/Time/je_timer.h @@ -0,0 +1,77 @@ +#ifndef __LIBJIN_TIMER_H +#define __LIBJIN_TIMER_H +#include "../core/je_configuration.h" +#if LIBJIN_MODULES_TIME + +#include +#include "SDL2/SDL.h" + +namespace jin +{ + namespace time + { + + 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); + + 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 timers; + + }; + + 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 getMilliSecond() + { + #if LIBJIN_TIME_SDL + return SDL_GetTicks(); + #endif + } + + } // namespace time +} // namespace jin + +#endif // LIBJIN_MODULES_TIME +#endif // __LIBJIN_TIMER_H diff --git a/src/libjin/Utils/Log.cpp b/src/libjin/Utils/Log.cpp deleted file mode 100644 index 5299942..0000000 --- a/src/libjin/Utils/Log.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#define LOGHELPER_IMPLEMENT -#include "log.h" \ No newline at end of file diff --git a/src/libjin/Utils/Log.h b/src/libjin/Utils/Log.h deleted file mode 100644 index e4ed879..0000000 --- a/src/libjin/Utils/Log.h +++ /dev/null @@ -1,134 +0,0 @@ -/** -* Single.h/loghelper.h -* Copyright (C) 2017~2018 chai -*/ -#ifndef __LOG_HELPER_H -#define __LOG_HELPER_H -#include -#include -#include -#include - -class Loghelper -{ -public: - // logÊä³öÄ¿±ê - enum Direction - { - DIR_CERR = 1 << 1, // ±ê×¼´íÎóÁ÷ - DIR_FILE = 1 << 2, // logÎļþ - }; - - // ´íÎóµÈ¼¶ - enum Level - { - LV_NONE = 0, // none - LV_ERROR = 1 << 1, // error - LV_WARN = 1 << 2, // warn - LV_INFO = 1 << 3, // info - LV_DEBUG = 1 << 4, // debug - LV_ALL = 0xffffffff - }; - - static void log(Level _level, const char* _fmt, ...); - - // ÖØ¶¨Ïò - static void redirect(unsigned int _dir, char* _path = nullptr); - - // ɸѡ´íÎóµÈ¼¶ - static void restrict(unsigned int levels); - - static void close(); - -private: - static unsigned int dir; // Êä³öÄ¿±ê - static unsigned int levels; // ´íÎóµÈ¼¶ - static std::ofstream fs; // Êä³öÎļþÁ÷ -}; - -typedef Loghelper::Level Loglevel; - -#ifdef LOGHELPER_IMPLEMENT - -#define hasbit(flag, bit) ((flag & bit) == bit) - -unsigned int Loghelper::dir = Loghelper::Direction::DIR_CERR; -unsigned int Loghelper::levels = Loghelper::Level::LV_ALL; -std::ofstream Loghelper::fs; - -void Loghelper::log(Level _level, const char* _fmt, ...) -{ - if (!hasbit(levels, _level)) - return; -#define FORMAT_MSG_BUFFER_SIZE (204800) - const char* levelStr = nullptr; - switch (_level) - { - case LV_ERROR: - levelStr = "[Jin Error]:"; - break; - case LV_WARN: - levelStr = "[Jin Warn]:"; - break; - case LV_INFO: - levelStr = "[Jin Info]:"; - break; - case LV_DEBUG: - levelStr = "[Jin Debug]:"; - break; - default: - levelStr = "[Jin Unknown]:"; - break; - } - char buffer[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 }; - strcpy(buffer, levelStr); - va_list args; - va_start(args, _fmt); - vsnprintf(buffer + strlen(buffer), FORMAT_MSG_BUFFER_SIZE, _fmt, args); - va_end(args); - if (hasbit(dir, DIR_CERR)) - { - std::cerr << buffer << std::endl; - } - if (hasbit(dir, DIR_FILE)) - { - fs << buffer << std::endl; - } -#undef FORMAT_MSG_BUFFER_SIZE -} - -// ÖØ¶¨Ïò -void Loghelper::redirect(unsigned int _dir, char* _path) -{ - dir = _dir; - if (hasbit(dir, DIR_FILE)) - { - try - { - fs.open(_path, std::ios_base::app); - } - catch (std::ios_base::failure& e) { - dir = DIR_CERR; - log(Level::LV_WARN, "ÖØ¶¨Ïòlog·¾¶ %s ʧ°Ü", _path); - } - } -} - -// ɸѡ´íÎóµÈ¼¶ -void Loghelper::restrict(unsigned int _levels) -{ - levels = _levels; -} - -void Loghelper::close() -{ - if (!fs.fail()) - fs.close(); - fs.clear(); -} - -#undef hasbit - -#endif - -#endif diff --git a/src/libjin/Utils/endian.h b/src/libjin/Utils/endian.h deleted file mode 100644 index 01def88..0000000 --- a/src/libjin/Utils/endian.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef LIBJIN_LIL_ENDIAN && LIBJIN_BIG_ENDIAN - -#define LIBJIN_LIL_ENDIAN 2 -#define LIBJIN_BIG_ENDIAN 4 - -#endif - -#ifndef LIBJIN_BYTEORDER -#ifdef __linux__ -#include -#define LIBJIN_BYTEORDER __BYTE_ORDER -#else /* __linux__ */ -#if defined(__hppa__) || \ - defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ - (defined(__MIPS__) && defined(__MISPEB__)) || \ - defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ - defined(__sparc__) -#define LIBJIN_BYTEORDER LIBJIN_BIG_ENDIAN -#else -#define LIBJIN_BYTEORDER LIBJIN_LIL_ENDIAN -#endif -#endif /* __linux__ */ -#endif /* !SDL_BYTEORDER */ \ No newline at end of file diff --git a/src/libjin/Utils/je_endian.h b/src/libjin/Utils/je_endian.h new file mode 100644 index 0000000..01def88 --- /dev/null +++ b/src/libjin/Utils/je_endian.h @@ -0,0 +1,23 @@ +#ifndef LIBJIN_LIL_ENDIAN && LIBJIN_BIG_ENDIAN + +#define LIBJIN_LIL_ENDIAN 2 +#define LIBJIN_BIG_ENDIAN 4 + +#endif + +#ifndef LIBJIN_BYTEORDER +#ifdef __linux__ +#include +#define LIBJIN_BYTEORDER __BYTE_ORDER +#else /* __linux__ */ +#if defined(__hppa__) || \ + defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ + (defined(__MIPS__) && defined(__MISPEB__)) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ + defined(__sparc__) +#define LIBJIN_BYTEORDER LIBJIN_BIG_ENDIAN +#else +#define LIBJIN_BYTEORDER LIBJIN_LIL_ENDIAN +#endif +#endif /* __linux__ */ +#endif /* !SDL_BYTEORDER */ \ No newline at end of file diff --git a/src/libjin/Utils/je_log.cpp b/src/libjin/Utils/je_log.cpp new file mode 100644 index 0000000..2bcb25a --- /dev/null +++ b/src/libjin/Utils/je_log.cpp @@ -0,0 +1,2 @@ +#define LOGHELPER_IMPLEMENT +#include "je_log.h" \ No newline at end of file diff --git a/src/libjin/Utils/je_log.h b/src/libjin/Utils/je_log.h new file mode 100644 index 0000000..9b3fe2c --- /dev/null +++ b/src/libjin/Utils/je_log.h @@ -0,0 +1,135 @@ +/** +* Single.h/loghelper.h +* Copyright (C) 2017~2018 chai +*/ +#ifndef __LOG_HELPER_H +#define __LOG_HELPER_H + +#include +#include +#include +#include + +class Loghelper +{ +public: + // logÊä³öÄ¿±ê + enum Direction + { + DIR_CERR = 1 << 1, // ±ê×¼´íÎóÁ÷ + DIR_FILE = 1 << 2, // logÎļþ + }; + + // ´íÎóµÈ¼¶ + enum Level + { + LV_NONE = 0, // none + LV_ERROR = 1 << 1, // error + LV_WARN = 1 << 2, // warn + LV_INFO = 1 << 3, // info + LV_DEBUG = 1 << 4, // debug + LV_ALL = 0xffffffff + }; + + static void log(Level _level, const char* _fmt, ...); + + // ÖØ¶¨Ïò + static void redirect(unsigned int _dir, char* _path = nullptr); + + // ɸѡ´íÎóµÈ¼¶ + static void restrict(unsigned int levels); + + static void close(); + +private: + static unsigned int dir; // Êä³öÄ¿±ê + static unsigned int levels; // ´íÎóµÈ¼¶ + static std::ofstream fs; // Êä³öÎļþÁ÷ +}; + +typedef Loghelper::Level Loglevel; + +#ifdef LOGHELPER_IMPLEMENT + +#define hasbit(flag, bit) ((flag & bit) == bit) + +unsigned int Loghelper::dir = Loghelper::Direction::DIR_CERR; +unsigned int Loghelper::levels = Loghelper::Level::LV_ALL; +std::ofstream Loghelper::fs; + +void Loghelper::log(Level _level, const char* _fmt, ...) +{ + if (!hasbit(levels, _level)) + return; +#define FORMAT_MSG_BUFFER_SIZE (204800) + const char* levelStr = nullptr; + switch (_level) + { + case LV_ERROR: + levelStr = "[Jin Error]:"; + break; + case LV_WARN: + levelStr = "[Jin Warn]:"; + break; + case LV_INFO: + levelStr = "[Jin Info]:"; + break; + case LV_DEBUG: + levelStr = "[Jin Debug]:"; + break; + default: + levelStr = "[Jin Unknown]:"; + break; + } + char buffer[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 }; + strcpy(buffer, levelStr); + va_list args; + va_start(args, _fmt); + vsnprintf(buffer + strlen(buffer), FORMAT_MSG_BUFFER_SIZE, _fmt, args); + va_end(args); + if (hasbit(dir, DIR_CERR)) + { + std::cerr << buffer << std::endl; + } + if (hasbit(dir, DIR_FILE)) + { + fs << buffer << std::endl; + } +#undef FORMAT_MSG_BUFFER_SIZE +} + +// ÖØ¶¨Ïò +void Loghelper::redirect(unsigned int _dir, char* _path) +{ + dir = _dir; + if (hasbit(dir, DIR_FILE)) + { + try + { + fs.open(_path, std::ios_base::app); + } + catch (std::ios_base::failure& e) { + dir = DIR_CERR; + log(Level::LV_WARN, "ÖØ¶¨Ïòlog·¾¶ %s ʧ°Ü", _path); + } + } +} + +// ɸѡ´íÎóµÈ¼¶ +void Loghelper::restrict(unsigned int _levels) +{ + levels = _levels; +} + +void Loghelper::close() +{ + if (!fs.fail()) + fs.close(); + fs.clear(); +} + +#undef hasbit + +#endif + +#endif diff --git a/src/libjin/Utils/je_macros.h b/src/libjin/Utils/je_macros.h new file mode 100644 index 0000000..e19193c --- /dev/null +++ b/src/libjin/Utils/je_macros.h @@ -0,0 +1,17 @@ +#ifndef __LIBJIN_MACROS_H +#define __LIBJIN_MACROS_H +#include + +//#define implement // ʵÏÖ½Ó¿Ú +// +//#define shared // ÉùÃ÷ÀàµÄ·½·¨ +// +//#define MASK // ÉùÃ÷ÑÚÂë enum +// +//#define onlyonce // ÉùÃ÷Ö»»áµ÷ÓÃÒ»´Î +//#define CALLONCE(call) static char __dummy__=(call, 1) // Ö»»áµ÷ÓÃÒ»´Î +//#define SAFECALL(func, params) if(func) func(params) +// +//#define zero(mem) memset(&mem, 0, sizeof(mem)) + +#endif \ No newline at end of file diff --git a/src/libjin/Utils/je_unittest.cpp b/src/libjin/Utils/je_unittest.cpp new file mode 100644 index 0000000..65dbaad --- /dev/null +++ b/src/libjin/Utils/je_unittest.cpp @@ -0,0 +1,108 @@ +#include "je_utils.h" +#if UNITTEST + +#include +#include +#include +#include "../audio/sdl/source.h" +#include "../audio/sdl/audio.h" + +using namespace jin::audio; +using namespace std; + +int main(int argc, char* argv[]) +{ + SDLAudio* audio = SDLAudio::get(); + audio->init(0); + SDLSource* source = SDLSource::createSource("a.ogg"); + SDLSource* source2 = SDLSource::createSource("a.wav"); + //source->play(); + source2->play(); + source->setLoop(true); + source2->setLoop(true); + int i = 0; + while (true) + { + SDL_Delay(1000); + } + audio->quit(); + return 0; +} + +/* +#include +#include +#include +#include "SDL2/SDL.h" + +#include <3rdparty/cmixer/cmixer.h> + +static SDL_mutex* audio_mutex; + +static void lock_handler(cm_Event *e) { + if (e->type == CM_EVENT_LOCK) { + SDL_LockMutex(audio_mutex); + } + if (e->type == CM_EVENT_UNLOCK) { + SDL_UnlockMutex(audio_mutex); + } +} + + +static void audio_callback(void *udata, Uint8 *stream, int size) { + cm_process((cm_Int16*)stream, size / 2); +} + + +int main(int argc, char **argv) { + SDL_AudioDeviceID dev; + SDL_AudioSpec fmt, got; + cm_Source *src; + cm_Source* src2; + + + SDL_Init(SDL_INIT_AUDIO); + audio_mutex = SDL_CreateMutex(); + + memset(&fmt, 0, sizeof(fmt)); + fmt.freq = 44100; + fmt.format = AUDIO_S16; + fmt.channels = 2; + fmt.samples = 1024; + fmt.callback = audio_callback; + + dev = SDL_OpenAudioDevice(NULL, 0, &fmt, &got, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); + if (dev == 0) { + fprintf(stderr, "Error: failed to open audio device '%s'\n", SDL_GetError()); + exit(EXIT_FAILURE); + } + + cm_init(got.freq); + cm_set_lock(lock_handler); + cm_set_master_gain(0.5); + + SDL_PauseAudioDevice(dev, 0); + + src = cm_new_source_from_file("a.ogg"); + src2 = cm_new_source_from_file("loop.wav"); + if (!src) { + fprintf(stderr, "Error: failed to create source '%s'\n", cm_get_error()); + exit(EXIT_FAILURE); + } + cm_set_loop(src2, 1); + + cm_play(src); + cm_play(src2); + + printf("Press [return] to exit\n"); + getchar(); + + cm_destroy_source(src); + SDL_CloseAudioDevice(dev); + SDL_Quit(); + + return EXIT_SUCCESS; +} +*/ + +#endif \ No newline at end of file diff --git a/src/libjin/Utils/je_utils.h b/src/libjin/Utils/je_utils.h new file mode 100644 index 0000000..583f892 --- /dev/null +++ b/src/libjin/Utils/je_utils.h @@ -0,0 +1,9 @@ +#ifndef __LIBJIN_UTILS_H +#define __LIBJIN_UTILS_H + +#include "je_macros.h" +#include "je_endian.h" + +#define UNITTEST 0 + +#endif \ No newline at end of file diff --git a/src/libjin/Utils/log.h b/src/libjin/Utils/log.h deleted file mode 100644 index e4ed879..0000000 --- a/src/libjin/Utils/log.h +++ /dev/null @@ -1,134 +0,0 @@ -/** -* Single.h/loghelper.h -* Copyright (C) 2017~2018 chai -*/ -#ifndef __LOG_HELPER_H -#define __LOG_HELPER_H -#include -#include -#include -#include - -class Loghelper -{ -public: - // logÊä³öÄ¿±ê - enum Direction - { - DIR_CERR = 1 << 1, // ±ê×¼´íÎóÁ÷ - DIR_FILE = 1 << 2, // logÎļþ - }; - - // ´íÎóµÈ¼¶ - enum Level - { - LV_NONE = 0, // none - LV_ERROR = 1 << 1, // error - LV_WARN = 1 << 2, // warn - LV_INFO = 1 << 3, // info - LV_DEBUG = 1 << 4, // debug - LV_ALL = 0xffffffff - }; - - static void log(Level _level, const char* _fmt, ...); - - // ÖØ¶¨Ïò - static void redirect(unsigned int _dir, char* _path = nullptr); - - // ɸѡ´íÎóµÈ¼¶ - static void restrict(unsigned int levels); - - static void close(); - -private: - static unsigned int dir; // Êä³öÄ¿±ê - static unsigned int levels; // ´íÎóµÈ¼¶ - static std::ofstream fs; // Êä³öÎļþÁ÷ -}; - -typedef Loghelper::Level Loglevel; - -#ifdef LOGHELPER_IMPLEMENT - -#define hasbit(flag, bit) ((flag & bit) == bit) - -unsigned int Loghelper::dir = Loghelper::Direction::DIR_CERR; -unsigned int Loghelper::levels = Loghelper::Level::LV_ALL; -std::ofstream Loghelper::fs; - -void Loghelper::log(Level _level, const char* _fmt, ...) -{ - if (!hasbit(levels, _level)) - return; -#define FORMAT_MSG_BUFFER_SIZE (204800) - const char* levelStr = nullptr; - switch (_level) - { - case LV_ERROR: - levelStr = "[Jin Error]:"; - break; - case LV_WARN: - levelStr = "[Jin Warn]:"; - break; - case LV_INFO: - levelStr = "[Jin Info]:"; - break; - case LV_DEBUG: - levelStr = "[Jin Debug]:"; - break; - default: - levelStr = "[Jin Unknown]:"; - break; - } - char buffer[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 }; - strcpy(buffer, levelStr); - va_list args; - va_start(args, _fmt); - vsnprintf(buffer + strlen(buffer), FORMAT_MSG_BUFFER_SIZE, _fmt, args); - va_end(args); - if (hasbit(dir, DIR_CERR)) - { - std::cerr << buffer << std::endl; - } - if (hasbit(dir, DIR_FILE)) - { - fs << buffer << std::endl; - } -#undef FORMAT_MSG_BUFFER_SIZE -} - -// ÖØ¶¨Ïò -void Loghelper::redirect(unsigned int _dir, char* _path) -{ - dir = _dir; - if (hasbit(dir, DIR_FILE)) - { - try - { - fs.open(_path, std::ios_base::app); - } - catch (std::ios_base::failure& e) { - dir = DIR_CERR; - log(Level::LV_WARN, "ÖØ¶¨Ïòlog·¾¶ %s ʧ°Ü", _path); - } - } -} - -// ɸѡ´íÎóµÈ¼¶ -void Loghelper::restrict(unsigned int _levels) -{ - levels = _levels; -} - -void Loghelper::close() -{ - if (!fs.fail()) - fs.close(); - fs.clear(); -} - -#undef hasbit - -#endif - -#endif diff --git a/src/libjin/Utils/macros.h b/src/libjin/Utils/macros.h deleted file mode 100644 index e19193c..0000000 --- a/src/libjin/Utils/macros.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __LIBJIN_MACROS_H -#define __LIBJIN_MACROS_H -#include - -//#define implement // ʵÏÖ½Ó¿Ú -// -//#define shared // ÉùÃ÷ÀàµÄ·½·¨ -// -//#define MASK // ÉùÃ÷ÑÚÂë enum -// -//#define onlyonce // ÉùÃ÷Ö»»áµ÷ÓÃÒ»´Î -//#define CALLONCE(call) static char __dummy__=(call, 1) // Ö»»áµ÷ÓÃÒ»´Î -//#define SAFECALL(func, params) if(func) func(params) -// -//#define zero(mem) memset(&mem, 0, sizeof(mem)) - -#endif \ No newline at end of file diff --git a/src/libjin/Utils/unittest.cpp b/src/libjin/Utils/unittest.cpp deleted file mode 100644 index 44f1ae5..0000000 --- a/src/libjin/Utils/unittest.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "utils.h" -#if UNITTEST - -#include -#include -#include -#include "../audio/sdl/source.h" -#include "../audio/sdl/audio.h" - -using namespace jin::audio; -using namespace std; - -int main(int argc, char* argv[]) -{ - SDLAudio* audio = SDLAudio::get(); - audio->init(0); - SDLSource* source = SDLSource::createSource("a.ogg"); - SDLSource* source2 = SDLSource::createSource("a.wav"); - //source->play(); - source2->play(); - source->setLoop(true); - source2->setLoop(true); - int i = 0; - while (true) - { - SDL_Delay(1000); - } - audio->quit(); - return 0; -} - -/* -#include -#include -#include -#include "SDL2/SDL.h" - -#include <3rdparty/cmixer/cmixer.h> - -static SDL_mutex* audio_mutex; - -static void lock_handler(cm_Event *e) { - if (e->type == CM_EVENT_LOCK) { - SDL_LockMutex(audio_mutex); - } - if (e->type == CM_EVENT_UNLOCK) { - SDL_UnlockMutex(audio_mutex); - } -} - - -static void audio_callback(void *udata, Uint8 *stream, int size) { - cm_process((cm_Int16*)stream, size / 2); -} - - -int main(int argc, char **argv) { - SDL_AudioDeviceID dev; - SDL_AudioSpec fmt, got; - cm_Source *src; - cm_Source* src2; - - - SDL_Init(SDL_INIT_AUDIO); - audio_mutex = SDL_CreateMutex(); - - memset(&fmt, 0, sizeof(fmt)); - fmt.freq = 44100; - fmt.format = AUDIO_S16; - fmt.channels = 2; - fmt.samples = 1024; - fmt.callback = audio_callback; - - dev = SDL_OpenAudioDevice(NULL, 0, &fmt, &got, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); - if (dev == 0) { - fprintf(stderr, "Error: failed to open audio device '%s'\n", SDL_GetError()); - exit(EXIT_FAILURE); - } - - cm_init(got.freq); - cm_set_lock(lock_handler); - cm_set_master_gain(0.5); - - SDL_PauseAudioDevice(dev, 0); - - src = cm_new_source_from_file("a.ogg"); - src2 = cm_new_source_from_file("loop.wav"); - if (!src) { - fprintf(stderr, "Error: failed to create source '%s'\n", cm_get_error()); - exit(EXIT_FAILURE); - } - cm_set_loop(src2, 1); - - cm_play(src); - cm_play(src2); - - printf("Press [return] to exit\n"); - getchar(); - - cm_destroy_source(src); - SDL_CloseAudioDevice(dev); - SDL_Quit(); - - return EXIT_SUCCESS; -} -*/ - -#endif \ No newline at end of file diff --git a/src/libjin/Utils/utils.h b/src/libjin/Utils/utils.h deleted file mode 100644 index 1654a8f..0000000 --- a/src/libjin/Utils/utils.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __LIBJIN_UTILS_H -#define __LIBJIN_UTILS_H - -#include "macros.h" -#include "endian.h" - -#define UNITTEST 0 - -#endif \ No newline at end of file diff --git a/src/libjin/audio/audio.cpp b/src/libjin/audio/audio.cpp deleted file mode 100644 index 928f01a..0000000 --- a/src/libjin/audio/audio.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_AUDIO - -#include "SDL2/SDL.h" -#include "audio.h" - -namespace jin -{ - namespace audio - { - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO diff --git a/src/libjin/audio/audio.h b/src/libjin/audio/audio.h deleted file mode 100644 index fd391aa..0000000 --- a/src/libjin/audio/audio.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __LIBJIN_AUDIO_H -#define __LIBJIN_AUDIO_H -#include "../configuration.h" -#if LIBJIN_MODULES_AUDIO - -#include "SDL2/SDL.h" - -#include "../utils/macros.h" -#include "../common/Subsystem.hpp" - -namespace jin -{ - namespace audio - { - - class Source; - - template - class Audio : public Subsystem - { - 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; - - }; - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO -#endif // __LIBJIN_AUDIO_H diff --git a/src/libjin/audio/source.cpp b/src/libjin/audio/source.cpp deleted file mode 100644 index 646e5ef..0000000 --- a/src/libjin/audio/source.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_AUDIO - -#include -#include "source.h" - -namespace jin -{ - 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); - } - - 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; - } - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO diff --git a/src/libjin/audio/source.h b/src/libjin/audio/source.h deleted file mode 100644 index 6dfc86c..0000000 --- a/src/libjin/audio/source.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __LIBJIN_AUDIO_SOURCE_H -#define __LIBJIN_AUDIO_SOURCE_H -#include "../configuration.h" -#if LIBJIN_MODULES_AUDIO - -#include "SDL2/SDL.h" - -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); - - }; - - } // namespace audio -} // namespace jin - -#endif // LIBJIN_MODULES_AUDIO -#endif // __LIBJIN_AUDIO_SOURCE_H diff --git a/src/libjin/configuration.h b/src/libjin/configuration.h deleted file mode 100644 index 55633a1..0000000 --- a/src/libjin/configuration.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __LIBJIN_COMMON_MODULES_H -#define __LIBJIN_COMMON_MODULES_H -/* -* ¿ØÖÆÄ£¿éºÍ×ÓÄ£¿éµÄ±àÒ룬²»ÐèҪģ¿é¹Ø±Õ²»±àÒë -*/ - -#define LIBJIN_MODULES_AUDIO 1 -#define LIBJIN_AUDIO_SDLAUDIO 1 -#define LIBJIN_AUDIO_OPENAL 1 - -#define LIBJIN_MODULES_RENDER 1 - -#define LIBJIN_MODULES_DEBUG 1 - -#define LIBJIN_MODULES_FILESYSTEM 1 - -#define LIBJIN_MODULES_INPUT 1 -#define LIBJIN_INPUT_SDL 1 - -#define LIBJIN_MODULES_MATH 1 - -#define LIBJIN_MODULES_NET 1 -#define LIBJIN_NET_TEKCOS 1 - -#define LIBJIN_MODULES_PHYSICS 0 -#define LIBJIN_PHYSICS_BOX2D 1 -#define LIBJIN_PHYSICS_NEWTON 1 - -#define LIBJIN_MODULES_TILEMAP 1 - -#define LIBJIN_MODULES_UI 1 - -#define LIBJIN_MODULES_TOOLS 0 -#define LIBJIN_TOOLS_COMPONENT 1 -#define LIBJIN_TOOLS_EVENTMSGCENTER 1 -#define LIBJIN_TOOLS_XML 1 -#define LIBJIN_TOOLS_CSV 1 -#define LIBJIN_TOOLS_JSON 1 - -#define LIBJIN_MODULES_THREAD 1 -#define LIBJIN_THREAD_SDL 1 -#define LIBJIN_THREAD_CPP 0 -#define LIBJIN_THREAD_PTHREAD 0 - -#define LIBJIN_MODULES_TIME 1 -#define LIBJIN_TIME_SDL 1 - -/* -* Open libjin debug -*/ - -#define LIBJIN_DEBUG 0 - -/* -* Operating system -*/ - -#define LIBJIN_WINDOWS 1 -#define LIBJIN_MACOS 2 -#define LIBJIN_LINUX 3 - -#define LIBJIN_OS LIBJIN_WINDOWS - -/// Ä£¿é±àÒë¿ØÖÆ -#define jin_graphics -#define jin_graphics_font -#define jin_graphics_shader - -#endif \ No newline at end of file diff --git a/src/libjin/core/je_configuration.h b/src/libjin/core/je_configuration.h new file mode 100644 index 0000000..55633a1 --- /dev/null +++ b/src/libjin/core/je_configuration.h @@ -0,0 +1,69 @@ +#ifndef __LIBJIN_COMMON_MODULES_H +#define __LIBJIN_COMMON_MODULES_H +/* +* ¿ØÖÆÄ£¿éºÍ×ÓÄ£¿éµÄ±àÒ룬²»ÐèҪģ¿é¹Ø±Õ²»±àÒë +*/ + +#define LIBJIN_MODULES_AUDIO 1 +#define LIBJIN_AUDIO_SDLAUDIO 1 +#define LIBJIN_AUDIO_OPENAL 1 + +#define LIBJIN_MODULES_RENDER 1 + +#define LIBJIN_MODULES_DEBUG 1 + +#define LIBJIN_MODULES_FILESYSTEM 1 + +#define LIBJIN_MODULES_INPUT 1 +#define LIBJIN_INPUT_SDL 1 + +#define LIBJIN_MODULES_MATH 1 + +#define LIBJIN_MODULES_NET 1 +#define LIBJIN_NET_TEKCOS 1 + +#define LIBJIN_MODULES_PHYSICS 0 +#define LIBJIN_PHYSICS_BOX2D 1 +#define LIBJIN_PHYSICS_NEWTON 1 + +#define LIBJIN_MODULES_TILEMAP 1 + +#define LIBJIN_MODULES_UI 1 + +#define LIBJIN_MODULES_TOOLS 0 +#define LIBJIN_TOOLS_COMPONENT 1 +#define LIBJIN_TOOLS_EVENTMSGCENTER 1 +#define LIBJIN_TOOLS_XML 1 +#define LIBJIN_TOOLS_CSV 1 +#define LIBJIN_TOOLS_JSON 1 + +#define LIBJIN_MODULES_THREAD 1 +#define LIBJIN_THREAD_SDL 1 +#define LIBJIN_THREAD_CPP 0 +#define LIBJIN_THREAD_PTHREAD 0 + +#define LIBJIN_MODULES_TIME 1 +#define LIBJIN_TIME_SDL 1 + +/* +* Open libjin debug +*/ + +#define LIBJIN_DEBUG 0 + +/* +* Operating system +*/ + +#define LIBJIN_WINDOWS 1 +#define LIBJIN_MACOS 2 +#define LIBJIN_LINUX 3 + +#define LIBJIN_OS LIBJIN_WINDOWS + +/// Ä£¿é±àÒë¿ØÖÆ +#define jin_graphics +#define jin_graphics_font +#define jin_graphics_shader + +#endif \ No newline at end of file diff --git a/src/libjin/core/je_types.h b/src/libjin/core/je_types.h new file mode 100644 index 0000000..71ba640 --- /dev/null +++ b/src/libjin/core/je_types.h @@ -0,0 +1,24 @@ +#ifndef __LIBJIN_CORE_TYPES_H +#define __LIBJIN_CORE_TYPES_H + +#include + +namespace jin +{ + namespace core + { + + typedef int8_t int8; ///< Signed integer with a size of 8 bits. Supports values from -128 to 127 + typedef uint8_t uint8; ///< Unsigned integer with a size of 8 bits. Supports values from 0 to 255. + typedef uint8 byte; ///< Unsigned integer with 8 bits (1 byte). Supports 256 values from 0 to 255. + typedef int16_t int16; ///< Signed integer with a size of 16 bits. Supports values from -32768 to 32767 + typedef uint16_t uint16; ///< Unsigned integer with a size of 16 bits. Supports values from 0 to 65535. + typedef int32_t int32; ///< Signed integer with a size of 32 bits. Supports values from -2147483648 to 2147483647. + typedef uint32_t uint32; ///< Unsigned integer with a size of 32 bits. Supports values from 0 to 4294967295, (2^32 - 1). + typedef int64_t int64; ///< Signed integer with a size of 64 bits. Supports values from -(2^63) to (2^63 - 1). + typedef uint64_t uint64; ///< Unsigned integer with a size of 64 bits, Supports values from 0 to (2^64 - 1). + + } +} + +#endif // __LIBJIN_CORE_TYPES_H \ No newline at end of file diff --git a/src/libjin/input/event.cpp b/src/libjin/input/event.cpp deleted file mode 100644 index c8eb78c..0000000 --- a/src/libjin/input/event.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "event.h" -#include "SDL2\SDL.h" - -namespace jin -{ - -} // namespace jin \ No newline at end of file diff --git a/src/libjin/input/event.h b/src/libjin/input/event.h deleted file mode 100644 index 3f2bc8e..0000000 --- a/src/libjin/input/event.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef __LIBJIN_EVENT_H -#define __LIBJIN_EVENT_H -#include "../configuration.h" -#if LIBJIN_MODULES_INPUT - -namespace jin -{ - namespace input - { - #if LIBJIN_INPUT_SDL - #include "SDL.h" - - typedef SDL_Event Event; - typedef SDL_Keycode Key; - typedef SDL_MouseWheelEvent Wheel; - - enum EventType { - QUIT = SDL_QUIT, - /* keyboard events */ - KEY_DOWN = SDL_KEYDOWN, - KEY_UP = SDL_KEYUP, - /* mouse events */ - MOUSE_MOTION = SDL_MOUSEMOTION, - MOUSE_BUTTON_DOWN = SDL_MOUSEBUTTONDOWN, - MOUSE_BUTTON_UP = SDL_MOUSEBUTTONUP, - MOUSE_WHEEL = SDL_MOUSEWHEEL, - /* joypad events */ - JOYBUTTONDOWN = SDL_JOYBUTTONDOWN, - JOYBUTTONUP = SDL_JOYBUTTONUP, - JOYAXISMOTION = SDL_JOYAXISMOTION, - JOYBALLMOTION = SDL_JOYBALLMOTION, - JOYHATMOTION = SDL_JOYHATMOTION, - JOYDEVICEADDED = SDL_JOYDEVICEADDED, - JOYDEVICEREMOVED = SDL_JOYDEVICEREMOVED, - CONTROLLERBUTTONDOWN = SDL_CONTROLLERBUTTONDOWN, - CONTROLLERBUTTONUP = SDL_CONTROLLERBUTTONUP, - CONTROLLERAXISMOTION = SDL_CONTROLLERAXISMOTION, - /* window evnets */ - WINDOW_EVENT = SDL_WINDOWEVENT, - }; - - enum WindowEvent { - WINDOW_SHOWN = SDL_WINDOWEVENT_SHOWN , - WINDOW_HIDDEN = SDL_WINDOWEVENT_HIDDEN , - WINDOW_EXPOSED = SDL_WINDOWEVENT_EXPOSED , - WINDOW_MOVED = SDL_WINDOWEVENT_MOVED , - WINDOW_RESIZED = SDL_WINDOWEVENT_RESIZED , - WINDOW_SIZE_CAHNGE = SDL_WINDOWEVENT_SIZE_CHANGED , - WINDOW_MINIMIZED = SDL_WINDOWEVENT_MINIMIZED , - WINDOW_MAXIMIZED = SDL_WINDOWEVENT_MAXIMIZED , - WINDOW_RESTORED = SDL_WINDOWEVENT_RESTORED , - WINDOW_ENTER = SDL_WINDOWEVENT_ENTER , - WINDOW_LEAVE = SDL_WINDOWEVENT_LEAVE , - WINDOW_FOCUS_GAINED = SDL_WINDOWEVENT_FOCUS_GAINED, - WINDOW_FOCUS_LOST = SDL_WINDOWEVENT_FOCUS_LOST , - WINDOW_CLOSE = SDL_WINDOWEVENT_CLOSE , - WINDOW_TAKE_FOCUS = SDL_WINDOWEVENT_TAKE_FOCUS , - WINDOW_HIT_TEST = SDL_WINDOWEVENT_HIT_TEST , - }; - - inline int pollEvent(Event* e) - { - return SDL_PollEvent(e); - } - - inline const char* getKeyName(Key key) - { - return SDL_GetKeyName(key); - } - - inline const char* getButtonName(int button) - { - switch (button) - { - case 1: return "Left"; - case 2: return "Middle"; - case 3: return "Right"; - case 4: return "WheelUp"; - case 5: return "WheelDown"; - default: return "?"; - } - } - - /* - inline const char* getWheelName(Wheel wheel) - { - if (wheel.x == -1) - return "left"; - else if (wheel.x == 1) - return "right"; - else if (wheel.y == -1) - return "near"; - else if (wheel.y == 1) - return "far"; - else - return "none"; - } - */ - - #endif // LIBJIN_INPUT_SDL - } // namespace input -} // namespace jin - -#endif // LIBJIN_MODULES_INPUT -#endif \ No newline at end of file diff --git a/src/libjin/input/input.h b/src/libjin/input/input.h deleted file mode 100644 index a828ac7..0000000 --- a/src/libjin/input/input.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __LIBJIN_INPUT_H -#define __LIBJIN_INPUT_H - -#include "event.h" -#include "keyboard.h" -#include "mouse.h" -#include "joypad.h" - -#endif \ No newline at end of file diff --git a/src/libjin/input/joypad.cpp b/src/libjin/input/joypad.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/libjin/input/joypad.h b/src/libjin/input/joypad.h deleted file mode 100644 index 570699e..0000000 --- a/src/libjin/input/joypad.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __LIBJIN_JOYPAD_H -#define __LIBJIN_JOYPAD_H - -#include - -namespace jin -{ - namespace input - { - - inline const char* getJoyButtonName(int button) - { - switch (button) - { - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A: return "A"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B : return "B"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X : return "X"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y: return "Y"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK: return "Back"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE: return "Guide"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START: return "Start"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK: return "LeftStick"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK: return "RightStick"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER: return "LeftShoulder"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: return "RightShoulder"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP: return "DpadUp"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN: return "DpadDown"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT: return "DpadLeft"; break; - case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return "DpadRight"; break; - default: return NULL; - } - } - - inline const char* getJoyAxisName(int axis) - { - switch (axis) - { - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX: return "LeftX"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY: return "LeftY"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX: return "RightX"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY: return "RightY"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT: return "TriggerLeft"; break; - case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT: return "TriggerRight"; break; - } - } - - } // namespace input -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/input/keyboard.cpp b/src/libjin/input/keyboard.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/libjin/input/keyboard.h b/src/libjin/input/keyboard.h deleted file mode 100644 index 60f1169..0000000 --- a/src/libjin/input/keyboard.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __LIBJIN_KEYBOARD_H -#define __LIBJIN_KEYBOARD_H - -namespace jin -{ - namespace input - { - - class Keyboard - { - - }; - - } // namespace input -} // namespace 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 deleted file mode 100644 index dcaa771..0000000 --- a/src/libjin/input/mouse.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "../configuration.h" -#ifdef LIBJIN_MODULES_INPUT - -#include "SDL.h" -#include "Mouse.h" - -namespace jin -{ - namespace input - { - - 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); - } - - } // namespace input -} // namespace 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 deleted file mode 100644 index 7e93792..0000000 --- a/src/libjin/input/mouse.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __LIBJIN_MOUSE_H -#define __LIBJIN_MOUSE_H -#include "../configuration.h" -#ifdef LIBJIN_MODULES_INPUT - -#include "../Common/Singleton.hpp" - -namespace jin -{ - namespace input - { - - class Mouse : public Singleton - { - public: - void getState(int* x, int* y); - void setVisible(bool visible); - - private: - singleton(Mouse); - - Mouse() {}; - ~Mouse() {}; - - }; - - } // namespace input -} // namespace jin - -#endif // LIBJIN_MODULES_INPUT -#endif // __LIBJIN_MOUSE_H \ No newline at end of file diff --git a/src/libjin/jin.h b/src/libjin/jin.h index ed00271..0b6a416 100644 --- a/src/libjin/jin.h +++ b/src/libjin/jin.h @@ -1,21 +1,21 @@ #ifndef __LIBJIN_H #define __LIBJIN_H -#include "configuration.h" +#include "core/je_configuration.h" -#include "Utils/utils.h" +#include "utils/je_utils.h" #ifdef LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO -#include "Audio/SDL/SDLAudio.h" +#include "audio/sdl/je_sdl_audio.h" #endif // LIBJIN_MODULES_AUDIO && LIBJIN_AUDIO_SDLAUDIO -#include "Game/Game.h" -#include "Filesystem/Filesystem.h" -#include "Filesystem/Buffer.h" -#include "Input/Input.h" -#include "Net/Net.h" -#include "Graphics/Graphics.h" -#include "Time/Timer.h" -#include "Thread/Thread.h" -#include "Common/common.h" +#include "game/je_game.h" +#include "filesystem/je_filesystem.h" +#include "filesystem/je_buffer.h" +#include "input/je_input.h" +#include "net/je_net.h" +#include "graphics/je_graphics.h" +#include "time/je_timer.h" +#include "thread/je_thread.h" +#include "common/je_common.h" #define LIBJIN_VERSION "Jin 0.1"; #define LIBJIN_AUTHOR "Chai"; diff --git a/src/libjin/math/constant.h b/src/libjin/math/constant.h deleted file mode 100644 index f8e0f5a..0000000 --- a/src/libjin/math/constant.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __LIBJIN_MATH_CONSTANT_H -#define __LIBJIN_MATH_CONSTANT_H - -#define PI 3.1415926f - -// int16 ·¶Î§ -#define INT16_RANGE_LEFT -32768 -#define INT16_RANGE_RIGHT 32767 - -#endif \ No newline at end of file diff --git a/src/libjin/math/math.h b/src/libjin/math/math.h deleted file mode 100644 index c1b5084..0000000 --- a/src/libjin/math/math.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __LIBJIN_UTILS_MATH_H -#define __LIBJIN_UTILS_MATH_H - -#include "constant.h" -#include "matrix.h" -#include "quad.h" - -namespace jin -{ - namespace math - { - - #ifdef min - # undef min - #endif // min - #ifdef max - # undef max - #endif // max - - template - inline T min(T a, T b) - { - return a < b ? a : b; - } - - template - inline T max(T a, T b) - { - return a > b ? a : b; - } - - template - inline T clamp(T a, T mi, T ma) - { - return min(max(a, mi), ma); - } - - template - inline bool within(T a, T mi, T ma) - { - return a >= mi && a <= ma; - } - - template - inline bool without(T a, T mi, T ma) - { - return a < mi || a > ma; - } - - template - inline T abs(T a) - { - return a > 0 ? a : -a; - } - - template - inline T lowerBound(T a, T lower) - { - return a < lower ? lower : a; - } - - template - inline T upperBound(T a, T upper) - { - return a > upper ? upper : a; - } - - template - inline T lerp(T a, T b, float t) - { - return a + t * (b - a); - } - - } // namespace math -} // namespace jin - -#endif \ No newline at end of file diff --git a/src/libjin/math/matrix.cpp b/src/libjin/math/matrix.cpp deleted file mode 100644 index 9f933f8..0000000 --- a/src/libjin/math/matrix.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include "Matrix.h" - -#include // memcpy -#include - -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 - { - public: - - protected: - singleton(Net); - Net() {}; - ~Net() {}; - bool initSystem(const SettingBase* setting) override; - void quitSystem() override; - - }; - - } // namespace net -} // namespace jin - -#endif // LIBJIN_MODULES_NET -#endif // __LIBJIN_NET_H diff --git a/src/libjin/thread/thread.cpp b/src/libjin/thread/thread.cpp deleted file mode 100644 index 3f2a50d..0000000 --- a/src/libjin/thread/thread.cpp +++ /dev/null @@ -1,301 +0,0 @@ -#include "../configuration.h" -#if LIBJIN_MODULES_THREAD - -#include "Thread.h" - -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&) {} - - }; - - ////////////////////////////////////////////////////////////////////// - - 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(); - }; - - 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(); - } - - } // namespace thread -} // namespace 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 deleted file mode 100644 index ea50444..0000000 --- a/src/libjin/thread/thread.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef __LIBJIN_THREAD_H -#define __LIBJIN_THREAD_H -#include "../configuration.h" -#if LIBJIN_MODULES_THREAD - -#include -#include -#if LIBJIN_THREAD_SDL -# include "SDL2/SDL_thread.h" -#elif LIBJIN_THREAD_CPP -# include -# include -# include -#endif - -namespace jin -{ - 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) {}; - }; - - 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); - - Conditional* condition; - Mutex* mutex; - - private: - std::map share; // threads shared value - - }; - - 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(); - - 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 - - }; - - } // namespace thread -} // namespace jin - -#endif // LIBJIN_MODULES_THREAD -#endif // __LIBJIN_THREAD_H \ No newline at end of file diff --git a/src/libjin/utils/endian.h b/src/libjin/utils/endian.h deleted file mode 100644 index 01def88..0000000 --- a/src/libjin/utils/endian.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef LIBJIN_LIL_ENDIAN && LIBJIN_BIG_ENDIAN - -#define LIBJIN_LIL_ENDIAN 2 -#define LIBJIN_BIG_ENDIAN 4 - -#endif - -#ifndef LIBJIN_BYTEORDER -#ifdef __linux__ -#include -#define LIBJIN_BYTEORDER __BYTE_ORDER -#else /* __linux__ */ -#if defined(__hppa__) || \ - defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ - (defined(__MIPS__) && defined(__MISPEB__)) || \ - defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ - defined(__sparc__) -#define LIBJIN_BYTEORDER LIBJIN_BIG_ENDIAN -#else -#define LIBJIN_BYTEORDER LIBJIN_LIL_ENDIAN -#endif -#endif /* __linux__ */ -#endif /* !SDL_BYTEORDER */ \ No newline at end of file diff --git a/src/libjin/utils/log.cpp b/src/libjin/utils/log.cpp deleted file mode 100644 index 5299942..0000000 --- a/src/libjin/utils/log.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#define LOGHELPER_IMPLEMENT -#include "log.h" \ No newline at end of file diff --git a/src/libjin/utils/log.h b/src/libjin/utils/log.h deleted file mode 100644 index e4ed879..0000000 --- a/src/libjin/utils/log.h +++ /dev/null @@ -1,134 +0,0 @@ -/** -* Single.h/loghelper.h -* Copyright (C) 2017~2018 chai -*/ -#ifndef __LOG_HELPER_H -#define __LOG_HELPER_H -#include -#include -#include -#include - -class Loghelper -{ -public: - // logÊä³öÄ¿±ê - enum Direction - { - DIR_CERR = 1 << 1, // ±ê×¼´íÎóÁ÷ - DIR_FILE = 1 << 2, // logÎļþ - }; - - // ´íÎóµÈ¼¶ - enum Level - { - LV_NONE = 0, // none - LV_ERROR = 1 << 1, // error - LV_WARN = 1 << 2, // warn - LV_INFO = 1 << 3, // info - LV_DEBUG = 1 << 4, // debug - LV_ALL = 0xffffffff - }; - - static void log(Level _level, const char* _fmt, ...); - - // ÖØ¶¨Ïò - static void redirect(unsigned int _dir, char* _path = nullptr); - - // ɸѡ´íÎóµÈ¼¶ - static void restrict(unsigned int levels); - - static void close(); - -private: - static unsigned int dir; // Êä³öÄ¿±ê - static unsigned int levels; // ´íÎóµÈ¼¶ - static std::ofstream fs; // Êä³öÎļþÁ÷ -}; - -typedef Loghelper::Level Loglevel; - -#ifdef LOGHELPER_IMPLEMENT - -#define hasbit(flag, bit) ((flag & bit) == bit) - -unsigned int Loghelper::dir = Loghelper::Direction::DIR_CERR; -unsigned int Loghelper::levels = Loghelper::Level::LV_ALL; -std::ofstream Loghelper::fs; - -void Loghelper::log(Level _level, const char* _fmt, ...) -{ - if (!hasbit(levels, _level)) - return; -#define FORMAT_MSG_BUFFER_SIZE (204800) - const char* levelStr = nullptr; - switch (_level) - { - case LV_ERROR: - levelStr = "[Jin Error]:"; - break; - case LV_WARN: - levelStr = "[Jin Warn]:"; - break; - case LV_INFO: - levelStr = "[Jin Info]:"; - break; - case LV_DEBUG: - levelStr = "[Jin Debug]:"; - break; - default: - levelStr = "[Jin Unknown]:"; - break; - } - char buffer[FORMAT_MSG_BUFFER_SIZE + 1] = { 0 }; - strcpy(buffer, levelStr); - va_list args; - va_start(args, _fmt); - vsnprintf(buffer + strlen(buffer), FORMAT_MSG_BUFFER_SIZE, _fmt, args); - va_end(args); - if (hasbit(dir, DIR_CERR)) - { - std::cerr << buffer << std::endl; - } - if (hasbit(dir, DIR_FILE)) - { - fs << buffer << std::endl; - } -#undef FORMAT_MSG_BUFFER_SIZE -} - -// ÖØ¶¨Ïò -void Loghelper::redirect(unsigned int _dir, char* _path) -{ - dir = _dir; - if (hasbit(dir, DIR_FILE)) - { - try - { - fs.open(_path, std::ios_base::app); - } - catch (std::ios_base::failure& e) { - dir = DIR_CERR; - log(Level::LV_WARN, "ÖØ¶¨Ïòlog·¾¶ %s ʧ°Ü", _path); - } - } -} - -// ɸѡ´íÎóµÈ¼¶ -void Loghelper::restrict(unsigned int _levels) -{ - levels = _levels; -} - -void Loghelper::close() -{ - if (!fs.fail()) - fs.close(); - fs.clear(); -} - -#undef hasbit - -#endif - -#endif diff --git a/src/libjin/utils/macros.h b/src/libjin/utils/macros.h deleted file mode 100644 index e19193c..0000000 --- a/src/libjin/utils/macros.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __LIBJIN_MACROS_H -#define __LIBJIN_MACROS_H -#include - -//#define implement // ʵÏÖ½Ó¿Ú -// -//#define shared // ÉùÃ÷ÀàµÄ·½·¨ -// -//#define MASK // ÉùÃ÷ÑÚÂë enum -// -//#define onlyonce // ÉùÃ÷Ö»»áµ÷ÓÃÒ»´Î -//#define CALLONCE(call) static char __dummy__=(call, 1) // Ö»»áµ÷ÓÃÒ»´Î -//#define SAFECALL(func, params) if(func) func(params) -// -//#define zero(mem) memset(&mem, 0, sizeof(mem)) - -#endif \ No newline at end of file diff --git a/src/libjin/utils/unittest.cpp b/src/libjin/utils/unittest.cpp deleted file mode 100644 index 44f1ae5..0000000 --- a/src/libjin/utils/unittest.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "utils.h" -#if UNITTEST - -#include -#include -#include -#include "../audio/sdl/source.h" -#include "../audio/sdl/audio.h" - -using namespace jin::audio; -using namespace std; - -int main(int argc, char* argv[]) -{ - SDLAudio* audio = SDLAudio::get(); - audio->init(0); - SDLSource* source = SDLSource::createSource("a.ogg"); - SDLSource* source2 = SDLSource::createSource("a.wav"); - //source->play(); - source2->play(); - source->setLoop(true); - source2->setLoop(true); - int i = 0; - while (true) - { - SDL_Delay(1000); - } - audio->quit(); - return 0; -} - -/* -#include -#include -#include -#include "SDL2/SDL.h" - -#include <3rdparty/cmixer/cmixer.h> - -static SDL_mutex* audio_mutex; - -static void lock_handler(cm_Event *e) { - if (e->type == CM_EVENT_LOCK) { - SDL_LockMutex(audio_mutex); - } - if (e->type == CM_EVENT_UNLOCK) { - SDL_UnlockMutex(audio_mutex); - } -} - - -static void audio_callback(void *udata, Uint8 *stream, int size) { - cm_process((cm_Int16*)stream, size / 2); -} - - -int main(int argc, char **argv) { - SDL_AudioDeviceID dev; - SDL_AudioSpec fmt, got; - cm_Source *src; - cm_Source* src2; - - - SDL_Init(SDL_INIT_AUDIO); - audio_mutex = SDL_CreateMutex(); - - memset(&fmt, 0, sizeof(fmt)); - fmt.freq = 44100; - fmt.format = AUDIO_S16; - fmt.channels = 2; - fmt.samples = 1024; - fmt.callback = audio_callback; - - dev = SDL_OpenAudioDevice(NULL, 0, &fmt, &got, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); - if (dev == 0) { - fprintf(stderr, "Error: failed to open audio device '%s'\n", SDL_GetError()); - exit(EXIT_FAILURE); - } - - cm_init(got.freq); - cm_set_lock(lock_handler); - cm_set_master_gain(0.5); - - SDL_PauseAudioDevice(dev, 0); - - src = cm_new_source_from_file("a.ogg"); - src2 = cm_new_source_from_file("loop.wav"); - if (!src) { - fprintf(stderr, "Error: failed to create source '%s'\n", cm_get_error()); - exit(EXIT_FAILURE); - } - cm_set_loop(src2, 1); - - cm_play(src); - cm_play(src2); - - printf("Press [return] to exit\n"); - getchar(); - - cm_destroy_source(src); - SDL_CloseAudioDevice(dev); - SDL_Quit(); - - return EXIT_SUCCESS; -} -*/ - -#endif \ No newline at end of file diff --git a/src/libjin/utils/utils.h b/src/libjin/utils/utils.h deleted file mode 100644 index 1654a8f..0000000 --- a/src/libjin/utils/utils.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __LIBJIN_UTILS_H -#define __LIBJIN_UTILS_H - -#include "macros.h" -#include "endian.h" - -#define UNITTEST 0 - -#endif \ No newline at end of file -- cgit v1.1-26-g67d0