Annotation of frontvm/src/screen.c, revision 1.1.1.2

1.1       root        1: /*
                      2:   Hatari - screen.c
                      3: 
                      4:   This file is distributed under the GNU Public License, version 2 or at your
                      5:   option any later version. Read the file gpl.txt for details.
                      6: */
                      7: 
                      8: #include <SDL.h>
                      9: #include <GL/gl.h>
                     10: #include <GL/glu.h>
                     11: 
                     12: #include "main.h"
                     13: #include "../m68000.h"
                     14: #include "screen.h"
                     15: 
                     16: unsigned long VideoBase;                        /* Base address in ST Ram for screen(read on each VBL) */
                     17: unsigned char *VideoRaster;                      /* Pointer to Video raster, after VideoBase in PC address space. Use to copy data on HBL */
                     18: 
                     19: int len_main_palette;
                     20: unsigned short MainPalette[256];
                     21: unsigned short CtrlPalette[16];
                     22: int fe2_bgcol;
                     23: 
                     24: unsigned int MainRGBPalette[256];
                     25: unsigned int CtrlRGBPalette[16];
                     26: 
                     27: unsigned long logscreen, logscreen2, physcreen, physcreen2;
                     28: 
                     29: SDL_Surface *sdlscrn;                             /* The SDL screen surface */
                     30: BOOL bGrabMouse = FALSE;                          /* Grab the mouse cursor in the window */
                     31: BOOL bInFullScreen = FALSE;
                     32: 
                     33: /* new stuff */
                     34: enum RENDERERS use_renderer = R_GL;
                     35: /* mouse shown this frame? */
                     36: int mouse_shown = 0;
                     37: /* fe2 UI blits are done to old screen memory and copied to this texture. */
                     38: static unsigned int screen_tex;
                     39: 
                     40: static GLUquadricObj *qobj;
                     41: static GLUtesselator *tobj;
                     42: 
                     43: float hack;
                     44: 
                     45: #define SCR_TEX_W      512
                     46: #define SCR_TEX_H      256
                     47: 
                     48: #define RAD_2_DEG      57.295779513082323f
                     49: 
                     50: /*-----------------------------------------------------------------------*/
                     51: /*
                     52:   Set window size
                     53: */
                     54: int screen_w = 640;
                     55: int screen_h = 480;
                     56: #define GLERR { printf ("GL: %s\n", gluErrorString (glGetError ()));}
                     57: 
                     58: #ifndef CALLBACK
                     59: # ifdef WIN32
                     60: #  define CALLBACK __attribute__ ((__stdcall__))
                     61: # else
                     62: #  define CALLBACK
                     63: # endif
                     64: #endif /* CALLBACK */
                     65: 
                     66: void CALLBACK beginCallback(GLenum which);
                     67: void CALLBACK errorCallback(GLenum errorCode);
                     68: void CALLBACK endCallback(void);
                     69: void CALLBACK vertexCallback(GLvoid *vertex, GLvoid *poly_data);
                     70: void CALLBACK combineCallback(GLdouble coords[3], 
                     71:                      GLdouble *vertex_data[4],
                     72:                      GLfloat weight[4], GLdouble **dataOut );
                     73: 
                     74: static void set_main_viewport ()
                     75: {
                     76:        int ctrl_h = 32*screen_h/200;
                     77:        glViewport (0, ctrl_h, screen_w, screen_h - ctrl_h);
                     78: }
                     79: 
                     80: static void set_ctrl_viewport ()
                     81: {
                     82:        glViewport (0, 0, screen_w, screen_h);
                     83: }
                     84: 
                     85: static void change_vidmode ()
                     86: {
                     87:        const SDL_VideoInfo *info = NULL;
                     88:        int modes;
                     89: 
                     90:        info = SDL_GetVideoInfo ();
                     91: 
                     92:        assert (info != NULL);
                     93: 
                     94:        SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
                     95:        
                     96:        modes = SDL_OPENGL | SDL_ANYFORMAT | (bInFullScreen ? SDL_FULLSCREEN : 0);
                     97:        
                     98:        if ((sdlscrn = SDL_SetVideoMode (screen_w, screen_h,
                     99:                                info->vfmt->BitsPerPixel, modes)) == 0) {
                    100:                fprintf (stderr, "Video mode set failed: %s\n", SDL_GetError ());
                    101:                SDL_Quit ();
                    102:                exit (-1);
                    103:        }
                    104: 
                    105:        glDisable (GL_CULL_FACE);
                    106:        glShadeModel (GL_FLAT);
                    107:        glDisable (GL_DEPTH_TEST);
                    108:        glClearColor (0, 0, 0, 0);
                    109: 
                    110:        glMatrixMode (GL_PROJECTION);
                    111:        glLoadIdentity ();
                    112:        /* aspect ratio of frontier's 3d view is 320/168 = 1.90 */
                    113:        gluPerspective (36.5f, 1.9f, 1.0f, 10000000000.0f);
                    114: 
                    115:        glEnable (GL_TEXTURE_2D);
                    116:        glGenTextures (1, &screen_tex);
                    117:        glBindTexture (GL_TEXTURE_2D, screen_tex);
                    118:        glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, SCR_TEX_W, SCR_TEX_H, 0, GL_RGBA, GL_INT, 0);
                    119:        glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
                    120:        glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
                    121:        glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                    122:        glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                    123:        
                    124:        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                    125:        glDisable (GL_TEXTURE_2D);
                    126:        
                    127:        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                    128:        glMatrixMode (GL_MODELVIEW);
                    129:        glLoadIdentity ();
                    130:        glDisable (GL_DEPTH_TEST);
                    131: }
                    132: 
                    133: void Screen_Init(void)
                    134: {
                    135:        change_vidmode ();
                    136:        
                    137:        qobj = gluNewQuadric ();
                    138: 
                    139:        tobj = gluNewTess ();
                    140:                
                    141:        gluTessCallback(tobj, GLU_TESS_VERTEX_DATA, (_GLUfuncptr) vertexCallback);
                    142:        gluTessCallback(tobj, GLU_TESS_BEGIN, (_GLUfuncptr) beginCallback);
                    143:        gluTessCallback(tobj, GLU_TESS_END, (_GLUfuncptr) endCallback);
                    144:        gluTessCallback(tobj, GLU_TESS_ERROR, (_GLUfuncptr) errorCallback);
                    145:        gluTessCallback(tobj, GLU_TESS_COMBINE, (_GLUfuncptr) combineCallback);
                    146:        
                    147:        /* Configure some SDL stuff: */
                    148:        SDL_WM_SetCaption(PROG_NAME, "Frontier");
                    149:        SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
                    150:        SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE);
                    151:        SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);
                    152:        SDL_ShowCursor(SDL_ENABLE);
                    153: }
                    154: 
                    155: void Screen_UnInit(void)
                    156: {
                    157: }
                    158: 
                    159: void Screen_ToggleFullScreen ()
                    160: {
                    161:        bInFullScreen = !bInFullScreen;
                    162:        change_vidmode ();
                    163:        //SDL_WM_ToggleFullScreen (sdlscrn);
                    164: }
                    165: 
                    166: static const unsigned char font_bmp[] = {
                    167:        0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x80,0x80,0x80,0x80,0x80,0x0,
                    168:        0x80,0x0,0x0,0x2,0xa0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x50,
                    169:        0xf8,0x50,0x50,0xf8,0x50,0x0,0x0,0x6,0x20,0xf0,0xa0,0xa0,0xa0,0xa0,0xf0,0x20,
                    170:        0x0,0x5,0x0,0xc8,0xd8,0x30,0x60,0xd8,0x98,0x0,0x0,0x6,0xa0,0x0,0xe0,0xa0,
                    171:        0xa0,0xa0,0xe0,0x0,0x0,0x4,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,
                    172:        0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0x0,0x3,0xc0,0x40,0x40,0x40,0x40,0x40,
                    173:        0x40,0xc0,0x0,0x3,0x0,0x0,0x20,0xf8,0x50,0xf8,0x20,0x0,0x0,0x6,0x0,0x0,
                    174:        0x40,0xe0,0x40,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,
                    175:        0x0,0x2,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,
                    176:        0x0,0x0,0x80,0x0,0x0,0x2,0x0,0x8,0x18,0x30,0x60,0xc0,0x80,0x0,0x0,0x6,
                    177:        0xe0,0xa0,0xa0,0xa0,0xa0,0xa0,0xe0,0x0,0x0,0x4,0x40,0xc0,0x40,0x40,0x40,0x40,
                    178:        0xe0,0x0,0x0,0x4,0xe0,0x20,0x20,0xe0,0x80,0x80,0xe0,0x0,0x0,0x4,0xe0,0x20,
                    179:        0x20,0xe0,0x20,0x20,0xe0,0x0,0x0,0x4,0x80,0x80,0xa0,0xa0,0xe0,0x20,0x20,0x0,
                    180:        0x0,0x4,0xe0,0x80,0x80,0xe0,0x20,0x20,0xe0,0x0,0x0,0x4,0xe0,0x80,0x80,0xe0,
                    181:        0xa0,0xa0,0xe0,0x0,0x0,0x4,0xe0,0x20,0x20,0x20,0x20,0x20,0x20,0x0,0x0,0x4,
                    182:        0xe0,0xa0,0xa0,0xe0,0xa0,0xa0,0xe0,0x0,0x0,0x4,0xe0,0xa0,0xa0,0xe0,0x20,0x20,
                    183:        0xe0,0x0,0x0,0x4,0x0,0x0,0x0,0x80,0x0,0x80,0x0,0x0,0x0,0x2,0x0,0x0,
                    184:        0x0,0x80,0x0,0x0,0x80,0x80,0x0,0x2,0xe0,0x0,0xe0,0xa0,0xa0,0xa0,0xa0,0x0,
                    185:        0x0,0x4,0x0,0x0,0xe0,0x0,0xe0,0x0,0x0,0x0,0x0,0x4,0xc0,0x0,0xe0,0xa0,
                    186:        0xe0,0x80,0xe0,0x0,0x0,0x4,0xe0,0x20,0x20,0xe0,0x80,0x0,0x80,0x0,0x0,0x4,
                    187:        0xfe,0x82,0xba,0xa2,0xba,0x82,0xfe,0x0,0x0,0x8,0xf0,0x90,0x90,0x90,0xf0,0x90,
                    188:        0x90,0x0,0x0,0x5,0xf0,0x90,0x90,0xf8,0x88,0x88,0xf8,0x0,0x0,0x6,0xe0,0x80,
                    189:        0x80,0x80,0x80,0x80,0xe0,0x0,0x0,0x4,0xf8,0x48,0x48,0x48,0x48,0x48,0xf8,0x0,
                    190:        0x0,0x6,0xf0,0x80,0x80,0xe0,0x80,0x80,0xf0,0x0,0x0,0x5,0xf0,0x80,0x80,0xe0,
                    191:        0x80,0x80,0x80,0x0,0x0,0x4,0xf0,0x80,0x80,0x80,0xb0,0x90,0xf0,0x0,0x0,0x5,
                    192:        0x90,0x90,0x90,0xf0,0x90,0x90,0x90,0x0,0x0,0x5,0xe0,0x40,0x40,0x40,0x40,0x40,
                    193:        0xe0,0x0,0x0,0x4,0xf0,0x20,0x20,0x20,0x20,0x20,0xe0,0x0,0x0,0x4,0x90,0xb0,
                    194:        0xe0,0xc0,0xe0,0xb0,0x90,0x0,0x0,0x5,0x80,0x80,0x80,0x80,0x80,0x80,0xe0,0x0,
                    195:        0x0,0x4,0x88,0xd8,0xf8,0xa8,0x88,0x88,0x88,0x0,0x0,0x6,0x90,0xd0,0xf0,0xb0,
                    196:        0x90,0x90,0x90,0x0,0x0,0x5,0xf0,0x90,0x90,0x90,0x90,0x90,0xf0,0x0,0x0,0x5,
                    197:        0xf0,0x90,0x90,0xf0,0x80,0x80,0x80,0x0,0x0,0x5,0xf0,0x90,0x90,0x90,0x90,0xb0,
                    198:        0xf0,0x18,0x0,0x5,0xf0,0x90,0x90,0xf0,0xe0,0xb0,0x90,0x0,0x0,0x5,0xf0,0x80,
                    199:        0x80,0xf0,0x10,0x10,0xf0,0x0,0x0,0x5,0xe0,0x40,0x40,0x40,0x40,0x40,0x40,0x0,
                    200:        0x0,0x3,0x90,0x90,0x90,0x90,0x90,0x90,0xf0,0x0,0x0,0x5,0x90,0x90,0x90,0xb0,
                    201:        0xe0,0xc0,0x80,0x0,0x0,0x5,0x88,0x88,0x88,0xa8,0xf8,0xd8,0x88,0x0,0x0,0x6,
                    202:        0x88,0xd8,0x70,0x20,0x70,0xd8,0x88,0x0,0x0,0x6,0x90,0x90,0x90,0xf0,0x20,0x20,
                    203:        0x20,0x0,0x0,0x5,0xf0,0x10,0x30,0x60,0xc0,0x80,0xf0,0x0,0x0,0x5,0xa0,0x0,
                    204:        0xa0,0xa0,0xa0,0xa0,0xe0,0x0,0x0,0x4,0x0,0x80,0xc0,0x60,0x30,0x18,0x8,0x0,
                    205:        0x0,0x6,0xe0,0xa0,0xa0,0xe0,0xa0,0xa0,0xe0,0x80,0x80,0x4,0xe0,0xa0,0xe0,0x0,
                    206:        0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x6,
                    207:        0xa0,0x0,0xe0,0x20,0xe0,0xa0,0xe0,0x0,0x0,0x4,0x0,0x0,0xe0,0x20,0xe0,0xa0,
                    208:        0xe0,0x0,0x0,0x4,0x80,0x80,0xe0,0xa0,0xa0,0xa0,0xe0,0x0,0x0,0x4,0x0,0x0,
                    209:        0xc0,0x80,0x80,0x80,0xc0,0x0,0x0,0x3,0x20,0x20,0xe0,0xa0,0xa0,0xa0,0xe0,0x0,
                    210:        0x0,0x4,0x0,0x0,0xe0,0xa0,0xe0,0x80,0xe0,0x0,0x0,0x4,0xc0,0x80,0x80,0xc0,
                    211:        0x80,0x80,0x80,0x0,0x0,0x3,0x0,0x0,0xe0,0xa0,0xa0,0xa0,0xe0,0x20,0xe0,0x4,
                    212:        0x80,0x80,0xe0,0xa0,0xa0,0xa0,0xa0,0x0,0x0,0x4,0x80,0x0,0x80,0x80,0x80,0x80,
                    213:        0x80,0x0,0x0,0x2,0x40,0x0,0x40,0x40,0x40,0x40,0x40,0xc0,0x0,0x3,0x80,0x80,
                    214:        0xb0,0xe0,0xe0,0xb0,0x90,0x0,0x0,0x5,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,
                    215:        0x0,0x2,0x0,0x0,0xf8,0xa8,0xa8,0xa8,0xa8,0x0,0x0,0x6,0x0,0x0,0xe0,0xa0,
                    216:        0xa0,0xa0,0xa0,0x0,0x0,0x4,0x0,0x0,0xe0,0xa0,0xa0,0xa0,0xe0,0x0,0x0,0x4,
                    217:        0x0,0x0,0xe0,0xa0,0xa0,0xa0,0xe0,0x80,0x80,0x4,0x0,0x0,0xe0,0xa0,0xa0,0xa0,
                    218:        0xe0,0x20,0x30,0x4,0x0,0x0,0xc0,0x80,0x80,0x80,0x80,0x0,0x0,0x3,0x0,0x0,
                    219:        0xc0,0x80,0xc0,0x40,0xc0,0x0,0x0,0x3,0x80,0x80,0xc0,0x80,0x80,0x80,0xc0,0x0,
                    220:        0x0,0x3,0x0,0x0,0xa0,0xa0,0xa0,0xa0,0xe0,0x0,0x0,0x4,0x0,0x0,0xa0,0xa0,
                    221:        0xe0,0xc0,0x80,0x0,0x0,0x4,0x0,0x0,0x88,0xa8,0xf8,0xd8,0x88,0x0,0x0,0x6,
                    222:        0x0,0x0,0xa0,0xe0,0x40,0xe0,0xa0,0x0,0x0,0x4,0x0,0x0,0xa0,0xa0,0xa0,0xa0,
                    223:        0xe0,0x20,0xe0,0x4,0x0,0x0,0xf0,0x30,0x60,0xc0,0xf0,0x0,0x0,0x5,0x81,0x8d,
                    224:        0xe1,0xa0,0xa0,0xa0,0xa0,0x0,0x0,0x9,0x2,0x1a,0xc2,0x80,0xc0,0x40,0xc0,0x0,
                    225:        0x0,0x8,0xfe,0xfc,0xf8,0xfc,0xfe,0xdf,0x8e,0x4,0x0,0x7,0x7f,0x3f,0x1f,0x3f,
                    226:        0x7f,0xfb,0x71,0x20,0x0,0x8,0x4,0x8e,0xdf,0xfe,0xfc,0xf8,0xfc,0xfe,0x0,0x8,
                    227:        0x20,0x71,0xfb,0x7f,0x3f,0x1f,0x3f,0x7f,0x0,0x7,0xff,0x81,0x81,0x81,0x81,0x81,
                    228:        0x81,0xff,0x0,0x9,0x0,0x0,0xe0,0x80,0x80,0x80,0xe0,0x40,0xc0,0x4,0x60,0x0,
                    229:        0xe0,0xa0,0xe0,0x80,0xe0,0x0,0x0,0x4,0xc0,0x0,0xa0,0xa0,0xa0,0xa0,0xe0,0x0,
                    230:        0x0,0x4,0x40,0xa0,0x40,0x40,0x40,0x40,0x40,0x0,0x0,0x4,0x40,0xa0,0xe0,0x20,
                    231:        0xe0,0xa0,0xe0,0x0,0x0,0x4,0x40,0xa0,0xe0,0xa0,0xa0,0xa0,0xe0,0x0,0x0,0x4,
                    232:        0x40,0xa0,0xe0,0xa0,0xe0,0x80,0xe0,0x0,0x0,0x4,0xe0,0x0,0xa0,0xa0,0xa0,0xa0,
                    233:        0xe0,0x0,0x0,0x4,0xc0,0x0,0xe0,0x20,0xe0,0xa0,0xe0,0x0,0x0,0x4,0xe0,0xa0,
                    234:        0xa0,0xa0,0xe0,0xa0,0xa0,0x0,0x0,0x4,0xc0,0xa0,0xa0,0xc0,0xa0,0xa0,0xc0,0x0,
                    235:        0x0,0x4,0xe0,0x80,0x80,0x80,0x80,0x80,0xe0,0x0,0x0,0x4,0xc0,0xa0,0xa0,0xa0,
                    236:        0xa0,0xa0,0xc0,0x0,0x0,0x4,0xe0,0x80,0x80,0xe0,0x80,0x80,0xe0,0x0,0x0,0x4,
                    237:        0xe0,0x80,0x80,0xe0,0x80,0x80,0x80,0x0,0x0,0x4
                    238: };
                    239: 
                    240: static int DrawChar (int col, int xoffset, char *scrline, int chr)
                    241: {
                    242:        const char *font_pos;
                    243:        char *pix;
                    244:        int i;
                    245:        
                    246:        font_pos = font_bmp;
                    247:        font_pos += (chr&0xff)*10;
                    248:        scrline += xoffset;
                    249:        
                    250:        if (xoffset < 0) {
                    251:                font_pos += 9;
                    252:                return xoffset + *font_pos;
                    253:        }
                    254:        
                    255:        for (i=0; i<8; i++, font_pos++, scrline += SCREENBYTES_LINE) {
                    256:                pix = scrline;
                    257:                if (xoffset > 319) continue;
                    258:                if (*font_pos & 0x80) *pix = col;
                    259:                pix++;
                    260:                if (xoffset+1 > 319) continue;
                    261:                if (*font_pos & 0x40) *pix = col;
                    262:                pix++;
                    263:                if (xoffset+2 > 319) continue;
                    264:                if (*font_pos & 0x20) *pix = col;
                    265:                pix++;
                    266:                if (xoffset+3 > 319) continue;
                    267:                if (*font_pos & 0x10) *pix = col;
                    268:                pix++;
                    269:                if (xoffset+4 > 319) continue;
                    270:                if (*font_pos & 0x8) *pix = col;
                    271:                pix++;
                    272:                if (xoffset+5 > 319) continue;
                    273:                if (*font_pos & 0x4) *pix = col;
                    274:                pix++;
                    275:                if (xoffset+6 > 319) continue;
                    276:                if (*font_pos & 0x2) *pix = col;
                    277:                pix++;
                    278:                if (xoffset+7 > 319) continue;
                    279:                if (*font_pos & 0x1) *pix = col;
                    280:        }
                    281:        /* width of character */
                    282:        font_pos++;
                    283:        i = *font_pos;
                    284:        return xoffset + i;
                    285: }
                    286: 
                    287: #define MAX_QUEUED_STRINGS     200
                    288: struct QueuedString {
                    289:        int x, y, col;
                    290:        unsigned char str[64];
                    291: } queued_strings[MAX_QUEUED_STRINGS];
                    292: int queued_string_pos;
                    293: 
                    294: void Nu_QueueDrawStr ()
                    295: {
                    296:        assert (queued_string_pos < MAX_QUEUED_STRINGS);
                    297:        strncpy (queued_strings[queued_string_pos].str, GetReg (REG_A0) + STRam, 64);
                    298:        queued_strings[queued_string_pos].x = GetReg (REG_D1);
                    299:        queued_strings[queued_string_pos].y = GetReg (REG_D2);
                    300:        queued_strings[queued_string_pos++].col = GetReg (REG_D0);
                    301: }
                    302: 
                    303: int DrawStr (int xpos, int ypos, int col, unsigned char *str, bool shadowed)
                    304: {
                    305:        int x, y, chr;
                    306:        char *screen;
                    307: 
                    308:        x = xpos;
                    309:        y = ypos;
                    310:        
                    311:        if ((y > 192) || (y<0)) return x;
                    312: set_line:
                    313:        screen = LOGSCREEN2;
                    314:        screen += SCREENBYTES_LINE * y;
                    315: 
                    316:        while (*str) {
                    317:                chr = *(str++);
                    318:                
                    319:                if (chr < 0x1e) {
                    320:                        if (chr == '\r') {
                    321:                                y += 10;
                    322:                                x = xpos;
                    323:                                goto set_line;
                    324:                        }
                    325:                        else if (chr == 1) col = *(str++);
                    326:                        continue;
                    327:                } else if (chr == 0x1e) {
                    328:                        /* read new xpos */
                    329:                        x = *(str++);
                    330:                        x *= 2;
                    331:                        continue;
                    332:                } else if (chr < 0x20) {
                    333:                        /* Read new position */
                    334:                        x = *(str++);
                    335:                        x *= 2;
                    336:                        y = *(str++);
                    337:                        goto set_line;
                    338:                }
                    339:                
                    340:                //if (x > 316) continue;
                    341: 
                    342:                if (shadowed) {
                    343:                        DrawChar (0, x+1, screen+SCREENBYTES_LINE, chr-0x20);
                    344:                }
                    345:                x = DrawChar (col, x, screen, chr-0x20);
                    346:        }
                    347: 
                    348:        return x;
                    349: }
                    350: 
                    351: static void push_ortho ()
                    352: {
                    353:        glDisable (GL_DEPTH_TEST);
                    354:        glMatrixMode (GL_PROJECTION);
                    355:        glPushMatrix ();
                    356:        glLoadIdentity ();
                    357:        glOrtho (0, 320, 0, 200, -1, 1);
                    358: 
                    359:        glMatrixMode (GL_MODELVIEW);
                    360:        glPushMatrix ();
                    361:        glLoadIdentity ();
                    362: }
                    363: 
                    364: static void pop_ortho ()
                    365: {
                    366:        glMatrixMode (GL_PROJECTION);
                    367:        glPopMatrix ();
                    368:        glMatrixMode (GL_MODELVIEW);
                    369:        glPopMatrix ();
                    370: }
                    371: 
                    372: void Screen_ToggleRenderer ()
                    373: {
                    374:        use_renderer++;
                    375:        if (use_renderer >= R_MAX) use_renderer = 0;
                    376: }
                    377: 
                    378: static void draw_control_panel ()
                    379: {
                    380:        int x, y;
                    381:        unsigned char *scr;
                    382:        unsigned int line[320];
                    383:        unsigned int *pal;
                    384: 
                    385:        set_ctrl_viewport ();
                    386:        
                    387:        /* this is a big fucking hack to make starsystem names
                    388:         * in the starmap show up. they are the only bitmap text
                    389:         * things drawn within the fe2 3d renderer, which makes
                    390:         * them fucking annoying. */
                    391:        y = logscreen2;
                    392:        logscreen2 = physcreen;
                    393:        for (x=0; x<queued_string_pos; x++) {
                    394:                DrawStr (       queued_strings[x].x,
                    395:                                queued_strings[x].y,
                    396:                                queued_strings[x].col,
                    397:                                queued_strings[x].str,
                    398:                                FALSE);
                    399:        }
                    400:        logscreen2 = y;
                    401:        /****************************************************/
                    402:        
                    403:        scr = VideoRaster;
                    404:        
                    405:        /* intro likes black at the bottom */
                    406:        /* hack hack hack what a pile of shite this is */
                    407:        push_ortho ();
                    408:        glColor3f (0.0f, 0.0f, 0.0f);
                    409:        glBegin (GL_TRIANGLE_STRIP);
                    410:                glVertex3f (0, 32, 0);
                    411:                glVertex3f (319, 32, 0);
                    412:                glVertex3f (0, 0, 0);
                    413:                glVertex3f (319, 0, 0);
                    414:        glEnd ();
                    415:        
                    416:        glEnable (GL_TEXTURE_2D);
                    417:        
                    418:        glBindTexture (GL_TEXTURE_2D, screen_tex);
                    419: 
                    420:        pal = MainRGBPalette;
                    421:        
                    422:        /* copy whole 320x200 screen to texture */
                    423:        for (y=0; y<200; y++) {
                    424:                /* the control panel at the bottom has its own palette */
                    425:                if (y >= 168) pal = CtrlRGBPalette;
                    426:                
                    427:                for (x=0; x<320; x++) {
                    428:                        /* in gl mode the ui texture has transparent crap where no shit is */
                    429:                        if ((*(scr)) == 255) {
                    430:                                scr++;
                    431:                                line[x] = 0;
                    432:                        } else {
                    433:                                line[x] = pal[*(scr++)];
                    434:                        }
                    435:                }
                    436:                glTexSubImage2D (GL_TEXTURE_2D, 0, 0, y, 320, 2, GL_RGBA, GL_UNSIGNED_BYTE, line);
                    437:        }
                    438:        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                    439:        
                    440:        if (use_renderer == R_OLD) {
                    441:                glBegin (GL_TRIANGLE_STRIP);
                    442:                        glTexCoord2f (0.0f, 200.0f/SCR_TEX_H);
                    443:                        glVertex2i (0, 0);
                    444:                        glTexCoord2f (320.0f/SCR_TEX_W, 200.0f/SCR_TEX_H);
                    445:                        glVertex2i (320, 0);
                    446:                        glTexCoord2f (0.0f, 0.0f);
                    447:                        glVertex2i (0, 200);
                    448:                        glTexCoord2f (320.0f/SCR_TEX_W, 0.0f);
                    449:                        glVertex2i (320, 200);
                    450:                glEnd ();
                    451:        } else {
                    452:                glEnable (GL_BLEND);
                    453:                glBegin (GL_TRIANGLE_STRIP);
                    454:                        glTexCoord2f (0.0f, 200.0f/SCR_TEX_H);
                    455:                        glVertex2i (0, 0);
                    456:                        glTexCoord2f (320.0f/SCR_TEX_W, 200.0f/SCR_TEX_H);
                    457:                        glVertex2i (320, 0);
                    458:                        glTexCoord2f (0.0f, 0.0f);
                    459:                        glVertex2i (0, 200);
                    460:                        glTexCoord2f (320.0f/SCR_TEX_W, 0.0f);
                    461:                        glVertex2i (320, 200);
                    462:                glEnd ();
                    463:                glDisable (GL_BLEND);
                    464:        }
                    465:        
                    466:        glDisable (GL_TEXTURE_2D);
                    467:        
                    468:        pop_ortho ();
                    469: }
                    470: 
                    471: static void _BuildRGBPalette (unsigned int *rgb, unsigned short *st, int len)
                    472: {
                    473:        int i;
                    474:        int st_col, r, g, b;
                    475: 
                    476:        for (i=0; i<len; i++, st++) {
                    477:                st_col = *st;
                    478:                b = (st_col & 0xf)<<4;
                    479:                g = (st_col & 0xf0);
                    480:                r = (st_col & 0xf00)>>4;
                    481:                rgb[i] = 0xff000000 | (b<<16) | (g<<8) | (r);
                    482:        }
                    483: }
                    484: 
                    485: static inline void split_rgb444b (int rgb, int *r, int *g, int *b)
                    486: {
                    487:        *r = (rgb & 0xf00) >> 4;
                    488:        *g = (rgb & 0xf0);
                    489:        *b = (rgb & 0xf) << 4;
                    490: }
                    491: 
                    492: static inline void split_rgb444i (unsigned int rgb, unsigned int *r, unsigned int *g, unsigned int *b)
                    493: {
                    494:        *r = (rgb & 0xf00) << 20;
                    495:        *g = (rgb & 0xf0) << 24;
                    496:        *b = (rgb & 0xf) << 28;
                    497: }
                    498: 
                    499: static inline void read_m68k_vertex (int st_vptr, int output[3])
                    500: {
                    501:        output[0] = STMemory_ReadLong (st_vptr);
                    502:        output[1] = STMemory_ReadLong (st_vptr+4);
                    503:        output[2] = -STMemory_ReadLong (st_vptr+8);
                    504: }
                    505: 
                    506: struct ZNode {
                    507:        unsigned int z;
                    508:        struct ZNode *less, *more;
                    509:        void *data;
                    510: };
                    511: 
                    512: #define MAX_OBJ_DATA   (2<<17)
                    513: static unsigned char obj_data_area[MAX_OBJ_DATA];
                    514: static int obj_data_pos;
                    515: #define MAX_ZNODES     1000
                    516: static struct ZNode znode_buf[MAX_ZNODES];
                    517: static int znode_buf_pos;
                    518: static struct ZNode *znode_start;
                    519: static struct ZNode *znode_cur;
                    520: 
                    521: static inline void znode_databegin ()
                    522: {
                    523:        znode_cur->data = &obj_data_area[obj_data_pos];
                    524: }
                    525: 
                    526: static inline void znode_wrlong (int val)
                    527: {
                    528:        *((int*)(obj_data_area+obj_data_pos)) = val;
                    529:        obj_data_pos+=4;
                    530: }
                    531: static inline void znode_wrword (short val)
                    532: {
                    533:        *((short*)(obj_data_area+obj_data_pos)) = val;
                    534:        obj_data_pos+=2;
                    535: }
                    536: static inline void znode_wrbyte (char val)
                    537: {
                    538:        *((char*)(obj_data_area+obj_data_pos)) = val;
                    539:        obj_data_pos++;
                    540: }
                    541: 
                    542: static inline void znode_wrnormal (p68K loc)
                    543: {
                    544:        znode_wrword (STMemory_ReadWord (loc));
                    545:        znode_wrword (STMemory_ReadWord (loc+2));
                    546:        znode_wrword (STMemory_ReadWord (loc+4));
                    547: }
                    548: 
                    549: static void znode_wrmatrix (p68K loc)
                    550: {
                    551:        znode_wrword (STMemory_ReadWord (loc));
                    552:        znode_wrword (STMemory_ReadWord (loc+2));
                    553:        znode_wrword (STMemory_ReadWord (loc+4));
                    554:        znode_wrword (STMemory_ReadWord (loc+6));
                    555:        znode_wrword (STMemory_ReadWord (loc+8));
                    556:        znode_wrword (STMemory_ReadWord (loc+10));
                    557:        znode_wrword (STMemory_ReadWord (loc+12));
                    558:        znode_wrword (STMemory_ReadWord (loc+14));
                    559:        znode_wrword (STMemory_ReadWord (loc+16));
                    560: }
                    561: 
                    562: static inline void znode_wrvertex (p68K loc)
                    563: {
                    564:        znode_wrlong (STMemory_ReadLong (loc));
                    565:        znode_wrlong (STMemory_ReadLong (loc+4));
                    566:        znode_wrlong (-STMemory_ReadLong (loc+8));
                    567: }
                    568: 
                    569: static inline void znode_wrlightsource (p68K loc)
                    570: {
                    571:        znode_wrlong (-STMemory_ReadWord (loc));
                    572:        znode_wrlong (-STMemory_ReadWord (loc+2));
                    573:        znode_wrlong (STMemory_ReadWord (loc+4));
                    574: }
                    575: 
                    576: static inline void znode_wrcolor (int rgb444col)
                    577: {
                    578:        int r,g,b;
                    579:        split_rgb444b (rgb444col, &r, &g, &b);
                    580:        znode_wrbyte (r);
                    581:        znode_wrbyte (g);
                    582:        znode_wrbyte (b);
                    583:        znode_wrbyte (0);
                    584: }
                    585: 
                    586: static inline int znode_rdlong (void **data)
                    587: {
                    588:        int val = *((int*)(*data));
                    589:        (*data) += 4;
                    590:        return val;
                    591: }
                    592: static inline short znode_rdword (void **data)
                    593: {
                    594:        short val = *((short*)(*data));
                    595:        (*data) += 2;
                    596:        return val;
                    597: }
                    598: static inline char znode_rdbyte (void **data)
                    599: {
                    600:        char val = *((char*)(*data));
                    601:        (*data)++;
                    602:        return val;
                    603: }
                    604: 
                    605: static void znode_rdmatrix (void **data, GLfloat m[16])
                    606: {
                    607:        short val;
                    608: 
                    609: #define rdmatrixval(idx)       \
                    610:        {       \
                    611:                val = znode_rdword (data);      \
                    612:                m[idx] = ((float)val)/-32768.0; \
                    613:        }
                    614:        
                    615:        rdmatrixval (0);
                    616:        rdmatrixval (1);
                    617:        rdmatrixval (2);
                    618:        m[3] = 0.0f;
                    619:        rdmatrixval (4);
                    620:        rdmatrixval (5);
                    621:        rdmatrixval (6);
                    622:        m[7] = 0.0f;
                    623:        rdmatrixval (8);
                    624:        rdmatrixval (9);
                    625:        rdmatrixval (10);
                    626:        m[11] = 0.0f;
                    627:        m[12] = 0.0f;
                    628:        m[13] = 0.0f;
                    629:        m[14] = 0.0f;
                    630:        m[15] = 1.0f;
                    631: 
                    632:        //m[0] = -m[0];
                    633:        //m[5] = -m[5];
                    634:        //m[10] = -m[10];
                    635: }
                    636: 
                    637: static inline void znode_rdnormal (void **data, short normal[3])
                    638: {
                    639:        normal[0] = znode_rdword (data);
                    640:        normal[1] = znode_rdword (data);
                    641:        normal[2] = znode_rdword (data);
                    642: }
                    643: 
                    644: static inline void znode_rdvertex (void **data, int vertex[3])
                    645: {
                    646:        vertex[0] = znode_rdlong (data);
                    647:        vertex[1] = znode_rdlong (data);
                    648:        vertex[2] = znode_rdlong (data);
                    649: }
                    650: 
                    651: static inline void znode_rdvertexf (void **data, float vertex[3])
                    652: {
                    653:        vertex[0] = znode_rdlong (data);
                    654:        vertex[1] = znode_rdlong (data);
                    655:        vertex[2] = znode_rdlong (data);
                    656: }
                    657: 
                    658: static inline void znode_rdvertexd (void **data, GLdouble vertex[3])
                    659: {
                    660:        vertex[0] = znode_rdlong (data);
                    661:        vertex[1] = znode_rdlong (data);
                    662:        vertex[2] = znode_rdlong (data);
                    663: }
                    664: 
                    665: static inline void znode_rdcolorv (void **data, int *rgb)
                    666: {
                    667:        rgb[0] = (unsigned char) znode_rdbyte (data);
                    668:        rgb[1] = (unsigned char) znode_rdbyte (data);
                    669:        rgb[2] = (unsigned char) znode_rdbyte (data);
                    670:        (*data)++;
                    671: }
                    672: 
                    673: static inline void znode_rdcolor (void **data, int *r, int *g, int *b)
                    674: {
                    675:        *r = znode_rdbyte (data);
                    676:        *g = znode_rdbyte (data);
                    677:        *b = znode_rdbyte (data);
                    678:        (*data)++;
                    679: }
                    680: 
                    681: enum NuPrimitive {
                    682:        NU_END,
                    683:        NU_TRIANGLE,
                    684:        NU_QUAD,
                    685:        NU_LINE,
                    686:        NU_BEZIER_LINE,
                    687:        NU_TEARDROP,
                    688:        NU_COMPLEX_SNEXT,
                    689:        NU_COMPLEX_START,
                    690:        NU_COMPLEX_END,
                    691:        NU_COMPLEX_INNER,
                    692:        NU_COMPLEX_BEZIER,
                    693:        NU_TWINKLYCIRCLE,
                    694:        NU_PLANET,
                    695:        NU_CIRCLE,
                    696:        NU_CYLINDER,
                    697:        NU_BLOB,
                    698:        NU_OVALTHINGY,
                    699:        NU_POINT,
1.1.1.2 ! root      700:        NU_2DLINE,
1.1       root      701:        NU_MAX
                    702: };
                    703: 
                    704: static inline void end_node ()
                    705: {
                    706:        znode_wrlong (0);
                    707: }
                    708: 
                    709: static void add_node (struct ZNode **node, unsigned int zval)
                    710: {
                    711:        assert (znode_buf_pos < MAX_ZNODES);
                    712:        /* end previous znode display list!!!!!!! */
                    713:        if (znode_cur) end_node ();
                    714:        
                    715:        *node = znode_cur = &znode_buf[znode_buf_pos++];
                    716:        znode_cur->z = zval;
                    717:        znode_cur->less = NULL;
                    718:        znode_cur->more = NULL;
                    719:        znode_databegin ();
                    720: }
                    721: 
                    722: static void znode_insert (struct ZNode *node, unsigned int zval)
                    723: {
                    724:        if (zval > node->z) {
                    725:                if (node->more) {
                    726:                        znode_insert (node->more, zval);
                    727:                } else {
                    728:                        add_node (&node->more, zval);
                    729:                }
                    730:        } else {
                    731:                if (node->less) {
                    732:                        znode_insert (node->less, zval);
                    733:                } else {
                    734:                        add_node (&node->less, zval);
                    735:                }
                    736:        }
                    737: }
                    738: 
                    739: static bool no_znodes_kthx;
                    740: 
                    741: void Nu_InsertZNode ()
                    742: {
                    743:        unsigned int zval = GetReg (4);
                    744:        if (use_renderer == R_OLD) return;
                    745:        if (no_znodes_kthx) return;
                    746:        if (znode_start == NULL) {
                    747:                add_node (&znode_start, zval);
                    748:        } else {
                    749:                znode_insert (znode_start, zval);
                    750:        }
                    751: }
                    752: 
                    753: void Nu_3DViewInit ()
                    754: {
                    755:        queued_string_pos = 0;
                    756:        //printf ("3dviewinit()\n");
                    757:        znode_buf_pos = 0;
                    758:        //printf ("%d bytes object data\n", obj_data_pos);
                    759:        obj_data_pos = 0;
                    760: 
                    761:        //add_node (&znode_start, 0);
                    762:        znode_start = NULL;
                    763:        znode_cur = NULL;
1.1.1.2 ! root      764:        no_znodes_kthx = FALSE;
1.1       root      765: }
                    766: 
                    767: static void lighting_on (float light_vec[4], int rgb444_light_col, int rgb444_extra_col, int rgb444_obj_col)
                    768: {
                    769:        bool do_not_light;
                    770:        unsigned int extra_col[4], obj_col[4], light_col[4];
                    771: 
                    772:        do_not_light = rgb444_obj_col & (1<<8);
                    773:        
                    774:        /* object color bit 0x8 set means DO NOT LIGHT */
                    775:        if (do_not_light) {
                    776:                rgb444_obj_col ^= (1<<8);
                    777:        } else {
                    778:                split_rgb444i (rgb444_light_col, &light_col[0], &light_col[1], &light_col[2]);
                    779:                light_col[3] = 0;
                    780:                light_vec[3] = 0.0f;
                    781:        }
                    782: 
                    783:        if (rgb444_obj_col & (1<<4)) {
                    784:                rgb444_obj_col ^= (1<<4);
                    785:                split_rgb444i (rgb444_obj_col, &obj_col[0], &obj_col[1], &obj_col[2]);
                    786:                split_rgb444i (rgb444_extra_col, &extra_col[0], &extra_col[1], &extra_col[2]);
                    787:                obj_col[0] += extra_col[0];
                    788:                obj_col[1] += extra_col[1];
                    789:                obj_col[2] += extra_col[2];
                    790:        } else {
                    791:                split_rgb444i (rgb444_obj_col, &obj_col[0], &obj_col[1], &obj_col[2]);
                    792:        }
                    793:        obj_col[3] = 0;
                    794: 
                    795:        if (do_not_light) {
                    796:                glDisable (GL_LIGHTING);
                    797:                glDisable (GL_LIGHT0);
                    798:                glColor3ui (obj_col[0], obj_col[1], obj_col[2]);
                    799:        } else {
                    800:                glLightfv (GL_LIGHT0, GL_POSITION, light_vec);
                    801:                glLightiv (GL_LIGHT0, GL_DIFFUSE, light_col);
                    802:                glLightiv (GL_LIGHT0, GL_AMBIENT, obj_col);
                    803:                glEnable (GL_LIGHTING);
                    804:                glEnable (GL_LIGHT0);
                    805:        }
                    806: }
                    807: 
                    808: static void lighting_off ()
                    809: {
                    810:        glDisable (GL_LIGHTING);
                    811:        glDisable (GL_LIGHT0);
                    812: }
                    813: 
                    814: void CALLBACK beginCallback(GLenum which)
                    815: {
                    816:    glBegin(which);
                    817: }
                    818: 
                    819: void CALLBACK errorCallback(GLenum errorCode)
                    820: {
                    821:    const GLubyte *estring;
                    822: 
                    823:    estring = gluErrorString(errorCode);
                    824:    fprintf(stderr, "Tessellation Error: %s\n", estring);
                    825: }
                    826: 
                    827: void CALLBACK endCallback(void)
                    828: {
                    829:    glEnd();
                    830: }
                    831: 
                    832: static int complex_col[3];
                    833: void CALLBACK vertexCallback(GLvoid *vertex, GLvoid *poly_data)
                    834: {
                    835:    const GLdouble *pointer;
                    836: 
                    837:    pointer = (GLdouble *) vertex;
                    838:    glColor3ub (complex_col[0], complex_col[1], complex_col[2]);
                    839:    glVertex3dv(pointer);
                    840: }
                    841: /*  combineCallback is used to create a new vertex when edges
                    842:  *  intersect.  coordinate location is trivial to calculate,
                    843:  *  but weight[4] may be used to average color, normal, or texture
                    844:  *  coordinate data.  In this program, color is weighted.
                    845:  */
                    846: void CALLBACK combineCallback(GLdouble coords[3], 
                    847:                      GLdouble *vertex_data[4],
                    848:                      GLfloat weight[4], GLdouble **dataOut )
                    849: {
1.1.1.2 ! root      850:    GLdouble *vertex;
1.1       root      851: 
1.1.1.2 ! root      852:    vertex = (GLdouble *) malloc(3 * sizeof(GLdouble));
1.1       root      853: 
                    854:    vertex[0] = coords[0];
                    855:    vertex[1] = coords[1];
                    856:    vertex[2] = coords[2];
                    857:    *dataOut = vertex;
                    858: }
                    859: #define MAX_TESS_VERTICES      400
                    860: static GLdouble tess_vertices[MAX_TESS_VERTICES][3];
                    861: static int tess_vpos;
                    862: 
1.1.1.2 ! root      863: static GLdouble tessModelMatrix[16];
        !           864: static GLdouble tessProjMatrix[16];
        !           865: static GLint tessViewport[4];
        !           866: 
1.1       root      867: static bool do_start_complex;
                    868: static int complex_col_rgb444;
                    869: 
                    870: static void put_complex_start_4real ()
                    871: {
                    872:        znode_wrlong (NU_COMPLEX_START);
                    873:        znode_wrcolor (complex_col_rgb444);
                    874:        no_znodes_kthx = TRUE;
                    875: }
                    876: 
1.1.1.2 ! root      877: /* well it works */
        !           878: static inline void push_tess_vertex (GLdouble v[3])
        !           879: {
        !           880:        static double prev[3];
        !           881: 
        !           882:        if ((v[0]==prev[0]) && (v[1]==prev[1]) && (v[2]==prev[2])) return;
        !           883:        prev[0] = v[0];
        !           884:        prev[1] = v[1];
        !           885:        prev[2] = v[2];
        !           886: 
        !           887:        if (!gluProject (v[0],v[1],v[2], tessModelMatrix, tessProjMatrix, tessViewport,
        !           888:                        &v[0], &v[1], &v[2])) {
        !           889:                //printf ("fuck %f,%f,%f\n", prev[0], prev[1], prev[2]);
        !           890:                tess_vpos--;
        !           891:        } else {
        !           892:                /* bad return.. */
        !           893:                if (prev[2] >= 0.0f) {
        !           894:                        /*printf ("(%.2f,%.2f,%.2f) -> (%.2f,%.2f,%.2f)\n",
        !           895:                                        prev[0], prev[1], prev[2],
        !           896:                                        v[0], v[1], v[2]);
        !           897:                        */return;
        !           898:                }
        !           899:                gluTessVertex (tobj, v, v);
        !           900:        }
        !           901: }
        !           902: 
1.1       root      903: void Nu_ComplexSNext ()
                    904: {
                    905:        if (use_renderer == R_OLD) return;
                    906:        if (do_start_complex) { put_complex_start_4real (); do_start_complex = FALSE; }
                    907:        znode_wrlong (NU_COMPLEX_SNEXT);
                    908:        znode_wrvertex (GetReg (REG_A0)+4);
                    909: }
                    910: void Nu_DrawComplexSNext (void **data)
                    911: {
                    912:        if (use_renderer == R_GLWIRE) {
                    913:                znode_rdvertexd (data, tess_vertices[tess_vpos]);
                    914:                glVertex3dv (tess_vertices[tess_vpos++]);
                    915:        } else {
                    916:                assert (tess_vpos < MAX_TESS_VERTICES);
                    917:                znode_rdvertexd (data, tess_vertices[tess_vpos]);
1.1.1.2 ! root      918:                push_tess_vertex (tess_vertices[tess_vpos]);
1.1       root      919:                tess_vpos++;
                    920:        }
                    921: }
                    922: void Nu_ComplexSBegin ()
                    923: {
                    924:        Nu_ComplexSNext ();
                    925: }
                    926: 
                    927: void Nu_ComplexStart ()
                    928: {
                    929:        if (use_renderer == R_OLD) return;
                    930:        do_start_complex = TRUE;
                    931:        complex_col_rgb444 = GetReg (REG_D6);
                    932: }
                    933: void Nu_DrawComplexStart (void **data)
                    934: {
                    935:        tess_vpos = 0;
                    936:        
                    937:        if (use_renderer == R_GL) {
1.1.1.2 ! root      938:                glGetDoublev (GL_MODELVIEW_MATRIX, tessModelMatrix);
        !           939:                glGetDoublev (GL_PROJECTION_MATRIX, tessProjMatrix);
        !           940:                glGetIntegerv (GL_VIEWPORT, tessViewport);
        !           941:                
        !           942:                glMatrixMode (GL_PROJECTION);
        !           943:                glPushMatrix ();
        !           944:                glLoadIdentity ();
        !           945:                glOrtho (tessViewport[0], tessViewport[0]+tessViewport[2], tessViewport[1], tessViewport[1]+tessViewport[3], -1, 1);
        !           946: 
        !           947:                glMatrixMode (GL_MODELVIEW);
        !           948:                glPushMatrix ();
        !           949:                glLoadIdentity ();
        !           950:                
        !           951:                gluTessNormal (tobj, 0, 0, 1);
1.1       root      952:                gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
                    953:                gluTessBeginPolygon (tobj, NULL);
                    954:                gluTessBeginContour (tobj);
                    955:        } else {
                    956:                glBegin (GL_LINE_STRIP);
                    957:        }
                    958:        znode_rdcolor (data, &complex_col[0], &complex_col[1], &complex_col[2]);
                    959:        glColor3ub (complex_col[0], complex_col[1], complex_col[2]);
                    960: }
                    961: 
                    962: 
                    963: void Nu_ComplexEnd ()
                    964: {
                    965:        if (use_renderer == R_OLD) return;
                    966:        if (do_start_complex) { put_complex_start_4real (); do_start_complex = FALSE; }
                    967:        znode_wrlong (NU_COMPLEX_END);
                    968:        do_start_complex = FALSE;
                    969:        no_znodes_kthx = FALSE;
                    970: }
                    971: void Nu_DrawComplexEnd (void **data)
                    972: {
                    973:        if (use_renderer == R_GL) {
                    974:                gluTessEndContour (tobj);
                    975:                gluTessEndPolygon (tobj);
1.1.1.2 ! root      976:                
        !           977:                glMatrixMode (GL_PROJECTION);
        !           978:                glPopMatrix ();
        !           979:                glMatrixMode (GL_MODELVIEW);
        !           980:                glPopMatrix ();
1.1       root      981:        } else if (use_renderer == R_GLWIRE) {
                    982:                glVertex3dv (tess_vertices[0]);
                    983:                glEnd ();
                    984:        }
                    985: }
                    986: 
                    987: void Nu_ComplexStartInner ()
                    988: {
                    989:        if (use_renderer == R_OLD) return;
                    990:        if (do_start_complex) { put_complex_start_4real (); do_start_complex = FALSE; }
                    991:        znode_wrlong (NU_COMPLEX_INNER);
                    992: }
                    993: void Nu_DrawComplexStartInner (void **data)
                    994: {
                    995:        if (use_renderer == R_GL) {
                    996:                gluTessEndContour (tobj);
                    997:                gluTessBeginContour (tobj);
                    998:        } else if (use_renderer == R_GLWIRE) {
                    999:                glEnd ();
                   1000:                glBegin (GL_LINE_STRIP);
                   1001:                tess_vpos = 0;
                   1002:        }
                   1003: }
                   1004: 
                   1005: #define BEZIER_STEPS   10
                   1006: static void eval_bezier (GLdouble *out, float _t, float ctrlpoints[4][3])
                   1007: {
                   1008:        float a,b,c,d,t2;
                   1009:        t2 = _t*_t;
                   1010:        c = 1.0f-_t;
                   1011:        d = t2*_t;
                   1012:        b = c*c;
                   1013:        a = b*c;
                   1014:        b = b*_t*3.0f;
                   1015:        c = c*3.0f*t2;
                   1016:        /* x */ 
                   1017:        out[0] =
                   1018:            ctrlpoints[0][0] * a +
                   1019:            ctrlpoints[1][0] * b +
                   1020:            ctrlpoints[2][0] * c +
                   1021:            ctrlpoints[3][0] * d;
                   1022:        /* y */ 
                   1023:        out[1] =
                   1024:            ctrlpoints[0][1] * a +
                   1025:            ctrlpoints[1][1] * b +
                   1026:            ctrlpoints[2][1] * c +
                   1027:            ctrlpoints[3][1] * d;
                   1028:        /* y */ 
                   1029:        out[2] =
                   1030:            ctrlpoints[0][2] * a +
                   1031:            ctrlpoints[1][2] * b +
                   1032:            ctrlpoints[2][2] * c +
                   1033:            ctrlpoints[3][2] * d;
                   1034: }
                   1035: 
                   1036: void Nu_ComplexBezier ()
                   1037: {
                   1038:        if (use_renderer == R_OLD) return;
                   1039:        if (do_start_complex) { put_complex_start_4real (); do_start_complex = FALSE; }
                   1040:        znode_wrlong (NU_COMPLEX_BEZIER);
                   1041:        znode_wrvertex (GetReg (REG_A0)+4);
                   1042:        znode_wrvertex (GetReg (REG_A1)+4);
                   1043:        znode_wrvertex (GetReg (REG_A2)+4);
                   1044:        znode_wrvertex (GetReg (REG_A3)+4);
                   1045: }
                   1046: void Nu_DrawComplexBezier (void **data)
                   1047: {
                   1048:        int i, bezier_steps;
                   1049:        float delta;
                   1050:        double v[3];
                   1051:        GLfloat ctrlpoints[4][3];
                   1052:        
                   1053:        znode_rdvertexf (data, ctrlpoints[0]);
                   1054:        znode_rdvertexf (data, ctrlpoints[1]);
                   1055:        znode_rdvertexf (data, ctrlpoints[2]);
                   1056:        znode_rdvertexf (data, ctrlpoints[3]);
                   1057:        
                   1058:        /*float poo = MAX (abs (ctrlpoints[0][0]-ctrlpoints[3][0]),
                   1059:                         abs (ctrlpoints[0][1]-ctrlpoints[3][1]));
                   1060:        poo /= MIN (ctrlpoints[0][2], ctrlpoints[3][2]);
                   1061:        bezier_steps = MIN (6 - 20*poo, 16);*/
                   1062:        //printf ("%d ", bezier_steps);
                   1063:        bezier_steps = 10;
                   1064:        
                   1065:        assert (tess_vpos + bezier_steps < MAX_TESS_VERTICES);
                   1066:        delta = 1.0f/bezier_steps;
                   1067: 
                   1068:        if (use_renderer == R_GLWIRE) {
                   1069:                tess_vertices[tess_vpos][0] = ctrlpoints[0][0];
                   1070:                tess_vertices[tess_vpos][1] = ctrlpoints[0][1];
                   1071:                tess_vertices[tess_vpos++][2] = ctrlpoints[0][2];
                   1072:                for (i=0; i<=bezier_steps; i++) {
                   1073:                        eval_bezier (v, i*delta, ctrlpoints);
                   1074:                        glVertex3dv (v);
                   1075:                }
                   1076:                return;
                   1077:        }
1.1.1.2 ! root     1078:        for (i=0; i<=bezier_steps; i++) {
1.1       root     1079:                eval_bezier (&tess_vertices[tess_vpos][0], i*delta, ctrlpoints);
1.1.1.2 ! root     1080:                push_tess_vertex (tess_vertices[tess_vpos]);
1.1       root     1081:                tess_vpos++;
                   1082:        }
                   1083: }
                   1084: 
                   1085: 
                   1086: /* For engines and industry chimney flares.
                   1087:  * This is a bit crap, as you will see by panning around the effect. */
                   1088: void Nu_PutTeardrop ()
                   1089: {
                   1090:        if (use_renderer == R_OLD) return;
                   1091:        znode_wrlong (NU_TEARDROP);
                   1092:        znode_wrvertex (GetReg (REG_A0)+4);
                   1093:        znode_wrvertex (GetReg (REG_A1)+4);
                   1094:        znode_wrcolor (GetReg (REG_D6));
                   1095: }
                   1096: void Nu_DrawTeardrop (void **data)
                   1097: {
                   1098:        int i;
                   1099:        float delta;
                   1100:        GLfloat ctrlpoints[4][3];
                   1101:        GLfloat dir[3], ppd[3];
                   1102:        GLdouble out[3];
                   1103:        int r, g, b;
                   1104: 
                   1105: #define TD_STRETCH     1.3333333333
                   1106: #define TD_BROADEN     0.33
                   1107: #define TD_BEZIER_STEPS        40
                   1108:        
                   1109:        if (use_renderer == R_OLD) return;
                   1110:        znode_rdvertexf (data, dir);
                   1111:        znode_rdvertexf (data, ctrlpoints[0]);
                   1112:        znode_rdcolor (data, &r, &g, &b);
                   1113:        
                   1114:        dir[0] -= ctrlpoints[0][0];
                   1115:        dir[1] -= ctrlpoints[0][1];
                   1116:        dir[2] -= ctrlpoints[0][2];
                   1117:        
                   1118:        ppd[0] = -dir[1];
                   1119:        ppd[1] = dir[0];
                   1120:        ppd[2] = dir[2];
                   1121: 
                   1122:        //h = sqrt (dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]);
                   1123:        
                   1124:        ctrlpoints[1][0] = ctrlpoints[0][0] + TD_STRETCH*dir[0] + TD_BROADEN*ppd[0];
                   1125:        ctrlpoints[1][1] = ctrlpoints[0][1] + TD_STRETCH*dir[1] + TD_BROADEN*ppd[1];
                   1126:        ctrlpoints[1][2] = ctrlpoints[0][2] + dir[2];
                   1127:        
                   1128:        ctrlpoints[2][0] = ctrlpoints[0][0] + TD_STRETCH*dir[0] - TD_BROADEN*ppd[0];
                   1129:        ctrlpoints[2][1] = ctrlpoints[0][1] + TD_STRETCH*dir[1] - TD_BROADEN*ppd[1];
                   1130:        ctrlpoints[2][2] = ctrlpoints[0][2] + dir[2];
                   1131:        
                   1132:        ctrlpoints[3][0] = ctrlpoints[0][0];
                   1133:        ctrlpoints[3][1] = ctrlpoints[0][1];
                   1134:        ctrlpoints[3][2] = ctrlpoints[0][2];
                   1135: 
                   1136:        delta = 1.0f/TD_BEZIER_STEPS;
                   1137:        glColor3ub (r, g, b);
                   1138:        glBegin (GL_TRIANGLE_FAN);
                   1139:        /* the tessellator prefers it :-) */
                   1140:        for (i=0; i<=TD_BEZIER_STEPS; i++) {
                   1141:                eval_bezier (out, i*delta, ctrlpoints);
                   1142:                glVertex3dv (out);
                   1143:        }
                   1144:        glEnd ();
                   1145: }
                   1146: 
                   1147: 
                   1148: void Nu_PutBezierLine ()
                   1149: {
                   1150:        if (use_renderer == R_OLD) return;
                   1151:        znode_wrlong (NU_BEZIER_LINE);
                   1152:        znode_wrvertex (GetReg (REG_A0)+4);
                   1153:        znode_wrvertex (GetReg (REG_A1)+4);
                   1154:        znode_wrvertex (GetReg (REG_A2)+4);
                   1155:        znode_wrvertex (GetReg (REG_A3)+4);
                   1156:        znode_wrcolor (GetReg (REG_D6));
                   1157: }
                   1158: void Nu_DrawBezierLine (void **data)
                   1159: {
                   1160:        int i, r, g, b;
                   1161:        GLfloat ctrlpoints[4][3];
                   1162:        GLfloat delta;
                   1163:        GLdouble out[3];
                   1164: 
                   1165:        znode_rdvertexf (data, ctrlpoints[0]);
                   1166:        znode_rdvertexf (data, ctrlpoints[1]);
                   1167:        znode_rdvertexf (data, ctrlpoints[2]);
                   1168:        znode_rdvertexf (data, ctrlpoints[3]);
                   1169:        znode_rdcolor (data, &r, &g, &b);
                   1170:        
                   1171:        delta = 1.0f/20;
                   1172:        glColor3ub (r, g, b);
                   1173:        glBegin (GL_LINE_STRIP);
                   1174:        for (i=0; i<=20; i++) {
                   1175:                eval_bezier (out, i*delta, ctrlpoints);
                   1176:                glVertex3dv (out);
                   1177:        }
                   1178:        glEnd ();
                   1179: }
                   1180: 
                   1181: void Nu_PutTriangle ()
                   1182: {
                   1183:        if (use_renderer == R_OLD) return;
                   1184:        znode_wrlong (NU_TRIANGLE);
                   1185:        znode_wrvertex (GetReg (REG_A0)+4);
                   1186:        znode_wrvertex (GetReg (REG_A1)+4);
                   1187:        znode_wrvertex (GetReg (REG_A2)+4);
                   1188:        znode_wrcolor (GetReg (REG_D6));
                   1189: }
                   1190: void Nu_DrawTriangle (void **data)
                   1191: {
                   1192:        float v1[3], v2[3], v3[3];
                   1193:        int rgb[3];
                   1194:        
                   1195:        znode_rdvertexf (data, v1);
                   1196:        znode_rdvertexf (data, v2);
                   1197:        znode_rdvertexf (data, v3);
                   1198:        znode_rdcolorv (data, rgb);
                   1199:        glColor3ub (rgb[0], rgb[1], rgb[2]);
                   1200:        if (use_renderer == R_GLWIRE) {
                   1201:                glBegin (GL_LINE_STRIP);
                   1202:                        glVertex3fv (v1);
                   1203:                        glVertex3fv (v2);
                   1204:                        glVertex3fv (v3);
                   1205:                        glVertex3fv (v1);
                   1206:                glEnd ();
                   1207:        } else {
                   1208:                glBegin (GL_TRIANGLES);
                   1209:                        glVertex3fv (v1);
                   1210:                        glVertex3fv (v2);
                   1211:                        glVertex3fv (v3);
                   1212:                glEnd ();
                   1213:        }
                   1214: }
                   1215: 
                   1216: void Nu_PutQuad ()
                   1217: {
                   1218:        if (use_renderer == R_OLD) return;
                   1219:        znode_wrlong (NU_QUAD);
                   1220:        znode_wrvertex (GetReg (REG_A0)+4);
                   1221:        znode_wrvertex (GetReg (REG_A1)+4);
                   1222:        znode_wrvertex (GetReg (REG_A2)+4);
                   1223:        znode_wrvertex (GetReg (REG_A3)+4);
                   1224:        znode_wrcolor (GetReg (REG_D6));
                   1225: }
                   1226: void Nu_DrawQuad (void **data)
                   1227: {
                   1228:        int v1[3], v2[3], v3[3], v4[3];
                   1229:        int r, g, b;
                   1230:        
                   1231:        znode_rdvertex (data, v1);
                   1232:        znode_rdvertex (data, v2);
                   1233:        znode_rdvertex (data, v3);
                   1234:        znode_rdvertex (data, v4);
                   1235:        znode_rdcolor (data, &r, &g, &b);
                   1236:        
                   1237:        glColor3ub (r, g, b);
                   1238:        if (use_renderer == R_GLWIRE) {
                   1239:                glBegin (GL_LINE_STRIP);
                   1240:                        glVertex3iv (v1);
                   1241:                        glVertex3iv (v2);
                   1242:                        glVertex3iv (v3);
                   1243:                        glVertex3iv (v4);
                   1244:                        glVertex3iv (v1);
                   1245:                glEnd ();
                   1246:        } else {
                   1247:                glBegin (GL_TRIANGLE_STRIP);
                   1248:                        glVertex3iv (v1);
                   1249:                        glVertex3iv (v2);
                   1250:                        glVertex3iv (v4);
                   1251:                        glVertex3iv (v3);
                   1252:                glEnd ();
                   1253:        }
                   1254: }
                   1255: void Nu_PutTwinklyCircle ()
                   1256: {
                   1257:        if (use_renderer == R_OLD) return;
                   1258:        znode_wrlong (NU_TWINKLYCIRCLE);
                   1259:        znode_wrlong (GetReg (REG_D2));
                   1260:        znode_wrvertex (GetReg (REG_A0)+4);
                   1261:        znode_wrcolor (GetReg (REG_D6));
                   1262: }
                   1263: void Nu_DrawTwinklyCircle (void **data)
                   1264: {
                   1265:        int v1[3];
                   1266:        unsigned int dreg2, isize;
                   1267:        float size;
                   1268:        int r, g, b;
                   1269: 
                   1270:        dreg2 = znode_rdlong (data);
                   1271:        znode_rdvertex (data, v1);
                   1272:        znode_rdcolor (data, &r, &g, &b);
                   1273:        
                   1274:        glColor3ub (r, g, b);
                   1275: 
                   1276:        isize = (dreg2 << 16) | (dreg2 >> 16);
                   1277:        //printf ("%x (%x)\n", GetReg (2), isize);
                   1278:        
                   1279:        size = -0.002*((short)dreg2)*v1[2];
                   1280:        
                   1281:        glPushMatrix ();
                   1282:        glTranslatef (v1[0], v1[1], v1[2]);
                   1283:        
                   1284:        if (size > 0.0f) gluDisk (qobj, 0.0, size, 32, 1);
                   1285:        
                   1286:        size = -0.002*((short) dreg2)*v1[2] - 0.016*v1[2];
                   1287:        
                   1288:        //printf ("Size %.2f\n", size);
                   1289:        if (size > 0.0f) {
                   1290:                glBegin (GL_LINES);
                   1291:                        glVertex3f (-size, 0.0f, 0.0f);
                   1292:                        glVertex3f (+size, 0.0f, 0.0f);
                   1293:                        glVertex3f (0.0f, -size, 0.0f);
                   1294:                        glVertex3f (0.0f, +size, 0.0f);
                   1295:                glEnd ();
                   1296:        }
                   1297:        glPopMatrix ();
                   1298: }
                   1299: 
1.1.1.2 ! root     1300: void Nu_Put2DLine ()
        !          1301: {
        !          1302:        if (use_renderer == R_OLD) return;
        !          1303: 
        !          1304:        if (znode_start == NULL) {
        !          1305:                add_node (&znode_start, 0);
        !          1306:        } else {
        !          1307:                znode_insert (znode_start, 0);
        !          1308:        }
        !          1309:        znode_wrlong (NU_2DLINE);
        !          1310:        znode_wrword (GetReg (REG_D0));
        !          1311:        znode_wrword (GetReg (REG_D1));
        !          1312:        znode_wrword (GetReg (REG_D2));
        !          1313:        znode_wrword (GetReg (REG_D3));
        !          1314:        znode_wrword (GetReg (REG_D4));
        !          1315:        ///printf ("%x\n",(GetReg (REG_D4)&0xffff)>>2);
        !          1316:        /* what about color!!!!!! */
        !          1317: }
        !          1318: void Nu_Draw2DLine (void **data)
        !          1319: {
        !          1320:        short x1,y1,x2,y2;
        !          1321:        int col;
        !          1322: 
        !          1323:        x1 = znode_rdword (data);
        !          1324:        y1 = znode_rdword (data);
        !          1325:        x2 = znode_rdword (data);
        !          1326:        y2 = znode_rdword (data);
        !          1327:        col = MainRGBPalette[(znode_rdword (data)&0xffff)>>2];
        !          1328: 
        !          1329:        //printf ("%x,%x,%x,%x\n", col, col&0xff, (col>>8)&0xff, (col>>16)&0xff);
        !          1330:        
        !          1331:        push_ortho ();
        !          1332:        set_ctrl_viewport ();
        !          1333:        //glColor3ub (col&0xff, (col>>8)&0xff, (col>>16)&0xff);
        !          1334:        glColor3ub (0,255,0);
        !          1335:        glBegin (GL_LINES);
        !          1336:                glVertex2i (x1, 199-y1);
        !          1337:                glVertex2i (x2, 199-y2);
        !          1338:        glEnd ();
        !          1339:        set_main_viewport ();
        !          1340:        pop_ortho ();
        !          1341: }
        !          1342: 
1.1       root     1343: #define NUS_X  0.525731112119133606
                   1344: #define NUS_Z  0.850650808352039932
                   1345: 
                   1346: static float nus_vdata[12][3] = {
                   1347:        {-NUS_X, 0.0, NUS_Z}, {NUS_X, 0.0, NUS_Z}, {-NUS_X, 0.0, -NUS_Z}, {NUS_X, 0.0, -NUS_Z},
                   1348:        {0.0, NUS_Z, NUS_X}, {0.0, NUS_Z, -NUS_X}, {0.0, -NUS_Z, NUS_X}, {0.0, -NUS_Z, -NUS_X},
                   1349:        {NUS_Z, NUS_X, 0.0}, {-NUS_Z, NUS_X, 0.0}, {NUS_Z, -NUS_X, 0.0}, {-NUS_Z, -NUS_X, 0.0}
                   1350: };
                   1351: 
                   1352: static int nus_tindices[20][3] = {
                   1353:        {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
                   1354:        {8,10,1}, {8,3,10},{5,3,8}, {5,2,3}, {2,7,3},
                   1355:        {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
                   1356:        {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11}
                   1357: };
                   1358: 
                   1359: static void Normalise (float v[3])
                   1360: {
                   1361:        float d = sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
                   1362:        d = 1.0f / d;
                   1363:        v[0] *= d;
                   1364:        v[1] *= d;
                   1365:        v[2] *= d;
                   1366: }
                   1367: 
                   1368: static void nuSubdivide (float v1[3], float v2[3], float v3[3], int depth)
                   1369: {
                   1370:        float v12[3], v23[3], v31[3];
                   1371:        int i;
                   1372: 
                   1373:        if (depth == 0) {
                   1374:                glBegin (GL_POLYGON);
                   1375:                        glNormal3fv (v1); glVertex3fv (v1);
                   1376:                        glNormal3fv (v2); glVertex3fv (v2);
                   1377:                        glNormal3fv (v3); glVertex3fv (v3);
                   1378:                glEnd ();
                   1379:                return;
                   1380:        }
                   1381: 
                   1382:        for (i=0; i<3; i++) {
                   1383:                v12[i] = v1[i]+v2[i];
                   1384:                v23[i] = v2[i]+v3[i];
                   1385:                v31[i] = v3[i]+v1[i];
                   1386:        }
                   1387:        Normalise (v12);
                   1388:        Normalise (v23);
                   1389:        Normalise (v31);
                   1390:        nuSubdivide(v1, v12, v31, depth-1);
                   1391:        nuSubdivide(v2, v23, v12, depth-1);
                   1392:        nuSubdivide(v3, v31, v23, depth-1);
                   1393:        nuSubdivide(v12, v23, v31, depth-1);
                   1394: }
                   1395: 
                   1396: /*
                   1397: static void NormCrossProd (float v1[3], float v2[3], float vout[3])
                   1398: {
                   1399:        vout[0] = v1[1]*v2[2] - v1[2]*v2[1];
                   1400:        vout[1] = v1[2]*v2[0] - v1[0]*v2[2];
                   1401:        vout[2] = v1[0]*v2[1] - v1[1]*v2[0];
                   1402:        Normalise (vout);
                   1403: }*/
                   1404: 
                   1405: #define NUSPHERE_SUBDIVS       4
                   1406: 
                   1407: void nuSphere (float size)
                   1408: {
                   1409:        int i;
                   1410:        glScalef (size, size, size);
                   1411:        for (i=0; i<20; i++) {
                   1412:                nuSubdivide (nus_vdata[nus_tindices[i][0]],
                   1413:                                nus_vdata[nus_tindices[i][1]],
                   1414:                                nus_vdata[nus_tindices[i][2]],
                   1415:                                NUSPHERE_SUBDIVS);
                   1416:        }
                   1417: }
                   1418: 
                   1419: /* not finished by a long shot */
                   1420: void Nu_PutPlanet ()
                   1421: {
                   1422:        if (use_renderer == R_OLD) return;
                   1423:        
                   1424:        /*{
                   1425:                int cunt, i;
                   1426:                cunt = GetReg (REG_A6);
                   1427:                cunt -= 36;
                   1428:                printf ("Cuntrix:");
                   1429:                for (i=0; i<9; i++) {
                   1430:                        if (((i)%3) == 0) printf ("\n");
                   1431:                        printf ("%04hx ", STMemory_ReadWord (cunt));
                   1432:                        cunt += 2;
                   1433:                }
                   1434:                printf ("\n");
                   1435:        }*/
                   1436:        
                   1437:        znode_wrlong (NU_PLANET);
                   1438:        znode_wrlong (GetReg (REG_D6));
                   1439:        znode_wrlong (GetReg (REG_D1));
                   1440:        znode_wrlong (GetReg (REG_D0));
                   1441:        /* lighting vector */
                   1442:        znode_wrlightsource (GetReg (REG_A1));
                   1443:        znode_wrvertex (GetReg (REG_A0)+4);
                   1444:        znode_wrmatrix (GetReg (REG_A6)-36);
                   1445: }
                   1446: void Nu_DrawPlanet (void **data)
                   1447: {
                   1448:        int v1[3];
                   1449:        int size;
                   1450:        float light_vec[4];
                   1451:        GLfloat rot_matrix[16];
                   1452:        unsigned int obj_col[4], light_col[4];
                   1453: 
                   1454:        /*obj_col[0] = 1000000000;
                   1455:        obj_col[1] = 1000000000;
                   1456:        obj_col[2] = 1000000000;
                   1457:        obj_col[3] = 0;*/
                   1458:        split_rgb444i (znode_rdlong (data), &obj_col[0], &obj_col[1], &obj_col[2]);
                   1459:        obj_col[3] = 0;
                   1460:        split_rgb444i (znode_rdlong (data), &light_col[0], &light_col[1], &light_col[2]);
                   1461:        light_col[3] = 0;
                   1462: 
                   1463:        size = znode_rdlong (data);
                   1464:        
                   1465:        znode_rdvertexf (data, light_vec);
                   1466:        light_vec[3] = 0.0f;
                   1467:        
                   1468:        glLightfv (GL_LIGHT1, GL_POSITION, light_vec);
                   1469: 
                   1470:        glLightiv (GL_LIGHT1, GL_DIFFUSE, light_col);
                   1471:        glLightiv (GL_LIGHT1, GL_AMBIENT, obj_col);
                   1472: 
                   1473: //     glMaterialiv (GL_FRONT, GL_AMBIENT, obj_col);
                   1474:        glEnable (GL_LIGHTING);
                   1475:        glEnable (GL_LIGHT1);
                   1476:        glEnable (GL_NORMALIZE);
                   1477:        
                   1478:        glShadeModel (GL_SMOOTH);
                   1479: //     glColor3uiv (obj_col);
                   1480:        znode_rdvertex (data, v1);
                   1481:        znode_rdmatrix (data, rot_matrix);
                   1482: 
                   1483:        //printf ("planet size %d, pos (%d,%d,%d)\n", size,v1[0],v1[1],v1[2]);
                   1484:        
                   1485:        glPushMatrix ();
                   1486:        glTranslatef (v1[0], v1[1], v1[2]);
                   1487:        glRotatef (180.0f, 1, 0, 0);
                   1488:        glRotatef (180.0f, 0, 1, 0);
                   1489:        glMultMatrixf (rot_matrix);
                   1490:        glCullFace (GL_BACK);
                   1491:        glEnable (GL_CULL_FACE);
                   1492:        /* why the fucking fudge factor?? */
                   1493:        nuSphere (size*1.0080);
                   1494:        //gluSphere (qobj, size, 100, 100);
                   1495:        glDisable (GL_CULL_FACE);
                   1496:        glPopMatrix ();
                   1497:        
                   1498:        glDisable (GL_NORMALIZE);
                   1499:        glDisable (GL_LIGHTING);
                   1500:        glDisable (GL_LIGHT1);
                   1501: }
                   1502: 
                   1503: void Nu_PutCircle ()
                   1504: {
                   1505:        if (use_renderer == R_OLD) return;
                   1506:        znode_wrlong (NU_CIRCLE);
                   1507:        znode_wrlong (GetReg (REG_D2));
                   1508:        znode_wrvertex (GetReg (REG_A0)+4);
                   1509:        znode_wrcolor (GetReg (REG_D6));
                   1510: }
                   1511: void Nu_DrawCircle (void **data)
                   1512: {
                   1513:        int v1[3];
                   1514:        unsigned int dreg2, isize;
                   1515:        float size;
                   1516:        int r, g, b;
                   1517: 
                   1518:        dreg2 = znode_rdlong (data);
                   1519:        znode_rdvertex (data, v1);
                   1520:        znode_rdcolor (data, &r, &g, &b);
                   1521:        
                   1522:        glColor3ub (r, g, b);
                   1523: 
                   1524:        isize = (dreg2 << 16) | (dreg2 >> 16);
                   1525:        //printf ("%x (%x)\n", GetReg (2), isize);
                   1526:        
                   1527:        size = -0.002*((short)dreg2)*v1[2];
                   1528:        
                   1529:        glPushMatrix ();
                   1530:        glTranslatef (v1[0], v1[1], v1[2]);
                   1531:        gluDisk (qobj, 0.0, size, 32, 1);
                   1532:        glPopMatrix ();
                   1533: }
                   1534: 
                   1535: /* life is so strange */
                   1536: void Nu_PutCylinder ()
                   1537: {
                   1538:        if (use_renderer == R_OLD) return;
                   1539:        znode_wrlong (NU_CYLINDER);
                   1540:        znode_wrlightsource (GetReg (REG_A4));
                   1541:        znode_wrlong (GetReg (REG_D3));
                   1542:        znode_wrlong (GetReg (REG_D2));
                   1543:        znode_wrlong (GetReg (REG_D6));
                   1544:        znode_wrvertex (GetReg (REG_A2)+4);
                   1545:        znode_wrvertex (GetReg (REG_A3)+4);
                   1546:        znode_wrlong (GetReg (REG_D0));
                   1547:        znode_wrlong (GetReg (REG_D1));
                   1548:        znode_wrlong (GetReg (REG_D5));
                   1549:        znode_wrlong (GetReg (REG_D4));
                   1550: }
                   1551: void Nu_DrawCylinder (void **data)
                   1552: {
                   1553:        float light_vec[4];
                   1554:        int v1[3], v2[3];
                   1555:        float vdiff[3];
                   1556:        int rad1, rad2;
                   1557:        int light_col, obj_col, extra_col;
                   1558:        float h;
                   1559: 
                   1560:        znode_rdvertexf (data, light_vec);
                   1561:        light_col = znode_rdlong (data);
                   1562:        obj_col = znode_rdlong (data);
                   1563:        extra_col = znode_rdlong (data);
                   1564: 
                   1565:        znode_rdvertex (data, v1);
                   1566:        znode_rdvertex (data, v2);
                   1567: 
                   1568:        vdiff[0] = v2[0] - v1[0];
                   1569:        vdiff[1] = v2[1] - v1[1];
                   1570:        vdiff[2] = v2[2] - v1[2];
                   1571:        
                   1572:        h = sqrt (vdiff[0]*vdiff[0] + vdiff[1]*vdiff[1] + vdiff[2]*vdiff[2]);
                   1573:        
                   1574:        rad1 = znode_rdlong (data) & 0xffff;
                   1575:        rad2 = znode_rdlong (data) & 0xffff;
                   1576:        
                   1577:        glShadeModel (GL_SMOOTH);
                   1578:        
                   1579:        glPushMatrix ();
                   1580:        glTranslatef (v1[0], v1[1], v1[2]);
                   1581:        glRotatef (-RAD_2_DEG * (atan2 (vdiff[2], vdiff[0]) - M_PI/2), 0.0f, 1.0f, 0.0f);
                   1582:        glRotatef (-RAD_2_DEG * asin (vdiff[1]/h), 1.0f, 0.0f, 0.0f);
                   1583: #define CYLINDER_POOP  20
                   1584:        
                   1585:        lighting_on (light_vec, light_col, extra_col, znode_rdlong (data));
                   1586:        gluDisk (qobj, 0.0, rad1, CYLINDER_POOP, 1);
                   1587:        glTranslatef (0, 0, h);
                   1588:        
                   1589:        lighting_on (light_vec, light_col, extra_col, znode_rdlong (data));
                   1590:        gluDisk (qobj, 0.0, rad2, CYLINDER_POOP, 1);
                   1591:        glTranslatef (0, 0, -h);
                   1592:        
                   1593:        glEnable (GL_CULL_FACE);
                   1594:        lighting_on (light_vec, light_col, extra_col, obj_col);
                   1595:        gluCylinder (qobj, rad1, rad2, h, CYLINDER_POOP, 1);
                   1596:        glDisable (GL_CULL_FACE);
                   1597:                
                   1598:        glPopMatrix ();
                   1599:        lighting_off ();
                   1600: }
                   1601: 
                   1602: /*
                   1603:  * this primitive is WRONG.
                   1604:  */
                   1605: void Nu_PutOval ()
                   1606: {
                   1607:        if (use_renderer == R_OLD) return;
                   1608:        znode_wrlong (NU_OVALTHINGY);
                   1609:        znode_wrvertex (GetReg (REG_A0)+4);
                   1610:        
                   1611:        znode_wrlong (GetReg (REG_D3));
                   1612:        znode_wrlong (GetReg (REG_D4));
                   1613:        znode_wrlong (GetReg (REG_D5));
                   1614: 
                   1615:        znode_wrlong (GetReg (REG_D6));
                   1616: }
                   1617: void Nu_DrawOval (void **data)
                   1618: {
                   1619:        int v1[3];
                   1620:        int rad, r, g, b;
                   1621:        unsigned short d,e,f;
                   1622: 
                   1623:        znode_rdvertex (data, v1);
                   1624: 
                   1625:        r = 0;
                   1626:        g = 0;
                   1627:        b = 0;
                   1628:        
                   1629:        d = (short) znode_rdlong (data);
                   1630:        e = (short) znode_rdlong (data);
                   1631:        f = (short) znode_rdlong (data);
                   1632:        rad = (short) znode_rdlong (data);
                   1633:        
                   1634:        glColor3ub (r, g, b);
                   1635:        glPushMatrix ();
                   1636:        glTranslatef (v1[0], v1[1], v1[2]);
                   1637:        //printf ("%d,%d,%d\n", d,e,f);
                   1638:        //glRotatef (RAD_2_DEG*M_PI*(d/32768.0f), 0.0f, 1.0f, 0.0f);
                   1639:        //glRotatef (RAD_2_DEG*M_PI*(e/32768.0f), 1.0f, 0.0f, 0.0f);
                   1640:        //glRotatef (-RAD_2_DEG*M_PI*(f/65536.0f), 0.0f, 1.0f, 0.0f);
                   1641:        gluDisk (qobj, 0.0, rad, 32, 1);
                   1642:        glPopMatrix ();
                   1643: }
                   1644: 
                   1645: void Nu_PutBlob ()
                   1646: {
                   1647:        if (use_renderer == R_OLD) return;
                   1648:        znode_wrlong (NU_BLOB);
                   1649:        znode_wrvertex (GetReg (REG_A0)+4);
                   1650:        znode_wrlong (GetReg (REG_D0));
                   1651:        znode_wrlong (GetReg (REG_D1));
                   1652: }
                   1653: void Nu_DrawBlob (void **data)
                   1654: {
                   1655:        int v1[3];
                   1656:        unsigned int r, g, b;
                   1657:        int rad;
                   1658:        int edges;
                   1659:        
                   1660:        znode_rdvertex (data, v1);
                   1661:        split_rgb444i (znode_rdlong (data), &r, &g, &b);
                   1662:        rad = znode_rdlong (data) & 0xffff;
                   1663:        edges = rad+4;
1.1.1.2 ! root     1664:        
1.1       root     1665:        glColor3ui (r, g, b);
                   1666:        if (rad < 3) {
                   1667:                glPointSize ((rad/2)+1);
                   1668:                glBegin (GL_POINTS);
                   1669:                        glVertex3iv (v1);
                   1670:                glEnd ();
                   1671:        } else {
                   1672:                glPushMatrix ();
                   1673:                glTranslatef (v1[0], v1[1], v1[2]);
                   1674:                gluDisk (qobj, 0.0, -0.002*(rad)*v1[2], edges, 1);
                   1675:                glPopMatrix ();
                   1676:        }
                   1677: }
                   1678: void Nu_PutColoredPoint ()
                   1679: {
                   1680:        if (use_renderer == R_OLD) return;
                   1681:        znode_wrlong (NU_POINT);
                   1682:        znode_wrvertex (GetReg (REG_A0)+4);
                   1683:        znode_wrcolor (GetReg (REG_D0));
                   1684:        znode_wrlong (2);
                   1685: }
                   1686: 
                   1687: void Nu_PutPoint ()
                   1688: {
                   1689:        if (use_renderer == R_OLD) return;
                   1690:        znode_wrlong (NU_POINT);
                   1691:        znode_wrvertex (GetReg (REG_A0)+4);
                   1692:        znode_wrcolor (0xfff);
                   1693:        znode_wrlong (1);
                   1694: }
                   1695: void Nu_DrawPoint (void **data)
                   1696: {
                   1697:        int v1[3];
                   1698:        int point_size, r, g, b;
                   1699: 
                   1700:        if (use_renderer == R_OLD) return;
                   1701:        znode_rdvertex (data, v1);
                   1702:        znode_rdcolor (data, &r, &g, &b);
                   1703:        point_size = znode_rdlong (data);
                   1704: 
                   1705:        glPointSize (point_size);
                   1706:        glColor3ub (r, g, b);
                   1707:        glBegin (GL_POINTS);
                   1708:                glVertex3iv (v1);
                   1709:        glEnd ();
                   1710: }
                   1711: 
                   1712: void Nu_PutLine ()
                   1713: {
                   1714:        if (use_renderer == R_OLD) return;
                   1715:        znode_wrlong (NU_LINE);
                   1716:        znode_wrvertex (GetReg (REG_A0)+4);
                   1717:        znode_wrvertex (GetReg (REG_A1)+4);
                   1718:        znode_wrcolor (GetReg (REG_D6));
                   1719: }
                   1720: void Nu_DrawLine (void **data)
                   1721: {
                   1722:        int v1[3], v2[3];
                   1723:        int r, g, b;
                   1724:        
                   1725:        znode_rdvertex (data, v1);
                   1726:        znode_rdvertex (data, v2);
                   1727:        znode_rdcolor (data, &r, &g, &b);
                   1728:        
                   1729:        glColor3ub (r, g, b);
                   1730:        glBegin (GL_LINES);
                   1731:                glVertex3iv (v1);
                   1732:                glVertex3iv (v2);
                   1733:        glEnd ();
                   1734: }
                   1735: 
                   1736: void Nu_IsGLRenderer ()
                   1737: {
                   1738:        if (use_renderer == R_OLD) {
                   1739:                SetReg (0, 0);
                   1740:        } else {
                   1741:                SetReg (0, 1);
                   1742:        }
                   1743: }
                   1744: 
                   1745: void Nu_GLClearArea ()
                   1746: {
                   1747:        unsigned char *screen, *screen2;
                   1748:        int x,y,x1,x2,y1,y2;
                   1749: 
                   1750:        if (use_renderer == R_OLD) return;
                   1751:        x1 = GetReg (0)&0xffff;
                   1752:        y1 = GetReg (1)&0xffff;
                   1753:        x2 = GetReg (2)&0xffff;
                   1754:        y2 = GetReg (3)&0xffff;
                   1755:        
                   1756:        push_ortho ();
                   1757:        set_ctrl_viewport ();
                   1758:        glColor3f (0.0f, 0.0f, 0.0f);
                   1759:        glBegin (GL_TRIANGLE_STRIP);
                   1760:                glVertex3f (x1, 200-y1, 0);
                   1761:                glVertex3f (x2, 200-y1, 0);
                   1762:                glVertex3f (x1, 200-y2, 0);
                   1763:                glVertex3f (x2, 200-y2, 0);
                   1764:        glEnd ();
                   1765:        set_main_viewport ();
                   1766:        pop_ortho ();
                   1767: 
                   1768:        /* and then we wipe the bit of the ST framebuffer (on both buffers)
                   1769:         * to transparent/unset */
                   1770:        screen = (unsigned char *)PHYSCREEN;
                   1771:        screen += SCREENBYTES_LINE * y1;
                   1772:        screen2 = (unsigned char *)LOGSCREEN;
                   1773:        screen2 += SCREENBYTES_LINE * y1;
                   1774: 
                   1775:        for (y=y1; y<y2; y++) {
                   1776:                for (x=x1; x<x2; x++) {
                   1777:                        *(screen+x) = 255;
                   1778:                        *(screen2+x) = 255;
                   1779:                }
                   1780:                screen += SCREENBYTES_LINE;
                   1781:                screen2 += SCREENBYTES_LINE;
                   1782:        }
                   1783: }
                   1784: 
                   1785: typedef void (*NU_DRAWFUNC) (void **);
                   1786: NU_DRAWFUNC nu_drawfuncs[NU_MAX] = {
                   1787:        NULL,
                   1788:        &Nu_DrawTriangle,
                   1789:        &Nu_DrawQuad,
                   1790:        &Nu_DrawLine,
                   1791:        &Nu_DrawBezierLine,
                   1792:        &Nu_DrawTeardrop,
                   1793:        &Nu_DrawComplexSNext, // 6
                   1794:        &Nu_DrawComplexStart,
                   1795:        &Nu_DrawComplexEnd,
                   1796:        &Nu_DrawComplexStartInner, // 9
                   1797:        &Nu_DrawComplexBezier,
                   1798:        &Nu_DrawTwinklyCircle,
                   1799:        &Nu_DrawPlanet,
                   1800:        &Nu_DrawCircle,
                   1801:        &Nu_DrawCylinder,
                   1802:        &Nu_DrawBlob,
                   1803:        &Nu_DrawOval,
1.1.1.2 ! root     1804:        &Nu_DrawPoint,
        !          1805:        &Nu_Draw2DLine
1.1       root     1806: };
                   1807: 
                   1808: static void Nu_DrawPrimitive (void *data)
                   1809: {
                   1810:        int fnum;
                   1811:        
                   1812:        for (;;) {
                   1813:                fnum = znode_rdlong (&data);
                   1814:                //fprintf (stderr, "%d ", fnum);
                   1815:                if (!fnum) return;
                   1816:                nu_drawfuncs[fnum] (&data);
                   1817:        }
                   1818: }
                   1819: 
                   1820: /*
                   1821:  * znode_start is the head of a btree of znodes, each with a linked list
                   1822:  * of GL display lists to draw (in list order).
                   1823:  *
                   1824:  * Draw this crap starting from biggest value znodes.
                   1825:  */
                   1826: static void draw_3dview (struct ZNode *node)
                   1827: {
                   1828:        if (node == NULL) return;
                   1829:        if (node->more) draw_3dview (node->more);
                   1830:        
                   1831:        if (use_renderer) {
                   1832:                //fprintf (stderr, "Z=%d ", node->z);
                   1833:                Nu_DrawPrimitive (node->data);
                   1834:        }
                   1835: 
                   1836:        if (node->less) draw_3dview (node->less);
                   1837: }
                   1838: 
                   1839: static void set_gl_clear_col (int rgb)
                   1840: {
                   1841:        float r,g,b;
                   1842:        r = (rgb&0xff)/255.0f;
                   1843:        g = (rgb&0xff00)/65280.0f;
                   1844:        b = (rgb&0xff0000)/16711680.0f;
                   1845:        glClearColor (r,g,b,0);
                   1846: }
                   1847: 
                   1848: void Nu_DrawScreen ()
                   1849: {
1.1.1.2 ! root     1850:        /* build RGB palettes */
        !          1851:        _BuildRGBPalette (MainRGBPalette, MainPalette, len_main_palette);
        !          1852:        _BuildRGBPalette (CtrlRGBPalette, CtrlPalette, 16);
        !          1853:        
1.1       root     1854:        //fprintf (stderr, "Render: ");
                   1855:        if (znode_cur) end_node ();
                   1856:        //printf ("Frame: %d znodes.\n", znode_buf_pos);
                   1857:        draw_3dview (znode_start);
                   1858:        //fprintf (stderr, "\n");
                   1859: 
                   1860:        if (mouse_shown) {
                   1861:                SDL_ShowCursor (SDL_ENABLE);
                   1862:                mouse_shown = 0;
                   1863:        } else {
                   1864:                SDL_ShowCursor (SDL_DISABLE);
                   1865:        }
                   1866:        draw_control_panel ();
                   1867:        glFlush ();
                   1868:        
                   1869:        SDL_GL_SwapBuffers ();
                   1870: 
                   1871:        /* frontier background color... */
1.1.1.2 ! root     1872:        if (use_renderer == R_GLWIRE) {
        !          1873:                glClearColor (0,0,0,0);
        !          1874:        } else {
        !          1875:                set_gl_clear_col (MainRGBPalette[fe2_bgcol]);
        !          1876:        }
1.1       root     1877:        
                   1878:        glMatrixMode (GL_MODELVIEW);
                   1879:        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                   1880:        glLoadIdentity ();
                   1881:        
                   1882:        set_main_viewport ();
                   1883: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.