Add audio; update Lua color API

This commit is contained in:
shylie 2024-07-17 12:08:58 -04:00
parent 9d88ebbb3b
commit 6663804c88
7 changed files with 92744 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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 }
}; };

View File

@ -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();

View File

@ -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; }
@ -924,4 +980,11 @@ 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
View 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

File diff suppressed because it is too large Load Diff