
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <nt.h>
#include <ntrtl.h>

#include <nturtl.h>
#include <windows.h>
#include <winddi.h>

#include <ksmips.h>
#include "glteb.h"
#include <GL/gl.h>
#include <gldrv.h>

/***************************************************
 *                                                 *
 *  Client API generator for MIPS (capimips)       *
 *                                                 *
 ***************************************************/

/*
 *  from /nt/private/windows/gdi/opengl/inc/glteb.h:
 *
 *      #define GLTEB_CLTDISPATCHTABLE
 *          ((PGLDISPATCHTABLE)(NtCurrentTeb()->glDispatchTable))
 *
 *  from /nt/public/sdk/inc/ntmips.h:#define NtCurrentTeb() ((PTEB)(PCR->Teb))
 *
 *      #define NtCurrentTeb() ((PTEB)(USER_PCR->Teb))
 *
 *  Define Address of Processor Control Registers.
 *
 *      #define USPCR 0x7ffff000            // user address of PCR
 *
 *  Define Pointer to Processor Control Registers.
 *
 *      #define USER_PCR ((KPCR * const)USPCR)
 *
 */

/*
 *  The compiler generated the the following code:
 *
 *  glNewList:
 *    00000000: 27BDFFE8 addiu       sp,sp,FFE8
 *    00000004: AFBF0014 sw          ra,0014(sp)
 *    00000008: 3C0E8000 lui         t6,8000
 *    0000000C: 8DCFF4A8 lw          t7,F4A8(t6)
 *    00000010: 8DF80714 lw          t8,0714(t7)
 *    00000014: 0300F809 jalr        ra,t8
 *    00000018: 00000000 nop
 *    0000001C: 8FBF0014 lw          ra,0014(sp)
 *    00000020: 03E00008 jr          ra
 *    00000024: 27BD0018 addiu       sp,sp,0018
 *    00000028: 00000000 nop
 *    0000002C: 00000000 nop
 *
 *  glMap2d:
 *    00000000: 27BDFFB8 addiu       sp,sp,FFB8
 *    00000004: AFBF0044 sw          ra,0044(sp)
 *    00000008: 44866000 mtc1        a2,$12
 *    0000000C: 44876800 mtc1        a3,$13
 *    00000010: 00000000 nop
 *    00000014: D7A40058 ldc1        $4,0058(sp)
 *    00000018: 3C098000 lui         t1,8000
 *    0000001C: 8FAE0060 lw          t6,0060(sp)
 *    00000020: 8FAF0064 lw          t7,0064(sp)
 *    00000024: D7A60068 ldc1        $6,0068(sp)
 *    00000028: D7A80070 ldc1        $8,0070(sp)
 *    0000002C: 8FB80078 lw          t8,0078(sp)
 *    00000030: 8FB9007C lw          t9,007C(sp)
 *    00000034: 8FA80080 lw          t0,0080(sp)
 *    00000038: F7A40010 sdc1        $4,0010(sp)
 *    0000003C: AFAE0018 sw          t6,0018(sp)
 *    00000040: AFAF001C sw          t7,001C(sp)
 *    00000044: F7A60020 sdc1        $6,0020(sp)
 *    00000048: F7A80028 sdc1        $8,0028(sp)
 *    0000004C: AFB80030 sw          t8,0030(sp)
 *    00000050: AFB90034 sw          t9,0034(sp)
 *    00000054: AFA80038 sw          t0,0038(sp)
 *    00000058: 8D2AF4A8 lw          t2,F4A8(t1)
 *    0000005C: 44066000 mfc1        a2,$12
 *    00000060: 44076800 mfc1        a3,$13
 *    00000064: 8D4B0A8C lw          t3,0A8C(t2)
 *    00000068: 0160F809 jalr        ra,t3
 *    0000006C: 00000000 nop
 *    00000070: 8FBF0044 lw          ra,0044(sp)
 *    00000074: 03E00008 jr          ra
 *    00000078: 27BD0048 addiu       sp,sp,0048
 *    0000007C: 00000000 nop
 *
 *  Summary:
 *
 *      C Version:                  Assembly version:
 *
 *      A0F0 .debug$S                 5C .debug$S
 *      425C .debug$T
 *      17E8 .pdata
 *      3ED0 .text                  17F0 .text
 */

#define PAGE_AFTER_LAST         0x80000000
#define OFFSET_FROM_PAGE        (PAGE_AFTER_LAST - (size_t)USER_PCR)
#define ADD_DEBUG_FORMATION
#define JUSTDOIT(x)                 Do( #x, offsetof(GLDISPATCHTABLE, x))

void Do( char *Func, size_t Fo );
void PrintEntryMacro( void );

void
main ( int argc, char **argv )
{
    printf("\n");
    printf("//////////////////////////////////////////////////////////\n");
    printf("//     This file was generated by %s\n", *argv);
    printf("//             DO NOT MODIFY\n");
    printf("//////////////////////////////////////////////////////////\n");
    printf("\n");
    printf("#include \"ksmips.h\"\n\n");

    PrintEntryMacro();

    JUSTDOIT( glNewList                 );
    JUSTDOIT( glEndList                 );
    JUSTDOIT( glCallList                );
    JUSTDOIT( glCallLists               );
    JUSTDOIT( glDeleteLists             );
    JUSTDOIT( glGenLists                );
    JUSTDOIT( glListBase                );
    JUSTDOIT( glBegin                   );
    JUSTDOIT( glBitmap                  );
    JUSTDOIT( glColor3b                 );
    JUSTDOIT( glColor3bv                );
    JUSTDOIT( glColor3d                 );
    JUSTDOIT( glColor3dv                );
    JUSTDOIT( glColor3f                 );
    JUSTDOIT( glColor3fv                );
    JUSTDOIT( glColor3i                 );
    JUSTDOIT( glColor3iv                );
    JUSTDOIT( glColor3s                 );
    JUSTDOIT( glColor3sv                );
    JUSTDOIT( glColor3ub                );
    JUSTDOIT( glColor3ubv               );
    JUSTDOIT( glColor3ui                );
    JUSTDOIT( glColor3uiv               );
    JUSTDOIT( glColor3us                );
    JUSTDOIT( glColor3usv               );
    JUSTDOIT( glColor4b                 );
    JUSTDOIT( glColor4bv                );
    JUSTDOIT( glColor4d                 );
    JUSTDOIT( glColor4dv                );
    JUSTDOIT( glColor4f                 );
    JUSTDOIT( glColor4fv                );
    JUSTDOIT( glColor4i                 );
    JUSTDOIT( glColor4iv                );
    JUSTDOIT( glColor4s                 );
    JUSTDOIT( glColor4sv                );
    JUSTDOIT( glColor4ub                );
    JUSTDOIT( glColor4ubv               );
    JUSTDOIT( glColor4ui                );
    JUSTDOIT( glColor4uiv               );
    JUSTDOIT( glColor4us                );
    JUSTDOIT( glColor4usv               );
    JUSTDOIT( glEdgeFlag                );
    JUSTDOIT( glEdgeFlagv               );
    JUSTDOIT( glEnd                     );
    JUSTDOIT( glIndexd                  );
    JUSTDOIT( glIndexdv                 );
    JUSTDOIT( glIndexf                  );
    JUSTDOIT( glIndexfv                 );
    JUSTDOIT( glIndexi                  );
    JUSTDOIT( glIndexiv                 );
    JUSTDOIT( glIndexs                  );
    JUSTDOIT( glIndexsv                 );
    JUSTDOIT( glNormal3b                );
    JUSTDOIT( glNormal3bv               );
    JUSTDOIT( glNormal3d                );
    JUSTDOIT( glNormal3dv               );
    JUSTDOIT( glNormal3f                );
    JUSTDOIT( glNormal3fv               );
    JUSTDOIT( glNormal3i                );
    JUSTDOIT( glNormal3iv               );
    JUSTDOIT( glNormal3s                );
    JUSTDOIT( glNormal3sv               );
    JUSTDOIT( glRasterPos2d             );
    JUSTDOIT( glRasterPos2dv            );
    JUSTDOIT( glRasterPos2f             );
    JUSTDOIT( glRasterPos2fv            );
    JUSTDOIT( glRasterPos2i             );
    JUSTDOIT( glRasterPos2iv            );
    JUSTDOIT( glRasterPos2s             );
    JUSTDOIT( glRasterPos2sv            );
    JUSTDOIT( glRasterPos3d             );
    JUSTDOIT( glRasterPos3dv            );
    JUSTDOIT( glRasterPos3f             );
    JUSTDOIT( glRasterPos3fv            );
    JUSTDOIT( glRasterPos3i             );
    JUSTDOIT( glRasterPos3iv            );
    JUSTDOIT( glRasterPos3s             );
    JUSTDOIT( glRasterPos3sv            );
    JUSTDOIT( glRasterPos4d             );
    JUSTDOIT( glRasterPos4dv            );
    JUSTDOIT( glRasterPos4f             );
    JUSTDOIT( glRasterPos4fv            );
    JUSTDOIT( glRasterPos4i             );
    JUSTDOIT( glRasterPos4iv            );
    JUSTDOIT( glRasterPos4s             );
    JUSTDOIT( glRasterPos4sv            );
    JUSTDOIT( glRectd                   );
    JUSTDOIT( glRectdv                  );
    JUSTDOIT( glRectf                   );
    JUSTDOIT( glRectfv                  );
    JUSTDOIT( glRecti                   );
    JUSTDOIT( glRectiv                  );
    JUSTDOIT( glRects                   );
    JUSTDOIT( glRectsv                  );
    JUSTDOIT( glTexCoord1d              );
    JUSTDOIT( glTexCoord1dv             );
    JUSTDOIT( glTexCoord1f              );
    JUSTDOIT( glTexCoord1fv             );
    JUSTDOIT( glTexCoord1i              );
    JUSTDOIT( glTexCoord1iv             );
    JUSTDOIT( glTexCoord1s              );
    JUSTDOIT( glTexCoord1sv             );
    JUSTDOIT( glTexCoord2d              );
    JUSTDOIT( glTexCoord2dv             );
    JUSTDOIT( glTexCoord2f              );
    JUSTDOIT( glTexCoord2fv             );
    JUSTDOIT( glTexCoord2i              );
    JUSTDOIT( glTexCoord2iv             );
    JUSTDOIT( glTexCoord2s              );
    JUSTDOIT( glTexCoord2sv             );
    JUSTDOIT( glTexCoord3d              );
    JUSTDOIT( glTexCoord3dv             );
    JUSTDOIT( glTexCoord3f              );
    JUSTDOIT( glTexCoord3fv             );
    JUSTDOIT( glTexCoord3i              );
    JUSTDOIT( glTexCoord3iv             );
    JUSTDOIT( glTexCoord3s              );
    JUSTDOIT( glTexCoord3sv             );
    JUSTDOIT( glTexCoord4d              );
    JUSTDOIT( glTexCoord4dv             );
    JUSTDOIT( glTexCoord4f              );
    JUSTDOIT( glTexCoord4fv             );
    JUSTDOIT( glTexCoord4i              );
    JUSTDOIT( glTexCoord4iv             );
    JUSTDOIT( glTexCoord4s              );
    JUSTDOIT( glTexCoord4sv             );
    JUSTDOIT( glVertex2d                );
    JUSTDOIT( glVertex2dv               );
    JUSTDOIT( glVertex2f                );
    JUSTDOIT( glVertex2fv               );
    JUSTDOIT( glVertex2i                );
    JUSTDOIT( glVertex2iv               );
    JUSTDOIT( glVertex2s                );
    JUSTDOIT( glVertex2sv               );
    JUSTDOIT( glVertex3d                );
    JUSTDOIT( glVertex3dv               );
    JUSTDOIT( glVertex3f                );
    JUSTDOIT( glVertex3fv               );
    JUSTDOIT( glVertex3i                );
    JUSTDOIT( glVertex3iv               );
    JUSTDOIT( glVertex3s                );
    JUSTDOIT( glVertex3sv               );
    JUSTDOIT( glVertex4d                );
    JUSTDOIT( glVertex4dv               );
    JUSTDOIT( glVertex4f                );
    JUSTDOIT( glVertex4fv               );
    JUSTDOIT( glVertex4i                );
    JUSTDOIT( glVertex4iv               );
    JUSTDOIT( glVertex4s                );
    JUSTDOIT( glVertex4sv               );
    JUSTDOIT( glClipPlane               );
    JUSTDOIT( glColorMaterial           );
    JUSTDOIT( glCullFace                );
    JUSTDOIT( glFogf                    );
    JUSTDOIT( glFogfv                   );
    JUSTDOIT( glFogi                    );
    JUSTDOIT( glFogiv                   );
    JUSTDOIT( glFrontFace               );
    JUSTDOIT( glHint                    );
    JUSTDOIT( glLightf                  );
    JUSTDOIT( glLightfv                 );
    JUSTDOIT( glLighti                  );
    JUSTDOIT( glLightiv                 );
    JUSTDOIT( glLightModelf             );
    JUSTDOIT( glLightModelfv            );
    JUSTDOIT( glLightModeli             );
    JUSTDOIT( glLightModeliv            );
    JUSTDOIT( glLineStipple             );
    JUSTDOIT( glLineWidth               );
    JUSTDOIT( glMaterialf               );
    JUSTDOIT( glMaterialfv              );
    JUSTDOIT( glMateriali               );
    JUSTDOIT( glMaterialiv              );
    JUSTDOIT( glPointSize               );
    JUSTDOIT( glPolygonMode             );
    JUSTDOIT( glPolygonStipple          );
    JUSTDOIT( glScissor                 );
    JUSTDOIT( glShadeModel              );
    JUSTDOIT( glTexParameterf           );
    JUSTDOIT( glTexParameterfv          );
    JUSTDOIT( glTexParameteri           );
    JUSTDOIT( glTexParameteriv          );
    JUSTDOIT( glTexImage1D              );
    JUSTDOIT( glTexImage2D              );
    JUSTDOIT( glTexEnvf                 );
    JUSTDOIT( glTexEnvfv                );
    JUSTDOIT( glTexEnvi                 );
    JUSTDOIT( glTexEnviv                );
    JUSTDOIT( glTexGend                 );
    JUSTDOIT( glTexGendv                );
    JUSTDOIT( glTexGenf                 );
    JUSTDOIT( glTexGenfv                );
    JUSTDOIT( glTexGeni                 );
    JUSTDOIT( glTexGeniv                );
    JUSTDOIT( glFeedbackBuffer          );
    JUSTDOIT( glSelectBuffer            );
    JUSTDOIT( glRenderMode              );
    JUSTDOIT( glInitNames               );
    JUSTDOIT( glLoadName                );
    JUSTDOIT( glPassThrough             );
    JUSTDOIT( glPopName                 );
    JUSTDOIT( glPushName                );
    JUSTDOIT( glDrawBuffer              );
    JUSTDOIT( glClear                   );
    JUSTDOIT( glClearAccum              );
    JUSTDOIT( glClearIndex              );
    JUSTDOIT( glClearColor              );
    JUSTDOIT( glClearStencil            );
    JUSTDOIT( glClearDepth              );
    JUSTDOIT( glStencilMask             );
    JUSTDOIT( glColorMask               );
    JUSTDOIT( glDepthMask               );
    JUSTDOIT( glIndexMask               );
    JUSTDOIT( glAccum                   );
    JUSTDOIT( glDisable                 );
    JUSTDOIT( glEnable                  );
    JUSTDOIT( glFinish                  );
    JUSTDOIT( glFlush                   );
    JUSTDOIT( glPopAttrib               );
    JUSTDOIT( glPushAttrib              );
    JUSTDOIT( glMap1d                   );
    JUSTDOIT( glMap1f                   );
    JUSTDOIT( glMap2d                   );
    JUSTDOIT( glMap2f                   );
    JUSTDOIT( glMapGrid1d               );
    JUSTDOIT( glMapGrid1f               );
    JUSTDOIT( glMapGrid2d               );
    JUSTDOIT( glMapGrid2f               );
    JUSTDOIT( glEvalCoord1d             );
    JUSTDOIT( glEvalCoord1dv            );
    JUSTDOIT( glEvalCoord1f             );
    JUSTDOIT( glEvalCoord1fv            );
    JUSTDOIT( glEvalCoord2d             );
    JUSTDOIT( glEvalCoord2dv            );
    JUSTDOIT( glEvalCoord2f             );
    JUSTDOIT( glEvalCoord2fv            );
    JUSTDOIT( glEvalMesh1               );
    JUSTDOIT( glEvalPoint1              );
    JUSTDOIT( glEvalMesh2               );
    JUSTDOIT( glEvalPoint2              );
    JUSTDOIT( glAlphaFunc               );
    JUSTDOIT( glBlendFunc               );
    JUSTDOIT( glLogicOp                 );
    JUSTDOIT( glStencilFunc             );
    JUSTDOIT( glStencilOp               );
    JUSTDOIT( glDepthFunc               );
    JUSTDOIT( glPixelZoom               );
    JUSTDOIT( glPixelTransferf          );
    JUSTDOIT( glPixelTransferi          );
    JUSTDOIT( glPixelStoref             );
    JUSTDOIT( glPixelStorei             );
    JUSTDOIT( glPixelMapfv              );
    JUSTDOIT( glPixelMapuiv             );
    JUSTDOIT( glPixelMapusv             );
    JUSTDOIT( glReadBuffer              );
    JUSTDOIT( glCopyPixels              );
    JUSTDOIT( glReadPixels              );
    JUSTDOIT( glDrawPixels              );
    JUSTDOIT( glGetBooleanv             );
    JUSTDOIT( glGetClipPlane            );
    JUSTDOIT( glGetDoublev              );
    JUSTDOIT( glGetError                );
    JUSTDOIT( glGetFloatv               );
    JUSTDOIT( glGetIntegerv             );
    JUSTDOIT( glGetLightfv              );
    JUSTDOIT( glGetLightiv              );
    JUSTDOIT( glGetMapdv                );
    JUSTDOIT( glGetMapfv                );
    JUSTDOIT( glGetMapiv                );
    JUSTDOIT( glGetMaterialfv           );
    JUSTDOIT( glGetMaterialiv           );
    JUSTDOIT( glGetPixelMapfv           );
    JUSTDOIT( glGetPixelMapuiv          );
    JUSTDOIT( glGetPixelMapusv          );
    JUSTDOIT( glGetPolygonStipple       );
    JUSTDOIT( glGetString               );
    JUSTDOIT( glGetTexEnvfv             );
    JUSTDOIT( glGetTexEnviv             );
    JUSTDOIT( glGetTexGendv             );
    JUSTDOIT( glGetTexGenfv             );
    JUSTDOIT( glGetTexGeniv             );
    JUSTDOIT( glGetTexImage             );
    JUSTDOIT( glGetTexParameterfv       );
    JUSTDOIT( glGetTexParameteriv       );
    JUSTDOIT( glGetTexLevelParameterfv  );
    JUSTDOIT( glGetTexLevelParameteriv  );
    JUSTDOIT( glIsEnabled               );
    JUSTDOIT( glIsList                  );
    JUSTDOIT( glDepthRange              );
    JUSTDOIT( glFrustum                 );
    JUSTDOIT( glLoadIdentity            );
    JUSTDOIT( glLoadMatrixf             );
    JUSTDOIT( glLoadMatrixd             );
    JUSTDOIT( glMatrixMode              );
    JUSTDOIT( glMultMatrixf             );
    JUSTDOIT( glMultMatrixd             );
    JUSTDOIT( glOrtho                   );
    JUSTDOIT( glPopMatrix               );
    JUSTDOIT( glPushMatrix              );
    JUSTDOIT( glRotated                 );
    JUSTDOIT( glRotatef                 );
    JUSTDOIT( glScaled                  );
    JUSTDOIT( glScalef                  );
    JUSTDOIT( glTranslated              );
    JUSTDOIT( glTranslatef              );
    JUSTDOIT( glViewport                );
}

void
oDo( char *Func, size_t Fo )
{
    /*
     *  This code will generate the following code:
     *
     *  glNewList:
     *    00000000: 3C0E8000 lui         t6,8000
     *    00000004: 8DCFF4A8 lw          t7,F4A8(t6)
     *    00000008: 8DF80714 lw          t8,0714(t7)
     *    0000000C: 03000008 jr          t8
     *    00000010: 00000000 nop
     */

    printf("    .text\n");
    printf("    .align 2\n");

#ifdef ADD_DEBUG_FORMATION
    printf("    .ent %s\n", Func);
#endif

    printf("    .globl %s\n", Func);


    printf("    li      $14, 0x%lX\n", PAGE_AFTER_LAST );
    printf("    lw      $15, 0x%lX($14)\n",
                                offsetof(KPCR, Teb) - OFFSET_FROM_PAGE );
    printf("    lw      $24, 0x%lX($15)\n", offsetof(TEB, glDispatchTable)+Fo);
    printf("    j       $24\n");

#ifdef ADD_DEBUG_FORMATION
    printf("    .end\n");
#endif

    printf("\n");
}

void
Do( char *Func, size_t Fo )
{
    /*
     *  This code will generate the following code:
     *
     *  glNewList:
     *    00000000: 3C0E8000 lui         t6,8000
     *    00000004: 8DCFF4A8 lw          t7,F4A8(t6)
     *    00000008: 8DF80714 lw          t8,0714(t7)
     *    0000000C: 03000008 jr          t8
     *    00000010: 00000000 nop
     */

    printf("    GL_TABLE_ENTRY(%s)\n", Func);
    printf("    lw      t7, UsPcr + PcTeb\n");
    printf("    lw      t8,TeglDispatchTable + 0x%lX(t7)\n", Fo); 
    printf("    j       t8\n");

#ifdef ADD_DEBUG_FORMATION
    printf("    .end\n");
#endif

    printf("\n");
}

void
PrintEntryMacro(void)
{
    printf("#define GL_TABLE_ENTRY(Name)            \\\n");
    printf("        .text;                          \\\n");
    printf("        .align  2;                      \\\n");
    printf("        .globl  Name;                   \\\n");
    printf("        .ent    Name, 0;                \\\n");
    printf("Name:;                                  \\\n");
    printf("        .frame  sp, 0, ra;              \\\n");
    printf("        .prologue 0;\n\n");
}

