Add audio; update Lua color API
This commit is contained in:
		
							parent
							
								
									9d88ebbb3b
								
							
						
					
					
						commit
						6663804c88
					
				| @ -28,6 +28,9 @@ add_library(glerminallib STATIC | |||||||
| 	source/glad/glad.h | 	source/glad/glad.h | ||||||
| 	source/KHR/khrplatform.h | 	source/KHR/khrplatform.h | ||||||
| 	source/glad.c | 	source/glad.c | ||||||
|  | 
 | ||||||
|  | 	source/miniaudio.h | ||||||
|  | 	source/miniaudio.c | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| set_target_properties(glerminallib | set_target_properties(glerminallib | ||||||
|  | |||||||
| @ -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) |  * @param layer layer of the cell in the range [0, LAYER_COUNT) | ||||||
|  * @return sprite index currently assigned to the cell |  * @return sprite index currently assigned to the cell | ||||||
|  */ |  */ | ||||||
| unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned short layer); | unsigned short glerminal_get(unsigned char x, unsigned char y, unsigned short layer); | ||||||
| /**
 | /**
 | ||||||
|  * @brief Set a cell's offset |  * @brief Set a cell's offset | ||||||
|  * @param x position of the cell in the range [0, GRID_WIDTH) |  * @param x position of the cell in the range [0, GRID_WIDTH) | ||||||
| @ -92,6 +92,8 @@ int glerminal_load_sprites_file(const char* filename); | |||||||
|  */ |  */ | ||||||
| int glerminal_load_sprites_buffer(unsigned char width, unsigned char height, const unsigned int* buffer); | int glerminal_load_sprites_buffer(unsigned char width, unsigned char height, const unsigned int* buffer); | ||||||
| 
 | 
 | ||||||
|  | void glerminal_sound(const char* name); | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -74,7 +74,30 @@ namespace | |||||||
| 		const unsigned char x = luaL_checkinteger(L, 1); | 		const unsigned char x = luaL_checkinteger(L, 1); | ||||||
| 		const unsigned char y = luaL_checkinteger(L, 2); | 		const unsigned char y = luaL_checkinteger(L, 2); | ||||||
| 		const unsigned char layer = luaL_checkinteger(L, 3) - 1; | 		const unsigned char layer = luaL_checkinteger(L, 3) - 1; | ||||||
| 		const unsigned int color = luaL_checkinteger(L, 4); | 		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); | 		glerminal_color(x, y, layer, color); | ||||||
| 
 | 
 | ||||||
| 		return 0; | 		return 0; | ||||||
| @ -99,6 +122,14 @@ namespace | |||||||
| 		return 1; | 		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[] = | 	const luaL_Reg lglerminal_methods[] = | ||||||
| 	{ | 	{ | ||||||
| 		{ "quit",    lglerminal_quit }, | 		{ "quit",    lglerminal_quit }, | ||||||
| @ -109,6 +140,7 @@ namespace | |||||||
| 		{ "tint",    lglerminal_layer_color }, | 		{ "tint",    lglerminal_layer_color }, | ||||||
| 		{ "scale",   lglerminal_layer_scale }, | 		{ "scale",   lglerminal_layer_scale }, | ||||||
| 		{ "sprites", lglerminal_load_sprites_file }, | 		{ "sprites", lglerminal_load_sprites_file }, | ||||||
|  | 		{ "sound",   lglerminal_play_sound }, | ||||||
| 		{ nullptr,   nullptr } | 		{ nullptr,   nullptr } | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #define GLERMINAL_PRIVATE_H | #define GLERMINAL_PRIVATE_H | ||||||
| 
 | 
 | ||||||
| #include "glerminal.h" | #include "glerminal.h" | ||||||
|  | #include "miniaudio.h" | ||||||
| 
 | 
 | ||||||
| #include <stb_image.h> | #include <stb_image.h> | ||||||
| #include <glad/glad.h> | #include <glad/glad.h> | ||||||
| @ -10,6 +11,8 @@ | |||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <fstream> | #include <fstream> | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
|  | #include <map> | ||||||
|  | #include <string> | ||||||
| 
 | 
 | ||||||
| namespace glerminal | namespace glerminal | ||||||
| { | { | ||||||
| @ -23,6 +26,7 @@ namespace glerminal | |||||||
| 	constexpr unsigned int GRID_AREA = GRID_WIDTH * GRID_HEIGHT; | 	constexpr unsigned int GRID_AREA = GRID_WIDTH * GRID_HEIGHT; | ||||||
| 	constexpr unsigned int SCREEN_WIDTH = GRID_WIDTH * CELL_SIZE * CELL_SCALE; | 	constexpr unsigned int SCREEN_WIDTH = GRID_WIDTH * CELL_SIZE * CELL_SCALE; | ||||||
| 	constexpr unsigned int SCREEN_HEIGHT = GRID_HEIGHT * CELL_SIZE * CELL_SCALE; | 	constexpr unsigned int SCREEN_HEIGHT = GRID_HEIGHT * CELL_SIZE * CELL_SCALE; | ||||||
|  | 	constexpr unsigned int SOUND_CHANNELS = 8; | ||||||
| 
 | 
 | ||||||
| 	constexpr unsigned int GRID_AREA_2 = (GRID_WIDTH + 2) * (GRID_HEIGHT + 2); | 	constexpr unsigned int GRID_AREA_2 = (GRID_WIDTH + 2) * (GRID_HEIGHT + 2); | ||||||
| 
 | 
 | ||||||
| @ -49,6 +53,8 @@ namespace glerminal | |||||||
| 		void color(unsigned char x, unsigned char y, unsigned char layer, unsigned int color); | 		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 scale(unsigned char x, unsigned char y, unsigned char layer, float scale); | ||||||
| 		void load_atlas(unsigned char w, unsigned char h, const unsigned int* data); | 		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); | ||||||
| 
 | 
 | ||||||
| 	private: | 	private: | ||||||
| 		// glfw data
 | 		// glfw data
 | ||||||
| @ -87,6 +93,9 @@ namespace glerminal | |||||||
| 		glerminal_mousemoved_cb m_mousemoved; | 		glerminal_mousemoved_cb m_mousemoved; | ||||||
| 		glerminal_mousepress_cb m_mousepressed, m_mousereleased; | 		glerminal_mousepress_cb m_mousepressed, m_mousereleased; | ||||||
| 
 | 
 | ||||||
|  | 		ma_engine m_audio_engine; | ||||||
|  | 		std::map<std::string, ma_sound> m_sounds; | ||||||
|  | 
 | ||||||
| #ifdef GLERMINAL_OPENGL_DEBUG_CONTEXT | #ifdef GLERMINAL_OPENGL_DEBUG_CONTEXT | ||||||
| 		mutable std::ofstream m_log; | 		mutable std::ofstream m_log; | ||||||
| #endif | #endif | ||||||
| @ -95,9 +104,13 @@ namespace glerminal | |||||||
| 		void init_glfw(); | 		void init_glfw(); | ||||||
| 		void init_gl(); | 		void init_gl(); | ||||||
| 
 | 
 | ||||||
|  | 		void init_audio(); | ||||||
|  | 
 | ||||||
| 		void deinit_glfw(); | 		void deinit_glfw(); | ||||||
| 		void deinit_gl(); | 		void deinit_gl(); | ||||||
| 
 | 
 | ||||||
|  | 		void deinit_audio(); | ||||||
|  | 
 | ||||||
| 		void update_sprites(); | 		void update_sprites(); | ||||||
| 		void update_colors(); | 		void update_colors(); | ||||||
| 		void update_scales(); | 		void update_scales(); | ||||||
|  | |||||||
| @ -229,6 +229,7 @@ namespace glerminal | |||||||
| 
 | 
 | ||||||
| 		init_glfw(); | 		init_glfw(); | ||||||
| 		init_gl(); | 		init_gl(); | ||||||
|  | 		init_audio(); | ||||||
| 
 | 
 | ||||||
| 		GLERMINAL_G = this; | 		GLERMINAL_G = this; | ||||||
| 
 | 
 | ||||||
| @ -237,6 +238,7 @@ namespace glerminal | |||||||
| 
 | 
 | ||||||
| 	glerminal::~glerminal() | 	glerminal::~glerminal() | ||||||
| 	{ | 	{ | ||||||
|  | 		deinit_audio(); | ||||||
| 		deinit_gl(); | 		deinit_gl(); | ||||||
| 		deinit_glfw(); | 		deinit_glfw(); | ||||||
| 
 | 
 | ||||||
| @ -363,6 +365,39 @@ namespace glerminal | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	bool glerminal::load_sound(const char* name) | ||||||
|  | 	{ | ||||||
|  | 		if (m_sounds.find(name) == m_sounds.end()) | ||||||
|  | 		{ | ||||||
|  | 			ma_sound& ref = m_sounds[name]; | ||||||
|  | 			const ma_result result = ma_sound_init_from_file( | ||||||
|  | 				&m_audio_engine, | ||||||
|  | 				name, | ||||||
|  | 				MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_NO_SPATIALIZATION, | ||||||
|  | 				nullptr, | ||||||
|  | 				nullptr, | ||||||
|  | 				&ref | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			if (result != MA_SUCCESS) | ||||||
|  | 			{ | ||||||
|  | 				return false; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void glerminal::play_sound(const char* name) | ||||||
|  | 	{ | ||||||
|  | 		load_sound(name); | ||||||
|  | 		const ma_result result = ma_engine_play_sound(&m_audio_engine, name, nullptr); | ||||||
|  | 		if (result != MA_SUCCESS) | ||||||
|  | 		{ | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	void glerminal::init_glfw() | 	void glerminal::init_glfw() | ||||||
| 	{ | 	{ | ||||||
| 		glfwInit(); | 		glfwInit(); | ||||||
| @ -743,6 +778,18 @@ namespace glerminal | |||||||
| 		glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_screen_framebuffer_backing_texture, 0); | 		glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_screen_framebuffer_backing_texture, 0); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void glerminal::init_audio() | ||||||
|  | 	{ | ||||||
|  | 		const ma_result result = ma_engine_init(nullptr, &m_audio_engine); | ||||||
|  | 
 | ||||||
|  | 		if (result != MA_SUCCESS) | ||||||
|  | 		{ | ||||||
|  | 			throw std::runtime_error("Failed to initialize audio engine"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ma_engine_set_volume(&m_audio_engine, 1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	void glerminal::deinit_glfw() | 	void glerminal::deinit_glfw() | ||||||
| 	{ | 	{ | ||||||
| 		glfwDestroyWindow(m_window); | 		glfwDestroyWindow(m_window); | ||||||
| @ -767,6 +814,15 @@ namespace glerminal | |||||||
| 		glDeleteProgram(m_program); | 		glDeleteProgram(m_program); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void glerminal::deinit_audio() | ||||||
|  | 	{ | ||||||
|  | 		for (auto& elem : m_sounds) | ||||||
|  | 		{ | ||||||
|  | 			ma_sound_uninit(&elem.second); | ||||||
|  | 		} | ||||||
|  | 		ma_engine_uninit(&m_audio_engine); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	void glerminal::update_sprites() | 	void glerminal::update_sprites() | ||||||
| 	{ | 	{ | ||||||
| 		glTextureSubImage2D(m_sprites_texture, 0, 0, 0, (CELL_SIZE + 2) * MAX_SPRITES_ROW, (CELL_SIZE + 2) * MAX_SPRITES_ROW, GL_RGBA, GL_UNSIGNED_BYTE, m_sprites); | 		glTextureSubImage2D(m_sprites_texture, 0, 0, 0, (CELL_SIZE + 2) * MAX_SPRITES_ROW, (CELL_SIZE + 2) * MAX_SPRITES_ROW, GL_RGBA, GL_UNSIGNED_BYTE, m_sprites); | ||||||
| @ -859,7 +915,7 @@ void glerminal_set(unsigned char x, unsigned char y, unsigned char layer, unsign | |||||||
| 	GLERMINAL_G->set(x, y, layer, sprite); | 	GLERMINAL_G->set(x, y, layer, sprite); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned short layer) | unsigned short glerminal_get(unsigned char x, unsigned char y, unsigned short layer) | ||||||
| { | { | ||||||
| 	if (!GLERMINAL_G) { return 0; } | 	if (!GLERMINAL_G) { return 0; } | ||||||
| 
 | 
 | ||||||
| @ -925,3 +981,10 @@ int glerminal_load_sprites_buffer(unsigned char width, unsigned char height, con | |||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void glerminal_sound(const char* name) | ||||||
|  | { | ||||||
|  | 	if (!GLERMINAL_G) { return; } | ||||||
|  | 
 | ||||||
|  | 	GLERMINAL_G->play_sound(name); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								source/miniaudio.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								source/miniaudio.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #ifndef GLERMINAL_MINIAUDIO_H | ||||||
|  | #define GLERMINAL_MINIAUDIO_H | ||||||
|  | 
 | ||||||
|  | #define MINIAUDIO_IMPLEMENTATION | ||||||
|  | #include "miniaudio.h" | ||||||
|  | 
 | ||||||
|  | #endif//GLERMINAL_MINIAUDIO_H
 | ||||||
							
								
								
									
										92621
									
								
								source/miniaudio.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92621
									
								
								source/miniaudio.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 shylie
						shylie