2017-12-08 22:12:31 -06:00
|
|
|
/*
|
|
|
|
* vm_screen.c
|
|
|
|
*
|
|
|
|
* Functions here support drawing to the virtual machine's "screen";
|
|
|
|
* exactly how that is done is an abstraction to the rest of the
|
|
|
|
* program, which only knows to call the functions here.
|
|
|
|
*/
|
|
|
|
|
2017-12-17 19:09:54 -06:00
|
|
|
#include <stdbool.h>
|
2017-11-21 23:24:51 -06:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "log.h"
|
|
|
|
#include "vm_screen.h"
|
|
|
|
|
2017-12-17 19:22:33 -06:00
|
|
|
/*
|
|
|
|
* Something to help us remember if we've already initialized glew or
|
|
|
|
* not.
|
|
|
|
*/
|
2017-12-17 19:09:54 -06:00
|
|
|
static bool init_glew = false;
|
|
|
|
|
2017-12-17 19:22:33 -06:00
|
|
|
/*
|
|
|
|
* Initialize the glew library, if it is needed -- it may not be.
|
|
|
|
*/
|
2017-12-17 19:09:54 -06:00
|
|
|
static void
|
|
|
|
glew_init()
|
|
|
|
{
|
|
|
|
if (!init_glew) {
|
|
|
|
glewExperimental = GL_TRUE;
|
|
|
|
glewInit();
|
|
|
|
|
|
|
|
init_glew = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-16 22:45:39 -06:00
|
|
|
int
|
|
|
|
vm_screen_init()
|
|
|
|
{
|
|
|
|
if (!glfwInit()) {
|
|
|
|
return ERR_GFXINIT;
|
|
|
|
}
|
|
|
|
|
2017-12-17 19:09:54 -06:00
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
|
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
|
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
|
|
|
|
|
|
|
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
|
|
|
|
2017-12-16 22:45:39 -06:00
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
vm_screen_finish()
|
|
|
|
{
|
|
|
|
glfwTerminate();
|
|
|
|
}
|
|
|
|
|
2017-12-06 21:25:47 -06:00
|
|
|
/*
|
2017-12-17 16:42:05 -06:00
|
|
|
* Return a new screen. We also set the color to black.
|
2017-12-06 21:25:47 -06:00
|
|
|
*/
|
2017-12-17 16:42:05 -06:00
|
|
|
vm_screen *
|
|
|
|
vm_screen_create()
|
2017-11-21 23:24:51 -06:00
|
|
|
{
|
2017-12-17 16:42:05 -06:00
|
|
|
vm_screen *screen;
|
2017-11-21 23:24:51 -06:00
|
|
|
|
2017-12-17 16:42:05 -06:00
|
|
|
screen = (vm_screen *)malloc(sizeof(vm_screen));
|
|
|
|
if (screen == NULL) {
|
|
|
|
log_critical("Failed to allocate vm_screen");
|
2017-11-21 23:24:51 -06:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2017-12-17 16:42:05 -06:00
|
|
|
vm_screen_set_color(screen, 0, 0, 0, 0);
|
|
|
|
return screen;
|
2017-11-21 23:24:51 -06:00
|
|
|
}
|
|
|
|
|
2017-12-16 22:45:39 -06:00
|
|
|
int
|
2017-12-17 16:42:05 -06:00
|
|
|
vm_screen_add_window(vm_screen *screen)
|
2017-12-16 22:45:39 -06:00
|
|
|
{
|
2017-12-17 19:09:54 -06:00
|
|
|
screen->window = glfwCreateWindow(VM_SCREEN_DEFWIDTH,
|
|
|
|
VM_SCREEN_DEFHEIGHT,
|
|
|
|
"erc", NULL, NULL);
|
|
|
|
|
2017-12-17 16:42:05 -06:00
|
|
|
if (screen->window == NULL) {
|
2017-12-16 22:45:39 -06:00
|
|
|
log_critical("Could not create a window");
|
|
|
|
return ERR_GFXINIT;
|
|
|
|
}
|
|
|
|
|
2017-12-17 16:42:05 -06:00
|
|
|
glfwMakeContextCurrent(screen->window);
|
2017-12-16 22:45:39 -06:00
|
|
|
|
2017-12-17 19:09:54 -06:00
|
|
|
// glew can only be initialized _after_ the window is built; if you
|
|
|
|
// do so beforehand, you will be rudely presented with a segfault.
|
|
|
|
glew_init();
|
|
|
|
|
2017-12-16 22:45:39 -06:00
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
2017-12-06 21:25:47 -06:00
|
|
|
/*
|
2017-12-17 16:42:05 -06:00
|
|
|
* Free the contents of a screen.
|
2017-12-06 21:25:47 -06:00
|
|
|
*/
|
2017-12-02 13:05:53 -06:00
|
|
|
void
|
2017-12-17 16:42:05 -06:00
|
|
|
vm_screen_free(vm_screen *screen)
|
2017-12-02 13:05:53 -06:00
|
|
|
{
|
2017-12-17 16:42:05 -06:00
|
|
|
free(screen);
|
2017-12-02 13:05:53 -06:00
|
|
|
}
|
|
|
|
|
2017-12-16 22:45:39 -06:00
|
|
|
bool
|
2017-12-17 16:42:05 -06:00
|
|
|
vm_screen_active(vm_screen *screen)
|
2017-12-16 22:45:39 -06:00
|
|
|
{
|
2017-12-17 16:42:05 -06:00
|
|
|
return !glfwWindowShouldClose(screen->window);
|
2017-12-16 22:45:39 -06:00
|
|
|
}
|
|
|
|
|
2017-12-16 23:38:59 -06:00
|
|
|
void
|
2017-12-17 16:42:05 -06:00
|
|
|
vm_screen_refresh(vm_screen *screen)
|
2017-12-16 23:38:59 -06:00
|
|
|
{
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
2017-12-17 16:42:05 -06:00
|
|
|
glfwSwapBuffers(screen->window);
|
2017-12-16 23:38:59 -06:00
|
|
|
|
|
|
|
glfwPollEvents();
|
|
|
|
}
|
|
|
|
|
2017-12-06 21:25:47 -06:00
|
|
|
/*
|
2017-12-17 16:42:05 -06:00
|
|
|
* Set the color of a screen screen to a given RGBA value.
|
2017-12-06 21:25:47 -06:00
|
|
|
*/
|
2017-11-21 23:24:51 -06:00
|
|
|
void
|
2017-12-17 16:42:05 -06:00
|
|
|
vm_screen_set_color(vm_screen *screen,
|
2017-11-21 23:24:51 -06:00
|
|
|
int red,
|
|
|
|
int green,
|
|
|
|
int blue,
|
|
|
|
int alpha)
|
|
|
|
{
|
2017-12-17 16:42:05 -06:00
|
|
|
screen->color_red = red;
|
|
|
|
screen->color_green = green;
|
|
|
|
screen->color_blue = blue;
|
|
|
|
screen->color_alpha = alpha;
|
2017-11-21 23:24:51 -06:00
|
|
|
}
|
|
|
|
|
2017-12-06 21:25:47 -06:00
|
|
|
/*
|
|
|
|
* Draw a rectangle on the screen at a given x/y position, with a given
|
2017-12-17 16:42:05 -06:00
|
|
|
* set of x/y dimensions, with a given screen.
|
2017-12-06 21:25:47 -06:00
|
|
|
*/
|
2017-11-21 23:24:51 -06:00
|
|
|
void
|
2017-12-17 16:42:05 -06:00
|
|
|
vm_screen_draw_rect(vm_screen *screen,
|
2017-11-21 23:24:51 -06:00
|
|
|
int xpos,
|
|
|
|
int ypos,
|
|
|
|
int xsize,
|
|
|
|
int ysize)
|
|
|
|
{
|
|
|
|
// FIXME: NOOP
|
|
|
|
}
|