Initial public api version

This commit is contained in:
Shylie 2024-05-14 16:46:30 -05:00
parent 06c7aa9eb5
commit a32897d5d4
4 changed files with 99 additions and 10 deletions

View File

@ -1,6 +1,31 @@
#include <glerminal.h> #include <glerminal.h>
namespace
{
void init()
{
glerminal_update_palette(0, 0xFF0000FF);
glerminal_update_palette(1, 0x00FF00FF);
glerminal_update_sprite(0, {
1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0
});
}
void mainloop(float dt)
{
glerminal_flush();
}
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
glerminal_run(glerminal_flush); glerminal_run(init, mainloop);
} }

View File

@ -12,7 +12,8 @@ enum
GLERMINAL_CELL_AREA = GLERMINAL_CELL_SIZE * GLERMINAL_CELL_SIZE GLERMINAL_CELL_AREA = GLERMINAL_CELL_SIZE * GLERMINAL_CELL_SIZE
}; };
typedef void (*glerminal_main_cb)(); typedef void (*glerminal_init_cb)();
typedef void (*glerminal_main_cb)(float dt);
typedef struct glerminal_sprite typedef struct glerminal_sprite
{ {
@ -20,10 +21,10 @@ typedef struct glerminal_sprite
} glerminal_sprite; } glerminal_sprite;
/** /**
* @brief Run the application's mainloop * @brief Call init once, then run the application's mainloop
* @param main main calllback * @param main main calllback
*/ */
void glerminal_run(glerminal_main_cb main); void glerminal_run(glerminal_init_cb init, glerminal_main_cb main);
/** /**
* @brief Update the displayed screen contents to the current state of the library * @brief Update the displayed screen contents to the current state of the library
@ -47,6 +48,20 @@ void glerminal_set(unsigned char x, unsigned char y, unsigned char layer, unsign
*/ */
unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned char layer); unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned char layer);
/**
* @brief Upload sprite to the given sprite ID
* @param id The ID of the sprite to change
* @param sprite The new sprite
*/
void glerminal_update_sprite(unsigned char id, glerminal_sprite sprite);
/**
* @brief Update palette color at index ID
* @param id Palette index to update
* @param color New color
*/
void glerminal_update_palette(unsigned char id, unsigned int color);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -25,7 +25,7 @@ namespace glerminal
class glerminal class glerminal
{ {
public: public:
glerminal(glerminal_main_cb main); glerminal(glerminal_init_cb init, glerminal_main_cb main);
~glerminal(); ~glerminal();
glerminal(const glerminal&) = delete; glerminal(const glerminal&) = delete;
@ -41,6 +41,9 @@ namespace glerminal
void set(unsigned char x, unsigned char y, unsigned char layer, unsigned char sprite); void set(unsigned char x, unsigned char y, unsigned char layer, unsigned char sprite);
unsigned char get(unsigned char x, unsigned char y, unsigned char layer) const; unsigned char get(unsigned char x, unsigned char y, unsigned char layer) const;
void update_sprite(unsigned char id, glerminal_sprite sprite);
void update_palette_color(unsigned char id, unsigned int color);
private: private:
GLFWwindow* m_window; GLFWwindow* m_window;

View File

@ -89,7 +89,7 @@ namespace
"void main()\n" "void main()\n"
"{\n" "{\n"
" gl_Position = vec4(position * 2 + 1, 0, 1);\n" " gl_Position = vec4(position * 2 + 1, 0, 1);\n"
" texcoord = -position;\n" " texcoord = vec2(position.x + 1, -position.y);\n"
"}"; "}";
constexpr char* SCREEN_FRAGMENT_SHADER_SOURCE = constexpr char* SCREEN_FRAGMENT_SHADER_SOURCE =
@ -111,7 +111,7 @@ namespace
namespace glerminal namespace glerminal
{ {
glerminal::glerminal(glerminal_main_cb main) : glerminal::glerminal(glerminal_init_cb init, glerminal_main_cb main) :
m_main(main), m_main(main),
m_cells{ }, m_cells{ },
m_sprites{ }, m_sprites{ },
@ -126,6 +126,11 @@ namespace glerminal
} }
// unsure if this should be an error // unsure if this should be an error
if (!init)
{
throw std::runtime_error("No init callback provided.");
}
if (!m_main) if (!m_main)
{ {
throw std::runtime_error("No main callback provided."); throw std::runtime_error("No main callback provided.");
@ -135,6 +140,8 @@ namespace glerminal
init_gl(); init_gl();
GLERMINAL_G = this; GLERMINAL_G = this;
init();
} }
glerminal::~glerminal() glerminal::~glerminal()
@ -147,17 +154,25 @@ namespace glerminal
void glerminal::run() void glerminal::run()
{ {
float last = glfwGetTime();
while (!glfwWindowShouldClose(m_window)) while (!glfwWindowShouldClose(m_window))
{ {
glfwPollEvents(); glfwPollEvents();
m_main(); const float current = glfwGetTime();
m_main(current - last);
last = current;
} }
} }
void glerminal::flush() void glerminal::flush()
{ {
// use dirty flag later
glNamedBufferData(m_instance_vbo, sizeof(m_cells), m_cells, GL_STREAM_DRAW); glNamedBufferData(m_instance_vbo, sizeof(m_cells), m_cells, GL_STREAM_DRAW);
update_sprites();
update_palette();
glUseProgram(m_program); glUseProgram(m_program);
glBindTexture(GL_TEXTURE_2D_ARRAY, m_sprites_texture); glBindTexture(GL_TEXTURE_2D_ARRAY, m_sprites_texture);
@ -196,6 +211,23 @@ namespace glerminal
} }
} }
void glerminal::update_sprite(unsigned char id, glerminal_sprite sprite)
{
// does this work?
reinterpret_cast<glerminal_sprite*>(m_sprites)[id] = sprite;
}
void glerminal::update_palette_color(unsigned char id, unsigned int color)
{
if (id < 16)
{
m_palette[4 * id + 0] = ((color >> 24) & 0xFF) / 255.0f;
m_palette[4 * id + 1] = ((color >> 16) & 0xFF) / 255.0f;
m_palette[4 * id + 2] = ((color >> 8) & 0xFF) / 255.0f;
m_palette[4 * id + 3] = ((color >> 0) & 0xFF) / 255.0f;
}
}
void glerminal::init_glfw() void glerminal::init_glfw()
{ {
glfwInit(); glfwInit();
@ -538,11 +570,11 @@ namespace glerminal
} }
} }
void glerminal_run(glerminal_main_cb main) void glerminal_run(glerminal_init_cb init, glerminal_main_cb main)
{ {
try try
{ {
glerminal::glerminal(main).run(); glerminal::glerminal(init, main).run();
} }
catch (const std::runtime_error& e) catch (const std::runtime_error& e)
{ {
@ -568,4 +600,18 @@ unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned char laye
if (!GLERMINAL_G) { return 0; } if (!GLERMINAL_G) { return 0; }
return GLERMINAL_G->get(x, y, layer); return GLERMINAL_G->get(x, y, layer);
}
void glerminal_update_sprite(unsigned char id, glerminal_sprite sprite)
{
if (!GLERMINAL_G) { return; }
GLERMINAL_G->update_sprite(id, sprite);
}
void glerminal_update_palette(unsigned char id, unsigned int color)
{
if (!GLERMINAL_G) { return; }
GLERMINAL_G->update_palette_color(id, color);
} }