179 lines
4.5 KiB
C
179 lines
4.5 KiB
C
|
#include <libreborn/libreborn.h>
|
||
|
|
||
|
#include "state.h"
|
||
|
#include "passthrough.h"
|
||
|
|
||
|
// GL State
|
||
|
gl_state_t gl_state = {
|
||
|
.color = {
|
||
|
.red = 1,
|
||
|
.green = 1,
|
||
|
.blue = 1,
|
||
|
.alpha = 1
|
||
|
},
|
||
|
.matrix_stacks = {
|
||
|
.mode = GL_MODELVIEW
|
||
|
},
|
||
|
.alpha_test = 0,
|
||
|
.texture_2d = 0,
|
||
|
.fog = {
|
||
|
.enabled = 0,
|
||
|
.mode = GL_LINEAR,
|
||
|
.color = {0, 0, 0, 0},
|
||
|
.start = 0,
|
||
|
.end = 1
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Change Color
|
||
|
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
|
||
|
gl_state.color.red = red;
|
||
|
gl_state.color.green = green;
|
||
|
gl_state.color.blue = blue;
|
||
|
gl_state.color.alpha = alpha;
|
||
|
}
|
||
|
|
||
|
// Array Pointer Storage
|
||
|
#define ARRAY_POINTER_FUNC(func, name) \
|
||
|
void func(GLint size, GLenum type, GLsizei stride, const void *pointer) { \
|
||
|
gl_state.array_pointers.name.size = size; \
|
||
|
gl_state.array_pointers.name.type = type; \
|
||
|
gl_state.array_pointers.name.stride = stride; \
|
||
|
gl_state.array_pointers.name.pointer = pointer; \
|
||
|
}
|
||
|
ARRAY_POINTER_FUNC(glVertexPointer, vertex)
|
||
|
ARRAY_POINTER_FUNC(glColorPointer, color)
|
||
|
ARRAY_POINTER_FUNC(glTexCoordPointer, tex_coord)
|
||
|
static array_pointer_t *get_array_pointer(GLenum array) {
|
||
|
switch (array) {
|
||
|
case GL_VERTEX_ARRAY: {
|
||
|
return &gl_state.array_pointers.vertex;
|
||
|
}
|
||
|
case GL_COLOR_ARRAY: {
|
||
|
return &gl_state.array_pointers.color;
|
||
|
}
|
||
|
case GL_TEXTURE_COORD_ARRAY: {
|
||
|
return &gl_state.array_pointers.tex_coord;
|
||
|
}
|
||
|
default: {
|
||
|
ERR("Unsupported Array Pointer: %i", array);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
void glEnableClientState(GLenum array) {
|
||
|
get_array_pointer(array)->enabled = 1;
|
||
|
}
|
||
|
void glDisableClientState(GLenum array) {
|
||
|
get_array_pointer(array)->enabled = 0;
|
||
|
}
|
||
|
|
||
|
// Enable/Disable State
|
||
|
GL_FUNC(glEnable, void, (GLenum cap));
|
||
|
void glEnable(GLenum cap) {
|
||
|
switch (cap) {
|
||
|
case GL_ALPHA_TEST: {
|
||
|
gl_state.alpha_test = 1;
|
||
|
break;
|
||
|
}
|
||
|
case GL_TEXTURE_2D: {
|
||
|
gl_state.texture_2d = 1;
|
||
|
break;
|
||
|
}
|
||
|
case GL_COLOR_MATERIAL: {
|
||
|
// Ignore
|
||
|
break;
|
||
|
}
|
||
|
case GL_FOG: {
|
||
|
gl_state.fog.enabled = 1;
|
||
|
break;
|
||
|
}
|
||
|
default: {
|
||
|
real_glEnable()(cap);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
GL_FUNC(glDisable, void, (GLenum cap));
|
||
|
void glDisable(GLenum cap) {
|
||
|
switch (cap) {
|
||
|
case GL_ALPHA_TEST: {
|
||
|
gl_state.alpha_test = 0;
|
||
|
break;
|
||
|
}
|
||
|
case GL_TEXTURE_2D: {
|
||
|
gl_state.texture_2d = 0;
|
||
|
break;
|
||
|
}
|
||
|
case GL_COLOR_MATERIAL: {
|
||
|
// Ignore
|
||
|
break;
|
||
|
}
|
||
|
case GL_FOG: {
|
||
|
gl_state.fog.enabled = 0;
|
||
|
break;
|
||
|
}
|
||
|
default: {
|
||
|
real_glDisable()(cap);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
void glAlphaFunc(GLenum func, GLclampf ref) {
|
||
|
if (func != GL_GREATER && ref != 0.1f) {
|
||
|
ERR("Unsupported Alpha Function");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Fog
|
||
|
#define UNSUPPORTED_FOG() ERR("Unsupported Fog Configuration")
|
||
|
void glFogfv(GLenum pname, const GLfloat *params) {
|
||
|
if (pname == GL_FOG_COLOR) {
|
||
|
memcpy((void *) gl_state.fog.color, params, sizeof (gl_state.fog.color));
|
||
|
} else {
|
||
|
UNSUPPORTED_FOG();
|
||
|
}
|
||
|
}
|
||
|
void glFogx(GLenum pname, GLfixed param) {
|
||
|
if (pname == GL_FOG_MODE && (param == GL_LINEAR || param == GL_EXP)) {
|
||
|
gl_state.fog.mode = param;
|
||
|
} else {
|
||
|
UNSUPPORTED_FOG();
|
||
|
}
|
||
|
}
|
||
|
void glFogf(GLenum pname, GLfloat param) {
|
||
|
switch (pname) {
|
||
|
case GL_FOG_DENSITY:
|
||
|
case GL_FOG_START: {
|
||
|
gl_state.fog.start = param;
|
||
|
break;
|
||
|
}
|
||
|
case GL_FOG_END: {
|
||
|
gl_state.fog.end = param;
|
||
|
break;
|
||
|
}
|
||
|
default: {
|
||
|
UNSUPPORTED_FOG();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Get Matrix Data
|
||
|
GL_FUNC(glGetFloatv, void, (GLenum pname, GLfloat *params));
|
||
|
void glGetFloatv(GLenum pname, GLfloat *params) {
|
||
|
switch (pname) {
|
||
|
case GL_MODELVIEW_MATRIX: {
|
||
|
memcpy((void *) params, gl_state.matrix_stacks.model_view.stack[gl_state.matrix_stacks.model_view.i].data, MATRIX_DATA_SIZE);
|
||
|
break;
|
||
|
}
|
||
|
case GL_PROJECTION_MATRIX: {
|
||
|
memcpy((void *) params, gl_state.matrix_stacks.projection.stack[gl_state.matrix_stacks.projection.i].data, MATRIX_DATA_SIZE);
|
||
|
break;
|
||
|
}
|
||
|
default: {
|
||
|
real_glGetFloatv()(pname, params);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|