├── .hgignore ├── GL ├── gl.h ├── glext.h ├── glu.h └── glut.h ├── GLES ├── egl.h ├── egltypes.h ├── gl.h └── glut.h ├── LICENSE ├── Makefile ├── README ├── _changes.txt ├── eglBindTexImage.c ├── eglChooseConfig.c ├── eglCreateContext.c ├── eglCreatePbufferSurface.c ├── eglCreateWindowSurface.c ├── eglDestroyContext.c ├── eglDestroySurface.c ├── eglGetConfigAttrib.c ├── eglGetConfigs.c ├── eglGetDisplay.c ├── eglGetError.c ├── eglGetProcAddress.c ├── eglInitialize.c ├── eglMakeCurrent.c ├── eglQueryString.c ├── eglSwapBuffers.c ├── eglSwapInterval.c ├── eglTerminate.c ├── eglWaitGL.c ├── eglWaitNative.c ├── glAlphaFunc.c ├── glArrayElement.c ├── glBegin.c ├── glBindBufferARB.c ├── glBindTexture.c ├── glBlendEquation.c ├── glBlendFunc.c ├── glBufferDataARB.c ├── glBufferSubDataARB.c ├── glClear.c ├── glClearColor.c ├── glClearDepth.c ├── glClearDepthf.c ├── glClearStencil.c ├── glColor.c ├── glColorMask.c ├── glColorPointer.c ├── glColorTable.c ├── glCompressedTexImage2D.c ├── glCopyTexImage2D.c ├── glCullFace.c ├── glDeleteBuffersARB.c ├── glDeleteLists.c ├── glDeleteTextures.c ├── glDepthFunc.c ├── glDepthMask.c ├── glDepthRange.c ├── glDepthRangef.c ├── glDisplayList.c ├── glDrawArrays.c ├── glDrawBezierArrays.c ├── glDrawBezierElements.c ├── glDrawBuffer.c ├── glDrawElements.c ├── glDrawSplineArrays.c ├── glDrawSplineElements.c ├── glEnable.c ├── glEnableClientState.c ├── glEnd.c ├── glFinish.c ├── glFlush.c ├── glFog.c ├── glFrontFace.c ├── glFrustum.c ├── glFrustumf.c ├── glGenBuffersARB.c ├── glGenLists.c ├── glGenTextures.c ├── glGetBufferSubDataARB.c ├── glGetError.c ├── glGetFloatv.c ├── glGetIntegerv.c ├── glGetString.c ├── glInterleavedArrays.c ├── glIsBufferARB.c ├── glIsList.c ├── glIsTexture.c ├── glLight.c ├── glLightModel.c ├── glLineWidth.c ├── glLoadIdentity.c ├── glLoadMatrixf.c ├── glLockArraysEXT.c ├── glLogicOp.c ├── glMapBufferARB.c ├── glMaterial.c ├── glMatrixMode.c ├── glMultMatrixf.c ├── glNormal.c ├── glNormalPointer.c ├── glNormald.c ├── glOrtho.c ├── glOrthof.c ├── glPixelStore.c ├── glPolygonMode.c ├── glPolygonOffset.c ├── glPopMatrix.c ├── glPrioritizeTextures.c ├── glPushAttrib.c ├── glPushClientAttrib.c ├── glPushMatrix.c ├── glReadBuffer.c ├── glReadPixels.c ├── glRotatef.c ├── glScaled.c ├── glScalef.c ├── glScissor.c ├── glShadeModel.c ├── glStencilFunc.c ├── glStencilMask.c ├── glStencilOp.c ├── glTexCoord.c ├── glTexCoordPointer.c ├── glTexEnv.c ├── glTexGen.c ├── glTexImage2D.c ├── glTexParameter.c ├── glTexSubImage2D.c ├── glTranslatef.c ├── glUnmapBufferARB.c ├── glVertex.c ├── glVertexPointer.c ├── glVertexd.c ├── glVertexi.c ├── glViewport.c ├── glWeightPointerPSP.c ├── gluBuildMipmaps.c ├── gluLookAt.c ├── gluLookAtf.c ├── gluPerspective.c ├── gluPerspectivef.c ├── gluScaleImage.c ├── glut.c ├── glut_shapes.c ├── guconsts.h ├── pspgl_buffers.c ├── pspgl_buffers.h ├── pspgl_codegen.h ├── pspgl_context.c ├── pspgl_copy_pixels.c ├── pspgl_dlist.c ├── pspgl_dlist.h ├── pspgl_ge_init.c ├── pspgl_hash.c ├── pspgl_hash.h ├── pspgl_internal.h ├── pspgl_matrix.c ├── pspgl_matrix.h ├── pspgl_misc.c ├── pspgl_misc.h ├── pspgl_stats.c ├── pspgl_texobj.c ├── pspgl_texobj.h ├── pspgl_varray.c ├── pspgl_varray_draw.c ├── pspgl_varray_draw_elts.c ├── pspgl_varray_draw_range_elts.c ├── pspgl_vidmem.c ├── pspglu.c ├── pspglu.h ├── swiz.c ├── test-q3 ├── Makefile ├── demota │ └── default.cfg ├── files_srcs.inc ├── filesvm_cgame.inc ├── filesvm_q3_ui.inc ├── filesvm_ui.inc ├── generic │ ├── glimp.c │ ├── input.c │ ├── main.c │ ├── net.c │ └── snddma.c ├── patch-q3-psp.diff ├── psp-setup.c └── strip_cr.sh ├── test-vfpu ├── Makefile ├── main.c └── psp-setup.c ├── tests ├── Makefile ├── bezier.c ├── copytex.c ├── depthtest.c ├── eglcube.c ├── eglpbuffers.c ├── firefox.png ├── four.png ├── glchk.h ├── glut.c ├── ground.png ├── idxtex.c ├── install-settings ├── logo.raw ├── mipmaps.c ├── one.png ├── perfmeter.c ├── perfmeter.h ├── psp-setup.c ├── readdepth.c ├── screenshot.c ├── sky.png ├── spots.c ├── tex.c ├── texmat.c ├── texsubimage.c ├── thrashalloc.c ├── three.png ├── two.png ├── varray.c ├── vertexblend.c └── viewports.c └── tools ├── Makefile ├── decode_ge_dump.c ├── decode_vram_dump.c ├── half.c ├── psp-install └── swog.c /.hgignore: -------------------------------------------------------------------------------- 1 | (^|/)\.svn($|/) 2 | (^|/)\.hg($|/) 3 | -------------------------------------------------------------------------------- /GLES/egltypes.h: -------------------------------------------------------------------------------- 1 | #ifndef __egltypes_h_ 2 | #define __egltypes_h_ 3 | 4 | /* 5 | ** Types and resources 6 | */ 7 | typedef int EGLBoolean; 8 | typedef int EGLint; 9 | 10 | typedef void *EGLDisplay; 11 | typedef void *EGLSurface; 12 | typedef void *EGLContext; 13 | 14 | typedef int EGLConfig; 15 | typedef int NativeDisplayType; 16 | typedef int NativeWindowType; 17 | typedef int NativePixmapType; 18 | 19 | /* 20 | ** EGL and native handle values 21 | */ 22 | #define EGL_DEFAULT_DISPLAY ((NativeDisplayType)0) 23 | #define EGL_NO_CONTEXT ((EGLContext)0) 24 | #define EGL_NO_DISPLAY ((EGLDisplay)0) 25 | #define EGL_NO_SURFACE ((EGLSurface)0) 26 | 27 | #ifndef APIENTRY 28 | #define APIENTRY 29 | #endif 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /GLES/glut.h: -------------------------------------------------------------------------------- 1 | #ifndef __glut_h__ 2 | #define __glut_h__ 3 | 4 | #include 5 | 6 | /* Display mode bit masks. */ 7 | #define GLUT_RGB 0 8 | #define GLUT_RGBA GLUT_RGB 9 | //#define GLUT_INDEX 1 10 | #define GLUT_SINGLE 0 11 | #define GLUT_DOUBLE 2 12 | #define GLUT_ACCUM 4 13 | #define GLUT_ALPHA 8 14 | #define GLUT_DEPTH 16 15 | #define GLUT_STENCIL 32 16 | 17 | /* mouse buttons and state */ 18 | #define GLUT_LEFT_BUTTON 0 19 | #define GLUT_MIDDLE_BUTTON 1 20 | #define GLUT_RIGHT_BUTTON 2 21 | #define GLUT_DOWN 0 22 | #define GLUT_UP 1 23 | 24 | /* special keys */ 25 | #define GLUT_KEY_F1 1 26 | #define GLUT_KEY_F2 2 27 | #define GLUT_KEY_F3 3 28 | #define GLUT_KEY_F4 4 29 | #define GLUT_KEY_F5 5 30 | #define GLUT_KEY_F6 6 31 | #define GLUT_KEY_F7 7 32 | #define GLUT_KEY_F8 8 33 | #define GLUT_KEY_F9 9 34 | #define GLUT_KEY_F10 10 35 | #define GLUT_KEY_F11 11 36 | #define GLUT_KEY_F12 12 37 | #define GLUT_KEY_LEFT 100 38 | #define GLUT_KEY_UP 101 39 | #define GLUT_KEY_RIGHT 102 40 | #define GLUT_KEY_DOWN 103 41 | #define GLUT_KEY_PAGE_UP 104 42 | #define GLUT_KEY_PAGE_DOWN 105 43 | #define GLUT_KEY_HOME 106 44 | #define GLUT_KEY_END 107 45 | #define GLUT_KEY_INSERT 108 46 | 47 | // @@@ added by edorul for key repeating handling 48 | #define GLUT_KEYREPEAT_DEFAULT 12 // repeat for special and mouse keys 49 | #define GLUT_KEYREPEAT_ASCII 2 50 | #define GLUT_KEYREPEAT_SPECIAL 4 51 | #define GLUT_KEYREPEAT_MOUSE 8 52 | #define GLUT_KEYREPEAT_OFF 0 53 | #define GLUT_KEYREPEAT_ALL 14 54 | extern void glutKeyRepeat(unsigned int val); 55 | // @@@ end of addition 56 | 57 | 58 | extern void glutInit (int *argcp, char **argv); 59 | 60 | extern void glutInitDisplayMode (unsigned int mode); 61 | 62 | extern void glutInitWindowPosition (int x, int y); 63 | 64 | extern void glutInitWindowSize (int width, int height); 65 | 66 | extern int glutCreateWindow (const char *title); 67 | 68 | extern void glutMainLoop (void); 69 | 70 | extern void glutPostRedisplay (void); 71 | 72 | extern void glutSwapBuffers(void); 73 | 74 | extern void glutDisplayFunc (void (*func) (void)); 75 | 76 | extern void glutReshapeFunc (void (*func) (int width, int height)); 77 | 78 | extern void glutKeyboardFunc (void (*func) (unsigned char key, int x, int y)); 79 | 80 | extern void glutMouseFunc (void (*func) (int button, int state, int x, int y)); 81 | 82 | extern void glutMotionFunc (void (*func) (int x, int y)); 83 | 84 | extern void glutPassiveMotionFunc (void (*func) (int x, int y)); 85 | 86 | extern void glutIdleFunc (void (*func) (void)); 87 | 88 | extern void glutTimerFunc (unsigned int millis, void (*func) (int value), int value); 89 | 90 | extern void glutSpecialFunc (void (*func) (int key, int x, int y)); 91 | 92 | extern void glutKeyboardUpFunc (void (*func) (unsigned char key, int x, int y)); 93 | 94 | extern void glutSpecialUpFunc (void (*func) (int key, int x, int y)); 95 | 96 | extern void glutJoystickFunc (void (*func) (unsigned int buttonMask, int x, int y, int z), int pollInterval); 97 | 98 | 99 | #endif 100 | 101 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2005 Holger Waechtler 2 | Copyright (c) 2005 Jeremy Fitzhardinge 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its contributors 17 | may be used to endorse or promote products derived from this software 18 | without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Hi, 2 | 3 | pspGL is a pure, minimal, hardware-accelerated implementation of something like 4 | OpenGL for the Playstation Portable. Before you are able to compile it, you 5 | need to set up a PSP toolchain and SDK as described on http://pspdev.org. 6 | 7 | Type 'make' to build, 'make -C install' to build and install one 8 | of the demos. Here an example how to build for a 1.50 PSP on MacOS-X: 9 | 10 | $ make && make -C tests clean install 11 | $ make && make -C test-glut clean install 12 | 13 | All OpenGL-ES fixed-point commands are not implemented. Please take a look 14 | in the GLES/gl.h header file for the OpenGL commands implemented additionally 15 | to the minimum OpenGL-ES profile. Define PURE_GLES before including this file 16 | if you want to switch off these extensions. 17 | 18 | You can also use the GL/gl.h include set, but should avoid double-precision 19 | function calls for performance reasons. 20 | 21 | Display lists are used internally, but not exposed to the GL API. 22 | 23 | Only a minimum set of the core GLUT functions is implemented. 24 | 25 | pspgl_misc.[hc] contains some debug functions to dump PSP GE command buffers, 26 | the GE register set and the GE matrix stack to the memory stick. In the 27 | tools/ directory you find a rough disassembler for GE packets, maybe you find 28 | this useful to debug your problems. Please note that still a lot of commands 29 | are missing, please send patches if you enhance this functionality. 30 | 31 | The PSP has been designed for gaming, so some OpenGL features that are rarely 32 | used in games are missing and some have only somewhat limited support by the 33 | Hardware. Here is a short list of things you should consider when writing 34 | GL applications for the PSP: 35 | 36 | - only 4 light sources are supported 37 | - antialiasing can get switched on/off only globally 38 | - No user-defined clip planes are supported 39 | - only single-pixel wide lines and points 40 | - We don't know yet whether/how the fog function can get changed. 41 | - Only single-sided lighting, for two sided shading you need a CW and a CCW pass. 42 | - No wireframe rendering, we don' know whether the PSP supports this. 43 | 44 | This list is by no means complete, please report if you encounter other issues. 45 | 46 | All files are BSD-licensed, feel free to use it in free or commercial projects. 47 | enjoy, have fun, 48 | 49 | See http://www.goop.org/psp/gl for more documentation about this library. 50 | 51 | Holger Waechtler 52 | Jeremy Fitzhardinge 53 | -------------------------------------------------------------------------------- /eglBindTexImage.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_texobj.h" 3 | 4 | EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 5 | { 6 | unsigned error; 7 | struct pspgl_texobj *tobj; 8 | struct pspgl_teximg *timg; 9 | struct pspgl_surface *s = (struct pspgl_surface *)surface; 10 | const struct pspgl_texfmt *texfmt; 11 | 12 | error = EGL_BAD_MATCH; 13 | if (dpy == EGL_NO_DISPLAY || surface == EGL_NO_SURFACE || !(s->flags & SURF_TEXTURE)) 14 | goto out_error; 15 | 16 | /* find an appropriate texture format */ 17 | for(texfmt = __pspgl_texformats; texfmt->format != 0; texfmt++) 18 | if (texfmt->hwformat == s->pixfmt && // match hardware format... 19 | ((s->flags & SURF_USEALPHA) == 0) == ((texfmt->flags & TF_ALPHA) == 0)) // ...and use of alpha 20 | break; 21 | 22 | if (texfmt->format == 0) 23 | goto out_error; /* could happen if we want alpha with non-alpha texfmt */ 24 | 25 | error = EGL_BAD_PARAMETER; 26 | if (buffer != EGL_BACK_BUFFER) 27 | goto out_error; 28 | 29 | if (!pspgl_curctx->texture.bound) 30 | glBindTexture(GL_TEXTURE_2D, 0); /* bind default texture */ 31 | 32 | tobj = pspgl_curctx->texture.bound; 33 | 34 | /* free all teximgs */ 35 | for(int i = 0; i < MIPMAP_LEVELS; i++) 36 | if (tobj->images[i] != NULL) { 37 | __pspgl_teximg_free(tobj->images[i]); 38 | tobj->images[i] = NULL; 39 | } 40 | 41 | tobj->flags &= ~TOF_SWIZZLED; 42 | tobj->flags |= TOF_FLIPPED; 43 | 44 | timg = __pspgl_teximg_from_buffer(s->color_back, 0, 45 | s->width, s->height, s->pixelperline, texfmt); 46 | 47 | __pspgl_set_texture_image(tobj, 0, timg); 48 | __pspgl_update_texenv(tobj); 49 | if (tobj->flags & TOF_GENERATE_MIPMAPS) 50 | __pspgl_update_mipmaps(); 51 | 52 | return EGL_TRUE; 53 | 54 | out_error: 55 | EGLERROR(error); 56 | return EGL_FALSE; /* ? */ 57 | } 58 | 59 | EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 60 | { 61 | /* No operation. In this implementation, we still allow a 62 | surface to be used while it is bound to a texture. We also 63 | allow it to be bound to multiple textures. This doesn't 64 | keep track of which texture(s) the surface has been bound 65 | to, so we don't try to track them down and do anything 66 | about it. */ 67 | 68 | return EGL_TRUE; 69 | } 70 | -------------------------------------------------------------------------------- /eglChooseConfig.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | 4 | /* Framebuffer pixel formats. These are in order of most desirable to 5 | least, appropximately. This means: 6 | - smaller formats are better 7 | - prefer alpha over stencil 8 | */ 9 | const struct pspgl_pixconfig __pspgl_pixconfigs[] = { 10 | /* R G B A S hwformat */ 11 | { 5, 6, 5, 0, 0, GE_RGB_565 }, 12 | { 5, 5, 5, 1, 0, GE_RGBA_5551 }, 13 | { 5, 5, 5, 0, 1, GE_RGBA_5551 }, 14 | { 4, 4, 4, 4, 0, GE_RGBA_4444 }, 15 | { 4, 4, 4, 0, 4, GE_RGBA_4444 }, 16 | { 8, 8, 8, 8, 0, GE_RGBA_8888 }, 17 | { 8, 8, 8, 0, 8, GE_RGBA_8888 }, 18 | 19 | { 0, 0, 0, 0, 0, -1 } 20 | }; 21 | 22 | 23 | EGLBoolean eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, 24 | EGLConfig *configs, EGLint config_size, EGLint *num_config) 25 | { 26 | int alpha_size = 0, blue_size = 0, green_size = 0, red_size = 0; 27 | int depth_size = 0, stencil_size = 0; 28 | int nconfig; 29 | int i; 30 | 31 | while (attrib_list && attrib_list[0] != EGL_NONE) { 32 | switch (*attrib_list) { 33 | case EGL_ALPHA_SIZE: alpha_size = attrib_list[1]; break; 34 | case EGL_BLUE_SIZE: blue_size = attrib_list[1]; break; 35 | case EGL_GREEN_SIZE: green_size = attrib_list[1]; break; 36 | case EGL_RED_SIZE: red_size = attrib_list[1]; break; 37 | case EGL_DEPTH_SIZE: depth_size = attrib_list[1]; break; 38 | case EGL_STENCIL_SIZE: stencil_size = attrib_list[1]; break; 39 | 40 | case EGL_BUFFER_SIZE: 41 | break; 42 | 43 | case EGL_CONFIG_CAVEAT: 44 | case EGL_CONFIG_ID: 45 | case EGL_LEVEL: 46 | case EGL_MAX_PBUFFER_HEIGHT: 47 | case EGL_MAX_PBUFFER_PIXELS: 48 | case EGL_MAX_PBUFFER_WIDTH: 49 | case EGL_NATIVE_RENDERABLE: 50 | case EGL_NATIVE_VISUAL_ID: 51 | case EGL_NATIVE_VISUAL_TYPE: 52 | case EGL_SAMPLES: 53 | case EGL_SAMPLE_BUFFERS: 54 | case EGL_SURFACE_TYPE: 55 | case EGL_TRANSPARENT_TYPE: 56 | case EGL_TRANSPARENT_BLUE_VALUE: 57 | case EGL_TRANSPARENT_GREEN_VALUE: 58 | case EGL_TRANSPARENT_RED_VALUE: 59 | case EGL_BIND_TO_TEXTURE_RGB: 60 | case EGL_BIND_TO_TEXTURE_RGBA: 61 | case EGL_MIN_SWAP_INTERVAL: 62 | case EGL_MAX_SWAP_INTERVAL: 63 | break; 64 | 65 | default: 66 | EGLERROR(EGL_BAD_ATTRIBUTE); 67 | return EGL_FALSE; 68 | } 69 | 70 | attrib_list += 2; 71 | } 72 | 73 | psp_log("looking for configs for red=%d green=%d blue=%d alpha=%d stencil=%d depth=%d\n", 74 | red_size, green_size, blue_size, alpha_size, stencil_size, depth_size); 75 | 76 | nconfig = 0; 77 | for(i = 0; __pspgl_pixconfigs[i].hwformat != -1; i++) { 78 | const struct pspgl_pixconfig *p = &__pspgl_pixconfigs[i]; 79 | 80 | psp_log(" config %d has red=%d green=%d blue=%d alpha=%d stencil=%d hwformat=%d\n", 81 | i, p->red_bits, p->green_bits, p->blue_bits, p->alpha_bits, 82 | p->stencil_bits, p->hwformat); 83 | 84 | if (depth_size > 16) 85 | continue; 86 | if (red_size > p->red_bits) 87 | continue; 88 | if (green_size > p->green_bits) 89 | continue; 90 | if (blue_size > p->blue_bits) 91 | continue; 92 | if (alpha_size > p->alpha_bits) 93 | continue; 94 | if (stencil_size > p->stencil_bits) 95 | continue; 96 | 97 | if (configs != NULL) { 98 | if (nconfig >= config_size) 99 | break; 100 | configs[nconfig] = EGLCONFIGIDX(i, depth_size); 101 | } 102 | 103 | psp_log("found config %d 0x%x\n", nconfig, EGLCONFIGIDX(i, depth_size)); 104 | 105 | nconfig++; 106 | } 107 | *num_config = nconfig; 108 | 109 | return EGL_TRUE; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /eglCreateContext.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include "pspgl_internal.h" 8 | #include "pspgl_matrix.h" 9 | 10 | static GLboolean init_matrix_stack(struct pspgl_matrix_stack *mstk, int limit, unsigned flags) 11 | { 12 | mstk->stack = memalign(VFPU_ALIGNMENT, sizeof(struct pspgl_matrix) * limit); 13 | if (mstk->stack == NULL) 14 | return GL_FALSE; 15 | 16 | memcpy(mstk->stack[0].mat, __pspgl_identity, sizeof(mstk->stack[0].mat)); 17 | mstk->stack[0].flags = MF_IDENTITY; 18 | 19 | mstk->limit = limit; 20 | mstk->depth = 0; 21 | mstk->flags = flags | MF_DIRTY; 22 | 23 | mstk->scale[0] = mstk->scale[1] = mstk->scale[2] = mstk->scale[3] = 1.0f; 24 | mstk->trans[0] = mstk->trans[1] = mstk->trans[2] = mstk->trans[3] = 0.0f; 25 | 26 | return GL_TRUE; 27 | } 28 | 29 | EGLContext eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) 30 | { 31 | struct pspgl_context *ctx = memalign(VFPU_ALIGNMENT, sizeof(struct pspgl_context)); 32 | 33 | if (!ctx) 34 | goto out_error; 35 | 36 | psp_log("created context %p\n", ctx); 37 | 38 | memset(ctx, 0, sizeof(*ctx)); 39 | 40 | ctx->refcount = 1; 41 | 42 | /* Use VFPU matrix 7 as the current matrix */ 43 | ctx->vfpu_context = pspvfpu_initcontext(); 44 | if (ctx->vfpu_context == NULL) 45 | goto out_free_partial; 46 | 47 | /* OpenGL/ES stack size limits; we could probably afford to be more generous */ 48 | if (!init_matrix_stack(&ctx->projection_stack, 2, 0) || 49 | !init_matrix_stack(&ctx->texture_stack, 2, 0) || 50 | !init_matrix_stack(&ctx->modelview_stack, 16, 0) || 51 | !init_matrix_stack(&ctx->view_stack, 8, 0)) 52 | goto out_free_partial; 53 | 54 | for(int i = 0; i < NBONES; i++) 55 | if (!init_matrix_stack(&ctx->bone_stacks[i], 1, MF_DISABLED)) 56 | goto out_free_partial; 57 | 58 | /* Make modelview current by default; this also loads the 59 | modelview into the VFPU */ 60 | ctx->current_matrix_stack = NULL; 61 | __pspgl_matrix_select(ctx, &ctx->modelview_stack); 62 | 63 | ctx->vertexblend.enabled = GL_FALSE; 64 | 65 | if (share_context == NULL) { 66 | ctx->shared = malloc(sizeof(struct pspgl_shared_context)); 67 | if (ctx->shared == NULL) 68 | goto out_free_partial; 69 | 70 | memset(ctx->shared, 0, sizeof(struct pspgl_shared_context)); 71 | } else 72 | ctx->shared = ((struct pspgl_context *) share_context)->shared; 73 | ctx->shared->refcount++; 74 | 75 | ctx->attribstackdepth = 0; 76 | ctx->clattribstackdepth = 0; 77 | 78 | ctx->pack.alignment = 4; 79 | ctx->unpack.alignment = 4; 80 | 81 | // @@@ added by edorul for display lists 82 | ctx->displaylists.nblists = 0; 83 | ctx->displaylists.is_in_glNewList = 0; 84 | ctx->displaylists.calllists_base = 0; 85 | ctx->displaylists.index = 0; 86 | // @@@ end of addition 87 | 88 | return (EGLContext) ctx; 89 | 90 | out_free_partial: 91 | eglDestroyContext(dpy, ctx); 92 | 93 | out_error: 94 | EGLERROR(EGL_BAD_ALLOC); 95 | return EGL_NO_CONTEXT; 96 | } 97 | 98 | 99 | -------------------------------------------------------------------------------- /eglCreatePbufferSurface.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "pspgl_internal.h" 5 | #include "pspgl_buffers.h" 6 | 7 | #define MASK(bits) ((1 << (bits)) - 1) 8 | 9 | EGLSurface eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, 10 | const EGLint *attrib_list) 11 | { 12 | unsigned width, height; 13 | unsigned egl_texfmt, egl_textarget; 14 | unsigned error; 15 | struct pspgl_surface *s; 16 | const struct pspgl_pixconfig *pixconf; 17 | int has_depthbuffer = EGLCFG_HASDEPTH(config); 18 | int bytesperpixel; 19 | unsigned bufferlen; 20 | 21 | pixconf = &__pspgl_pixconfigs[EGLCFG_PIXIDX(config)]; 22 | 23 | s = NULL; 24 | width = height = 0; 25 | egl_texfmt = EGL_NO_TEXTURE; 26 | egl_textarget = EGL_NO_TEXTURE; 27 | 28 | for(; attrib_list && attrib_list[0] != EGL_NONE; attrib_list += 2) { 29 | switch(attrib_list[0]) { 30 | case EGL_WIDTH: 31 | width = attrib_list[1]; 32 | break; 33 | case EGL_HEIGHT: 34 | height = attrib_list[1]; 35 | break; 36 | case EGL_TEXTURE_TARGET: 37 | egl_textarget = attrib_list[1]; 38 | break; 39 | case EGL_TEXTURE_FORMAT: 40 | egl_texfmt = attrib_list[1]; 41 | break; 42 | } 43 | } 44 | 45 | error = EGL_BAD_MATCH; 46 | 47 | /* Can't have stencil and alpha */ 48 | if (pixconf->stencil_bits && (EGL_TEXTURE_FORMAT == EGL_TEXTURE_RGBA)) 49 | goto out_error; 50 | 51 | if ((egl_textarget == EGL_NO_TEXTURE) != (egl_textarget == EGL_NO_TEXTURE)) 52 | goto out_error; 53 | 54 | if (pixconf->hwformat == GE_RGBA_8888) 55 | bytesperpixel = 4; 56 | else 57 | bytesperpixel = 2; 58 | 59 | bufferlen = pow2(width) * height * bytesperpixel; 60 | 61 | if (egl_textarget != EGL_NO_TEXTURE) { 62 | if (!ispow2(width) || !ispow2(height)) 63 | goto out_error; 64 | 65 | } 66 | 67 | error = EGL_BAD_ALLOC; 68 | 69 | s = malloc(sizeof(*s)); 70 | 71 | if (s == NULL) 72 | goto out_error; 73 | 74 | memset(s, 0, sizeof(*s)); 75 | s->refcount = 1; 76 | s->width = width; 77 | s->height = height; 78 | s->pixelperline = pow2(width); 79 | s->flags = 0; 80 | s->pixfmt = pixconf->hwformat; 81 | 82 | s->read = &s->color_back; 83 | s->draw = &s->color_back; 84 | 85 | if (egl_textarget != EGL_NO_TEXTURE) 86 | s->flags |= SURF_TEXTURE; 87 | if (egl_texfmt == EGL_TEXTURE_RGBA) 88 | s->flags |= SURF_USEALPHA; 89 | 90 | s->alpha_mask = MASK(pixconf->alpha_bits); 91 | s->stencil_mask = MASK(pixconf->stencil_bits); 92 | 93 | if (!(s->color_back = __pspgl_buffer_new(bufferlen, GL_STATIC_COPY_ARB))) 94 | goto out_error; 95 | s->color_front = s->color_back; 96 | s->color_front->refcount++; 97 | 98 | if (has_depthbuffer) { 99 | bufferlen = s->height * s->pixelperline * 2; 100 | if ((s->depth_buffer = __pspgl_buffer_new(bufferlen, GL_STATIC_COPY_ARB)) == NULL) 101 | goto out_error; 102 | } 103 | 104 | return (EGLSurface)s; 105 | 106 | out_error: 107 | if (s) 108 | eglDestroySurface(dpy, s); 109 | EGLERROR(error); 110 | return EGL_NO_SURFACE; 111 | } 112 | -------------------------------------------------------------------------------- /eglCreateWindowSurface.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "pspgl_internal.h" 5 | #include "pspgl_buffers.h" 6 | 7 | #define MASK(bits) ((1 << (bits)) - 1) 8 | 9 | EGLSurface eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, NativeWindowType window, 10 | const EGLint *attrib_list) 11 | { 12 | struct pspgl_surface *s; 13 | unsigned long bytesperpixel; 14 | unsigned long bufferlen; 15 | const struct pspgl_pixconfig *pixconf; 16 | int has_depthbuffer = EGLCFG_HASDEPTH(config); 17 | 18 | pixconf = &__pspgl_pixconfigs[EGLCFG_PIXIDX(config)]; 19 | 20 | s = malloc(sizeof(struct pspgl_surface)); 21 | if (!s) 22 | goto bad_alloc; 23 | memset(s, 0, sizeof(*s)); 24 | 25 | if (pixconf->hwformat == GE_RGBA_8888) 26 | bytesperpixel = 4; 27 | else 28 | bytesperpixel = 2; 29 | 30 | int has_frontbuffer = 1; /* always */ 31 | int has_backbuffer = 1; /* caller can request no backbuffer */ 32 | 33 | for(; attrib_list && attrib_list[0] != EGL_NONE; attrib_list += 2) { 34 | switch(attrib_list[0]) { 35 | #ifdef EGL_RENDER_BUFFER 36 | /* EGL_RENDER_BUFFER is EGL 1.2; we need a header update */ 37 | case EGL_RENDER_BUFFER: 38 | has_backbuffer = (attrib_list[1] == EGL_BACK_BUFFER); 39 | break; 40 | #endif 41 | } 42 | } 43 | 44 | s->refcount = 1; 45 | s->width = 480; 46 | s->height = 272; 47 | s->pixelperline = pow2(s->width); 48 | s->flags = SURF_DISPLAYED; 49 | s->pixfmt = pixconf->hwformat; 50 | 51 | s->alpha_mask = MASK(pixconf->alpha_bits); 52 | s->stencil_mask = MASK(pixconf->stencil_bits); 53 | 54 | s->read = &s->color_back; 55 | s->draw = &s->color_back; 56 | 57 | bufferlen = s->height * s->pixelperline * bytesperpixel; 58 | 59 | psp_log("width = %lu\n", s->width); 60 | psp_log("height = %lu\n", s->height); 61 | psp_log("pixelperline = %lu\n", s->pixelperline); 62 | psp_log("pixelformat = 0x%04x\n", s->pixfmt); 63 | psp_log("masks: alpha=%02x stencil=%02x\n", 64 | s->alpha_mask, s->stencil_mask); 65 | 66 | if (has_frontbuffer) { 67 | if (!(s->color_front = __pspgl_buffer_new(bufferlen, GL_STATIC_COPY_ARB))) 68 | goto bad_alloc; 69 | s->color_front->flags |= BF_PINNED_FIXED; 70 | } 71 | 72 | if (has_backbuffer) { 73 | if (!(s->color_back = __pspgl_buffer_new(bufferlen, GL_STATIC_COPY_ARB))) 74 | goto bad_alloc; 75 | s->color_back->flags |= BF_PINNED_FIXED; 76 | } else { 77 | /* If we're single buffered, set back buffer == front 78 | buffer; this way all the other code can assume 79 | double-buffering without needing to check, but we 80 | still get single-buffered behaviour. */ 81 | s->color_back = s->color_front; 82 | s->color_back->refcount++; 83 | } 84 | 85 | bufferlen = s->height * s->pixelperline * 2; 86 | 87 | if (has_depthbuffer) { 88 | if (!(s->depth_buffer = __pspgl_buffer_new(bufferlen, GL_STATIC_COPY_ARB))) 89 | goto bad_alloc; 90 | s->depth_buffer->flags |= BF_PINNED_FIXED; 91 | } 92 | 93 | return (EGLSurface) s; 94 | 95 | bad_alloc: 96 | eglDestroySurface(dpy, s); 97 | EGLERROR(EGL_BAD_ALLOC); 98 | return EGL_NO_SURFACE; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /eglDestroyContext.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "pspgl_internal.h" 6 | #include "pspgl_texobj.h" 7 | 8 | EGLBoolean eglDestroyContext (EGLDisplay dpy, EGLContext ctx) 9 | { 10 | struct pspgl_context *c = (struct pspgl_context *) ctx; 11 | 12 | if (!c) { 13 | EGLERROR(EGL_BAD_CONTEXT); 14 | return EGL_FALSE; 15 | } 16 | 17 | assert(c->refcount > 0); 18 | if (--c->refcount) 19 | return EGL_TRUE; 20 | 21 | c->shared->refcount--; 22 | 23 | if (c->shared->refcount == 0) { 24 | __pspgl_hash_foreach_free(&c->shared->texture_objects, (void (*) (void *)) __pspgl_texobj_free); 25 | __pspgl_hash_foreach_free(&c->shared->display_lists, /* XXX should become dlist_free() */ free); 26 | free(c->shared); 27 | } 28 | 29 | if (c->draw) 30 | eglDestroySurface(dpy, c->draw); 31 | if (c->read) 32 | eglDestroySurface(dpy, c->read); 33 | 34 | free(c->projection_stack.stack); 35 | free(c->modelview_stack.stack); 36 | free(c->texture_stack.stack); 37 | free(c->view_stack.stack); 38 | for(int i = 0; i < NBONES; i++) 39 | free(c->bone_stacks[i].stack); 40 | 41 | if (c->vfpu_context) 42 | pspvfpu_deletecontext(c->vfpu_context); 43 | 44 | free(c); 45 | 46 | return EGL_TRUE; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /eglDestroySurface.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | #include "pspgl_buffers.h" 4 | 5 | EGLBoolean eglDestroySurface (EGLDisplay dpy, EGLSurface surface) 6 | { 7 | struct pspgl_surface *s = (struct pspgl_surface*) surface; 8 | 9 | if (!s) 10 | return EGL_FALSE; 11 | 12 | assert(s->refcount > 0); 13 | if (--s->refcount) 14 | return EGL_TRUE; 15 | 16 | /* Even if single-buffered, both front and back are initialized */ 17 | __pspgl_buffer_free(s->color_front); 18 | __pspgl_buffer_free(s->color_back); 19 | 20 | if (s->depth_buffer) 21 | __pspgl_buffer_free(s->depth_buffer); 22 | 23 | free(s); 24 | 25 | return EGL_TRUE; 26 | } 27 | -------------------------------------------------------------------------------- /eglGetConfigAttrib.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | EGLBoolean eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) 5 | { 6 | switch (attribute) { 7 | case EGL_WIDTH: 8 | *value = 480; 9 | break; 10 | case EGL_HEIGHT: 11 | *value = 272; 12 | break; 13 | default: 14 | return EGL_FALSE; 15 | } 16 | 17 | return EGL_TRUE; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /eglGetConfigs.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | EGLBoolean eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, 5 | EGLint config_size, EGLint *num_config) 6 | { 7 | int depth; 8 | int nconfig = 0; 9 | 10 | for(depth = 0; depth <= 1; depth++) { 11 | int pixidx; 12 | 13 | for(pixidx = 0; __pspgl_pixconfigs[pixidx].hwformat != -1; pixidx++) { 14 | if (configs != NULL) { 15 | if (nconfig >= config_size) 16 | goto out; 17 | 18 | configs[nconfig] = EGLCONFIGIDX(pixidx, depth); 19 | } 20 | nconfig++; 21 | } 22 | } 23 | 24 | out: 25 | *num_config = nconfig; 26 | return EGL_TRUE; 27 | } 28 | -------------------------------------------------------------------------------- /eglGetDisplay.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | 5 | EGLDisplay eglGetDisplay (NativeDisplayType display) 6 | { 7 | return (EGLDisplay)"foo"; /* non-EGL_NO_DISPLAY thing */ 8 | } 9 | -------------------------------------------------------------------------------- /eglGetError.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | EGLint eglGetError (void) 5 | { 6 | EGLint err = __pspgl_eglerror; 7 | __pspgl_eglerror = EGL_SUCCESS; 8 | return err; 9 | } 10 | -------------------------------------------------------------------------------- /eglGetProcAddress.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "pspgl_internal.h" 5 | 6 | struct pspgl_proc { 7 | const char *name; 8 | void (*proc)(); 9 | }; 10 | 11 | static const struct pspgl_proc proctable[] = { 12 | #include "pspgl_proctable.h" 13 | }; 14 | #define NPROC (sizeof(proctable)/sizeof(proctable[0])) 15 | 16 | static int cmp_procname(const void *a, const void *b) 17 | { 18 | const char *name = a; 19 | const struct pspgl_proc *entry = b; 20 | 21 | return strcmp(name, entry->name); 22 | } 23 | 24 | GLAPI void (* APIENTRY eglGetProcAddress (const char *procname))() 25 | { 26 | struct pspgl_proc *entry; 27 | 28 | entry = bsearch(procname, proctable, NPROC, sizeof(struct pspgl_proc), 29 | cmp_procname); 30 | 31 | if (entry != NULL) 32 | return entry->proc; 33 | 34 | return NULL; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /eglInitialize.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "pspgl_internal.h" 4 | 5 | 6 | EGLBoolean eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor) 7 | { 8 | static int initialized = 0; 9 | 10 | psp_log("\n\n=============== pspGL, build " __DATE__ ", " __TIME__ " ===============\n"); 11 | 12 | if (!initialized) { 13 | atexit((void *) eglTerminate); 14 | sceDisplaySetMode(0, 480, 272); 15 | initialized = 1; 16 | } 17 | 18 | if (major) 19 | *major = 1; 20 | if (minor) 21 | *minor = 1; 22 | 23 | return EGL_TRUE; 24 | } 25 | -------------------------------------------------------------------------------- /eglMakeCurrent.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | #include "pspgl_dlist.h" 4 | 5 | /** 6 | * mask out trigger action registers, or the GE might run amok on context changes... 7 | * This bitfield is generated from ge_init_state[] with all non-action fields enabled. 8 | */ 9 | uint32_t __pspgl_context_register[256 / 32]; 10 | 11 | EGLBoolean eglMakeCurrent (EGLDisplay dpy, 12 | EGLSurface drawsurf, EGLSurface readsurf, 13 | EGLContext ctx) 14 | { 15 | struct pspgl_context *c = (struct pspgl_context *) ctx; 16 | struct pspgl_surface *read = (struct pspgl_surface *)readsurf; 17 | struct pspgl_surface *draw = (struct pspgl_surface *)drawsurf; 18 | int changed; 19 | 20 | changed = (c != pspgl_curctx); 21 | 22 | if (c) { 23 | c->refcount++; 24 | 25 | if (draw) 26 | draw->refcount++; 27 | if (read) 28 | read->refcount++; 29 | if (c->draw) 30 | eglDestroySurface(dpy, c->draw); 31 | if (c->read) 32 | eglDestroySurface(dpy, c->read); 33 | c->draw = draw; 34 | c->read = read; 35 | } 36 | 37 | if (pspgl_curctx) { 38 | if (changed) 39 | glFinish(); 40 | eglDestroyContext(dpy, pspgl_curctx); 41 | } 42 | 43 | pspgl_curctx = c; 44 | 45 | if (c == NULL) 46 | return EGL_TRUE; 47 | 48 | if (!c->initialized) { 49 | __pspgl_dlist_init(); 50 | __pspgl_ge_init(c); 51 | c->initialized = 1; 52 | } 53 | 54 | if (changed) { 55 | /* mark all registers and matrices as dirty, we need to 56 | rewrite them at init and after context restore... */ 57 | for (int i=0; ihw.ge_reg_touched)/sizeof(c->hw.ge_reg_touched[0]); i++) 58 | c->hw.ge_reg_touched[i] |= __pspgl_context_register[i]; 59 | 60 | c->projection_stack.flags |= MF_DIRTY; 61 | c->modelview_stack.flags |= MF_DIRTY; 62 | c->texture_stack.flags |= MF_DIRTY; 63 | c->view_stack.flags |= MF_DIRTY; 64 | for(int i = 0; i < NBONES; i++) 65 | c->bone_stacks[i].flags |= MF_DIRTY; 66 | } 67 | 68 | return __pspgl_vidmem_setup_write_and_display_buffer(c->draw); 69 | } 70 | 71 | -------------------------------------------------------------------------------- /eglQueryString.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | 4 | 5 | static const 6 | char *egl_strings [] = { 7 | /* EGL_VENDOR */ 8 | "pspEGL", 9 | /* EGL_VERSION */ 10 | "(pspEGL build " __DATE__ ", " __TIME__ ")", 11 | /* EGL_EXTENSIONS */ 12 | "" 13 | }; 14 | 15 | 16 | const char* eglQueryString (EGLDisplay dpy, EGLint name) 17 | { 18 | unsigned long idx = name - EGL_VENDOR; 19 | const char *s; 20 | 21 | if (idx >= sizeof(egl_strings)/sizeof(egl_strings[0])) { 22 | EGLERROR(EGL_BAD_PARAMETER); 23 | s = NULL; 24 | } else { 25 | s = egl_strings[idx]; 26 | } 27 | 28 | return s; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /eglSwapBuffers.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | EGLBoolean eglSwapBuffers (EGLDisplay dpy, EGLSurface draw) 5 | { 6 | struct pspgl_surface *s = (struct pspgl_surface *) draw; 7 | struct pspgl_buffer *t; 8 | 9 | t = s->color_front; 10 | s->color_front = s->color_back; 11 | s->color_back = t; 12 | 13 | return __pspgl_vidmem_setup_write_and_display_buffer(s); 14 | } 15 | -------------------------------------------------------------------------------- /eglSwapInterval.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) 5 | { 6 | __pspgl_curctx->swap_interval = interval; 7 | return EGL_TRUE; 8 | } 9 | -------------------------------------------------------------------------------- /eglTerminate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | #include "pspgl_dlist.h" 4 | 5 | EGLBoolean eglTerminate (EGLDisplay dpy) 6 | { 7 | psp_log("\n\n=============== pspGL, build " __DATE__ ", " __TIME__ " ===============\n"); 8 | 9 | __pspgl_dlist_cancel(); 10 | 11 | return EGL_TRUE; 12 | } 13 | -------------------------------------------------------------------------------- /eglWaitGL.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | EGLBoolean eglWaitGL (void) 5 | { 6 | glFinish(); 7 | return EGL_TRUE; 8 | } 9 | -------------------------------------------------------------------------------- /eglWaitNative.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | EGLBoolean eglWaitNative (EGLint engine) 5 | { 6 | return EGL_TRUE; 7 | } 8 | -------------------------------------------------------------------------------- /glAlphaFunc.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | static const char alphatestfunc_mapping [] = { 0, 4, 2, 5, 6, 3, 7, 1 }; 5 | 6 | void glAlphaFunc (GLenum func, GLclampf ref) 7 | { 8 | unsigned char aref = (unsigned char) (255.0f * CLAMPF(ref)); 9 | unsigned char amsk = 0xff; 10 | 11 | if (unlikely(func < GL_NEVER || func > GL_ALWAYS)) 12 | goto out_error; 13 | 14 | func &= 0x0007; 15 | 16 | sendCommandi(CMD_ALPHA_FUNC, (amsk << 16) | (aref << 8) | alphatestfunc_mapping[func]); 17 | return; 18 | 19 | out_error: 20 | GLERROR(GL_INVALID_ENUM); 21 | } 22 | -------------------------------------------------------------------------------- /glArrayElement.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | static const 5 | GLfloat scale_factor [] = { 6 | 1.0f/127.0f, 7 | 1.0f/255.0f, 8 | 1.0f/32767.0f, 9 | 1.0f/65535.0f, 10 | 1.0f/2147483647.0f, 11 | 1.0f/4294967295.0f 12 | }; 13 | 14 | 15 | static 16 | void dereference (struct pspgl_vertex_array *a, GLint idx, 17 | void (*glfunc) (const GLfloat *v), int scale) 18 | { 19 | const void *ptr; 20 | GLfloat val [4]; 21 | GLfloat factor; 22 | int i; 23 | 24 | if (!a->enabled) 25 | return; 26 | 27 | 28 | ptr = __pspgl_bufferobj_map(a->buffer, GL_READ_ONLY_ARB, (void *)a->ptr); 29 | ptr += a->stride * idx; 30 | 31 | if (scale && a->type >= GL_BYTE && a->type <= GL_UNSIGNED_INT) 32 | factor = scale_factor[a->type - GL_BYTE]; 33 | else 34 | factor = 1.0f; 35 | 36 | /* be prepared for incomplete initialisations... */ 37 | val[2] = 0.0f; 38 | val[3] = 1.0f; 39 | 40 | switch (a->type) { 41 | case GL_BYTE: 42 | for (i=0; isize; i++) 43 | val[i] = ((GLbyte *) ptr)[i] * factor; 44 | break; 45 | 46 | case GL_UNSIGNED_BYTE: 47 | for (i=0; isize; i++) 48 | val[i] = ((GLubyte *) ptr)[i] * factor; 49 | break; 50 | 51 | case GL_SHORT: 52 | for (i=0; isize; i++) 53 | val[i] = ((GLshort *) ptr)[i] * factor; 54 | break; 55 | 56 | case GL_UNSIGNED_SHORT: 57 | for (i=0; isize; i++) 58 | val[i] = ((GLushort *) ptr)[i] * factor; 59 | break; 60 | 61 | case GL_INT: 62 | for (i=0; isize; i++) 63 | val[i] = ((GLint *) ptr)[i] * factor; 64 | break; 65 | 66 | case GL_UNSIGNED_INT: 67 | for (i=0; isize; i++) 68 | val[i] = ((GLuint *) ptr)[i] * factor; 69 | break; 70 | 71 | case GL_FLOAT: 72 | for (i=0; isize; i++) 73 | val[i] = ((GLfloat *) ptr)[i]; 74 | break; 75 | 76 | case GL_DOUBLE: 77 | for (i=0; isize; i++) 78 | val[i] = ((GLdouble *) ptr)[i]; 79 | break; 80 | 81 | default: 82 | GLERROR(GL_INVALID_ENUM); 83 | } 84 | 85 | (*glfunc)(val); 86 | 87 | __pspgl_bufferobj_unmap(a->buffer, GL_READ_ONLY_ARB); 88 | } 89 | 90 | 91 | void glArrayElement (GLint i) 92 | { 93 | dereference(&pspgl_curctx->vertex_array.texcoord, i, glTexCoord4fv, 1); 94 | dereference(&pspgl_curctx->vertex_array.color, i, glColor4fv, 1); 95 | dereference(&pspgl_curctx->vertex_array.normal, i, glNormal3fv, 1); 96 | dereference(&pspgl_curctx->vertex_array.vertex, i, glVertex4fv, 0); 97 | } 98 | 99 | -------------------------------------------------------------------------------- /glBegin.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glBegin (GLenum mode) 5 | { 6 | // @@@ from here it's allways the same code exept for index of the command 7 | if (pspgl_curctx->displaylists.is_in_glNewList & GL_COMPILE) { // we must record this command 8 | struct stDisplayElement *new; 9 | new = (struct stDisplayElement *) malloc (sizeof(struct stDisplayElement)); 10 | // @@@ put new element at the end of list 11 | if (!__pspgl_actuallist->first) 12 | __pspgl_actuallist->first = new; 13 | if (__pspgl_actuallist->last) 14 | __pspgl_actuallist->last->next = new; 15 | new->next = NULL; 16 | __pspgl_actuallist->last = new; 17 | 18 | new->command_num = GLBEGIN; 19 | new->parami1 = mode; 20 | } 21 | 22 | if ((pspgl_curctx->displaylists.is_in_glNewList == GL_COMPILE_AND_EXECUTE)||(pspgl_curctx->displaylists.is_in_glNewList == 0)) { 23 | // @@@ from here it's different 24 | if (likely(mode >= GL_POINTS && mode <= GL_SPRITES_PSP)) { 25 | pspgl_curctx->beginend.primitive = mode; 26 | pspgl_curctx->beginend.vertex_count = 0; 27 | return; 28 | } 29 | GLERROR(GL_INVALID_ENUM); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /glBindBufferARB.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | void glBindBufferARB(GLenum target, GLuint id) 5 | { 6 | struct hashtable *hash = &pspgl_curctx->shared->buffers; 7 | struct pspgl_bufferobj *bufp, *prev, **prevp; 8 | 9 | prevp = __pspgl_bufferobj_for_target(target); 10 | 11 | if (prevp == NULL) 12 | return; 13 | 14 | prev = *prevp; 15 | 16 | bufp = NULL; 17 | if (id != 0) { 18 | bufp = __pspgl_hash_lookup(hash, id); 19 | 20 | if (bufp == NULL) { 21 | bufp = __pspgl_bufferobj_new(NULL); 22 | if (unlikely(bufp == NULL)) 23 | goto out_error; 24 | 25 | __pspgl_hash_insert(hash, id, bufp); 26 | } 27 | } 28 | 29 | if (bufp == prev) 30 | return; 31 | 32 | if (prev) { 33 | if (prev->mapped && prev->data) 34 | __pspgl_buffer_unmap(prev->data, prev->access); 35 | 36 | psp_log("unbinding %p from target %x\n", prev, target); 37 | 38 | prev->mapped = GL_FALSE; 39 | __pspgl_bufferobj_free(prev); 40 | } 41 | 42 | psp_log("binding %p to target %x\n", bufp, target); 43 | 44 | *prevp = bufp; 45 | if (bufp) 46 | bufp->refcount++; 47 | return; 48 | 49 | out_error: 50 | GLERROR(GL_OUT_OF_MEMORY); 51 | } 52 | 53 | void glBindBuffer (GLenum, GLuint) 54 | __attribute__((alias("glBindBufferARB"))); 55 | -------------------------------------------------------------------------------- /glBindTexture.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | #include "pspgl_texobj.h" 4 | 5 | void glBindTexture(GLenum target, GLuint id) 6 | { 7 | struct pspgl_texobj *tobj, *bound; 8 | struct hashtable *hash = &pspgl_curctx->shared->texture_objects; 9 | unsigned i; 10 | GLenum error; 11 | 12 | bound = pspgl_curctx->texture.bound; 13 | tobj = __pspgl_hash_lookup(hash, id); 14 | 15 | if (likely(tobj != NULL)) { 16 | error = GL_INVALID_OPERATION; 17 | 18 | if (unlikely(tobj->target == 0)) 19 | tobj->target = target; 20 | else if (unlikely(tobj->target != target)) 21 | goto out_error; 22 | } else { 23 | /* if this is a new id, create the texture */ 24 | tobj = __pspgl_texobj_new(id, target); 25 | psp_log("id %u unknown; creating new texture %p\n", id, tobj); 26 | 27 | error = GL_OUT_OF_MEMORY; 28 | if (unlikely(tobj == NULL)) 29 | goto out_error; 30 | 31 | __pspgl_hash_insert(hash, id, tobj); 32 | } 33 | 34 | if (bound == tobj) 35 | return; 36 | 37 | if (bound != NULL) { 38 | int i; 39 | 40 | psp_log("unbinding previous texture %p\n", bound); 41 | 42 | /* save per-texture state in texture object */ 43 | for(i = TEXSTATE_START; i <= TEXSTATE_END; i++) 44 | bound->ge_texreg[i - TEXSTATE_START] = getReg(i); 45 | 46 | __pspgl_texobj_free(bound); 47 | } 48 | 49 | psp_log("binding to %u (%p)\n", id, tobj); 50 | 51 | tobj->refcount++; 52 | pspgl_curctx->texture.bound = tobj; 53 | 54 | /* restore texture state */ 55 | psp_log("updating register state\n"); 56 | for(i = TEXSTATE_START; i <= TEXSTATE_END; i++) 57 | if (i != CMD_CLUT_LOAD) 58 | sendCommandi(i, tobj->ge_texreg[i - TEXSTATE_START]); 59 | 60 | if (__pspgl_texobj_cmap(tobj) != NULL) 61 | pspgl_curctx->hw.dirty |= HWD_CLUT; 62 | 63 | __pspgl_update_texenv(tobj); 64 | sendCommandi(CMD_TEXCACHE_FLUSH, getReg(CMD_TEXCACHE_FLUSH)+1); 65 | return; 66 | 67 | out_error: 68 | GLERROR(error); 69 | } 70 | -------------------------------------------------------------------------------- /glBlendEquation.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | /* Blend Equation */ 5 | #define GE_ADD 0 6 | #define GE_SUBTRACT 1 7 | #define GE_REVERSE_SUBTRACT 2 8 | #define GE_MIN 3 9 | #define GE_MAX 4 10 | #define GE_ABS 5 11 | 12 | 13 | void glBlendEquation (GLenum equation) 14 | { 15 | int e; 16 | 17 | switch (equation) { 18 | case GL_FUNC_SUBTRACT: 19 | e = GE_SUBTRACT; 20 | break; 21 | case GL_FUNC_REVERSE_SUBTRACT: 22 | e = GE_REVERSE_SUBTRACT; 23 | break; 24 | case GL_MIN: 25 | e = GE_MIN; 26 | break; 27 | case GL_MAX: 28 | e = GE_MAX; 29 | break; 30 | case GL_FUNC_ADD: 31 | e = GE_ADD; 32 | break; 33 | default: 34 | GLERROR(GL_INVALID_ENUM); 35 | return; 36 | } 37 | 38 | __pspgl_context_writereg_masked(pspgl_curctx, CMD_BLEND_FUNC, (e << 8), 0xf00); 39 | } 40 | 41 | -------------------------------------------------------------------------------- /glBlendFunc.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | /* Blend Src Factor */ 5 | #define GE_SF_DST_COLOR 0 6 | #define GE_SF_ONE_MINUS_DST_COLOR 1 7 | #define GE_SF_SRC_ALPHA 2 8 | #define GE_SF_ONE_MINUS_SRC_ALPHA 3 9 | #define GE_SF_DST_ALPHA 4 10 | #define GE_SF_ONE_MINUS_DST_ALPHA 5 11 | #define GE_SF_FIX 10 12 | 13 | /* Blend Dst Factor */ 14 | #define GE_DF_SRC_COLOR 0 15 | #define GE_DF_ONE_MINUS_SRC_COLOR 1 16 | #define GE_DF_SRC_ALPHA 2 17 | #define GE_DF_ONE_MINUS_SRC_ALPHA 3 18 | #define GE_DF_DST_ALPHA 4 19 | #define GE_DF_ONE_MINUS_DST_ALPHA 5 20 | #define GE_DF_FIX 10 21 | 22 | 23 | void glBlendFunc (GLenum sfactor, GLenum dfactor) 24 | { 25 | unsigned int srcfact, dstfact; 26 | 27 | switch (dfactor) { 28 | case GL_ZERO: 29 | sendCommandi(CMD_FIXEDCOL_DST, 0x000000); 30 | dstfact = GE_DF_FIX; 31 | break; 32 | case GL_ONE: 33 | sendCommandi(CMD_FIXEDCOL_DST, 0xffffff); 34 | dstfact = GE_DF_FIX; 35 | break; 36 | case GL_SRC_ALPHA: 37 | dstfact = GE_DF_SRC_ALPHA; 38 | break; 39 | case GL_ONE_MINUS_SRC_ALPHA: 40 | dstfact = GE_DF_ONE_MINUS_SRC_ALPHA; 41 | break; 42 | case GL_DST_ALPHA: 43 | dstfact = GE_DF_DST_ALPHA; 44 | break; 45 | case GL_ONE_MINUS_DST_ALPHA: 46 | dstfact = GE_DF_ONE_MINUS_DST_ALPHA; 47 | break; 48 | case GL_SRC_COLOR: 49 | dstfact = GE_DF_SRC_COLOR; 50 | break; 51 | case GL_ONE_MINUS_SRC_COLOR: 52 | dstfact = GE_DF_ONE_MINUS_SRC_COLOR; 53 | break; 54 | 55 | case GL_DST_COLOR: 56 | case GL_ONE_MINUS_DST_COLOR: 57 | default: 58 | goto out_error; 59 | } 60 | 61 | switch (sfactor) { 62 | case GL_ZERO: 63 | sendCommandi(CMD_FIXEDCOL_SRC, 0x000000); 64 | srcfact = GE_SF_FIX; 65 | break; 66 | case GL_ONE: 67 | sendCommandi(CMD_FIXEDCOL_SRC, 0xffffff); 68 | srcfact = GE_SF_FIX; 69 | break; 70 | case GL_SRC_ALPHA: 71 | srcfact = GE_SF_SRC_ALPHA; 72 | break; 73 | case GL_ONE_MINUS_SRC_ALPHA: 74 | srcfact = GE_SF_ONE_MINUS_SRC_ALPHA; 75 | break; 76 | case GL_DST_COLOR: 77 | srcfact = GE_SF_DST_COLOR; 78 | break; 79 | case GL_ONE_MINUS_DST_COLOR: 80 | srcfact = GE_SF_ONE_MINUS_DST_COLOR; 81 | break; 82 | case GL_DST_ALPHA: 83 | srcfact = GE_SF_DST_ALPHA; 84 | break; 85 | case GL_ONE_MINUS_DST_ALPHA: 86 | srcfact = GE_SF_ONE_MINUS_DST_ALPHA; 87 | break; 88 | 89 | case GL_SRC_ALPHA_SATURATE: 90 | case GL_SRC_COLOR: 91 | case GL_ONE_MINUS_SRC_COLOR: 92 | default: 93 | goto out_error; 94 | } 95 | 96 | __pspgl_context_writereg_masked(pspgl_curctx, CMD_BLEND_FUNC, 97 | (dstfact << 4) | srcfact, 0x0ff); 98 | return; 99 | 100 | out_error: 101 | GLERROR(GL_INVALID_ENUM); 102 | } 103 | 104 | -------------------------------------------------------------------------------- /glBufferDataARB.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "pspgl_internal.h" 6 | #include "pspgl_buffers.h" 7 | 8 | void glBufferDataARB(GLenum target, GLsizeiptr size, 9 | const GLvoid *init_data, GLenum usage) 10 | { 11 | struct pspgl_bufferobj *buf, **bufp; 12 | struct pspgl_buffer *databuf; 13 | GLenum error; 14 | 15 | bufp = __pspgl_bufferobj_for_target(target); 16 | 17 | if (bufp == NULL) 18 | return; 19 | 20 | buf = *bufp; 21 | 22 | error = GL_INVALID_OPERATION; 23 | if (unlikely(buf == NULL)) 24 | goto out_error; 25 | 26 | error = GL_INVALID_VALUE; 27 | if (unlikely(size < 0)) 28 | goto out_error; 29 | 30 | databuf = __pspgl_buffer_new(size, usage); 31 | 32 | error = GL_OUT_OF_MEMORY; 33 | if (unlikely(databuf == NULL)) 34 | goto out_error; 35 | 36 | if (buf->data) { 37 | if (buf->mapped) 38 | __pspgl_buffer_unmap(buf->data, buf->access); 39 | 40 | psp_log("freeing data %p for buffer %p\n", buf->data, buf); 41 | __pspgl_buffer_free(buf->data); 42 | } 43 | 44 | buf->mapped = GL_FALSE; 45 | buf->usage = usage; 46 | buf->data = databuf; 47 | 48 | psp_log("attaching data %p(%p) to buffer %p\n", 49 | databuf, databuf->base, buf); 50 | 51 | if (init_data != NULL) { 52 | void *p; 53 | 54 | p = __pspgl_buffer_map(databuf, GL_WRITE_ONLY_ARB); 55 | 56 | memcpy(p, init_data, size); 57 | 58 | __pspgl_buffer_unmap(databuf, GL_WRITE_ONLY_ARB); 59 | } 60 | return; 61 | 62 | out_error: 63 | GLERROR(error); 64 | } 65 | 66 | void glBufferData(GLenum target, GLsizeiptr size, 67 | const GLvoid *init_data, GLenum usage) 68 | __attribute__((alias("glBufferDataARB"))); 69 | -------------------------------------------------------------------------------- /glBufferSubDataARB.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | #include "pspgl_buffers.h" 5 | 6 | void glBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, 7 | const GLvoid *data) 8 | { 9 | struct pspgl_bufferobj *buf, **bufp; 10 | void *p; 11 | GLenum error; 12 | 13 | bufp = __pspgl_bufferobj_for_target(target); 14 | 15 | if (bufp == NULL) 16 | return; 17 | 18 | buf = *bufp; 19 | 20 | error = GL_INVALID_OPERATION; 21 | if (unlikely(buf == NULL) || unlikely(buf->mapped)) 22 | goto out_error; 23 | 24 | error = GL_INVALID_VALUE; 25 | if (size < 0 || 26 | buf->data == NULL || 27 | size+offset > buf->data->size) 28 | goto out_error; 29 | 30 | __pspgl_buffer_dlist_sync(buf->data); 31 | 32 | p = __pspgl_buffer_map(buf->data, GL_WRITE_ONLY_ARB); 33 | 34 | memcpy(p + offset, data, size); 35 | 36 | __pspgl_buffer_unmap(buf->data, GL_WRITE_ONLY_ARB); 37 | return; 38 | 39 | out_error: 40 | GLERROR(error); 41 | } 42 | 43 | void glBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, 44 | const GLvoid *data) 45 | __attribute__((alias("glBufferSubDataARB"))); 46 | 47 | -------------------------------------------------------------------------------- /glClear.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_dlist.h" 3 | 4 | struct clear_vertex { 5 | unsigned long color; 6 | short x,y,z; 7 | short _pad; 8 | }; 9 | 10 | 11 | void glClear (GLbitfield mask) 12 | { 13 | struct clear_vertex *vbuf; 14 | struct pspgl_surface *s = pspgl_curctx->draw; 15 | unsigned long clearmask = pspgl_curctx->clear.color; 16 | unsigned long clearmode = 0; 17 | unsigned x, y, width, height; 18 | 19 | if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 20 | goto out_error; 21 | 22 | /* make room for 2 embedded vertices in cmd_buf, aligned to 16byte boundary */ 23 | vbuf = __pspgl_dlist_insert_space(2 * sizeof(struct clear_vertex)); 24 | 25 | if (mask & GL_COLOR_BUFFER_BIT) { 26 | clearmode |= GU_COLOR_BUFFER_BIT; 27 | if (s->alpha_mask) 28 | clearmode |= GU_STENCIL_BUFFER_BIT; /* really alpha */ 29 | } 30 | 31 | if (s->stencil_mask && (mask & GL_STENCIL_BUFFER_BIT)) { 32 | static const unsigned char stencil_shift [] = { 32-1, 32-4, 32-8 }; 33 | clearmask &= 0x00ffffff; 34 | clearmask |= (pspgl_curctx->clear.stencil) << stencil_shift[s->pixfmt-1]; 35 | clearmode |= GU_STENCIL_BUFFER_BIT; 36 | } 37 | 38 | if (s->depth_buffer && (mask & GL_DEPTH_BUFFER_BIT)) 39 | clearmode |= GU_DEPTH_BUFFER_BIT; 40 | 41 | if (pspgl_curctx->scissor_test.enabled) { 42 | x = pspgl_curctx->scissor_test.x; 43 | y = pspgl_curctx->scissor_test.y; 44 | width = pspgl_curctx->scissor_test.width; 45 | height = pspgl_curctx->scissor_test.height; 46 | } else { 47 | x = 0; 48 | y = 0; 49 | width = s->width; 50 | height = s->height; 51 | } 52 | 53 | vbuf[0].color = clearmask; 54 | vbuf[0].x = x; 55 | vbuf[0].y = s->height - y; 56 | vbuf[0].z = pspgl_curctx->clear.depth; 57 | 58 | vbuf[1].color = clearmask; 59 | vbuf[1].x = x + width; 60 | vbuf[1].y = s->height - (y + height); 61 | vbuf[1].z = pspgl_curctx->clear.depth; 62 | 63 | /* enable clear mode */ 64 | sendCommandi(CMD_CLEARMODE, (clearmode << 8) | 1); 65 | 66 | /* draw array */ 67 | __pspgl_context_render_prim(pspgl_curctx, GE_SPRITES, 2, 68 | GE_COLOR_8888 | GE_VERTEX_16BIT | GE_TRANSFORM_2D, vbuf, NULL); 69 | 70 | /* leave clear mode */ 71 | sendCommandi(CMD_CLEARMODE, 0); 72 | return; 73 | 74 | out_error: 75 | GLERROR(GL_INVALID_VALUE); 76 | } 77 | 78 | -------------------------------------------------------------------------------- /glClearColor.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 4 | { 5 | pspgl_curctx->clear.color = ((((int) (255.0 * CLAMPF(alpha))) << 24) | 6 | (((int) (255.0 * CLAMPF(blue))) << 16) | 7 | (((int) (255.0 * CLAMPF(green))) << 8) | 8 | ((int) (255.0 * CLAMPF(red)))); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /glClearDepth.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void glClearDepth (GLclampd depth) 4 | { 5 | /* The PSP's Z coord is backwards from OpenGL's, so the clear 6 | depth has the opposite sense. */ 7 | pspgl_curctx->clear.depth = 65535 - (unsigned)(65535.0f * CLAMPF((GLfloat) depth)); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /glClearDepthf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | 4 | void glClearDepthf (GLclampf depth) 5 | { 6 | /* The PSP's Z coord is backwards from OpenGL's, so the clear 7 | depth has the opposite sense. */ 8 | pspgl_curctx->clear.depth = 65535 - (unsigned)(65535.0f * CLAMPF((GLfloat) depth)); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /glClearStencil.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glClearStencil (GLint s) 5 | { 6 | pspgl_curctx->clear.stencil = s; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /glColor.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void __pspgl_update_color(unsigned long c) 4 | { 5 | // @@@ from here it's allways the same code exept for index of the command 6 | if (pspgl_curctx->displaylists.is_in_glNewList & GL_COMPILE) { // we must record this command 7 | struct stDisplayElement *new; 8 | new = (struct stDisplayElement *) malloc (sizeof(struct stDisplayElement)); 9 | // @@@ put new element at the end of list 10 | if (!__pspgl_actuallist->first) 11 | __pspgl_actuallist->first = new; 12 | if (__pspgl_actuallist->last) 13 | __pspgl_actuallist->last->next = new; 14 | new->next = NULL; 15 | __pspgl_actuallist->last = new; 16 | 17 | new->command_num = GLCOLOR; 18 | new->parami1 = c; 19 | } 20 | 21 | if ((pspgl_curctx->displaylists.is_in_glNewList == GL_COMPILE_AND_EXECUTE)||(pspgl_curctx->displaylists.is_in_glNewList == 0)) { 22 | // @@@ from here it's different, because it's the old function 23 | pspgl_curctx->current.color = c; 24 | 25 | /* only apply when lighting is disabled */ 26 | if ((getReg(CMD_ENA_LIGHTING) & 0xff) == 0) { 27 | sendCommandi(CMD_MATERIAL_AMB_C, c); 28 | sendCommandi(CMD_MATERIAL_AMB_A, c>>24); 29 | } 30 | } 31 | } 32 | 33 | void glColor4fv (const GLfloat *color) 34 | { 35 | __pspgl_update_color(COLOR4(color)); 36 | } 37 | 38 | 39 | void glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 40 | { 41 | __pspgl_update_color((((int) (255.0 * CLAMPF(alpha))) << 24) | 42 | (((int) (255.0 * CLAMPF(blue))) << 16) | 43 | (((int) (255.0 * CLAMPF(green))) << 8) | 44 | ((int) (255.0 * CLAMPF(red)))); 45 | } 46 | 47 | // @@@ added by Edorul 48 | void glColor3fv(const GLfloat *color) 49 | { 50 | __pspgl_update_color((((int) (255.0 * CLAMPF(1.0f))) << 24) | 51 | (((int) (255.0 * CLAMPF(color[2]))) << 16) | 52 | (((int) (255.0 * CLAMPF(color[1]))) << 8) | 53 | ((int) (255.0 * CLAMPF(color[0])))); 54 | } 55 | // @@@ end of Edorul's addition 56 | 57 | void glColor3f (GLfloat red, GLfloat green, GLfloat blue) 58 | { 59 | glColor4f(red, green, blue, 1.0); 60 | } 61 | 62 | 63 | void glColor4ubv (const GLubyte *c) 64 | { 65 | __pspgl_update_color((c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0]); 66 | } 67 | 68 | 69 | void glColor3ub (GLubyte r, GLubyte g, GLubyte b) 70 | { 71 | __pspgl_update_color(0xff000000 | (b << 16) | (g << 8) | r); 72 | } 73 | 74 | 75 | void glColor4ub (GLubyte r, GLubyte g, GLubyte b, GLubyte a) 76 | { 77 | __pspgl_update_color((a << 24) | (b << 16) | (g << 8) | r); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /glColorMask.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) 5 | { 6 | unsigned long mask = red ? 0xffff00 : 0xffffff; 7 | 8 | if (green) 9 | mask &= 0xff00ff; 10 | 11 | if (blue) 12 | mask &= 0x00ffff; 13 | 14 | pspgl_curctx->write_mask.alpha = alpha ? pspgl_curctx->draw->alpha_mask : 0x00; 15 | 16 | sendCommandi(CMD_RGB_MASK, mask); 17 | 18 | /** 19 | * Alpha Channel and Stencil are shared. Only update Alpha mask register 20 | * if stencil test is disabled. 21 | */ 22 | if ((pspgl_curctx->hw.ge_reg[CMD_ENA_STENCIL_TEST] & 1) == 0) 23 | sendCommandi(CMD_ALPHA_MASK, ~pspgl_curctx->write_mask.alpha); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /glColorPointer.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) 5 | { 6 | struct pspgl_vertex_array *va = &pspgl_curctx->vertex_array.color; 7 | GLboolean native; 8 | GLenum error; 9 | 10 | error = GL_INVALID_VALUE; 11 | if (unlikely(size != 3 && size != 4)) 12 | goto out_error; 13 | 14 | if (unlikely(stride < 0)) 15 | goto out_error; 16 | 17 | error = GL_INVALID_ENUM; 18 | if (unlikely(type != GL_FLOAT && type != GL_UNSIGNED_BYTE)) 19 | goto out_error; 20 | 21 | if (stride == 0) 22 | stride = __pspgl_gl_sizeof(type) * size; 23 | 24 | native = (type == GL_UNSIGNED_BYTE) && (size == 4); 25 | 26 | psp_log("ptr=%p size=%d type=%x stride=%d native=%d\n", 27 | pointer, size, type, stride, native); 28 | 29 | va->size = size; 30 | va->type = type; 31 | va->stride = stride; 32 | va->ptr = pointer; 33 | va->native = native; 34 | 35 | __pspgl_varray_bind_buffer(va, pspgl_curctx->vertex_array.arraybuffer); 36 | return; 37 | 38 | out_error: 39 | GLERROR(error); 40 | } 41 | -------------------------------------------------------------------------------- /glColorTable.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_texobj.h" 3 | 4 | void glColorTable(GLenum target, GLenum internalformat, 5 | GLsizei width, GLenum format, GLenum type, const GLvoid *data) 6 | { 7 | struct pspgl_teximg *cmap; 8 | struct pspgl_texobj *tobj; 9 | const struct pspgl_texfmt *fmt; 10 | GLenum error; 11 | 12 | error = GL_INVALID_ENUM; 13 | if (unlikely(target != GL_TEXTURE_2D)) 14 | goto out_error; 15 | 16 | if (!(format == GL_RGB || format == GL_RGBA)) 17 | goto out_error; 18 | 19 | fmt = __pspgl_hardware_format(__pspgl_texformats, format, type); 20 | if (unlikely(fmt == NULL)) 21 | goto out_error; 22 | 23 | error = GL_INVALID_OPERATION; 24 | if (internalformat != format) 25 | goto out_error; 26 | 27 | error = GL_INVALID_VALUE; 28 | if (!ispow2(width)) 29 | goto out_error; 30 | 31 | cmap = __pspgl_teximg_new(data, &pspgl_curctx->unpack, width, 1, 0, GL_FALSE, fmt); 32 | if (cmap == NULL) 33 | return; /* error already set */ 34 | 35 | if (!pspgl_curctx->texture.bound) 36 | glBindTexture(target, 0); 37 | 38 | tobj = pspgl_curctx->texture.bound; 39 | 40 | if (tobj->cmap) { 41 | /* release old cmap */ 42 | __pspgl_teximg_free(tobj->cmap); 43 | } 44 | tobj->cmap = cmap; 45 | pspgl_curctx->hw.dirty |= HWD_CLUT; 46 | 47 | __pspgl_update_texenv(tobj); 48 | 49 | return; 50 | 51 | out_error: 52 | GLERROR(error); 53 | return; 54 | } 55 | 56 | void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *data) 57 | __attribute__((alias("glColorTable"))); 58 | -------------------------------------------------------------------------------- /glCompressedTexImage2D.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "pspgl_internal.h" 5 | #include "pspgl_texobj.h" 6 | 7 | /* 8 | For compressed formats, convert the whole image; 9 | width is the compressed image size in bytes 10 | */ 11 | 12 | /* PSP DXT1 hardware format reverses the colors and the per-pixel 13 | bits, and encodes the color in RGB 565 format */ 14 | static void copy_dxt1(const struct pspgl_texfmt *fmt, void *to, const void *from, unsigned size) 15 | { 16 | const unsigned long *src = from; 17 | unsigned long *dest = to; 18 | 19 | for(; size >= 8; size -= 8) { 20 | dest[0] = src[1]; 21 | dest[1] = src[0]; 22 | 23 | dest += 2; 24 | src += 2; 25 | } 26 | } 27 | 28 | /* PSP DXT3 format reverses the alpha and color parts of each block, 29 | and reverse the color and per-pixel terms in the color part. */ 30 | static void copy_dxt3(const struct pspgl_texfmt *fmt, void *to, const void *from, unsigned size) 31 | { 32 | const unsigned long *src = from; 33 | unsigned long *dest = to; 34 | 35 | for(; size >= 16; size -= 16) { 36 | /* colour */ 37 | dest[0] = src[3]; 38 | dest[1] = src[2]; 39 | /* alpha */ 40 | dest[2] = src[0]; 41 | dest[3] = src[1]; 42 | 43 | dest += 4; 44 | src += 4; 45 | } 46 | } 47 | 48 | /* PSP DXT5 format reverses the alpha and color parts of each block, 49 | and reverse the color and per-pixel terms in the color part. In 50 | the alpha part, the 2 reference alpha values are swapped with the 51 | alpha interpolation values. */ 52 | static void copy_dxt5(const struct pspgl_texfmt *fmt, void *to, const void *from, unsigned size) 53 | { 54 | const unsigned short *src = from; 55 | unsigned short *dest = to; 56 | 57 | for(; size >= 16; size -= 16) { 58 | /* colour */ 59 | ((unsigned long *)dest)[0] = ((unsigned long *)src)[3]; 60 | ((unsigned long *)dest)[1] = ((unsigned long *)src)[2]; 61 | 62 | /* alpha */ 63 | dest[4] = src[1]; 64 | dest[5] = src[2]; 65 | dest[6] = src[3]; 66 | dest[7] = src[0]; 67 | 68 | dest += 8; 69 | src += 8; 70 | } 71 | } 72 | 73 | static const struct pspgl_texfmt comptexformats[] = { 74 | /* Compressed textures */ 75 | { GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, 1, GE_DXT1, 1, copy_dxt1, 0 }, 76 | { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, 1, GE_DXT1, 1, copy_dxt1, TF_ALPHA }, 77 | { GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_UNSIGNED_BYTE, 1, GE_DXT3, 1, copy_dxt3, TF_ALPHA }, 78 | { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_UNSIGNED_BYTE, 1, GE_DXT5, 1, copy_dxt5, TF_ALPHA }, 79 | 80 | { 0, 0 } 81 | }; 82 | 83 | void glCompressedTexImage2D(GLenum target, GLint level, 84 | GLenum internalformat, GLsizei width, 85 | GLsizei height, GLint border, 86 | GLsizei imageSize, const void *data) 87 | { 88 | const struct pspgl_texfmt *texfmt; 89 | struct pspgl_texobj *tobj; 90 | struct pspgl_teximg *timg; 91 | GLenum error; 92 | 93 | error = GL_INVALID_VALUE; 94 | if (!ispow2(width) || !ispow2(height)) 95 | goto out_error; 96 | 97 | if (level < 0 || level > MIPMAP_LEVELS) 98 | goto out_error; 99 | 100 | if (border != 0) 101 | goto out_error; 102 | 103 | texfmt = __pspgl_hardware_format(comptexformats, internalformat, GL_UNSIGNED_BYTE); 104 | error = GL_INVALID_ENUM; 105 | if (unlikely(texfmt == NULL)) 106 | goto out_error; 107 | 108 | if (!pspgl_curctx->texture.bound) 109 | glBindTexture(target, 0); 110 | 111 | tobj = pspgl_curctx->texture.bound; 112 | error = GL_OUT_OF_MEMORY; 113 | if (unlikely(tobj == NULL)) 114 | goto out_error; 115 | 116 | __pspgl_texobj_unswizzle(tobj); 117 | 118 | timg = __pspgl_teximg_new(data, &pspgl_curctx->unpack, 119 | width, height, imageSize, GL_FALSE, texfmt); 120 | if (timg == NULL) 121 | return; /* error already set */ 122 | 123 | __pspgl_set_texture_image(tobj, level, timg); 124 | 125 | __pspgl_update_texenv(tobj); 126 | return; 127 | 128 | out_error: 129 | GLERROR(error); 130 | } 131 | -------------------------------------------------------------------------------- /glCopyTexImage2D.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "pspgl_internal.h" 5 | #include "pspgl_texobj.h" 6 | #include "pspgl_dlist.h" 7 | 8 | static const struct { 9 | GLenum format, type; 10 | } formats[] = { 11 | [GE_RGB_565] = { GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV }, 12 | [GE_RGBA_5551] = { GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV }, 13 | [GE_RGBA_4444] = { GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV }, 14 | [GE_RGBA_8888] = { GL_RGBA, GL_UNSIGNED_BYTE }, 15 | }; 16 | 17 | void glCopyTexImage2D(GLenum target, 18 | GLint level, 19 | GLenum internalformat, 20 | GLint x, GLint y, 21 | GLsizei width, GLsizei height, 22 | GLint border) 23 | { 24 | GLenum fb_fmt, fb_type; 25 | struct pspgl_texobj *tobj; 26 | struct pspgl_teximg *timg; 27 | struct pspgl_surface *read; 28 | int dest_x, dest_y; 29 | 30 | read = pspgl_curctx->read; 31 | fb_fmt = formats[read->pixfmt].format; 32 | fb_type = formats[read->pixfmt].type; 33 | 34 | /* glTexImage2D does all the hard work... */ 35 | glTexImage2D(target, level, fb_fmt, width, height, border, fb_fmt, fb_type, NULL); 36 | if (pspgl_curctx->glerror != GL_NO_ERROR) 37 | return; 38 | 39 | tobj = pspgl_curctx->texture.bound; 40 | timg = tobj->images[level]; 41 | 42 | __pspgl_texobj_unswizzle(tobj); 43 | 44 | assert(timg->texfmt->hwformat == read->pixfmt); 45 | assert(width == timg->width); 46 | assert(height == timg->height); 47 | 48 | dest_x = 0; 49 | dest_y = 0; 50 | 51 | if (x < 0) { 52 | x = -x; 53 | dest_x += x; 54 | width -= x; 55 | x = 0; 56 | } 57 | if ((x + width) > read->width) 58 | width -= (x + width) - read->width; 59 | 60 | if (y < 0) { 61 | y = -y; 62 | dest_y += y; 63 | height -= y; 64 | y = 0; 65 | } 66 | if ((y + height) > read->height) 67 | height -= (y + height) - read->height; 68 | 69 | if (unlikely(width <= 0) || unlikely(height <= 0)) 70 | goto out_error; 71 | 72 | /* The framebuffer and the texture are upside down with 73 | respect to each other, so we need to flip the image (in the 74 | framebuffer, lower addresses are in the upper-left, but for 75 | textures, lower addresses are lower-left). */ 76 | tobj->flags |= TOF_FLIPPED; 77 | y = read->height - y - height; 78 | 79 | struct pspgl_buffer *framebuffer = *(read->read); 80 | 81 | __pspgl_copy_pixels(framebuffer->base, read->pixelperline, x, y, 82 | timg->image->base + timg->offset, timg->width, dest_x, dest_y, 83 | width, height, read->pixfmt); 84 | 85 | __pspgl_dlist_pin_buffer(timg->image, BF_PINNED_WR); 86 | __pspgl_dlist_pin_buffer(framebuffer, BF_PINNED_RD); 87 | 88 | sendCommandi(CMD_TEXCACHE_SYNC, getReg(CMD_TEXCACHE_SYNC)+1); 89 | sendCommandi(CMD_TEXCACHE_FLUSH, getReg(CMD_TEXCACHE_FLUSH)+1); 90 | 91 | if (level == 0 && (tobj->flags & TOF_GENERATE_MIPMAPS)) 92 | __pspgl_update_mipmaps(); 93 | 94 | return; 95 | 96 | out_error: 97 | GLERROR(GL_INVALID_VALUE); 98 | } 99 | -------------------------------------------------------------------------------- /glCullFace.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glCullFace (GLenum mode) 5 | { 6 | switch (mode) { 7 | case GL_BACK: 8 | case GL_FRONT: 9 | pspgl_curctx->polygon.cull_front = (mode == GL_FRONT); 10 | 11 | /* Because the PSP uses a right-handed screen coord system, 12 | the cull face direction is reversed with respect to the 13 | normal sense of CMD_CULL_FACE. */ 14 | sendCommandi(CMD_CULL_FACE, (pspgl_curctx->polygon.front_cw ^ pspgl_curctx->polygon.cull_front)); 15 | break; 16 | 17 | case GL_FRONT_AND_BACK: 18 | default: 19 | GLERROR(GL_INVALID_ENUM); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /glDeleteBuffersARB.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | void glDeleteBuffersARB (GLsizei n, const GLuint *buffers) 5 | { 6 | int i; 7 | struct hashtable *hash = &pspgl_curctx->shared->buffers; 8 | 9 | if (unlikely(n < 0)) 10 | goto out_error; 11 | 12 | for(i = 0; i < n; i++) { 13 | GLuint id = buffers[i]; 14 | struct pspgl_bufferobj *bufp; 15 | 16 | if (id == 0) 17 | continue; 18 | 19 | bufp = __pspgl_hash_remove(hash, id); 20 | 21 | if (bufp) { 22 | int t; 23 | struct pspgl_bufferobj **boundp; 24 | static const GLenum targets[] = { 25 | GL_ARRAY_BUFFER_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB 26 | }; 27 | 28 | for(t = 0; t < sizeof(targets)/sizeof(*targets); t++) { 29 | boundp = __pspgl_bufferobj_for_target(targets[t]); 30 | 31 | if (boundp != NULL && *boundp == bufp) 32 | glBindBufferARB(targets[t], 0); 33 | } 34 | 35 | __pspgl_bufferobj_free(bufp); 36 | } 37 | } 38 | return; 39 | 40 | out_error: 41 | GLERROR(GL_INVALID_VALUE); 42 | } 43 | 44 | void glDeleteBuffers (GLsizei n, const GLuint *buffers) 45 | __attribute__((alias("glDeleteBuffersARB"))); 46 | -------------------------------------------------------------------------------- /glDeleteLists.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | 4 | 5 | void glDeleteLists (GLuint list, GLsizei range) 6 | { 7 | struct hashtable *hash = &pspgl_curctx->shared->display_lists; 8 | 9 | if (unlikely(range < 0)) 10 | goto out_error; 11 | 12 | for (; range>0; list++, range--) { 13 | void *dlist = __pspgl_hash_remove(hash, list); 14 | if (dlist) { 15 | if (dlist == pspgl_curctx->dlist_current) 16 | /*set default dlist*/; 17 | /* should become a dlist_free() */ 18 | free(dlist); 19 | } 20 | } 21 | 22 | return; 23 | out_error: 24 | GLERROR(GL_INVALID_VALUE); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /glDeleteTextures.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | #include "pspgl_texobj.h" 4 | 5 | void glDeleteTextures (GLsizei n, const GLuint *textures) 6 | { 7 | struct hashtable *hash = &pspgl_curctx->shared->texture_objects; 8 | GLsizei i; 9 | 10 | if (unlikely(n < 0)) 11 | goto out_error; 12 | 13 | for (i=0; itexture.bound) 18 | glBindTexture(tobj->target, 0); 19 | __pspgl_texobj_free(tobj); 20 | } 21 | } 22 | } 23 | 24 | return; 25 | out_error: 26 | GLERROR(GL_INVALID_VALUE); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /glDepthFunc.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | /* 4 | Because the PSP's Z coord system is backwards from OpenGL's, we 5 | need to reverse order of depth comparisons. 6 | */ 7 | static const unsigned char depthfunc_mapping [] = { 8 | GE_NEVER, /* GL_NEVER */ 9 | GE_GEQUAL, /* GL_LESS */ 10 | GE_EQUAL, /* GL_EQUAL */ 11 | GE_GREATER, /* GL_LEQUAL */ 12 | GE_LEQUAL, /* GL_GREATER */ 13 | GE_NOTEQUAL, /* GL_NOTEQUAL */ 14 | GE_LESS, /* GL_GEQUAL */ 15 | GE_ALWAYS, /* GL_ALWAYS */ 16 | }; 17 | 18 | void glDepthFunc (GLenum func) 19 | { 20 | if (unlikely(func < GL_NEVER) || unlikely(func > GL_ALWAYS)) 21 | goto out_error; 22 | 23 | sendCommandi(CMD_DEPTH_FUNC, depthfunc_mapping[func - GL_NEVER]); 24 | return; 25 | 26 | out_error: 27 | GLERROR(GL_INVALID_ENUM); 28 | } 29 | -------------------------------------------------------------------------------- /glDepthMask.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glDepthMask (GLboolean flag) 5 | { 6 | sendCommandi(CMD_DEPTH_MASK, flag ? 0 : ~0); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /glDepthRange.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void glDepthRangef (GLclampf zNear, GLclampf zFar); 4 | 5 | void glDepthRange (GLclampd zNear, GLclampd zFar) 6 | { 7 | glDepthRangef(zNear, zFar); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /glDepthRangef.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | 4 | void glDepthRangef (GLclampf zNear, GLclampf zFar) 5 | { 6 | float mid; 7 | 8 | zNear = CLAMPF(zNear) * 65535.f; 9 | zFar = CLAMPF(zFar) * 65535.f; 10 | 11 | mid = (zNear+zFar) / 2; 12 | 13 | /* z Scale and Offset 14 | 15 | The PSP seems to use the opposite convention from OpenGL 16 | about the depth direction; uses positive Z into the screen, 17 | with larger depth-buffer values being closer. This Z scale 18 | factor flips Z around to match what the rest of GL expects. 19 | */ 20 | sendCommandf(CMD_VIEWPORT_SZ, mid - zFar); 21 | sendCommandf(CMD_VIEWPORT_TZ, mid + pspgl_curctx->viewport.depth_offset); 22 | 23 | if (zNear > zFar) { 24 | GLfloat temp = zNear; 25 | zNear = zFar; 26 | zFar = temp; 27 | } 28 | 29 | /* Far and Near Clip Planes. Clipping happens before the 30 | viewport transform, and are therefore in the OpenGL 31 | coordinate system. */ 32 | sendCommandi(CMD_CLIP_NEAR, (int) zNear); 33 | sendCommandi(CMD_CLIP_FAR, (int) zFar); 34 | } 35 | -------------------------------------------------------------------------------- /glDrawArrays.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glDrawArrays (GLenum mode, GLint first, GLsizei count) 5 | { 6 | __pspgl_varray_draw(mode, first, count); 7 | } 8 | -------------------------------------------------------------------------------- /glDrawBezierArrays.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | #include "pspgl_buffers.h" 5 | #include "pspgl_dlist.h" 6 | 7 | void glDrawBezierArraysPSP(GLenum mode, GLuint u, GLuint v, GLint first) 8 | { 9 | struct pspgl_context *c = pspgl_curctx; 10 | struct vertex_format vfmt, *vfmtp; 11 | struct pspgl_buffer *vbuf; 12 | unsigned vbuf_offset; 13 | const void *buf; 14 | unsigned prim; 15 | unsigned count; 16 | GLenum error; 17 | 18 | error = GL_INVALID_ENUM; 19 | 20 | switch(mode) { 21 | case GL_TRIANGLES: prim = 0; break; 22 | case GL_LINES: prim = 1; break; 23 | case GL_POINTS: prim = 2; break; 24 | 25 | default: 26 | goto out_error; 27 | } 28 | sendCommandi(CMD_PATCH_PRIM, prim); 29 | 30 | count = u * v; 31 | 32 | vbuf = NULL; 33 | vbuf_offset = 0; 34 | vfmtp = &vfmt; 35 | 36 | if (__pspgl_cache_arrays()) { 37 | /* FAST: draw from locked array */ 38 | struct locked_arrays *l = &c->vertex_array.locked; 39 | 40 | vbuf = l->cached_array; 41 | vbuf_offset = l->cached_array_offset; 42 | vfmtp = &l->vfmt; 43 | first -= l->cached_first; 44 | 45 | vbuf->refcount++; 46 | } 47 | 48 | if (unlikely(vbuf == NULL)) { 49 | /* SLOW: convert us some arrays */ 50 | __pspgl_ge_vertex_fmt(c, &vfmt); 51 | 52 | if (vfmt.hwformat == 0) 53 | return; 54 | 55 | vbuf = __pspgl_varray_convert(&vfmt, first, count); 56 | 57 | error = GL_OUT_OF_MEMORY; 58 | if (vbuf == NULL) 59 | goto out_error; 60 | } 61 | 62 | buf = vbuf->base + vbuf_offset; 63 | buf += first * vfmtp->vertex_size; 64 | 65 | __pspgl_context_render_setup(c, vfmtp->hwformat, buf, NULL); 66 | __pspgl_context_writereg_uncached(c, CMD_BEZIER, (v << 8) | u); 67 | __pspgl_context_pin_buffers(c); 68 | __pspgl_dlist_pin_buffer(vbuf, BF_PINNED_RD); 69 | 70 | __pspgl_buffer_free(vbuf); 71 | return; 72 | 73 | out_error: 74 | GLERROR(error); 75 | } 76 | 77 | 78 | void glPatchSubdivisionPSP(GLuint u, GLuint v) 79 | { 80 | sendCommandi(CMD_PATCH_SUBDIV, (v << 8) | u); 81 | } 82 | -------------------------------------------------------------------------------- /glDrawBezierElements.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | #include "pspgl_dlist.h" 4 | 5 | void glDrawBezierRangeElementsPSP(GLenum mode, GLuint start, GLuint end, 6 | GLuint u, GLuint v, 7 | GLenum idx_type, const GLvoid *indices) 8 | { 9 | struct pspgl_context *c = pspgl_curctx; 10 | long prim; 11 | struct vertex_format vfmt; 12 | const struct vertex_format *vfmtp; 13 | struct pspgl_buffer *vbuf, *ibuf; 14 | unsigned vbuf_offset; 15 | unsigned idx_base; 16 | unsigned ibuf_offset; 17 | const void *vtxp, *idxp; 18 | unsigned hwformat; 19 | unsigned count; 20 | int minidx = start; 21 | int maxidx = end; 22 | GLenum error; 23 | 24 | error = GL_INVALID_ENUM; 25 | switch(mode) { 26 | case GL_TRIANGLES: prim = 0; break; 27 | case GL_LINES: prim = 1; break; 28 | case GL_POINTS: prim = 2; break; 29 | 30 | default: 31 | goto out_error; 32 | } 33 | sendCommandi(CMD_PATCH_PRIM, prim); 34 | 35 | count = u * v; 36 | 37 | if (count == 0) 38 | return; 39 | 40 | vbuf = NULL; 41 | idx_base = 0; 42 | vfmtp = &vfmt; 43 | vbuf_offset = 0; 44 | 45 | if (__pspgl_cache_arrays()) { 46 | /* FAST: directly usable locked arrays */ 47 | struct locked_arrays *l = &c->vertex_array.locked; 48 | 49 | vbuf = l->cached_array; 50 | vbuf_offset = l->cached_array_offset; 51 | vfmtp = &l->vfmt; 52 | idx_base = l->cached_first; 53 | 54 | vbuf->refcount++; 55 | } 56 | 57 | error = GL_OUT_OF_MEMORY; 58 | if (unlikely(vbuf == NULL)) { 59 | /* SLOW: convert us some arrays */ 60 | __pspgl_ge_vertex_fmt(c, &vfmt); 61 | 62 | if (vfmt.hwformat == 0) 63 | return; 64 | 65 | if (minidx == -1 || maxidx == -1) { 66 | /* need to work out min/maxidx for ourselves */ 67 | const void *idxmap; 68 | 69 | idxmap = __pspgl_bufferobj_map(c->vertex_array.indexbuffer, 70 | GL_READ_ONLY_ARB, (void *)indices); 71 | 72 | __pspgl_find_minmax_indices(idx_type, idxmap, count, 73 | &minidx, &maxidx); 74 | 75 | __pspgl_bufferobj_unmap(c->vertex_array.indexbuffer, 76 | GL_READ_ONLY_ARB); 77 | } 78 | 79 | vbuf = __pspgl_varray_convert(&vfmt, minidx, maxidx-minidx+1); 80 | vbuf_offset = 0; 81 | idx_base = minidx; 82 | 83 | if (vbuf == NULL) 84 | goto out_error; 85 | } 86 | 87 | hwformat = vfmtp->hwformat; 88 | 89 | ibuf = __pspgl_varray_convert_indices(idx_type, indices, idx_base, count, 90 | &ibuf_offset, &hwformat); 91 | if (ibuf == NULL) 92 | goto out_error_free_vbuf; 93 | 94 | vtxp = vbuf->base + vbuf_offset; 95 | idxp = ibuf->base + ibuf_offset; 96 | 97 | __pspgl_context_render_setup(c, hwformat, vtxp, idxp); 98 | __pspgl_context_writereg_uncached(c, CMD_BEZIER, (v << 8) | u); 99 | __pspgl_context_pin_buffers(c); 100 | __pspgl_dlist_pin_buffer(vbuf, BF_PINNED_RD); 101 | __pspgl_dlist_pin_buffer(ibuf, BF_PINNED_RD); 102 | 103 | __pspgl_buffer_free(vbuf); 104 | __pspgl_buffer_free(ibuf); 105 | return; 106 | 107 | out_error_free_vbuf: 108 | __pspgl_buffer_free(vbuf); 109 | 110 | out_error: 111 | GLERROR(error); 112 | } 113 | 114 | void glDrawBezierElementsPSP(GLenum mode, GLuint u, GLuint v, 115 | GLenum idx_type, const GLvoid *indices) 116 | { 117 | struct locked_arrays *l = &pspgl_curctx->vertex_array.locked; 118 | int minidx, maxidx; 119 | 120 | minidx = maxidx = -1; 121 | 122 | if (l->count > 0) { 123 | /* use locked range */ 124 | 125 | minidx = l->first; 126 | maxidx = l->first + l->count; 127 | } 128 | 129 | glDrawBezierRangeElementsPSP(mode, minidx, maxidx, u, v, idx_type, indices); 130 | } 131 | -------------------------------------------------------------------------------- /glDrawBuffer.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | void glDrawBuffer(GLenum mode) 5 | { 6 | struct pspgl_surface *s = pspgl_curctx->draw; 7 | 8 | switch (mode) { 9 | case GL_BACK: 10 | s->draw = &s->color_back; 11 | break; 12 | case GL_FRONT: 13 | s->draw = &s->color_front; 14 | break; 15 | default: 16 | /* XXX IMPROVE: support front & aux buffers */ 17 | GLERROR(GL_INVALID_ENUM); 18 | return; 19 | } 20 | 21 | unsigned adr = (unsigned long) (*s->draw)->base; 22 | sendCommandi(CMD_DRAWBUF, (adr & 0x00ffffff)); 23 | sendCommandi(CMD_DRAWBUFWIDTH, ((adr & 0xff000000) >> 8) | s->pixelperline); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /glDrawElements.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) 5 | { 6 | __pspgl_varray_draw_elts(mode, type, indices, count); 7 | } 8 | -------------------------------------------------------------------------------- /glDrawSplineArrays.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | #include "pspgl_buffers.h" 5 | #include "pspgl_dlist.h" 6 | 7 | void glDrawSplineArraysPSP(GLenum mode, GLuint u, GLuint v, 8 | GLenum u_flags, GLenum v_flags, 9 | GLint first) 10 | { 11 | struct pspgl_context *c = pspgl_curctx; 12 | struct vertex_format vfmt, *vfmtp; 13 | struct pspgl_buffer *vbuf; 14 | unsigned vbuf_offset; 15 | const void *buf; 16 | unsigned prim; 17 | unsigned count; 18 | GLenum error; 19 | 20 | error = GL_INVALID_ENUM; 21 | 22 | if (u_flags < GL_PATCH_INNER_INNER_PSP || u_flags > GL_PATCH_OUTER_OUTER_PSP || 23 | v_flags < GL_PATCH_INNER_INNER_PSP || v_flags > GL_PATCH_OUTER_OUTER_PSP) 24 | goto out_error; 25 | 26 | switch(mode) { 27 | case GL_TRIANGLES: prim = 0; break; 28 | case GL_LINES: prim = 1; break; 29 | case GL_POINTS: prim = 2; break; 30 | 31 | default: 32 | goto out_error; 33 | } 34 | sendCommandi(CMD_PATCH_PRIM, prim); 35 | 36 | count = u * v; 37 | 38 | vbuf = NULL; 39 | vbuf_offset = 0; 40 | vfmtp = &vfmt; 41 | 42 | if (__pspgl_cache_arrays()) { 43 | /* FAST: draw from locked array */ 44 | struct locked_arrays *l = &c->vertex_array.locked; 45 | 46 | vbuf = l->cached_array; 47 | vbuf_offset = l->cached_array_offset; 48 | vfmtp = &l->vfmt; 49 | first -= l->cached_first; 50 | 51 | vbuf->refcount++; 52 | } 53 | 54 | error = GL_OUT_OF_MEMORY; 55 | if (unlikely(vbuf == NULL)) { 56 | /* SLOW: convert us some arrays */ 57 | __pspgl_ge_vertex_fmt(c, &vfmt); 58 | 59 | if (vfmt.hwformat == 0) 60 | return; 61 | 62 | vbuf = __pspgl_varray_convert(&vfmt, first, count); 63 | 64 | if (vbuf == NULL) 65 | goto out_error; 66 | } 67 | 68 | buf = vbuf->base + vbuf_offset; 69 | buf += first * vfmtp->vertex_size; 70 | 71 | u_flags &= 3; 72 | v_flags &= 3; 73 | 74 | __pspgl_context_render_setup(c, vfmtp->hwformat, buf, NULL); 75 | __pspgl_context_writereg_uncached(c, CMD_SPLINE, 76 | (v_flags << 18) | (u_flags << 16) | (v << 8) | u); 77 | __pspgl_context_pin_buffers(c); 78 | __pspgl_dlist_pin_buffer(vbuf, BF_PINNED_RD); 79 | 80 | __pspgl_buffer_free(vbuf); 81 | return; 82 | 83 | out_error: 84 | GLERROR(error); 85 | } 86 | -------------------------------------------------------------------------------- /glDrawSplineElements.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | #include "pspgl_dlist.h" 4 | 5 | void glDrawSplineRangeElementsPSP(GLenum mode, GLuint start, GLuint end, 6 | GLuint u, GLuint v, 7 | GLenum u_flags, GLenum v_flags, 8 | GLenum idx_type, const GLvoid *indices) 9 | { 10 | struct pspgl_context *c = pspgl_curctx; 11 | long prim; 12 | struct vertex_format vfmt; 13 | const struct vertex_format *vfmtp; 14 | struct pspgl_buffer *vbuf, *ibuf; 15 | unsigned vbuf_offset; 16 | unsigned idx_base; 17 | unsigned ibuf_offset; 18 | const void *vtxp, *idxp; 19 | unsigned hwformat; 20 | unsigned count; 21 | int minidx = start; 22 | int maxidx = end; 23 | GLenum error; 24 | 25 | error = GL_INVALID_ENUM; 26 | if (u_flags < GL_PATCH_INNER_INNER_PSP || u_flags > GL_PATCH_OUTER_OUTER_PSP || 27 | v_flags < GL_PATCH_INNER_INNER_PSP || v_flags > GL_PATCH_OUTER_OUTER_PSP) 28 | goto out_error; 29 | 30 | switch(mode) { 31 | case GL_TRIANGLES: prim = 0; break; 32 | case GL_LINES: prim = 1; break; 33 | case GL_POINTS: prim = 2; break; 34 | 35 | default: 36 | goto out_error; 37 | } 38 | sendCommandi(CMD_PATCH_PRIM, prim); 39 | 40 | count = u * v; 41 | 42 | if (count == 0) 43 | return; 44 | 45 | vbuf = NULL; 46 | idx_base = 0; 47 | 48 | if (__pspgl_cache_arrays()) { 49 | /* FAST: directly usable locked arrays */ 50 | struct locked_arrays *l = &c->vertex_array.locked; 51 | 52 | vbuf = l->cached_array; 53 | vbuf_offset = l->cached_array_offset; 54 | vfmtp = &l->vfmt; 55 | idx_base = l->cached_first; 56 | 57 | vbuf->refcount++; 58 | } 59 | 60 | if (vbuf == NULL) { 61 | /* SLOW: convert us some arrays */ 62 | vfmtp = &vfmt; 63 | __pspgl_ge_vertex_fmt(c, &vfmt); 64 | 65 | if (vfmt.hwformat == 0) 66 | return; 67 | 68 | if (minidx == -1 || maxidx == -1) { 69 | /* need to work out min/maxidx for ourselves */ 70 | const void *idxmap; 71 | 72 | idxmap = __pspgl_bufferobj_map(c->vertex_array.indexbuffer, 73 | GL_READ_ONLY_ARB, (void *)indices); 74 | 75 | __pspgl_find_minmax_indices(idx_type, idxmap, count, 76 | &minidx, &maxidx); 77 | 78 | __pspgl_bufferobj_unmap(c->vertex_array.indexbuffer, 79 | GL_READ_ONLY_ARB); 80 | } 81 | 82 | vbuf = __pspgl_varray_convert(&vfmt, minidx, maxidx-minidx+1); 83 | vbuf_offset = 0; 84 | idx_base = minidx; 85 | 86 | error = GL_OUT_OF_MEMORY; 87 | if (vbuf == NULL) 88 | goto out_error; 89 | } 90 | 91 | hwformat = vfmtp->hwformat; 92 | 93 | ibuf = __pspgl_varray_convert_indices(idx_type, indices, idx_base, count, 94 | &ibuf_offset, &hwformat); 95 | if (ibuf == NULL) 96 | goto out_error_free_vbuf; 97 | 98 | vtxp = vbuf->base + vbuf_offset; 99 | idxp = ibuf->base + ibuf_offset; 100 | 101 | u_flags &= 3; 102 | v_flags &= 3; 103 | 104 | __pspgl_context_render_setup(c, hwformat, vtxp, idxp); 105 | __pspgl_context_writereg_uncached(c, CMD_SPLINE, 106 | (v_flags << 18) | (u_flags << 16) | (v << 8) | u); 107 | __pspgl_context_pin_buffers(c); 108 | __pspgl_dlist_pin_buffer(vbuf, BF_PINNED_RD); 109 | __pspgl_dlist_pin_buffer(ibuf, BF_PINNED_RD); 110 | 111 | __pspgl_buffer_free(vbuf); 112 | __pspgl_buffer_free(ibuf); 113 | return; 114 | 115 | out_error_free_vbuf: 116 | __pspgl_buffer_free(vbuf); 117 | 118 | out_error: 119 | GLERROR(error); 120 | } 121 | 122 | void glDrawSplineElementsPSP(GLenum mode, GLuint u, GLuint v, 123 | GLenum u_flags, GLenum v_flags, 124 | GLenum idx_type, const GLvoid *indices) 125 | { 126 | struct locked_arrays *l = &pspgl_curctx->vertex_array.locked; 127 | int minidx, maxidx; 128 | 129 | minidx = maxidx = -1; 130 | 131 | if (l->count > 0) { 132 | /* use locked range */ 133 | 134 | minidx = l->first; 135 | maxidx = l->first + l->count; 136 | } 137 | 138 | glDrawSplineRangeElementsPSP(mode, minidx, maxidx, 139 | u, v, u_flags, v_flags, 140 | idx_type, indices); 141 | } 142 | -------------------------------------------------------------------------------- /glEnable.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void __pspgl_enable_state (GLenum cap, GLboolean enable) 4 | { 5 | int i; 6 | unsigned char opcode = 0; 7 | 8 | // @@@ from here it's allways the same code exept for index of the command 9 | if (pspgl_curctx->displaylists.is_in_glNewList & GL_COMPILE) { // we must record this command 10 | struct stDisplayElement *new; 11 | new = (struct stDisplayElement *) malloc (sizeof(struct stDisplayElement)); 12 | // @@@ put new element at the end of list 13 | if (!__pspgl_actuallist->first) 14 | __pspgl_actuallist->first = new; 15 | if (__pspgl_actuallist->last) 16 | __pspgl_actuallist->last->next = new; 17 | new->next = NULL; 18 | __pspgl_actuallist->last = new; 19 | 20 | new->command_num = GLENABLE; 21 | new->parami1 = cap; 22 | new->parami2 = enable; 23 | } 24 | 25 | if ((pspgl_curctx->displaylists.is_in_glNewList == GL_COMPILE_AND_EXECUTE)||(pspgl_curctx->displaylists.is_in_glNewList == 0)) { 26 | // @@@ from here it's different, because it's the old function 27 | switch (cap) { 28 | case GL_FOG: 29 | opcode = CMD_ENA_FOG; 30 | break; 31 | case GL_LIGHTING: { 32 | unsigned long c; 33 | opcode = CMD_ENA_LIGHTING; 34 | 35 | /* switch material ambient around depending on lighting state */ 36 | if (enable) 37 | c = pspgl_curctx->material.ambient; 38 | else 39 | c = pspgl_curctx->current.color; 40 | sendCommandi(CMD_MATERIAL_AMB_C, c); 41 | sendCommandi(CMD_MATERIAL_AMB_A, c>>24); 42 | break; 43 | } 44 | case GL_TEXTURE_2D: 45 | opcode = CMD_ENA_TEXTURE; 46 | break; 47 | case GL_CULL_FACE: 48 | opcode = CMD_ENA_CULL; 49 | break; 50 | case GL_ALPHA_TEST: 51 | opcode = CMD_ENA_ALPHA_TEST; 52 | break; 53 | case GL_BLEND: 54 | opcode = CMD_ENA_BLEND; 55 | break; 56 | case GL_COLOR_LOGIC_OP: 57 | opcode = CMD_ENA_LOGIC; 58 | break; 59 | case GL_DITHER: 60 | opcode = CMD_ENA_DITHER; 61 | break; 62 | case GL_STENCIL_TEST: 63 | opcode = CMD_ENA_STENCIL_TEST; 64 | enable = enable && pspgl_curctx->draw->stencil_mask; 65 | if (enable) 66 | sendCommandi(CMD_ALPHA_MASK, ~pspgl_curctx->write_mask.stencil); 67 | else 68 | sendCommandi(CMD_ALPHA_MASK, ~pspgl_curctx->write_mask.alpha); 69 | break; 70 | case GL_DEPTH_TEST: 71 | opcode = CMD_ENA_DEPTH_TEST; 72 | enable = enable && pspgl_curctx->draw->depth_buffer; 73 | break; 74 | case GL_LIGHT0: 75 | case GL_LIGHT1: 76 | case GL_LIGHT2: 77 | case GL_LIGHT3: 78 | opcode = cap - GL_LIGHT0 + CMD_ENA_LIGHT0; 79 | break; 80 | case GL_LINE_SMOOTH: 81 | case GL_POINT_SMOOTH: 82 | opcode = CMD_ENA_ANTIALIAS; /* XXX : antialiasing. both line and point? */ 83 | break; 84 | case GL_SCISSOR_TEST: 85 | pspgl_curctx->scissor_test.enabled = enable; 86 | __pspgl_set_scissor(); 87 | return; 88 | 89 | case GL_VERTEX_BLEND_PSP: 90 | /* There's no specific enable flag for vertex 91 | blending, but disabling the matricies (=identity) 92 | should have the same effect. */ 93 | pspgl_curctx->vertexblend.enabled = enable; 94 | for(i = 0; i < NBONES; i++) { 95 | struct pspgl_matrix_stack *m = &pspgl_curctx->bone_stacks[i]; 96 | 97 | m->flags = (m->flags & ~MF_DISABLED) | 98 | (enable ? 0 : MF_DISABLED) | MF_DIRTY; 99 | } 100 | break; 101 | 102 | case GL_TEXTURE_GEN_S: 103 | case GL_TEXTURE_GEN_T: 104 | /* TODO */ 105 | break; 106 | case GL_NORMALIZE: 107 | /* ? */ 108 | break; 109 | 110 | case GL_COLOR_MATERIAL: 111 | case GL_RESCALE_NORMAL: 112 | case GL_POLYGON_OFFSET_FILL: 113 | case GL_VERTEX_ARRAY: 114 | case GL_NORMAL_ARRAY: 115 | case GL_COLOR_ARRAY: 116 | case GL_TEXTURE_COORD_ARRAY: 117 | case GL_MULTISAMPLE: 118 | case GL_SAMPLE_ALPHA_TO_COVERAGE: 119 | case GL_SAMPLE_ALPHA_TO_ONE: 120 | case GL_SAMPLE_COVERAGE: 121 | default: 122 | GLERROR(GL_INVALID_ENUM); 123 | return; 124 | } 125 | 126 | if (opcode) 127 | sendCommandi(opcode, enable); 128 | } 129 | } 130 | 131 | 132 | void glEnable (GLenum cap) 133 | { 134 | __pspgl_enable_state(cap, 1); 135 | } 136 | 137 | 138 | void glDisable (GLenum cap) 139 | { 140 | __pspgl_enable_state(cap, 0); 141 | } 142 | 143 | -------------------------------------------------------------------------------- /glEnableClientState.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | static void enable_clientstate (GLenum array, GLboolean enable) 5 | { 6 | struct varray *va = &pspgl_curctx->vertex_array; 7 | 8 | switch (array) { 9 | case GL_VERTEX_ARRAY: 10 | va->vertex.enabled = enable; 11 | break; 12 | case GL_COLOR_ARRAY: 13 | va->color.enabled = enable; 14 | break; 15 | case GL_NORMAL_ARRAY: 16 | va->normal.enabled = enable; 17 | break; 18 | case GL_TEXTURE_COORD_ARRAY: 19 | va->texcoord.enabled = enable; 20 | break; 21 | case GL_WEIGHT_ARRAY_PSP: 22 | va->weight.enabled = enable; 23 | break; 24 | default: 25 | GLERROR(GL_INVALID_ENUM); 26 | return; 27 | } 28 | 29 | if (va->locked.cached_array && 30 | va->locked.vfmt.arrays != __pspgl_enabled_array_bits()) { 31 | psp_log("array state changed %x->%x; invalidating cached arrays\n", 32 | va->locked.vfmt.arrays, __pspgl_enabled_array_bits()); 33 | __pspgl_uncache_arrays(); 34 | } 35 | } 36 | 37 | 38 | void glEnableClientState (GLenum array) 39 | { 40 | enable_clientstate(array, GL_TRUE); 41 | } 42 | 43 | 44 | void glDisableClientState (GLenum array) 45 | { 46 | enable_clientstate(array, GL_FALSE); 47 | } 48 | -------------------------------------------------------------------------------- /glEnd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | 4 | 5 | void glEnd (void) 6 | { 7 | struct pspgl_context *c = pspgl_curctx; 8 | 9 | // @@@ from here it's allways the same code exept for index of the command 10 | if (pspgl_curctx->displaylists.is_in_glNewList & GL_COMPILE) { // we must record this command 11 | struct stDisplayElement *new; 12 | new = (struct stDisplayElement *) malloc (sizeof(struct stDisplayElement)); 13 | // @@@ put new element at the end of list 14 | if (!__pspgl_actuallist->first) 15 | __pspgl_actuallist->first = new; 16 | if (__pspgl_actuallist->last) 17 | __pspgl_actuallist->last->next = new; 18 | new->next = NULL; 19 | __pspgl_actuallist->last = new; 20 | 21 | new->command_num = GLEND; 22 | } 23 | 24 | if ((pspgl_curctx->displaylists.is_in_glNewList == GL_COMPILE_AND_EXECUTE)||(pspgl_curctx->displaylists.is_in_glNewList == 0)) { 25 | // @@@ from here it's different 26 | if (likely(c->beginend.vertex_count > 0)) { 27 | long prim = __pspgl_glprim2geprim(c->beginend.primitive); 28 | 29 | if (unlikely(prim < 0)) 30 | goto out_error; 31 | 32 | /* If we've finished a line loop, connect the last 33 | edge to the first vertex to close the loop. */ 34 | if (c->beginend.primitive == GL_LINE_LOOP) { 35 | struct t2f_c4ub_n3f_v3f *vbuf = (struct t2f_c4ub_n3f_v3f *) c->beginend.vbuf_adr; 36 | 37 | vbuf += c->beginend.vertex_count; 38 | memcpy(vbuf, &c->beginend.line_loop_start, sizeof(*vbuf)); 39 | c->beginend.vertex_count++; 40 | } 41 | 42 | __pspgl_context_render_prim(pspgl_curctx, prim, c->beginend.vertex_count, 43 | GE_TEXTURE_32BITF | GE_COLOR_8888 | GE_NORMAL_32BITF | GE_VERTEX_32BITF, 44 | c->beginend.vbuf_adr, NULL); 45 | } 46 | 47 | pspgl_curctx->beginend.primitive = -1; 48 | return; 49 | 50 | out_error: 51 | GLERROR(GL_INVALID_ENUM); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /glFinish.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_dlist.h" 3 | 4 | void glFinish (void) 5 | { 6 | __pspgl_dlist_submit(); 7 | __pspgl_dlist_await_completion(NULL, NULL); 8 | } 9 | -------------------------------------------------------------------------------- /glFlush.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_dlist.h" 3 | 4 | void glFlush (void) 5 | { 6 | __pspgl_dlist_submit(); 7 | } 8 | -------------------------------------------------------------------------------- /glFog.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glFogf (GLenum pname, GLfloat param) 5 | { 6 | float distance; 7 | GLenum error; 8 | 9 | error = GL_INVALID_VALUE; 10 | switch (pname) { 11 | case GL_FOG_MODE: 12 | if (param != GL_LINEAR) 13 | goto out_error; 14 | break; 15 | 16 | case GL_FOG_START: 17 | pspgl_curctx->fog.near = param; 18 | distance = pspgl_curctx->fog.far - pspgl_curctx->fog.near; 19 | if (unlikely(distance == 0)) 20 | goto out_error; 21 | distance = 1.0f / distance; 22 | sendCommandf(CMD_FOG_NEAR, distance); 23 | break; 24 | 25 | case GL_FOG_END: 26 | pspgl_curctx->fog.far = param; 27 | // @@@ added by Edorul by this way we can declare GL_FOG_START before GL_FOG_END 28 | // @@@ else we have a strange result (the fog is "inversed") 29 | distance = pspgl_curctx->fog.far - pspgl_curctx->fog.near; 30 | if (unlikely(distance == 0)) 31 | goto out_error; 32 | distance = 1.0f / distance; 33 | sendCommandf(CMD_FOG_NEAR, distance); 34 | // @@@ end modif by Edorul 35 | sendCommandf(CMD_FOG_FAR, pspgl_curctx->fog.far); 36 | break; 37 | /** 38 | case XXXX: 39 | pspgl_curctx->fog.XXXXX = param; 40 | sendCommandf(248, ??fog type??); 41 | break; 42 | */ 43 | default: 44 | error = GL_INVALID_ENUM; 45 | goto out_error; 46 | } 47 | 48 | return; 49 | 50 | out_error: 51 | GLERROR(error); 52 | } 53 | 54 | 55 | void glFogi (GLenum pname, GLint param) 56 | { 57 | glFogf(pname, (GLfloat) param); 58 | } 59 | 60 | 61 | void glFogfv (GLenum pname, const GLfloat *param) 62 | { 63 | switch (pname) { 64 | case GL_FOG_COLOR: 65 | sendCommandi(CMD_FOG_COLOR, COLOR3(param)); 66 | break; 67 | default: 68 | glFogf(pname, param[0]); 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /glFrontFace.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glFrontFace (GLenum mode) 5 | { 6 | if (unlikely(mode != GL_CW && mode != GL_CCW)) 7 | goto out_error; 8 | 9 | pspgl_curctx->polygon.front_cw = (mode == GL_CW); 10 | 11 | /* Because the PSP uses a right-handed screen coord system, 12 | the cull face direction is reversed with respect to the 13 | normal sense of CMD_CULL_FACE. */ 14 | sendCommandi(CMD_CULL_FACE, (pspgl_curctx->polygon.front_cw ^ pspgl_curctx->polygon.cull_front)); 15 | return; 16 | 17 | out_error: 18 | GLERROR(GL_INVALID_ENUM); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /glFrustum.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | extern void glFrustumf (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar); 4 | 5 | void glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) 6 | { 7 | glFrustumf(left, right, bottom, top, zNear, zFar); 8 | } 9 | -------------------------------------------------------------------------------- /glFrustumf.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | 5 | 6 | void glFrustumf (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far) 7 | { 8 | GLfloat m [16]; 9 | GLfloat _2n = 2.0 * near; 10 | GLfloat _1over_rml = 1.0 / (right - left); 11 | GLfloat _1over_fmn = 1.0 / (far - near); 12 | GLfloat _1over_tmb = 1.0 / (top - bottom); 13 | 14 | m[0] = _2n * _1over_rml; 15 | m[1] = 0.0; 16 | m[2] = 0.0; 17 | m[3] = 0.0; 18 | 19 | m[4] = 0.0; 20 | m[5] = _2n * _1over_tmb; 21 | m[6] = 0.0; 22 | m[7] = 0.0; 23 | 24 | m[8] = (right + left) * _1over_rml; 25 | m[9] = (top + bottom) * _1over_tmb; 26 | m[10] = (-(far + near)) * _1over_fmn; 27 | m[11] = -1.0; 28 | 29 | m[12] = 0.0; 30 | m[13] = 0.0; 31 | m[14] = -(_2n * far * _1over_fmn); 32 | m[15] = 0.0; 33 | 34 | glMultMatrixf(m); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /glGenBuffersARB.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | void glGenBuffersARB (GLsizei n, GLuint *buffers) 5 | { 6 | struct hashtable *hash = &pspgl_curctx->shared->buffers; 7 | int i; 8 | 9 | if (unlikely(n < 0)) 10 | goto out_error; 11 | 12 | if (unlikely(!buffers)) 13 | return; 14 | 15 | for(i = 0; i < n; i++) { 16 | unsigned id; 17 | struct pspgl_bufferobj *bufp; 18 | 19 | id = __pspgl_hash_uniquekey(hash); 20 | 21 | bufp = __pspgl_bufferobj_new(NULL); 22 | __pspgl_hash_insert(hash, id, bufp); 23 | 24 | buffers[i] = id; 25 | } 26 | return; 27 | 28 | out_error: 29 | GLERROR(GL_INVALID_VALUE); 30 | } 31 | 32 | void glGenBuffers (GLsizei count, GLuint *buffers) 33 | __attribute__((alias("glGenBuffersARB"))); 34 | -------------------------------------------------------------------------------- /glGenLists.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | GLuint glGenLists(GLsizei range) 5 | { 6 | struct hashtable *hash = &pspgl_curctx->shared->display_lists; 7 | GLuint id, start, i; 8 | 9 | if (range < 0) 10 | GLERROR(GL_INVALID_VALUE); 11 | 12 | if (range <= 0) 13 | return 0; 14 | 15 | start = id = __pspgl_hash_uniquekey(hash); 16 | 17 | again: 18 | for(i = 0; i < range; i++) { 19 | if (id < start && id+range >= start) { 20 | /* no space in the ID range */ 21 | id = 0; 22 | break; 23 | } 24 | 25 | if (__pspgl_hash_lookup(hash, id+i) != NULL) { 26 | id = id+i+1; 27 | goto again; 28 | } 29 | } 30 | 31 | for(i = 0; i < range; i++) 32 | __pspgl_hash_insert(hash, id+i, "foo"); 33 | 34 | return id; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /glGenTextures.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_texobj.h" 3 | 4 | void glGenTextures (GLsizei n, GLuint *textures) 5 | { 6 | struct hashtable *hash = &pspgl_curctx->shared->texture_objects; 7 | GLsizei i; 8 | GLenum error; 9 | 10 | error = GL_INVALID_VALUE; 11 | if (unlikely(n < 0)) 12 | goto out_error; 13 | 14 | for(i = 0; i < n; i++) { 15 | unsigned id; 16 | struct pspgl_texobj *tobj; 17 | 18 | id = __pspgl_hash_uniquekey(hash); 19 | 20 | tobj = __pspgl_texobj_new(id, 0); 21 | error = GL_OUT_OF_MEMORY; 22 | if (tobj == NULL) 23 | goto out_error; 24 | 25 | __pspgl_hash_insert(hash, id, tobj); 26 | 27 | textures[i] = id; 28 | } 29 | return; 30 | 31 | out_error: 32 | GLERROR(error); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /glGetBufferSubDataARB.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | #include "pspgl_buffers.h" 5 | 6 | void glGetBufferSubDataARB(GLenum target, GLintptrARB offset, 7 | GLsizeiptrARB size, GLvoid *data) 8 | { 9 | struct pspgl_bufferobj *buf, **bufp; 10 | void *p; 11 | GLenum error; 12 | 13 | bufp = __pspgl_bufferobj_for_target(target); 14 | 15 | if (bufp == NULL) 16 | return; 17 | 18 | buf = *bufp; 19 | 20 | error = GL_INVALID_OPERATION; 21 | if (buf == NULL || buf->data == NULL || buf->mapped) 22 | goto out_error; 23 | 24 | error = GL_INVALID_VALUE; 25 | if (size < 0 || offset+size > buf->data->size) 26 | goto out_error; 27 | 28 | p = __pspgl_buffer_map(buf->data, GL_READ_ONLY); 29 | 30 | memcpy(data, p+offset, size); 31 | 32 | __pspgl_buffer_unmap(buf->data, GL_READ_ONLY); 33 | return; 34 | 35 | out_error: 36 | GLERROR(error); 37 | } 38 | 39 | void glGetBufferSubData(GLenum target, GLintptrARB offset, 40 | GLsizeiptrARB size, GLvoid *data) 41 | __attribute__((alias("glGetBufferSubDataARB"))); 42 | -------------------------------------------------------------------------------- /glGetError.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | GLenum glGetError (void) 5 | { 6 | GLenum err = pspgl_curctx->glerror; 7 | pspgl_curctx->glerror = GL_NO_ERROR; 8 | return err; 9 | } 10 | -------------------------------------------------------------------------------- /glGetFloatv.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_matrix.h" 3 | 4 | void glGetFloatv (GLenum pname, GLfloat *params) 5 | { 6 | struct pspgl_matrix_stack *s; 7 | 8 | switch (pname) { 9 | case GL_LINE_WIDTH: 10 | params[0] = 1.0f; 11 | break; 12 | case GL_ALIASED_POINT_SIZE_RANGE: 13 | case GL_SMOOTH_POINT_SIZE_RANGE: 14 | case GL_SMOOTH_POINT_SIZE_GRANULARITY: 15 | case GL_ALIASED_LINE_WIDTH_RANGE: 16 | case GL_SMOOTH_LINE_WIDTH_RANGE: 17 | case GL_SMOOTH_LINE_WIDTH_GRANULARITY: 18 | params[0] = 1.0f; 19 | params[1] = 1.0f; 20 | break; 21 | case GL_COLOR_CLEAR_VALUE: 22 | params[0] = ((pspgl_curctx->clear.color >> 0) & 0xff) / 255.f; 23 | params[1] = ((pspgl_curctx->clear.color >> 8) & 0xff) / 255.f; 24 | params[2] = ((pspgl_curctx->clear.color >>16) & 0xff) / 255.f; 25 | params[3] = ((pspgl_curctx->clear.color >>24) & 0xff) / 255.f; 26 | break; 27 | case GL_MODELVIEW_MATRIX: s = &pspgl_curctx->modelview_stack; goto get_matrix; 28 | case GL_TEXTURE_MATRIX: s = &pspgl_curctx->texture_stack; goto get_matrix; 29 | case GL_PROJECTION_MATRIX: s = &pspgl_curctx->projection_stack; goto get_matrix; 30 | case GL_VIEW_PSP: s = &pspgl_curctx->view_stack; goto get_matrix; 31 | case GL_BONE0_PSP ... GL_BONE7_PSP: 32 | s = &pspgl_curctx->bone_stacks[pname - GL_BONE0_PSP]; 33 | /* FALLTHROUGH */ 34 | get_matrix: 35 | if (params) { 36 | const GLfloat *matrix = s->stack[s->depth].mat; 37 | int i; 38 | 39 | __pspgl_matrix_sync(pspgl_curctx, s); 40 | 41 | for (i=0; i<16; i++) 42 | params[i] = matrix[i]; 43 | } 44 | break; 45 | default: 46 | GLERROR(GL_INVALID_ENUM); 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /glGetIntegerv.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | #define GU_PSM_5650 (0) /* Display, Texture, Palette */ 4 | #define GU_PSM_5551 (1) /* Display, Texture, Palette */ 5 | #define GU_PSM_4444 (2) /* Display, Texture, Palette */ 6 | #define GU_PSM_8888 (3) /* Display, Texture, Palette */ 7 | 8 | static const 9 | struct { 10 | unsigned int red_bits : 4; 11 | unsigned int green_bits : 4; 12 | unsigned int blue_bits : 4; 13 | unsigned int alpha_bits : 4; 14 | } colorfmt [] = { 15 | { .red_bits = 5, .green_bits = 6, .blue_bits = 5, .alpha_bits = 0 }, 16 | { .red_bits = 5, .green_bits = 5, .blue_bits = 5, .alpha_bits = 1 }, 17 | { .red_bits = 4, .green_bits = 4, .blue_bits = 4, .alpha_bits = 4 }, 18 | { .red_bits = 8, .green_bits = 8, .blue_bits = 8, .alpha_bits = 8 }, 19 | }; 20 | 21 | 22 | void glGetIntegerv (GLenum pname, GLint *params) 23 | { 24 | struct pspgl_surface *s = pspgl_curctx->draw; 25 | 26 | switch (pname) { 27 | case GL_MAX_TEXTURE_SIZE: 28 | params[0] = 512; 29 | break; 30 | case GL_VIEWPORT: 31 | /* XXX IMPRPOVE: better read from registers / register cache */ 32 | params[0] = pspgl_curctx->viewport.x; 33 | params[1] = pspgl_curctx->viewport.y; 34 | params[2] = pspgl_curctx->viewport.width; 35 | params[3] = pspgl_curctx->viewport.height; 36 | break; 37 | case GL_MAX_VIEWPORT_DIMS: 38 | params[0] = s->width; 39 | params[1] = s->height; 40 | break; 41 | case GL_DEPTH_BITS: 42 | params[0] = (s->depth_buffer == NULL) ? 0 : 16; 43 | break; 44 | case GL_STENCIL_BITS: 45 | params[0] = colorfmt[s->pixfmt].alpha_bits; 46 | break; 47 | case GL_RED_BITS: 48 | params[0] = colorfmt[s->pixfmt].red_bits; 49 | break; 50 | case GL_GREEN_BITS: 51 | params[0] = colorfmt[s->pixfmt].green_bits; 52 | break; 53 | case GL_BLUE_BITS: 54 | params[0] = colorfmt[s->pixfmt].blue_bits; 55 | break; 56 | case GL_ALPHA_BITS: 57 | params[0] = colorfmt[s->pixfmt].alpha_bits; 58 | break; 59 | case GL_MAX_TEXTURE_UNITS_ARB: 60 | params[0] = 1; 61 | break; 62 | case GL_MAX_LIGHTS: 63 | params[0] = 4; 64 | break; 65 | case GL_MAX_CLIP_PLANES: 66 | params[0] = 0; 67 | break; 68 | case GL_STENCIL_WRITEMASK: 69 | params[0] = pspgl_curctx->write_mask.stencil; 70 | break; 71 | case GL_DEPTH_CLEAR_VALUE: 72 | params[0] = pspgl_curctx->clear.depth; 73 | break; 74 | case GL_STENCIL_CLEAR_VALUE: 75 | params[0] = pspgl_curctx->clear.stencil; 76 | break; 77 | case GL_MAX_ATTRIB_STACK_DEPTH: 78 | params[0] = MAX_ATTRIB_STACK; 79 | break; 80 | case GL_ATTRIB_STACK_DEPTH: 81 | params[0] = pspgl_curctx->attribstackdepth; 82 | break; 83 | //@@@ added by Edorul for display lists 84 | case GL_LIST_BASE: 85 | params[0] = pspgl_curctx->displaylists.calllists_base; 86 | break; 87 | case GL_LIST_MODE: 88 | params[0] = pspgl_curctx->displaylists.is_in_glNewList; 89 | break; 90 | case GL_LIST_INDEX: 91 | params[0] = pspgl_curctx->displaylists.index; 92 | break; 93 | //@@@ end of addition 94 | default: 95 | GLERROR(GL_INVALID_ENUM); 96 | } 97 | } 98 | 99 | -------------------------------------------------------------------------------- /glGetString.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | 4 | 5 | static const 6 | char *gl_strings [] = { 7 | /* GL_VENDOR */ 8 | "pspGL", 9 | /* GL_RENDERER */ 10 | "OpenGL ES-CM 1.1", 11 | /* GL_VERSION */ 12 | "1.3 (pspGL build " __DATE__ ", " __TIME__ ")", 13 | /* GL_EXTENSIONS */ 14 | "GL_EXT_texture_env_add " 15 | "GL_ARB_texture_env_add " 16 | "GL_EXT_blend_minmax " 17 | "GL_EXT_blend_subtract " 18 | "GL_EXT_paletted_texture " 19 | "GL_ARB_texture_compression " 20 | "GL_EXT_texture_compression_s3tc " 21 | "GL_EXT_vertex_array " 22 | "GL_EXT_compiled_vertex_array " 23 | "GL_PSP_statistics " 24 | "GL_ARB_vertex_buffer_object " 25 | "GL_PSP_bezier_patch " 26 | "GL_PSP_vertex_blend " 27 | "GL_PSP_view_matrix " 28 | "GL_PSP_sprites " 29 | "GL_MESA_pack_invert " 30 | "GL_ARB_pixel_buffer_object " 31 | "GL_EXT_pixel_buffer_object " 32 | }; 33 | 34 | 35 | const GLubyte * glGetString (GLenum name) 36 | { 37 | unsigned long idx = name - GL_VENDOR; 38 | const char *s; 39 | 40 | s = NULL; 41 | if (idx >= sizeof(gl_strings)/sizeof(gl_strings[0])) 42 | goto out_error; 43 | 44 | s = gl_strings[idx]; 45 | 46 | return (const GLubyte *) s; 47 | 48 | out_error: 49 | GLERROR(GL_INVALID_ENUM); 50 | return NULL; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /glInterleavedArrays.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | static const 5 | struct desc { 6 | unsigned int size_texcoord : 3; 7 | unsigned int size_color : 3; 8 | unsigned int size_normal : 1; 9 | unsigned int size_vertex : 3; 10 | 11 | unsigned int color_is_float : 1; 12 | 13 | unsigned int offset_color : 3; 14 | unsigned int offset_normal: 4; 15 | unsigned int offset_vertex : 4; 16 | } array_desc [] = { 17 | #define VFMT(tcsz, csz, norm, vsz, fpcol) \ 18 | { tcsz, csz, norm, vsz, fpcol, \ 19 | tcsz, \ 20 | tcsz + (csz / (fpcol ? 1 : 4)), \ 21 | tcsz + (csz / (fpcol ? 1 : 4)) + 3*norm } 22 | 23 | /* T C N V fpcol */ 24 | VFMT(0, 0, 0, 2, 0), /* GL_V2F */ 25 | VFMT(0, 0, 0, 3, 0), /* GL_V3F */ 26 | VFMT(0, 4, 0, 2, 0), /* GL_C4UB_V2F */ 27 | VFMT(0, 4, 0, 3, 0), /* GL_C4UB_V3F */ 28 | 29 | VFMT(0, 3, 0, 3, 1), /* GL_C3F_V3F */ 30 | VFMT(0, 0, 1, 3, 0), /* GL_N3F_V3F */ 31 | VFMT(0, 4, 1, 3, 1), /* GL_C4F_N3F_V3F */ 32 | VFMT(2, 0, 0, 3, 0), /* GL_T2F_V3F */ 33 | 34 | VFMT(4, 0, 0, 4, 0), /* GL_T4F_V4F */ 35 | VFMT(2, 4, 0, 3, 0), /* GL_T2F_C4UB_V3F */ 36 | VFMT(2, 3, 0, 3, 1), /* GL_T2F_C3F_V3F */ 37 | VFMT(2, 0, 1, 3, 0), /* GL_T2F_N3F_V3F */ 38 | 39 | VFMT(2, 4, 1, 3, 1), /* GL_T2F_C4F_N3F_V3F */ 40 | VFMT(4, 4, 1, 4, 1), /* GL_T4F_C4F_N3F_V4F */ 41 | #undef VFMT 42 | }; 43 | 44 | 45 | void glInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *p) 46 | { 47 | struct varray *va = &pspgl_curctx->vertex_array; 48 | unsigned long idx = format - GL_V2F; 49 | const struct desc *desc; 50 | 51 | if (idx > sizeof(array_desc)/sizeof(array_desc[0])) 52 | goto out_error; 53 | 54 | desc = &array_desc[idx]; 55 | 56 | va->vertex.enabled = GL_TRUE; 57 | va->texcoord.enabled = desc->size_texcoord != 0; 58 | va->color.enabled = desc->size_color != 0; 59 | va->normal.enabled = desc->size_normal != 0; 60 | 61 | va->vertex.size = desc->size_vertex; 62 | va->texcoord.size = desc->size_texcoord; 63 | va->color.size = desc->size_color; 64 | va->normal.size = 3; 65 | 66 | va->vertex.type = GL_FLOAT; 67 | va->texcoord.type = GL_FLOAT; 68 | va->color.type = desc->color_is_float ? GL_FLOAT : GL_UNSIGNED_BYTE; 69 | va->normal.type = GL_FLOAT; 70 | 71 | if (stride == 0) 72 | stride = 4 * (desc->offset_vertex + desc->size_vertex); 73 | 74 | va->vertex.stride = stride; 75 | va->texcoord.stride = stride; 76 | va->color.stride = stride; 77 | va->normal.stride = stride; 78 | 79 | va->vertex.native = (va->vertex.size == 3); 80 | va->texcoord.native = (va->texcoord.size == 2); 81 | va->color.native = (va->color.type == GL_UNSIGNED_BYTE && va->color.size == 4); 82 | va->normal.native = GL_TRUE; 83 | 84 | va->vertex.ptr = (p + 4 * desc->offset_vertex); 85 | va->normal.ptr = (p + 4 * desc->offset_normal); 86 | va->color.ptr = (p + 4 * desc->offset_color); 87 | va->texcoord.ptr = p; 88 | 89 | __pspgl_varray_bind_buffer(&va->vertex, va->arraybuffer); 90 | __pspgl_varray_bind_buffer(&va->normal, va->arraybuffer); 91 | __pspgl_varray_bind_buffer(&va->color, va->arraybuffer); 92 | __pspgl_varray_bind_buffer(&va->texcoord, va->arraybuffer); 93 | 94 | if (va->locked.cached_array && 95 | va->locked.vfmt.arrays != __pspgl_enabled_array_bits()) { 96 | psp_log("array state changed %x->%x; invalidating cached arrays\n", 97 | va->locked.vfmt.arrays, __pspgl_enabled_array_bits()); 98 | __pspgl_uncache_arrays(); 99 | } 100 | return; 101 | 102 | out_error: 103 | GLERROR(GL_INVALID_ENUM); 104 | } 105 | -------------------------------------------------------------------------------- /glIsBufferARB.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | GLboolean glIsBufferARB(GLuint buffer) 4 | { 5 | struct hashtable *hash = &pspgl_curctx->shared->buffers; 6 | return __pspgl_hash_lookup(hash, buffer) != NULL; 7 | } 8 | 9 | GLboolean glIsBuffer(GLuint buffer) 10 | __attribute__((alias("glIsBufferARB"))); 11 | 12 | -------------------------------------------------------------------------------- /glIsList.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | GLboolean glIsList (GLuint list) 5 | { 6 | struct hashtable *hash = &pspgl_curctx->shared->texture_objects; 7 | return (__pspgl_hash_lookup(hash, list) == NULL) ? GL_FALSE : GL_TRUE; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /glIsTexture.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | GLboolean glIsTexture (GLuint texture) 5 | { 6 | struct hashtable *hash = &pspgl_curctx->shared->texture_objects; 7 | return (texture == 0 || __pspgl_hash_lookup(hash, texture) == NULL) ? GL_FALSE : GL_TRUE; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /glLightModel.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glLightModelfv (GLenum pname, const GLfloat *params) 5 | { 6 | switch (pname) { 7 | case GL_LIGHT_MODEL_AMBIENT: 8 | sendCommandi(CMD_AMBIENT_COLOR, COLOR3(params)); 9 | sendCommandi(CMD_AMBIENT_ALPHA, (int) (255.0 * CLAMPF(params[3]))); 10 | break; 11 | case GL_LIGHT_MODEL_COLOR_CONTROL: 12 | sendCommandi(CMD_LIGHTMODEL, 13 | (params[0] == GL_SEPARATE_SPECULAR_COLOR) ? 1 : 0); 14 | break; 15 | default: 16 | GLERROR(GL_INVALID_ENUM); 17 | return; 18 | } 19 | } 20 | 21 | 22 | void glLightModelf (GLenum pname, GLfloat param) 23 | { 24 | glLightModelfv(pname, ¶m); 25 | } 26 | 27 | void glLightModeli (GLenum pname, GLint param) 28 | { 29 | glLightModelf(pname, param); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /glLineWidth.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glLineWidth (GLfloat width) 5 | { 6 | if (width <= 0.f) 7 | GLERROR(GL_INVALID_VALUE); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /glLoadIdentity.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | 5 | const GLfloat __pspgl_identity[] __attribute__((aligned(VFPU_ALIGNMENT))) = { 6 | 1.0, 0.0, 0.0, 0.0, 7 | 0.0, 1.0, 0.0, 0.0, 8 | 0.0, 0.0, 1.0, 0.0, 9 | 0.0, 0.0, 0.0, 1.0, 10 | }; 11 | 12 | void glLoadIdentity (void) 13 | { 14 | struct pspgl_context *c = pspgl_curctx; 15 | struct pspgl_matrix_stack *stk = c->current_matrix_stack; 16 | struct pspgl_matrix *mat = c->current_matrix; 17 | 18 | if (mat->flags & MF_IDENTITY) 19 | return; 20 | 21 | assert(stk->flags & MF_VFPU); 22 | 23 | pspvfpu_use_matrices(c->vfpu_context, VFPU_STACKTOP, 0); 24 | 25 | mat->flags |= MF_IDENTITY; 26 | if (!(stk->flags & MF_DISABLED)) 27 | stk->flags |= MF_DIRTY; 28 | 29 | asm volatile("vmidt.q m700"); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /glLoadMatrixf.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | #include "pspgl_matrix.h" 5 | 6 | void glLoadMatrixf (const GLfloat *m) 7 | { 8 | struct pspgl_matrix_stack *stk = pspgl_curctx->current_matrix_stack; 9 | struct pspgl_matrix *mat = pspgl_curctx->current_matrix; 10 | 11 | assert(stk->flags & MF_VFPU); 12 | 13 | pspvfpu_use_matrices(pspgl_curctx->vfpu_context, VFPU_STACKTOP, 0); 14 | 15 | asm volatile("ulv.q c700, 0 + %0\n" 16 | "ulv.q c710, 16 + %0\n" 17 | "ulv.q c720, 32 + %0\n" 18 | "ulv.q c730, 48 + %0\n" 19 | : : "m" (*m) : "memory"); 20 | 21 | if (!(stk->flags & MF_DISABLED)) 22 | stk->flags |= MF_DIRTY; 23 | 24 | mat->flags &= ~MF_IDENTITY; 25 | } 26 | -------------------------------------------------------------------------------- /glLogicOp.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glLogicOp (GLenum opcode) 5 | { 6 | if (unlikely(opcode < GL_CLEAR) || unlikely(opcode > GL_SET)) 7 | goto out_error; 8 | 9 | opcode &= 0x000f; 10 | sendCommandi(CMD_LOGICOP, opcode); 11 | return; 12 | 13 | out_error: 14 | GLERROR(GL_INVALID_ENUM); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /glMapBufferARB.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | GLvoid *glMapBufferARB(GLenum target, GLenum access) 5 | { 6 | struct pspgl_bufferobj *buf, **bufp; 7 | void *p; 8 | 9 | bufp = __pspgl_bufferobj_for_target(target); 10 | 11 | if (bufp == NULL) 12 | return NULL; 13 | 14 | buf = *bufp; 15 | 16 | if (unlikely(buf == NULL) || unlikely(buf->data == NULL) || unlikely(buf->mapped)) 17 | goto out_error; 18 | 19 | /* If we're writing the buffer or the hardware is writing to 20 | the buffer, wait for the hardware to finish with it. (The 21 | CPU and graphics hardware are allowed to read 22 | concurrently.) */ 23 | if (access != GL_READ_ONLY_ARB || 24 | (buf->data->flags & BF_PINNED_WR)) 25 | __pspgl_buffer_dlist_sync(buf->data); 26 | 27 | buf->access = access; 28 | buf->mapped = GL_TRUE; 29 | 30 | p = __pspgl_buffer_map(buf->data, access); 31 | 32 | psp_log("mapped buf %p data %p -> %p\n", 33 | buf, buf->data->base, p); 34 | 35 | return p; 36 | 37 | out_error: 38 | GLERROR(GL_INVALID_OPERATION); 39 | return NULL; 40 | } 41 | 42 | GLvoid *glMapBuffer(GLenum target, GLenum access) 43 | __attribute__((alias("glMapBufferARB"))); 44 | -------------------------------------------------------------------------------- /glMaterial.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glMaterialfv (GLenum face, GLenum pname, const GLfloat *params) 5 | { 6 | switch (pname) { 7 | case GL_AMBIENT: 8 | pspgl_curctx->material.ambient = COLOR4(params); 9 | 10 | /* material ambient is overloaded by glColor() */ 11 | if (getReg(CMD_ENA_LIGHTING) & 0xff) { 12 | sendCommandi(CMD_MATERIAL_AMB_C, pspgl_curctx->material.ambient); 13 | sendCommandi(CMD_MATERIAL_AMB_A, pspgl_curctx->material.ambient >> 24); 14 | } 15 | break; 16 | case GL_EMISSION: 17 | sendCommandi(CMD_MATERIAL_EMS_C, COLOR3(params)); 18 | break; 19 | case GL_DIFFUSE: 20 | sendCommandi(CMD_MATERIAL_DIF_C, COLOR3(params)); 21 | break; 22 | case GL_AMBIENT_AND_DIFFUSE: 23 | glMaterialfv(face, GL_AMBIENT, params); 24 | glMaterialfv(face, GL_DIFFUSE, params); 25 | break; 26 | case GL_SPECULAR: 27 | sendCommandi(CMD_MATERIAL_SPC_C, COLOR3(params)); 28 | break; 29 | case GL_SHININESS: 30 | sendCommandf(CMD_MATERIAL_SPEC_POW, params[0]); 31 | break; 32 | default: 33 | GLERROR(GL_INVALID_ENUM); 34 | return; 35 | } 36 | 37 | #if 0 38 | unsigned components; 39 | 40 | /* glColorMaterial? */ 41 | components = 0; 42 | if (pspgl_curctx->material.ambient) 43 | components |= GE_AMBIENT; 44 | if ((getReg(CMD_MATERIAL_SPC_C) & 0xffffff) != 0) 45 | components |= GE_SPECULAR; 46 | if ((getReg(CMD_MATERIAL_DIF_C) & 0xffffff) != 0) 47 | components |= GE_DIFFUSE; 48 | sendCommandi(CMD_MATERIAL, components); 49 | #endif 50 | } 51 | 52 | 53 | void glMaterialf (GLenum face, GLenum pname, GLfloat param) 54 | { 55 | glMaterialfv(face, pname, ¶m); 56 | } 57 | 58 | void glMateriali (GLenum face, GLenum pname, GLint param) 59 | { 60 | glMaterialf(face, pname, param); 61 | } 62 | 63 | -------------------------------------------------------------------------------- /glMatrixMode.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_matrix.h" 3 | 4 | void glMatrixMode (GLenum mode) 5 | { 6 | struct pspgl_matrix_stack *s; 7 | struct pspgl_context *c = pspgl_curctx; 8 | 9 | switch(mode) { 10 | case GL_MODELVIEW: s = &c->modelview_stack; break; 11 | case GL_TEXTURE: s = &c->texture_stack; break; 12 | case GL_PROJECTION: s = &c->projection_stack; break; 13 | case GL_VIEW_PSP: s = &c->view_stack; break; 14 | 15 | case GL_BONE0_PSP ... GL_BONE7_PSP: 16 | s = &c->bone_stacks[mode - GL_BONE0_PSP]; 17 | break; 18 | 19 | default: 20 | goto out_error; 21 | } 22 | 23 | __pspgl_matrix_select(c, s); 24 | return; 25 | 26 | out_error: 27 | GLERROR(GL_INVALID_ENUM); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /glMultMatrixf.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | 5 | 6 | void glMultMatrixf (const GLfloat *m) 7 | { 8 | struct pspgl_context *c = pspgl_curctx; 9 | struct pspgl_matrix_stack *stk = c->current_matrix_stack; 10 | struct pspgl_matrix *mat = c->current_matrix; 11 | 12 | if (!(stk->flags & MF_DISABLED)) 13 | stk->flags |= MF_DIRTY; 14 | 15 | mat->flags &= ~MF_IDENTITY; 16 | 17 | pspvfpu_use_matrices(pspgl_curctx->vfpu_context, VFPU_STACKTOP, VMAT6 | VMAT5); 18 | 19 | assert(stk->flags & MF_VFPU); 20 | 21 | asm volatile("vmmov.q m500, m700\n" 22 | 23 | "ulv.q c600, 0 + %0\n" 24 | "ulv.q c610, 16 + %0\n" 25 | "ulv.q c620, 32 + %0\n" 26 | "ulv.q c630, 48 + %0\n" 27 | 28 | "vmmul.q m700, m500, m600\n" 29 | : : "m" (*m) : "memory"); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /glNormal.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz) 5 | { 6 | pspgl_curctx->current.normal[0] = nx; 7 | pspgl_curctx->current.normal[1] = ny; 8 | pspgl_curctx->current.normal[2] = nz; 9 | } 10 | 11 | 12 | void glNormal3fv (const GLfloat *n) 13 | { 14 | pspgl_curctx->current.normal[0] = n[0]; 15 | pspgl_curctx->current.normal[1] = n[1]; 16 | pspgl_curctx->current.normal[2] = n[2]; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /glNormalPointer.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | void glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer) 5 | { 6 | struct pspgl_vertex_array *va = &pspgl_curctx->vertex_array.normal; 7 | GLenum error; 8 | 9 | error = GL_INVALID_ENUM; 10 | if (unlikely(type != GL_BYTE && type != GL_SHORT && type != GL_FLOAT)) 11 | goto out_error; 12 | 13 | error = GL_INVALID_VALUE; 14 | if (unlikely(stride < 0)) 15 | goto out_error; 16 | 17 | if (stride == 0) 18 | stride = __pspgl_gl_sizeof(type) * 3; 19 | 20 | psp_log("ptr=%p(%p) type=%x stride=%d\n", 21 | pointer, __pspgl_bufferobj_deref(pspgl_curctx->vertex_array.arraybuffer, 22 | (void *)pointer), 23 | type, stride); 24 | 25 | va->size = 3; 26 | va->type = type; 27 | va->stride = stride; 28 | va->ptr = pointer; 29 | va->native = GL_TRUE; 30 | 31 | __pspgl_varray_bind_buffer(va, pspgl_curctx->vertex_array.arraybuffer); 32 | return; 33 | 34 | out_error: 35 | GLERROR(error); 36 | return; 37 | } 38 | -------------------------------------------------------------------------------- /glNormald.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz) 4 | { 5 | glNormal3f(nx, ny, nz); 6 | } 7 | 8 | void glNormal3dv(const GLdouble *p) 9 | { 10 | glNormal3f(p[0], p[1], p[2]); 11 | } 12 | -------------------------------------------------------------------------------- /glOrtho.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | extern void glOrthof (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far); 5 | 6 | 7 | void glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) 8 | { 9 | glOrthof(left, right, bottom, top, zNear, zFar); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /glOrthof.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | 4 | void glOrthof (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far) 5 | { 6 | GLfloat m [16]; 7 | GLfloat rml = right - left; 8 | GLfloat fmn = far - near; 9 | GLfloat tmb = top - bottom; 10 | GLfloat _1over_rml; 11 | GLfloat _1over_fmn; 12 | GLfloat _1over_tmb; 13 | 14 | if (rml == 0.0 || fmn == 0.0 || tmb == 0.0) { 15 | GLERROR(GL_INVALID_VALUE); 16 | return; 17 | } 18 | 19 | _1over_rml = 1.0 / rml; 20 | _1over_fmn = 1.0 / fmn; 21 | _1over_tmb = 1.0 / tmb; 22 | 23 | m[0] = 2.0 * _1over_rml; 24 | m[1] = 0.0; 25 | m[2] = 0.0; 26 | m[3] = 0.0; 27 | 28 | m[4] = 0.0; 29 | m[5] = 2.0 * _1over_tmb; 30 | m[6] = 0.0; 31 | m[7] = 0.0; 32 | 33 | m[8] = 0.0; 34 | m[9] = 0.0; 35 | m[10] = -2.0 * _1over_fmn; 36 | m[11] = 0.0; 37 | 38 | m[12] = -(right + left) * _1over_rml; 39 | m[13] = -(top + bottom) * _1over_tmb; 40 | m[14] = -(far + near) * _1over_fmn; 41 | m[15] = 1.0; 42 | 43 | glMultMatrixf(m); 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /glPixelStore.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void glPixelStorei( GLenum pname, GLint param ) 4 | { 5 | struct pspgl_context *c = pspgl_curctx; 6 | GLenum error; 7 | 8 | error = GL_INVALID_VALUE; 9 | if (param < 0) 10 | goto out_error; 11 | 12 | error = GL_INVALID_ENUM; 13 | switch(pname) { 14 | case GL_PACK_ROW_LENGTH: 15 | c->pack.row_length = param; 16 | break; 17 | case GL_PACK_ALIGNMENT: 18 | error = GL_INVALID_VALUE; 19 | if (!ispow2(param) || param < 1 || param > 8) 20 | goto out_error; 21 | c->pack.alignment = param; 22 | break; 23 | case GL_PACK_SKIP_PIXELS: 24 | c->pack.skip_pixels = param; 25 | break; 26 | case GL_PACK_SKIP_ROWS: 27 | c->pack.skip_rows = param; 28 | break; 29 | case GL_PACK_INVERT_MESA: 30 | c->pack.invert = param; 31 | break; 32 | 33 | case GL_UNPACK_ROW_LENGTH: 34 | c->unpack.row_length = param; 35 | break; 36 | case GL_UNPACK_ALIGNMENT: 37 | error = GL_INVALID_VALUE; 38 | if (!ispow2(param) || param < 1 || param > 8) 39 | goto out_error; 40 | c->unpack.alignment = param; 41 | break; 42 | case GL_UNPACK_SKIP_PIXELS: 43 | c->unpack.skip_pixels = param; 44 | break; 45 | case GL_UNPACK_SKIP_ROWS: 46 | c->unpack.skip_rows = param; 47 | break; 48 | 49 | default: 50 | goto out_error; 51 | } 52 | 53 | return; 54 | 55 | out_error: 56 | GLERROR(error); 57 | } 58 | 59 | void glPixelStoref( GLenum pname, GLfloat param ) 60 | { 61 | glPixelStorei(pname, param); 62 | } 63 | -------------------------------------------------------------------------------- /glPolygonMode.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glPolygonMode (GLenum face, GLenum mode) 5 | { 6 | if (mode != GL_FILL) 7 | GLERROR(GL_INVALID_ENUM); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /glPolygonOffset.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void glPolygonOffset (GLfloat factor, GLfloat units) 4 | { 5 | /* XXX: not correct, but may work well in most cases. */ 6 | pspgl_curctx->viewport.depth_offset = units; 7 | } 8 | -------------------------------------------------------------------------------- /glPopMatrix.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | #include "pspgl_matrix.h" 5 | 6 | void glPopMatrix (void) 7 | { 8 | struct pspgl_context *c = pspgl_curctx; 9 | struct pspgl_matrix_stack *curstk = c->current_matrix_stack; 10 | 11 | assert(curstk->flags & MF_VFPU); 12 | 13 | if (unlikely(curstk->depth == 0)) 14 | goto out_error; 15 | 16 | c->current_matrix = &curstk->stack[--curstk->depth]; 17 | if (!(curstk->flags & MF_DISABLED)) 18 | curstk->flags |= MF_DIRTY; 19 | 20 | /* Reload VFPU with new top-of-stack */ 21 | __pspgl_matrix_load(c, curstk); 22 | return; 23 | 24 | out_error: 25 | GLERROR(GL_STACK_UNDERFLOW); 26 | } 27 | -------------------------------------------------------------------------------- /glPrioritizeTextures.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_texobj.h" 3 | 4 | void glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities) 5 | { 6 | struct hashtable *hash = &pspgl_curctx->shared->texture_objects; 7 | struct pspgl_texobj *texobj; 8 | GLsizei i; 9 | 10 | if (unlikely(n < 0)) { 11 | GLERROR(GL_INVALID_VALUE); 12 | return; 13 | } 14 | 15 | for (i=0; ipriority = priorities[i]; 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /glPushClientAttrib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "pspgl_internal.h" 5 | #include "pspgl_buffers.h" 6 | 7 | struct pspgl_saved_clattrib { 8 | GLbitfield attrmask; 9 | 10 | struct varray varray; 11 | struct pixelstore pack, unpack; 12 | }; 13 | 14 | void glPushClientAttrib(GLbitfield mask) 15 | { 16 | struct pspgl_context *c = pspgl_curctx; 17 | struct pspgl_saved_clattrib *a; 18 | GLenum error; 19 | 20 | error = GL_STACK_OVERFLOW; 21 | if (unlikely(c->attribstackdepth >= MAX_ATTRIB_STACK)) 22 | goto out_error; 23 | 24 | a = malloc(sizeof(*a)); 25 | 26 | error = GL_OUT_OF_MEMORY; 27 | if (a == NULL) 28 | goto out_error; 29 | 30 | memset(a, 0, sizeof(*a)); 31 | 32 | a->attrmask = mask; 33 | 34 | if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { 35 | a->varray = c->vertex_array; 36 | 37 | if (a->varray.vertex.buffer) 38 | a->varray.vertex.buffer->refcount++; 39 | 40 | if (a->varray.normal.buffer) 41 | a->varray.normal.buffer->refcount++; 42 | 43 | if (a->varray.color.buffer) 44 | a->varray.color.buffer->refcount++; 45 | 46 | if (a->varray.texcoord.buffer) 47 | a->varray.texcoord.buffer->refcount++; 48 | 49 | if (a->varray.weight.buffer) 50 | a->varray.weight.buffer->refcount++; 51 | 52 | if (a->varray.arraybuffer) 53 | a->varray.arraybuffer->refcount++; 54 | if (a->varray.indexbuffer) 55 | a->varray.indexbuffer->refcount++; 56 | 57 | if (a->varray.locked.cached_array) 58 | a->varray.locked.cached_array->refcount++; 59 | } 60 | 61 | if (mask & GL_CLIENT_PIXEL_STORE_BIT) { 62 | a->pack = c->pack; 63 | a->unpack = c->unpack; 64 | 65 | if (a->pack.pbo) 66 | a->pack.pbo->refcount++; 67 | if (a->unpack.pbo) 68 | a->unpack.pbo->refcount++; 69 | } 70 | 71 | c->clattribstack[c->clattribstackdepth++] = a; 72 | return; 73 | 74 | out_error: 75 | GLERROR(error); 76 | } 77 | 78 | void glPopClientAttrib(void) 79 | { 80 | struct pspgl_context *c = pspgl_curctx; 81 | struct pspgl_saved_clattrib *a; 82 | unsigned mask; 83 | 84 | if (c->clattribstackdepth == 0) 85 | goto out_error; 86 | 87 | a = c->clattribstack[--c->clattribstackdepth]; 88 | 89 | mask = a->attrmask; 90 | 91 | if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { 92 | struct varray *va = &c->vertex_array; 93 | 94 | if (va->vertex.buffer) 95 | __pspgl_bufferobj_free(va->vertex.buffer); 96 | 97 | if (va->normal.buffer) 98 | __pspgl_bufferobj_free(va->normal.buffer); 99 | 100 | if (va->color.buffer) 101 | __pspgl_bufferobj_free(va->color.buffer); 102 | 103 | if (va->texcoord.buffer) 104 | __pspgl_bufferobj_free(va->texcoord.buffer); 105 | 106 | if (va->weight.buffer) 107 | __pspgl_bufferobj_free(va->weight.buffer); 108 | 109 | if (va->arraybuffer) 110 | __pspgl_bufferobj_free(va->arraybuffer); 111 | if (va->indexbuffer) 112 | __pspgl_bufferobj_free(va->indexbuffer); 113 | 114 | if (va->locked.cached_array) 115 | __pspgl_buffer_free(va->locked.cached_array); 116 | 117 | *va = a->varray; 118 | } 119 | 120 | if (mask & GL_CLIENT_PIXEL_STORE_BIT) { 121 | if (c->pack.pbo) 122 | __pspgl_bufferobj_free(c->pack.pbo); 123 | c->pack = a->pack; 124 | 125 | if (c->unpack.pbo) 126 | __pspgl_bufferobj_free(c->unpack.pbo); 127 | c->unpack = a->unpack; 128 | } 129 | 130 | free(a); 131 | return; 132 | 133 | out_error: 134 | GLERROR(GL_STACK_UNDERFLOW); 135 | } 136 | -------------------------------------------------------------------------------- /glPushMatrix.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "pspgl_internal.h" 5 | #include "pspgl_matrix.h" 6 | 7 | void glPushMatrix (void) 8 | { 9 | struct pspgl_context *c = pspgl_curctx; 10 | struct pspgl_matrix_stack *curstk = c->current_matrix_stack; 11 | unsigned flags; 12 | 13 | assert(curstk->flags & MF_VFPU); 14 | 15 | /* Make sure VFPU state is written back to memory */ 16 | __pspgl_matrix_sync(c, curstk); 17 | 18 | if (unlikely(++curstk->depth == curstk->limit)) 19 | goto out_error; 20 | 21 | /* No need to copy matrix values, since it's already in the 22 | VFPU. Do need to copy the flags though. */ 23 | 24 | flags = c->current_matrix->flags; 25 | c->current_matrix = &curstk->stack[curstk->depth]; 26 | c->current_matrix->flags = flags; 27 | return; 28 | 29 | out_error: 30 | curstk->depth--; 31 | GLERROR(GL_STACK_OVERFLOW); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /glReadBuffer.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glReadBuffer(GLenum mode) 5 | { 6 | struct pspgl_surface *s = pspgl_curctx->read; 7 | 8 | switch (mode) { 9 | case GL_BACK: 10 | s->read = &s->color_back; 11 | break; 12 | case GL_FRONT: 13 | s->read = &s->color_front; 14 | break; 15 | default: 16 | /* XXX IMPROVE: support front & aux buffers */ 17 | GLERROR(GL_INVALID_ENUM); 18 | } 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /glScaled.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glScaled (GLdouble x, GLdouble y, GLdouble z) 5 | { 6 | glScalef(x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /glScalef.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | 5 | 6 | void glScalef (GLfloat x, GLfloat y, GLfloat z) 7 | { 8 | struct pspgl_context *c = pspgl_curctx; 9 | struct pspgl_matrix_stack *stk = c->current_matrix_stack; 10 | struct pspgl_matrix *mat = c->current_matrix; 11 | 12 | if (!(stk->flags & MF_DISABLED)) 13 | stk->flags |= MF_DIRTY; 14 | 15 | mat->flags &= ~MF_IDENTITY; 16 | 17 | pspvfpu_use_matrices(pspgl_curctx->vfpu_context, VFPU_STACKTOP, VMAT6); 18 | 19 | assert(stk->flags & MF_VFPU); 20 | 21 | asm volatile("mtv %0, s600\n" 22 | "mtv %1, s610\n" 23 | "mtv %2, s620\n" 24 | "vscl.q c700, c700, s600\n" 25 | "vscl.q c710, c710, s610\n" 26 | "vscl.q c720, c720, s620\n" 27 | : : "r" (x), "r" (y), "r" (z)); 28 | } 29 | -------------------------------------------------------------------------------- /glScissor.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void __pspgl_set_scissor(void) 4 | { 5 | int t,b,l,r; 6 | struct pspgl_context *c = pspgl_curctx; 7 | 8 | if (c->scissor_test.enabled) { 9 | b = c->draw->height - c->scissor_test.y; 10 | t = b - c->scissor_test.height; 11 | l = c->scissor_test.x; 12 | r = l + c->scissor_test.width; 13 | } else { 14 | b = c->draw->height; 15 | t = 0; 16 | l = 0; 17 | r = c->draw->width; 18 | } 19 | 20 | sendCommandi(CMD_SCISSOR1, (t << 10) | l); 21 | sendCommandi(CMD_SCISSOR2, ((b - 1) << 10) | (r - 1)); 22 | } 23 | 24 | void glScissor (GLint x, GLint y, GLsizei width, GLsizei height) 25 | { 26 | pspgl_curctx->scissor_test.x = x; 27 | pspgl_curctx->scissor_test.y = y; 28 | pspgl_curctx->scissor_test.width = width; 29 | pspgl_curctx->scissor_test.height = height; 30 | 31 | __pspgl_set_scissor(); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /glShadeModel.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glShadeModel (GLenum mode) 5 | { 6 | switch (mode) { 7 | case GL_FLAT: 8 | case GL_SMOOTH: 9 | sendCommandi(CMD_SHADEMODEL, (mode & 1)); 10 | break; 11 | default: 12 | GLERROR(GL_INVALID_ENUM); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /glStencilFunc.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | static const char stenciltestfunc_mapping [] = { 0, 4, 2, 5, 6, 3, 7, 1 }; 5 | 6 | void glStencilFunc( GLenum func, GLint ref, GLuint mask) 7 | { 8 | unsigned char sref = (unsigned char) ref; 9 | 10 | if (unlikely(func < GL_NEVER) || unlikely(func > GL_ALWAYS)) 11 | goto out_error; 12 | 13 | func &= 0x0007; 14 | 15 | sendCommandi(CMD_STENCIL_FUNC, (mask << 16) | (sref << 8) | stenciltestfunc_mapping[func]); 16 | return; 17 | 18 | out_error: 19 | GLERROR(GL_INVALID_ENUM); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /glStencilMask.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glStencilMask (GLuint mask) 5 | { 6 | pspgl_curctx->write_mask.stencil = mask & pspgl_curctx->draw->stencil_mask; 7 | 8 | /** 9 | * Alpha Channel and Stencil are shared. Only update mask register 10 | * if stencil test is enabled. 11 | */ 12 | if (pspgl_curctx->hw.ge_reg[CMD_ENA_STENCIL_TEST] & 1) 13 | sendCommandi(CMD_ALPHA_MASK, pspgl_curctx->write_mask.stencil); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /glStencilOp.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | static 5 | int map_sfunc (GLenum opcode) 6 | { 7 | int ret; 8 | 9 | switch (opcode) { 10 | case GL_ZERO: 11 | ret = GU_ZERO; 12 | break; 13 | case GL_INVERT: 14 | ret = GU_INVERT; 15 | break; 16 | case GL_KEEP: 17 | ret = GU_KEEP; 18 | break; 19 | case GL_REPLACE: 20 | ret = GU_REPLACE; 21 | break; 22 | case GL_INCR: 23 | ret = GU_INCR; 24 | break; 25 | case GL_DECR: 26 | ret = GU_DECR; 27 | break; 28 | default: 29 | GLERROR(GL_INVALID_ENUM); 30 | ret = 0; 31 | } 32 | 33 | return ret; 34 | } 35 | 36 | void glStencilOp (GLenum fail, GLenum zfail, GLenum zpass) 37 | { 38 | sendCommandi(CMD_STENCIL_OP, (map_sfunc(zpass) << 16) | (map_sfunc(zfail) << 8) | map_sfunc(fail)); 39 | } 40 | -------------------------------------------------------------------------------- /glTexCoord.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | // @@@ modified by Edorul 4 | void glTexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q ) 5 | { 6 | // @@@ from here it's allways the same code exept for params of the command 7 | if (pspgl_curctx->displaylists.is_in_glNewList & GL_COMPILE) { // we must record this command 8 | struct stDisplayElement *new; 9 | new = (struct stDisplayElement *) malloc (sizeof(struct stDisplayElement)); 10 | // @@@ put new element at the end of list 11 | if (!__pspgl_actuallist->first) 12 | __pspgl_actuallist->first = new; 13 | if (__pspgl_actuallist->last) 14 | __pspgl_actuallist->last->next = new; 15 | new->next = NULL; 16 | __pspgl_actuallist->last = new; 17 | 18 | // params of the command 19 | new->command_num = GLTEXCOORD; // to modify 20 | new->parami1 = 0; // to modify 21 | new->parami2 = 0; // to modify 22 | new->paramf1 = s; // to modify 23 | new->paramf2 = t; // to modify 24 | new->paramf3 = r; // to modify 25 | new->paramf4 = q; // to modify 26 | } 27 | 28 | if ((pspgl_curctx->displaylists.is_in_glNewList == GL_COMPILE_AND_EXECUTE)||(pspgl_curctx->displaylists.is_in_glNewList == 0)) { 29 | // @@@ from here it's different, because it's the old function 30 | pspgl_curctx->current.texcoord[0] = s; 31 | pspgl_curctx->current.texcoord[1] = t; 32 | pspgl_curctx->current.texcoord[2] = r; 33 | pspgl_curctx->current.texcoord[3] = q; 34 | } 35 | } 36 | 37 | void glTexCoord1f (GLfloat s) 38 | { 39 | glTexCoord4f(s, 0.0f, 0.0f, 1.0f); 40 | } 41 | 42 | void glTexCoord1fv(const GLfloat *v) 43 | { 44 | glTexCoord4f(v[0], 0.0f, 0.0f, 1.0f); 45 | } 46 | 47 | void glTexCoord2f (GLfloat s, GLfloat t) 48 | { 49 | glTexCoord4f(s, t, 0.0f, 1.0f); 50 | } 51 | 52 | void glTexCoord2fv(const GLfloat *v) 53 | { 54 | glTexCoord4f(v[0], v[1], 0.0f, 1.0f); 55 | } 56 | 57 | void glTexCoord3f (GLfloat s, GLfloat t, GLfloat r) 58 | { 59 | glTexCoord4f(s, t, r, 1.0f); 60 | } 61 | 62 | void glTexCoord3fv(const GLfloat *v) 63 | { 64 | glTexCoord4f(v[0], v[1], v[2], 1.0f); 65 | } 66 | 67 | void glTexCoord4fv(const GLfloat *v) 68 | { 69 | glTexCoord4f(v[0], v[1], v[2], v[3]); 70 | } 71 | 72 | void glTexCoord1d (GLdouble s) 73 | { 74 | glTexCoord4f((GLfloat)s, 0.0f, 0.0f, 1.0f); 75 | } 76 | 77 | void glTexCoord1dv(const GLdouble *v) 78 | { 79 | glTexCoord4f((GLfloat)v[0], 0.0f, 0.0f, 1.0f); 80 | } 81 | 82 | void glTexCoord2d (GLdouble s, GLdouble t) 83 | { 84 | glTexCoord4f((GLfloat)s, (GLfloat)t, 0.0f, 1.0f); 85 | } 86 | 87 | void glTexCoord2dv(const GLdouble *v) 88 | { 89 | glTexCoord4f((GLfloat)v[0], (GLfloat)v[1], 0.0f, 1.0f); 90 | } 91 | 92 | void glTexCoord3d (GLdouble s, GLdouble t, GLdouble r) 93 | { 94 | glTexCoord4f((GLfloat)s, (GLfloat)t, (GLfloat)r, 1.0f); 95 | } 96 | 97 | void glTexCoord3dv(const GLdouble *v) 98 | { 99 | glTexCoord4f((GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], 1.0f); 100 | } 101 | 102 | void glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q) 103 | { 104 | glTexCoord4f((GLfloat)s, (GLfloat)t, (GLfloat)r, (GLfloat)q); 105 | } 106 | 107 | void glTexCoord4dv(const GLdouble *v) 108 | { 109 | glTexCoord4f((GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]); 110 | } 111 | 112 | // @@@ end of modifs 113 | -------------------------------------------------------------------------------- /glTexCoordPointer.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | void glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) 5 | { 6 | struct pspgl_vertex_array *va = &pspgl_curctx->vertex_array.texcoord; 7 | GLboolean native; 8 | GLenum error; 9 | 10 | error = GL_INVALID_VALUE; 11 | 12 | if (unlikely(size < 2 || size > 4)) 13 | goto out_error; 14 | 15 | if (unlikely(stride < 0)) 16 | goto out_error; 17 | 18 | error = GL_INVALID_ENUM; 19 | if (unlikely(type != GL_BYTE && type != GL_SHORT && type != GL_FLOAT)) 20 | goto out_error; 21 | 22 | if (stride == 0) 23 | stride = __pspgl_gl_sizeof(type) * size; 24 | 25 | native = (size == 2); 26 | 27 | psp_log("ptr=%p(%p) size=%d type=%x stride=%d native=%d\n", 28 | pointer, __pspgl_bufferobj_deref(pspgl_curctx->vertex_array.arraybuffer, (void *)pointer), 29 | size, type, stride, native); 30 | 31 | /* If we're changed vertex formats, then mark the texture 32 | matrix as dirty, so that any adjustment for this format can 33 | be applied. */ 34 | if (va->type != type) 35 | pspgl_curctx->texture_stack.flags |= MF_DIRTY; 36 | 37 | va->size = size; 38 | va->type = type; 39 | va->stride = stride; 40 | va->ptr = pointer; 41 | va->native = native; 42 | 43 | __pspgl_varray_bind_buffer(va, pspgl_curctx->vertex_array.arraybuffer); 44 | 45 | return; 46 | 47 | out_error: 48 | GLERROR(error); 49 | } 50 | -------------------------------------------------------------------------------- /glTexEnv.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | #define GE_TEXENV_MODULATE 0 5 | #define GE_TEXENV_DECAL 1 6 | #define GE_TEXENV_BLEND 2 7 | #define GE_TEXENV_REPLACE 3 8 | #define GE_TEXENV_ADD 4 9 | 10 | 11 | void glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params) 12 | { 13 | int mode; 14 | 15 | if (target != GL_TEXTURE_ENV) 16 | goto out_error; 17 | 18 | switch (pname) { 19 | case GL_TEXTURE_ENV_MODE: 20 | switch ((GLenum) params[0]) { 21 | case GL_MODULATE: 22 | mode = GE_TEXENV_MODULATE; 23 | break; 24 | case GL_DECAL: 25 | mode = GE_TEXENV_DECAL; 26 | break; 27 | case GL_BLEND: 28 | mode = GE_TEXENV_BLEND; 29 | break; 30 | case GL_REPLACE: 31 | mode = GE_TEXENV_REPLACE; 32 | break; 33 | case GL_ADD: 34 | mode = GE_TEXENV_ADD; 35 | break; 36 | default: 37 | goto out_error; 38 | } 39 | __pspgl_context_writereg_masked(pspgl_curctx, CMD_TEXENV_FUNC, mode, 0x0000ff); 40 | break; 41 | 42 | case GL_TEXTURE_ENV_COLOR: 43 | __pspgl_context_writereg(pspgl_curctx, CMD_TEXENV_COL, COLOR3(params)); 44 | break; 45 | 46 | default: 47 | goto out_error; 48 | } 49 | 50 | return; 51 | 52 | out_error: 53 | GLERROR(GL_INVALID_ENUM); 54 | } 55 | 56 | 57 | void glTexEnvf (GLenum target, GLenum pname, GLfloat param) 58 | { 59 | glTexEnvfv(target, pname, ¶m); 60 | } 61 | 62 | 63 | void glTexEnvi (GLenum target, GLenum pname, GLint param) 64 | { 65 | GLfloat p = param; 66 | glTexEnvfv(target, pname, &p); 67 | } 68 | 69 | -------------------------------------------------------------------------------- /glTexGen.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void glTexGenf( GLenum coord, GLenum pname, GLfloat param ) 4 | { 5 | } 6 | 7 | void glTexGeni( GLenum coord, GLenum pname, GLint param ) 8 | { 9 | } 10 | 11 | void glTexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) 12 | { 13 | } 14 | 15 | void glTexGeniv( GLenum coord, GLenum pname, const GLint *params ) 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /glTexParameter.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_texobj.h" 3 | 4 | static 5 | int filter_gl2ge (GLenum f) 6 | { 7 | if (f >= GL_NEAREST_MIPMAP_NEAREST) 8 | f += -GL_NEAREST_MIPMAP_NEAREST + GE_TEX_FILTER_NEAREST_MIPMAP_NEAREST; 9 | return (f & 0x7); 10 | } 11 | 12 | 13 | static 14 | void update_clamp (struct pspgl_context *c, int shift, GLenum param) 15 | { 16 | unsigned clamp; 17 | 18 | switch (param) { 19 | case GL_REPEAT: 20 | clamp = GE_TEX_WRAP_REPEAT; 21 | break; 22 | 23 | case GL_CLAMP_TO_EDGE: 24 | case GL_CLAMP: /* no borders, so not really but close enough */ 25 | clamp = GE_TEX_WRAP_CLAMP; 26 | break; 27 | 28 | default: 29 | GLERROR(GL_INVALID_ENUM); 30 | return; 31 | } 32 | 33 | __pspgl_context_writereg_masked(c, CMD_TEXWRAP, clamp << shift, 0xff << shift); 34 | } 35 | 36 | 37 | static 38 | void update_texfilter (struct pspgl_context *c, int shift, GLenum param) 39 | { 40 | switch (param) { 41 | case GL_NEAREST: 42 | case GL_LINEAR: 43 | case GL_NEAREST_MIPMAP_NEAREST: 44 | case GL_LINEAR_MIPMAP_NEAREST: 45 | case GL_NEAREST_MIPMAP_LINEAR: 46 | case GL_LINEAR_MIPMAP_LINEAR: 47 | __pspgl_context_writereg_masked(c, CMD_TEXFILT, filter_gl2ge(param) << shift, 0xff << shift); 48 | break; 49 | default: 50 | GLERROR(GL_INVALID_ENUM); 51 | } 52 | } 53 | 54 | 55 | void glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params) 56 | { 57 | if (target != GL_TEXTURE_2D) 58 | goto invalid_enum; 59 | 60 | if (!pspgl_curctx->texture.bound) 61 | glBindTexture(target, 0); 62 | 63 | switch (pname) { 64 | case GL_TEXTURE_WRAP_S: 65 | case GL_TEXTURE_WRAP_T: 66 | update_clamp(pspgl_curctx, (pname == GL_TEXTURE_WRAP_S) ? 0 : 8, params[0]); 67 | break; 68 | case GL_TEXTURE_MAG_FILTER: 69 | case GL_TEXTURE_MIN_FILTER: 70 | update_texfilter(pspgl_curctx, (pname == GL_TEXTURE_MIN_FILTER) ? 0 : 8, params[0]); 71 | break; 72 | case GL_GENERATE_MIPMAP: 73 | if (*params) 74 | pspgl_curctx->texture.bound->flags |= TOF_GENERATE_MIPMAPS; 75 | else 76 | pspgl_curctx->texture.bound->flags &= ~TOF_GENERATE_MIPMAPS; 77 | break; 78 | case GL_GENERATE_MIPMAP_DEBUG_PSP: 79 | if (*params) 80 | pspgl_curctx->texture.bound->flags |= TOF_GENERATE_MIPMAP_DEBUG; 81 | else 82 | pspgl_curctx->texture.bound->flags &= ~TOF_GENERATE_MIPMAP_DEBUG; 83 | break; 84 | 85 | default: 86 | goto invalid_enum; 87 | } 88 | 89 | return; 90 | 91 | invalid_enum: 92 | GLERROR(GL_INVALID_ENUM); 93 | } 94 | 95 | 96 | void glTexParameterf (GLenum target, GLenum pname, GLfloat param) 97 | { 98 | glTexParameterfv(target, pname, ¶m); 99 | } 100 | 101 | 102 | void glTexParameteri (GLenum target, GLenum pname, GLint param) 103 | { 104 | GLfloat p = param; 105 | glTexParameterfv(target, pname, &p); 106 | } 107 | 108 | -------------------------------------------------------------------------------- /glTranslatef.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | 5 | 6 | void glTranslatef (GLfloat x, GLfloat y, GLfloat z) 7 | { 8 | struct pspgl_context *c = pspgl_curctx; 9 | struct pspgl_matrix_stack *stk = c->current_matrix_stack; 10 | struct pspgl_matrix *mat = c->current_matrix; 11 | 12 | // @@@ from here it's allways the same code exept for params of the command 13 | if (pspgl_curctx->displaylists.is_in_glNewList & GL_COMPILE) { // we must record this command 14 | struct stDisplayElement *new; 15 | new = (struct stDisplayElement *) malloc (sizeof(struct stDisplayElement)); 16 | // @@@ put new element at the end of list 17 | if (!__pspgl_actuallist->first) 18 | __pspgl_actuallist->first = new; 19 | if (__pspgl_actuallist->last) 20 | __pspgl_actuallist->last->next = new; 21 | new->next = NULL; 22 | __pspgl_actuallist->last = new; 23 | 24 | // params of the command 25 | new->command_num = GLTRANSLATE; // to modify 26 | new->paramf1 = x; // to modify 27 | new->paramf2 = y; // to modify 28 | new->paramf3 = z; // to modify 29 | } 30 | 31 | if ((pspgl_curctx->displaylists.is_in_glNewList == GL_COMPILE_AND_EXECUTE)||(pspgl_curctx->displaylists.is_in_glNewList == 0)) { 32 | // @@@ from here it's different, because it's the old function 33 | assert(stk->flags & MF_VFPU); 34 | 35 | if (!(stk->flags & MF_DISABLED)) 36 | stk->flags |= MF_DIRTY; 37 | 38 | mat->flags &= ~MF_IDENTITY; 39 | 40 | pspvfpu_use_matrices(c->vfpu_context, VFPU_STACKTOP, VMAT6); 41 | 42 | asm volatile("mtv %0, s630\n" // x 43 | "mtv %1, s631\n" // y 44 | "mtv %2, s632\n" // z 45 | 46 | "vscl.q c600, c700, s630\n" // col[0] * x 47 | "vscl.q c610, c710, s631\n" // col[1] * y 48 | "vscl.q c620, c720, s632\n" // col[2] * z 49 | 50 | "vadd.q c610, c610, c600\n" // col[1] += col[0] 51 | "vadd.q c730, c730, c620\n" // col[3] += col[2] 52 | "vadd.q c730, c730, c610\n" // col[3] += col[1]+col[0] 53 | : : "r" (x), "r" (y), "r" (z)); 54 | } 55 | } 56 | 57 | // @@@ added by Edorul 58 | void glTranslated(GLdouble x, GLdouble y, GLdouble z) 59 | { 60 | glTranslatef((GLfloat)x, (GLfloat)y, (GLfloat)z); 61 | } 62 | -------------------------------------------------------------------------------- /glUnmapBufferARB.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | GLboolean glUnmapBufferARB(GLenum target) 5 | { 6 | struct pspgl_bufferobj *buf, **bufp; 7 | 8 | bufp = __pspgl_bufferobj_for_target(target); 9 | 10 | if (bufp == NULL) 11 | return GL_FALSE; 12 | 13 | buf = *bufp; 14 | 15 | if (buf == NULL || buf->data == NULL || !buf->mapped) 16 | goto out_error; 17 | 18 | buf->mapped = GL_FALSE; 19 | 20 | __pspgl_buffer_unmap(buf->data, buf->access); 21 | 22 | return GL_TRUE; 23 | 24 | out_error: 25 | GLERROR(GL_INVALID_OPERATION); 26 | return GL_FALSE; 27 | } 28 | 29 | GLboolean glUnmapBuffer(GLenum target) 30 | __attribute__((alias("glUnmapBufferARB"))); 31 | -------------------------------------------------------------------------------- /glVertexPointer.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | void glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) 5 | { 6 | struct pspgl_vertex_array *va = &pspgl_curctx->vertex_array.vertex; 7 | GLboolean native; 8 | GLenum error; 9 | 10 | error = GL_INVALID_VALUE; 11 | if (unlikely(size < 2 || size > 4)) 12 | goto out_error; 13 | 14 | if (unlikely(stride < 0)) 15 | goto out_error; 16 | 17 | error = GL_INVALID_ENUM; 18 | if (unlikely(type != GL_BYTE && type != GL_SHORT && type != GL_FLOAT)) 19 | goto out_error; 20 | 21 | if (stride == 0) 22 | stride = __pspgl_gl_sizeof(type) * size; 23 | 24 | native = (size == 3); 25 | 26 | psp_log("ptr=%p(%p) size=%d type=%x stride=%d native=%d\n", 27 | pointer, __pspgl_bufferobj_deref(pspgl_curctx->vertex_array.arraybuffer, (void *)pointer), 28 | size, type, stride, native); 29 | 30 | /* If we're changed vertex formats, then mark the modelview matrix 31 | as dirty, so that any adjustment for this format can be 32 | applied. */ 33 | if (va->type != type) 34 | pspgl_curctx->modelview_stack.flags |= MF_DIRTY; 35 | 36 | va->size = size; 37 | va->type = type; 38 | va->stride = stride; 39 | va->ptr = pointer; 40 | va->native = native; 41 | 42 | __pspgl_varray_bind_buffer(va, pspgl_curctx->vertex_array.arraybuffer); 43 | 44 | return; 45 | 46 | out_error: 47 | GLERROR(error); 48 | } 49 | -------------------------------------------------------------------------------- /glVertexd.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | void glVertex2d(GLdouble x, GLdouble y) 4 | { 5 | glVertex3f(x,y, 0.0f); // @@@ modified by edorul 6 | } 7 | 8 | void glVertex2dv(const GLdouble *p) 9 | { 10 | glVertex3f(p[0], p[1], 0.0f); // @@@ modified by edorul 11 | } 12 | 13 | void glVertex3d(GLdouble x, GLdouble y, GLdouble z) 14 | { 15 | glVertex3f(x,y,z); 16 | } 17 | 18 | void glVertex3dv(const GLdouble *p) 19 | { 20 | glVertex3f(p[0], p[1], p[2]); 21 | } 22 | -------------------------------------------------------------------------------- /glVertexi.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glVertex3i (GLint x, GLint y, GLint z) 5 | { 6 | glVertex3f(x, y, z); 7 | } 8 | 9 | 10 | void glVertex2i (GLint x, GLint y) 11 | { 12 | glVertex3f(x, y, 0.0); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /glViewport.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | 4 | void glViewport (GLint x, GLint y, GLsizei width, GLsizei height) 5 | { 6 | struct pspgl_context *c = pspgl_curctx; 7 | struct pspgl_surface *s = c->draw; 8 | 9 | c->viewport.x = x; 10 | c->viewport.y = y; 11 | c->viewport.width = width; 12 | c->viewport.height = height; 13 | 14 | if (x < 0 || y < 0 || width < 0 || height < 0 || 15 | x+width > s->width || 16 | y+height > s->height) 17 | { 18 | GLERROR(GL_INVALID_VALUE); 19 | return; 20 | } 21 | 22 | /* Flip y coord */ 23 | y = s->height - y; 24 | height = -height; 25 | 26 | /* Viewport / Screen Offset */ 27 | sendCommandi(CMD_OFFSETX, (2048*16 - s->width*16/2)); 28 | sendCommandi(CMD_OFFSETY, (2048*16 - s->height*16/2)); 29 | 30 | /* Viewport Size (X/Y, Width/Height) */ 31 | sendCommandf(CMD_VIEWPORT_SX, width * .5f); 32 | sendCommandf(CMD_VIEWPORT_SY, height * .5f); 33 | 34 | /* Viewport Center (X/Y) */ 35 | float cx = 2048.f - (s->width * .5f) + (width * .5f) + x; 36 | float cy = 2048.f - (s->height * .5f) + (height * .5f) + y; 37 | sendCommandf(CMD_VIEWPORT_TX, cx); 38 | sendCommandf(CMD_VIEWPORT_TY, cy); 39 | 40 | /* Drawing Rectangle (unaffected by viewport) */ 41 | sendCommandi(CMD_REGION1, (0 << 10) | 0); 42 | sendCommandi(CMD_REGION2, ((s->height-1) << 10) | (s->width-1)); 43 | } 44 | -------------------------------------------------------------------------------- /glWeightPointerPSP.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | void glWeightPointerPSP(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) 5 | { 6 | struct pspgl_vertex_array *va = &pspgl_curctx->vertex_array.weight; 7 | GLenum error; 8 | 9 | error = GL_INVALID_VALUE; 10 | if (unlikely(size < 1 || size > NBONES)) 11 | goto out_error; 12 | 13 | if (unlikely(stride < 0)) 14 | goto out_error; 15 | 16 | error = GL_INVALID_ENUM; 17 | if (unlikely(type != GL_BYTE && type != GL_SHORT && type != GL_FLOAT)) 18 | goto out_error; 19 | 20 | if (stride == 0) 21 | stride = __pspgl_gl_sizeof(type) * size; 22 | 23 | psp_log("ptr=%p(%p) size=%d type=%x stride=%d\n", 24 | pointer, __pspgl_bufferobj_deref(pspgl_curctx->vertex_array.arraybuffer, 25 | (void *)pointer), 26 | size, type, stride); 27 | 28 | va->size = size; 29 | va->type = type; 30 | va->stride = stride; 31 | va->ptr = pointer; 32 | va->native = GL_TRUE; 33 | 34 | __pspgl_varray_bind_buffer(va, pspgl_curctx->vertex_array.arraybuffer); 35 | return; 36 | 37 | out_error: 38 | GLERROR(error); 39 | } 40 | -------------------------------------------------------------------------------- /gluBuildMipmaps.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pspglu.h" 7 | #include "pspgl_misc.h" 8 | 9 | GLint gluBuild2DMipmaps( GLenum target, 10 | GLint internalFormat, 11 | GLsizei width, 12 | GLsizei height, 13 | GLenum format, 14 | GLenum type, 15 | const void *data ) 16 | { 17 | const struct format *fmt = __pspglu_getformat(format, type); 18 | GLsizei tw, th; 19 | const void *src; 20 | void *dst; 21 | int level, levels; 22 | GLint maxtex; 23 | 24 | if (fmt == NULL) 25 | return GLU_INVALID_ENUM; 26 | 27 | tw = pow2(width); 28 | th = pow2(height); 29 | 30 | glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtex); 31 | 32 | while(tw > maxtex) 33 | tw /= 2; 34 | while(th > maxtex) 35 | th /= 2; 36 | 37 | levels = lg2(tw); 38 | level = lg2(th); 39 | if (level > levels) 40 | levels = level; 41 | 42 | src = data; 43 | dst = NULL; 44 | 45 | for(level = 0; level <= levels; level++) { 46 | dst = malloc(tw * th * fmt->size); 47 | 48 | gluScaleImage(format, 49 | width, height, type, src, 50 | tw, th, type, dst); 51 | 52 | glTexImage2D(target, level, internalFormat, 53 | tw, th, 0, format, type, dst); 54 | 55 | if (src != data) 56 | free((void *)src); 57 | src = dst; 58 | width = tw; 59 | height = th; 60 | 61 | if (tw > 1) 62 | tw /= 2; 63 | if (th > 1) 64 | th /= 2; 65 | } 66 | free(dst); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /gluLookAt.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include 3 | 4 | extern 5 | void gluLookAtf (GLfloat eyeX, GLfloat eyeY, GLfloat eyeZ, 6 | GLfloat centerX, GLfloat centerY, GLfloat centerZ, 7 | GLfloat upX, GLfloat upY, GLfloat upZ); 8 | 9 | 10 | void gluLookAt (GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, 11 | GLdouble centerX, GLdouble centerY, GLdouble centerZ, 12 | GLdouble upX, GLdouble upY, GLdouble upZ) 13 | { 14 | gluLookAtf(eyeX, eyeY, eyeZ, 15 | centerX, centerY, centerZ, 16 | upX, upY, upZ); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /gluLookAtf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | #include "pspgl_matrix.h" 4 | 5 | static inline 6 | void cross_product (GLfloat a [3], GLfloat b [3], GLfloat product [3]) 7 | { 8 | product[0] = a[1] * b[2] - a[2] * b[1]; 9 | product[1] = a[2] * b[0] - a[0] * b[2]; 10 | product[2] = a[0] * b[1] - a[1] * b[0]; 11 | } 12 | 13 | 14 | static inline 15 | void normalize (GLfloat v [3]) 16 | { 17 | GLfloat len = sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); 18 | 19 | if (len != 0.0) { 20 | GLfloat scale = 1.0f / len; 21 | v[0] *= scale; 22 | v[1] *= scale; 23 | v[2] *= scale; 24 | } 25 | } 26 | 27 | 28 | /** 29 | * Variable names like in 'man gluLookAt' 30 | */ 31 | void gluLookAtf (GLfloat eyeX, GLfloat eyeY, GLfloat eyeZ, 32 | GLfloat centerX, GLfloat centerY, GLfloat centerZ, 33 | GLfloat upX, GLfloat upY, GLfloat upZ) 34 | { 35 | #if 0 36 | GLfloat m [16]; 37 | GLfloat f [3]; 38 | GLfloat u [3]; 39 | GLfloat s [3]; 40 | 41 | f[0] = centerX - eyeX; 42 | f[1] = centerY - eyeY; 43 | f[2] = centerZ - eyeZ; 44 | 45 | u[0] = upX; 46 | u[1] = upY; 47 | u[2] = upZ; 48 | 49 | normalize(f); 50 | cross_product(f, u, s); 51 | normalize(s); 52 | cross_product(s, f, u); 53 | 54 | m[0] = s[0]; m[4] = s[1]; m[8] = s[2]; m[12] = 0.0; 55 | m[1] = u[0]; m[5] = u[1]; m[9] = u[2]; m[13] = 0.0; 56 | m[2] = -f[0]; m[6] = -f[1]; m[10] = -f[2]; m[14] = 0.0; 57 | m[3] = 0.0; m[7] = 0.0; m[11] = 0.0; m[15] = 1.0; 58 | 59 | glMultMatrixf(m); 60 | glTranslatef(-eyeX, -eyeY, -eyeZ); 61 | #else 62 | struct pspgl_context *c = pspgl_curctx; 63 | struct pspgl_matrix_stack *stk = c->current_matrix_stack; 64 | struct pspgl_matrix *mat = c->current_matrix; 65 | 66 | pspvfpu_use_matrices(c->vfpu_context, VFPU_STACKTOP, VMAT5 | VMAT6); 67 | 68 | assert(stk->flags & MF_VFPU); 69 | 70 | if (!(stk->flags & MF_DISABLED)) 71 | stk->flags |= MF_DIRTY; 72 | 73 | mat->flags &= ~MF_IDENTITY; 74 | 75 | /* 76 | Matrix 5: 77 | 0: sX sY sZ 1/|s| 78 | 1: uX uY uZ - 79 | 2: fX fY fZ 1/|f| 80 | */ 81 | asm volatile("mtv %0, s501\n" : : "r" (upX)); 82 | asm volatile("mtv %0, s511\n" : : "r" (upY)); 83 | asm volatile("mtv %0, s521\n" : : "r" (upZ)); 84 | 85 | asm volatile("mtv %0, s502\n" : : "r" (centerX - eyeX)); 86 | asm volatile("mtv %0, s512\n" : : "r" (centerY - eyeY)); 87 | asm volatile("mtv %0, s522\n" : : "r" (centerZ - eyeZ)); 88 | 89 | asm volatile("vmmov.t m600, m700\n" // prepare for multiply 90 | 91 | "vdot.t s532, r502, r502\n" // t = fx*fx + fy*fy + fz*fz 92 | "vrsq.s s532, s532\n" // t = 1/sqrt(t) 93 | "vscl.t r502[-1:1,-1:1,-1:1], r502, s532\n" // normalize f 94 | 95 | "vcrsp.t r500, r502, r501\n" // s = f x u 96 | "vdot.t s530, r500, r500\n" // t = sx*sx+sy*sy+sz*sz 97 | "vrsq.s s530, s530\n" // t = 1/sqrt(t) 98 | "vscl.t r500[-1:1,-1:1,-1:1], r500, s530\n" // normalize s 99 | 100 | "vcrsp.t r501, r500, r502\n" // u = s x f 101 | 102 | "vneg.t r502, r502\n" // f = -f 103 | 104 | "vmmul.t m700, m600, m500\n" // top *= mat5 105 | ); 106 | 107 | glTranslatef(-eyeX, -eyeY, -eyeZ); 108 | #endif 109 | } 110 | 111 | -------------------------------------------------------------------------------- /gluPerspective.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include 3 | 4 | void gluPerspectivef (GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); 5 | 6 | 7 | void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) 8 | { 9 | gluPerspectivef(fovy, aspect, zNear, zFar); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /gluPerspectivef.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_internal.h" 3 | 4 | 5 | void gluPerspectivef (GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) 6 | { 7 | GLfloat f = 1.0f / tanf(fovy * (M_PI/360.0)); 8 | GLfloat m [16]; 9 | 10 | m[0] = f / aspect; 11 | m[1] = 0.0; 12 | m[2] = 0.0; 13 | m[3] = 0.0; 14 | 15 | m[4] = 0.0; 16 | m[5] = f; 17 | m[6] = 0.0; 18 | m[7] = 0.0; 19 | 20 | m[8] = 0.0; 21 | m[9] = 0.0; 22 | m[10] = (zFar + zNear) / (zNear - zFar); 23 | m[11] = -1.0; 24 | 25 | m[12] = 0.0; 26 | m[13] = 0.0; 27 | m[14] = 2.0 * zFar * zNear / (zNear - zFar); 28 | m[15] = 0.0; 29 | 30 | glMultMatrixf(m); 31 | } 32 | -------------------------------------------------------------------------------- /pspgl_buffers.h: -------------------------------------------------------------------------------- 1 | #ifndef _PSPGL_BUFFERS_H 2 | #define _PSPGL_BUFFERS_H 3 | 4 | #include "pspgl_internal.h" 5 | 6 | struct pspgl_buffer { 7 | short refcount; 8 | short generation; /* generation counter to detect changes */ 9 | signed char mapped; /* mapping counter */ 10 | unsigned char flags; 11 | #define BF_PINNED_RD (1<<0) /* buffer is pinned for reading (by hardware) */ 12 | #define BF_PINNED_WR (1<<1) /* buffer if pinned for writing (by hardware) */ 13 | #define BF_PINNED (BF_PINNED_RD|BF_PINNED_WR) 14 | #define BF_PINNED_FIXED (1<<2) /* buffer is pinned permanently */ 15 | #define BF_UNMANAGED (1<<3) /* buffer is not allocated by us */ 16 | #define BF_TRANSIENT (1<<4) /* buffer is in the transient pool */ 17 | #define BF_MIGRATING (1<<5) /* buffer is marked for migration (transient) */ 18 | 19 | /* Pointers for the pin list */ 20 | struct pspgl_buffer **pin_prevp; 21 | struct pspgl_buffer *pin_next; 22 | 23 | /* Pointer used for the global buffer list */ 24 | struct pspgl_buffer *list_prev; 25 | struct pspgl_buffer *list_next; 26 | 27 | void *base; 28 | GLsizeiptr size; 29 | }; 30 | 31 | struct pspgl_bufferobj { 32 | int refcount; 33 | 34 | GLenum usage, access; 35 | GLboolean mapped; /* glMapBuffer called */ 36 | 37 | struct pspgl_buffer *data; 38 | }; 39 | 40 | /* Create new buffer, but does not allocate any storage for it. 41 | Returns a buffer with a refcount of 1 */ 42 | struct pspgl_bufferobj *__pspgl_bufferobj_new(struct pspgl_buffer *data) 43 | __attribute__((malloc)); 44 | 45 | /* Decrements refcount, and frees if it hits 0 */ 46 | void __pspgl_bufferobj_free(struct pspgl_bufferobj *); 47 | 48 | /* Convert a buffer+offset into a pointer; if buffer is NULL, then 49 | offset is returned as a pointer. This pointer has not been mapped, 50 | and should not be dereferenced. */ 51 | void *__pspgl_bufferobj_deref(const struct pspgl_bufferobj *buf, void *offset) 52 | __attribute__((pure)); 53 | 54 | /* Helper to map a buffer and return a pointer to an offset; if buffer 55 | is NULL, then offset is returned as a pointer. */ 56 | void *__pspgl_bufferobj_map(const struct pspgl_bufferobj *buf, GLenum access, void *off); 57 | /* Unmap a buffer mapped above. Should always be paired. */ 58 | void __pspgl_bufferobj_unmap(const struct pspgl_bufferobj *buf, GLenum access); 59 | 60 | /* Return a bufferobj ** for a particular target. Returns NULL if target 61 | is unknown/invalid, and sets GLERROR appropriately. */ 62 | struct pspgl_bufferobj **__pspgl_bufferobj_for_target(GLenum target); 63 | 64 | /* Allocate and initialize a buffer, allocating data according the "usage" */ 65 | struct pspgl_buffer *__pspgl_buffer_new(GLsizeiptr size, GLenum usage) 66 | __attribute__((malloc)); 67 | 68 | /* Decrement a buffer's count and free if it hits 0 */ 69 | void __pspgl_buffer_free(struct pspgl_buffer *data); 70 | 71 | /* Map a buffer for access type "access". May be called repeatedly. */ 72 | void *__pspgl_buffer_map(struct pspgl_buffer *data, GLenum access); 73 | 74 | /* Unmap a buffer and do the appropriate fixups. Must be paired with 75 | buffer_map(). */ 76 | void __pspgl_buffer_unmap(struct pspgl_buffer *data, GLenum access); 77 | 78 | /* Buffer wants to be in vidmem (a hint, not an absolute requirement) */ 79 | void __pspgl_buffer_want_vidmem(struct pspgl_buffer *buf); 80 | 81 | /* Wait for hardware to finished with a buffer */ 82 | void __pspgl_buffer_dlist_sync(struct pspgl_buffer *data); 83 | 84 | #endif /* PSPGL_BUFFERS_H */ 85 | -------------------------------------------------------------------------------- /pspgl_copy_pixels.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | 3 | static inline int absi(int x) 4 | { 5 | return (x < 0) ? -x : x; 6 | } 7 | 8 | static inline int sgni(int x) 9 | { 10 | if (x < 0) 11 | return -1; 12 | if (x == 0) 13 | return 0; 14 | return 1; 15 | } 16 | 17 | void __pspgl_copy_pixels(const void *srcbuf, int srcstride, int srcx, int srcy, 18 | void *dstbuf, int dststride, int dstx, int dsty, 19 | int width, int height, unsigned pixfmt) 20 | { 21 | sendCommandi(CMD_COPY_SRC, (unsigned)srcbuf); 22 | sendCommandi(CMD_COPY_DST, (unsigned)dstbuf); 23 | 24 | if (srcstride < 0 || dststride < 0) { 25 | /* Flipping the image, so copy line-by-line */ 26 | int sdy = sgni(srcstride); 27 | int ddy = sgni(dststride); 28 | 29 | srcstride = absi(srcstride); 30 | dststride = absi(dststride); 31 | 32 | sendCommandi(CMD_COPY_SRC_STRIDE, (((unsigned)srcbuf & 0xff000000) >> 8) | srcstride); 33 | sendCommandi(CMD_COPY_DST_STRIDE, (((unsigned)dstbuf & 0xff000000) >> 8) | dststride); 34 | 35 | sendCommandi(CMD_COPY_SIZE, ((1-1) << 10) | (width-1)); 36 | 37 | while(height--) { 38 | sendCommandi(CMD_COPY_SRC_XY, (srcy << 10) | srcx); 39 | sendCommandi(CMD_COPY_DST_XY, (dsty << 10) | dstx); 40 | 41 | __pspgl_context_flush_pending_state_changes (pspgl_curctx, 42 | CMD_COPY_SRC, 43 | CMD_COPY_DST_STRIDE); 44 | __pspgl_context_flush_pending_state_changes (pspgl_curctx, 45 | CMD_COPY_SRC_XY, 46 | CMD_COPY_SIZE); 47 | sendCommandiUncached(CMD_COPY_START, (pixfmt == GE_RGBA_8888)); 48 | 49 | srcy += sdy; 50 | dsty += ddy; 51 | } 52 | } else { 53 | /* Just copy the whole thing in one go */ 54 | sendCommandi(CMD_COPY_SRC_STRIDE, (((unsigned)srcbuf & 0xff000000) >> 8) | srcstride); 55 | sendCommandi(CMD_COPY_DST_STRIDE, (((unsigned)dstbuf & 0xff000000) >> 8) | dststride); 56 | 57 | sendCommandi(CMD_COPY_SRC_XY, (srcy << 10) | srcx); 58 | sendCommandi(CMD_COPY_DST_XY, (dsty << 10) | dstx); 59 | 60 | sendCommandi(CMD_COPY_SIZE, ((height-1) << 10) | (width-1)); 61 | 62 | __pspgl_context_flush_pending_state_changes (pspgl_curctx, 63 | CMD_COPY_SRC, 64 | CMD_COPY_DST_STRIDE); 65 | __pspgl_context_flush_pending_state_changes (pspgl_curctx, 66 | CMD_COPY_SRC_XY, 67 | CMD_COPY_SIZE); 68 | 69 | sendCommandiUncached(CMD_COPY_START, (pixfmt == GE_RGBA_8888)); 70 | } 71 | } 72 | 73 | /* Copy memory with the GE. Typically used for moving things to/from 74 | or within vidmem. Does not synchronize anything, and doesn't pin 75 | any buffers. Handles overlapping src and dst. */ 76 | void __pspgl_copy_memory(const void *src, void *dst, size_t size) 77 | { 78 | size_t xfersize; 79 | 80 | psp_log("coping %p->%p %u\n", src, dst, size); 81 | 82 | xfersize = size; 83 | 84 | if ((dst < src && (dst+size) > src) || 85 | (src < dst && (src+size) > dst)) { 86 | if (dst < src) 87 | xfersize = src - dst; 88 | else 89 | xfersize = dst - src; 90 | psp_log(" OVERLAPPING: xfersize=%u\n", 91 | xfersize); 92 | } 93 | 94 | /* Copy 32bpp "pixels" */ 95 | size /= 4; 96 | xfersize /= 4; 97 | 98 | /* Copy the data as a series of 512xN blits (or Nx1 for 99 | transfers of less than 512 words). If the src and dst 100 | overlap, then the transfer size may be smaller. */ 101 | while(size > 0) { 102 | unsigned w, h; 103 | unsigned chunk = size; 104 | 105 | if (chunk > xfersize) 106 | chunk = xfersize; 107 | 108 | if (chunk < 512) { 109 | w = chunk; 110 | h = 1; 111 | } else { 112 | w = 512; 113 | h = chunk / 512; 114 | } 115 | 116 | psp_log(" chunk %p->%p %dx%d\n", 117 | src, dst, w, h); 118 | 119 | __pspgl_copy_pixels(src, w, 0, 0, 120 | dst, w, 0, 0, 121 | w, h, GE_RGBA_8888); 122 | 123 | size -= w * h; 124 | src += w * h; 125 | dst += w * h; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /pspgl_dlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __pspgl_dlist_h__ 2 | #define __pspgl_dlist_h__ 3 | 4 | #include "pspgl_misc.h" 5 | 6 | 7 | /* Initialize the dlist subsystem */ 8 | extern void __pspgl_dlist_init(void); 9 | 10 | /* flush pending buffers to hardware, and return asynchronously. */ 11 | extern void __pspgl_dlist_submit (void); 12 | 13 | /* Wait until all commands in currently queued dlist are executed and 14 | drawn, or the predicate function returns true. The predicate is 15 | called each time a buffer of commands has been finalized. A NULL 16 | predicate is considered to always return False. */ 17 | extern void __pspgl_dlist_await_completion (int (*pred)(void *p), void *data); 18 | 19 | /* cancel the currently running wait queue */ 20 | extern void __pspgl_dlist_cancel (void); 21 | 22 | /* Pin a pspgl_buffer, indicating it is being used by hardware. The 23 | buffer is unpinned when the GE has reached the current point in the 24 | commands stream. The flags contain one or both of BF_PINNED_RD or 25 | BF_PINNED_WR to indicate whether the buffer is pinned for reading 26 | or writing. */ 27 | extern void __pspgl_dlist_pin_buffer(struct pspgl_buffer *data, unsigned flags); 28 | 29 | /** 30 | * check if dlist has room for (size) bytes embedded in cmd buf and 31 | * advance cmd_buf pointer, useful e.g. for vertex data embedded in 32 | * command stream. Will go to next dlist if necessary to get the 33 | * space. Returned memory pointer is aligned to 16-byte boundaries. 34 | */ 35 | extern void * __pspgl_dlist_insert_space (unsigned long size); 36 | 37 | 38 | /** 39 | * insert cmd in dlist. If dlist is full, automatically go to the next one. 40 | */ 41 | extern void __pspgl_dlist_enqueue_cmd (unsigned long cmd); 42 | 43 | #endif 44 | 45 | -------------------------------------------------------------------------------- /pspgl_hash.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pspgl_hash.h" 3 | 4 | 5 | #define HASH(k) ((k) % HASH_SIZE) 6 | 7 | struct hashentry { 8 | unsigned long key; 9 | void *data; 10 | struct hashentry *next; 11 | }; 12 | 13 | 14 | void* __pspgl_hash_lookup (const struct hashtable *h, unsigned long key) 15 | { 16 | struct hashentry *ent; 17 | 18 | if (key > h->maxkey) 19 | return NULL; 20 | 21 | for (ent=h->buckets[HASH(key)]; ent!=NULL; ent=ent->next) { 22 | if (ent->key == key) 23 | return ent->data; 24 | } 25 | 26 | return NULL; 27 | } 28 | 29 | 30 | void __pspgl_hash_insert (struct hashtable *h, unsigned long key, void *value) 31 | { 32 | unsigned long b = HASH(key); 33 | struct hashentry *ent; 34 | 35 | if (key <= h->maxkey) { 36 | for (ent=h->buckets[b]; ent!=NULL; ent=ent->next) { 37 | if (ent->key == key) { 38 | ent->data = value; 39 | return; 40 | } 41 | } 42 | } 43 | 44 | if ((ent = malloc(sizeof(*ent)))) { 45 | ent->key = key; 46 | ent->data = value; 47 | ent->next = h->buckets[b]; 48 | h->buckets[b] = ent; 49 | if (key > h->maxkey) 50 | h->maxkey = key; 51 | } 52 | } 53 | 54 | 55 | void* __pspgl_hash_remove (struct hashtable *h, unsigned long key) 56 | { 57 | struct hashentry **entp; 58 | 59 | for (entp=&h->buckets[HASH(key)]; *entp!=NULL; entp=&(*entp)->next) { 60 | struct hashentry *ent = *entp; 61 | 62 | if (ent->key == key) { 63 | void *ret = ent->data; 64 | *entp = ent->next; 65 | free(ent); 66 | return ret; 67 | } 68 | } 69 | 70 | return NULL; 71 | } 72 | 73 | 74 | unsigned long __pspgl_hash_uniquekey (const struct hashtable *h) 75 | { 76 | unsigned long ret; 77 | 78 | if (h->maxkey < HASH_NO_KEY-1) { 79 | ret = h->maxkey + 1; 80 | } else { 81 | for(ret=1; retbuckets[i]; ent!=NULL; ent=next) { 98 | next = ent->next; 99 | func(ent->data); 100 | free(ent); 101 | } 102 | h->buckets[i] = NULL; 103 | } 104 | } 105 | 106 | -------------------------------------------------------------------------------- /pspgl_hash.h: -------------------------------------------------------------------------------- 1 | #ifndef __hash_h__ 2 | #define __hash_h__ 3 | 4 | 5 | #define HASH_SIZE (32) 6 | #define HASH_NO_KEY (~0) 7 | 8 | 9 | struct hashtable { 10 | struct hashentry *buckets [HASH_SIZE]; 11 | unsigned long maxkey; 12 | }; 13 | 14 | extern void __pspgl_hash_insert (struct hashtable *h, unsigned long key, void *value); 15 | extern void* __pspgl_hash_remove (struct hashtable *h, unsigned long key); 16 | extern void* __pspgl_hash_lookup (const struct hashtable *h, unsigned long key); 17 | 18 | /* return unused key, HASH_NO_KEY on failure */ 19 | extern unsigned long __pspgl_hash_uniquekey (const struct hashtable *h); 20 | 21 | /* call func() for each entry, free entry thenafter. */ 22 | extern void __pspgl_hash_foreach_free (struct hashtable *, void (*func) (void *data)); 23 | 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /pspgl_matrix.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pspgl_internal.h" 4 | #include "pspgl_matrix.h" 5 | 6 | #if VFPU_STACKTOP != VMAT7 7 | #error Fix this VFPU assembler 8 | #endif 9 | 10 | /* Write a copy of a matrix from the VFPU into memory; does not change 11 | the state of MF_VFPU. */ 12 | void __pspgl_matrix_sync(struct pspgl_context *c, const struct pspgl_matrix_stack *s) 13 | { 14 | struct pspgl_matrix *m = &s->stack[s->depth]; 15 | 16 | if ((s->flags & MF_VFPU) == 0) 17 | return; 18 | 19 | pspvfpu_use_matrices(c->vfpu_context, VFPU_STACKTOP, 0); 20 | 21 | asm volatile("sv.q c700, 0 + %0, wb\n" 22 | "sv.q c710, 16 + %0, wb\n" 23 | "sv.q c720, 32 + %0, wb\n" 24 | "sv.q c730, 48 + %0, wb\n" 25 | : "=m" (m->mat[0]) : : "memory"); 26 | } 27 | 28 | /* Load the top of a matrix stack into the VFPU. */ 29 | void __pspgl_matrix_load(struct pspgl_context *c, struct pspgl_matrix_stack *s) 30 | { 31 | const struct pspgl_matrix *m = &s->stack[s->depth]; 32 | 33 | pspvfpu_use_matrices(c->vfpu_context, VFPU_STACKTOP, 0); 34 | 35 | if (m->flags & MF_IDENTITY) 36 | asm volatile("vmidt.q m700\n" : : : "memory"); 37 | else 38 | asm volatile("lv.q c700, 0 + %0\n" 39 | "lv.q c710, 16 + %0\n" 40 | "lv.q c720, 32 + %0\n" 41 | "lv.q c730, 48 + %0\n" 42 | : : "m" (m->mat[0]) : "memory"); 43 | 44 | s->flags |= MF_VFPU; 45 | } 46 | 47 | /* Select a new matrix stack as the current matrix stack. This 48 | enforces the invarient that the top of the current matrix stack is 49 | always in the VFPU. */ 50 | void __pspgl_matrix_select(struct pspgl_context *c, struct pspgl_matrix_stack *s) 51 | { 52 | struct pspgl_matrix_stack *stk = c->current_matrix_stack; 53 | 54 | if (stk == s) 55 | return; 56 | 57 | if (stk) { 58 | /* Flush out the old stack state */ 59 | assert(stk->flags & MF_VFPU); 60 | __pspgl_matrix_sync(c, stk); 61 | stk->flags &= ~MF_VFPU; 62 | } 63 | 64 | c->current_matrix_stack = s; 65 | c->current_matrix = &s->stack[s->depth]; 66 | 67 | /* Load up the new VFPU state */ 68 | assert((s->flags & MF_VFPU) == 0); 69 | __pspgl_matrix_load(c, s); 70 | } 71 | -------------------------------------------------------------------------------- /pspgl_matrix.h: -------------------------------------------------------------------------------- 1 | #ifndef PSPGL_MATRIX_H 2 | #define PSPGL_MATRIX_H 3 | 4 | /* Write the VFPU's copy of the top-of-stack matrix back to memory */ 5 | void __pspgl_matrix_sync(struct pspgl_context *c, const struct pspgl_matrix_stack *s); 6 | 7 | /* Load the VFPU with the top-of-stack matrix */ 8 | void __pspgl_matrix_load(struct pspgl_context *c, struct pspgl_matrix_stack *s); 9 | 10 | /* Select a new current matrix stack, setting up the VFPU as required. */ 11 | void __pspgl_matrix_select(struct pspgl_context *c, struct pspgl_matrix_stack *s); 12 | 13 | #endif /* PSPGL_MATRIX_H */ 14 | -------------------------------------------------------------------------------- /pspgl_stats.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define GL_GLEXT_PROTOTYPES 6 | #include "pspgl_internal.h" 7 | #include 8 | 9 | unsigned __pspgl_ticks_to_us(unsigned long long ticks) 10 | { 11 | static unsigned tickres; 12 | 13 | if (tickres == 0) { 14 | tickres = sceRtcGetTickResolution(); 15 | psp_log("tick resolution %d\n", tickres); 16 | } 17 | 18 | return (ticks * 1000000ull) / tickres; 19 | } 20 | 21 | void glEnableStatsPSP(GLenum stats) 22 | { 23 | switch(stats) { 24 | case GL_STATS_TIMING_PSP: 25 | pspgl_curctx->stats.enabled = GL_TRUE; 26 | break; 27 | default: 28 | GLERROR(GL_INVALID_ENUM); 29 | } 30 | } 31 | 32 | void glDisableStatsPSP(GLenum stats) 33 | { 34 | switch(stats) { 35 | case GL_STATS_TIMING_PSP: 36 | pspgl_curctx->stats.enabled = GL_FALSE; 37 | break; 38 | default: 39 | GLERROR(GL_INVALID_ENUM); 40 | } 41 | } 42 | 43 | void glResetStatsPSP(GLenum stats) 44 | { 45 | switch(stats) { 46 | case GL_STATS_CMDISSUES_PSP: 47 | pspgl_curctx->stats.buffer_issues = 0; 48 | 49 | case GL_STATS_QUEUEWAITTIME_PSP: 50 | pspgl_curctx->stats.queuewait = 0; 51 | break; 52 | default: 53 | GLERROR(GL_INVALID_ENUM); 54 | } 55 | 56 | } 57 | 58 | void glGetStatisticsuivPSP(GLenum stats, GLuint *ret) 59 | { 60 | switch(stats) { 61 | case GL_STATS_FRAMETIME_PSP: 62 | ret[0] = __pspgl_ticks_to_us(pspgl_curctx->draw->flip_end - 63 | pspgl_curctx->draw->prev_end); 64 | return; 65 | case GL_STATS_APPTIME_PSP: 66 | ret[0] = __pspgl_ticks_to_us(pspgl_curctx->draw->flip_start - 67 | pspgl_curctx->draw->prev_end); 68 | break; 69 | case GL_STATS_SWAPTIME_PSP: 70 | ret[0] = __pspgl_ticks_to_us(pspgl_curctx->draw->flip_end - 71 | pspgl_curctx->draw->flip_start); 72 | break; 73 | case GL_STATS_CMDISSUES_PSP: 74 | ret[0] = pspgl_curctx->stats.buffer_issues; 75 | break; 76 | case GL_STATS_QUEUEWAITTIME_PSP: 77 | ret[0] = __pspgl_ticks_to_us(pspgl_curctx->stats.queuewait); 78 | break; 79 | 80 | default: 81 | GLERROR(GL_INVALID_ENUM); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /pspgl_varray_draw.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | #include "pspgl_dlist.h" 4 | 5 | void __pspgl_varray_draw(GLenum mode, GLint first, GLsizei count) 6 | { 7 | long prim; 8 | struct vertex_format vfmt, *vfmtp; 9 | struct pspgl_buffer *vbuf; 10 | unsigned vbuf_offset; 11 | const void *buf; 12 | GLenum error; 13 | 14 | error = GL_INVALID_ENUM; 15 | prim = __pspgl_glprim2geprim(mode); 16 | if (unlikely(prim < 0)) 17 | goto out_error; 18 | 19 | if (unlikely(count == 0)) 20 | return; 21 | 22 | vbuf = NULL; 23 | vbuf_offset = 0; 24 | vfmtp = &vfmt; 25 | 26 | psp_log("checking for cached array...\n"); 27 | /* Check to see if we can use the locked array fast path */ 28 | if (__pspgl_cache_arrays()) { 29 | /* FAST: draw from locked array */ 30 | struct locked_arrays *l = &pspgl_curctx->vertex_array.locked; 31 | 32 | psp_log("yep, cached\n"); 33 | vbuf = l->cached_array; 34 | vbuf_offset = l->cached_array_offset; 35 | vfmtp = &l->vfmt; 36 | first -= l->cached_first; 37 | 38 | vbuf->refcount++; 39 | } 40 | 41 | if (unlikely(vbuf == NULL)) { 42 | /* SLOW: convert us some arrays */ 43 | vfmtp = &vfmt; 44 | __pspgl_ge_vertex_fmt(pspgl_curctx, &vfmt); 45 | 46 | if (unlikely(vfmt.hwformat == 0)) 47 | return; 48 | 49 | psp_log("converting %d vertices at %d\n", count, first); 50 | 51 | vbuf = __pspgl_varray_convert(&vfmt, first, count); 52 | vbuf_offset = 0; 53 | 54 | psp_log("returned vbuf=%p\n", vbuf); 55 | 56 | error = GL_OUT_OF_MEMORY; 57 | if (unlikely(vbuf == NULL)) 58 | goto out_error; 59 | } 60 | 61 | buf = vbuf->base + vbuf_offset; 62 | buf += first * vfmtp->vertex_size; 63 | 64 | __pspgl_context_render_prim(pspgl_curctx, prim, count, vfmtp->hwformat, buf, NULL); 65 | __pspgl_dlist_pin_buffer(vbuf, BF_PINNED_RD); 66 | 67 | if (mode == GL_LINE_LOOP) { 68 | GLushort *idx = __pspgl_dlist_insert_space(sizeof(GLushort) * 2); 69 | 70 | assert(idx != NULL); 71 | 72 | idx[0] = first+count-1; 73 | idx[1] = first; 74 | 75 | psp_log("drawing closing line on loop: idx=%d %d\n", idx[0], idx[1]); 76 | __pspgl_context_render_prim(pspgl_curctx, GE_LINES, 2, 77 | vfmtp->hwformat | GE_VINDEX_16BIT, buf, idx); 78 | __pspgl_dlist_pin_buffer(vbuf, BF_PINNED_RD); 79 | } 80 | 81 | __pspgl_buffer_free(vbuf); 82 | return; 83 | 84 | out_error: 85 | GLERROR(error); 86 | } 87 | 88 | -------------------------------------------------------------------------------- /pspgl_varray_draw_elts.c: -------------------------------------------------------------------------------- 1 | #include "pspgl_internal.h" 2 | #include "pspgl_buffers.h" 3 | 4 | void __pspgl_varray_draw_elts(GLenum mode, GLenum idx_type, const void *const indices, GLsizei count) 5 | { 6 | struct locked_arrays *l = &pspgl_curctx->vertex_array.locked; 7 | int minidx, maxidx; 8 | 9 | minidx = maxidx = -1; 10 | 11 | if (l->count > 0) { 12 | /* use locked range */ 13 | 14 | minidx = l->first; 15 | maxidx = l->first + l->count; 16 | } 17 | 18 | __pspgl_varray_draw_range_elts(mode, idx_type, indices, count, minidx, maxidx); 19 | } 20 | -------------------------------------------------------------------------------- /pspglu.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSPGLU_H 2 | #define __PSPGLU_H 3 | 4 | #include 5 | 6 | #define RGBA(r,g,b,a) ((((a)&0xff) << 24) | \ 7 | (((b)&0xff) << 16) | \ 8 | (((g)&0xff) << 8) | \ 9 | (((r)&0xff) << 0)) 10 | 11 | #define R(rgba) (((rgba) & 0x000000ff) >> 0) 12 | #define G(rgba) (((rgba) & 0x0000ff00) >> 8) 13 | #define B(rgba) (((rgba) & 0x00ff0000) >>16) 14 | #define A(rgba) (((rgba) & 0xff000000) >>24) 15 | 16 | 17 | struct format; 18 | typedef unsigned pix_t; 19 | 20 | typedef void (*unpack_t)(const struct format *fmt, const void *src, pix_t *dst, int count); 21 | typedef void (*pack_t)(const struct format *fmt, const pix_t *src, void *dst, int count); 22 | 23 | struct format { 24 | GLenum format; 25 | GLenum type; 26 | 27 | GLubyte channels; 28 | GLubyte size; 29 | 30 | unpack_t unpack; 31 | pack_t pack; 32 | }; 33 | 34 | const struct format *__pspglu_getformat(GLenum format, GLenum type); 35 | 36 | #endif /* PSPGLU_H */ 37 | -------------------------------------------------------------------------------- /test-q3/Makefile: -------------------------------------------------------------------------------- 1 | SOURCEDIR = ./quake3-1.32b 2 | CODEDIR = $(SOURCEDIR)/code 3 | Q3ZIP = $(SOURCEDIR)-source.zip 4 | TARGET = Quake3 5 | 6 | include $(wildcard files_*.inc) 7 | 8 | OBJS := $(SRC_FILES:.c=.o) 9 | DEPS := $(SRC_FILES:.c=.d) 10 | 11 | ARCH = psp- 12 | CC = $(ARCH)gcc 13 | RM = rm -f 14 | 15 | CFLAGS = -g -Wall -O0 -MD -DBOTLIB 16 | LFLAGS = -g -Wall -O0 17 | 18 | #CFLAGS += -ffunction-sections 19 | 20 | ifeq ($(ARCH),psp-) 21 | SDKPATH := $(shell psp-config --pspsdk-path) 22 | # XXX FIXME: Toolchain quirk: this should get set by the compiler!! 23 | CFLAGS += -D__LITTLE_ENDIAN__ 24 | CFLAGS += -I$(SDKPATH)/include -I$(SDKPATH)/include/GL 25 | # XXX FIXME: Do we still need -G0 ?? 26 | CFLAGS += -G0 -fsingle-precision-constant 27 | # we place all missing libc bits in generic/... 28 | CFLAGS += -I ./generic 29 | LFLAGS += -DMODULE_NAME="Quake3" psp-setup.c 30 | LFLAGS += -L$(SDKPATH)/lib -lglut -lGL 31 | LFLAGS += -lpspdebug -lpspge -lpspdisplay -lpspctrl -lpspsdk -lm -lc -lpspuser -lpsputility -lpspkernel 32 | else 33 | ifeq ($(shell uname),Darwin) 34 | CFLAGS += -F OpenGL -I/System/Library/Frameworks/OpenGL.framework/Headers/ 35 | CFLAGS += -F GLUT -I/System/Library/Frameworks/GLUT.framework/Headers/ 36 | LFLAGS += -framework GLUT -framework OpenGL 37 | else 38 | CFLAGS += -I/usr/X11R6/include/GL -I/usr/include/GL 39 | LFLAGS += -L/usr/X11R6/lib -lGL -lGLU -lglut 40 | endif 41 | endif 42 | 43 | 44 | all: $(SOURCEDIR) $(TARGET) 45 | 46 | $(SOURCEDIR): 47 | @test -e $(Q3ZIP) || ( echo "please copy $(Q3ZIP) into this directory!" ; exit 1 ) 48 | unzip $(Q3ZIP) 49 | @echo "--------------------------------------------------------------------------" 50 | @echo " Source Package unpacked. Removing DOS CR/LF... " 51 | @echo "--------------------------------------------------------------------------" 52 | # leaving them as-is would cause troubles when patching... 53 | find $(SOURCEDIR) -iname "*.[hc]" -exec sh ./strip_cr.sh {} \; 54 | @echo "--------------------------------------------------------------------------" 55 | @echo " Patching... " 56 | @echo "--------------------------------------------------------------------------" 57 | patch -p0 < $(wildcard *.diff) 58 | @echo "--------------------------------------------------------------------------" 59 | @echo " Compiling... " 60 | @echo "--------------------------------------------------------------------------" 61 | @$(MAKE) 62 | 63 | $(TARGET): $(SOURCEDIR) $(OBJS) 64 | $(CC) -o $@ $(OBJS) $(LFLAGS) 65 | 66 | .c.o: 67 | @echo "compile: $<" 68 | @$(CC) $(CFLAGS) -c $< -o $@ 69 | 70 | clean: 71 | @echo "remove object, dependency files and built files..." 72 | @$(RM) $(OBJS) $(DEPS) $(TARGET) 73 | @echo "done." 74 | 75 | -include $(DEPS) dummy 76 | 77 | -------------------------------------------------------------------------------- /test-q3/demota/default.cfg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test-q3/filesvm_cgame.inc: -------------------------------------------------------------------------------- 1 | 2 | SRC_FILES += \ 3 | $(CODEDIR)/cgame/cg_consolecmds.c \ 4 | $(CODEDIR)/cgame/cg_draw.c \ 5 | $(CODEDIR)/cgame/cg_drawtools.c \ 6 | $(CODEDIR)/cgame/cg_effects.c \ 7 | $(CODEDIR)/cgame/cg_ents.c \ 8 | $(CODEDIR)/cgame/cg_event.c \ 9 | $(CODEDIR)/cgame/cg_info.c \ 10 | $(CODEDIR)/cgame/cg_localents.c \ 11 | $(CODEDIR)/cgame/cg_main.c \ 12 | $(CODEDIR)/cgame/cg_marks.c \ 13 | $(CODEDIR)/cgame/cg_particles.c \ 14 | $(CODEDIR)/cgame/cg_players.c \ 15 | $(CODEDIR)/cgame/cg_playerstate.c \ 16 | $(CODEDIR)/cgame/cg_predict.c \ 17 | $(CODEDIR)/cgame/cg_scoreboard.c \ 18 | $(CODEDIR)/cgame/cg_servercmds.c \ 19 | $(CODEDIR)/cgame/cg_snapshot.c \ 20 | $(CODEDIR)/cgame/cg_syscalls.c \ 21 | $(CODEDIR)/cgame/cg_view.c \ 22 | $(CODEDIR)/cgame/cg_weapons.c 23 | 24 | # not for classic Q3A, only for MISSIONPACK 25 | # $(CODEDIR)/cgame/cg_newdraw.c \ 26 | 27 | 28 | -------------------------------------------------------------------------------- /test-q3/filesvm_q3_ui.inc: -------------------------------------------------------------------------------- 1 | 2 | SRC_FILES += \ 3 | $(CODEDIR)/q3_ui/ui_addbots.c \ 4 | $(CODEDIR)/q3_ui/ui_atoms.c \ 5 | $(CODEDIR)/q3_ui/ui_cdkey.c \ 6 | $(CODEDIR)/q3_ui/ui_cinematics.c \ 7 | $(CODEDIR)/q3_ui/ui_confirm.c \ 8 | $(CODEDIR)/q3_ui/ui_connect.c \ 9 | $(CODEDIR)/q3_ui/ui_controls2.c \ 10 | $(CODEDIR)/q3_ui/ui_credits.c \ 11 | $(CODEDIR)/q3_ui/ui_demo2.c \ 12 | $(CODEDIR)/q3_ui/ui_display.c \ 13 | $(CODEDIR)/q3_ui/ui_gameinfo.c \ 14 | $(CODEDIR)/q3_ui/ui_ingame.c \ 15 | $(CODEDIR)/q3_ui/ui_loadconfig.c \ 16 | $(CODEDIR)/q3_ui/ui_login.c \ 17 | $(CODEDIR)/q3_ui/ui_main.c \ 18 | $(CODEDIR)/q3_ui/ui_menu.c \ 19 | $(CODEDIR)/q3_ui/ui_mfield.c \ 20 | $(CODEDIR)/q3_ui/ui_mods.c \ 21 | $(CODEDIR)/q3_ui/ui_network.c \ 22 | $(CODEDIR)/q3_ui/ui_options.c \ 23 | $(CODEDIR)/q3_ui/ui_playermodel.c \ 24 | $(CODEDIR)/q3_ui/ui_players.c \ 25 | $(CODEDIR)/q3_ui/ui_playersettings.c \ 26 | $(CODEDIR)/q3_ui/ui_preferences.c \ 27 | $(CODEDIR)/q3_ui/ui_qmenu.c \ 28 | $(CODEDIR)/q3_ui/ui_removebots.c \ 29 | $(CODEDIR)/q3_ui/ui_saveconfig.c \ 30 | $(CODEDIR)/q3_ui/ui_serverinfo.c \ 31 | $(CODEDIR)/q3_ui/ui_servers2.c \ 32 | $(CODEDIR)/q3_ui/ui_setup.c \ 33 | $(CODEDIR)/q3_ui/ui_sound.c \ 34 | $(CODEDIR)/q3_ui/ui_sparena.c \ 35 | $(CODEDIR)/q3_ui/ui_specifyleague.c \ 36 | $(CODEDIR)/q3_ui/ui_specifyserver.c \ 37 | $(CODEDIR)/q3_ui/ui_splevel.c \ 38 | $(CODEDIR)/q3_ui/ui_sppostgame.c \ 39 | $(CODEDIR)/q3_ui/ui_spreset.c \ 40 | $(CODEDIR)/q3_ui/ui_spskill.c \ 41 | $(CODEDIR)/q3_ui/ui_startserver.c \ 42 | $(CODEDIR)/q3_ui/ui_team.c \ 43 | $(CODEDIR)/q3_ui/ui_teamorders.c \ 44 | $(CODEDIR)/q3_ui/ui_video.c 45 | 46 | # XXX FIXME ?!? 47 | # $(CODEDIR)/q3_ui/ui_rankings.c \ 48 | # $(CODEDIR)/q3_ui/ui_rankstatus.c \ 49 | # $(CODEDIR)/q3_ui/ui_signup.c \ 50 | 51 | -------------------------------------------------------------------------------- /test-q3/filesvm_ui.inc: -------------------------------------------------------------------------------- 1 | 2 | SRC_FILES += \ 3 | $(CODEDIR)/ui/ui_atoms.c \ 4 | $(CODEDIR)/ui/ui_gameinfo.c \ 5 | $(CODEDIR)/ui/ui_main.c \ 6 | $(CODEDIR)/ui/ui_players.c \ 7 | $(CODEDIR)/ui/ui_shared.c \ 8 | $(CODEDIR)/ui/ui_syscalls.c \ 9 | $(CODEDIR)/ui/ui_util.c 10 | 11 | -------------------------------------------------------------------------------- /test-q3/generic/input.c: -------------------------------------------------------------------------------- 1 | /* 2 | =========================================================================== 3 | Copyright (C) 1999-2005 Id Software, Inc. 4 | 5 | This file is part of Quake III Arena source code. 6 | 7 | Quake III Arena source code is free software; you can redistribute it 8 | and/or modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2 of the License, 10 | or (at your option) any later version. 11 | 12 | Quake III Arena source code is distributed in the hope that it will be 13 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with Foobar; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | =========================================================================== 21 | */ 22 | #include "../quake3-1.32b/code/client/client.h" 23 | 24 | void IN_Init (void) 25 | { 26 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 27 | } 28 | 29 | 30 | void IN_Frame (void) 31 | { 32 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 33 | } 34 | 35 | 36 | void IN_Shutdown (void) 37 | { 38 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 39 | } 40 | 41 | 42 | void Sys_SendKeyEvents (void) 43 | { 44 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /test-q3/generic/net.c: -------------------------------------------------------------------------------- 1 | /* 2 | =========================================================================== 3 | Copyright (C) 1999-2005 Id Software, Inc. 4 | 5 | This file is part of Quake III Arena source code. 6 | 7 | Quake III Arena source code is free software; you can redistribute it 8 | and/or modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2 of the License, 10 | or (at your option) any later version. 11 | 12 | Quake III Arena source code is distributed in the hope that it will be 13 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with Foobar; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | =========================================================================== 21 | */ 22 | 23 | #include "../quake3-1.32b/code/game/q_shared.h" 24 | #include "../quake3-1.32b/code/qcommon/qcommon.h" 25 | 26 | 27 | qboolean Sys_StringToAdr (const char *s, netadr_t *a) 28 | { 29 | printf("%s (%d): %s\n", __FUNCTION__, __LINE__, s); 30 | return qfalse; 31 | } 32 | 33 | 34 | qboolean Sys_IsLANAddress (netadr_t adr) 35 | { 36 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 37 | return qfalse; 38 | } 39 | 40 | 41 | void Sys_ShowIP (void) 42 | { 43 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 44 | } 45 | 46 | 47 | void Sys_SendPacket (int length, const void *data, netadr_t to) 48 | { 49 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 50 | } 51 | 52 | /* Never called by the game logic, just the system event queing */ 53 | qboolean Sys_GetPacket (netadr_t *net_from, msg_t *net_message) 54 | { 55 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 56 | return qfalse; 57 | } 58 | 59 | 60 | void NET_Sleep (int msec) 61 | { 62 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 63 | } 64 | 65 | -------------------------------------------------------------------------------- /test-q3/generic/snddma.c: -------------------------------------------------------------------------------- 1 | /* 2 | =========================================================================== 3 | Copyright (C) 1999-2005 Id Software, Inc. 4 | 5 | This file is part of Quake III Arena source code. 6 | 7 | Quake III Arena source code is free software; you can redistribute it 8 | and/or modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2 of the License, 10 | or (at your option) any later version. 11 | 12 | Quake III Arena source code is distributed in the hope that it will be 13 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with Foobar; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | =========================================================================== 21 | */ 22 | 23 | #include "../quake3-1.32b/code/client/client.h" 24 | 25 | // snddma_null.c 26 | // all other sound mixing is portable 27 | 28 | qboolean SNDDMA_Init(void) 29 | { 30 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 31 | return qfalse; 32 | } 33 | 34 | int SNDDMA_GetDMAPos(void) 35 | { 36 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 37 | return 0; 38 | } 39 | 40 | void SNDDMA_Shutdown(void) 41 | { 42 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 43 | } 44 | 45 | void SNDDMA_BeginPainting (void) 46 | { 47 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 48 | } 49 | 50 | void SNDDMA_Submit(void) 51 | { 52 | printf("%s (%d):\n", __FUNCTION__, __LINE__); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /test-q3/strip_cr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "strip CR/LF: $1" 3 | sed -e "s/ //g" $1 > $1.bak && mv $1.bak $1 4 | 5 | -------------------------------------------------------------------------------- /test-vfpu/Makefile: -------------------------------------------------------------------------------- 1 | ARCH = psp- 2 | CC = $(ARCH)gcc 3 | PSP_INSTALL = ../tools/psp-install 4 | RM = rm -f 5 | 6 | TARGET = test-vfpu 7 | OBJS = main.o 8 | 9 | PSPPATH := $(shell psp-config --pspsdk-path) 10 | LIBS = -lpspdebug -lpspdisplay -lpspge -lpspsdk -lpspctrl -lm -lc -lpspuser -lpsputility -lpspkernel 11 | CFLAGS = -g -Wall -O2 -MD -I$(PSPPATH)/include 12 | LFLAGS = -g -Wall -O2 -DMODULE_NAME=$(TARGET) psp-setup.c -L$(PSPPATH)/lib $(LIBS) 13 | 14 | BUILDDATE = $(shell date "+%Y/%m/%d %k:%M:%S") 15 | 16 | 17 | all: $(TARGET) 18 | 19 | .c.o: 20 | $(CC) $(CFLAGS) -c $< 21 | 22 | $(TARGET): $(OBJS) psp-setup.c 23 | $(CC) $(OBJS) $(LFLAGS) -o $@ 24 | 25 | install: all 26 | $(PSP_INSTALL) $(TARGET) --eboot-title="$(TARGET) $(BUILDDATE)" 27 | 28 | clean: 29 | $(RM) $(TARGET) *.d *.o *.a *.elf *.sfo EBOOT.PBP 30 | 31 | -include $(wildcard *.d) dummy 32 | 33 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | ARCH = psp- 2 | CC = $(ARCH)gcc 3 | AS = $(ARCH)as 4 | SIZE = $(ARCH)size 5 | PSP_INSTALL = ../tools/psp-install 6 | RM = rm -f 7 | 8 | PSPPATH := $(shell psp-config --pspsdk-path) 9 | PSPGL_LFLAGS = -lglut -lGLU -lGL -lm -lc -lpsputility -lpspdebug -lpspge -lpspdisplay -lpspctrl -lpspsdk \ 10 | -lpspvfpu -lpspuser -lpspkernel -lpsprtc 11 | 12 | CFLAGS = -std=gnu99 -fsingle-precision-constant -g -Wall -O2 \ 13 | -MD -MF $(DEPDIR)/$(basename $@).d -I.. -I$(PSPPATH)/include 14 | LDFLAGS = -g -Wall -L.. -L$(PSPPATH)/lib 15 | 16 | TESTS=bezier copytex depthtest eglcube glut spots \ 17 | tex texsubimage varray vertexblend mipmaps viewports \ 18 | thrashalloc readdepth eglpbuffers texmat 19 | #TESTS+=idxtex 20 | 21 | BUILDDATE := $(shell date "+%Y/%m/%d %k:%M:%S") 22 | PSP_EBOOT_TITLE = $(TARGET) $(BUILDDATE) 23 | PSP_EBOOT_ICON = firefox.png 24 | PSP_EBOOT_ICON1 = NULL 25 | PSP_EBOOT_UNKPNG = NULL 26 | PSP_EBOOT_PIC1 = NULL 27 | PSP_EBOOT_SND0 = NULL 28 | PSP_EBOOT_PSAR = NULL 29 | 30 | DEPDIR = .deps 31 | PSPSDK := $(shell psp-config --pspsdk-path) 32 | 33 | all: $(DEPDIR) $(TESTS:%=%.elf) 34 | 35 | syms: $(TESTS:%=%.sym) 36 | 37 | %.sym: %.elf 38 | prxtool -y $< > $@ 39 | 40 | install: $(TESTS:%=install-%) 41 | 42 | -include install-settings 43 | 44 | install-%: %.elf 45 | while [ ! -d $(PSP_MOUNTDIR)/psp/game ]; do mount $(PSP_MOUNTDIR); sleep 1; done 46 | PSP_MOUNTDIR=$(PSP_MOUNTDIR) \ 47 | $(PSP_INSTALL) $(INSTALLFLAGS) $< \ 48 | --eboot-title="$* $(BUILDDATE)" --eboot-icon="firefox.png" 49 | umount $(PSP_MOUNTDIR) 50 | 51 | DXTTEX:=$(wildcard dxt3/*.dxt3) 52 | DXTOBJ:=$(DXTTEX:%.dxt3=%.o) 53 | 54 | bezier.elf: firefox.o 55 | copytex.elf: firefox.o 56 | eglcube.elf: logo.o 57 | idxtex.elf: firefox-mono.o textab.h $(DXTOBJ) 58 | spots.elf: firefox.o 59 | tex.elf: firefox.o 60 | texsubimage.elf: one.o two.o three.o four.o 61 | varray.elf: firefox.o 62 | viewports.elf: firefox.o 63 | mipmaps.elf: sky.o ground.o 64 | 65 | psp-setup-%.o: psp-setup.c 66 | $(CC) $(CFLAGS) -o $@ -c -DMODULE_NAME="$(patsubst psp-setup-%.o,%,$@)" psp-setup.c 67 | 68 | %.elf: %.o perfmeter.o screenshot.o psp-setup-%.o ../libGL.a ../libGLU.a ../libglut.a 69 | $(CC) -o $@ $(LDFLAGS) $(filter %.o,$^) -lpng -lz $(PSPGL_LFLAGS) 70 | 71 | %.sys: %-sys.o 72 | cc -o $@ $^ -lglut -lGL 73 | 74 | %.raw: %.png 75 | convert $< rgba:$@ 76 | 77 | %-mono.raw: %.png 78 | convert $< gray:$@ 79 | 80 | %.o: %.raw 81 | (sym=`echo $(notdir $*) | tr '-' '_'`; \ 82 | printf ".data\n.global $${sym}_start\n$${sym}_start:\n\t.incbin \"$<\"" | $(AS) -o $@) 83 | 84 | %.o: %.dxt3 85 | (sym=`echo $(notdir $*) | tr '-' '_'`; \ 86 | printf ".data\n.global $${sym}_start\n.global $${sym}_end\n$${sym}_start:\n\t.incbin \"$<\"\n$${sym}_end:\n" | $(AS) -o $@) 87 | 88 | textab.h: $(DXTTEX) Makefile 89 | (for i in $(DXTTEX); do b=`basename $$i .dxt3`; echo "extern unsigned char $${b}_start[], $${b}_end[];"; done; \ 90 | echo "static const struct { const unsigned char *start, *end; } dxt[] = {"; \ 91 | for i in $(DXTTEX); do b=`basename $$i .dxt3`; echo " { $${b}_start, $${b}_end },"; done; \ 92 | echo "};" )> $@ || rm -f $@ 93 | 94 | 95 | %.o: $(DEPDIR) %.c 96 | $(CC) $(CFLAGS) -c $*.c 97 | 98 | %-sys.o: %.c 99 | cc -g -DSYS -c -o $@ $< 100 | 101 | $(DEPDIR): 102 | mkdir $(DEPDIR) 103 | 104 | clean: 105 | $(RM) $(DEPDIR)/*.d *.o $(DXTOBJ) *.a *.elf *.sys *~ 106 | 107 | -include $(wildcard *.d) dummy 108 | 109 | -------------------------------------------------------------------------------- /tests/depthtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define GL_GLEXT_PROTOTYPES 3 | 4 | #include 5 | #include 6 | 7 | #include "glchk.h" 8 | 9 | 10 | static 11 | void reshape (int w, int h) 12 | { 13 | GLCHK(glViewport(0, 0, w, h)); 14 | GLCHK(glMatrixMode(GL_PROJECTION)); 15 | GLCHK(glLoadIdentity()); 16 | GLCHK(glOrtho(0, 1, 0, 1, -1, 1)); 17 | 18 | GLCHK(glMatrixMode(GL_MODELVIEW)); 19 | 20 | glutPostRedisplay(); 21 | } 22 | 23 | 24 | static 25 | void display (void) 26 | { 27 | GLCHK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); 28 | 29 | //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 30 | GLCHK(glShadeModel(GL_SMOOTH)); 31 | 32 | /* middle band */ 33 | glColor3f(1,1,0); 34 | glBegin(GL_TRIANGLE_FAN); 35 | glVertex3f(0,.25,0); 36 | glVertex3f(1,.25,0); 37 | glVertex3f(1,.75,0); 38 | glVertex3f(0,.75,0); 39 | glEnd(); 40 | 41 | /* top strip */ 42 | glBegin(GL_TRIANGLE_FAN); 43 | glVertex3f(0,.9,0); 44 | glVertex3f(1,.9,0); 45 | glVertex3f(1,1,0); 46 | glVertex3f(0,1,0); 47 | glEnd(); 48 | 49 | /* ramp */ 50 | glBegin(GL_TRIANGLE_FAN); 51 | glColor3f(0,0,0); 52 | glVertex3f(0,0,-1); /* near */ 53 | 54 | glColor3f(1,1,1); 55 | glVertex3f(1,0,1); /* far */ 56 | 57 | glVertex3f(1,.5,1); /* far */ 58 | 59 | glColor3f(0,0,0); 60 | glVertex3f(0,.5,-1); /* near */ 61 | 62 | glEnd(); 63 | 64 | glutSwapBuffers(); 65 | } 66 | 67 | 68 | static 69 | void keydown (unsigned char key, int x, int y) 70 | { 71 | switch (key) { 72 | case 'd': /* delta, triangle */ 73 | GLCHK(glDepthFunc(GL_GEQUAL)); 74 | break; 75 | case 'o': /* round */ 76 | GLCHK(glDisable(GL_DEPTH_TEST)); 77 | break; 78 | case 'q': /* square*/ 79 | break; 80 | case 'x': /* cross button */ 81 | exit(0); 82 | break; 83 | default: 84 | ; 85 | } 86 | 87 | glutPostRedisplay(); 88 | } 89 | 90 | 91 | static 92 | void keyup (unsigned char key, int x, int y) 93 | { 94 | switch (key) { 95 | case 'd': 96 | GLCHK(glDepthFunc(GL_LESS)); 97 | break; 98 | case 'o': 99 | GLCHK(glEnable(GL_DEPTH_TEST)); 100 | break; 101 | default: 102 | ; 103 | } 104 | 105 | glutPostRedisplay(); 106 | } 107 | 108 | static 109 | void joystick (unsigned int buttonMask, int x, int y, int z) 110 | { 111 | GLCHK(glClearColor(x * 1.0f/2000.0f + 0.5f, y * 1.0f/2000.0f + 0.5f, 1.0f, 1.0f)); 112 | glutPostRedisplay(); 113 | } 114 | 115 | 116 | int main(int argc, char* argv[]) 117 | { 118 | glutInit(&argc, argv); 119 | glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 120 | glutInitWindowSize(480, 272); 121 | glutJoystickFunc(joystick, 0); 122 | glutCreateWindow( __FILE__ ); 123 | glutKeyboardFunc(keydown); 124 | glutKeyboardUpFunc(keyup); 125 | glutReshapeFunc(reshape); 126 | glutDisplayFunc(display); 127 | 128 | GLCHK(glDepthFunc(GL_LESS)); 129 | GLCHK(glEnable(GL_DEPTH_TEST)); 130 | 131 | GLCHK(glDepthRange(1,0)); 132 | 133 | glutMainLoop(); 134 | 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /tests/firefox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pspdev/pspgl/de4260adf56d06516ec46018d404ca77e0b61748/tests/firefox.png -------------------------------------------------------------------------------- /tests/four.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pspdev/pspgl/de4260adf56d06516ec46018d404ca77e0b61748/tests/four.png -------------------------------------------------------------------------------- /tests/glchk.h: -------------------------------------------------------------------------------- 1 | #ifndef _glchk_h 2 | #define _glchk_h 3 | 4 | #ifndef SYS 5 | #define SYS 0 6 | #endif 7 | 8 | 9 | #if !SYS 10 | 11 | extern void __pspgl_log (const char *fmt, ...); 12 | 13 | /* disable verbose logging to "ms0:/pspgl.ge" */ 14 | #if LOGME 15 | #define psp_log(x...) __pspgl_log(x) 16 | #else 17 | #define psp_log(x...) do {} while (0) 18 | #endif 19 | 20 | /* enable GLerror logging to "ms0:/log.txt" */ 21 | #if 1 22 | #define EGLCHK(x) \ 23 | do { \ 24 | EGLint errcode; \ 25 | psp_log("%d: %s\n", __LINE__, # x ); \ 26 | x; \ 27 | errcode = eglGetError(); \ 28 | if (errcode != EGL_SUCCESS) { \ 29 | __pspgl_log("%s (%d): EGL error 0x%04x\n", \ 30 | __FUNCTION__, __LINE__, (unsigned int) errcode);\ 31 | } \ 32 | } while (0) 33 | 34 | #define GLCHK(x) \ 35 | do { \ 36 | GLint errcode; \ 37 | psp_log(#x "\n"); \ 38 | x; \ 39 | errcode = glGetError(); \ 40 | if (errcode != GL_NO_ERROR) { \ 41 | __pspgl_log("%s (%d): GL error 0x%04x\n", \ 42 | __FUNCTION__, __LINE__, (unsigned int) errcode);\ 43 | } \ 44 | } while (0) 45 | #else 46 | #define GLCHK(x) x 47 | #define EGLCHK(x) x 48 | #endif 49 | 50 | #else 51 | #include 52 | #if 1 53 | #define GLCHK(x) \ 54 | do { \ 55 | GLint errcode; \ 56 | x; \ 57 | errcode = glGetError(); \ 58 | if (errcode != GL_NO_ERROR) { \ 59 | printf("%s (%d): GL error 0x%04x\n", \ 60 | __FUNCTION__, __LINE__, (unsigned int) errcode);\ 61 | } \ 62 | } while (0) 63 | #else 64 | #define GLCHK(x) x 65 | #define EGLCHK(x) x 66 | #endif 67 | #define psp_log printf 68 | #endif 69 | 70 | void screenshot(const char *); 71 | 72 | #endif /* _glchk_h */ 73 | -------------------------------------------------------------------------------- /tests/glut.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "glchk.h" 5 | 6 | static 7 | void reshape (int w, int h) 8 | { 9 | GLCHK(glViewport(0, 0, w, h)); 10 | GLCHK(glMatrixMode(GL_PROJECTION)); 11 | GLCHK(glLoadIdentity()); 12 | GLCHK(glOrtho(-2, 2, -2, 2, -2, 2)); 13 | GLCHK(glMatrixMode(GL_MODELVIEW)); 14 | GLCHK(glLoadIdentity()); 15 | } 16 | 17 | 18 | static float delta = 1.0; 19 | 20 | static 21 | void display (void) 22 | { 23 | static GLfloat angle; 24 | angle += delta; 25 | 26 | GLCHK(glMatrixMode(GL_MODELVIEW)); 27 | GLCHK(glLoadIdentity()); 28 | //GLCHK(glTranslatef(0.0f, 0.0f, -2.5f)); 29 | // GLCHK(glRotatef(angle * 0.79f, 1.0f, 0.0f, 0.0f)); 30 | // GLCHK(glRotatef(angle * 0.98f, 0.0f, 1.0f, 0.0f)); 31 | GLCHK(glRotatef(angle * 1.32f, 0.0f, 0.0f, 1.0f)); 32 | 33 | GLCHK(glShadeModel(GL_SMOOTH)); 34 | 35 | GLCHK(glClear(GL_COLOR_BUFFER_BIT)); 36 | glBegin(GL_TRIANGLES); 37 | glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(1.0f, 0.0f, 0.0f); 38 | glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); 39 | glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 1.0f); 40 | GLCHK(glEnd()); 41 | glutSwapBuffers(); 42 | glutPostRedisplay(); 43 | } 44 | 45 | 46 | static 47 | void keydown (unsigned char key, int x, int y) 48 | { 49 | switch (key) { 50 | case 'd': /* delta, triangle */ 51 | break; 52 | case 'o': /* round */ 53 | delta = 0.0f; 54 | break; 55 | case 'q': /* square*/ 56 | break; 57 | case 'x': /* cross button */ 58 | exit(0); 59 | break; 60 | default: 61 | ; 62 | } 63 | } 64 | 65 | 66 | static 67 | void keyup (unsigned char key, int x, int y) 68 | { 69 | switch (key) { 70 | case 'o': 71 | delta = 1.0f; 72 | break; 73 | default: 74 | ; 75 | } 76 | } 77 | 78 | 79 | static 80 | void joystick (unsigned int buttonMask, int x, int y, int z) 81 | { 82 | GLCHK(glClearColor(x * 1.0f/2000.0f + 0.5f, y * 1.0f/2000.0f + 0.5f, 1.0f, 1.0f)); 83 | } 84 | 85 | 86 | int main(int argc, char* argv[]) 87 | { 88 | glutInit(&argc, argv); 89 | glutCreateWindow( __FILE__ ); 90 | glutKeyboardFunc(keydown); 91 | glutKeyboardUpFunc(keyup); 92 | glutJoystickFunc(joystick, 0); 93 | glutReshapeFunc(reshape); 94 | glutDisplayFunc(display); 95 | glutMainLoop(); 96 | return 0; 97 | } 98 | 99 | -------------------------------------------------------------------------------- /tests/ground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pspdev/pspgl/de4260adf56d06516ec46018d404ca77e0b61748/tests/ground.png -------------------------------------------------------------------------------- /tests/install-settings: -------------------------------------------------------------------------------- 1 | # Put your settings for psp-install here 2 | INSTALLFLAGS=--psp-revision=1.50 3 | #PSP_MOUNTDIR=/mnt/stick 4 | -------------------------------------------------------------------------------- /tests/logo.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pspdev/pspgl/de4260adf56d06516ec46018d404ca77e0b61748/tests/logo.raw -------------------------------------------------------------------------------- /tests/one.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pspdev/pspgl/de4260adf56d06516ec46018d404ca77e0b61748/tests/one.png -------------------------------------------------------------------------------- /tests/perfmeter.h: -------------------------------------------------------------------------------- 1 | #ifndef _PERFMETER_H 2 | #define _PERFMETER_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void pm_framestart(void); 9 | void pm_frameend(void); 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif /* _PERFMETER_H */ 16 | -------------------------------------------------------------------------------- /tests/psp-setup.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This file handles all the PSP-specific kernel setup and exit stuff. 3 | * 4 | * Is there some general interest for this file, so that we can place it 5 | * somewhere in the compiler toolchain include path? 6 | * 7 | * Usage: Simply add 8 | * -DMODULE_NAME="your-module-name" psp-setup.c 9 | * to the LFLAGS or LDFLAGS of your project, so that this file is 10 | * compiled in when gcc collects and links the final ELF binary. 11 | * 12 | * Options: 13 | * -DMODULE_NAME="name" -- set the name (default NONAME) 14 | * -DMODULE_ATTR=0 -- module attributes (default 0) 15 | * -DVERSION_MAJOR=1 -- version 1.x (default 1) 16 | * -DVERSION_MINOR=0 -- version x.0 (default 0) 17 | * 18 | * Note: The linker flags and library lists need to be placed after this 19 | * entry on the LFLAG or LDFLAGS command line, otherwise gcc won't 20 | * be able to to resolve all symbols. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #if !defined(MODULE_NAME) 27 | #define MODULE_NAME NONAME 28 | #endif 29 | 30 | 31 | #if !defined(MODULE_VERSION_MAJOR) 32 | #define MODULE_VERSION_MAJOR 1 33 | #endif 34 | 35 | 36 | #if !defined(MODULE_VERSION_MINOR) 37 | #define MODULE_VERSION_MINOR 0 38 | #endif 39 | 40 | 41 | #if !defined(MODULE_ATTR) 42 | #define MODULE_ATTR 0 43 | #endif 44 | 45 | 46 | #define __stringify(s) __tostring(s) 47 | #define __tostring(s) #s 48 | 49 | PSP_MODULE_INFO(__stringify(MODULE_NAME), MODULE_ATTR, MODULE_VERSION_MAJOR, MODULE_VERSION_MINOR); 50 | 51 | 52 | static 53 | int exit_callback (int arg1, int arg2, void *common) 54 | { 55 | sceKernelExitGame(); 56 | return 0; 57 | } 58 | 59 | 60 | static 61 | int update_thread (SceSize args, void *argp) 62 | { 63 | int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); 64 | sceKernelRegisterExitCallback(cbid); 65 | sceKernelSleepThreadCB(); 66 | return 0; 67 | } 68 | 69 | 70 | static void setup_callbacks (void) __attribute__((constructor)); 71 | static void setup_callbacks (void) 72 | { 73 | int id; 74 | 75 | if ((id = sceKernelCreateThread("update_thread", update_thread, 0x11, 0xFA0, 0, 0)) >= 0) 76 | sceKernelStartThread(id, 0, 0); 77 | } 78 | 79 | 80 | 81 | static void back_to_kernel (void) __attribute__((destructor)); 82 | static void back_to_kernel (void) 83 | { 84 | sceKernelExitGame(); 85 | } 86 | 87 | -------------------------------------------------------------------------------- /tests/screenshot.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define GL_GLEXT_PROTOTYPES 8 | #include 9 | 10 | static void writepng(FILE *fp, const unsigned char *image, int width, int height) 11 | { 12 | const unsigned char *rows[height]; 13 | png_structp png_ptr = NULL; 14 | png_infop info_ptr = NULL; 15 | int row; 16 | 17 | png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 18 | if (!png_ptr) 19 | return; 20 | info_ptr = png_create_info_struct(png_ptr); 21 | if (!info_ptr) 22 | goto out_free_write_struct; 23 | 24 | png_init_io(png_ptr, fp); 25 | png_set_IHDR(png_ptr, info_ptr, width, height, 26 | 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, 27 | PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 28 | 29 | for(row = 0; row < height; row++) 30 | rows[row] = &image[row * width * 4]; 31 | 32 | png_set_rows(png_ptr, info_ptr, (png_byte**)rows); 33 | png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); 34 | png_write_end(png_ptr, info_ptr); 35 | 36 | out_free_write_struct: 37 | png_destroy_write_struct(&png_ptr, (png_infopp)NULL); 38 | } 39 | 40 | void screenshot(const char *basename) 41 | { 42 | if (basename == NULL) 43 | basename = "screenshot"; 44 | char name[6 + strlen(basename) + 4 + 4 + 1]; 45 | int count = 0; 46 | FILE *fp = NULL; 47 | unsigned char *image; 48 | 49 | do { 50 | if (fp) 51 | fclose(fp); 52 | #if SYS 53 | sprintf(name, "%s%03d.png", basename, count++); 54 | #else 55 | sprintf(name, "ms0:/%s%03d.png", basename, count++); 56 | #endif 57 | fp = fopen(name, "rb"); 58 | } while(fp != NULL && count < 1000); 59 | 60 | if (count == 1000) { 61 | if (fp) 62 | fclose(fp); 63 | return; 64 | } 65 | 66 | fp = fopen(name, "wb"); 67 | if (fp == NULL) 68 | return; 69 | 70 | glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); 71 | glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE); 72 | glPixelStorei(GL_PACK_ALIGNMENT, 1); 73 | glPixelStorei(GL_PACK_ROW_LENGTH, 0); 74 | glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); 75 | 76 | //image = malloc(480*272*4); 77 | image = memalign(64, 480*272*4); 78 | glReadPixels(0,0, 480,272, GL_RGBA,GL_UNSIGNED_BYTE, image); 79 | 80 | glPopClientAttrib(); 81 | 82 | if (glGetError() != 0) 83 | goto out; 84 | 85 | writepng(fp, image, 480, 272); 86 | 87 | out: 88 | fclose(fp); 89 | free(image); 90 | } 91 | -------------------------------------------------------------------------------- /tests/sky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pspdev/pspgl/de4260adf56d06516ec46018d404ca77e0b61748/tests/sky.png -------------------------------------------------------------------------------- /tests/texsubimage.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "glchk.h" 5 | 6 | static 7 | void reshape (int w, int h) 8 | { 9 | GLCHK(glViewport(0, 0, w, h)); 10 | GLCHK(glMatrixMode(GL_PROJECTION)); 11 | GLCHK(glLoadIdentity()); 12 | GLCHK(glOrtho(-2*1.7, 2*1.7, 2, -2, -2, 2)); 13 | GLCHK(glMatrixMode(GL_MODELVIEW)); 14 | GLCHK(glLoadIdentity()); 15 | } 16 | 17 | 18 | static int freezecol = 0; 19 | 20 | extern unsigned char one_start[]; 21 | extern unsigned char two_start[]; 22 | extern unsigned char three_start[]; 23 | extern unsigned char four_start[]; 24 | 25 | static unsigned char *img[] = { 26 | one_start, 27 | two_start, 28 | three_start, 29 | four_start, 30 | }; 31 | 32 | static 33 | void display (void) 34 | { 35 | int i; 36 | 37 | GLCHK(glShadeModel(GL_SMOOTH)); 38 | 39 | GLCHK(glClear(GL_COLOR_BUFFER_BIT)); 40 | 41 | GLCHK(glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)); 42 | GLCHK(glEnable(GL_BLEND)); 43 | GLCHK(glEnable(GL_TEXTURE_2D)); 44 | GLCHK(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); 45 | 46 | GLCHK(glMatrixMode(GL_MODELVIEW)); 47 | GLCHK(glLoadIdentity()); 48 | GLCHK(glTranslatef(-2, 0, 0)); 49 | 50 | if (!freezecol) 51 | GLCHK(glColor3ub(rand(), rand(), rand())); 52 | 53 | glFlush(); 54 | for(i = 0; i < 4; i++) { 55 | GLCHK(glTexSubImage2D(GL_TEXTURE_2D, 0, 13*i, 13*i, 64, 64, GL_RGBA, GL_UNSIGNED_BYTE, img[i])); 56 | 57 | glBegin(GL_TRIANGLE_FAN); 58 | glTexCoord2f(0, 0); 59 | glVertex3f(0, 0, 0); 60 | 61 | glTexCoord2f(0, 1); 62 | glVertex3f(0, 1, 0); 63 | 64 | glTexCoord2f(1, 1); 65 | glVertex3f(1, 1, 0); 66 | 67 | glTexCoord2f(1, 0); 68 | glVertex3f(1, 0, 0); 69 | glEnd(); 70 | 71 | GLCHK(glTranslatef(1, 0, 0)); 72 | } 73 | 74 | #if SYS 75 | usleep(100000); 76 | #endif 77 | glutSwapBuffers(); 78 | glutPostRedisplay(); 79 | } 80 | 81 | 82 | static 83 | void keydown (unsigned char key, int x, int y) 84 | { 85 | switch (key) { 86 | case 'd': /* delta, triangle */ 87 | break; 88 | case 'o': /* round */ 89 | freezecol=1; 90 | break; 91 | case 'q': /* square*/ 92 | break; 93 | case 'x': /* cross button */ 94 | exit(0); 95 | break; 96 | default: 97 | ; 98 | } 99 | } 100 | 101 | 102 | static 103 | void keyup (unsigned char key, int x, int y) 104 | { 105 | switch (key) { 106 | case 'o': 107 | freezecol=0; 108 | break; 109 | default: 110 | ; 111 | } 112 | } 113 | 114 | 115 | static 116 | void joystick (unsigned int buttonMask, int x, int y, int z) 117 | { 118 | GLCHK(glClearColor(x * 1.0f/2000.0f + 0.5f, y * 1.0f/2000.0f + 0.5f, 1.0f, 1.0f)); 119 | } 120 | 121 | int main(int argc, char* argv[]) 122 | { 123 | unsigned int pix[128*128]; 124 | int i; 125 | 126 | glutInit(&argc, argv); 127 | 128 | #if SYS 129 | glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 130 | glutInitWindowSize(480, 272); 131 | #endif 132 | glutCreateWindow( __FILE__ ); 133 | glutKeyboardFunc(keydown); 134 | glutKeyboardUpFunc(keyup); 135 | glutJoystickFunc(joystick, 0); 136 | glutReshapeFunc(reshape); 137 | glutDisplayFunc(display); 138 | 139 | GLCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); 140 | GLCHK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); 141 | 142 | for(i = 0; i < 128*128; i++) 143 | pix[i] = rand(); 144 | GLCHK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix)); 145 | 146 | GLCHK(glEnable(GL_TEXTURE_2D)); 147 | 148 | glutMainLoop(); 149 | return 0; 150 | } 151 | -------------------------------------------------------------------------------- /tests/thrashalloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define LOGME 0 5 | 6 | #include "glchk.h" 7 | 8 | static 9 | void reshape (int w, int h) 10 | { 11 | GLCHK(glViewport(0, 0, w, h)); 12 | GLCHK(glMatrixMode(GL_PROJECTION)); 13 | GLCHK(glLoadIdentity()); 14 | GLCHK(glOrtho(-2, 2, -2, 2, -2, 2)); 15 | GLCHK(glMatrixMode(GL_MODELVIEW)); 16 | GLCHK(glLoadIdentity()); 17 | } 18 | 19 | 20 | static float delta = 1.0; 21 | 22 | #define NTEX 200 23 | GLuint tex[NTEX]; 24 | 25 | static void thrashtex() 26 | { 27 | int idx = rand() % NTEX; 28 | int w = rand() % 9; 29 | int h = rand() % 9; 30 | 31 | GLCHK(glBindTexture(GL_TEXTURE_2D, tex[idx])); 32 | 33 | psp_log("allocating %d: %dx%d\n", tex[idx], 1< 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "../guconsts.h" 11 | #include "../pspgl_misc.h" 12 | 13 | static int vram_id = -1; 14 | 15 | static inline 16 | uint32_t swap32 (uint32_t x) 17 | { 18 | return ((x >> 24) & 0x000000ff) | 19 | ((x >> 8) & 0x0000ff00) | 20 | ((x << 8) & 0x00ff0000) | 21 | ((x << 24) & 0xff000000); 22 | } 23 | 24 | static inline 25 | uint16_t swap16 (uint16_t x) 26 | { 27 | return ((x >> 8) & 0x00ff) | 28 | ((x << 8) & 0xff00); 29 | } 30 | 31 | 32 | #if __BYTE_ORDER == __BIG_ENDIAN 33 | #define be32_to_cpu(x) (x) 34 | #define le32_to_cpu(x) swap32(x) 35 | #define be16_to_cpu(x) (x) 36 | #define le16_to_cpu(x) swap16(x) 37 | #elif __BYTE_ORDER == __LITTLE_ENDIAN 38 | #define le32_to_cpu(x) (x) 39 | #define be32_to_cpu(x) swap32(x) 40 | #define le16_to_cpu(x) (x) 41 | #define be16_to_cpu(x) swap16(x) 42 | #else 43 | #error unknown endianess!! 44 | #endif 45 | 46 | static void showsurf(const char *surf, struct pspgl_dump_surf *s) 47 | { 48 | unsigned start = le32_to_cpu(s->start); 49 | unsigned size = le32_to_cpu(s->size); 50 | unsigned stride = le32_to_cpu(s->stride); 51 | 52 | fprintf(stderr, " %s offset %d size %d stride %d\n", 53 | surf, start, size, stride); 54 | } 55 | 56 | static 57 | void process_chunk (uint32_t tag, uint32_t *buf, unsigned long len) 58 | { 59 | static int vram_dump_id = 0; 60 | 61 | fprintf(stderr, "\ngot chunk (tag 0x%08x, len %lu bytes)\n", tag, len); 62 | 63 | switch (tag) { 64 | struct pspgl_dump_surfaces *s; 65 | 66 | case PSPGL_GE_DUMP_SURFACES: 67 | s = (struct pspgl_dump_surfaces *)(buf + 2); 68 | 69 | fprintf(stderr, " pixfmt=%d\n", le32_to_cpu(s->pixfmt)); 70 | fprintf(stderr, " alpha mask=%x, stencil mask=%x\n\n", 71 | le32_to_cpu(s->alpha_mask), le32_to_cpu(s->stencil_mask)); 72 | showsurf("front", &s->front); 73 | showsurf("back", &s->back); 74 | showsurf("depth", &s->depth); 75 | break; 76 | 77 | case PSPGL_GE_DUMP_VRAM: 78 | if (vram_dump_id++ == vram_id) { 79 | uint32_t vram_start = buf[0]; 80 | uint32_t vram_size = buf[1]; 81 | 82 | write(1, buf+2, vram_size); 83 | } 84 | break; 85 | } 86 | } 87 | 88 | 89 | int main (int argc, char **argv) 90 | { 91 | unsigned long flen, fpos; 92 | uint32_t *fptr; 93 | int fd; 94 | 95 | if (argc != 3) { 96 | fprintf(stderr, "\n\tusage: %s vram-id\n\n", argv[0]); 97 | return 1; 98 | } 99 | 100 | if (isatty(1)) { 101 | fprintf(stderr, "Direct output to a file/pipe\n"); 102 | return 1; 103 | } 104 | 105 | vram_id = atoi(argv[2]); 106 | 107 | fd = open(argv[1], O_RDONLY, 0); 108 | flen = lseek(fd, 0, SEEK_END); 109 | lseek(fd, 0, SEEK_SET); 110 | fptr = (uint32_t*) mmap(NULL, flen, PROT_READ, MAP_PRIVATE, fd, 0); 111 | 112 | fpos = 0; 113 | flen /= 4; 114 | 115 | while (fpos flen) { 120 | fprintf(stderr, "**** unexpected end of file! ****\n"); 121 | break; 122 | } 123 | 124 | if (len == 0) 125 | break; 126 | 127 | process_chunk(tag, &fptr[fpos+2], len-2*4); 128 | fpos += len/4; 129 | } 130 | 131 | munmap((void*) fptr, flen); 132 | close(fd); 133 | 134 | return 0; 135 | } 136 | -------------------------------------------------------------------------------- /tools/half.c: -------------------------------------------------------------------------------- 1 | 2 | main() 3 | { 4 | char b[2]; 5 | 6 | while(read(0, b, 2) == 2) 7 | write(1, b+1, 1); 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /tools/swog.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* 8 | 0 -> 0 9 | 16 -> 32 10 | 32 -> 64 11 | 48 -> 96... 12 | 13 | 256 -> 16 14 | 15 | 16 | 8 7 6 5 4 3 2 1 0 17 | 18 | vvvvvvvvvvvvvvvvv 19 | 20 | 7 6 5 4 9 3 2 1 0 21 | */ 22 | 23 | unsigned swoz(unsigned x) 24 | { 25 | return ((x & 0x100) >> 4) | ((x & 0xf0) << 1) | x & 0xf; 26 | } 27 | 28 | 29 | int main(int argc, char **argv) 30 | { 31 | int x, y; 32 | int in = open(argv[1], O_RDONLY); 33 | int out = open(argv[2], O_RDWR | O_TRUNC | O_CREAT, 0660); 34 | unsigned size; 35 | const unsigned char *p; 36 | unsigned char *dest; 37 | 38 | if (in == -1) { 39 | perror(argv[1]); 40 | return 1; 41 | } 42 | if (out == -1) { 43 | perror(argv[2]); 44 | return 1; 45 | } 46 | 47 | size = lseek(in, 0, SEEK_END); 48 | p = mmap(0, size, PROT_READ, MAP_PRIVATE, in, 0); 49 | if (ftruncate(out, size) == -1) { 50 | perror("ftruncate"); 51 | return 1; 52 | } 53 | dest = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, out, 0); 54 | 55 | 56 | for(y = 0; y < size/512; y++) { 57 | for(x = 0; x < 512; x += 16) 58 | memcpy(&dest[y * 512 + (x)], &p[y * 512 + swoz(x)], 16); 59 | } 60 | close(in); 61 | close(out); 62 | return 0; 63 | } 64 | 65 | --------------------------------------------------------------------------------