diff --git a/.gitignore b/.gitignore index c1b78b3..f445fc5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ *.img dc-build.sh .buildconfig -GL/version.h +build/* +builddir/* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2c21ac7..060ccd6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,5 +6,18 @@ build:sh4-gcc: image: kazade/dreamcast-sdk script: - source /etc/bash.bashrc - - make clean - - make samples + - mkdir builddir + - cd builddir + - cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/Dreamcast.cmake .. + - make + +build:x86-gcc: + stage: build + image: fedora:33 + before_script: + - sudo dnf install -y cmake gcc gcc-c++ SDL2-devel.i686 glibc-devel.i686 + script: + - mkdir builddir + - cd builddir + - cmake .. + - make diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ffc6089 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,146 @@ +cmake_minimum_required(VERSION 3.0) +project(GLdc) + +# set the default backend +if(PLATFORM_DREAMCAST) + set(BACKEND "kospvr" CACHE STRING "Backend to use") +else() + set(BACKEND "software" CACHE STRING "Backend to use") +endif() + +# List of possible backends +set_property(CACHE BACKEND PROPERTY STRINGS kospvr software) + +message("\nCompiling using backend: ${BACKEND}\n") + +string(TOUPPER ${BACKEND} BACKEND_UPPER) +add_definitions(-DBACKEND_${BACKEND_UPPER}) + +set(CMAKE_C_STANDARD 99) + +include_directories(include) + +if(NOT PLATFORM_DREAMCAST) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") +endif() + +set( + SOURCES + containers/aligned_vector.c + containers/named_array.c + containers/stack.c + GL/clip.c + GL/draw.c + GL/error.c + GL/flush.c + GL/fog.c + GL/framebuffer.c + GL/glu.c + GL/immediate.c + GL/lighting.c + GL/matrix.c + GL/profiler.c + GL/state.c + GL/texture.c + GL/util.c + GL/yalloc/yalloc.c + ${CMAKE_CURRENT_BINARY_DIR}/version.c +) + +execute_process( + COMMAND git describe --abbrev=4 --dirty --always --tags + OUTPUT_VARIABLE GLDC_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +configure_file(GL/version.c.in ${CMAKE_CURRENT_BINARY_DIR}/version.c) + +if(PLATFORM_DREAMCAST) + set(SOURCES ${SOURCES} GL/platforms/sh4.c) +else() + find_package(SDL2 REQUIRED) + include_directories(${SDL2_INCLUDE_DIRS}) + link_libraries(${SDL2_LIBRARIES}) + set( + SOURCES + ${SOURCES} + GL/platforms/software.c + GL/platforms/software/edge_equation.c + GL/platforms/software/parameter_equation.c + ) +endif() + +add_library(GLdc STATIC ${SOURCES}) +link_libraries(m) + +include_directories(include) + +link_libraries(GLdc) + +function(gen_sample sample) + set(SAMPLE_SRCS ${ARGN}) + set(GENROMFS "$ENV{KOS_BASE}/utils/genromfs/genromfs") + set(BIN2O $ENV{KOS_BASE}/utils/bin2o/bin2o) + set(ROMDISK_IMG "${CMAKE_SOURCE_DIR}/samples/${sample}/romdisk.img") + set(ROMDISK_O "${CMAKE_SOURCE_DIR}/samples/${sample}/romdisk.o") + set(ROMDISK_DIR "${CMAKE_SOURCE_DIR}/samples/${sample}/romdisk") + + add_executable(${sample} ${SAMPLE_SRCS}) + + if(PLATFORM_DREAMCAST) + if(EXISTS "${CMAKE_SOURCE_DIR}/samples/${sample}/romdisk") + message("Generating romdisk for sample: ${sample}") + add_custom_command( + OUTPUT ${ROMDISK_IMG} + COMMAND ${GENROMFS} -f ${ROMDISK_IMG} -d ${ROMDISK_DIR} -v + ) + + add_custom_command( + OUTPUT ${ROMDISK_O} + COMMAND ${BIN2O} romdisk.img romdisk romdisk.o + DEPENDS ${ROMDISK_IMG} + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/samples/${sample}" + ) + + add_custom_target(${sample}_romdisk DEPENDS ${ROMDISK_O}) + add_dependencies(${sample} ${sample}_romdisk) + target_link_libraries(${sample} ${ROMDISK_O}) + + else() + message("No such romdisk for sample: ${sample} at 'samples/${sample}/romdisk'") + endif() + endif() +endfunction() + +gen_sample(blend_test samples/blend_test/main.c) +gen_sample(depth_funcs samples/depth_funcs/main.c) +gen_sample(depth_funcs_alpha_testing samples/depth_funcs_alpha_testing/main.c samples/depth_funcs_alpha_testing/gl_png.c) +gen_sample(depth_funcs_ortho samples/depth_funcs_ortho/main.c) +gen_sample(lerabot01 samples/lerabot01/main.c) +gen_sample(lerabot_blend_test samples/lerabot_blend_test/main.c) +gen_sample(lights samples/lights/main.c) +gen_sample(mipmap samples/mipmap/main.c) +gen_sample(multitexture_arrays samples/multitexture_arrays/main.c samples/multitexture_arrays/pvr-texture.c) +gen_sample(nehe02 samples/nehe02/main.c) +gen_sample(nehe02de samples/nehe02de/main.c) +gen_sample(nehe02va samples/nehe02va/main.c) +gen_sample(nehe03 samples/nehe03/main.c) +gen_sample(nehe04 samples/nehe04/main.c) +gen_sample(nehe05 samples/nehe05/main.c) +gen_sample(nehe06 samples/nehe06/main.c) +gen_sample(nehe06_vq samples/nehe06_vq/main.c) +gen_sample(ortho2d samples/ortho2d/main.c) +gen_sample(paletted samples/paletted/main.c) +gen_sample(paletted_pcx samples/paletted_pcx/main.c) +gen_sample(polygon_offset samples/polygon_offset/main.c) +gen_sample(terrain samples/terrain/main.c) +gen_sample(zclip samples/zclip/main.c) +gen_sample(zclip_triangle samples/zclip_triangle/main.c) +gen_sample(zclip_trianglestrip samples/zclip_trianglestrip/main.c) + +if(PLATFORM_DREAMCAST) + gen_sample(polymark samples/polymark/main.c) + gen_sample(quadmark samples/quadmark/main.c) + gen_sample(trimark samples/trimark/main.c) +endif() diff --git a/GL/draw.c b/GL/draw.c index fc99dee..8a6f73c 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -4,14 +4,10 @@ #include #include #include -#include -#include "../include/gl.h" -#include "../include/glext.h" #include "private.h" #include "profiler.h" -#include "sh4_math.h" - +#include "platform.h" static AttribPointer VERTEX_POINTER; static AttribPointer UV_POINTER; @@ -439,7 +435,7 @@ GL_FORCE_INLINE void transformNormalToEyeSpace(GLfloat* normal) { mat_trans_normal3(normal[0], normal[1], normal[2]); } -PVRHeader* _glSubmissionTargetHeader(SubmissionTarget* target) { +PolyHeader *_glSubmissionTargetHeader(SubmissionTarget* target) { assert(target->header_offset < target->output->vector.size); return aligned_vector_at(&target->output->vector, target->header_offset); } @@ -458,7 +454,7 @@ static inline void genTriangles(Vertex* output, GLuint count) { GLuint i; for(i = 0; i < count; i += 3) { - it->flags = PVR_CMD_VERTEX_EOL; + it->flags = GPU_CMD_VERTEX_EOL; it += 3; } } @@ -468,13 +464,13 @@ static inline void genQuads(Vertex* output, GLuint count) { GLuint i; for(i = 0; i < count; i += 4) { swapVertex((final - 1), final); - final->flags = PVR_CMD_VERTEX_EOL; + final->flags = GPU_CMD_VERTEX_EOL; final += 4; } } static void genTriangleStrip(Vertex* output, GLuint count) { - output[count - 1].flags = PVR_CMD_VERTEX_EOL; + output[count - 1].flags = GPU_CMD_VERTEX_EOL; } static void genTriangleFan(Vertex* output, GLuint count) { @@ -486,7 +482,7 @@ static void genTriangleFan(Vertex* output, GLuint count) { GLubyte i = count - 2; while(i--) { *dst = *src--; - (*dst--).flags = PVR_CMD_VERTEX_EOL; + (*dst--).flags = GPU_CMD_VERTEX_EOL; *dst-- = *src; *dst-- = *output; } @@ -655,7 +651,7 @@ GL_FORCE_INLINE void _readSTData(const GLuint first, const GLuint count, VertexE const GLubyte ststride = (ST_POINTER.stride) ? ST_POINTER.stride : ST_POINTER.size * byte_size(ST_POINTER.type); const void* stptr = ((GLubyte*) ST_POINTER.ptr + (first * ststride)); - ReadUVFunc func = calcReadUVFunc(); + ReadUVFunc func = calcReadSTFunc(); GLubyte* out = (GLubyte*) extra[0].st; ITERATE(count) { @@ -697,7 +693,8 @@ GL_FORCE_INLINE void _readNormalData(const GLuint first, const GLuint count, Ver } GL_FORCE_INLINE void _readDiffuseData(const GLuint first, const GLuint count, Vertex* output) { - const GLuint cstride = (DIFFUSE_POINTER.stride) ? DIFFUSE_POINTER.stride : DIFFUSE_POINTER.size * byte_size(DIFFUSE_POINTER.type); + const GLuint size = (DIFFUSE_POINTER.size == GL_BGRA) ? 4 : DIFFUSE_POINTER.size; + const GLuint cstride = (DIFFUSE_POINTER.stride) ? DIFFUSE_POINTER.stride : size * byte_size(DIFFUSE_POINTER.type); const GLubyte* cptr = ((GLubyte*) DIFFUSE_POINTER.ptr) + (first * cstride); ReadDiffuseFunc func = calcReadDiffuseFunc(); @@ -765,7 +762,7 @@ static void generateElements( st_func(st, (GLubyte*) ve->st); normal_func(nxyz, (GLubyte*) ve->nxyz); - output->flags = PVR_CMD_VERTEX; + output->flags = GPU_CMD_VERTEX; ++output; ++ve; } @@ -786,7 +783,7 @@ static void generate(SubmissionTarget* target, const GLenum mode, const GLsizei const GLubyte* pos = VERTEX_POINTER.ptr; Vertex* it = start; ITERATE(count) { - it->flags = PVR_CMD_VERTEX; + it->flags = GPU_CMD_VERTEX; memcpy(it->xyz, pos, FAST_PATH_BYTE_SIZE); it++; pos += VERTEX_POINTER.stride; @@ -799,7 +796,7 @@ static void generate(SubmissionTarget* target, const GLenum mode, const GLsizei Vertex* it = _glSubmissionTargetStart(target); ITERATE(count) { - it->flags = PVR_CMD_VERTEX; + it->flags = GPU_CMD_VERTEX; ++it; } } @@ -843,25 +840,7 @@ static void transform(SubmissionTarget* target) { _glApplyRenderMatrix(); /* Apply the Render Matrix Stack */ - ITERATE(target->count) { - register float __x __asm__("fr12") = (vertex->xyz[0]); - register float __y __asm__("fr13") = (vertex->xyz[1]); - register float __z __asm__("fr14") = (vertex->xyz[2]); - register float __w __asm__("fr15") = (vertex->w); - - __asm__ __volatile__( - "fldi1 fr15\n" - "ftrv xmtrx,fv12\n" - : "=f" (__x), "=f" (__y), "=f" (__z), "=f" (__w) - : "0" (__x), "1" (__y), "2" (__z), "3" (__w) - ); - - vertex->xyz[0] = __x; - vertex->xyz[1] = __y; - vertex->xyz[2] = __z; - vertex->w = __w; - ++vertex; - } + TransformVertices(vertex, target->count); } static void clip(SubmissionTarget* target) { @@ -875,14 +854,17 @@ static void clip(SubmissionTarget* target) { } static void mat_transform3(const float* xyz, const float* xyzOut, const uint32_t count, const uint32_t inStride, const uint32_t outStride) { - uint8_t* dataIn = (uint8_t*) xyz; + const uint8_t* dataIn = (const uint8_t*) xyz; uint8_t* dataOut = (uint8_t*) xyzOut; ITERATE(count) { - float* in = (float*) dataIn; + const float* in = (const float*) dataIn; float* out = (float*) dataOut; - mat_trans_single3_nodiv_nomod(in[0], in[1], in[2], out[0], out[1], out[2]); + TransformVec3NoMod( + in, + out + ); dataIn += inStride; dataOut += outStride; @@ -890,14 +872,14 @@ static void mat_transform3(const float* xyz, const float* xyzOut, const uint32_t } static void mat_transform_normal3(const float* xyz, const float* xyzOut, const uint32_t count, const uint32_t inStride, const uint32_t outStride) { - uint8_t* dataIn = (uint8_t*) xyz; + const uint8_t* dataIn = (const uint8_t*) xyz; uint8_t* dataOut = (uint8_t*) xyzOut; ITERATE(count) { - float* in = (float*) dataIn; + const float* in = (const float*) dataIn; float* out = (float*) dataOut; - mat_trans_normal3_nomod(in[0], in[1], in[2], out[0], out[1], out[2]); + TransformNormalNoMod(in, out); dataIn += inStride; dataOut += outStride; @@ -930,8 +912,8 @@ static void light(SubmissionTarget* target) { _glPerformLighting(vertex, ES, target->count); } -#define PVR_MIN_Z 0.2f -#define PVR_MAX_Z 1.0 + PVR_MIN_Z +#define GPU_MIN_Z 0.2f +#define GPU_MAX_Z 1.0 + GPU_MIN_Z GL_FORCE_INLINE void divide(SubmissionTarget* target) { TRACE(); @@ -949,26 +931,26 @@ GL_FORCE_INLINE void divide(SubmissionTarget* target) { } } -GL_FORCE_INLINE void push(PVRHeader* header, GLboolean multiTextureHeader, PolyList* activePolyList, GLshort textureUnit) { +GL_FORCE_INLINE void push(PolyHeader* header, GLboolean multiTextureHeader, PolyList* activePolyList, GLshort textureUnit) { TRACE(); // Compile the header - pvr_poly_cxt_t cxt = *_glGetPVRContext(); + PolyContext cxt = *_glGetPVRContext(); cxt.list_type = activePolyList->list_type; _glUpdatePVRTextureContext(&cxt, textureUnit); if(multiTextureHeader) { - assert(cxt.list_type == PVR_LIST_TR_POLY); + assert(cxt.list_type == GPU_LIST_TR_POLY); - cxt.gen.alpha = PVR_ALPHA_ENABLE; - cxt.txr.alpha = PVR_TXRALPHA_ENABLE; - cxt.blend.src = PVR_BLEND_ZERO; - cxt.blend.dst = PVR_BLEND_DESTCOLOR; - cxt.depth.comparison = PVR_DEPTHCMP_EQUAL; + cxt.gen.alpha = GPU_ALPHA_ENABLE; + cxt.txr.alpha = GPU_TXRALPHA_ENABLE; + cxt.blend.src = GPU_BLEND_ZERO; + cxt.blend.dst = GPU_BLEND_DESTCOLOR; + cxt.depth.comparison = GPU_DEPTHCMP_EQUAL; } - pvr_poly_compile(&header->hdr, &cxt); + CompilePolyHeader(header, &cxt); /* Post-process the vertex list */ /* @@ -1136,7 +1118,7 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GL assert(vertex); - PVRHeader* mtHeader = (PVRHeader*) vertex++; + PolyHeader* mtHeader = (PolyHeader*) vertex++; /* Replace the UV coordinates with the ST ones */ VertexExtra* ve = aligned_vector_at(target->extras, 0); diff --git a/GL/error.c b/GL/error.c index 49732e5..c964fec 100644 --- a/GL/error.c +++ b/GL/error.c @@ -8,10 +8,10 @@ KOS Open GL State Machine Error Code Implementation. */ -#include "gl.h" - #include +#include "private.h" + static GLenum last_error = GL_NO_ERROR; static char error_function[64] = { '\0' }; diff --git a/GL/flush.c b/GL/flush.c index 95a6dde..8829533 100644 --- a/GL/flush.c +++ b/GL/flush.c @@ -1,57 +1,12 @@ - -#include - -#include "../include/glkos.h" #include "../containers/aligned_vector.h" #include "private.h" #include "profiler.h" -#include "version.h" - -#define TA_SQ_ADDR (unsigned int *)(void *) \ - (0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0)) static PolyList OP_LIST; static PolyList PT_LIST; static PolyList TR_LIST; -static void pvr_list_submit(void *src, int n) { - GLuint *d = TA_SQ_ADDR; - GLuint *s = src; - - /* fill/write queues as many times necessary */ - while(n--) { - __asm__("pref @%0" : : "r"(s + 8)); /* prefetch 32 bytes for next loop */ - d[0] = *(s++); - d[1] = *(s++); - d[2] = *(s++); - d[3] = *(s++); - d[4] = *(s++); - d[5] = *(s++); - d[6] = *(s++); - d[7] = *(s++); - __asm__("pref @%0" : : "r"(d)); - d += 8; - } - - /* Wait for both store queues to complete */ - d = (GLuint *)0xe0000000; - d[0] = d[8] = 0; -} - -static void _glInitPVR(GLboolean autosort, GLboolean fsaa) { - pvr_init_params_t params = { - /* Enable opaque and translucent polygons with size 32 and 32 */ - {PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32}, - PVR_VERTEX_BUF_SIZE, /* Vertex buffer size */ - 0, /* No DMA */ - fsaa, /* No FSAA */ - (autosort) ? 0 : 1 /* Disable translucent auto-sorting to match traditional GL */ - }; - - pvr_init(¶ms); -} - PolyList* _glActivePolyList() { if(_glIsBlendingEnabled()) { @@ -92,7 +47,7 @@ void APIENTRY glKosInitEx(GLdcConfig* config) { printf("\nWelcome to GLdc! Git revision: %s\n\n", GLDC_VERSION); - _glInitPVR(config->autosort_enabled, config->fsaa_enabled); + InitGPU(config->autosort_enabled, config->fsaa_enabled); _glInitMatrices(); _glInitAttributePointers(); @@ -105,9 +60,9 @@ void APIENTRY glKosInitEx(GLdcConfig* config) { _glInitTextures(); - OP_LIST.list_type = PVR_LIST_OP_POLY; - PT_LIST.list_type = PVR_LIST_PT_POLY; - TR_LIST.list_type = PVR_LIST_TR_POLY; + OP_LIST.list_type = GPU_LIST_OP_POLY; + PT_LIST.list_type = GPU_LIST_PT_POLY; + TR_LIST.list_type = GPU_LIST_TR_POLY; aligned_vector_init(&OP_LIST.vector, sizeof(Vertex)); aligned_vector_init(&PT_LIST.vector, sizeof(Vertex)); @@ -124,7 +79,6 @@ void APIENTRY glKosInit() { glKosInitEx(&config); } -#define QACRTA ((((unsigned int)0x10000000)>>26)<<2)&0x1c void APIENTRY glKosSwapBuffers() { static int frame_count = 0; @@ -133,24 +87,19 @@ void APIENTRY glKosSwapBuffers() { profiler_push(__func__); - pvr_wait_ready(); + SceneBegin(); + SceneListBegin(GPU_LIST_OP_POLY); + SceneListSubmit(OP_LIST.vector.data, OP_LIST.vector.size); + SceneListFinish(); - pvr_scene_begin(); - QACR0 = QACRTA; - QACR1 = QACRTA; + SceneListBegin(GPU_LIST_PT_POLY); + SceneListSubmit(PT_LIST.vector.data, PT_LIST.vector.size); + SceneListFinish(); - pvr_list_begin(PVR_LIST_OP_POLY); - pvr_list_submit(OP_LIST.vector.data, OP_LIST.vector.size); - pvr_list_finish(); - - pvr_list_begin(PVR_LIST_PT_POLY); - pvr_list_submit(PT_LIST.vector.data, PT_LIST.vector.size); - pvr_list_finish(); - - pvr_list_begin(PVR_LIST_TR_POLY); - pvr_list_submit(TR_LIST.vector.data, TR_LIST.vector.size); - pvr_list_finish(); - pvr_scene_finish(); + SceneListBegin(GPU_LIST_TR_POLY); + SceneListSubmit(TR_LIST.vector.data, TR_LIST.vector.size); + SceneListFinish(); + SceneFinish(); aligned_vector_clear(&OP_LIST.vector); aligned_vector_clear(&PT_LIST.vector); diff --git a/GL/fog.c b/GL/fog.c index ccf0662..08dc21d 100644 --- a/GL/fog.c +++ b/GL/fog.c @@ -10,13 +10,13 @@ static GLfloat FOG_COLOR [] = {0.0f, 0.0f, 0.0f, 0.0f}; static void updatePVRFog() { if(FOG_MODE == GL_LINEAR) { - pvr_fog_table_linear(FOG_START, FOG_END); + GPUSetFogLinear(FOG_START, FOG_END); } else if(FOG_MODE == GL_EXP) { - pvr_fog_table_exp(FOG_DENSITY); + GPUSetFogExp(FOG_DENSITY); } else if(FOG_MODE == GL_EXP2) { - pvr_fog_table_exp2(FOG_DENSITY); + GPUSetFogExp2(FOG_DENSITY); } - pvr_fog_table_color(FOG_COLOR[3], FOG_COLOR[0], FOG_COLOR[1], FOG_COLOR[2]); + GPUSetFogColor(FOG_COLOR[3], FOG_COLOR[0], FOG_COLOR[1], FOG_COLOR[2]); } void APIENTRY glFogf(GLenum pname, GLfloat param) { diff --git a/GL/framebuffer.c b/GL/framebuffer.c index 96c1d43..0df1893 100644 --- a/GL/framebuffer.c +++ b/GL/framebuffer.c @@ -2,8 +2,6 @@ #include #include "private.h" -#include "../include/glkos.h" -#include "../include/glext.h" typedef struct { GLuint index; @@ -160,7 +158,7 @@ static GL_NO_INSTRUMENT GLboolean _glCalculateAverageTexel(GLuint pvrFormat, con const GLubyte ARGB4444 = 1; const GLubyte RGB565 = 2; - if((pvrFormat & PVR_TXRFMT_PAL8BPP) == PVR_TXRFMT_PAL8BPP) { + if((pvrFormat & GPU_TXRFMT_PAL8BPP) == GPU_TXRFMT_PAL8BPP) { /* Paletted... all we can do really is just pick one of the * 4 texels.. unless we want to change the palette (bad) or * pick the closest available colour (slow, and probably bad) @@ -232,7 +230,7 @@ GLboolean _glGenerateMipmapTwiddled(const GLuint pvrFormat, const GLubyte* prevD uint32_t i, j; uint32_t stride = 0; - if((pvrFormat & PVR_TXRFMT_PAL8BPP) == PVR_TXRFMT_PAL8BPP) { + if((pvrFormat & GPU_TXRFMT_PAL8BPP) == GPU_TXRFMT_PAL8BPP) { stride = 1; } else { stride = 2; @@ -281,7 +279,7 @@ void APIENTRY glGenerateMipmapEXT(GLenum target) { return; } - if((tex->color & PVR_TXRFMT_NONTWIDDLED) == PVR_TXRFMT_NONTWIDDLED) { + if((tex->color & GPU_TXRFMT_NONTWIDDLED) == GPU_TXRFMT_NONTWIDDLED) { /* glTexImage2D should twiddle internally textures in nearly all cases * so this error is unlikely */ diff --git a/GL/glu.c b/GL/glu.c index 9b3e8cf..717b273 100644 --- a/GL/glu.c +++ b/GL/glu.c @@ -6,7 +6,7 @@ void APIENTRY gluPerspective(GLfloat angle, GLfloat aspect, GLfloat znear, GLfloat zfar) { GLfloat fW, fH; - fH = tanf(angle * (F_PI / 360.0f)) * znear; + fH = tanf(angle * (M_PI / 360.0f)) * znear; fW = fH * aspect; glFrustum(-fW, fW, -fH, fH, znear, zfar); diff --git a/GL/immediate.c b/GL/immediate.c index e1f530b..f9e1958 100644 --- a/GL/immediate.c +++ b/GL/immediate.c @@ -10,11 +10,7 @@ #include #include -#include "../include/gl.h" -#include "../include/glext.h" -#include "../include/glkos.h" #include "profiler.h" - #include "private.h" static GLboolean IMMEDIATE_MODE_ACTIVE = GL_FALSE; diff --git a/GL/lighting.c b/GL/lighting.c index a7d2094..de0e15f 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -3,8 +3,9 @@ #include #include #include -#include + #include "private.h" +#include "platform.h" #define _MIN(x, y) (x < y) ? x : y @@ -201,12 +202,7 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) { if(LIGHTS[idx].isDirectional) { //FIXME: Do we need to rotate directional lights? } else { - mat_trans_single4( - LIGHTS[idx].position[0], - LIGHTS[idx].position[1], - LIGHTS[idx].position[2], - LIGHTS[idx].position[3] - ); + TransformVec3(LIGHTS[idx].position); } } break; @@ -387,10 +383,6 @@ GL_FORCE_INLINE GLboolean isSpecularColorMaterial() { return (COLOR_MATERIAL_MODE == GL_SPECULAR); } -GL_FORCE_INLINE void initVec3(struct vec3f* v, const GLfloat* src) { - memcpy(v, src, sizeof(GLfloat) * 3); -} - /* * Implementation from here (MIT): * https://github.com/appleseedhq/appleseed/blob/master/src/appleseed/foundation/math/fastmath.h @@ -455,7 +447,7 @@ GL_FORCE_INLINE void _glLightVertexPoint( #undef _PROCESS_COMPONENT } -void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const int32_t count) { +void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const uint32_t count) { GLubyte i; GLuint j; @@ -503,7 +495,7 @@ void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const int32_t count) float Vx = -data->xyz[0]; float Vy = -data->xyz[1]; float Vz = -data->xyz[2]; - vec3f_normalize(Vx, Vy, Vz); + VEC3_NORMALIZE(Vx, Vy, Vz); const float Nx = data->n[0]; const float Ny = data->n[1]; @@ -523,15 +515,15 @@ void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const int32_t count) float Hy = (Ly + 0); float Hz = (Lz + 1); - vec3f_normalize(Lx, Ly, Lz); - vec3f_normalize(Hx, Hy, Hz); + VEC3_NORMALIZE(Lx, Ly, Lz); + VEC3_NORMALIZE(Hx, Hy, Hz); float LdotN, NdotH; - vec3f_dot( + VEC3_DOT( Nx, Ny, Nz, Lx, Ly, Lz, LdotN ); - vec3f_dot( + VEC3_DOT( Nx, Ny, Nz, Hx, Hy, Hz, NdotH ); @@ -544,8 +536,7 @@ void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const int32_t count) ); } else { float D; - - vec3f_length(Lx, Ly, Lz, D); + VEC3_LENGTH(Lx, Ly, Lz, D); float att = ( LIGHTS[i].constant_attenuation + ( @@ -563,15 +554,15 @@ void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const int32_t count) float Hy = (Ly + Vy); float Hz = (Lz + Vz); - vec3f_normalize(Lx, Ly, Lz); - vec3f_normalize(Hx, Hy, Hz); + VEC3_NORMALIZE(Lx, Ly, Lz); + VEC3_NORMALIZE(Hx, Hy, Hz); float LdotN, NdotH; - vec3f_dot( + VEC3_DOT( Nx, Ny, Nz, Lx, Ly, Lz, LdotN ); - vec3f_dot( + VEC3_DOT( Nx, Ny, Nz, Hx, Hy, Hz, NdotH ); diff --git a/GL/matrix.c b/GL/matrix.c index b0b21d5..275b607 100644 --- a/GL/matrix.c +++ b/GL/matrix.c @@ -1,13 +1,9 @@ #include - +#include #include -#include -#include -#include -#include #include "private.h" -#include "../include/gl.h" + #include "../containers/stack.h" #define DEG2RAD (0.01745329251994329576923690768489) @@ -36,18 +32,6 @@ static const Matrix4x4 IDENTITY = { GLfloat NEAR_PLANE_DISTANCE = 0.0f; -static inline void upload_matrix(Matrix4x4* m) { - mat_load((matrix_t*) m); -} - -static inline void multiply_matrix(Matrix4x4* m) { - mat_apply((matrix_t*) m); -} - -static inline void download_matrix(Matrix4x4* m) { - mat_store((matrix_t*) m); -} - Matrix4x4* _glGetProjectionMatrix() { return (Matrix4x4*) stack_top(&MATRIX_STACKS[1]); } @@ -65,8 +49,10 @@ void _glInitMatrices() { stack_push(&MATRIX_STACKS[1], IDENTITY); stack_push(&MATRIX_STACKS[2], IDENTITY); - memcpy4(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4)); - memcpy4(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4)); + FASTCPY4(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4)); + FASTCPY4(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4)); + + const VideoMode* vid_mode = GetVideoMode(); glDepthRange(0.0f, 1.0f); glViewport(0, 0, vid_mode->width, vid_mode->height); @@ -110,7 +96,7 @@ static void transpose(GLfloat* m) { } static void recalculateNormalMatrix() { - memcpy4(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(Matrix4x4)); + FASTCPY4(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(Matrix4x4)); inverse((GLfloat*) NORMAL_MATRIX); transpose((GLfloat*) NORMAL_MATRIX); } @@ -136,20 +122,16 @@ void APIENTRY glLoadIdentity() { } void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) { - static Matrix4x4 trn __attribute__((aligned(32))) = { + const Matrix4x4 trn __attribute__((aligned(32))) = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f + x, y, z, 1.0f }; - trn[M12] = x; - trn[M13] = y; - trn[M14] = z; - - upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); - multiply_matrix(&trn); - download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); + MultiplyMatrix4x4(&trn); + DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); @@ -158,20 +140,16 @@ void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) { void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) { - static Matrix4x4 scale __attribute__((aligned(32))) = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, + const Matrix4x4 scale __attribute__((aligned(32))) = { + x, 0.0f, 0.0f, 0.0f, + 0.0f, y, 0.0f, 0.0f, + 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; - scale[M0] = x; - scale[M5] = y; - scale[M10] = z; - - upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); - multiply_matrix(&scale); - download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); + MultiplyMatrix4x4(&scale); + DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); @@ -179,7 +157,7 @@ void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) { } void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { - static Matrix4x4 rotate __attribute__((aligned(32))) = { + Matrix4x4 rotate __attribute__((aligned(32))) = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, @@ -190,7 +168,7 @@ void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { float c = cos(r); float s = sin(r); - vec3f_normalize(x, y, z); + VEC3_NORMALIZE(x, y, z); float invc = 1.0f - c; float xs = x * s; @@ -212,9 +190,9 @@ void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { rotate[M9] = yz * invc - xs; rotate[M10] = (z * z) * invc + c; - upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); - multiply_matrix(&rotate); - download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); + MultiplyMatrix4x4((const Matrix4x4*) &rotate); + DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); @@ -258,7 +236,7 @@ void APIENTRY glOrtho(GLfloat left, GLfloat right, GLfloat znear, GLfloat zfar) { /* Ortho Matrix */ - static Matrix4x4 OrthoMatrix __attribute__((aligned(32))) = { + Matrix4x4 OrthoMatrix __attribute__((aligned(32))) = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, @@ -272,9 +250,9 @@ void APIENTRY glOrtho(GLfloat left, GLfloat right, OrthoMatrix[M13] = -(top + bottom) / (top - bottom); OrthoMatrix[M14] = -(zfar + znear) / (zfar - znear); - upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); - multiply_matrix(&OrthoMatrix); - download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); + MultiplyMatrix4x4((const Matrix4x4*) &OrthoMatrix); + DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); } @@ -284,9 +262,9 @@ void APIENTRY glFrustum(GLfloat left, GLfloat right, GLfloat znear, GLfloat zfar) { /* Frustum Matrix */ - static Matrix4x4 FrustumMatrix __attribute__((aligned(32))); + Matrix4x4 FrustumMatrix __attribute__((aligned(32))); - memset(FrustumMatrix, 0, sizeof(float) * 16); + MEMSET(FrustumMatrix, 0, sizeof(float) * 16); const float near2 = 2.0f * znear; const float A = (right + left) / (right - left); @@ -303,39 +281,20 @@ void APIENTRY glFrustum(GLfloat left, GLfloat right, FrustumMatrix[M11] = -1.0f; FrustumMatrix[M14] = D; - upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); - multiply_matrix(&FrustumMatrix); - download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); + MultiplyMatrix4x4((const Matrix4x4*) &FrustumMatrix); + DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); } /* Multiply the current matrix by an arbitrary matrix */ void glMultMatrixf(const GLfloat *m) { - static Matrix4x4 TEMP; + Matrix4x4 TEMP; + FASTCPY4(TEMP, m, sizeof(Matrix4x4)); - TEMP[M0] = m[0]; - TEMP[M1] = m[1]; - TEMP[M2] = m[2]; - TEMP[M3] = m[3]; - - TEMP[M4] = m[4]; - TEMP[M5] = m[5]; - TEMP[M6] = m[6]; - TEMP[M7] = m[7]; - - TEMP[M8] = m[8]; - TEMP[M9] = m[9]; - TEMP[M10] = m[10]; - TEMP[M11] = m[11]; - - TEMP[M12] = m[12]; - TEMP[M13] = m[13]; - TEMP[M14] = m[14]; - TEMP[M15] = m[15]; - - upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); - multiply_matrix((Matrix4x4*) &TEMP); - download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); + MultiplyMatrix4x4((const Matrix4x4*) &TEMP); + DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); @@ -400,9 +359,9 @@ void glMultTransposeMatrixf(const GLfloat *m) { TEMP[M14] = m[11]; TEMP[M15] = m[15]; - upload_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); - multiply_matrix(&TEMP); - download_matrix(stack_top(MATRIX_STACKS + MATRIX_IDX)); + UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); + MultiplyMatrix4x4((const Matrix4x4*) &TEMP); + DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX)); if(MATRIX_MODE == GL_MODELVIEW) { recalculateNormalMatrix(); @@ -411,6 +370,8 @@ void glMultTransposeMatrixf(const GLfloat *m) { /* Set the GL viewport */ void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { + const VideoMode* vid_mode = GetVideoMode(); + gl_viewport_x1 = x; gl_viewport_y1 = y; gl_viewport_width = width; @@ -453,40 +414,40 @@ static inline void vec3f_cross(const GLfloat* v1, const GLfloat* v2, GLfloat* re GL_FORCE_INLINE void vec3f_normalize_sh4(float *v){ float length, ilength; - ilength = MATH_fsrra(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + ilength = MATH_fsrra(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); length = MATH_Fast_Invert(ilength); - if (length) - { - v[0] *= ilength; - v[1] *= ilength; - v[2] *= ilength; - } + if (length) + { + v[0] *= ilength; + v[1] *= ilength; + v[2] *= ilength; + } } void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy, GLfloat upz) { GLfloat m [16]; - GLfloat f [3]; - GLfloat u [3]; - GLfloat s [3]; + GLfloat f [3]; + GLfloat u [3]; + GLfloat s [3]; - f[0] = centerx - eyex; - f[1] = centery - eyey; - f[2] = centerz - eyez; + f[0] = centerx - eyex; + f[1] = centery - eyey; + f[2] = centerz - eyez; - u[0] = upx; - u[1] = upy; - u[2] = upz; + u[0] = upx; + u[1] = upy; + u[2] = upz; vec3f_normalize_sh4(f); - vec3f_cross(f, u, s); + vec3f_cross(f, u, s); vec3f_normalize_sh4(s); - vec3f_cross(s, f, u); + vec3f_cross(s, f, u); - m[0] = s[0]; m[4] = s[1]; m[8] = s[2]; m[12] = 0.0f; - m[1] = u[0]; m[5] = u[1]; m[9] = u[2]; m[13] = 0.0f; - m[2] = -f[0]; m[6] = -f[1]; m[10] = -f[2]; m[14] = 0.0f; + m[0] = s[0]; m[4] = s[1]; m[8] = s[2]; m[12] = 0.0f; + m[1] = u[0]; m[5] = u[1]; m[9] = u[2]; m[13] = 0.0f; + m[2] = -f[0]; m[6] = -f[1]; m[10] = -f[2]; m[14] = 0.0f; m[3] = 0.0f; m[7] = 0.0f; m[11] = 0.0f; m[15] = 1.0f; static Matrix4x4 trn __attribute__((aligned(32))) = { @@ -501,26 +462,26 @@ void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, trn[M14] = -eyez; // Does not modify internal Modelview matrix - upload_matrix(&m); - multiply_matrix(&trn); - multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); - download_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); + UploadMatrix4x4((const Matrix4x4*) &m); + MultiplyMatrix4x4((const Matrix4x4*) &trn); + MultiplyMatrix4x4(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); + DownloadMatrix4x4(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); } void _glApplyRenderMatrix() { - upload_matrix(&SCREENVIEW_MATRIX); - multiply_matrix(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF))); - multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); + UploadMatrix4x4((const Matrix4x4*) &SCREENVIEW_MATRIX); + MultiplyMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF))); + MultiplyMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); } void _glMatrixLoadTexture() { - upload_matrix(stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF))); + UploadMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF))); } void _glMatrixLoadModelView() { - upload_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); + UploadMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); } void _glMatrixLoadNormal() { - upload_matrix(&NORMAL_MATRIX); + UploadMatrix4x4((const Matrix4x4*) &NORMAL_MATRIX); } diff --git a/GL/platform.h b/GL/platform.h new file mode 100644 index 0000000..b8d4db5 --- /dev/null +++ b/GL/platform.h @@ -0,0 +1,498 @@ +#pragma once + +#include +#include +#include + +#define MEMSET(dst, v, size) memset((dst), (v), (size)) + +typedef enum GPUAlpha { + GPU_ALPHA_DISABLE = 0, + GPU_ALPHA_ENABLE = 1 +} GPUAlpha; + +typedef enum GPUTexture { + GPU_TEXTURE_DISABLE = 0, + GPU_TEXTURE_ENABLE = 1 +} GPUTexture; + +typedef enum GPUTextureAlpha { + GPU_TXRALPHA_DISABLE = 1, + GPU_TXRALPHA_ENABLE = 0 +} GPUTextureAlpha; + +typedef enum GPUList { + GPU_LIST_OP_POLY = 0, + GPU_LIST_OP_MOD = 1, + GPU_LIST_TR_POLY = 2, + GPU_LIST_TR_MOD = 3, + GPU_LIST_PT_POLY = 4 +} GPUList; + +typedef enum GPUBlend { + GPU_BLEND_ZERO = 0, + GPU_BLEND_ONE = 1, + GPU_BLEND_DESTCOLOR = 2, + GPU_BLEND_INVDESTCOLOR = 3, + GPU_BLEND_SRCALPHA = 4, + GPU_BLEND_INVSRCALPHA = 5, + GPU_BLEND_DESTALPHA = 6, + GPU_BLEND_INVDESTALPHA = 7 +} GPUBlend; + +typedef enum GPUDepthCompare { + GPU_DEPTHCMP_NEVER = 0, + GPU_DEPTHCMP_LESS = 1, + GPU_DEPTHCMP_EQUAL = 2, + GPU_DEPTHCMP_LEQUAL = 3, + GPU_DEPTHCMP_GREATER = 4, + GPU_DEPTHCMP_NOTEQUAL = 5, + GPU_DEPTHCMP_GEQUAL = 6, + GPU_DEPTHCMP_ALWAYS = 7 +} GPUDepthCompare; + +typedef enum GPUTextureFormat { + GPU_TXRFMT_NONE, + GPU_TXRFMT_VQ_DISABLE = (0 << 30), + GPU_TXRFMT_VQ_ENABLE = (1 << 30), + GPU_TXRFMT_ARGB1555 = (0 << 27), + GPU_TXRFMT_RGB565 = (1 << 27), + GPU_TXRFMT_ARGB4444 = (2 << 27), + GPU_TXRFMT_YUV422 = (3 << 27), + GPU_TXRFMT_BUMP = (4 << 27), + GPU_TXRFMT_PAL4BPP = (5 << 27), + GPU_TXRFMT_PAL8BPP = (6 << 27), + GPU_TXRFMT_TWIDDLED = (0 << 26), + GPU_TXRFMT_NONTWIDDLED = (1 << 26), + GPU_TXRFMT_NOSTRIDE = (0 << 21), + GPU_TXRFMT_STRIDE = (1 << 21) +} GPUTextureFormat; + +static inline uint32_t GPUPaletteSelect8BPP(uint32_t x) { + return x << 25; +} + +static inline uint32_t GPUPaletteSelect4BPP(uint32_t x) { + return x << 21; +} + +typedef enum GPUCulling { + GPU_CULLING_NONE = 0, + GPU_CULLING_SMALL = 1, + GPU_CULLING_CCW = 2, + GPU_CULLING_CW = 3 +} GPUCulling; + +typedef enum GPUUVFlip { + GPU_UVFLIP_NONE = 0, + GPU_UVFLIP_V = 1, + GPU_UVFLIP_U = 2, + GPU_UVFLIP_UV = 3 +} GPUUVFlip; + +typedef enum GPUUVClamp { + GPU_UVCLAMP_NONE = 0, + GPU_UVCLAMP_V = 1, + GPU_UVCLAMP_U = 2, + GPU_UVCLAMP_UV = 3 +} GPUUVClamp; + +typedef enum GPUColorClamp { + GPU_CLRCLAMP_DISABLE = 0, + GPU_CLRCLAMP_ENABLE = 1 +} GPUColorClamp; + +typedef enum GPUFilter { + GPU_FILTER_NEAREST = 0, + GPU_FILTER_BILINEAR = 2, + GPU_FILTER_TRILINEAR1 = 4, + GPU_FILTER_TRILINEAR2 = 6 +} GPUFilter; + +typedef enum GPUDepthWrite { + GPU_DEPTHWRITE_ENABLE = 0, + GPU_DEPTHWRITE_DISABLE = 1 +} GPUDepthWrite; + +typedef enum GPUUserClip { + GPU_USERCLIP_DISABLE = 0, + GPU_USERCLIP_INSIDE = 2, + GPU_USERCLIP_OUTSIDE = 3 +} GPUUserClip; + +typedef enum GPUColorFormat { + GPU_CLRFMT_ARGBPACKED = 0, + GPU_CLRFMT_4FLOATS = 1, + GPU_CLRFMT_INTENSITY = 2, + GPU_CLRFMT_INTENSITY_PREV = 3 +} GPUColorFormat; + +typedef enum GPUUVFormat { + GPU_UVFMT_32BIT = 0, + GPU_UVFMT_16BIT = 1 +} GPUUVFormat; + +typedef enum GPUPaletteFormat { + GPU_PAL_ARGB1555 = 0, + GPU_PAL_RGB565 = 1, + GPU_PAL_ARGB4444 = 2, + GPU_PAL_ARGB8888 = 3 +} GPUPaletteFormat; + +typedef enum GPUFog { + GPU_FOG_TABLE = 0, + GPU_FOG_VERTEX = 1, + GPU_FOG_DISABLE = 2, + GPU_FOG_TABLE2 = 3 +} GPUFog; + +typedef enum GPUShade { + GPU_SHADE_FLAT = 0, + GPU_SHADE_GOURAUD = 1 +} GPUShade; + +typedef enum GPUTextureEnv { + GPU_TXRENV_REPLACE = 0, + GPU_TXRENV_MODULATE = 1, + GPU_TXRENV_DECAL = 2, + GPU_TXRENV_MODULATEALPHA = 3 +} GPUTextureEnv; + +typedef struct VideoMode { + uint16_t width; + uint16_t height; +} VideoMode; + +const VideoMode* GetVideoMode(); + +/* Duplication of pvr_poly_cxt_t from KOS so that we can + * compile on non-KOS platforms for testing */ + +typedef struct { + GPUList list_type; + + struct { + int alpha; + int shading; + int fog_type; + int culling; + int color_clamp; + int clip_mode; + int modifier_mode; + int specular; + int alpha2; + int fog_type2; + int color_clamp2; + } gen; + struct { + int src; + int dst; + int src_enable; + int dst_enable; + int src2; + int dst2; + int src_enable2; + int dst_enable2; + } blend; + struct { + int color; + int uv; + int modifier; + } fmt; + struct { + int comparison; + int write; + } depth; + struct { + int enable; + int filter; + int mipmap; + int mipmap_bias; + int uv_flip; + int uv_clamp; + int alpha; + int env; + int width; + int height; + int format; + void* base; + } txr; + struct { + int enable; + int filter; + int mipmap; + int mipmap_bias; + int uv_flip; + int uv_clamp; + int alpha; + int env; + int width; + int height; + int format; + void* base; + } txr2; +} PolyContext; + +typedef struct { + uint32_t cmd; + uint32_t mode1; + uint32_t mode2; + uint32_t mode3; + uint32_t d1; + uint32_t d2; + uint32_t d3; + uint32_t d4; +} PolyHeader; + +enum GPUCommand { + GPU_CMD_POLYHDR = 0x80840000, + GPU_CMD_VERTEX = 0xe0000000, + GPU_CMD_VERTEX_EOL = 0xf0000000, + GPU_CMD_USERCLIP = 0x20000000, + GPU_CMD_MODIFIER = 0x80000000, + GPU_CMD_SPRITE = 0xA0000000 +}; + +typedef float Matrix4x4[16]; + +void SceneBegin(); + +void SceneListBegin(GPUList list); +void SceneListSubmit(void* src, int n); +void SceneListFinish(); + +void SceneFinish(); + +#define GPU_TA_CMD_TYPE_SHIFT 24 +#define GPU_TA_CMD_TYPE_MASK (7 << GPU_TA_CMD_TYPE_SHIFT) + +#define GPU_TA_CMD_USERCLIP_SHIFT 16 +#define GPU_TA_CMD_USERCLIP_MASK (3 << GPU_TA_CMD_USERCLIP_SHIFT) + +#define GPU_TA_CMD_CLRFMT_SHIFT 4 +#define GPU_TA_CMD_CLRFMT_MASK (7 << GPU_TA_CMD_CLRFMT_SHIFT) + +#define GPU_TA_CMD_SPECULAR_SHIFT 2 +#define GPU_TA_CMD_SPECULAR_MASK (1 << GPU_TA_CMD_SPECULAR_SHIFT) + +#define GPU_TA_CMD_SHADE_SHIFT 1 +#define GPU_TA_CMD_SHADE_MASK (1 << GPU_TA_CMD_SHADE_SHIFT) + +#define GPU_TA_CMD_UVFMT_SHIFT 0 +#define GPU_TA_CMD_UVFMT_MASK (1 << GPU_TA_CMD_UVFMT_SHIFT) + +#define GPU_TA_CMD_MODIFIER_SHIFT 7 +#define GPU_TA_CMD_MODIFIER_MASK (1 << GPU_TA_CMD_MODIFIER_SHIFT) + +#define GPU_TA_CMD_MODIFIERMODE_SHIFT 6 +#define GPU_TA_CMD_MODIFIERMODE_MASK (1 << GPU_TA_CMD_MODIFIERMODE_SHIFT) + +#define GPU_TA_PM1_DEPTHCMP_SHIFT 29 +#define GPU_TA_PM1_DEPTHCMP_MASK (7 << GPU_TA_PM1_DEPTHCMP_SHIFT) + +#define GPU_TA_PM1_CULLING_SHIFT 27 +#define GPU_TA_PM1_CULLING_MASK (3 << GPU_TA_PM1_CULLING_SHIFT) + +#define GPU_TA_PM1_DEPTHWRITE_SHIFT 26 +#define GPU_TA_PM1_DEPTHWRITE_MASK (1 << GPU_TA_PM1_DEPTHWRITE_SHIFT) + +#define GPU_TA_PM1_TXRENABLE_SHIFT 25 +#define GPU_TA_PM1_TXRENABLE_MASK (1 << GPU_TA_PM1_TXRENABLE_SHIFT) + +#define GPU_TA_PM1_MODIFIERINST_SHIFT 29 +#define GPU_TA_PM1_MODIFIERINST_MASK (3 << GPU_TA_PM1_MODIFIERINST_SHIFT) + +#define GPU_TA_PM2_SRCBLEND_SHIFT 29 +#define GPU_TA_PM2_SRCBLEND_MASK (7 << GPU_TA_PM2_SRCBLEND_SHIFT) + +#define GPU_TA_PM2_DSTBLEND_SHIFT 26 +#define GPU_TA_PM2_DSTBLEND_MASK (7 << GPU_TA_PM2_DSTBLEND_SHIFT) + +#define GPU_TA_PM2_SRCENABLE_SHIFT 25 +#define GPU_TA_PM2_SRCENABLE_MASK (1 << GPU_TA_PM2_SRCENABLE_SHIFT) + +#define GPU_TA_PM2_DSTENABLE_SHIFT 24 +#define GPU_TA_PM2_DSTENABLE_MASK (1 << GPU_TA_PM2_DSTENABLE_SHIFT) + +#define GPU_TA_PM2_FOG_SHIFT 22 +#define GPU_TA_PM2_FOG_MASK (3 << GPU_TA_PM2_FOG_SHIFT) + +#define GPU_TA_PM2_CLAMP_SHIFT 21 +#define GPU_TA_PM2_CLAMP_MASK (1 << GPU_TA_PM2_CLAMP_SHIFT) + +#define GPU_TA_PM2_ALPHA_SHIFT 20 +#define GPU_TA_PM2_ALPHA_MASK (1 << GPU_TA_PM2_ALPHA_SHIFT) + +#define GPU_TA_PM2_TXRALPHA_SHIFT 19 +#define GPU_TA_PM2_TXRALPHA_MASK (1 << GPU_TA_PM2_TXRALPHA_SHIFT) + +#define GPU_TA_PM2_UVFLIP_SHIFT 17 +#define GPU_TA_PM2_UVFLIP_MASK (3 << GPU_TA_PM2_UVFLIP_SHIFT) + +#define GPU_TA_PM2_UVCLAMP_SHIFT 15 +#define GPU_TA_PM2_UVCLAMP_MASK (3 << GPU_TA_PM2_UVCLAMP_SHIFT) + +#define GPU_TA_PM2_FILTER_SHIFT 12 +#define GPU_TA_PM2_FILTER_MASK (7 << GPU_TA_PM2_FILTER_SHIFT) + +#define GPU_TA_PM2_MIPBIAS_SHIFT 8 +#define GPU_TA_PM2_MIPBIAS_MASK (15 << GPU_TA_PM2_MIPBIAS_SHIFT) + +#define GPU_TA_PM2_TXRENV_SHIFT 6 +#define GPU_TA_PM2_TXRENV_MASK (3 << GPU_TA_PM2_TXRENV_SHIFT) + +#define GPU_TA_PM2_USIZE_SHIFT 3 +#define GPU_TA_PM2_USIZE_MASK (7 << GPU_TA_PM2_USIZE_SHIFT) + +#define GPU_TA_PM2_VSIZE_SHIFT 0 +#define GPU_TA_PM2_VSIZE_MASK (7 << GPU_TA_PM2_VSIZE_SHIFT) + +#define GPU_TA_PM3_MIPMAP_SHIFT 31 +#define GPU_TA_PM3_MIPMAP_MASK (1 << GPU_TA_PM3_MIPMAP_SHIFT) + +#define GPU_TA_PM3_TXRFMT_SHIFT 0 +#define GPU_TA_PM3_TXRFMT_MASK 0xffffffff + +/* Compile a polygon context into a polygon header */ +static inline void CompilePolyHeader(PolyHeader *dst, const PolyContext *src) { + int u, v; + uint32_t txr_base; + + /* Basically we just take each parameter, clip it, shift it + into place, and OR it into the final result. */ + + /* The base values for CMD */ + dst->cmd = GPU_CMD_POLYHDR; + + if(src->txr.enable == GPU_TEXTURE_ENABLE) + dst->cmd |= 8; + + /* Or in the list type, shading type, color and UV formats */ + dst->cmd |= (src->list_type << GPU_TA_CMD_TYPE_SHIFT) & GPU_TA_CMD_TYPE_MASK; + dst->cmd |= (src->fmt.color << GPU_TA_CMD_CLRFMT_SHIFT) & GPU_TA_CMD_CLRFMT_MASK; + dst->cmd |= (src->gen.shading << GPU_TA_CMD_SHADE_SHIFT) & GPU_TA_CMD_SHADE_MASK; + dst->cmd |= (src->fmt.uv << GPU_TA_CMD_UVFMT_SHIFT) & GPU_TA_CMD_UVFMT_MASK; + dst->cmd |= (src->gen.clip_mode << GPU_TA_CMD_USERCLIP_SHIFT) & GPU_TA_CMD_USERCLIP_MASK; + dst->cmd |= (src->fmt.modifier << GPU_TA_CMD_MODIFIER_SHIFT) & GPU_TA_CMD_MODIFIER_MASK; + dst->cmd |= (src->gen.modifier_mode << GPU_TA_CMD_MODIFIERMODE_SHIFT) & GPU_TA_CMD_MODIFIERMODE_MASK; + dst->cmd |= (src->gen.specular << GPU_TA_CMD_SPECULAR_SHIFT) & GPU_TA_CMD_SPECULAR_MASK; + + /* Polygon mode 1 */ + dst->mode1 = (src->depth.comparison << GPU_TA_PM1_DEPTHCMP_SHIFT) & GPU_TA_PM1_DEPTHCMP_MASK; + dst->mode1 |= (src->gen.culling << GPU_TA_PM1_CULLING_SHIFT) & GPU_TA_PM1_CULLING_MASK; + dst->mode1 |= (src->depth.write << GPU_TA_PM1_DEPTHWRITE_SHIFT) & GPU_TA_PM1_DEPTHWRITE_MASK; + dst->mode1 |= (src->txr.enable << GPU_TA_PM1_TXRENABLE_SHIFT) & GPU_TA_PM1_TXRENABLE_MASK; + + /* Polygon mode 2 */ + dst->mode2 = (src->blend.src << GPU_TA_PM2_SRCBLEND_SHIFT) & GPU_TA_PM2_SRCBLEND_MASK; + dst->mode2 |= (src->blend.dst << GPU_TA_PM2_DSTBLEND_SHIFT) & GPU_TA_PM2_DSTBLEND_MASK; + dst->mode2 |= (src->blend.src_enable << GPU_TA_PM2_SRCENABLE_SHIFT) & GPU_TA_PM2_SRCENABLE_MASK; + dst->mode2 |= (src->blend.dst_enable << GPU_TA_PM2_DSTENABLE_SHIFT) & GPU_TA_PM2_DSTENABLE_MASK; + dst->mode2 |= (src->gen.fog_type << GPU_TA_PM2_FOG_SHIFT) & GPU_TA_PM2_FOG_MASK; + dst->mode2 |= (src->gen.color_clamp << GPU_TA_PM2_CLAMP_SHIFT) & GPU_TA_PM2_CLAMP_MASK; + dst->mode2 |= (src->gen.alpha << GPU_TA_PM2_ALPHA_SHIFT) & GPU_TA_PM2_ALPHA_MASK; + + if(src->txr.enable == GPU_TEXTURE_DISABLE) { + dst->mode3 = 0; + } + else { + dst->mode2 |= (src->txr.alpha << GPU_TA_PM2_TXRALPHA_SHIFT) & GPU_TA_PM2_TXRALPHA_MASK; + dst->mode2 |= (src->txr.uv_flip << GPU_TA_PM2_UVFLIP_SHIFT) & GPU_TA_PM2_UVFLIP_MASK; + dst->mode2 |= (src->txr.uv_clamp << GPU_TA_PM2_UVCLAMP_SHIFT) & GPU_TA_PM2_UVCLAMP_MASK; + dst->mode2 |= (src->txr.filter << GPU_TA_PM2_FILTER_SHIFT) & GPU_TA_PM2_FILTER_MASK; + dst->mode2 |= (src->txr.mipmap_bias << GPU_TA_PM2_MIPBIAS_SHIFT) & GPU_TA_PM2_MIPBIAS_MASK; + dst->mode2 |= (src->txr.env << GPU_TA_PM2_TXRENV_SHIFT) & GPU_TA_PM2_TXRENV_MASK; + + switch(src->txr.width) { + case 8: + u = 0; + break; + case 16: + u = 1; + break; + case 32: + u = 2; + break; + case 64: + u = 3; + break; + case 128: + u = 4; + break; + case 256: + u = 5; + break; + case 512: + u = 6; + break; + case 1024: + u = 7; + break; + default: + assert(0 && "Invalid texture U size"); + u = 0; + break; + } + + switch(src->txr.height) { + case 8: + v = 0; + break; + case 16: + v = 1; + break; + case 32: + v = 2; + break; + case 64: + v = 3; + break; + case 128: + v = 4; + break; + case 256: + v = 5; + break; + case 512: + v = 6; + break; + case 1024: + v = 7; + break; + default: + assert(0 && "Invalid texture V size"); + v = 0; + break; + } + + dst->mode2 |= (u << GPU_TA_PM2_USIZE_SHIFT) & GPU_TA_PM2_USIZE_MASK; + dst->mode2 |= (v << GPU_TA_PM2_VSIZE_SHIFT) & GPU_TA_PM2_VSIZE_MASK; + + /* Polygon mode 3 */ + dst->mode3 = (src->txr.mipmap << GPU_TA_PM3_MIPMAP_SHIFT) & GPU_TA_PM3_MIPMAP_MASK; + dst->mode3 |= (src->txr.format << GPU_TA_PM3_TXRFMT_SHIFT) & GPU_TA_PM3_TXRFMT_MASK; + + /* Convert the texture address */ + txr_base = (uint32_t) src->txr.base; + txr_base = (txr_base & 0x00fffff8) >> 3; + dst->mode3 |= txr_base; + } + + if(src->fmt.modifier && src->gen.modifier_mode) { + /* If we're affected by a modifier volume, silently promote the header + to the one that is affected by a modifier volume. */ + dst->d1 = dst->mode2; + dst->d2 = dst->mode3; + } + else { + dst->d1 = dst->d2 = 0xffffffff; + } + + dst->d3 = dst->d4 = 0xffffffff; +} + +#ifdef BACKEND_KOSPVR +#include "platforms/sh4.h" +#else +#include "platforms/software.h" +#endif diff --git a/GL/platforms/sh4.c b/GL/platforms/sh4.c new file mode 100644 index 0000000..23d8c7a --- /dev/null +++ b/GL/platforms/sh4.c @@ -0,0 +1,72 @@ +#include "../platform.h" +#include "sh4.h" + +#define TA_SQ_ADDR (unsigned int *)(void *) \ + (0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0)) + +#define QACRTA ((((unsigned int)0x10000000)>>26)<<2)&0x1c + +#define PVR_VERTEX_BUF_SIZE 2560 * 256 + +void InitGPU(_Bool autosort, _Bool fsaa) { + pvr_init_params_t params = { + /* Enable opaque and translucent polygons with size 32 and 32 */ + {PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32}, + PVR_VERTEX_BUF_SIZE, /* Vertex buffer size */ + 0, /* No DMA */ + fsaa, /* No FSAA */ + (autosort) ? 0 : 1 /* Disable translucent auto-sorting to match traditional GL */ + }; + + pvr_init(¶ms); +} + +void SceneBegin() { + pvr_wait_ready(); + pvr_scene_begin(); + QACR0 = QACRTA; + QACR1 = QACRTA; +} + +void SceneListBegin(GPUList list) { + pvr_list_begin(list); +} + +void SceneListSubmit(void* src, int n) { + uint32_t *d = (uint32_t*) TA_SQ_ADDR; + uint32_t *s = src; + + /* fill/write queues as many times necessary */ + while(n--) { + __asm__("pref @%0" : : "r"(s + 8)); /* prefetch 32 bytes for next loop */ + d[0] = *(s++); + d[1] = *(s++); + d[2] = *(s++); + d[3] = *(s++); + d[4] = *(s++); + d[5] = *(s++); + d[6] = *(s++); + d[7] = *(s++); + __asm__("pref @%0" : : "r"(d)); + d += 8; + } + + /* Wait for both store queues to complete */ + d = (uint32_t *)0xe0000000; + d[0] = d[8] = 0; +} + +void SceneListFinish() { + pvr_list_finish(); +} + +void SceneFinish() { + pvr_scene_finish(); +} + +const VideoMode* GetVideoMode() { + static VideoMode mode; + mode.width = vid_mode->width; + mode.height = vid_mode->height; + return &mode; +} diff --git a/GL/platforms/sh4.h b/GL/platforms/sh4.h new file mode 100644 index 0000000..0bc7dd6 --- /dev/null +++ b/GL/platforms/sh4.h @@ -0,0 +1,124 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "../types.h" +#include "sh4_math.h" + +#define FASTCPY(dst, src, bytes) \ + (bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy(dst, src, bytes) + +#define FASTCPY4(dst, src, bytes) \ + (bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy4(dst, src, bytes) + +#define MEMSET4(dst, v, size) memset4((dst), (v), (size)) + +#define VEC3_NORMALIZE(x, y, z) vec3f_normalize((x), (y), (z)) +#define VEC3_LENGTH(x, y, z, l) vec3f_length((x), (y), (z), (l)) +#define VEC3_DOT(x1, y1, z1, x2, y2, z2, d) vec3f_dot((x1), (y1), (z1), (x2), (y2), (z2), (d)) + +static inline void UploadMatrix4x4(const Matrix4x4* mat) { + mat_load((matrix_t*) mat); +} + +static inline void DownloadMatrix4x4(Matrix4x4* mat) { + mat_store((matrix_t*) mat); +} + +static inline void MultiplyMatrix4x4(const Matrix4x4* mat) { + mat_apply((matrix_t*) mat); +} + +static inline void TransformVec3(float* x) { + mat_trans_single4(x[0], x[1], x[2], x[3]); +} + +/* Transform a 3-element vector using the stored matrix (w == 1) */ +static inline void TransformVec3NoMod(const float* xIn, float* xOut) { + mat_trans_single3_nodiv_nomod(xIn[0], xIn[1], xIn[2], xOut[0], xOut[1], xOut[2]); +} + +/* Transform a 3-element normal using the stored matrix (w == 0)*/ +static inline void TransformNormalNoMod(const float* in, float* out) { + mat_trans_normal3_nomod(in[0], in[1], in[2], out[0], out[1], out[2]); +} + +/* Transform a 4-element vector in-place by the stored matrix */ +inline void TransformVec4(float* x) { + +} + +static inline void TransformVertices(Vertex* vertices, const int count) { + Vertex* it = vertices; + for(int i = 0; i < count; ++i, ++it) { + register float __x __asm__("fr12") = (it->xyz[0]); + register float __y __asm__("fr13") = (it->xyz[1]); + register float __z __asm__("fr14") = (it->xyz[2]); + register float __w __asm__("fr15") = (it->w); + + __asm__ __volatile__( + "fldi1 fr15\n" + "ftrv xmtrx,fv12\n" + : "=f" (__x), "=f" (__y), "=f" (__z), "=f" (__w) + : "0" (__x), "1" (__y), "2" (__z), "3" (__w) + ); + + it->xyz[0] = __x; + it->xyz[1] = __y; + it->xyz[2] = __z; + it->w = __w; + } +} + +void InitGPU(_Bool autosort, _Bool fsaa); + +static inline size_t GPUMemoryAvailable() { + return pvr_mem_available(); +} + +static inline void* GPUMemoryAlloc(size_t size) { + return pvr_mem_malloc(size); +} + +static inline void GPUSetPaletteFormat(GPUPaletteFormat format) { + pvr_set_pal_format(format); +} + +static inline void GPUSetPaletteEntry(uint32_t idx, uint32_t value) { + pvr_set_pal_entry(idx, value); +} + +static inline void GPUSetBackgroundColour(float r, float g, float b) { + pvr_set_bg_color(r, g, b); +} + +#define PT_ALPHA_REF 0x011c + +static inline void GPUSetAlphaCutOff(uint8_t val) { + PVR_SET(PT_ALPHA_REF, val); +} + +static inline void GPUSetClearDepth(float v) { + pvr_set_zclip(v); +} + +static inline void GPUSetFogLinear(float start, float end) { + pvr_fog_table_linear(start, end); +} + +static inline void GPUSetFogExp(float density) { + pvr_fog_table_exp(density); +} + +static inline void GPUSetFogExp2(float density) { + pvr_fog_table_exp2(density); +} + +static inline void GPUSetFogColor(float r, float g, float b, float a) { + pvr_fog_table_color(r, g, b, a); +} diff --git a/GL/sh4_math.h b/GL/platforms/sh4_math.h similarity index 100% rename from GL/sh4_math.h rename to GL/platforms/sh4_math.h diff --git a/GL/platforms/software.c b/GL/platforms/software.c new file mode 100644 index 0000000..7e904a0 --- /dev/null +++ b/GL/platforms/software.c @@ -0,0 +1,330 @@ +#include + +#include +#include + +#include "../platform.h" +#include "software.h" +#include "software/edge_equation.h" +#include "software/parameter_equation.h" + +static size_t AVAILABLE_VRAM = 16 * 1024 * 1024; +static Matrix4x4 MATRIX; + +static SDL_Window* WINDOW = NULL; +static SDL_Renderer* RENDERER = NULL; + +static uint8_t BACKGROUND_COLOR[3] = {0, 0, 0}; + +GPUCulling CULL_MODE = GPU_CULLING_CCW; + + +static VideoMode vid_mode = { + 640, 480 +}; + + +typedef struct GPUVertex { + uint32_t flags; + float x; + float y; + float z; + float u; + float v; + uint8_t bgra[4]; + uint8_t obgra[4]; +} GPUVertex; + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) + +static void DrawTriangle(GPUVertex* v0, GPUVertex* v1, GPUVertex* v2) { + // Compute triangle bounding box. + + int minX = MIN(MIN(v0->x, v1->x), v2->x); + int maxX = MAX(MAX(v0->x, v1->x), v2->x); + int minY = MIN(MIN(v0->y, v1->y), v2->y); + int maxY = MAX(MAX(v0->y, v1->y), v2->y); + + // Clip to scissor rect. + + minX = MAX(minX, 0); + maxX = MIN(maxX, vid_mode.width); + minY = MAX(minY, 0); + maxY = MIN(maxY, vid_mode.height); + + // Compute edge equations. + + EdgeEquation e0, e1, e2; + EdgeEquationInit(&e0, &v0->x, &v1->x); + EdgeEquationInit(&e1, &v1->x, &v2->x); + EdgeEquationInit(&e2, &v2->x, &v0->x); + + float area = 0.5 * (e0.c + e1.c + e2.c); + + /* This is very ugly. I don't understand the math properly + * so I just swap the vertex order if something is back-facing + * and we want to render it. Patches welcome! */ +#define REVERSE_WINDING() \ + GPUVertex* tv = v0; \ + v0 = v1; \ + v1 = tv; \ + EdgeEquationInit(&e0, &v0->x, &v1->x); \ + EdgeEquationInit(&e1, &v1->x, &v2->x); \ + EdgeEquationInit(&e2, &v2->x, &v0->x); \ + area = 0.5f * (e0.c + e1.c + e2.c) \ + + // Check if triangle is backfacing. + if(CULL_MODE == GPU_CULLING_CCW) { + if(area < 0) { + return; + } + } else if(CULL_MODE == GPU_CULLING_CW) { + if(area < 0) { + // We only draw front-facing polygons, so swap + // the back to front and draw + REVERSE_WINDING(); + } else { + // Front facing, so bail + return; + } + } else if(area < 0) { + /* We're not culling, but this is backfacing, so swap vertices and edges */ + REVERSE_WINDING(); + } + + ParameterEquation r, g, b; + + ParameterEquationInit(&r, v0->bgra[2], v1->bgra[2], v2->bgra[2], &e0, &e1, &e2, area); + ParameterEquationInit(&g, v0->bgra[1], v1->bgra[1], v2->bgra[1], &e0, &e1, &e2, area); + ParameterEquationInit(&b, v0->bgra[0], v1->bgra[0], v2->bgra[0], &e0, &e1, &e2, area); + + // Add 0.5 to sample at pixel centers. + for (float x = minX + 0.5f, xm = maxX + 0.5f; x <= xm; x += 1.0f) + for (float y = minY + 0.5f, ym = maxY + 0.5f; y <= ym; y += 1.0f) + { + if (EdgeEquationTestPoint(&e0, x, y) && EdgeEquationTestPoint(&e1, x, y) && EdgeEquationTestPoint(&e2, x, y)) { + int rint = ParameterEquationEvaluate(&r, x, y); + int gint = ParameterEquationEvaluate(&g, x, y); + int bint = ParameterEquationEvaluate(&b, x, y); + SDL_SetRenderDrawColor(RENDERER, rint, gint, bint, 255); + SDL_RenderDrawPoint(RENDERER, x, y); + } + } +} + + +void InitGPU(_Bool autosort, _Bool fsaa) { + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS); + + WINDOW = SDL_CreateWindow( + "GLdc", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + vid_mode.width, vid_mode.height, + SDL_WINDOW_SHOWN + ); + + RENDERER = SDL_CreateRenderer( + WINDOW, -1, SDL_RENDERER_ACCELERATED + ); +} + +void SceneBegin() { + SDL_SetRenderDrawColor(RENDERER, BACKGROUND_COLOR[0], BACKGROUND_COLOR[1], BACKGROUND_COLOR[2], 0); + SDL_RenderClear(RENDERER); +} + +void SceneListBegin(GPUList list) { + +} + +void SceneListSubmit(void* src, int n) { + uint32_t vertex_counter = 0; + const uint32_t* flags = (const uint32_t*) src; + uint32_t step = sizeof(GPUVertex) / sizeof(uint32_t); + + for(int i = 0; i < n; ++i, flags += step) { + if((*flags & GPU_CMD_POLYHDR) == GPU_CMD_POLYHDR) { + vertex_counter = 0; + + uint32_t mode1 = *(flags + 1); + // Extract culling mode + uint32_t mask = mode1 & GPU_TA_PM1_CULLING_MASK; + CULL_MODE = mask >> GPU_TA_PM1_CULLING_SHIFT; + + } else { + switch(*flags) { + case GPU_CMD_VERTEX_EOL: + case GPU_CMD_VERTEX: // Fallthrough + vertex_counter++; + break; + default: + break; + } + } + + if(vertex_counter > 2) { + GPUVertex* v0 = (GPUVertex*) (flags - step - step); + GPUVertex* v1 = (GPUVertex*) (flags - step); + GPUVertex* v2 = (GPUVertex*) (flags); + (vertex_counter % 2 == 0) ? DrawTriangle(v0, v1, v2) : DrawTriangle(v1, v0, v2); + } + + if((*flags) == GPU_CMD_VERTEX_EOL) { + vertex_counter = 0; + } + } +} + +void SceneListFinish() { + +} + +void SceneFinish() { + SDL_RenderPresent(RENDERER); + + /* Only sensible place to hook the quit signal */ + + SDL_Event e = {0}; + + while (SDL_PollEvent(&e)) + switch (e.type) { + case SDL_QUIT: + exit(0); + break; + default: + break; + } +} + +void UploadMatrix4x4(const Matrix4x4* mat) { + memcpy(&MATRIX, mat, sizeof(Matrix4x4)); +} + +void MultiplyMatrix4x4(const Matrix4x4* mat) { + Matrix4x4 product; + + product[0] = MATRIX[0] * (*mat)[0] + MATRIX[4] * (*mat)[1] + MATRIX[8] * (*mat)[2] + MATRIX[12] * (*mat)[3]; + product[1] = MATRIX[1] * (*mat)[0] + MATRIX[5] * (*mat)[1] + MATRIX[9] * (*mat)[2] + MATRIX[13] * (*mat)[3]; + product[2] = MATRIX[2] * (*mat)[0] + MATRIX[6] * (*mat)[1] + MATRIX[10] * (*mat)[2] + MATRIX[14] * (*mat)[3]; + product[3] = MATRIX[3] * (*mat)[0] + MATRIX[7] * (*mat)[1] + MATRIX[11] * (*mat)[2] + MATRIX[15] * (*mat)[3]; + + product[4] = MATRIX[0] * (*mat)[4] + MATRIX[4] * (*mat)[5] + MATRIX[8] * (*mat)[6] + MATRIX[12] * (*mat)[7]; + product[5] = MATRIX[1] * (*mat)[4] + MATRIX[5] * (*mat)[5] + MATRIX[9] * (*mat)[6] + MATRIX[13] * (*mat)[7]; + product[6] = MATRIX[2] * (*mat)[4] + MATRIX[6] * (*mat)[5] + MATRIX[10] * (*mat)[6] + MATRIX[14] * (*mat)[7]; + product[7] = MATRIX[3] * (*mat)[4] + MATRIX[7] * (*mat)[5] + MATRIX[11] * (*mat)[6] + MATRIX[15] * (*mat)[7]; + + product[8] = MATRIX[0] * (*mat)[8] + MATRIX[4] * (*mat)[9] + MATRIX[8] * (*mat)[10] + MATRIX[12] * (*mat)[11]; + product[9] = MATRIX[1] * (*mat)[8] + MATRIX[5] * (*mat)[9] + MATRIX[9] * (*mat)[10] + MATRIX[13] * (*mat)[11]; + product[10] = MATRIX[2] * (*mat)[8] + MATRIX[6] * (*mat)[9] + MATRIX[10] * (*mat)[10] + MATRIX[14] * (*mat)[11]; + product[11] = MATRIX[3] * (*mat)[8] + MATRIX[7] * (*mat)[9] + MATRIX[11] * (*mat)[10] + MATRIX[15] * (*mat)[11]; + + product[12] = MATRIX[0] * (*mat)[12] + MATRIX[4] * (*mat)[13] + MATRIX[8] * (*mat)[14] + MATRIX[12] * (*mat)[15]; + product[13] = MATRIX[1] * (*mat)[12] + MATRIX[5] * (*mat)[13] + MATRIX[9] * (*mat)[14] + MATRIX[13] * (*mat)[15]; + product[14] = MATRIX[2] * (*mat)[12] + MATRIX[6] * (*mat)[13] + MATRIX[10] * (*mat)[14] + MATRIX[14] * (*mat)[15]; + product[15] = MATRIX[3] * (*mat)[12] + MATRIX[7] * (*mat)[13] + MATRIX[11] * (*mat)[14] + MATRIX[15] * (*mat)[15]; + + UploadMatrix4x4(&product); +} + +void DownloadMatrix4x4(Matrix4x4* mat) { + memcpy(mat, &MATRIX, sizeof(Matrix4x4)); +} + +const VideoMode* GetVideoMode() { + return &vid_mode; +} + +size_t GPUMemoryAvailable() { + return AVAILABLE_VRAM; +} + +void* GPUMemoryAlloc(size_t size) { + if(size > AVAILABLE_VRAM) { + return NULL; + } else { + AVAILABLE_VRAM -= size; + return malloc(size); + } +} + +void GPUSetPaletteFormat(GPUPaletteFormat format) { + +} + +void GPUSetPaletteEntry(uint32_t idx, uint32_t value) { + +} + +void GPUSetBackgroundColour(float r, float g, float b) { + BACKGROUND_COLOR[0] = r * 255.0f; + BACKGROUND_COLOR[1] = g * 255.0f; + BACKGROUND_COLOR[2] = b * 255.0f; +} + +void GPUSetAlphaCutOff(uint8_t v) { + +} + +void GPUSetClearDepth(float v) { + +} + +void GPUSetFogLinear(float start, float end) { + +} + +void GPUSetFogExp(float density) { + +} + +void GPUSetFogExp2(float density) { + +} + +void GPUSetFogColor(float r, float g, float b, float a) { + +} + +void TransformVec3NoMod(const float* v, float* ret) { + ret[0] = v[0] * MATRIX[0] + v[1] * MATRIX[4] + v[2] * MATRIX[8] + 1.0f * MATRIX[12]; + ret[1] = v[0] * MATRIX[1] + v[1] * MATRIX[5] + v[2] * MATRIX[9] + 1.0f * MATRIX[13]; + ret[2] = v[0] * MATRIX[2] + v[1] * MATRIX[6] + v[2] * MATRIX[10] + 1.0f * MATRIX[14]; +} + +void TransformVec4NoMod(const float* v, float* ret) { + ret[0] = v[0] * MATRIX[0] + v[1] * MATRIX[4] + v[2] * MATRIX[8] + v[3] * MATRIX[12]; + ret[1] = v[0] * MATRIX[1] + v[1] * MATRIX[5] + v[2] * MATRIX[9] + v[3] * MATRIX[13]; + ret[2] = v[0] * MATRIX[2] + v[1] * MATRIX[6] + v[2] * MATRIX[10] + v[3] * MATRIX[14]; + ret[3] = v[0] * MATRIX[3] + v[1] * MATRIX[7] + v[2] * MATRIX[11] + v[3] * MATRIX[15]; +} + +void TransformVec3(float* v) { + float ret[3]; + TransformVec3NoMod(v, ret); + FASTCPY(v, ret, sizeof(float) * 3); +} + +void TransformVec4(float* v) { + float ret[4]; + TransformVec4NoMod(v, ret); + FASTCPY(v, ret, sizeof(float) * 4); +} + +void TransformVertices(Vertex* vertices, const int count) { + float ret[4]; + for(int i = 0; i < count; ++i, ++vertices) { + ret[0] = vertices->xyz[0]; + ret[1] = vertices->xyz[1]; + ret[2] = vertices->xyz[2]; + ret[3] = 1.0f; + + TransformVec4(ret); + + vertices->xyz[0] = ret[0]; + vertices->xyz[1] = ret[1]; + vertices->xyz[2] = ret[2]; + vertices->w = ret[3]; + } +} diff --git a/GL/platforms/software.h b/GL/platforms/software.h new file mode 100644 index 0000000..5bac618 --- /dev/null +++ b/GL/platforms/software.h @@ -0,0 +1,69 @@ +#pragma once + +#include +#include + +#include "../types.h" + +#define MATH_Fast_Divide(n, d) (n / d) +#define MATH_fmac(a, b, c) (a * b + c) +#define MATH_Fast_Sqrt(x) sqrtf((x)) +#define MATH_fsrra(x) (1.0f / sqrtf((x))) +#define MATH_Fast_Invert(x) (1.0f / (x)) + +#define FASTCPY(dst, src, bytes) memcpy(dst, src, bytes) +#define FASTCPY4(dst, src, bytes) memcpy(dst, src, bytes) +#define MEMSET4(dst, v, size) memset((dst), (v), (size)) + +#define VEC3_NORMALIZE(x, y, z) \ + do { \ + float l = MATH_fsrra((x) * (x) + (y) * (y) + (z) * (z)); \ + x *= l; \ + y *= l; \ + z *= l; \ + } while(0) + +#define VEC3_LENGTH(x, y, z, d) \ + d = MATH_Fast_Sqrt((x) * (x) + (y) * (y) + (z) * (z)) + +#define VEC3_DOT(x1, y1, z1, x2, y2, z2, d) \ + d = (x1 * x2) + (y1 * y2) + (z1 * z2) + +struct PolyHeader; +struct PolyContext; + +void UploadMatrix4x4(const Matrix4x4* mat); +void MultiplyMatrix4x4(const Matrix4x4* mat); +void DownloadMatrix4x4(Matrix4x4* mat); + +/* Transform a 3-element vector in-place using the stored matrix (w == 1) */ +void TransformVec3(float* v); + +/* Transform a 3-element vector using the stored matrix (w == 1) */ +void TransformVec3NoMod(const float* v, float* ret); + +/* Transform a 3-element normal using the stored matrix (w == 0)*/ +static inline void TransformNormalNoMod(const float* xIn, float* xOut) { + +} + +void TransformVertices(Vertex* vertices, const int count); + +void InitGPU(_Bool autosort, _Bool fsaa); + +enum GPUPaletteFormat; + +size_t GPUMemoryAvailable(); +void* GPUMemoryAlloc(size_t size); +void GPUSetPaletteFormat(GPUPaletteFormat format); +void GPUSetPaletteEntry(uint32_t idx, uint32_t value); + +void GPUSetBackgroundColour(float r, float g, float b); +void GPUSetAlphaCutOff(uint8_t v); +void GPUSetClearDepth(float v); + +void GPUSetFogLinear(float start, float end); +void GPUSetFogExp(float density); +void GPUSetFogExp2(float density); +void GPUSetFogColor(float r, float g, float b, float a); + diff --git a/GL/platforms/software/edge_equation.c b/GL/platforms/software/edge_equation.c new file mode 100644 index 0000000..6a6c7cb --- /dev/null +++ b/GL/platforms/software/edge_equation.c @@ -0,0 +1,20 @@ +#include "edge_equation.h" + +void EdgeEquationInit(EdgeEquation* edge, const float* v0, const float* v1) { + edge->a = v0[1] - v1[1]; + edge->b = v1[0] - v0[0]; + edge->c = -(edge->a * (v0[0] + v1[0]) + edge->b * (v0[1] + v1[1])) / 2; + edge->tie = edge->a != 0 ? edge->a > 0 : edge->b > 0; +} + +float EdgeEquationEvaluate(const EdgeEquation* edge, float x, float y) { + return edge->a * x + edge->b * y + edge->c; +} + +bool EdgeEquationTestValue(const EdgeEquation* edge, float value) { + return (value >= 0 || (value == 0 && edge->tie)); +} + +bool EdgeEquationTestPoint(const EdgeEquation* edge, float x, float y) { + return EdgeEquationTestValue(edge, EdgeEquationEvaluate(edge, x, y)); +} diff --git a/GL/platforms/software/edge_equation.h b/GL/platforms/software/edge_equation.h new file mode 100644 index 0000000..2bd1bde --- /dev/null +++ b/GL/platforms/software/edge_equation.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +typedef struct EdgeEquation { + float a; + float b; + float c; + bool tie; +} EdgeEquation; + +void EdgeEquationInit(EdgeEquation* edge, const float* v0, const float* v1); +float EdgeEquationEvaluate(const EdgeEquation* edge, float x, float y); +bool EdgeEquationTestValue(const EdgeEquation* edge, float value); +bool EdgeEquationTestPoint(const EdgeEquation* edge, float x, float y); + diff --git a/GL/platforms/software/parameter_equation.c b/GL/platforms/software/parameter_equation.c new file mode 100644 index 0000000..cf46299 --- /dev/null +++ b/GL/platforms/software/parameter_equation.c @@ -0,0 +1,16 @@ +#include "parameter_equation.h" +#include "edge_equation.h" + +void ParameterEquationInit(ParameterEquation* equation, float p0, float p1, float p2, const EdgeEquation* e0, const EdgeEquation* e1, const EdgeEquation* e2, float area) { + + float factor = 1.0f / (2.0f * area); + + equation->a = factor * (p0 * e0->a + p1 * e1->a + p2 * e2->a); + equation->b = factor * (p0 * e0->b + p1 * e1->b + p2 * e2->b); + equation->c = factor * (p0 * e0->c + p1 * e1->c + p2 * e2->c); +} + + +float ParameterEquationEvaluate(const ParameterEquation* equation, float x, float y) { + return equation->a * x + equation->b * y + equation->c; +} diff --git a/GL/platforms/software/parameter_equation.h b/GL/platforms/software/parameter_equation.h new file mode 100644 index 0000000..6c3beb7 --- /dev/null +++ b/GL/platforms/software/parameter_equation.h @@ -0,0 +1,16 @@ +#pragma once + +typedef struct ParameterEquation { + float a; + float b; + float c; +} ParameterEquation; + +struct EdgeEquation; + +void ParameterEquationInit( + ParameterEquation* equation, + float p0, float p1, float p2, + const struct EdgeEquation* e0, const struct EdgeEquation* e1, const struct EdgeEquation* e2, float area); + +float ParameterEquationEvaluate(const ParameterEquation* equation, float x, float y); diff --git a/GL/private.h b/GL/private.h index cf6f789..2908508 100644 --- a/GL/private.h +++ b/GL/private.h @@ -2,16 +2,17 @@ #define PRIVATE_H #include -#include -#include -#include -#include -#include +#include + +#include "platform.h" +#include "types.h" + +#include "../include/GL/gl.h" +#include "../include/GL/glext.h" +#include "../include/GL/glkos.h" -#include "../include/gl.h" #include "../containers/aligned_vector.h" #include "../containers/named_array.h" -#include "sh4_math.h" extern void* memcpy4 (void *dest, const void *src, size_t count); @@ -20,12 +21,6 @@ extern void* memcpy4 (void *dest, const void *src, size_t count); #define GL_FORCE_INLINE static GL_INLINE_DEBUG #define _GL_UNUSED(x) (void)(x) -#define FASTCPY(dst, src, bytes) \ - (bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy(dst, src, bytes); - -#define FASTCPY4(dst, src, bytes) \ - (bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy4(dst, src, bytes); - #define _PACK4(v) ((v * 0xF) / 0xFF) #define PACK_ARGB4444(a,r,g,b) (_PACK4(a) << 12) | (_PACK4(r) << 8) | (_PACK4(g) << 4) | (_PACK4(b)) #define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) ) @@ -46,7 +41,6 @@ extern void* memcpy4 (void *dest, const void *src, size_t count); #define MAX_TEXTURE_SIZE 1024 -typedef float Matrix4x4[16]; /* This gives us an easy way to switch * internal matrix order if necessary */ @@ -89,9 +83,6 @@ typedef float Matrix4x4[16]; #define M15 15 #endif -typedef struct { - pvr_poly_hdr_t hdr; -} PVRHeader; typedef struct { unsigned int flags; /* Constant PVR_CMD_USERCLIP */ @@ -192,19 +183,6 @@ typedef struct { GLfloat specularMaterial[4]; } LightSource; -typedef struct { - /* Same 32 byte layout as pvr_vertex_t */ - uint32_t flags; - float xyz[3]; - float uv[2]; - uint8_t bgra[4]; - - /* In the pvr_vertex_t structure, this next 4 bytes is oargb - * but we're not using that for now, so having W here makes the code - * simpler */ - float w; -} Vertex; - #define argbcpy(dst, src) \ *((GLuint*) dst) = *((GLuint*) src) \ @@ -263,7 +241,7 @@ typedef struct { AlignedVector* extras; } SubmissionTarget; -PVRHeader* _glSubmissionTargetHeader(SubmissionTarget* target); +PolyHeader* _glSubmissionTargetHeader(SubmissionTarget* target); Vertex* _glSubmissionTargetStart(SubmissionTarget* target); Vertex* _glSubmissionTargetEnd(SubmissionTarget* target); @@ -310,10 +288,10 @@ Matrix4x4* _glGetModelViewMatrix(); void _glWipeTextureOnFramebuffers(GLuint texture); GLubyte _glCheckImmediateModeInactive(const char* func); -pvr_poly_cxt_t* _glGetPVRContext(); +PolyContext* _glGetPVRContext(); GLubyte _glInitTextures(); -void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit); +void _glUpdatePVRTextureContext(PolyContext* context, GLshort textureUnit); void _glAllocateSpaceForMipmaps(TextureObject* active); typedef struct { @@ -365,7 +343,7 @@ typedef struct { float finalColour[4]; //16 bytes (to 40) } EyeSpaceData; -extern void _glPerformLighting(Vertex* vertices, EyeSpaceData *es, const int32_t count); +extern void _glPerformLighting(Vertex* vertices, EyeSpaceData *es, const uint32_t count); unsigned char _glIsClippingEnabled(); void _glEnableClipping(unsigned char v); @@ -378,7 +356,6 @@ GLuint _glFreeTextureMemory(); GLuint _glUsedTextureMemory(); GLuint _glFreeContiguousTextureMemory(); -#define PVR_VERTEX_BUF_SIZE 2560 * 256 #define MAX_TEXTURE_UNITS 2 #define MAX_LIGHTS 8 diff --git a/GL/profiler.c b/GL/profiler.c index c74d84a..6a27981 100644 --- a/GL/profiler.c +++ b/GL/profiler.c @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/GL/state.c b/GL/state.c index 4f08ea5..9487e6a 100644 --- a/GL/state.c +++ b/GL/state.c @@ -2,19 +2,11 @@ #include #include -#include -#include -#include - -#include "../include/gl.h" -#include "../include/glext.h" -#include "../include/glkos.h" - #include "private.h" -static pvr_poly_cxt_t GL_CONTEXT; +static PolyContext GL_CONTEXT; -pvr_poly_cxt_t* _glGetPVRContext() { +PolyContext *_glGetPVRContext() { return &GL_CONTEXT; } @@ -43,12 +35,12 @@ GLboolean _glIsSharedTexturePaletteEnabled() { static int _calc_pvr_face_culling() { if(!CULLING_ENABLED) { - return PVR_CULLING_NONE; + return GPU_CULLING_NONE; } else { if(CULL_FACE == GL_BACK) { - return (FRONT_FACE == GL_CW) ? PVR_CULLING_CCW : PVR_CULLING_CW; + return (FRONT_FACE == GL_CW) ? GPU_CULLING_CCW : GPU_CULLING_CW; } else { - return (FRONT_FACE == GL_CCW) ? PVR_CULLING_CCW : PVR_CULLING_CW; + return (FRONT_FACE == GL_CCW) ? GPU_CULLING_CCW : GPU_CULLING_CW; } } } @@ -58,28 +50,28 @@ static GLboolean DEPTH_TEST_ENABLED = GL_FALSE; static int _calc_pvr_depth_test() { if(!DEPTH_TEST_ENABLED) { - return PVR_DEPTHCMP_ALWAYS; + return GPU_DEPTHCMP_ALWAYS; } switch(DEPTH_FUNC) { case GL_NEVER: - return PVR_DEPTHCMP_NEVER; + return GPU_DEPTHCMP_NEVER; case GL_LESS: - return PVR_DEPTHCMP_GREATER; + return GPU_DEPTHCMP_GREATER; case GL_EQUAL: - return PVR_DEPTHCMP_EQUAL; + return GPU_DEPTHCMP_EQUAL; case GL_LEQUAL: - return PVR_DEPTHCMP_GEQUAL; + return GPU_DEPTHCMP_GEQUAL; case GL_GREATER: - return PVR_DEPTHCMP_LESS; + return GPU_DEPTHCMP_LESS; case GL_NOTEQUAL: - return PVR_DEPTHCMP_NOTEQUAL; + return GPU_DEPTHCMP_NOTEQUAL; case GL_GEQUAL: - return PVR_DEPTHCMP_LEQUAL; + return GPU_DEPTHCMP_LEQUAL; break; case GL_ALWAYS: default: - return PVR_DEPTHCMP_ALWAYS; + return GPU_DEPTHCMP_ALWAYS; } } @@ -105,32 +97,32 @@ GLboolean _glIsAlphaTestEnabled() { static int _calcPVRBlendFactor(GLenum factor) { switch(factor) { case GL_ZERO: - return PVR_BLEND_ZERO; + return GPU_BLEND_ZERO; case GL_SRC_ALPHA: - return PVR_BLEND_SRCALPHA; + return GPU_BLEND_SRCALPHA; case GL_DST_COLOR: - return PVR_BLEND_DESTCOLOR; + return GPU_BLEND_DESTCOLOR; case GL_DST_ALPHA: - return PVR_BLEND_DESTALPHA; + return GPU_BLEND_DESTALPHA; case GL_ONE_MINUS_DST_COLOR: - return PVR_BLEND_INVDESTCOLOR; + return GPU_BLEND_INVDESTCOLOR; case GL_ONE_MINUS_SRC_ALPHA: - return PVR_BLEND_INVSRCALPHA; + return GPU_BLEND_INVSRCALPHA; case GL_ONE_MINUS_DST_ALPHA: - return PVR_BLEND_INVDESTALPHA; + return GPU_BLEND_INVDESTALPHA; case GL_ONE: - return PVR_BLEND_ONE; + return GPU_BLEND_ONE; default: fprintf(stderr, "Invalid blend mode: %u\n", (unsigned int) factor); - return PVR_BLEND_ONE; + return GPU_BLEND_ONE; } } -static void _updatePVRBlend(pvr_poly_cxt_t* context) { +static void _updatePVRBlend(PolyContext* context) { if(BLEND_ENABLED || ALPHA_TEST_ENABLED) { - context->gen.alpha = PVR_ALPHA_ENABLE; + context->gen.alpha = GPU_ALPHA_ENABLE; } else { - context->gen.alpha = PVR_ALPHA_DISABLE; + context->gen.alpha = GPU_ALPHA_DISABLE; } context->blend.src = _calcPVRBlendFactor(BLEND_SFACTOR); @@ -158,21 +150,21 @@ GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func) { GLboolean TEXTURES_ENABLED [] = {GL_FALSE, GL_FALSE}; -void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) { +void _glUpdatePVRTextureContext(PolyContext *context, GLshort textureUnit) { const TextureObject *tx1 = (textureUnit == 0) ? _glGetTexture0() : _glGetTexture1(); /* Disable all texturing to start with */ - context->txr.enable = PVR_TEXTURE_DISABLE; - context->txr2.enable = PVR_TEXTURE_DISABLE; - context->txr2.alpha = PVR_TXRALPHA_DISABLE; + context->txr.enable = GPU_TEXTURE_DISABLE; + context->txr2.enable = GPU_TEXTURE_DISABLE; + context->txr2.alpha = GPU_TXRALPHA_DISABLE; if(!TEXTURES_ENABLED[textureUnit] || !tx1) { return; } - context->txr.alpha = (BLEND_ENABLED || ALPHA_TEST_ENABLED) ? PVR_TXRALPHA_ENABLE : PVR_TXRALPHA_DISABLE; + context->txr.alpha = (BLEND_ENABLED || ALPHA_TEST_ENABLED) ? GPU_TXRALPHA_ENABLE : GPU_TXRALPHA_DISABLE; - GLuint filter = PVR_FILTER_NEAREST; + GLuint filter = GPU_FILTER_NEAREST; GLboolean enableMipmaps = GL_FALSE; switch(tx1->minFilter) { @@ -199,17 +191,17 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) { if(enableMipmaps) { if(tx1->minFilter == GL_LINEAR_MIPMAP_NEAREST) { - filter = PVR_FILTER_TRILINEAR1; + filter = GPU_FILTER_TRILINEAR1; } else if(tx1->minFilter == GL_LINEAR_MIPMAP_LINEAR) { - filter = PVR_FILTER_TRILINEAR2; + filter = GPU_FILTER_TRILINEAR2; } else if(tx1->minFilter == GL_NEAREST_MIPMAP_LINEAR) { - filter = PVR_FILTER_BILINEAR; + filter = GPU_FILTER_BILINEAR; } else { - filter = PVR_FILTER_NEAREST; + filter = GPU_FILTER_NEAREST; } } else { if(tx1->minFilter == GL_LINEAR && tx1->magFilter == GL_LINEAR) { - filter = PVR_FILTER_BILINEAR; + filter = GPU_FILTER_BILINEAR; } } @@ -221,7 +213,7 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) { } if(tx1->data) { - context->txr.enable = PVR_TEXTURE_ENABLE; + context->txr.enable = GPU_TEXTURE_ENABLE; context->txr.filter = filter; context->txr.width = tx1->width; context->txr.height = tx1->height; @@ -239,14 +231,14 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) { if(tx1->isPaletted) { if(_glIsSharedTexturePaletteEnabled()) { TexturePalette* palette = _glGetSharedPalette(tx1->shared_bank); - context->txr.format |= PVR_TXRFMT_8BPP_PAL(palette->bank); + context->txr.format |= GPUPaletteSelect8BPP(palette->bank); } else { - context->txr.format |= PVR_TXRFMT_8BPP_PAL((tx1->palette) ? tx1->palette->bank : 0); + context->txr.format |= GPUPaletteSelect8BPP((tx1->palette) ? tx1->palette->bank : 0); } } context->txr.env = tx1->env; - context->txr.uv_flip = PVR_UVFLIP_NONE; + context->txr.uv_flip = GPU_UVFLIP_NONE; context->txr.uv_clamp = tx1->uv_clamp; } } @@ -262,12 +254,12 @@ GLboolean _glIsColorMaterialEnabled() { static GLfloat CLEAR_COLOUR[3]; void _glInitContext() { - memset(&GL_CONTEXT, 0, sizeof(pvr_poly_cxt_t)); + memset(&GL_CONTEXT, 0, sizeof(PolyContext)); - GL_CONTEXT.list_type = PVR_LIST_OP_POLY; - GL_CONTEXT.fmt.color = PVR_CLRFMT_ARGBPACKED; - GL_CONTEXT.fmt.uv = PVR_UVFMT_32BIT; - GL_CONTEXT.gen.color_clamp = PVR_CLRCLAMP_DISABLE; + GL_CONTEXT.list_type = GPU_LIST_OP_POLY; + GL_CONTEXT.fmt.color = GPU_CLRFMT_ARGBPACKED; + GL_CONTEXT.fmt.uv = GPU_UVFMT_32BIT; + GL_CONTEXT.gen.color_clamp = GPU_CLRCLAMP_DISABLE; glClearDepth(1.0f); glDepthFunc(GL_LESS); @@ -309,13 +301,13 @@ GLAPI void APIENTRY glEnable(GLenum cap) { _updatePVRBlend(&GL_CONTEXT); } break; case GL_SCISSOR_TEST: { - GL_CONTEXT.gen.clip_mode = PVR_USERCLIP_INSIDE; + GL_CONTEXT.gen.clip_mode = GPU_USERCLIP_INSIDE; } break; case GL_LIGHTING: { LIGHTING_ENABLED = GL_TRUE; } break; case GL_FOG: - GL_CONTEXT.gen.fog_type = PVR_FOG_TABLE; + GL_CONTEXT.gen.fog_type = GPU_FOG_TABLE; break; case GL_COLOR_MATERIAL: COLOR_MATERIAL_ENABLED = GL_TRUE; @@ -372,13 +364,13 @@ GLAPI void APIENTRY glDisable(GLenum cap) { _updatePVRBlend(&GL_CONTEXT); break; case GL_SCISSOR_TEST: { - GL_CONTEXT.gen.clip_mode = PVR_USERCLIP_DISABLE; + GL_CONTEXT.gen.clip_mode = GPU_USERCLIP_DISABLE; } break; case GL_LIGHTING: { LIGHTING_ENABLED = GL_FALSE; } break; case GL_FOG: - GL_CONTEXT.gen.fog_type = PVR_FOG_DISABLE; + GL_CONTEXT.gen.fog_type = GPU_FOG_DISABLE; break; case GL_COLOR_MATERIAL: COLOR_MATERIAL_ENABLED = GL_FALSE; @@ -419,7 +411,7 @@ GLAPI void APIENTRY glDisable(GLenum cap) { /* Clear Caps */ GLAPI void APIENTRY glClear(GLuint mode) { if(mode & GL_COLOR_BUFFER_BIT) { - pvr_set_bg_color(CLEAR_COLOUR[0], CLEAR_COLOUR[1], CLEAR_COLOUR[2]); + GPUSetBackgroundColour(CLEAR_COLOUR[0], CLEAR_COLOUR[1], CLEAR_COLOUR[2]); } } @@ -429,9 +421,12 @@ GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { if(b > 1) b = 1; if(a > 1) a = 1; - CLEAR_COLOUR[0] = r * a; - CLEAR_COLOUR[1] = g * a; - CLEAR_COLOUR[2] = b * a; + /* FIXME: The background-poly doesn't take an alpha value */ + _GL_UNUSED(a); + + CLEAR_COLOUR[0] = r; + CLEAR_COLOUR[1] = g; + CLEAR_COLOUR[2] = b; } /* Depth Testing */ @@ -441,7 +436,7 @@ GLAPI void APIENTRY glClearDepthf(GLfloat depth) { GLAPI void APIENTRY glClearDepth(GLfloat depth) { /* We reverse because using invW means that farther Z == lower number */ - pvr_set_zclip(1.0f - depth); + GPUSetClearDepth(1.0f - depth); } GLAPI void APIENTRY glDrawBuffer(GLenum mode) { @@ -455,7 +450,7 @@ GLAPI void APIENTRY glReadBuffer(GLenum mode) { } 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) ? GPU_DEPTHWRITE_ENABLE : GPU_DEPTHWRITE_DISABLE; } GLAPI void APIENTRY glDepthFunc(GLenum func) { @@ -484,12 +479,12 @@ GLAPI void APIENTRY glCullFace(GLenum mode) { } GLenum _glGetShadeModel() { - return (GL_CONTEXT.gen.shading == PVR_SHADE_FLAT) ? GL_FLAT : GL_SMOOTH; + return (GL_CONTEXT.gen.shading == GPU_SHADE_FLAT) ? GL_FLAT : GL_SMOOTH; } /* Shading - Flat or Goraud */ GLAPI void APIENTRY glShadeModel(GLenum mode) { - GL_CONTEXT.gen.shading = (mode == GL_SMOOTH) ? PVR_SHADE_GOURAUD : PVR_SHADE_FLAT; + GL_CONTEXT.gen.shading = (mode == GL_SMOOTH) ? GPU_SHADE_GOURAUD : GPU_SHADE_FLAT; } /* Blending */ @@ -499,7 +494,6 @@ GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { _updatePVRBlend(&GL_CONTEXT); } -#define PT_ALPHA_REF 0x011c GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref) { GLint validFuncs[] = { @@ -512,7 +506,7 @@ GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref) { } GLubyte val = (GLubyte)(ref * 255.0f); - PVR_SET(PT_ALPHA_REF, val); + GPUSetAlphaCutOff(val); } void glLineWidth(GLfloat width) { @@ -561,6 +555,9 @@ void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { PVRTileClipCommand *c = aligned_vector_extend(&_glActivePolyList()->vector, 1); GLint miny, maxx, maxy; + + const VideoMode* vid_mode = GetVideoMode(); + GLsizei gl_scissor_width = MAX( MIN(width, vid_mode->width), 0 ); GLsizei gl_scissor_height = MAX( MIN(height, vid_mode->height), 0 ); @@ -570,7 +567,7 @@ void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { maxy = (gl_scissor_height + miny); /* load command structure while mapping screen coords to TA tiles */ - c->flags = PVR_CMD_USERCLIP; + c->flags = GPU_CMD_USERCLIP; c->d1 = c->d2 = c->d3 = 0; c->sx = CLAMP(x / 32, 0, vid_mode->width / 32); c->sy = CLAMP(miny / 32, 0, vid_mode->height / 32); @@ -583,7 +580,7 @@ GLboolean APIENTRY glIsEnabled(GLenum cap) { case GL_DEPTH_TEST: return DEPTH_TEST_ENABLED; case GL_SCISSOR_TEST: - return GL_CONTEXT.gen.clip_mode == PVR_USERCLIP_INSIDE; + return GL_CONTEXT.gen.clip_mode == GPU_USERCLIP_INSIDE; case GL_CULL_FACE: return CULLING_ENABLED; case GL_LIGHTING: @@ -643,10 +640,10 @@ void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) { void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) { switch(pname) { case GL_PROJECTION_MATRIX: - memcpy4(params, _glGetProjectionMatrix(), sizeof(float) * 16); + FASTCPY4(params, _glGetProjectionMatrix(), sizeof(float) * 16); break; case GL_MODELVIEW_MATRIX: - memcpy4(params, _glGetModelViewMatrix(), sizeof(float) * 16); + FASTCPY4(params, _glGetModelViewMatrix(), sizeof(float) * 16); break; case GL_POLYGON_OFFSET_FACTOR: *params = OFFSET_FACTOR; diff --git a/GL/texture.c b/GL/texture.c index e052e83..fca7c07 100644 --- a/GL/texture.c +++ b/GL/texture.c @@ -7,13 +7,10 @@ #include #include "config.h" -#include "../include/glext.h" -#include "../include/glkos.h" +#include "platform.h" #include "yalloc/yalloc.h" -#include - /* We always leave this amount of vram unallocated to prevent * issues with the allocator */ #define PVR_MEM_BUFFER_SIZE (64 * 1024) @@ -55,7 +52,7 @@ static TexturePalette* _initTexturePalette() { TexturePalette* palette = (TexturePalette*) malloc(sizeof(TexturePalette)); assert(palette); - memset4(palette, 0x0, sizeof(TexturePalette)); + MEMSET4(palette, 0x0, sizeof(TexturePalette)); palette->bank = -1; return palette; } @@ -115,6 +112,54 @@ static void _glReleasePaletteSlot(GLshort slot, GLushort size) { } } +/* 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) ) + + +static void GPUTextureTwiddle8PPP(void* src, void* dst, uint32_t w, uint32_t h) { + uint32_t x, y, yout, min, mask; + + min = MIN(w, h); + mask = min - 1; + + uint8_t* pixels; + uint16_t* vtex; + pixels = (uint8_t*) src; + vtex = (uint16_t*) dst; + + for(y = 0; y < h; y += 2) { + yout = 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); + } + } +} + +static void GPUTextureTwiddle16BPP(void * src, void* dst, uint32_t w, uint32_t h) { + uint32_t x, y, yout, min, mask; + + min = MIN(w, h); + mask = min - 1; + + uint16_t* pixels; + uint16_t* vtex; + pixels = (uint16_t*) src; + vtex = (uint16_t*) dst; + + for(y = 0; y < h; y++) { + yout = y; + + for(x = 0; x < w; x++) { + vtex[TWIDOUT(x & mask, yout & mask) + + (x / min + yout / min)*min * min] = pixels[y * w + x]; + } + } +} + TexturePalette* _glGetSharedPalette(GLshort bank) { assert(bank >= 0 && bank < 4); return SHARED_PALETTES[bank]; @@ -124,10 +169,10 @@ void _glSetInternalPaletteFormat(GLenum val) { INTERNAL_PALETTE_FORMAT = val; if(INTERNAL_PALETTE_FORMAT == GL_RGBA4) { - pvr_set_pal_format(PVR_PAL_ARGB4444); + GPUSetPaletteFormat(GPU_PAL_ARGB4444); } else { assert(INTERNAL_PALETTE_FORMAT == GL_RGBA8); - pvr_set_pal_format(PVR_PAL_ARGB8888); + GPUSetPaletteFormat(GPU_PAL_ARGB8888); } } @@ -146,9 +191,9 @@ void _glApplyColorTable(TexturePalette* src) { for(i = 0; i < src->width; ++i) { GLubyte* entry = &src->data[i * 4]; if(INTERNAL_PALETTE_FORMAT == GL_RGBA8) { - pvr_set_pal_entry(offset + i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2])); + GPUSetPaletteEntry(offset + i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2])); } else { - pvr_set_pal_entry(offset + i, PACK_ARGB4444(entry[3], entry[0], entry[1], entry[2])); + GPUSetPaletteEntry(offset + i, PACK_ARGB4444(entry[3], entry[0], entry[1], entry[2])); } } } @@ -333,9 +378,9 @@ GLubyte _glInitTextures() { memset((void*) BANKS_USED, 0x0, sizeof(BANKS_USED)); memset((void*) SUBBANKS_USED, 0x0, sizeof(SUBBANKS_USED)); - size_t vram_free = pvr_mem_available(); + size_t vram_free = GPUMemoryAvailable(); YALLOC_SIZE = vram_free - PVR_MEM_BUFFER_SIZE; /* Take all but 64kb VRAM */ - YALLOC_BASE = pvr_mem_malloc(YALLOC_SIZE); + YALLOC_BASE = GPUMemoryAlloc(YALLOC_SIZE); yalloc_init(YALLOC_BASE, YALLOC_SIZE); return 1; } @@ -375,7 +420,7 @@ static void _glInitializeTextureObject(TextureObject* txr, unsigned int id) { txr->width = txr->height = 0; txr->mipmap = 0; txr->uv_clamp = 0; - txr->env = PVR_TXRENV_MODULATEALPHA; + txr->env = GPU_TXRENV_MODULATEALPHA; txr->data = NULL; txr->mipmapCount = 0; txr->minFilter = GL_NEAREST; @@ -497,13 +542,13 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) { switch(param) { case GL_MODULATE: - active->env = PVR_TXRENV_MODULATEALPHA; + active->env = GPU_TXRENV_MODULATEALPHA; break; case GL_DECAL: - active->env = PVR_TXRENV_DECAL; + active->env = GPU_TXRENV_DECAL; break; case GL_REPLACE: - active->env = PVR_TXRENV_REPLACE; + active->env = GPU_TXRENV_REPLACE; break; default: break; @@ -631,7 +676,7 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target, active->data = yalloc_alloc_and_defrag(imageSize); if(data) { - sq_cpy(active->data, data, imageSize); + FASTCPY(active->data, data, imageSize); } } @@ -722,47 +767,47 @@ static GLint _cleanInternalFormat(GLint internalFormat) { * the type was already 1555 (1-bit alpha) in which case we return that */ if(type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { - return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED; + return GPU_TXRFMT_ARGB1555 | GPU_TXRFMT_NONTWIDDLED; } else if(type == GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS) { - return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED; + return GPU_TXRFMT_ARGB1555 | GPU_TXRFMT_TWIDDLED; } else if(type == GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS) { - return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED; + return GPU_TXRFMT_ARGB4444 | GPU_TXRFMT_TWIDDLED; } else { - return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED; + return GPU_TXRFMT_ARGB4444 | GPU_TXRFMT_NONTWIDDLED; } case GL_RED: case GL_RGB: /* No alpha? Return RGB565 which is the best we can do without using palettes */ - return PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED; + return GPU_TXRFMT_RGB565 | GPU_TXRFMT_NONTWIDDLED; /* Compressed and twiddled versions */ case GL_UNSIGNED_SHORT_5_6_5_TWID_KOS: - return PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED; + return GPU_TXRFMT_RGB565 | GPU_TXRFMT_TWIDDLED; case GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS: - return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED; + return GPU_TXRFMT_ARGB4444 | GPU_TXRFMT_TWIDDLED; case GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS: - return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED; + return GPU_TXRFMT_ARGB1555 | GPU_TXRFMT_TWIDDLED; case GL_COMPRESSED_RGB_565_VQ_KOS: case GL_COMPRESSED_RGB_565_VQ_MIPMAP_KOS: - return PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE; + return GPU_TXRFMT_RGB565 | GPU_TXRFMT_NONTWIDDLED | GPU_TXRFMT_VQ_ENABLE; case GL_COMPRESSED_RGB_565_VQ_TWID_KOS: case GL_COMPRESSED_RGB_565_VQ_MIPMAP_TWID_KOS: - return PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; + return GPU_TXRFMT_RGB565 | GPU_TXRFMT_TWIDDLED | GPU_TXRFMT_VQ_ENABLE; case GL_COMPRESSED_ARGB_4444_VQ_TWID_KOS: case GL_COMPRESSED_ARGB_4444_VQ_MIPMAP_TWID_KOS: - return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; + return GPU_TXRFMT_ARGB4444 | GPU_TXRFMT_TWIDDLED | GPU_TXRFMT_VQ_ENABLE; case GL_COMPRESSED_ARGB_4444_VQ_KOS: case GL_COMPRESSED_ARGB_4444_VQ_MIPMAP_KOS: - return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE; + return GPU_TXRFMT_ARGB4444 | GPU_TXRFMT_NONTWIDDLED | GPU_TXRFMT_VQ_ENABLE; case GL_COMPRESSED_ARGB_1555_VQ_KOS: case GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_KOS: - return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE; + return GPU_TXRFMT_ARGB1555 | GPU_TXRFMT_NONTWIDDLED | GPU_TXRFMT_VQ_ENABLE; case GL_COMPRESSED_ARGB_1555_VQ_TWID_KOS: case GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_TWID_KOS: - return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; + return GPU_TXRFMT_ARGB1555 | GPU_TXRFMT_TWIDDLED | GPU_TXRFMT_VQ_ENABLE; case GL_COLOR_INDEX8_EXT: - return PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_TWIDDLED; + return GPU_TXRFMT_PAL8BPP | GPU_TXRFMT_TWIDDLED; case GL_COLOR_INDEX4_EXT: - return PVR_TXRFMT_PAL4BPP | PVR_TXRFMT_TWIDDLED; + return GPU_TXRFMT_PAL4BPP | GPU_TXRFMT_TWIDDLED; default: return 0; } @@ -1228,9 +1273,9 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, const GLubyte *pixels = (GLubyte*) (conversionBuffer) ? conversionBuffer : data; if(internalFormat == GL_COLOR_INDEX8_EXT) { - pvr_txr_load_ex((void*) pixels, targetData, width, height, PVR_TXRLOAD_8BPP); + GPUTextureTwiddle8PPP((void*) pixels, targetData, width, height); } else { - pvr_txr_load_ex((void*) pixels, targetData, width, height, PVR_TXRLOAD_16BPP); + GPUTextureTwiddle16BPP((void*) pixels, targetData, width, height); } /* We make sure we remove nontwiddled and add twiddled. We could always diff --git a/GL/types.h b/GL/types.h new file mode 100644 index 0000000..99758e2 --- /dev/null +++ b/GL/types.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +typedef struct { + /* Same 32 byte layout as pvr_vertex_t */ + uint32_t flags; + float xyz[3]; + float uv[2]; + uint8_t bgra[4]; + + /* In the pvr_vertex_t structure, this next 4 bytes is oargb + * but we're not using that for now, so having W here makes the code + * simpler */ + float w; +} Vertex; diff --git a/GL/util.c b/GL/util.c index eaf2e17..835dd98 100644 --- a/GL/util.c +++ b/GL/util.c @@ -1,4 +1,4 @@ -#include "../include/glkos.h" +#include "private.h" void APIENTRY glVertexPackColor3fKOS(GLVertexKOS* vertex, float r, float g, float b) { vertex->bgra[3] = 255; diff --git a/GL/version.c.in b/GL/version.c.in new file mode 100644 index 0000000..7e37b06 --- /dev/null +++ b/GL/version.c.in @@ -0,0 +1,2 @@ + +const char* GLDC_VERSION = "@GLDC_VERSION@"; diff --git a/Makefile b/Makefile deleted file mode 100644 index 0fa72f6..0000000 --- a/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# KallistiOS ##version## -# -# kos-ports/libgl Makefile -# Copyright (C) 2013, 2014 Josh Pearson -# Copyright (C) 2014 Lawrence Sebald -# Copyright (C) 2020 Luke Benstead - -TARGET = libGLdc.a -OBJS = GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o GL/glu.o GL/version.h -OBJS += GL/matrix.o GL/fog.o GL/error.o GL/clip.o containers/stack.o containers/named_array.o containers/aligned_vector.o GL/profiler.o -OBJS += GL/yalloc/yalloc.o - -SUBDIRS = - -KOS_CFLAGS += -ffast-math -Ofast -Iinclude - -GL/version.h: - rm -f $@ - @printf '#pragma once\n#define GLDC_VERSION "$(shell git describe --abbrev=4 --dirty --always --tags)"\n' > $@ - -link: - $(KOS_AR) rcs $(TARGET) $(OBJS) - -build: GL/version.h $(OBJS) link - - -samples: build - $(KOS_MAKE) -C samples all - -defaultall: create_kos_link $(OBJS) subdirs linklib samples - -include $(KOS_BASE)/addons/Makefile.prefab - -# creates the kos link to the headers -create_kos_link: - rm -f ../include/GL - ln -s ../GLdc/include ../include/GL diff --git a/containers/aligned_vector.h b/containers/aligned_vector.h index dbbcda4..b64d089 100644 --- a/containers/aligned_vector.h +++ b/containers/aligned_vector.h @@ -1,14 +1,12 @@ #pragma once -#ifndef ALIGNED_VECTOR_H -#define ALIGNED_VECTOR_H +#include +#include #ifdef __cplusplus extern "C" { #endif -#include - typedef struct { unsigned int size; unsigned int capacity; @@ -39,5 +37,3 @@ static inline void* aligned_vector_back(AlignedVector* vector){ #ifdef __cplusplus } #endif - -#endif // ALIGNED_VECTOR_H diff --git a/include/gl.h b/include/GL/gl.h similarity index 100% rename from include/gl.h rename to include/GL/gl.h diff --git a/include/glext.h b/include/GL/glext.h similarity index 100% rename from include/glext.h rename to include/GL/glext.h diff --git a/include/glkos.h b/include/GL/glkos.h similarity index 99% rename from include/glkos.h rename to include/GL/glkos.h index dd290bb..184ecaf 100644 --- a/include/glkos.h +++ b/include/GL/glkos.h @@ -4,6 +4,9 @@ __BEGIN_DECLS +extern const char* GLDC_VERSION; + + /* * Dreamcast specific compressed + twiddled formats. * We use constants from the range 0xEEE0 onwards diff --git a/include/glu.h b/include/GL/glu.h similarity index 98% rename from include/glu.h rename to include/GL/glu.h index ee9717d..0c8420c 100644 --- a/include/glu.h +++ b/include/GL/glu.h @@ -17,7 +17,7 @@ __BEGIN_DECLS #ifndef BUILD_LIBGL -#include +#include "gl.h" #endif #define GLU_FALSE 0 diff --git a/samples/blend_test/main.c b/samples/blend_test/main.c index 2635e9b..191bbe9 100644 --- a/samples/blend_test/main.c +++ b/samples/blend_test/main.c @@ -4,9 +4,9 @@ * output and incorrect depth testing */ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. diff --git a/samples/depth_funcs/main.c b/samples/depth_funcs/main.c index aab0184..fe90f35 100644 --- a/samples/depth_funcs/main.c +++ b/samples/depth_funcs/main.c @@ -1,6 +1,6 @@ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. diff --git a/samples/depth_funcs_alpha_testing/gl_png.c b/samples/depth_funcs_alpha_testing/gl_png.c index 05dedc4..78298b3 100644 --- a/samples/depth_funcs_alpha_testing/gl_png.c +++ b/samples/depth_funcs_alpha_testing/gl_png.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -188,7 +187,7 @@ int dtex_to_gl_texture(texture *tex, char* filename) { printf("Texture %s loaded\n", tex->path); return(1); -}; +} void draw_textured_quad(texture *tex) { if(glIsTexture(tex->id)) { diff --git a/samples/depth_funcs_alpha_testing/gl_png.h b/samples/depth_funcs_alpha_testing/gl_png.h index 21070b7..29b312f 100644 --- a/samples/depth_funcs_alpha_testing/gl_png.h +++ b/samples/depth_funcs_alpha_testing/gl_png.h @@ -2,7 +2,7 @@ #define __GL_PNG_H__ #include -#include +#include #include typedef struct _texture { diff --git a/samples/depth_funcs_alpha_testing/main.c b/samples/depth_funcs_alpha_testing/main.c index 5bdbaad..c0e7e81 100644 --- a/samples/depth_funcs_alpha_testing/main.c +++ b/samples/depth_funcs_alpha_testing/main.c @@ -1,11 +1,11 @@ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" #include "gl_png.h" //$KOS_BASE/utils/texconv/texconv --in disk.png --format ARGB4444 --preview disk_preview.png --out disk.dtex -extern uint8 romdisk[]; +extern uint8_t romdisk[]; KOS_INIT_ROMDISK(romdisk); texture t; int blendActive = -1; diff --git a/samples/depth_funcs_ortho/main.c b/samples/depth_funcs_ortho/main.c index 01a3639..837ede0 100644 --- a/samples/depth_funcs_ortho/main.c +++ b/samples/depth_funcs_ortho/main.c @@ -1,6 +1,6 @@ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. diff --git a/samples/lerabot01/main.c b/samples/lerabot01/main.c index 4ce79b6..dfcb696 100644 --- a/samples/lerabot01/main.c +++ b/samples/lerabot01/main.c @@ -1,11 +1,16 @@ #include -#include "gl.h" -#include "glu.h" -#include "glkos.h" #include +#include +#include +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" + +#ifdef __DREAMCAST__ extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); +#endif /* floats for x rotation, y rotation, z rotation */ float xrot, yrot, zrot; diff --git a/samples/lerabot_blend_test/main.c b/samples/lerabot_blend_test/main.c index 65e58ec..24722ef 100644 --- a/samples/lerabot_blend_test/main.c +++ b/samples/lerabot_blend_test/main.c @@ -4,9 +4,9 @@ * output and incorrect depth testing */ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. diff --git a/samples/lights/main.c b/samples/lights/main.c index 72777eb..15088d7 100644 --- a/samples/lights/main.c +++ b/samples/lights/main.c @@ -1,12 +1,23 @@ #include +#include +#include -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glext.h" +#include "GL/glkos.h" -extern uint8 romdisk[]; +#ifdef __DREAMCAST__ + +#include +extern uint8_t romdisk[]; KOS_INIT_ROMDISK(romdisk); +#define IMAGE_FILENAME "/rd/NeHe.bmp" + +#else +#define IMAGE_FILENAME "samples/lights/romdisk/NeHe.bmp" +#endif float xrot, yrot, zrot; @@ -89,7 +100,7 @@ int ImageLoad(char *filename, Image *image) { } if ((i = fread(image->data, size, 1, file)) != 1) { - printf(stderr, "Error reading image data from %s.\n", filename); + fprintf(stderr, "Error reading image data from %s.\n", filename); return 0; } @@ -115,7 +126,7 @@ void LoadGLTextures() { exit(0); } - if (!ImageLoad("/rd/NeHe.bmp", image1)) { + if (!ImageLoad(IMAGE_FILENAME, image1)) { exit(1); } diff --git a/samples/mipmap/main.c b/samples/mipmap/main.c index 15397d3..0ab8447 100644 --- a/samples/mipmap/main.c +++ b/samples/mipmap/main.c @@ -1,13 +1,21 @@ #include #include +#include -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glext.h" +#include "GL/glkos.h" -extern uint8 romdisk[]; +extern uint8_t romdisk[]; KOS_INIT_ROMDISK(romdisk); +#ifdef __DREAMCAST__ +#define IMAGE_FILENAME "/rd/NeHe.bmp" +#else +#define IMAGE_FILENAME "samples/mipmap/romdisk/NeHe.bmp" +#endif + /* storage for one texture */ int texture[1]; @@ -87,7 +95,7 @@ int ImageLoad(char *filename, Image *image) { } if ((i = fread(image->data, size, 1, file)) != 1) { - printf(stderr, "Error reading image data from %s.\n", filename); + fprintf(stderr, "Error reading image data from %s.\n", filename); return 0; } @@ -113,7 +121,7 @@ void LoadGLTextures() { exit(0); } - if (!ImageLoad("/rd/NeHe.bmp", image1)) { + if (!ImageLoad(IMAGE_FILENAME, image1)) { exit(1); } diff --git a/samples/multitexture_arrays/main.c b/samples/multitexture_arrays/main.c index 58bf860..0923c6d 100644 --- a/samples/multitexture_arrays/main.c +++ b/samples/multitexture_arrays/main.c @@ -8,11 +8,21 @@ */ #include +#include +#include -#include "gl.h" -#include "glu.h" -#include "glkos.h" -#include "glext.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" +#include "GL/glext.h" + +#ifdef __DREAMCAST__ +#define IMAGE1_FILENAME "/rd/wp001vq.pvr" +#define IMAGE2_FILENAME "/rd/FlareWS_256.pvr" +#else +#define IMAGE1_FILENAME "samples/multitexture_arrays/romdisk/wp001vq.pvr" +#define IMAGE2_FILENAME "samples/multitexture_arrays/romdisk/FlareWS_256.pvr" +#endif /* Load a PVR texture - located in pvr-texture.c */ extern GLuint glTextureLoadPVR(char *fname, unsigned char isMipMapped, unsigned char glMipMap); @@ -29,7 +39,7 @@ GLfloat TEXCOORD_ARRAY[4 * 2] = { 0, 0, 0, 1 }; -GLuint ARGB_ARRAY[4 * 1] = { 0xFFFF0000, 0xFF0000FF, 0xFF00FF00, 0xFFFFFF00 }; +GLuint ARGB_ARRAY[4] = { 0xFFFF0000, 0xFF0000FF, 0xFF00FF00, 0xFFFFFF00 }; /* Multi-Texture Example using Open GL Vertex Buffer Submission. */ @@ -91,7 +101,7 @@ void RenderCallback(GLuint texID0, GLuint texID1) { glDisableClientState(GL_VERTEX_ARRAY); } -extern uint8 romdisk[]; +extern uint8_t romdisk[]; KOS_INIT_ROMDISK(romdisk); int main(int argc, char **argv) { @@ -105,8 +115,8 @@ int main(int argc, char **argv) { glLoadIdentity(); /* Load two PVR textures to OpenGL */ - GLuint texID0 = glTextureLoadPVR("/rd/wp001vq.pvr", 0, 0); - GLuint texID1 = glTextureLoadPVR("/rd/FlareWS_256.pvr", 0, 0); + GLuint texID0 = glTextureLoadPVR(IMAGE1_FILENAME, 0, 0); + GLuint texID1 = glTextureLoadPVR(IMAGE2_FILENAME, 0, 0); while(1) { /* Draw the "scene" */ diff --git a/samples/multitexture_arrays/pvr-texture.c b/samples/multitexture_arrays/pvr-texture.c index 3732803..c9d5f92 100644 --- a/samples/multitexture_arrays/pvr-texture.c +++ b/samples/multitexture_arrays/pvr-texture.c @@ -6,13 +6,14 @@ Load A PVR Texture to the PVR using Open GL */ +#include +#include +#include -#include - -#include "../include/gl.h" -#include "../include/glu.h" -#include "../include/glkos.h" -#include "../include/glext.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" +#include "GL/glext.h" #define PVR_HDR_SIZE 0x20 #define MAX(x, y) ((x > y) ? x : y) @@ -51,8 +52,8 @@ static GLuint _glGetMipmapDataSize(GLuint width, GLuint height) { glMipMap should be passed as 1 if Open GL should calculate the Mipmap levels, 0 otherwise */ GLuint glTextureLoadPVR(char *fname, unsigned char isMipMapped, unsigned char glMipMap) { FILE *tex = NULL; - uint16 *TEX0 = NULL; - uint8 HDR[PVR_HDR_SIZE]; + uint16_t *TEX0 = NULL; + uint8_t HDR[PVR_HDR_SIZE]; GLuint texID, texSize, texW, texH, texFormat; /* Open the PVR texture file, and get its file size */ diff --git a/samples/nehe02/main.c b/samples/nehe02/main.c index b3782e6..ae6a0d0 100644 --- a/samples/nehe02/main.c +++ b/samples/nehe02/main.c @@ -1,6 +1,6 @@ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. @@ -16,7 +16,7 @@ void InitGL(int Width, int Height) // We call this right after our OpenG gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window - glMatrixMode(GL_MODELVIEW); + glMatrixMode(GL_MODELVIEW); } /* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */ diff --git a/samples/nehe02de/main.c b/samples/nehe02de/main.c index eba7fca..f84775c 100644 --- a/samples/nehe02de/main.c +++ b/samples/nehe02de/main.c @@ -1,6 +1,6 @@ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. diff --git a/samples/nehe02va/main.c b/samples/nehe02va/main.c index 5256cc7..ebaf30a 100644 --- a/samples/nehe02va/main.c +++ b/samples/nehe02va/main.c @@ -1,6 +1,6 @@ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. diff --git a/samples/nehe03/main.c b/samples/nehe03/main.c index 61361ee..a4e7c35 100644 --- a/samples/nehe03/main.c +++ b/samples/nehe03/main.c @@ -1,6 +1,7 @@ -#include "gl.h" -#include "glu.h" -#include "glkos.h" + +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. diff --git a/samples/nehe04/main.c b/samples/nehe04/main.c index d4cb75a..a84e94e 100644 --- a/samples/nehe04/main.c +++ b/samples/nehe04/main.c @@ -1,6 +1,6 @@ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" GLfloat rtri; GLfloat rquad; diff --git a/samples/nehe05/main.c b/samples/nehe05/main.c index 77b7e52..6bffe61 100644 --- a/samples/nehe05/main.c +++ b/samples/nehe05/main.c @@ -1,6 +1,6 @@ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" GLfloat rtri; GLfloat rquad; diff --git a/samples/nehe06/main.c b/samples/nehe06/main.c index cd3e9f1..c712ba3 100644 --- a/samples/nehe06/main.c +++ b/samples/nehe06/main.c @@ -1,17 +1,26 @@ #include +#include +#include +#include -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glext.h" +#include "GL/glkos.h" -extern uint8 romdisk[]; +#ifdef __DREAMCAST__ +#define IMAGE_FILENAME "/rd/NeHe.bmp" +extern uint8_t romdisk[]; KOS_INIT_ROMDISK(romdisk); +#else +#define IMAGE_FILENAME "samples/nehe06/romdisk/NeHe.bmp" +#endif /* floats for x rotation, y rotation, z rotation */ float xrot, yrot, zrot; /* storage for one texture */ -int texture[1]; +GLuint texture[1]; /* Image type - contains height, width, and data */ struct Image { @@ -89,7 +98,7 @@ int ImageLoad(char *filename, Image *image) { } if ((i = fread(image->data, size, 1, file)) != 1) { - printf(stderr, "Error reading image data from %s.\n", filename); + fprintf(stderr, "Error reading image data from %s.\n", filename); return 0; } @@ -115,7 +124,7 @@ void LoadGLTextures() { exit(0); } - if (!ImageLoad("/rd/NeHe.bmp", image1)) { + if (!ImageLoad(IMAGE_FILENAME, image1)) { exit(1); } diff --git a/samples/nehe06_vq/main.c b/samples/nehe06_vq/main.c index ad2cc25..c4501e2 100644 --- a/samples/nehe06_vq/main.c +++ b/samples/nehe06_vq/main.c @@ -1,12 +1,15 @@ #include +#include -#include "gl.h" -#include "glu.h" -#include "glkos.h" -#include "glext.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" +#include "GL/glext.h" +#ifdef __DREAMCAST__ extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); +#endif /* floats for x rotation, y rotation, z rotation */ float xrot, yrot, zrot; diff --git a/samples/ortho2d/main.c b/samples/ortho2d/main.c index e2173da..99354c7 100644 --- a/samples/ortho2d/main.c +++ b/samples/ortho2d/main.c @@ -1,6 +1,6 @@ -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. diff --git a/samples/paletted/main.c b/samples/paletted/main.c index 5def756..69826da 100644 --- a/samples/paletted/main.c +++ b/samples/paletted/main.c @@ -1,13 +1,14 @@ #include #include #include +#include -#include "gl.h" -#include "glext.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glext.h" +#include "GL/glu.h" +#include "GL/glkos.h" -extern uint8 romdisk[]; +extern uint8_t romdisk[]; KOS_INIT_ROMDISK(romdisk); /* floats for x rotation, y rotation, z rotation */ diff --git a/samples/paletted_pcx/main.c b/samples/paletted_pcx/main.c index b82a54a..bb8a0e0 100644 --- a/samples/paletted_pcx/main.c +++ b/samples/paletted_pcx/main.c @@ -4,13 +4,16 @@ #include #include -#include "gl.h" -#include "glext.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glext.h" +#include "GL/glkos.h" -extern uint8 romdisk[]; -KOS_INIT_ROMDISK(romdisk); +#ifdef __DREAMCAST__ + #include + extern uint8 romdisk[]; + KOS_INIT_ROMDISK(romdisk); +#endif /* floats for x rotation, y rotation, z rotation */ float xrot, yrot, zrot; diff --git a/samples/polygon_offset/main.c b/samples/polygon_offset/main.c index 101f4d6..a00278d 100644 --- a/samples/polygon_offset/main.c +++ b/samples/polygon_offset/main.c @@ -1,12 +1,17 @@ -#include + typedef enum { false, true } bool; -#include "gl.h" -#include "glu.h" -#include "glkos.h" + +#ifdef __DREAMCAST__ +#include +#endif + +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ void InitGL(int Width, int Height) // We call this right after our OpenGL window is created. @@ -96,6 +101,7 @@ void drawPolygon() int frames = 0; void check_input() { +#ifdef __DREAMCAST__ maple_device_t *cont; cont_state_t *state; @@ -117,6 +123,7 @@ void check_input() } } } +#endif } /* The main drawing function. */ diff --git a/samples/polymark/main.c b/samples/polymark/main.c index 2a671fc..d0d6378 100644 --- a/samples/polymark/main.c +++ b/samples/polymark/main.c @@ -10,6 +10,7 @@ #include #include +#include #include #include diff --git a/samples/quadmark/main.c b/samples/quadmark/main.c index 3788875..59da143 100644 --- a/samples/quadmark/main.c +++ b/samples/quadmark/main.c @@ -10,6 +10,7 @@ #include #include +#include #include #include diff --git a/samples/terrain/main.c b/samples/terrain/main.c index 4b4adb2..3ab9163 100644 --- a/samples/terrain/main.c +++ b/samples/terrain/main.c @@ -1,9 +1,9 @@ #include #include -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" #define TERRAIN_SIZE 100 #define TERRAIN_SCALE 1.0f diff --git a/samples/zclip/main.c b/samples/zclip/main.c index cbe2148..2da470b 100644 --- a/samples/zclip/main.c +++ b/samples/zclip/main.c @@ -1,15 +1,18 @@ #include #include #include +#include -#include "gl.h" -#include "glext.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glext.h" +#include "GL/glkos.h" +#ifdef __DREAMCAST__ +#include extern uint8 romdisk[]; KOS_INIT_ROMDISK(romdisk); - +#endif /* Image type - contains height, width, and data */ typedef struct // Create A Structure @@ -29,85 +32,85 @@ TextureImage lightmap; GLboolean LoadTGA(TextureImage *texture, const char *filename) // Loads A TGA File Into Memory { - GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header - GLubyte TGAcompare[12]; // Used To Compare TGA Header - GLubyte header[6]; // First 6 Useful Bytes From The Header - GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File - GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram - GLuint temp; // Temporary Variable - GLuint type=GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP) + GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header + GLubyte TGAcompare[12]; // Used To Compare TGA Header + GLubyte header[6]; // First 6 Useful Bytes From The Header + GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File + GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram + GLuint temp; // Temporary Variable + GLuint type=GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP) - FILE *file = fopen(filename, "rb"); // Open The TGA File + FILE *file = fopen(filename, "rb"); // Open The TGA File - if( file==NULL || // Does File Even Exist? - fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read? - memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || // Does The Header Match What We Want? - fread(header,1,sizeof(header),file)!=sizeof(header)) // If So Read Next 6 Header Bytes - { - if (file == NULL) { // Did The File Even Exist? *Added Jim Strong* + if( file==NULL || // Does File Even Exist? + fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read? + memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || // Does The Header Match What We Want? + fread(header,1,sizeof(header),file)!=sizeof(header)) // If So Read Next 6 Header Bytes + { + if (file == NULL) { // Did The File Even Exist? *Added Jim Strong* fprintf(stderr, "Missing file\n"); - return GL_FALSE; // Return False + return GL_FALSE; // Return False } else - { + { fprintf(stderr, "Invalid format\n"); - fclose(file); // If Anything Failed, Close The File - return GL_FALSE; // Return False - } - } + fclose(file); // If Anything Failed, Close The File + return GL_FALSE; // Return False + } + } - texture->width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte) - texture->height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte) + texture->width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte) + texture->height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte) - if( texture->width <=0 || // Is The Width Less Than Or Equal To Zero - texture->height <=0 || // Is The Height Less Than Or Equal To Zero - (header[4]!=24 && header[4]!=32)) // Is The TGA 24 or 32 Bit? - { - fprintf(stderr, "Wrong format\n"); + if( texture->width <=0 || // Is The Width Less Than Or Equal To Zero + texture->height <=0 || // Is The Height Less Than Or Equal To Zero + (header[4]!=24 && header[4]!=32)) // Is The TGA 24 or 32 Bit? + { + fprintf(stderr, "Wrong format\n"); fclose(file); // If Anything Failed, Close The File - return GL_FALSE; // Return False - } + return GL_FALSE; // Return False + } - texture->bpp = header[4]; // Grab The TGA's Bits Per Pixel (24 or 32) - bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The Bytes Per Pixel - imageSize = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data + texture->bpp = header[4]; // Grab The TGA's Bits Per Pixel (24 or 32) + bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The Bytes Per Pixel + imageSize = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data - texture->imageData=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data + texture->imageData=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data - if( texture->imageData==NULL || // Does The Storage Memory Exist? - fread(texture->imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved? - { - if(texture->imageData!=NULL) // Was Image Data Loaded - free(texture->imageData); // If So, Release The Image Data + if( texture->imageData==NULL || // Does The Storage Memory Exist? + fread(texture->imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved? + { + if(texture->imageData!=NULL) // Was Image Data Loaded + free(texture->imageData); // If So, Release The Image Data - fclose(file); // Close The File - return GL_FALSE; // Return False - } + fclose(file); // Close The File + return GL_FALSE; // Return False + } GLuint i; - for(i = 0; i < (int)imageSize; i += bytesPerPixel) // Loop Through The Image Data - { // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue) - temp=texture->imageData[i]; // Temporarily Store The Value At Image Data 'i' - texture->imageData[i] = texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte - texture->imageData[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) - } + for(i = 0; i < (int)imageSize; i += bytesPerPixel) // Loop Through The Image Data + { // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue) + temp=texture->imageData[i]; // Temporarily Store The Value At Image Data 'i' + texture->imageData[i] = texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte + texture->imageData[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) + } - fclose (file); // Close The File + fclose (file); // Close The File - // Build A Texture From The Data - glGenTextures(1, &texture[0].texID); // Generate OpenGL texture IDs + // Build A Texture From The Data + glGenTextures(1, &texture[0].texID); // Generate OpenGL texture IDs - glBindTexture(GL_TEXTURE_2D, texture[0].texID); // Bind Our Texture - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered + glBindTexture(GL_TEXTURE_2D, texture[0].texID); // Bind Our Texture + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered - if (texture[0].bpp==24) // Was The TGA 24 Bits - { - type=GL_RGB; // If So Set The 'type' To GL_RGB - } + if (texture[0].bpp==24) // Was The TGA 24 Bits + { + type=GL_RGB; // If So Set The 'type' To GL_RGB + } - glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData); + glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData); - return GL_TRUE; // Texture Building Went Ok, Return True + return GL_TRUE; // Texture Building Went Ok, Return True } // Load Bitmaps And Convert To Textures void LoadGLTextures() { diff --git a/samples/zclip_triangle/main.c b/samples/zclip_triangle/main.c index 46ea274..0400f0b 100644 --- a/samples/zclip_triangle/main.c +++ b/samples/zclip_triangle/main.c @@ -2,9 +2,9 @@ #include #include -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ diff --git a/samples/zclip_trianglestrip/main.c b/samples/zclip_trianglestrip/main.c index f6b8e80..332ec3e 100644 --- a/samples/zclip_trianglestrip/main.c +++ b/samples/zclip_trianglestrip/main.c @@ -2,9 +2,9 @@ #include #include -#include "gl.h" -#include "glu.h" -#include "glkos.h" +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glkos.h" /* A general OpenGL initialization function. Sets all of the initial parameters. */ diff --git a/toolchains/Dreamcast.cmake b/toolchains/Dreamcast.cmake new file mode 100644 index 0000000..9a10474 --- /dev/null +++ b/toolchains/Dreamcast.cmake @@ -0,0 +1,59 @@ +SET(CMAKE_SYSTEM_NAME Generic) + +SET(PLATFORM_DREAMCAST TRUE) + +SET(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_CROSSCOMPILING TRUE) + +set(CMAKE_C_COMPILER $ENV{KOS_CC_BASE}/bin/sh-elf-gcc) +set(CMAKE_CXX_COMPILER $ENV{KOS_CC_BASE}/bin/sh-elf-g++) + +add_compile_options(-ml -m4-single-only -ffunction-sections -fdata-sections) + +set(CMAKE_EXE_LINKER_FLAGS " -ml -m4-single-only -Wl,-Ttext=0x8c010000 -Wl,--gc-sections -T$ENV{KOS_BASE}/utils/ldscripts/shlelf.xc -nodefaultlibs" CACHE INTERNAL "" FORCE) + +set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +set(CMAKE_SYSTEM_INCLUDE_PATH "${CMAKE_SYSTEM_INCLUDE_PATH} $ENV{KOS_BASE}/include $ENV{KOS_BASE}/kernel/arch/dreamcast/include $ENV{KOS_BASE}/addons/include $ENV{KOS_BASE}/../kos-ports/include") + +INCLUDE_DIRECTORIES( + $ENV{KOS_BASE}/include + $ENV{KOS_BASE}/kernel/arch/dreamcast/include + $ENV{KOS_BASE}/addons/include + $ENV{KOS_BASE}/../kos-ports/include +) + +LINK_DIRECTORIES( + $ENV{KOS_BASE}/addons/lib/dreamcast + $ENV{KOS_PORTS}/lib +) + +IF(${CMAKE_BUILD_TYPE} MATCHES Debug) +LINK_DIRECTORIES($ENV{KOS_BASE}/lib/dreamcast/debug) +ELSE() +LINK_DIRECTORIES($ENV{KOS_BASE}/lib/dreamcast) +ENDIF() + + +add_link_options(-L$ENV{KOS_BASE}/lib/dreamcast) +link_libraries(-Wl,--start-group -lstdc++ -lkallisti -lc -lgcc -Wl,--end-group m) + +SET(CMAKE_EXECUTABLE_SUFFIX ".elf") +SET(CMAKE_EXECUTABLE_SUFFIX_CXX ".elf") + +ADD_DEFINITIONS( + -D__DREAMCAST__ + -DDREAMCAST + -D_arch_dreamcast + -D__arch_dreamcast + -D_arch_sub_pristine +) + +if (NOT CMAKE_BUILD_TYPE MATCHES Debug) + ADD_DEFINITIONS(-DNDEBUG) +endif() + +SET(CMAKE_ASM_FLAGS "") +SET(CMAKE_ASM_FLAGS_RELEASE "")