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>
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)
{
glerminal_run(glerminal_flush);
glerminal_run(init, mainloop);
}

View File

@ -12,7 +12,8 @@ enum
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
{
@ -20,10 +21,10 @@ typedef struct glerminal_sprite
} glerminal_sprite;
/**
* @brief Run the application's mainloop
* @brief Call init once, then run the application's mainloop
* @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
@ -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);
/**
* @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
}
#endif

View File

@ -25,7 +25,7 @@ namespace glerminal
class glerminal
{
public:
glerminal(glerminal_main_cb main);
glerminal(glerminal_init_cb init, glerminal_main_cb main);
~glerminal();
glerminal(const glerminal&) = delete;
@ -41,6 +41,9 @@ namespace glerminal
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;
void update_sprite(unsigned char id, glerminal_sprite sprite);
void update_palette_color(unsigned char id, unsigned int color);
private:
GLFWwindow* m_window;

View File

@ -89,7 +89,7 @@ namespace
"void main()\n"
"{\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 =
@ -111,7 +111,7 @@ namespace
namespace glerminal
{
glerminal::glerminal(glerminal_main_cb main) :
glerminal::glerminal(glerminal_init_cb init, glerminal_main_cb main) :
m_main(main),
m_cells{ },
m_sprites{ },
@ -126,6 +126,11 @@ namespace glerminal
}
// unsure if this should be an error
if (!init)
{
throw std::runtime_error("No init callback provided.");
}
if (!m_main)
{
throw std::runtime_error("No main callback provided.");
@ -135,6 +140,8 @@ namespace glerminal
init_gl();
GLERMINAL_G = this;
init();
}
glerminal::~glerminal()
@ -147,17 +154,25 @@ namespace glerminal
void glerminal::run()
{
float last = glfwGetTime();
while (!glfwWindowShouldClose(m_window))
{
glfwPollEvents();
m_main();
const float current = glfwGetTime();
m_main(current - last);
last = current;
}
}
void glerminal::flush()
{
// use dirty flag later
glNamedBufferData(m_instance_vbo, sizeof(m_cells), m_cells, GL_STREAM_DRAW);
update_sprites();
update_palette();
glUseProgram(m_program);
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()
{
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
{
glerminal::glerminal(main).run();
glerminal::glerminal(init, main).run();
}
catch (const std::runtime_error& e)
{
@ -569,3 +601,17 @@ unsigned char glerminal_get(unsigned char x, unsigned char y, unsigned char laye
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);
}