/* Copyright (C) 2006-2007 Mark Olsen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #define SYSTEM_PRIVATE #include #include #include #include #include #include #include #include #include #include #include "quakedef.h" #include "glquake.h" #include "gl_vidtinyglstubs.c" #define WARP_WIDTH 320 #define WARP_HEIGHT 200 extern qboolean gammaworks; extern unsigned short ramps[3][256]; struct Library *TinyGLBase = 0; GLContext *__tglContext; static int glctx = 0; unsigned char *mosgammatable; struct Window *window; struct Screen *screen; static void *pointermem; static int real_width, real_height; static void *TinyGL_GetSymbol(char *name) { void *ret = 0; if (strcmp(name, "glAlphaFunc") == 0) ret = stub_glAlphaFunc; else if (strcmp(name, "glBegin") == 0) ret = stub_glBegin; else if (strcmp(name, "glBlendFunc") == 0) ret = stub_glBlendFunc; else if (strcmp(name, "glBindTexture") == 0) ret = stub_glBindTexture; else if (strcmp(name, "glClear") == 0) ret = stub_glClear; else if (strcmp(name, "glClearColor") == 0) ret = stub_glClearColor; else if (strcmp(name, "glClearDepth") == 0) ret = stub_glClearDepth; else if (strcmp(name, "glClearStencil") == 0) ret = stub_glClearStencil; else if (strcmp(name, "glColor3f") == 0) ret = stub_glColor3f; else if (strcmp(name, "glColor3ub") == 0) ret = stub_glColor3ub; else if (strcmp(name, "glColor4f") == 0) ret = stub_glColor4f; else if (strcmp(name, "glColor4fv") == 0) ret = stub_glColor4fv; else if (strcmp(name, "glColor4ub") == 0) ret = stub_glColor4ub; else if (strcmp(name, "glColor4ubv") == 0) ret = stub_glColor4ubv; else if (strcmp(name, "glColorMask") == 0) ret = stub_glColorMask; else if (strcmp(name, "glCopyTexImage2D") == 0) ret = stub_glCopyTexImage2D; else if (strcmp(name, "glCopyTexSubImage2D") == 0) ret = stub_glCopyTexSubImage2D; else if (strcmp(name, "glCullFace") == 0) ret = stub_glCullFace; else if (strcmp(name, "glDepthFunc") == 0) ret = stub_glDepthFunc; else if (strcmp(name, "glDepthMask") == 0) ret = stub_glDepthMask; else if (strcmp(name, "glDepthRange") == 0) ret = stub_glDepthRange; else if (strcmp(name, "glDisable") == 0) ret = stub_glDisable; else if (strcmp(name, "glDrawBuffer") == 0) ret = stub_glDrawBuffer; else if (strcmp(name, "glDrawPixels") == 0) ret = stub_glDrawPixels; else if (strcmp(name, "glEnable") == 0) ret = stub_glEnable; else if (strcmp(name, "glEnd") == 0) ret = stub_glEnd; else if (strcmp(name, "glFinish") == 0) ret = stub_glFinish; else if (strcmp(name, "glFlush") == 0) ret = stub_glFlush; else if (strcmp(name, "glFrustum") == 0) ret = stub_glFrustum; else if (strcmp(name, "glGetFloatv") == 0) ret = stub_glGetFloatv; else if (strcmp(name, "glGetIntegerv") == 0) ret = stub_glGetIntegerv; else if (strcmp(name, "glGetString") == 0) ret = stub_glGetString; else if (strcmp(name, "glGetTexLevelParameteriv") == 0) ret = stub_glGetTexLevelParameteriv; else if (strcmp(name, "glHint") == 0) ret = stub_glHint; else if (strcmp(name, "glLoadIdentity") == 0) ret = stub_glLoadIdentity; else if (strcmp(name, "glLoadMatrixf") == 0) ret = stub_glLoadMatrixf; else if (strcmp(name, "glNormal3f") == 0) ret = stub_glNormal3f; else if (strcmp(name, "glNormal3fv") == 0) ret = stub_glNormal3fv; else if (strcmp(name, "glMatrixMode") == 0) ret = stub_glMatrixMode; else if (strcmp(name, "glMultMatrixf") == 0) ret = stub_glMultMatrixf; else if (strcmp(name, "glOrtho") == 0) ret = stub_glOrtho; else if (strcmp(name, "glPolygonMode") == 0) ret = stub_glPolygonMode; else if (strcmp(name, "glPopMatrix") == 0) ret = stub_glPopMatrix; else if (strcmp(name, "glPushMatrix") == 0) ret = stub_glPushMatrix; else if (strcmp(name, "glReadBuffer") == 0) ret = stub_glReadBuffer; else if (strcmp(name, "glReadPixels") == 0) ret = stub_glReadPixels; else if (strcmp(name, "glRotatef") == 0) ret = stub_glRotatef; else if (strcmp(name, "glScalef") == 0) ret = stub_glScalef; else if (strcmp(name, "glShadeModel") == 0) ret = stub_glShadeModel; else if (strcmp(name, "glTexCoord1f") == 0) ret = stub_glTexCoord1f; else if (strcmp(name, "glTexCoord2f") == 0) ret = stub_glTexCoord2f; else if (strcmp(name, "glTexCoord2fv") == 0) ret = stub_glTexCoord2fv; else if (strcmp(name, "glTexEnvf") == 0) ret = stub_glTexEnvf; else if (strcmp(name, "glTexEnvfv") == 0) ret = stub_glTexEnvfv; else if (strcmp(name, "glTexEnvi") == 0) ret = stub_glTexEnvi; else if (strcmp(name, "glTexGeni") == 0) ret = stub_glTexGeni; else if (strcmp(name, "glTexImage2D") == 0) ret = stub_glTexImage2D; else if (strcmp(name, "glTexParameteri") == 0) ret = stub_glTexParameteri; else if (strcmp(name, "glTexParameterf") == 0) ret = stub_glTexParameterf; else if (strcmp(name, "glTexSubImage2D") == 0) ret = stub_glTexSubImage2D; else if (strcmp(name, "glTranslatef") == 0) ret = stub_glTranslatef; else if (strcmp(name, "glVertex2f") == 0) ret = stub_glVertex2f; else if (strcmp(name, "glVertex3f") == 0) ret = stub_glVertex3f; else if (strcmp(name, "glVertex3fv") == 0) ret = stub_glVertex3fv; else if (strcmp(name, "glViewport") == 0) ret = stub_glViewport; else if (strcmp(name, "glGetError") == 0) ret = stub_glGetError; else if (strcmp(name, "glDrawElements") == 0) ret = stub_glDrawElements; else if (strcmp(name, "glArrayElement") == 0) ret = stub_glArrayElement; else if (strcmp(name, "glVertexPointer") == 0) ret = stub_glVertexPointer; else if (strcmp(name, "glNormalPointer") == 0) ret = stub_glNormalPointer; else if (strcmp(name, "glTexCoordPointer") == 0) ret = stub_glTexCoordPointer; else if (strcmp(name, "glColorPointer") == 0) ret = stub_glColorPointer; else if (strcmp(name, "glDrawArrays") == 0) ret = stub_glDrawArrays; else if (strcmp(name, "glEnableClientState") == 0) ret = stub_glEnableClientState; else if (strcmp(name, "glDisableClientState") == 0) ret = stub_glDisableClientState; else if (strcmp(name, "glStencilOp") == 0) ret = stub_glStencilOp; else if (strcmp(name, "glStencilFunc") == 0) ret = stub_glStencilFunc; else if (strcmp(name, "glPushAttrib") == 0) ret = stub_glPushAttrib; else if (strcmp(name, "glPopAttrib") == 0) ret = stub_glPopAttrib; else if (strcmp(name, "glScissor") == 0) ret = stub_glScissor; else if (strcmp(name, "glMultiTexCoord2fARB") == 0) ret = stub_glMultiTexCoord2fARB; else if (strcmp(name, "glMultiTexCoord3fARB") == 0) ret = stub_glMultiTexCoord3fARB; else if (strcmp(name, "glActiveTextureARB") == 0) ret = stub_glActiveTextureARB; else if (strcmp(name, "glClientActiveTextureARB") == 0) ret = stub_glClientActiveTextureARB; else printf("Function \"%s\" not found\n", name); return ret; } qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) { int argnum; int r; int i; int depth = 24; struct TagItem tgltags[] = { { 0, 0 }, { TGL_CONTEXT_STENCIL, TRUE }, { TAG_DONE } }; if (IntuitionBase->LibNode.lib_Version > 50 || (IntuitionBase->LibNode.lib_Version == 50 && IntuitionBase->LibNode.lib_Revision >= 74)) { mosgammatable = AllocVec(256*3, MEMF_ANY); if (mosgammatable) gammaworks = 1; } vid.width = info->width; vid.height = info->height; vid.maxwarpwidth = WARP_WIDTH; vid.maxwarpheight = WARP_HEIGHT; vid.numpages = 3; vid.colormap = host_colormap; if (vid.width <= 640) { vid.conwidth = vid.width; vid.conheight = vid.height; } else { vid.conwidth = vid.width/2; vid.conheight = vid.height/2; } if ((i = COM_CheckParm("-conwidth")) && i + 1 < com_argc) { vid.conwidth = Q_atoi(com_argv[i + 1]); // pick a conheight that matches with correct aspect vid.conheight = vid.conwidth * 3 / 4; } vid.conwidth &= 0xfff8; // make it a multiple of eight if ((i = COM_CheckParm("-conheight")) && i + 1 < com_argc) vid.conheight = Q_atoi(com_argv[i + 1]); if (vid.conwidth < 320) vid.conwidth = 320; if (vid.conheight < 200) vid.conheight = 200; TinyGLBase = OpenLibrary("tinygl.library", 0); if (TinyGLBase) { if (TinyGLBase->lib_Version > 50 || (TinyGLBase->lib_Version == 50 && TinyGLBase->lib_Revision >= 9)) { vid.rowbytes = vid.width; vid.direct = 0; /* Isn't used anywhere, but whatever. */ vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); if (info->fullscreen) { screen = OpenScreenTags(0, SA_Width, vid.width, SA_Height, vid.height, SA_Depth, depth, SA_Quiet, TRUE, SA_GammaControl, TRUE, SA_3DSupport, TRUE, TAG_DONE); } window = OpenWindowTags(0, WA_InnerWidth, vid.width, WA_InnerHeight, vid.height, WA_Title, "FTEQuake", WA_DragBar, screen?FALSE:TRUE, WA_DepthGadget, screen?FALSE:TRUE, WA_Borderless, screen?TRUE:FALSE, WA_RMBTrap, TRUE, screen?WA_PubScreen:TAG_IGNORE, (ULONG)screen, WA_Activate, TRUE, TAG_DONE); if (window) { if (screen == 0) gammaworks = 0; __tglContext = GLInit(); if (__tglContext) { if (screen) { tgltags[0].ti_Tag = TGL_CONTEXT_SCREEN; tgltags[0].ti_Data = screen; } else { tgltags[0].ti_Tag = TGL_CONTEXT_WINDOW; tgltags[0].ti_Data = window; } r = GLAInitializeContext(__tglContext, tgltags); if (r) { glctx = 1; gl_canstencil = 8; pointermem = AllocVec(256, MEMF_ANY|MEMF_CLEAR); if (pointermem) { SetPointer(window, pointermem, 16, 16, 0, 0); #if 0 lastwindowedmouse = 1; #endif real_width = vid.width; real_height = vid.height; if (vid.conheight > vid.height) vid.conheight = vid.height; if (vid.conwidth > vid.width) vid.conwidth = vid.width; vid.width = vid.conwidth; vid.height = vid.conheight; GL_Init(&TinyGL_GetSymbol); VID_SetPalette(palette); vid.recalc_refdef = 1; return true; } else { Con_Printf("Unable to allocate memory for mouse pointer"); } if (screen && !(TinyGLBase->lib_Version == 0 && TinyGLBase->lib_Revision < 4)) { glADestroyContextScreen(); } else { glADestroyContextWindowed(); } glctx = 0; } else { Con_Printf("Unable to initialize GL context"); } GLClose(__tglContext); __tglContext = 0; } else { Con_Printf("Unable to create GL context"); } if (screen) { CloseScreen(screen); screen = 0; } CloseWindow(window); window = 0; } else { Con_Printf("Unable to open window"); } } CloseLibrary(TinyGLBase); TinyGLBase = 0; } else { Con_Printf("Couldn't open tinygl.library"); } return false; } void GLVID_DeInit() { printf("1\n"); if (glctx) { if (screen && !(TinyGLBase->lib_Version == 0 && TinyGLBase->lib_Revision < 4)) { glADestroyContextScreen(); } else { glADestroyContextWindowed(); } glctx = 0; } printf("2\n"); if (__tglContext) { GLClose(__tglContext); __tglContext = 0; } if (window) { CloseWindow(window); window = 0; } if (pointermem) { FreeVec(pointermem); pointermem = 0; } if (screen) { CloseScreen(screen); screen = 0; } if (TinyGLBase) { CloseLibrary(TinyGLBase); TinyGLBase = 0; } if (mosgammatable) { FreeVec(mosgammatable); mosgammatable = 0; } } void GL_BeginRendering (int *x, int *y, int *width, int *height) { *x = *y = 0; *width = real_width; *height = real_height; } void GL_EndRendering (void) { glASwapBuffers(); } void GL_DoSwap(void) { } void GLVID_SetPalette (unsigned char *palette) { qbyte *pal; unsigned int r,g,b; int i; unsigned *table1; unsigned *table2; extern qbyte gammatable[256]; Con_Printf("Converting 8to24\n"); pal = palette; table1 = d_8to24rgbtable; table2 = d_8to24bgrtable; for (i=0 ; i<256 ; i++) { r = gammatable[pal[0]]; g = gammatable[pal[1]]; b = gammatable[pal[2]]; pal += 3; *table1++ = LittleLong((255<<24) + (r<<0) + (g<<8) + (b<<16)); *table2++ = LittleLong((255<<24) + (r<<16) + (g<<8) + (b<<0)); } d_8to24bgrtable[255] &= LittleLong(0xffffff); // 255 is transparent d_8to24rgbtable[255] &= LittleLong(0xffffff); // 255 is transparent } void GLVID_ShiftPalette (unsigned char *palette) { int i; if (gammaworks) { for(i=0;i<768;i++) { mosgammatable[i] = ramps[0][i]>>8; } SetAttrs(screen, SA_GammaRed, mosgammatable, SA_GammaGreen, mosgammatable+256, SA_GammaBlue, mosgammatable+512, TAG_DONE); } } void GLD_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height) { } void GLD_EndDirectRect (int x, int y, int width, int height) { } void GLVID_UnlockBuffer() { } void GLVID_LockBuffer() { } int GLVID_ForceUnlockedAndReturnState (void) { return 0; } void GLVID_ForceLockState (int lk) { } void GLVID_HandlePause (qboolean pause) { } void Sys_SendKeyEvents(void) { } void GLVID_SetCaption(char *caption) { SetWindowTitles(window, caption, (void *)-1); }