mirror of
				https://git.shylie.info/shylie/glerminal.git
				synced 2025-10-26 23:00:07 +00:00 
			
		
		
		
	Compare commits
	
		
			15 Commits
		
	
	
		
			6663804c88
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| fb3eeb6ec9 | |||
| 263cf68ca2 | |||
| b8e616c8d6 | |||
| 1bfbab7a96 | |||
| d156005441 | |||
| 82389b8c12 | |||
| 0a9d211942 | |||
| 937693ce6a | |||
| 365cad551b | |||
| 5fbeb1e4e9 | |||
| 11ffc40bbb | |||
| db46885ee9 | |||
| 20fad92e4f | |||
| 7c0c02b9af | |||
| 1a1f4e8b13 | 
| @@ -5,7 +5,7 @@ on: push | ||||
|  | ||||
| jobs: | ||||
|   build-app: | ||||
|     runs-on: linux_amd64 | ||||
|     runs-on: shy-server | ||||
|     steps: | ||||
|       - name: Checkout current | ||||
|         uses: actions/checkout@v4 | ||||
| @@ -20,7 +20,7 @@ jobs: | ||||
|           fetch-depth: 0 | ||||
|           submodules: recursive | ||||
|           lfs: true | ||||
|       - run: cd prev && git checkout 10a90a5f6a | ||||
|       - run: cd prev && git checkout 263cf68ca2 | ||||
|       - name: Build current | ||||
|         run: cmake -S curr -B curr/build -DGLERMINAL_TEST=ON && cmake --build curr/build | ||||
|       - name: Build previous | ||||
|   | ||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,4 @@ | ||||
| build/ | ||||
| cmake-build-*/ | ||||
| .idea/ | ||||
| .idea/ | ||||
| .cache/ | ||||
|   | ||||
							
								
								
									
										5
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,3 @@ | ||||
| [submodule "glfw"] | ||||
| 	path = glfw | ||||
| 	url = https://git.shylie.info/mirror/glfw.git | ||||
| [submodule "Lua"] | ||||
| 	path = Lua | ||||
| 	url = https://git.shylie.info/mirror/Lua.git | ||||
| 	url = https://github.com/glfw/glfw.git | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| cmake_minimum_required(VERSION 3.28) | ||||
|  | ||||
| project(glerminal | ||||
| 	VERSION 0.1.0 | ||||
| 	LANGUAGES C CXX | ||||
|   VERSION 0.1.0 | ||||
|   LANGUAGES C CXX | ||||
| ) | ||||
|  | ||||
| option(GLERMINAL_OPENGL_DEBUG_CONTEXT "" OFF) | ||||
| @@ -11,75 +11,58 @@ set(GLERMINAL_GRID_WIDTH 40 CACHE STRING "") | ||||
| set(GLERMINAL_GRID_HEIGHT 25 CACHE STRING "") | ||||
| set(GLERMINAL_LAYER_COUNT 64 CACHE STRING "") | ||||
| set(GLERMINAL_CELL_SCALE 4 CACHE STRING "") | ||||
| set(GLERMINAL_CELL_SIZE 8 CACHE STRING "") | ||||
|  | ||||
| configure_file(source/glerminal-config.h.in glerminal-config.h @ONLY) | ||||
|  | ||||
| add_subdirectory(glfw) | ||||
| add_subdirectory(Lua) | ||||
|  | ||||
| add_library(glerminallib STATIC | ||||
| 	${CMAKE_CURRENT_BINARY_DIR}/glerminal-config.h | ||||
| 	include/glerminal.h | ||||
| add_library(glerminal STATIC | ||||
|   ${CMAKE_CURRENT_BINARY_DIR}/glerminal-config.h | ||||
|   include/glerminal.h | ||||
|  | ||||
| 	source/stb_image.h | ||||
| 	source/glerminal-private.h | ||||
| 	source/glerminal.cpp | ||||
|   source/stb_image.h | ||||
|   source/glerminal-private.h | ||||
|   source/glerminal.cpp | ||||
|  | ||||
| 	source/glad/glad.h | ||||
| 	source/KHR/khrplatform.h | ||||
| 	source/glad.c | ||||
|   source/glad/glad.h | ||||
|   source/KHR/khrplatform.h | ||||
|   source/glad.c | ||||
|  | ||||
| 	source/miniaudio.h | ||||
| 	source/miniaudio.c | ||||
|   source/miniaudio.h | ||||
|   source/miniaudio.c | ||||
| ) | ||||
|  | ||||
| set_target_properties(glerminallib | ||||
| 	PROPERTIES | ||||
| 		CXX_STANDARD 11 | ||||
| set_target_properties(glerminal | ||||
|   PROPERTIES | ||||
|     CXX_STANDARD 11 | ||||
| ) | ||||
|  | ||||
| target_include_directories(glerminallib | ||||
| 	PUBLIC | ||||
| 		include | ||||
| 		${CMAKE_CURRENT_BINARY_DIR} | ||||
| 	PRIVATE | ||||
| 		source | ||||
| ) | ||||
|  | ||||
| target_link_libraries(glerminallib | ||||
| 	PUBLIC | ||||
| 		glfw | ||||
| ) | ||||
|  | ||||
| target_compile_definitions(glerminallib | ||||
| 	PUBLIC | ||||
| 		GLERMINAL_VERSION=${PROJECT_VERSION} | ||||
| 		GLERMINAL_VERSION_MAJOR=${PROJECT_VERSION_MAJOR} | ||||
| 		GLERMINAL_VERSION_MINOR=${PROJECT_VERSION_MINOR} | ||||
| 		GLERMINAL_VERSION_PATCH=${PROJECT_VERSION_PATCH} | ||||
| ) | ||||
|  | ||||
| if (MSVC) | ||||
| 	target_link_options(glerminallib | ||||
| 		PUBLIC | ||||
| 			"/ENTRY:mainCRTStartup" | ||||
| 	) | ||||
| endif() | ||||
|  | ||||
| add_executable(glerminal WIN32 | ||||
| 	source/glerminal-main.cpp | ||||
| target_include_directories(glerminal | ||||
|   PUBLIC | ||||
|     include | ||||
|     ${CMAKE_CURRENT_BINARY_DIR} | ||||
|   PRIVATE | ||||
|     source | ||||
| ) | ||||
|  | ||||
| target_link_libraries(glerminal | ||||
| 	PRIVATE | ||||
| 		glerminallib | ||||
| 		lua_static | ||||
|   PUBLIC | ||||
|     glfw | ||||
| ) | ||||
|  | ||||
| if (PROJECT_IS_TOP_LEVEL) | ||||
| 	add_subdirectory(examples examples) | ||||
| target_compile_definitions(glerminal | ||||
|   PUBLIC | ||||
|     GLERMINAL_VERSION=${PROJECT_VERSION} | ||||
|     GLERMINAL_VERSION_MAJOR=${PROJECT_VERSION_MAJOR} | ||||
|     GLERMINAL_VERSION_MINOR=${PROJECT_VERSION_MINOR} | ||||
|     GLERMINAL_VERSION_PATCH=${PROJECT_VERSION_PATCH} | ||||
| ) | ||||
|  | ||||
| if(PROJECT_IS_TOP_LEVEL) | ||||
|   add_subdirectory(examples examples) | ||||
| endif() | ||||
|  | ||||
| if (GLERMINAL_TEST) | ||||
| 	add_subdirectory(tests tests) | ||||
| endif() | ||||
| if(GLERMINAL_TEST) | ||||
|   add_subdirectory(tests tests) | ||||
| endif() | ||||
|   | ||||
							
								
								
									
										1
									
								
								Lua
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								Lua
									
									
									
									
									
								
							 Submodule Lua deleted from 88246d621a
									
								
							
							
								
								
									
										37
									
								
								PROJECT_RETROSPECTIVE.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								PROJECT_RETROSPECTIVE.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| # A look back on what I learned | ||||
|  | ||||
| ## why? | ||||
|  | ||||
| I came across an art/rendering style called "sprite stacking". | ||||
| I found sprite stacking very interesting in comparison to traditional methods, | ||||
| and wanted to experiment with the style. | ||||
|  | ||||
| ## challenge | ||||
|  | ||||
| This was my first big graphics-based project. Computer graphics | ||||
| at the low-level was new to me. I took this as an opportunity to | ||||
| learn the basics of OpenGL. This learning process was the most | ||||
| difficult part of the project, especially the domain-specific | ||||
| rendering techniques used. | ||||
|  | ||||
| ## how? | ||||
|  | ||||
| I found some [great tutorials](https://learnopengl.com) to get started, | ||||
| and though these helped, I also did a lot of individual | ||||
| learning through experimentation and discussion with peers. | ||||
|  | ||||
| ## results | ||||
|  | ||||
| In the end, the library had most of the functionality | ||||
| I originally wanted. The library can draw up to 256 layers of icons in a grid, | ||||
| with optional offsets and tints per icon. Here's an example with only 7 library calls: | ||||
|  | ||||
|  | ||||
|  | ||||
| ## evaluation | ||||
|  | ||||
| Besides learning the basics of OpenGL, I also learned | ||||
| how to use CMake to help build the library. Also, I set up | ||||
| continuous integration for automated testing on a git commit. | ||||
| If I were to rewrite this library, I would definitely invest more | ||||
| into the automated testing process. | ||||
| @@ -1,2 +1,4 @@ | ||||
| # termg | ||||
| # glerminal | ||||
|  | ||||
| glerminal is a tile-based graphics library created | ||||
| with the intent to use a sprite-stacking art style. | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								example.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								example.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 6.1 MiB | 
| @@ -36,5 +36,5 @@ list(TRANSFORM EXAMPLE_RESOURCES PREPEND ${CMAKE_CURRENT_BINARY_DIR}/) | ||||
| foreach(SOURCE_FILE ${EXAMPLE_SOURCES}) | ||||
| 	get_filename_component(SOURCE_FILENAME ${SOURCE_FILE} NAME_WLE) | ||||
| 	add_executable(${SOURCE_FILENAME} WIN32 ${SOURCE_FILE} ${EXAMPLE_RESOURCES}) | ||||
| 	target_link_libraries(${SOURCE_FILENAME} PRIVATE glerminallib) | ||||
| endforeach() | ||||
| 	target_link_libraries(${SOURCE_FILENAME} PRIVATE glerminal) | ||||
| endforeach() | ||||
|   | ||||
| @@ -42,7 +42,7 @@ void glerminal_flush(); | ||||
|  * @param layer layer of the cell in the range [0, LAYER_COUNT) | ||||
|  * @param sprite sprite's index in the range [0, 4096) | ||||
|  */ | ||||
| void glerminal_set(unsigned char x, unsigned char y, unsigned char layer, unsigned short sprite); | ||||
| void glerminal_set(int x, int y, int layer, unsigned short sprite); | ||||
| /** | ||||
|  * @brief Get a cell's sprite | ||||
|  * @param x position of the cell in the range [0, GRID_WIDTH) | ||||
| @@ -50,7 +50,7 @@ void glerminal_set(unsigned char x, unsigned char y, unsigned char layer, unsign | ||||
|  * @param layer layer of the cell in the range [0, LAYER_COUNT) | ||||
|  * @return sprite index currently assigned to the cell | ||||
|  */ | ||||
| unsigned short glerminal_get(unsigned char x, unsigned char y, unsigned short layer); | ||||
| unsigned short glerminal_get(int x, int y, int layer); | ||||
| /** | ||||
|  * @brief Set a cell's offset | ||||
|  * @param x position of the cell in the range [0, GRID_WIDTH) | ||||
| @@ -59,7 +59,7 @@ unsigned short glerminal_get(unsigned char x, unsigned char y, unsigned short la | ||||
|  * @param x_offset offset of the cell on the x axis in cells | ||||
|  * @param y_offset offset of the cell on the y axis in cells | ||||
|  */ | ||||
| void glerminal_offset(unsigned char x, unsigned char y, unsigned char layer, float x_offset, float y_offset); | ||||
| void glerminal_offset(int x, int y, int layer, float x_offset, float y_offset); | ||||
|  | ||||
| /** | ||||
|  * @brief Set a cell's color | ||||
| @@ -68,7 +68,7 @@ void glerminal_offset(unsigned char x, unsigned char y, unsigned char layer, flo | ||||
|  * @param layer layer of the cell in the range [0, LAYER_COUNT) | ||||
|  * @param color The new color | ||||
|  */ | ||||
| void glerminal_color(unsigned char x, unsigned char y, unsigned char layer, unsigned int color); | ||||
| void glerminal_color(int x, int y, int layer, unsigned int color); | ||||
| /** | ||||
|  * @brief Set a cell's scale | ||||
|  * @param x position of the cell in the range [0, GRID_WIDTH) | ||||
| @@ -76,7 +76,7 @@ void glerminal_color(unsigned char x, unsigned char y, unsigned char layer, unsi | ||||
|  * @param layer layer of the cell in the range [0, LAYER_COUNT) | ||||
|  * @param scale The new scale | ||||
|  */ | ||||
| void glerminal_scale(unsigned char x, unsigned char y, unsigned char layer, float scale); | ||||
| void glerminal_scale(int x, int y, int layer, float scale); | ||||
|  | ||||
| /** | ||||
|  * @brief Load sprites from a png file | ||||
|   | ||||
| @@ -1,35 +0,0 @@ | ||||
| local time = 0 | ||||
|  | ||||
| function glerminal.init() | ||||
|     if not glerminal.sprites('sprites.png') then | ||||
|         print('failed to load sprites') | ||||
|     end | ||||
|  | ||||
|     for i = 1, 40 do | ||||
|         for j = 1, 25 do | ||||
|             glerminal.set(i, j, 1, 2) | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     glerminal.tint(1, 0xA0FFFFFF) | ||||
|  | ||||
|     glerminal.flush() | ||||
| end | ||||
|  | ||||
| function glerminal.main(dt) | ||||
|     time = time + dt / 2 | ||||
|  | ||||
|     for i = 1, 40 do | ||||
|         for j = 1, 25 do | ||||
|             glerminal.offset(i, j, 1, math.cos(time * i / math.pi), math.sin(time * j / math.pi)) | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     glerminal.flush() | ||||
| end | ||||
|  | ||||
| function glerminal.keypresse(key) end | ||||
| function glerminal.keyrelease(key) end | ||||
| function glerminal.mousemove(x, y) end | ||||
| function glerminal.mousepress(button, x, y) end | ||||
| function glerminal.mouserelease(button, x, y) end | ||||
| @@ -1,3 +0,0 @@ | ||||
| version https://git-lfs.github.com/spec/v1 | ||||
| oid sha256:6dee3efcdfa72e54a602f69643907bb8e8a3328d2b40c2116dce22ff179d8892 | ||||
| size 182 | ||||
| @@ -16,7 +16,8 @@ enum | ||||
| 	GRID_WIDTH = @GLERMINAL_GRID_WIDTH@, | ||||
| 	GRID_HEIGHT = @GLERMINAL_GRID_HEIGHT@, | ||||
| 	LAYER_COUNT = @GLERMINAL_LAYER_COUNT@, | ||||
| 	CELL_SCALE = @GLERMINAL_CELL_SCALE@ | ||||
| 	CELL_SCALE = @GLERMINAL_CELL_SCALE@, | ||||
| 	CELL_SIZE = @GLERMINAL_CELL_SIZE@ | ||||
| }; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|   | ||||
| @@ -1,372 +0,0 @@ | ||||
| #include <glerminal.h> | ||||
| #define GLFW_INCLUDE_NONE | ||||
| #include <GLFW/glfw3.h> | ||||
|  | ||||
| extern "C" | ||||
| { | ||||
| #include <lualib.h> | ||||
| #include <lauxlib.h> | ||||
| } | ||||
|  | ||||
| #include <iostream> | ||||
| #include <string> | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| #define WINDOWS_LEAN_AND_MEAN | ||||
| #include <Windows.h> | ||||
| #define CHANGE_WORKING_DIRECTORY(path) !(SetCurrentDirectory(path)) | ||||
| #else | ||||
| #include <unistd.h> | ||||
| #define CHANGE_WORKING_DIRECTORY(path) chdir(path) | ||||
| #endif | ||||
|  | ||||
| namespace | ||||
| { | ||||
| 	int lglerminal_quit(lua_State* L) | ||||
| 	{ | ||||
| 		glerminal_quit(); | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	int lglerminal_flush(lua_State* L) | ||||
| 	{ | ||||
| 		glerminal_flush(); | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	int lglerminal_set(lua_State* L) | ||||
| 	{ | ||||
| 		const unsigned char x = luaL_checkinteger(L, 1); | ||||
| 		const unsigned char y = luaL_checkinteger(L, 2); | ||||
| 		const unsigned char layer = luaL_checkinteger(L, 3) - 1; | ||||
| 		const unsigned short sprite = luaL_checkinteger(L, 4) - 1; | ||||
| 		glerminal_set(x, y, layer, sprite); | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	int lglerminal_get(lua_State* L) | ||||
| 	{ | ||||
| 		const unsigned char x = luaL_checkinteger(L, 1); | ||||
| 		const unsigned char y = luaL_checkinteger(L, 2); | ||||
| 		const unsigned char layer = luaL_checkinteger(L, 3) - 1; | ||||
| 		lua_pushnumber(L, glerminal_get(x, y, layer) + 1); | ||||
|  | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	int lglerminal_offset(lua_State* L) | ||||
| 	{ | ||||
| 		const unsigned char x = luaL_checkinteger(L, 1); | ||||
| 		const unsigned char y = luaL_checkinteger(L, 2); | ||||
| 		const unsigned char layer = luaL_checkinteger(L, 3) - 1; | ||||
| 		const float ox = luaL_checknumber(L, 4); | ||||
| 		const float oy = luaL_checknumber(L, 5); | ||||
| 		glerminal_offset(x, y, layer, ox, oy); | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	int lglerminal_layer_color(lua_State* L) | ||||
| 	{ | ||||
| 		const unsigned char x = luaL_checkinteger(L, 1); | ||||
| 		const unsigned char y = luaL_checkinteger(L, 2); | ||||
| 		const unsigned char layer = luaL_checkinteger(L, 3) - 1; | ||||
| 		const float r = luaL_checknumber(L, 4); | ||||
| 		const float g = luaL_checknumber(L, 5); | ||||
| 		const float b = luaL_checknumber(L, 6); | ||||
| 		const float a =	luaL_optnumber(L, 7, 1.0f); | ||||
|  | ||||
| 		int ri = 255 * r; | ||||
| 		int gi = 255 * g; | ||||
| 		int bi = 255 * b; | ||||
| 		int ai = 255 * a; | ||||
|  | ||||
| 		if (ri > 255) { ri = 255; } | ||||
| 		if (ri < 0)   { ri = 0;   } | ||||
|  | ||||
| 		if (gi > 255) { ri = 255; } | ||||
| 		if (gi < 0)   { ri = 0;   } | ||||
|  | ||||
| 		if (bi > 255) { ri = 255; } | ||||
| 		if (bi < 0)   { ri = 0;   } | ||||
|  | ||||
| 		if (ai > 255) { ri = 255; } | ||||
| 		if (ai < 0)   { ri = 0;   } | ||||
|  | ||||
| 		const unsigned int color = ri | (gi << 8) | (bi << 16) | (ai << 24); | ||||
|  | ||||
| 		glerminal_color(x, y, layer, color); | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	int lglerminal_layer_scale(lua_State* L) | ||||
| 	{ | ||||
| 		const unsigned char x = luaL_checkinteger(L, 1); | ||||
| 		const unsigned char y = luaL_checkinteger(L, 2); | ||||
| 		const unsigned char layer = luaL_checkinteger(L, 3) - 1; | ||||
| 		const float scale = luaL_checknumber(L, 4); | ||||
| 		glerminal_scale(x, y, layer, scale); | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	int lglerminal_load_sprites_file(lua_State* L) | ||||
| 	{ | ||||
| 		const char* path = luaL_checkstring(L, 1); | ||||
| 		lua_pushboolean(L, glerminal_load_sprites_file(path)); | ||||
|  | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	int lglerminal_play_sound(lua_State* L) | ||||
| 	{ | ||||
| 		const char* name = luaL_checkstring(L, 1); | ||||
| 		glerminal_sound(name); | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	const luaL_Reg lglerminal_methods[] = | ||||
| 	{ | ||||
| 		{ "quit",    lglerminal_quit }, | ||||
| 		{ "flush",   lglerminal_flush }, | ||||
| 		{ "set",     lglerminal_set }, | ||||
| 		{ "get",     lglerminal_get }, | ||||
| 		{ "offset",  lglerminal_offset }, | ||||
| 		{ "tint",    lglerminal_layer_color }, | ||||
| 		{ "scale",   lglerminal_layer_scale }, | ||||
| 		{ "sprites", lglerminal_load_sprites_file }, | ||||
| 		{ "sound",   lglerminal_play_sound }, | ||||
| 		{ nullptr,   nullptr } | ||||
| 	}; | ||||
|  | ||||
| 	int message_handler(lua_State* L) | ||||
| 	{ | ||||
| 		luaL_traceback(L, L, lua_tostring(L, -1), 1); | ||||
| 		lua_remove(L, -2); | ||||
|  | ||||
| 		glerminal_quit(); | ||||
|  | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	lua_State* L; | ||||
|  | ||||
| 	void init() | ||||
| 	{ | ||||
| 		lua_pushcfunction(L, message_handler); | ||||
| 		const int handler = lua_gettop(L); | ||||
| 		lua_getglobal(L, "glerminal"); | ||||
| 		lua_getfield(L, -1, "init"); | ||||
| 		lua_remove(L, -2); | ||||
| 		if (lua_pcall(L, 0, 0, handler) != LUA_OK) | ||||
| 		{ | ||||
| 			std::cout << lua_tostring(L, -1) << std::endl; | ||||
| 			lua_pop(L, 1); | ||||
| 		} | ||||
| 		lua_remove(L, handler); | ||||
| 	} | ||||
|  | ||||
| 	void mainloop(double dt) | ||||
| 	{ | ||||
| 		lua_pushcfunction(L, message_handler); | ||||
| 		const int handler = lua_gettop(L); | ||||
| 		lua_getglobal(L, "glerminal"); | ||||
| 		lua_getfield(L, -1, "main"); | ||||
| 		lua_remove(L, -2); | ||||
| 		lua_pushnumber(L, dt); | ||||
| 		if (lua_pcall(L, 1, 0, handler) != LUA_OK) | ||||
| 		{ | ||||
| 			std::cout << lua_tostring(L, -1) << std::endl; | ||||
| 			lua_pop(L, 1); | ||||
| 		} | ||||
| 		lua_remove(L, handler); | ||||
| 	} | ||||
|  | ||||
| 	void keypressed(int key) | ||||
| 	{ | ||||
| 		const char* const name = glfwGetKeyName(key, 0); | ||||
| 		if (name) | ||||
| 		{ | ||||
| 			lua_pushcfunction(L, message_handler); | ||||
| 			const int handler = lua_gettop(L); | ||||
| 			lua_getglobal(L, "glerminal"); | ||||
| 			lua_getfield(L, -1, "keypress"); | ||||
| 			lua_remove(L, -2); | ||||
| 			lua_pushstring(L, name); | ||||
| 			if (lua_pcall(L, 1, 0, handler) != LUA_OK) | ||||
| 			{ | ||||
| 				std::cout << lua_tostring(L, -1) << std::endl; | ||||
| 				lua_pop(L, 1); | ||||
| 			} | ||||
| 			lua_remove(L, handler); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void keyrelease(int key) | ||||
| 	{ | ||||
| 		const char* const name = glfwGetKeyName(key, 0); | ||||
| 		if (name) | ||||
| 		{ | ||||
| 			lua_pushcfunction(L, message_handler); | ||||
| 			const int handler = lua_gettop(L); | ||||
| 			lua_getglobal(L, "glerminal"); | ||||
| 			lua_getfield(L, -1, "keyrelease"); | ||||
| 			lua_remove(L, -2); | ||||
| 			lua_pushstring(L, name); | ||||
| 			if (lua_pcall(L, 1, 0, handler) != LUA_OK) | ||||
| 			{ | ||||
| 				std::cout << lua_tostring(L, -1) << std::endl; | ||||
| 				lua_pop(L, 1); | ||||
| 			} | ||||
| 			lua_remove(L, handler); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void mousemove(double x, double y) | ||||
| 	{ | ||||
| 		lua_pushcfunction(L, message_handler); | ||||
| 		const int handler = lua_gettop(L); | ||||
| 		lua_getglobal(L, "glerminal"); | ||||
| 		lua_getfield(L, -1, "mousemove"); | ||||
| 		lua_remove(L, -2); | ||||
| 		lua_pushnumber(L, x); | ||||
| 		lua_pushnumber(L, y); | ||||
| 		if (lua_pcall(L, 2, 0, handler) != LUA_OK) | ||||
| 		{ | ||||
| 			std::cout << lua_tostring(L, -1) << std::endl; | ||||
| 			lua_pop(L, 1); | ||||
| 		} | ||||
| 		lua_remove(L, handler); | ||||
| 	} | ||||
|  | ||||
| 	void mousepress(int button, double x, double y) | ||||
| 	{ | ||||
| 		const char* button_name = nullptr; | ||||
| 		switch (button) | ||||
| 		{ | ||||
| 			case GLFW_MOUSE_BUTTON_LEFT: | ||||
| 				button_name = "left"; | ||||
| 			break; | ||||
|  | ||||
| 			case GLFW_MOUSE_BUTTON_RIGHT: | ||||
| 				button_name = "right"; | ||||
| 			break; | ||||
|  | ||||
| 			case GLFW_MOUSE_BUTTON_MIDDLE: | ||||
| 				button_name = "middle"; | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		if (button_name) | ||||
| 		{ | ||||
| 			lua_pushcfunction(L, message_handler); | ||||
| 			const int handler = lua_gettop(L); | ||||
| 			lua_getglobal(L, "glerminal"); | ||||
| 			lua_getfield(L, -1, "mousepress"); | ||||
| 			lua_remove(L, -2); | ||||
| 			lua_pushstring(L, button_name); | ||||
| 			lua_pushnumber(L, x); | ||||
| 			lua_pushnumber(L, y); | ||||
| 			if (lua_pcall(L, 3, 0, handler) != LUA_OK) | ||||
| 			{ | ||||
| 				std::cout << lua_tostring(L, -1) << std::endl; | ||||
| 				lua_pop(L, 1); | ||||
| 			} | ||||
| 			lua_remove(L, handler); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void mouserelease(int button, double x, double y) | ||||
| 	{ | ||||
| 		const char* button_name = nullptr; | ||||
| 		switch (button) | ||||
| 		{ | ||||
| 			case GLFW_MOUSE_BUTTON_LEFT: | ||||
| 				button_name = "left"; | ||||
| 			break; | ||||
|  | ||||
| 			case GLFW_MOUSE_BUTTON_RIGHT: | ||||
| 				button_name = "right"; | ||||
| 			break; | ||||
|  | ||||
| 			case GLFW_MOUSE_BUTTON_MIDDLE: | ||||
| 				button_name = "middle"; | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		if (button_name) | ||||
| 		{ | ||||
| 			lua_pushcfunction(L, message_handler); | ||||
| 			const int handler = lua_gettop(L); | ||||
| 			lua_getglobal(L, "glerminal"); | ||||
| 			lua_getfield(L, -1, "mouserelease"); | ||||
| 			lua_remove(L, -2); | ||||
| 			lua_pushstring(L, button_name); | ||||
| 			lua_pushnumber(L, x); | ||||
| 			lua_pushnumber(L, y); | ||||
| 			if (lua_pcall(L, 3, 0, handler) != LUA_OK) | ||||
| 			{ | ||||
| 				std::cout << lua_tostring(L, -1) << std::endl; | ||||
| 				lua_pop(L, 1); | ||||
| 			} | ||||
| 			lua_remove(L, handler); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int main(int argc, char** argv) | ||||
| { | ||||
| 	if (argc == 1) | ||||
| 	{ | ||||
| 		std::cout << "Usage: " << argv[0] << " <project directory>" << std::endl; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (CHANGE_WORKING_DIRECTORY(argv[1])) | ||||
| 	{ | ||||
| 		std::cout << "Failed to find project directory" << std::endl; | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	L = luaL_newstate(); | ||||
| 	luaL_openlibs(L); | ||||
|  | ||||
| 	luaL_newlib(L, lglerminal_methods); | ||||
| 	lua_setglobal(L, "glerminal"); | ||||
|  | ||||
| 	lua_pushcfunction(L, message_handler); | ||||
| 	const int handler = lua_gettop(L); | ||||
| 	if (luaL_loadfile(L, "main.lua") != LUA_OK) | ||||
| 	{ | ||||
| 		const char* str = lua_tostring(L, -1); | ||||
| 		std::cout << str << std::endl; | ||||
| 		lua_pop(L, 1); | ||||
| 	} | ||||
| 	else if (lua_pcall(L, 0, LUA_MULTRET, handler) != LUA_OK) | ||||
| 	{ | ||||
| 		const char* str = lua_tostring(L, -1); | ||||
| 		std::cout << str << std::endl; | ||||
| 		lua_pop(L, 1); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		glerminal_init_params params; | ||||
| 		params.init = init; | ||||
| 		params.main = mainloop; | ||||
| 		params.keypress = keypressed; | ||||
| 		params.keyrelease = keyrelease; | ||||
| 		params.moved = mousemove; | ||||
| 		params.mousepress = mousepress; | ||||
| 		params.mouserelease = mouserelease; | ||||
| 		glerminal_run(params); | ||||
| 	} | ||||
|  | ||||
| 	lua_close(L); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| @@ -9,20 +9,18 @@ | ||||
| #include <GLFW/glfw3.h> | ||||
|  | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
| #include <stdexcept> | ||||
| #include <map> | ||||
| #include <string> | ||||
|  | ||||
| namespace glerminal | ||||
| { | ||||
| 	constexpr unsigned int CELL_SIZE = 8; | ||||
| 	constexpr unsigned int MAX_SPRITES_ROW = 64; | ||||
| 	constexpr unsigned int MAX_SPRITES = MAX_SPRITES_ROW * MAX_SPRITES_ROW; | ||||
| 	constexpr unsigned int GRID_WIDTH = ::GRID_WIDTH; | ||||
| 	constexpr unsigned int GRID_HEIGHT = ::GRID_HEIGHT; | ||||
| 	constexpr unsigned int LAYER_COUNT = ::LAYER_COUNT; | ||||
| 	constexpr unsigned int CELL_SCALE = ::CELL_SCALE; | ||||
| 	constexpr unsigned int CELL_SIZE = ::CELL_SIZE; | ||||
| 	constexpr unsigned int GRID_AREA = GRID_WIDTH * GRID_HEIGHT; | ||||
| 	constexpr unsigned int SCREEN_WIDTH = GRID_WIDTH * CELL_SIZE * CELL_SCALE; | ||||
| 	constexpr unsigned int SCREEN_HEIGHT = GRID_HEIGHT * CELL_SIZE * CELL_SCALE; | ||||
| @@ -47,11 +45,11 @@ namespace glerminal | ||||
|  | ||||
| 		void flush(); | ||||
|  | ||||
| 		void set(unsigned char x, unsigned char y, unsigned char layer, unsigned short sprite); | ||||
| 		unsigned short get(unsigned char x, unsigned char y, unsigned char layer) const; | ||||
| 		void offset(unsigned char x, unsigned char y, unsigned char layer, float x_offset, float y_offset); | ||||
| 		void color(unsigned char x, unsigned char y, unsigned char layer, unsigned int color); | ||||
| 		void scale(unsigned char x, unsigned char y, unsigned char layer, float scale); | ||||
| 		void set(int x, int y, int layer, unsigned short sprite); | ||||
| 		unsigned short get(int x, int y, int layer) const; | ||||
| 		void offset(int x, int y, int layer, float x_offset, float y_offset); | ||||
| 		void color(int x, int y, int layer, unsigned int color); | ||||
| 		void scale(int x,int y, int layer, float scale); | ||||
| 		void load_atlas(unsigned char w, unsigned char h, const unsigned int* data); | ||||
| 		bool load_sound(const char* name); | ||||
| 		void play_sound(const char* name); | ||||
| @@ -121,4 +119,4 @@ namespace glerminal | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| #endif//GLERMINAL_PRIVATE_H | ||||
| #endif//GLERMINAL_PRIVATE_H | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| #define STB_IMAGE_IMPLEMENTATION | ||||
| #define STBI_ONLY_PNG | ||||
| #define STBI_MAX_DIMENSIONS 512 | ||||
| #define STBI_MAX_DIMENSIONS 2048 | ||||
| #include "glerminal-private.h" | ||||
|  | ||||
| #define GRID_SIZE_UNIFORM_NAME "grid_size" | ||||
| @@ -8,6 +8,7 @@ | ||||
| #define LAYERS_UNIFORM_NAME "layers" | ||||
| #define LAYER_COUNT_UNIFORM_NAME "layer_count" | ||||
| #define ATLAS_WIDTH_UNIFORM_NAME "atlas_width" | ||||
| #define CELL_SIZE_UNIFORM_NAME "cell_size" | ||||
|  | ||||
| namespace | ||||
| { | ||||
| @@ -33,6 +34,7 @@ namespace | ||||
| 		"layout (location = 2) in int sprite;\n" | ||||
| 		"layout (location = 3) in vec4 color;\n" | ||||
| 		"layout (location = 4) in float scale;\n" | ||||
| 		"uniform float " CELL_SIZE_UNIFORM_NAME ";\n" | ||||
| 		"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n" | ||||
| 		"uniform int " ATLAS_WIDTH_UNIFORM_NAME ";\n" | ||||
| 		"out VS_OUT {\n" | ||||
| @@ -48,7 +50,7 @@ namespace | ||||
| 		"	vs_out.sprite = sprite;\n" | ||||
| 		"	vs_out.layer = layer;\n" | ||||
| 		"	vs_out.layer_color = color;\n" | ||||
| 		"	vs_out.texcoord = vec2(sprite % " ATLAS_WIDTH_UNIFORM_NAME " + position.x + 1, (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ") + vec2(-(2 * position.x + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16, (2 * position.y + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16);\n" | ||||
| 		"	vs_out.texcoord = vec2(sprite % " ATLAS_WIDTH_UNIFORM_NAME " + position.x + 1, (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ") + vec2(-(2 * position.x + 1) * " GRID_SIZE_UNIFORM_NAME ".z / (2 * " CELL_SIZE_UNIFORM_NAME "), (2 * position.y + 1) * " GRID_SIZE_UNIFORM_NAME ".z / (2 * " CELL_SIZE_UNIFORM_NAME "));\n" | ||||
| 		"	vec2 cell_position = vec2(scale + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x));\n" | ||||
| 		"	vec2 temp = ((position + vec2(-0.5, 0.5)) * scale + cell_position + vec2(-0.5, 0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n" | ||||
| 		"	gl_Position = vec4(scaled_offset.x + temp.x, scaled_offset.y - temp.y, 0, 1);\n" | ||||
| @@ -64,6 +66,7 @@ namespace | ||||
| 		"layout (location = 2) in int sprite;\n" | ||||
| 		"layout (location = 3) in vec4 color;\n" | ||||
| 		"layout (location = 4) in float scale;\n" | ||||
| 		"uniform float " CELL_SIZE_UNIFORM_NAME ";\n" | ||||
| 		"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n" | ||||
| 		"uniform int " ATLAS_WIDTH_UNIFORM_NAME ";\n" | ||||
| 		"out VS_OUT {\n" | ||||
| @@ -77,7 +80,7 @@ namespace | ||||
| 		"	gl_Layer = layer;\n" | ||||
| 		"	vec2 scaled_offset = 2 * offset * " GRID_SIZE_UNIFORM_NAME ".zw;\n" | ||||
| 		"	vs_out.sprite = sprite;\n" | ||||
| 		"	vs_out.texcoord = vec2(sprite % " ATLAS_WIDTH_UNIFORM_NAME " + position.x + 1, (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ") + vec2(-(2 * position.x + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16, (2 * position.y + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16);\n" | ||||
| 		"	vs_out.texcoord = vec2(sprite % " ATLAS_WIDTH_UNIFORM_NAME " + position.x + 1, (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ") + vec2(-(2 * position.x + 1) * " GRID_SIZE_UNIFORM_NAME ".z / (2 * " CELL_SIZE_UNIFORM_NAME "), (2 * position.y + 1) * " GRID_SIZE_UNIFORM_NAME ".z / (2 * " CELL_SIZE_UNIFORM_NAME "));\n" | ||||
| 		"	vs_out.layer_color = color;\n" | ||||
| 		"	vec2 cell_position = vec2(scale + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x));\n" | ||||
| 		"	vec2 temp = ((position + vec2(-0.5, 0.5)) * scale + cell_position + vec2(-0.5, 0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n" | ||||
| @@ -285,26 +288,23 @@ namespace glerminal | ||||
| 		glClear(GL_COLOR_BUFFER_BIT); | ||||
| 		glDrawArrays(GL_TRIANGLES, 0, 6); | ||||
|  | ||||
|     glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||
|     glClear(GL_COLOR_BUFFER_BIT); | ||||
| 		glBlitNamedFramebuffer(m_screen_framebuffer, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); | ||||
|  | ||||
| 		glfwSwapInterval(0); | ||||
| 		glfwSwapBuffers(m_window); | ||||
| 		glBlitNamedFramebuffer(m_screen_framebuffer, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); | ||||
| 		glfwSwapInterval(1); | ||||
| 		glfwSwapBuffers(m_window); | ||||
| 	} | ||||
|  | ||||
| 	void glerminal::set(unsigned char x, unsigned char y, unsigned char layer, unsigned short sprite) | ||||
| 	void glerminal::set(int x, int y, int layer, unsigned short sprite) | ||||
| 	{ | ||||
| 		if (x < GRID_WIDTH + 2 && y < GRID_HEIGHT + 2 && layer < LAYER_COUNT) | ||||
| 		if (x >= 0 && x < GRID_WIDTH + 2 && y >= 0 && y < GRID_HEIGHT + 2 && layer >= 0 && layer < LAYER_COUNT) | ||||
| 		{ | ||||
| 			m_cells[x + y * (GRID_WIDTH + 2) + layer * GRID_AREA_2] = sprite; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	unsigned short glerminal::get(unsigned char x, unsigned char y, unsigned char layer) const | ||||
| 	unsigned short glerminal::get(int x, int y, int layer) const | ||||
| 	{ | ||||
| 		if (x < GRID_WIDTH + 2 && y < GRID_HEIGHT + 2 && layer < LAYER_COUNT) | ||||
| 		if (x >= 0 && x < GRID_WIDTH + 2 && y >= 0 && y < GRID_HEIGHT + 2 && layer >= 0 && layer < LAYER_COUNT) | ||||
| 		{ | ||||
| 			return m_cells[x + y * (GRID_WIDTH + 2) + layer * GRID_AREA_2]; | ||||
| 		} | ||||
| @@ -314,18 +314,18 @@ namespace glerminal | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void glerminal::offset(unsigned char x, unsigned char y, unsigned char layer, float x_offset, float y_offset) | ||||
| 	void glerminal::offset(int x, int y, int layer, float x_offset, float y_offset) | ||||
| 	{ | ||||
| 		if (x < GRID_WIDTH + 2 && y < GRID_HEIGHT + 2 && layer < LAYER_COUNT) | ||||
| 		if (x >= 0 && x < GRID_WIDTH + 2 && y >= 0 && y < GRID_HEIGHT + 2 && layer >= 0 && layer < LAYER_COUNT) | ||||
| 		{ | ||||
| 			m_offsets[2 * (x + y * (GRID_WIDTH + 2) + layer * GRID_AREA_2) + 0] = x_offset; | ||||
| 			m_offsets[2 * (x + y * (GRID_WIDTH + 2) + layer * GRID_AREA_2) + 1] = y_offset; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void glerminal::color(unsigned char x, unsigned char y, unsigned char layer, unsigned int color) | ||||
| 	void glerminal::color(int x, int y, int layer, unsigned int color) | ||||
| 	{ | ||||
| 		if (x < GRID_WIDTH + 2 && y < GRID_HEIGHT + 2 && layer < LAYER_COUNT) | ||||
| 		if (x >= 0 && x < GRID_WIDTH + 2 && y >= 0 && y < GRID_HEIGHT + 2 && layer >= 0 && layer < LAYER_COUNT) | ||||
| 		{ | ||||
| 			m_colors[4 * (x + y * (GRID_WIDTH + 2) + layer * GRID_AREA_2) + 0] = (color >>  0) & 0xFF; | ||||
| 			m_colors[4 * (x + y * (GRID_WIDTH + 2) + layer * GRID_AREA_2) + 1] = (color >>  8) & 0xFF; | ||||
| @@ -334,9 +334,12 @@ namespace glerminal | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void glerminal::scale(unsigned char x, unsigned char y, unsigned char layer, float scale) | ||||
| 	void glerminal::scale(int x, int y, int layer, float scale) | ||||
| 	{ | ||||
| 		m_scales[x + y * (GRID_WIDTH + 2) + layer * GRID_AREA_2] = scale; | ||||
| 		if (x >= 0 && x < GRID_WIDTH + 2 && y >= 0 && y < GRID_HEIGHT + 2 && layer >= 0 && layer < LAYER_COUNT) | ||||
| 		{ | ||||
| 			m_scales[x + y * (GRID_WIDTH + 2) + layer * GRID_AREA_2] = scale; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void glerminal::load_atlas(unsigned char w, unsigned char h, const unsigned int* data) | ||||
| @@ -654,6 +657,7 @@ namespace glerminal | ||||
|  | ||||
| 		// setup uniforms | ||||
| 		glUseProgram(m_program); | ||||
| 		glUniform1f(glGetUniformLocation(m_program, CELL_SIZE_UNIFORM_NAME), CELL_SIZE); | ||||
| 		glUniform4f(glGetUniformLocation(m_program, GRID_SIZE_UNIFORM_NAME), GRID_WIDTH + 2, GRID_AREA_2, 1.0f / GRID_WIDTH, 1.0f / GRID_HEIGHT); | ||||
| 		glUniform1i(glGetUniformLocation(m_program, ATLAS_WIDTH_UNIFORM_NAME), MAX_SPRITES_ROW); | ||||
|  | ||||
| @@ -735,7 +739,6 @@ namespace glerminal | ||||
| 		update_sprites(); | ||||
|  | ||||
| 		glBindTextureUnit(2, m_sprites_texture); | ||||
| 		const auto err = glGetError(); | ||||
|  | ||||
| 		// -- setup framebuffer -- | ||||
| 		glGenFramebuffers(1, &m_framebuffer); | ||||
| @@ -908,39 +911,39 @@ void glerminal_flush() | ||||
| 	GLERMINAL_G->flush(); | ||||
| } | ||||
|  | ||||
| void glerminal_set(unsigned char x, unsigned char y, unsigned char layer, unsigned short sprite) | ||||
| void glerminal_set(int x, int y, int layer, unsigned short sprite) | ||||
| { | ||||
| 	if (!GLERMINAL_G) { return; } | ||||
|  | ||||
| 	GLERMINAL_G->set(x, y, layer, sprite); | ||||
| 	GLERMINAL_G->set(x + 1, y + 1, layer, sprite); | ||||
| } | ||||
|  | ||||
| unsigned short glerminal_get(unsigned char x, unsigned char y, unsigned short layer) | ||||
| unsigned short glerminal_get(int x, int y, int layer) | ||||
| { | ||||
| 	if (!GLERMINAL_G) { return 0; } | ||||
|  | ||||
| 	return GLERMINAL_G->get(x, y, layer); | ||||
| 	return GLERMINAL_G->get(x + 1, y + 1, layer); | ||||
| } | ||||
|  | ||||
| void glerminal_offset(unsigned char x, unsigned char y, unsigned char layer, float x_offset, float y_offset) | ||||
| void glerminal_offset(int x, int y, int layer, float x_offset, float y_offset) | ||||
| { | ||||
| 	if (!GLERMINAL_G) { return; } | ||||
|  | ||||
| 	GLERMINAL_G->offset(x, y, layer, x_offset, y_offset); | ||||
| 	GLERMINAL_G->offset(x + 1, y + 1, layer, x_offset, y_offset); | ||||
| } | ||||
|  | ||||
| void glerminal_color(unsigned char x, unsigned char y, unsigned char layer, unsigned int color) | ||||
| void glerminal_color(int x, int y, int layer, unsigned int color) | ||||
| { | ||||
| 	if (!GLERMINAL_G) { return; } | ||||
|  | ||||
| 	GLERMINAL_G->color(x, y, layer, color); | ||||
| 	GLERMINAL_G->color(x + 1, y + 1, layer, color); | ||||
| } | ||||
|  | ||||
| void glerminal_scale(unsigned char x, unsigned char y, unsigned char layer, float scale) | ||||
| void glerminal_scale(int x, int y, int layer, float scale) | ||||
| { | ||||
| 	if (!GLERMINAL_G) { return; } | ||||
|  | ||||
| 	GLERMINAL_G->scale(x, y, layer, scale); | ||||
| 	GLERMINAL_G->scale(x + 1, y + 1, layer, scale); | ||||
| } | ||||
|  | ||||
| int glerminal_load_sprites_file(const char* filename) | ||||
| @@ -987,4 +990,4 @@ void glerminal_sound(const char* name) | ||||
| 	if (!GLERMINAL_G) { return; } | ||||
|  | ||||
| 	GLERMINAL_G->play_sound(name); | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -17,7 +17,7 @@ target_include_directories(test-common | ||||
| 		${CMAKE_SOURCE_DIR}/source | ||||
| ) | ||||
|  | ||||
| target_link_libraries(test-common PRIVATE glerminallib) | ||||
| target_link_libraries(test-common PRIVATE glerminal) | ||||
|  | ||||
| file(GLOB_RECURSE | ||||
| 	TEST_RESOURCES | ||||
| @@ -52,5 +52,5 @@ list(TRANSFORM TEST_RESOURCES PREPEND ${CMAKE_CURRENT_BINARY_DIR}/) | ||||
| foreach(SOURCE_FILE ${TEST_SOURCES}) | ||||
| 	get_filename_component(SOURCE_FILENAME ${SOURCE_FILE} NAME_WLE) | ||||
| 	add_executable(test-${SOURCE_FILENAME} WIN32 ${SOURCE_FILE} ${TEST_RESOURCES}) | ||||
| 	target_link_libraries(test-${SOURCE_FILENAME} PRIVATE glerminallib test-common) | ||||
| endforeach() | ||||
| 	target_link_libraries(test-${SOURCE_FILENAME} PRIVATE glerminal test-common) | ||||
| endforeach() | ||||
|   | ||||
| @@ -15,7 +15,7 @@ namespace | ||||
| 		 | ||||
| 		for (int i = 0; i < GRID_HEIGHT; i++) | ||||
| 		{ | ||||
| 			glerminal_set(i + 1, i + 1, 0, 1); | ||||
| 			glerminal_set(i, i, 0, 1); | ||||
| 		} | ||||
|  | ||||
| 		glerminal_flush(); | ||||
|   | ||||
| @@ -8,18 +8,18 @@ | ||||
|  | ||||
| namespace | ||||
| { | ||||
| 	unsigned char pixels[(GRID_WIDTH * CELL_SCALE * 8) * (GRID_HEIGHT * CELL_SCALE * 8) * 3]; | ||||
| 	unsigned char pixels[(GRID_WIDTH * CELL_SIZE * CELL_SCALE) * (GRID_HEIGHT * CELL_SIZE * CELL_SCALE) * 3]; | ||||
| } | ||||
|  | ||||
| void glerminal_test_save_image() | ||||
| { | ||||
| 	// -- DIRTY HACK -- | ||||
| 	//  | ||||
| 	// | ||||
| 	// GL_TEXTURE_2D is not rebound after setting up screen framebuffer | ||||
| 	// This code will break if this behavior changes | ||||
|  | ||||
| 	glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels); | ||||
|  | ||||
| 	stbi_flip_vertically_on_write(true); | ||||
| 	stbi_write_png("image.png", GRID_WIDTH * CELL_SCALE * 8, GRID_HEIGHT * CELL_SCALE * 8, 3, pixels, GRID_WIDTH * CELL_SCALE * 8 * 3); | ||||
| } | ||||
| 	stbi_write_png("image.png", GRID_WIDTH * CELL_SIZE * CELL_SCALE, GRID_HEIGHT * CELL_SIZE * CELL_SCALE, 3, pixels, GRID_WIDTH * CELL_SIZE * CELL_SCALE * 3); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user