IGNORE: Merge OVER my own codebase.

This commit is contained in:
Hayden K 2019-03-10 21:09:35 -04:00
parent 5eea65c31f
commit 06ac73d82f
14 changed files with 426 additions and 236 deletions

View File

@ -152,6 +152,15 @@ static inline void markDead(ClipVertex* vert) {
vert->flags = VERTEX_CMD_EOL; vert->flags = VERTEX_CMD_EOL;
} }
#define B000 0
#define B111 7
#define B100 4
#define B010 2
#define B001 1
#define B101 5
#define B011 3
#define B110 6
void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset, uint8_t fladeShade) { void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset, uint8_t fladeShade) {
/* Room for clipping 16 triangles */ /* Room for clipping 16 triangles */
typedef struct { typedef struct {
@ -195,11 +204,11 @@ void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset, uint8_t fladeS
uint8_t visible = ((v1->w > 0) ? 4 : 0) | ((v2->w > 0) ? 2 : 0) | ((v3->w > 0) ? 1 : 0); uint8_t visible = ((v1->w > 0) ? 4 : 0) | ((v2->w > 0) ? 2 : 0) | ((v3->w > 0) ? 1 : 0);
switch(visible) { switch(visible) {
case 0b111: case B111:
/* All visible? Do nothing */ /* All visible? Do nothing */
continue; continue;
break; break;
case 0b000: case B000:
/* /*
It is not possible that this is any trangle except the first It is not possible that this is any trangle except the first
in a strip. That's because: in a strip. That's because:
@ -234,12 +243,12 @@ void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset, uint8_t fladeS
v3->flags = VERTEX_CMD; v3->flags = VERTEX_CMD;
} }
break; break;
case 0b100: case B100:
case 0b010: case B010:
case 0b001: case B001:
case 0b101: case B101:
case 0b011: case B011:
case 0b110: case B110:
/* Store the triangle for clipping */ /* Store the triangle for clipping */
TO_CLIP[CLIP_COUNT].vertex[0] = *v1; TO_CLIP[CLIP_COUNT].vertex[0] = *v1;
TO_CLIP[CLIP_COUNT].vertex[1] = *v2; TO_CLIP[CLIP_COUNT].vertex[1] = *v2;

View File

@ -2,7 +2,8 @@
#define CONFIG_H #define CONFIG_H
#define MAX_TEXTURE_COUNT 1088 //@Todo: or 1088 explain why increased. mrneo240 /* This figure is derived from the needs of Quake 1 */
#define MAX_TEXTURE_COUNT 1088
#endif // CONFIG_H #endif // CONFIG_H

View File

@ -3,6 +3,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include <assert.h>
#include "../include/gl.h" #include "../include/gl.h"
#include "../include/glext.h" #include "../include/glext.h"
@ -449,8 +450,8 @@ static inline PolyBuildFunc _calcBuildFunc(const GLenum type) {
case GL_QUADS: case GL_QUADS:
return &_buildQuad; return &_buildQuad;
break; break;
case GL_POLYGON:
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
case GL_POLYGON:
return &_buildTriangleFan; return &_buildTriangleFan;
break; break;
default: default:
@ -459,7 +460,7 @@ static inline PolyBuildFunc _calcBuildFunc(const GLenum type) {
return &_buildStrip; return &_buildStrip;
} }
#include <assert.h>
static inline void nullFloatParseFunc(GLfloat* out, const GLubyte* in) {} static inline void nullFloatParseFunc(GLfloat* out, const GLubyte* in) {}
static inline void genElementsCommon( static inline void genElementsCommon(
@ -480,8 +481,13 @@ static inline void genElementsCommon(
const FloatParseFunc normalFunc = (doLighting) ? _calcNormalParseFunc() : &nullFloatParseFunc; const FloatParseFunc normalFunc = (doLighting) ? _calcNormalParseFunc() : &nullFloatParseFunc;
const IndexParseFunc indexFunc = _calcParseIndexFunc(type); const IndexParseFunc indexFunc = _calcParseIndexFunc(type);
assert(vertexFunc); assert(vertexFunc);
assert(diffuseFunc); assert(diffuseFunc);
assert(uvFunc);
assert(stFunc);
assert(normalFunc);
assert(indexFunc);
GLsizei i = 0; GLsizei i = 0;
const GLubyte* idx = iptr; const GLubyte* idx = iptr;
@ -548,7 +554,6 @@ static inline void genElementsQuads(
} }
static inline void genElementsTriangleFan( static inline void genElementsTriangleFan(
ClipVertex* output, ClipVertex* output,
GLsizei count, GLsizei count,
const GLubyte* iptr, GLuint istride, GLenum type, const GLubyte* iptr, GLuint istride, GLenum type,
@ -625,6 +630,12 @@ static inline void genArraysCommon(
const FloatParseFunc stFunc = _calcSTParseFunc(); const FloatParseFunc stFunc = _calcSTParseFunc();
const FloatParseFunc normalFunc = _calcNormalParseFunc(); const FloatParseFunc normalFunc = _calcNormalParseFunc();
assert(vertexFunc);
assert(diffuseFunc);
assert(uvFunc);
assert(stFunc);
assert(normalFunc);
GLsizei i = count; GLsizei i = count;
ClipVertex* vertex = output; ClipVertex* vertex = output;
@ -745,6 +756,7 @@ static void genArraysTriangleStrip(
output[count - 1].flags = PVR_CMD_VERTEX_EOL; output[count - 1].flags = PVR_CMD_VERTEX_EOL;
} }
#define MAX_POLYGON_SIZE 32
static ClipVertex buffer[MAX_POLYGON_SIZE]; static ClipVertex buffer[MAX_POLYGON_SIZE];
static void genArraysTriangleFan( static void genArraysTriangleFan(
@ -757,17 +769,14 @@ static void genArraysTriangleFan(
const GLubyte* nptr, GLuint nstride, const GLubyte* nptr, GLuint nstride,
GLboolean doTexture, GLboolean doMultitexture, GLboolean doLighting) { GLboolean doTexture, GLboolean doMultitexture, GLboolean doLighting) {
assert(count < MAX_POLYGON_SIZE);
genArraysCommon( genArraysCommon(
output, count, output, count,
vptr, vstride, cptr, cstride, uvptr, uvstride, stptr, ststride, nptr, nstride, vptr, vstride, cptr, cstride, uvptr, uvstride, stptr, ststride, nptr, nstride,
doTexture, doMultitexture, doLighting doTexture, doMultitexture, doLighting
); );
#if TRACE_ENABLED
printf("%s(%s[%d]): count: %d\n",__func__, __FILE__,__LINE__, count);
#endif
assert(count <= MAX_POLYGON_SIZE);
if(count <= 3){ if(count <= 3){
swapVertex(&output[1], &output[2]); swapVertex(&output[1], &output[2]);
output[2].flags = PVR_CMD_VERTEX_EOL; output[2].flags = PVR_CMD_VERTEX_EOL;
@ -777,28 +786,15 @@ static void genArraysTriangleFan(
memcpy(buffer, output, sizeof(ClipVertex) * count); memcpy(buffer, output, sizeof(ClipVertex) * count);
// First 3 vertices are in the right place, just end early // First 3 vertices are in the right place, just end early
//swapVertex(&output[1], &output[2]);
output[2].flags = PVR_CMD_VERTEX_EOL; output[2].flags = PVR_CMD_VERTEX_EOL;
GLsizei i = 3, target = 3; GLsizei i = 3, target = 3;
ClipVertex* first = &output[0]; ClipVertex* first = &output[0];
#if TRACE_ENABLED
printf("%s(%s[%d]): Triangle!\n",__func__, __FILE__,__LINE__);
#endif
for(; i < count; ++i) { for(; i < count; ++i) {
output[target++] = *first; output[target++] = *first;
output[target++] = buffer[i - 1]; output[target++] = buffer[i - 1];
output[target] = buffer[i]; output[target] = buffer[i];
#if TRACE_ENABLED
printf("%s(%s[%d]): Triangle!\n",__func__, __FILE__,__LINE__);
printf("%s(%s[%d]):\tvert(%f,%f,%f)\n",__func__, __FILE__,__LINE__,
(*first).xyz[0],(*first).xyz[1],(*first).xyz[2]);
printf("%s(%s[%d]):\tvert(%f,%f,%f)\n",__func__, __FILE__,__LINE__,
(buffer[i - 1]).xyz[0],(buffer[i - 1]).xyz[1],(buffer[i - 1]).xyz[2]);
printf("%s(%s[%d]):\tvert(%f,%f,%f)\n",__func__, __FILE__,__LINE__,
(buffer[i]).xyz[0],(buffer[i]).xyz[1],(buffer[i]).xyz[2]);
#endif
output[target++].flags = PVR_CMD_VERTEX_EOL; output[target++].flags = PVR_CMD_VERTEX_EOL;
} }
} }
@ -1085,7 +1081,6 @@ static void push(PVRHeader* header, ClipVertex* output, const GLsizei count, Pol
#define DEBUG_CLIPPING 0 #define DEBUG_CLIPPING 0
static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) { static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) {
TRACE();
/* Do nothing if vertices aren't enabled */ /* Do nothing if vertices aren't enabled */
if(!(ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) { if(!(ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) {
return; return;
@ -1317,8 +1312,7 @@ GLuint _glGetActiveClientTexture() {
} }
void APIENTRY glClientActiveTextureARB(GLenum texture) { void APIENTRY glClientActiveTextureARB(GLenum texture) {
//@TODO: Uncomment TRACE();
//TRACE();
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) { if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) {
_glKosThrowError(GL_INVALID_ENUM, __func__); _glKosThrowError(GL_INVALID_ENUM, __func__);

View File

@ -55,6 +55,8 @@ static void _glInitPVR() {
PolyList* _glActivePolyList() { PolyList* _glActivePolyList() {
if(_glIsBlendingEnabled()) { if(_glIsBlendingEnabled()) {
return &TR_LIST; return &TR_LIST;
} else if(_glIsAlphaTestEnabled()) {
return &PT_LIST;
} else { } else {
return &OP_LIST; return &OP_LIST;
} }
@ -64,6 +66,15 @@ PolyList *_glTransparentPolyList() {
return &TR_LIST; return &TR_LIST;
} }
void APIENTRY glFlush() {
}
void APIENTRY glFinish() {
}
void APIENTRY glKosInit() { void APIENTRY glKosInit() {
TRACE(); TRACE();
@ -94,14 +105,10 @@ void APIENTRY glKosSwapBuffers() {
TRACE(); TRACE();
PROFILER_PUSH(__func__); profiler_push(__func__);
//printf("Flush:\n\tOP:%d\n\tPT:%d\n\tTR:%d\n",OP_LIST.vector.size,PT_LIST.vector.size,TR_LIST.vector.size);
//printf("Flush: glTexImage mem free:%d\n",pvr_mem_available());
pvr_wait_ready(); pvr_wait_ready();
pvr_scene_begin(); pvr_scene_begin();
QACR0 = QACRTA; QACR0 = QACRTA;
QACR1 = QACRTA; QACR1 = QACRTA;
@ -123,12 +130,11 @@ void APIENTRY glKosSwapBuffers() {
aligned_vector_clear(&PT_LIST.vector); aligned_vector_clear(&PT_LIST.vector);
aligned_vector_clear(&TR_LIST.vector); aligned_vector_clear(&TR_LIST.vector);
#ifdef PROFILER_COMPILE profiler_checkpoint("scene");
PROFILER_CHECKPOINT("scene"); profiler_pop();
PROFILER_POP();
if(frame_count++ > 100) { if(frame_count++ > 100) {
profiler_print_stats(); profiler_print_stats();
frame_count = 0; frame_count = 0;
} }
#endif
} }

View File

@ -83,6 +83,10 @@ void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b) {
glColor4f(r, g, b, a); glColor4f(r, g, b, a);
} }
void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue) {
glColor3f((float) red / 255, (float) green / 255, (float) blue / 255);
}
void APIENTRY glColor3fv(const GLfloat* v) { void APIENTRY glColor3fv(const GLfloat* v) {
glColor3f(v[0], v[1], v[2]); glColor3f(v[0], v[1], v[2]);
} }

View File

@ -7,7 +7,7 @@
static GLfloat SCENE_AMBIENT [] = {0.2, 0.2, 0.2, 1.0}; static GLfloat SCENE_AMBIENT [] = {0.2, 0.2, 0.2, 1.0};
static GLboolean VIEWER_IN_EYE_COORDINATES = GL_TRUE; static GLboolean VIEWER_IN_EYE_COORDINATES = GL_TRUE;
static GLenum COLOR_CONTROL = GL_SINGLE_COLOR; static GLenum COLOR_CONTROL = GL_SINGLE_COLOR;
//static GLboolean TWO_SIDED_LIGHTING = GL_FALSE; static GLboolean TWO_SIDED_LIGHTING = GL_FALSE;
static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE; static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
static LightSource LIGHTS[MAX_LIGHTS]; static LightSource LIGHTS[MAX_LIGHTS];

View File

@ -9,7 +9,7 @@
#define DEG2RAD (0.01745329251994329576923690768489) #define DEG2RAD (0.01745329251994329576923690768489)
/* Viewport mapping */ /* Viewport mapping */
//static GLfloat gl_viewport_scale[3], gl_viewport_offset[3]; static GLfloat gl_viewport_scale[3], gl_viewport_offset[3];
/* Depth range */ /* Depth range */
static GLclampf gl_depthrange_near, gl_depthrange_far; static GLclampf gl_depthrange_near, gl_depthrange_far;
@ -33,14 +33,14 @@ static const matrix_t IDENTITY = {
void APIENTRY glDepthRange(GLclampf n, GLclampf f); void APIENTRY glDepthRange(GLclampf n, GLclampf f);
matrix_t* _glGetModelViewMatrix() {
return (matrix_t*)stack_top(&MATRIX_STACKS[0]);
}
matrix_t* _glGetProjectionMatrix() { matrix_t* _glGetProjectionMatrix() {
return (matrix_t*) stack_top(&MATRIX_STACKS[1]); return (matrix_t*) stack_top(&MATRIX_STACKS[1]);
} }
matrix_t* _glGetModelViewMatrix() {
return (matrix_t*) stack_top(&MATRIX_STACKS[0]);
}
void _glInitMatrices() { void _glInitMatrices() {
init_stack(&MATRIX_STACKS[0], sizeof(matrix_t), 32); init_stack(&MATRIX_STACKS[0], sizeof(matrix_t), 32);
init_stack(&MATRIX_STACKS[1], sizeof(matrix_t), 32); init_stack(&MATRIX_STACKS[1], sizeof(matrix_t), 32);

View File

@ -16,7 +16,6 @@
#define NORMAL_ENABLED_FLAG (1 << 4) #define NORMAL_ENABLED_FLAG (1 << 4)
#define MAX_TEXTURE_SIZE 1024 #define MAX_TEXTURE_SIZE 1024
#define MAX_POLYGON_SIZE 18
#define CLIP_VERTEX_INT_PADDING 6 #define CLIP_VERTEX_INT_PADDING 6
@ -46,8 +45,10 @@ typedef struct {
/* Palette data is always stored in RAM as RGBA8888 and packed as ARGB8888 /* Palette data is always stored in RAM as RGBA8888 and packed as ARGB8888
* when uploaded to the PVR */ * when uploaded to the PVR */
GLubyte* data; GLubyte* data;
GLushort width; GLushort width; /* The user specified width */
GLushort size; /* The size of the bank (16 or 256) */
GLenum format; GLenum format;
GLshort bank;
} TexturePalette; } TexturePalette;
typedef struct { typedef struct {
@ -69,6 +70,9 @@ typedef struct {
GLboolean isPaletted; GLboolean isPaletted;
TexturePalette* palette; TexturePalette* palette;
/* When using the shared palette, this is the bank (0-3) */
GLushort shared_bank;
} TextureObject; } TextureObject;
typedef struct { typedef struct {
@ -142,11 +146,14 @@ TextureObject* _glGetTexture1();
TextureObject* _glGetBoundTexture(); TextureObject* _glGetBoundTexture();
GLubyte _glGetActiveTexture(); GLubyte _glGetActiveTexture();
GLuint _glGetActiveClientTexture(); GLuint _glGetActiveClientTexture();
TexturePalette* _glGetSharedPalette(GLshort bank);
GLboolean _glIsSharedTexturePaletteEnabled(); GLboolean _glIsSharedTexturePaletteEnabled();
void _glApplyColorTable(); void _glApplyColorTable(TexturePalette *palette);
GLboolean _glIsBlendingEnabled(); GLboolean _glIsBlendingEnabled();
GLboolean _glIsAlphaTestEnabled();
GLboolean _glIsMipmapComplete(const TextureObject* obj); GLboolean _glIsMipmapComplete(const TextureObject* obj);
GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level); GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level);
GLuint _glGetMipmapLevelCount(TextureObject* obj); GLuint _glGetMipmapLevelCount(TextureObject* obj);

View File

@ -30,6 +30,9 @@ static GLboolean COLOR_MATERIAL_ENABLED = GL_FALSE;
/* Is the shared texture palette enabled? */ /* Is the shared texture palette enabled? */
static GLboolean SHARED_PALETTE_ENABLED = GL_FALSE; static GLboolean SHARED_PALETTE_ENABLED = GL_FALSE;
static GLboolean ALPHA_TEST_ENABLED = GL_FALSE;
GLboolean _glIsSharedTexturePaletteEnabled() { GLboolean _glIsSharedTexturePaletteEnabled() {
return SHARED_PALETTE_ENABLED; return SHARED_PALETTE_ENABLED;
} }
@ -84,6 +87,10 @@ GLboolean _glIsBlendingEnabled() {
return BLEND_ENABLED; return BLEND_ENABLED;
} }
GLboolean _glIsAlphaTestEnabled() {
return ALPHA_TEST_ENABLED;
}
static int _calcPVRBlendFactor(GLenum factor) { static int _calcPVRBlendFactor(GLenum factor) {
switch(factor) { switch(factor) {
case GL_ZERO: case GL_ZERO:
@ -103,7 +110,7 @@ static int _calcPVRBlendFactor(GLenum factor) {
case GL_ONE: case GL_ONE:
return PVR_BLEND_ONE; return PVR_BLEND_ONE;
default: default:
printf("Invalid blend mode: %d\n", factor); fprintf(stderr, "Invalid blend mode: %d\n", factor);
return PVR_BLEND_ONE; return PVR_BLEND_ONE;
} }
} }
@ -127,7 +134,7 @@ static void _updatePVRBlend(pvr_poly_cxt_t* context) {
GLboolean _glCheckValidEnum(GLint param, GLenum* values, const char* func) { GLboolean _glCheckValidEnum(GLint param, GLenum* values, const char* func) {
GLubyte found = 0; GLubyte found = 0;
while(*values != 0) { while(*values != 0) {
if(*values == param) { if(*values == (GLenum)param) {
found++; found++;
break; break;
} }
@ -135,9 +142,8 @@ GLboolean _glCheckValidEnum(GLint param, GLenum* values, const char* func) {
} }
if(!found) { if(!found) {
//_glKosThrowError(GL_INVALID_ENUM, func); _glKosThrowError(GL_INVALID_ENUM, func);
//_glKosPrintError(); _glKosPrintError();
printf("GL_INVALID_ENUM when calling %s\n",func);
return GL_TRUE; return GL_TRUE;
} }
@ -179,9 +185,6 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
if(tx1->isCompressed && _glIsMipmapComplete(tx1)) { if(tx1->isCompressed && _glIsMipmapComplete(tx1)) {
enableMipmaps = GL_TRUE; enableMipmaps = GL_TRUE;
} }
if(tx1->isPaletted){
enableMipmaps = GL_FALSE;
}
if(enableMipmaps) { if(enableMipmaps) {
if(tx1->minFilter == GL_LINEAR_MIPMAP_NEAREST) { if(tx1->minFilter == GL_LINEAR_MIPMAP_NEAREST) {
@ -197,9 +200,6 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
if(tx1->minFilter == GL_LINEAR && tx1->magFilter == GL_LINEAR) { if(tx1->minFilter == GL_LINEAR && tx1->magFilter == GL_LINEAR) {
filter = PVR_FILTER_BILINEAR; filter = PVR_FILTER_BILINEAR;
} }
if(tx1->isPaletted){
filter = PVR_FILTER_NONE;
}
} }
/* If we don't have complete mipmaps, and yet mipmapping was enabled, we disable texturing. /* If we don't have complete mipmaps, and yet mipmapping was enabled, we disable texturing.
@ -221,6 +221,16 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
context->txr.height = tx1->height; context->txr.height = tx1->height;
context->txr.base = tx1->data; context->txr.base = tx1->data;
context->txr.format = tx1->color; context->txr.format = tx1->color;
if(tx1->isPaletted) {
if(_glIsSharedTexturePaletteEnabled()) {
TexturePalette* palette = _glGetSharedPalette(tx1->shared_bank);
context->txr.format |= PVR_TXRFMT_8BPP_PAL((palette) ? 0 : palette->bank);
} else {
context->txr.format |= PVR_TXRFMT_8BPP_PAL((tx1->palette) ? tx1->palette->bank : 0);
}
}
context->txr.env = tx1->env; context->txr.env = tx1->env;
context->txr.uv_flip = PVR_UVFLIP_NONE; context->txr.uv_flip = PVR_UVFLIP_NONE;
context->txr.uv_clamp = tx1->uv_clamp; context->txr.uv_clamp = tx1->uv_clamp;
@ -307,11 +317,11 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
break; break;
case GL_SHARED_TEXTURE_PALETTE_EXT: { case GL_SHARED_TEXTURE_PALETTE_EXT: {
SHARED_PALETTE_ENABLED = GL_TRUE; SHARED_PALETTE_ENABLED = GL_TRUE;
/* Apply the texture palette if necessary */
//_glApplyColorTable(); //@Todo: Actually Dont.
} }
break; break;
case GL_ALPHA_TEST: {
ALPHA_TEST_ENABLED = GL_TRUE;
} break;
case GL_LIGHT0: case GL_LIGHT0:
case GL_LIGHT1: case GL_LIGHT1:
case GL_LIGHT2: case GL_LIGHT2:
@ -361,11 +371,11 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
break; break;
case GL_SHARED_TEXTURE_PALETTE_EXT: { case GL_SHARED_TEXTURE_PALETTE_EXT: {
SHARED_PALETTE_ENABLED = GL_FALSE; SHARED_PALETTE_ENABLED = GL_FALSE;
/* Restore whatever palette may exist on a bound texture */
//_glApplyColorTable(); //@Todo: Actually Dont.
} }
break; break;
case GL_ALPHA_TEST: {
ALPHA_TEST_ENABLED = GL_FALSE;
} break;
case GL_LIGHT0: case GL_LIGHT0:
case GL_LIGHT1: case GL_LIGHT1:
case GL_LIGHT2: case GL_LIGHT2:
@ -411,6 +421,14 @@ GLAPI void APIENTRY glClearDepth(GLfloat depth) {
} }
GLAPI void APIENTRY glDrawBuffer(GLenum mode) {
}
GLAPI void APIENTRY glReadBuffer(GLenum mode) {
}
GLAPI void APIENTRY glDepthMask(GLboolean flag) { GLAPI void APIENTRY glDepthMask(GLboolean flag) {
GL_CONTEXT.depth.write = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE; GL_CONTEXT.depth.write = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE;
GL_CONTEXT.depth.comparison = _calc_pvr_depth_test(); GL_CONTEXT.depth.comparison = _calc_pvr_depth_test();
@ -457,8 +475,20 @@ GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) {
_updatePVRBlend(&GL_CONTEXT); _updatePVRBlend(&GL_CONTEXT);
} }
void glAlphaFunc(GLenum func, GLclampf ref) { #define PT_ALPHA_REF 0x011c
;
GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref) {
GLenum validFuncs[] = {
GL_GREATER,
0
};
if(_glCheckValidEnum(func, validFuncs, __func__) != 0) {
return;
}
GLubyte val = (GLubyte)(ref * 255.0f);
PVR_SET(PT_ALPHA_REF, val);
} }
void glLineWidth(GLfloat width) { void glLineWidth(GLfloat width) {
@ -579,6 +609,7 @@ void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) {
switch(pname) { switch(pname) {
case GL_PROJECTION_MATRIX: case GL_PROJECTION_MATRIX:
memcpy(params, _glGetProjectionMatrix(), sizeof(float) * 16); memcpy(params, _glGetProjectionMatrix(), sizeof(float) * 16);
break;
case GL_MODELVIEW_MATRIX: case GL_MODELVIEW_MATRIX:
memcpy(params, _glGetModelViewMatrix(), sizeof(float) * 16); memcpy(params, _glGetModelViewMatrix(), sizeof(float) * 16);
break; break;
@ -643,7 +674,7 @@ const GLbyte *glGetString(GLenum name) {
return "GLdc 1.x"; return "GLdc 1.x";
case GL_EXTENSIONS: case GL_EXTENSIONS:
return "GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg, GL_EXT_paletted_texture, GL_EXT_shared_texture_palette"; return "GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg, GL_EXT_paletted_texture, GL_EXT_shared_texture_palette, GL_KOS_multiple_shared_palette";
} }
return "GL_KOS_ERROR: ENUM Unsupported\n"; return "GL_KOS_ERROR: ENUM Unsupported\n";

View File

@ -18,65 +18,107 @@ static TextureObject* TEXTURE_UNITS[MAX_TEXTURE_UNITS] = {NULL, NULL};
static NamedArray TEXTURE_OBJECTS; static NamedArray TEXTURE_OBJECTS;
static GLubyte ACTIVE_TEXTURE = 0; static GLubyte ACTIVE_TEXTURE = 0;
static TexturePalette* SHARED_PALETTE = NULL; static TexturePalette* SHARED_PALETTES[4] = {NULL, NULL, NULL, NULL};
static GLbyte CURRENT_PALETTE = 0;
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type); static GLuint _determinePVRFormat(GLint internalFormat, GLenum type);
#define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) ) #define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) )
static TexturePalette* last_bound_palette = NULL; static GLboolean BANKS_USED[4]; // Each time a 256 colour bank is used, this is set to true
static GLboolean SUBBANKS_USED[4][16]; // 4 counts of the used 16 colour banks within the 256 ones
void _glApplyColorTable() {
static TexturePalette* _initTexturePalette() {
TexturePalette* palette = (TexturePalette*) malloc(sizeof(TexturePalette));
assert(palette);
memset(palette, 0x0, sizeof(TexturePalette));
palette->data = NULL;
palette->format = 0;
palette->width = 0;
palette->bank = -1;
palette->size = 0;
return palette;
}
static GLshort _glGenPaletteSlot(GLushort size) {
GLushort i, j;
assert(size == 16 || size == 256);
if(size == 16) {
for(i = 0; i < 4; ++i) {
for(j = 0; j < 16; ++j) {
if(!SUBBANKS_USED[i][j]) {
BANKS_USED[i] = GL_TRUE;
SUBBANKS_USED[i][j] = GL_TRUE;
return (i * 16) + j;
}
}
}
} else {
for(i = 0; i < 4; ++i) {
if(!BANKS_USED[i]) {
BANKS_USED[i] = GL_TRUE;
for(j = 0; j < 16; ++j) {
SUBBANKS_USED[i][j] = GL_TRUE;
}
return i;
}
}
}
fprintf(stderr, "GL ERROR: No palette slots remain\n");
return -1;
}
static void _glReleasePaletteSlot(GLshort slot, GLushort size) {
GLushort i;
assert(size == 16 || size == 256);
if(size == 16) {
GLushort bank = slot / 4;
GLushort subbank = slot % 4;
SUBBANKS_USED[bank][subbank] = GL_FALSE;
for(i = 0; i < 16; ++i) {
if(SUBBANKS_USED[bank][i]) {
return;
}
}
BANKS_USED[bank] = GL_FALSE;
} else {
BANKS_USED[slot] = GL_FALSE;
for(i = 0; i < 16; ++i) {
SUBBANKS_USED[slot][i] = GL_FALSE;
}
}
}
TexturePalette* _glGetSharedPalette(GLshort bank) {
assert(bank >= 0 && bank < 4);
return SHARED_PALETTES[bank];
}
void _glApplyColorTable(TexturePalette* src) {
/* /*
* FIXME: * FIXME:
* *
* - Different palette formats (GL_RGB -> PVR_PAL_RGB565) * - Different palette formats (GL_RGB -> PVR_PAL_RGB565)
*/ */
TexturePalette* src = NULL; if(!src || !src->data) {
if(_glIsSharedTexturePaletteEnabled()) {
src = SHARED_PALETTE;
assert(src);
/* Don't apply a palette if we haven't uploaded one yet */
if(!src->data) {
return; return;
} }
} else {
TextureObject* active = _glGetBoundTexture();
if(!active) {
return; //? Unload the palette? Make White?
}
if(!active->palette || !active->palette->data) {
return;
}
src = active->palette;
}
/* Don't reapply the palette if it was the last one we applied */
if(src == last_bound_palette) {
return;
}
last_bound_palette = src;
pvr_set_pal_format(PVR_PAL_ARGB8888); pvr_set_pal_format(PVR_PAL_ARGB8888);
GLushort i = 0; GLushort i;
GLushort offset = src->size * src->bank;
//printf("Palette Entries: %d\n",src->width); for(i = 0; i < src->width; ++i) {
for(; i < src->width; ++i) {
GLubyte* entry = &src->data[i * 4]; GLubyte* entry = &src->data[i * 4];
//printf("#%02X%02X%02X\t\t %08X\n",entry[0],entry[1],entry[2], PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2])); pvr_set_pal_entry(offset + i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
pvr_set_pal_entry(i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
} }
//printf("------END------\n");
} }
GLubyte _glGetActiveTexture() { GLubyte _glGetActiveTexture() {
@ -159,10 +201,11 @@ GLubyte _glInitTextures() {
// Reserve zero so that it is never given to anyone as an ID! // Reserve zero so that it is never given to anyone as an ID!
named_array_reserve(&TEXTURE_OBJECTS, 0); named_array_reserve(&TEXTURE_OBJECTS, 0);
SHARED_PALETTE = (TexturePalette*) malloc(sizeof(TexturePalette)); SHARED_PALETTES[0] = _initTexturePalette();
SHARED_PALETTE->data = NULL; SHARED_PALETTES[1] = _initTexturePalette();
SHARED_PALETTE->format = 0; SHARED_PALETTES[2] = _initTexturePalette();
SHARED_PALETTE->width = 0; SHARED_PALETTES[3] = _initTexturePalette();
return 1; return 1;
} }
@ -179,8 +222,7 @@ TextureObject* _glGetBoundTexture() {
} }
void APIENTRY glActiveTextureARB(GLenum texture) { void APIENTRY glActiveTextureARB(GLenum texture) {
//@TODO: Uncomment TRACE();
//TRACE();
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS)
_glKosThrowError(GL_INVALID_ENUM, "glActiveTextureARB"); _glKosThrowError(GL_INVALID_ENUM, "glActiveTextureARB");
@ -210,6 +252,9 @@ static void _glInitializeTextureObject(TextureObject* txr, unsigned int id) {
txr->palette = NULL; txr->palette = NULL;
txr->isCompressed = GL_FALSE; txr->isCompressed = GL_FALSE;
txr->isPaletted = GL_FALSE; txr->isPaletted = GL_FALSE;
/* Always default to the first shared bank */
txr->shared_bank = 0;
} }
void APIENTRY glGenTextures(GLsizei n, GLuint *textures) { void APIENTRY glGenTextures(GLsizei n, GLuint *textures) {
@ -248,7 +293,7 @@ void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) {
} }
if(txr->palette && txr->palette->data) { if(txr->palette && txr->palette->data) {
pvr_mem_free(txr->palette->data); free(txr->palette->data);
txr->palette->data = NULL; txr->palette->data = NULL;
} }
@ -277,10 +322,8 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) {
TextureObject* txr = named_array_reserve(&TEXTURE_OBJECTS, texture); TextureObject* txr = named_array_reserve(&TEXTURE_OBJECTS, texture);
_glInitializeTextureObject(txr, texture); _glInitializeTextureObject(txr, texture);
} }
TEXTURE_UNITS[ACTIVE_TEXTURE] = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, texture);
/* Apply the texture palette if necessary */ TEXTURE_UNITS[ACTIVE_TEXTURE] = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, texture);
//_glApplyColorTable(); //@Todo: Actually Dont.
} else { } else {
TEXTURE_UNITS[ACTIVE_TEXTURE] = NULL; TEXTURE_UNITS[ACTIVE_TEXTURE] = NULL;
} }
@ -295,9 +338,9 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
GLubyte failures = 0; GLubyte failures = 0;
/*failures += _glCheckValidEnum(target, target_values, __func__); failures += _glCheckValidEnum(target, target_values, __func__);
failures += _glCheckValidEnum(pname, pname_values, __func__); failures += _glCheckValidEnum(pname, pname_values, __func__);
failures += _glCheckValidEnum(param, param_values, __func__);*/ failures += _glCheckValidEnum(param, param_values, __func__);
TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE]; TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE];
@ -324,7 +367,7 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
} }
} }
void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) { void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLint param) {
glTexEnvi(target, pname, param); glTexEnvi(target, pname, param);
} }
@ -553,7 +596,7 @@ static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
case GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_TWID_KOS: case GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_TWID_KOS:
return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE;
case GL_COLOR_INDEX8_EXT: case GL_COLOR_INDEX8_EXT:
return PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_8BPP_PAL(CURRENT_PALETTE); return PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_TWIDDLED;
default: default:
return 0; return 0;
} }
@ -568,11 +611,11 @@ static inline void _rgba8888_to_argb4444(const GLubyte* source, GLubyte* dest) {
static inline void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) { static inline void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
/* Noop */ /* Noop */
//GLubyte* dst = (GLubyte*) dest; GLubyte* dst = (GLubyte*) dest;
dest[0] = source[0]; dst[0] = source[0];
dest[1] = source[1]; dst[1] = source[1];
dest[2] = source[2]; dst[2] = source[2];
dest[3] = source[3]; dst[3] = source[3];
} }
static inline void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) { static inline void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) {
@ -581,11 +624,11 @@ static inline void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) {
static inline void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) { static inline void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
/* Noop */ /* Noop */
//GLubyte* dst = (GLubyte*) dest; GLubyte* dst = (GLubyte*) dest;
dest[0] = source[0]; dst[0] = source[0];
dest[1] = source[1]; dst[1] = source[1];
dest[2] = source[2]; dst[2] = source[2];
dest[3] = 255; dst[3] = 255;
} }
static inline void _rgb888_to_rgb565(const GLubyte* source, GLubyte* dest) { static inline void _rgb888_to_rgb565(const GLubyte* source, GLubyte* dest) {
@ -681,7 +724,7 @@ static TextureConversionFunc _determineConversion(GLint internalFormat, GLenum f
} }
break; break;
default: default:
printf("Unsupported conversion: %x -> %x, %x\n", internalFormat, format, type); fprintf(stderr, "Unsupported conversion: %x -> %x, %x\n", internalFormat, format, type);
break; break;
} }
return 0; return 0;
@ -694,7 +737,6 @@ static GLboolean _isSupportedFormat(GLenum format) {
case GL_RGBA: case GL_RGBA:
case GL_BGRA: case GL_BGRA:
case GL_COLOR_INDEX: case GL_COLOR_INDEX:
case GL_LUMINANCE:
return GL_TRUE; return GL_TRUE;
default: default:
return GL_FALSE; return GL_FALSE;
@ -716,6 +758,20 @@ GLboolean _glIsMipmapComplete(const TextureObject* obj) {
return GL_TRUE; return GL_TRUE;
} }
static inline GLuint morton_1by1(GLuint x) {
x &= 0x0000ffff; // x = ---- ---- ---- ---- fedc ba98 7654 3210
x = (x ^ (x << 8)) & 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210
x = (x ^ (x << 4)) & 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210
x = (x ^ (x << 2)) & 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10
x = (x ^ (x << 1)) & 0x55555555; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0
return x;
}
static inline GLuint morton_index(GLuint x, GLuint y) {
return (morton_1by1(y) << 1) + morton_1by1(x);
}
void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLint border, GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, const GLvoid *data) { GLenum format, GLenum type, const GLvoid *data) {
@ -723,12 +779,12 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
TRACE(); TRACE();
if(target != GL_TEXTURE_2D) { if(target != GL_TEXTURE_2D) {
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D-tex2d"); _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
} }
if(format != GL_COLOR_INDEX) { if(format != GL_COLOR_INDEX) {
if(!_isSupportedFormat(format)) { if(!_isSupportedFormat(format)) {
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D-invalid_format"); _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
} }
/* Abuse determineStride to see if type is valid */ /* Abuse determineStride to see if type is valid */
@ -738,43 +794,43 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
internalFormat = _cleanInternalFormat(internalFormat); internalFormat = _cleanInternalFormat(internalFormat);
if(internalFormat == -1) { if(internalFormat == -1) {
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D-internal_fmt"); _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
} }
} else { } else {
if(internalFormat != GL_COLOR_INDEX8_EXT) { if(internalFormat != GL_COLOR_INDEX8_EXT) {
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D-8EXT"); _glKosThrowError(GL_INVALID_ENUM, __func__);
} }
} }
GLint w = width; GLint w = width;
if(w < 8 || (w & -w) != w) { if(w < 8 || (w & -w) != w) {
/* Width is not a power of two. Must be!*/ /* Width is not a power of two. Must be!*/
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D-width"); _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
} }
GLint h = height; GLint h = height;
if(h < 8 || (h & -h) != h) { if(h < 8 || (h & -h) != h) {
/* height is not a power of two. Must be!*/ /* height is not a power of two. Must be!*/
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D-height"); _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
} }
if(level < 0) { if(level < 0) {
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D-level"); _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
} }
if(border) { if(border) {
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D-border"); _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
} }
if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) { if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) {
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D-active_tex"); _glKosThrowError(GL_INVALID_OPERATION, __func__);
} }
GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT) ? GL_TRUE : GL_FALSE; GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT) ? GL_TRUE : GL_FALSE;
if(isPaletted && level > 0) { if(isPaletted && level > 0) {
/* Paletted textures can't have mipmaps */ /* Paletted textures can't have mipmaps */
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D-palette_level"); _glKosThrowError(GL_INVALID_OPERATION, __func__);
} }
if(_glKosHasError()) { if(_glKosHasError()) {
@ -838,52 +894,16 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
/* Let's assume we need to convert */ /* Let's assume we need to convert */
GLboolean needsConversion = GL_TRUE; GLboolean needsConversion = GL_TRUE;
GLboolean needsTwiddling = GL_FALSE;
GLubyte* targetData = _glGetMipmapLocation(active, level);
assert(targetData);
/* /*
* These are the only formats where the source format passed in matches the pvr format. * These are the only formats where the source format passed in matches the pvr format.
* Note the REV formats + GL_BGRA will reverse to ARGB which is what the PVR supports * Note the REV formats + GL_BGRA will reverse to ARGB which is what the PVR supports
*/ */
if(format == GL_COLOR_INDEX) { if(format == GL_COLOR_INDEX) {
if(type == GL_UNSIGNED_BYTE_TWID_KOS){
} else {
/* Don't convert color indexes */ /* Don't convert color indexes */
/* Linear/iterative twiddling algorithm from Marcus' tatest */
#define TWIDTAB(x) ( (x&1)|((x&2)<<1)|((x&4)<<2)|((x&8)<<3)|((x&16)<<4)| \
((x&32)<<5)|((x&64)<<6)|((x&128)<<7)|((x&256)<<8)|((x&512)<<9) )
#define TWIDOUT(x, y) ( TWIDTAB((y)) | (TWIDTAB((x)) << 1) )
#define MIN(a, b) ( (a)<(b)? (a):(b) )
uint32 x, y, yout, min, mask, invert;
min = MIN(w, h);
mask = min - 1;
invert = 0;
uint8 * pixels;
uint16 * vtex;
pixels = (uint8 *) data;
vtex = (uint16*)targetData;
for(y = 0; y < h; y += 2) {
if(!invert)
yout = y;
else
yout = ((h - 1) - y);
for(x = 0; x < w; x++) {
vtex[TWIDOUT((yout & mask) / 2, x & mask) +
(x / min + yout / min)*min * min / 2] =
pixels[y * w + x] | (pixels[(y + 1) * w + x] << 8);
}
}
data = NULL;
}
needsConversion = GL_FALSE; needsConversion = GL_FALSE;
needsTwiddling = type == GL_UNSIGNED_BYTE;
} else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && internalFormat == GL_RGBA) { } else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && internalFormat == GL_RGBA) {
needsConversion = GL_FALSE; needsConversion = GL_FALSE;
} else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV && internalFormat == GL_RGBA) { } else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV && internalFormat == GL_RGBA) {
@ -898,6 +918,9 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
needsConversion = GL_FALSE; needsConversion = GL_FALSE;
} }
GLubyte* targetData = _glGetMipmapLocation(active, level);
assert(targetData);
if(!data) { if(!data) {
/* No data? Do nothing! */ /* No data? Do nothing! */
return; return;
@ -906,8 +929,49 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
assert(data); assert(data);
assert(bytes); assert(bytes);
if(needsTwiddling) {
/*assert(type == GL_UNSIGNED_BYTE); // Anything else needs this loop adjusting
GLuint x, y;
for(y = 0; y < height; ++y) {
for(x = 0; x < width; ++x) {
GLuint src = (y * width) + x;
GLuint dest = morton_index(x, y);
targetData[dest] = ((GLubyte*) data)[src];
}
}
*/
/* Don't convert color indexes */
/* Linear/iterative twiddling algorithm from Marcus' tatest */
#define TWIDTAB(x) ( (x&1)|((x&2)<<1)|((x&4)<<2)|((x&8)<<3)|((x&16)<<4)| \
((x&32)<<5)|((x&64)<<6)|((x&128)<<7)|((x&256)<<8)|((x&512)<<9) )
#define TWIDOUT(x, y) ( TWIDTAB((y)) | (TWIDTAB((x)) << 1) )
#define MIN(a, b) ( (a)<(b)? (a):(b) )
uint32 x, y, min, mask;
min = MIN(w, h);
mask = min - 1;
uint8 * pixels;
uint16 * vtex;
pixels = (uint8 *) data;
vtex = (uint16*)targetData;
for(y = 0; y < h; y += 2) {
for(x = 0; x < w; x++) {
vtex[TWIDOUT((y & mask) / 2, x & mask) +
(x / min + y / min)*min * min / 2] =
pixels[y * w + x] | (pixels[(y + 1) * w + x] << 8);
}
}
data = NULL;
} else {
/* No conversion? Just copy the data, and the pvr_format is correct */ /* No conversion? Just copy the data, and the pvr_format is correct */
sq_cpy(targetData, data, bytes); sq_cpy(targetData, data, bytes);
}
return; return;
} else { } else {
TextureConversionFunc convert = _determineConversion( TextureConversionFunc convert = _determineConversion(
@ -917,7 +981,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
); );
if(!convert) { if(!convert) {
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D-convert"); _glKosThrowError(GL_INVALID_OPERATION, __func__);
return; return;
} }
@ -931,7 +995,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
assert(stride > -1); assert(stride > -1);
if(stride == -1) { if(stride == -1) {
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D-stride"); _glKosThrowError(GL_INVALID_OPERATION, __func__);
return; return;
} }
@ -944,7 +1008,6 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
source += stride; source += stride;
} }
} }
//printf("GLdc: glTexImage mem free:%d\n",pvr_mem_available());
} }
void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
@ -1012,6 +1075,11 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
break; break;
} }
break;
case GL_SHARED_TEXTURE_BANK_KOS:
active->shared_bank = param;
break;
default:
break; break;
} }
} }
@ -1022,7 +1090,16 @@ void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLint param) {
} }
GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data) { GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data) {
GLenum validTargets[] = {GL_TEXTURE_2D, GL_SHARED_TEXTURE_PALETTE_EXT, 0}; GLenum validTargets[] = {
GL_TEXTURE_2D,
GL_SHARED_TEXTURE_PALETTE_EXT,
GL_SHARED_TEXTURE_PALETTE_0_KOS,
GL_SHARED_TEXTURE_PALETTE_1_KOS,
GL_SHARED_TEXTURE_PALETTE_2_KOS,
GL_SHARED_TEXTURE_PALETTE_3_KOS,
0
};
GLenum validInternalFormats[] = {GL_RGB8, GL_RGBA8, 0}; GLenum validInternalFormats[] = {GL_RGB8, GL_RGBA8, 0};
GLenum validFormats[] = {GL_RGB, GL_RGBA, 0}; GLenum validFormats[] = {GL_RGB, GL_RGBA, 0};
GLenum validTypes[] = {GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, 0}; GLenum validTypes[] = {GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, 0};
@ -1068,12 +1145,19 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
TexturePalette* palette = NULL; TexturePalette* palette = NULL;
if(target == GL_SHARED_TEXTURE_PALETTE_EXT) { /* Custom extension - allow uploading to one of 4 custom palettes */
palette = SHARED_PALETTE; if(target == GL_SHARED_TEXTURE_PALETTE_EXT || target == GL_SHARED_TEXTURE_PALETTE_0_KOS) {
palette = SHARED_PALETTES[0];
} else if(target == GL_SHARED_TEXTURE_PALETTE_1_KOS) {
palette = SHARED_PALETTES[1];
} else if(target == GL_SHARED_TEXTURE_PALETTE_2_KOS) {
palette = SHARED_PALETTES[2];
} else if(target == GL_SHARED_TEXTURE_PALETTE_3_KOS) {
palette = SHARED_PALETTES[3];
} else { } else {
TextureObject* active = _glGetBoundTexture(); TextureObject* active = _glGetBoundTexture();
if(!active->palette) { if(!active->palette) {
active->palette = (TexturePalette*) malloc(sizeof(TexturePalette)); active->palette = _initTexturePalette();
} }
palette = active->palette; palette = active->palette;
@ -1082,15 +1166,32 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
assert(palette); assert(palette);
if(target) { if(target) {
//pvr_mem_free(palette->data);
free(palette->data); free(palette->data);
palette->data = NULL; palette->data = NULL;
} }
//palette->data = (GLubyte*) pvr_mem_malloc(width * 4); if(palette->bank > -1) {
_glReleasePaletteSlot(palette->bank, palette->size);
palette->bank = -1;
}
palette->data = (GLubyte*) malloc(width * 4); palette->data = (GLubyte*) malloc(width * 4);
palette->format = format; palette->format = format;
palette->width = width; palette->width = width;
palette->size = (width > 16) ? 256 : 16;
assert(palette->size == 16 || palette->size == 256);
palette->bank = _glGenPaletteSlot(palette->size);
if(palette->bank < 0) {
/* We ran out of slots! */
_glKosThrowError(GL_INVALID_OPERATION, __func__);
_glKosPrintError();
free(palette->data);
palette->format = palette->width = palette->size = 0;
return;
}
GLubyte* src = (GLubyte*) data; GLubyte* src = (GLubyte*) data;
GLubyte* dst = (GLubyte*) palette->data; GLubyte* dst = (GLubyte*) palette->data;
@ -1107,10 +1208,7 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
dst += 4; dst += 4;
} }
_glApplyColorTable(palette);
/* Colour table might have changed the active palette, so wipe last_bound_palette before reapplying */
last_bound_palette = NULL;
_glApplyColorTable();
} }
GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) { GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) {
@ -1133,23 +1231,27 @@ GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, G
_glKosPrintError(); _glKosPrintError();
} }
void APIENTRY glKosSetPalette( GLenum palette ) { GLAPI void APIENTRY glTexSubImage2D(
switch(palette) { GLenum target, GLint level, GLint xoffset, GLint yoffset,
case GL_EXT_PALLETE_0_8BPP: GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {
CURRENT_PALETTE = 0;
break;
case GL_EXT_PALLETE_1_8BPP:
CURRENT_PALETTE = 1;
break;
case GL_EXT_PALLETE_2_8BPP:
CURRENT_PALETTE = 2;
break;
case GL_EXT_PALLETE_3_8BPP:
CURRENT_PALETTE = 3;
break;
}
} }
GLbyte APIENTRY glKosGetPalette() { GLAPI void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
return CURRENT_PALETTE;
}
GLAPI void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {
}
GLAPI void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
}
GLAPI void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) {
}
GLAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
} }

View File

@ -112,10 +112,10 @@ __BEGIN_DECLS
/* Texture Environment */ /* Texture Environment */
#define GL_TEXTURE_ENV_MODE 0x2200 #define GL_TEXTURE_ENV_MODE 0x2200
#define GL_REPLACE 0x0 #define GL_REPLACE 0x1E01
#define GL_MODULATE 0x1 #define GL_MODULATE 0x2100
#define GL_DECAL 0x2 #define GL_DECAL 0x2101
#define GL_MODULATEALPHA 0x3
/* TextureMagFilter */ /* TextureMagFilter */
#define GL_NEAREST 0x2600 #define GL_NEAREST 0x2600
@ -393,6 +393,9 @@ __BEGIN_DECLS
/* Initialize the GL pipeline. GL will initialize the PVR. */ /* Initialize the GL pipeline. GL will initialize the PVR. */
GLAPI void APIENTRY glKosInit(); GLAPI void APIENTRY glKosInit();
GLAPI void APIENTRY glFlush();
GLAPI void APIENTRY glFinish();
/* Start Submission of Primitive Data */ /* Start Submission of Primitive Data */
/* Currently Supported Primitive Types: /* Currently Supported Primitive Types:
-GL_POINTS ( does NOT work with glDrawArrays )( ZClipping NOT supported ) -GL_POINTS ( does NOT work with glDrawArrays )( ZClipping NOT supported )
@ -413,6 +416,7 @@ GLAPI void APIENTRY glTexCoord2fv(const GLfloat *uv);
GLAPI void APIENTRY glColor1ui(GLuint argb); GLAPI void APIENTRY glColor1ui(GLuint argb);
GLAPI void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a); GLAPI void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
GLAPI void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b); GLAPI void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b);
GLAPI void APIENTRY glColor3ub(GLubyte r, GLubyte g, GLubyte b);
GLAPI void APIENTRY glColor3fv(const GLfloat *rgb); GLAPI void APIENTRY glColor3fv(const GLfloat *rgb);
GLAPI void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a); GLAPI void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
GLAPI void APIENTRY glColor4fv(const GLfloat *rgba); GLAPI void APIENTRY glColor4fv(const GLfloat *rgba);
@ -462,6 +466,9 @@ GLAPI void APIENTRY glDisable(GLenum cap);
GLAPI void APIENTRY glClear(GLuint mode); GLAPI void APIENTRY glClear(GLuint mode);
GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a); GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
GLAPI void APIENTRY glReadBuffer(GLenum mode);
GLAPI void APIENTRY glDrawBuffer(GLenum mode);
/* Depth Testing */ /* Depth Testing */
GLAPI void APIENTRY glClearDepth(GLfloat depth); GLAPI void APIENTRY glClearDepth(GLfloat depth);
GLAPI void APIENTRY glClearDepthf(GLfloat depth); GLAPI void APIENTRY glClearDepthf(GLfloat depth);
@ -486,7 +493,7 @@ GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor);
/* Texturing */ /* Texturing */
GLAPI void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param);
GLAPI void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param);
GLAPI void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param); GLAPI void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLint param);
GLAPI GLboolean APIENTRY glIsTexture(GLuint texture); GLAPI GLboolean APIENTRY glIsTexture(GLuint texture);
GLAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures); GLAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures);
@ -524,6 +531,13 @@ GLAPI void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalForma
GLsizei width, GLsizei height, GLint border, GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, const GLvoid *data); GLenum format, GLenum type, const GLvoid *data);
GLAPI void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
GLAPI void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
GLAPI void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
GLAPI void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
GLAPI void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
GLAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
/* GL Array API - Only GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_QUADS are supported */ /* GL Array API - Only GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_QUADS are supported */
GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type, GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type,

View File

@ -34,14 +34,36 @@ __BEGIN_DECLS
#define GL_UNSIGNED_BYTE_TWID_KOS 0xEEFB #define GL_UNSIGNED_BYTE_TWID_KOS 0xEEFB
#define GL_EXT_PALLETE_0_8BPP 0xEFA0
#define GL_EXT_PALLETE_1_8BPP 0xEFA1
#define GL_EXT_PALLETE_2_8BPP 0xEFA2
#define GL_EXT_PALLETE_3_8BPP 0xEFA3
GLAPI void APIENTRY glKosSwapBuffers(); GLAPI void APIENTRY glKosSwapBuffers();
GLAPI void APIENTRY glKosSetPalette( GLenum palette );
/*
* CUSTOM EXTENSION multiple_shared_palette_KOS
*
* This extension allows using up to 4 different shared palettes
* with ColorTableEXT. The following constants are provided
* to use as targets for ColorTableExt:
*
* - SHARED_TEXTURE_PALETTE_0_KOS
* - SHARED_TEXTURE_PALETTE_1_KOS
* - SHARED_TEXTURE_PALETTE_2_KOS
* - SHARED_TEXTURE_PALETTE_3_KOS
*
* In this use case SHARED_TEXTURE_PALETTE_0_KOS is interchangable with SHARED_TEXTURE_PALETTE_EXT
* (both refer to the first shared palette).
*
* To select which palette a texture uses, a new pname is accepted by TexParameteri: SHARED_TEXTURE_BANK_KOS
* by default textures use shared palette 0.
*/
#define GL_SHARED_TEXTURE_PALETTE_0_KOS 0xEEFC
#define GL_SHARED_TEXTURE_PALETTE_1_KOS 0xEEFD
#define GL_SHARED_TEXTURE_PALETTE_2_KOS 0xEEFE
#define GL_SHARED_TEXTURE_PALETTE_3_KOS 0xEEFF
/* Pass to glTexParameteri to set the shared bank */
#define GL_SHARED_TEXTURE_BANK_KOS 0xEF00
__END_DECLS __END_DECLS