|
|
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, ! 700: NU_MAX ! 701: }; ! 702: ! 703: static inline void end_node () ! 704: { ! 705: znode_wrlong (0); ! 706: } ! 707: ! 708: static void add_node (struct ZNode **node, unsigned int zval) ! 709: { ! 710: assert (znode_buf_pos < MAX_ZNODES); ! 711: /* end previous znode display list!!!!!!! */ ! 712: if (znode_cur) end_node (); ! 713: ! 714: *node = znode_cur = &znode_buf[znode_buf_pos++]; ! 715: znode_cur->z = zval; ! 716: znode_cur->less = NULL; ! 717: znode_cur->more = NULL; ! 718: znode_databegin (); ! 719: } ! 720: ! 721: static void znode_insert (struct ZNode *node, unsigned int zval) ! 722: { ! 723: if (zval > node->z) { ! 724: if (node->more) { ! 725: znode_insert (node->more, zval); ! 726: } else { ! 727: add_node (&node->more, zval); ! 728: } ! 729: } else { ! 730: if (node->less) { ! 731: znode_insert (node->less, zval); ! 732: } else { ! 733: add_node (&node->less, zval); ! 734: } ! 735: } ! 736: } ! 737: ! 738: static bool no_znodes_kthx; ! 739: ! 740: void Nu_InsertZNode () ! 741: { ! 742: unsigned int zval = GetReg (4); ! 743: if (use_renderer == R_OLD) return; ! 744: if (no_znodes_kthx) return; ! 745: if (znode_start == NULL) { ! 746: add_node (&znode_start, zval); ! 747: } else { ! 748: znode_insert (znode_start, zval); ! 749: } ! 750: } ! 751: ! 752: void Nu_3DViewInit () ! 753: { ! 754: queued_string_pos = 0; ! 755: //printf ("3dviewinit()\n"); ! 756: znode_buf_pos = 0; ! 757: //printf ("%d bytes object data\n", obj_data_pos); ! 758: obj_data_pos = 0; ! 759: ! 760: //add_node (&znode_start, 0); ! 761: znode_start = NULL; ! 762: znode_cur = NULL; ! 763: } ! 764: ! 765: static void lighting_on (float light_vec[4], int rgb444_light_col, int rgb444_extra_col, int rgb444_obj_col) ! 766: { ! 767: bool do_not_light; ! 768: unsigned int extra_col[4], obj_col[4], light_col[4]; ! 769: ! 770: do_not_light = rgb444_obj_col & (1<<8); ! 771: ! 772: /* object color bit 0x8 set means DO NOT LIGHT */ ! 773: if (do_not_light) { ! 774: rgb444_obj_col ^= (1<<8); ! 775: } else { ! 776: split_rgb444i (rgb444_light_col, &light_col[0], &light_col[1], &light_col[2]); ! 777: light_col[3] = 0; ! 778: light_vec[3] = 0.0f; ! 779: } ! 780: ! 781: if (rgb444_obj_col & (1<<4)) { ! 782: rgb444_obj_col ^= (1<<4); ! 783: split_rgb444i (rgb444_obj_col, &obj_col[0], &obj_col[1], &obj_col[2]); ! 784: split_rgb444i (rgb444_extra_col, &extra_col[0], &extra_col[1], &extra_col[2]); ! 785: obj_col[0] += extra_col[0]; ! 786: obj_col[1] += extra_col[1]; ! 787: obj_col[2] += extra_col[2]; ! 788: } else { ! 789: split_rgb444i (rgb444_obj_col, &obj_col[0], &obj_col[1], &obj_col[2]); ! 790: } ! 791: obj_col[3] = 0; ! 792: ! 793: if (do_not_light) { ! 794: glDisable (GL_LIGHTING); ! 795: glDisable (GL_LIGHT0); ! 796: glColor3ui (obj_col[0], obj_col[1], obj_col[2]); ! 797: } else { ! 798: glLightfv (GL_LIGHT0, GL_POSITION, light_vec); ! 799: glLightiv (GL_LIGHT0, GL_DIFFUSE, light_col); ! 800: glLightiv (GL_LIGHT0, GL_AMBIENT, obj_col); ! 801: glEnable (GL_LIGHTING); ! 802: glEnable (GL_LIGHT0); ! 803: } ! 804: } ! 805: ! 806: static void lighting_off () ! 807: { ! 808: glDisable (GL_LIGHTING); ! 809: glDisable (GL_LIGHT0); ! 810: } ! 811: ! 812: void CALLBACK beginCallback(GLenum which) ! 813: { ! 814: glBegin(which); ! 815: } ! 816: ! 817: void CALLBACK errorCallback(GLenum errorCode) ! 818: { ! 819: const GLubyte *estring; ! 820: ! 821: estring = gluErrorString(errorCode); ! 822: fprintf(stderr, "Tessellation Error: %s\n", estring); ! 823: } ! 824: ! 825: void CALLBACK endCallback(void) ! 826: { ! 827: glEnd(); ! 828: } ! 829: ! 830: static int complex_col[3]; ! 831: void CALLBACK vertexCallback(GLvoid *vertex, GLvoid *poly_data) ! 832: { ! 833: const GLdouble *pointer; ! 834: ! 835: pointer = (GLdouble *) vertex; ! 836: glColor3ub (complex_col[0], complex_col[1], complex_col[2]); ! 837: glVertex3dv(pointer); ! 838: } ! 839: /* combineCallback is used to create a new vertex when edges ! 840: * intersect. coordinate location is trivial to calculate, ! 841: * but weight[4] may be used to average color, normal, or texture ! 842: * coordinate data. In this program, color is weighted. ! 843: */ ! 844: void CALLBACK combineCallback(GLdouble coords[3], ! 845: GLdouble *vertex_data[4], ! 846: GLfloat weight[4], GLdouble **dataOut ) ! 847: { ! 848: GLdouble vertex[6]; ! 849: ! 850: //vertex = (GLdouble *) malloc(6 * sizeof(GLdouble)); ! 851: ! 852: vertex[0] = coords[0]; ! 853: vertex[1] = coords[1]; ! 854: vertex[2] = coords[2]; ! 855: *dataOut = vertex; ! 856: } ! 857: #define MAX_TESS_VERTICES 400 ! 858: static GLdouble tess_vertices[MAX_TESS_VERTICES][3]; ! 859: static int tess_vpos; ! 860: ! 861: static bool do_start_complex; ! 862: static int complex_col_rgb444; ! 863: ! 864: static void put_complex_start_4real () ! 865: { ! 866: znode_wrlong (NU_COMPLEX_START); ! 867: znode_wrcolor (complex_col_rgb444); ! 868: no_znodes_kthx = TRUE; ! 869: } ! 870: ! 871: void Nu_ComplexSNext () ! 872: { ! 873: if (use_renderer == R_OLD) return; ! 874: if (do_start_complex) { put_complex_start_4real (); do_start_complex = FALSE; } ! 875: znode_wrlong (NU_COMPLEX_SNEXT); ! 876: znode_wrvertex (GetReg (REG_A0)+4); ! 877: } ! 878: void Nu_DrawComplexSNext (void **data) ! 879: { ! 880: if (use_renderer == R_GLWIRE) { ! 881: znode_rdvertexd (data, tess_vertices[tess_vpos]); ! 882: glVertex3dv (tess_vertices[tess_vpos++]); ! 883: } else { ! 884: assert (tess_vpos < MAX_TESS_VERTICES); ! 885: znode_rdvertexd (data, tess_vertices[tess_vpos]); ! 886: gluTessVertex (tobj, tess_vertices[tess_vpos], tess_vertices[tess_vpos]); ! 887: tess_vpos++; ! 888: } ! 889: } ! 890: void Nu_ComplexSBegin () ! 891: { ! 892: Nu_ComplexSNext (); ! 893: } ! 894: ! 895: void Nu_ComplexStart () ! 896: { ! 897: if (use_renderer == R_OLD) return; ! 898: do_start_complex = TRUE; ! 899: complex_col_rgb444 = GetReg (REG_D6); ! 900: } ! 901: void Nu_DrawComplexStart (void **data) ! 902: { ! 903: tess_vpos = 0; ! 904: ! 905: if (use_renderer == R_GL) { ! 906: gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); ! 907: gluTessBeginPolygon (tobj, NULL); ! 908: gluTessBeginContour (tobj); ! 909: } else { ! 910: glBegin (GL_LINE_STRIP); ! 911: } ! 912: znode_rdcolor (data, &complex_col[0], &complex_col[1], &complex_col[2]); ! 913: glColor3ub (complex_col[0], complex_col[1], complex_col[2]); ! 914: } ! 915: ! 916: ! 917: void Nu_ComplexEnd () ! 918: { ! 919: if (use_renderer == R_OLD) return; ! 920: if (do_start_complex) { put_complex_start_4real (); do_start_complex = FALSE; } ! 921: znode_wrlong (NU_COMPLEX_END); ! 922: do_start_complex = FALSE; ! 923: no_znodes_kthx = FALSE; ! 924: } ! 925: void Nu_DrawComplexEnd (void **data) ! 926: { ! 927: if (use_renderer == R_GL) { ! 928: gluTessEndContour (tobj); ! 929: gluTessEndPolygon (tobj); ! 930: } else if (use_renderer == R_GLWIRE) { ! 931: glVertex3dv (tess_vertices[0]); ! 932: glEnd (); ! 933: } ! 934: } ! 935: ! 936: void Nu_ComplexStartInner () ! 937: { ! 938: if (use_renderer == R_OLD) return; ! 939: if (do_start_complex) { put_complex_start_4real (); do_start_complex = FALSE; } ! 940: znode_wrlong (NU_COMPLEX_INNER); ! 941: } ! 942: void Nu_DrawComplexStartInner (void **data) ! 943: { ! 944: if (use_renderer == R_GL) { ! 945: gluTessEndContour (tobj); ! 946: gluTessBeginContour (tobj); ! 947: } else if (use_renderer == R_GLWIRE) { ! 948: glEnd (); ! 949: glBegin (GL_LINE_STRIP); ! 950: tess_vpos = 0; ! 951: } ! 952: } ! 953: ! 954: #define BEZIER_STEPS 10 ! 955: static void eval_bezier (GLdouble *out, float _t, float ctrlpoints[4][3]) ! 956: { ! 957: float a,b,c,d,t2; ! 958: t2 = _t*_t; ! 959: c = 1.0f-_t; ! 960: d = t2*_t; ! 961: b = c*c; ! 962: a = b*c; ! 963: b = b*_t*3.0f; ! 964: c = c*3.0f*t2; ! 965: /* x */ ! 966: out[0] = ! 967: ctrlpoints[0][0] * a + ! 968: ctrlpoints[1][0] * b + ! 969: ctrlpoints[2][0] * c + ! 970: ctrlpoints[3][0] * d; ! 971: /* y */ ! 972: out[1] = ! 973: ctrlpoints[0][1] * a + ! 974: ctrlpoints[1][1] * b + ! 975: ctrlpoints[2][1] * c + ! 976: ctrlpoints[3][1] * d; ! 977: /* y */ ! 978: out[2] = ! 979: ctrlpoints[0][2] * a + ! 980: ctrlpoints[1][2] * b + ! 981: ctrlpoints[2][2] * c + ! 982: ctrlpoints[3][2] * d; ! 983: } ! 984: ! 985: void Nu_ComplexBezier () ! 986: { ! 987: if (use_renderer == R_OLD) return; ! 988: if (do_start_complex) { put_complex_start_4real (); do_start_complex = FALSE; } ! 989: znode_wrlong (NU_COMPLEX_BEZIER); ! 990: znode_wrvertex (GetReg (REG_A0)+4); ! 991: znode_wrvertex (GetReg (REG_A1)+4); ! 992: znode_wrvertex (GetReg (REG_A2)+4); ! 993: znode_wrvertex (GetReg (REG_A3)+4); ! 994: } ! 995: void Nu_DrawComplexBezier (void **data) ! 996: { ! 997: int i, bezier_steps; ! 998: float delta; ! 999: double v[3]; ! 1000: GLfloat ctrlpoints[4][3]; ! 1001: ! 1002: znode_rdvertexf (data, ctrlpoints[0]); ! 1003: znode_rdvertexf (data, ctrlpoints[1]); ! 1004: znode_rdvertexf (data, ctrlpoints[2]); ! 1005: znode_rdvertexf (data, ctrlpoints[3]); ! 1006: ! 1007: /*float poo = MAX (abs (ctrlpoints[0][0]-ctrlpoints[3][0]), ! 1008: abs (ctrlpoints[0][1]-ctrlpoints[3][1])); ! 1009: poo /= MIN (ctrlpoints[0][2], ctrlpoints[3][2]); ! 1010: bezier_steps = MIN (6 - 20*poo, 16);*/ ! 1011: //printf ("%d ", bezier_steps); ! 1012: bezier_steps = 10; ! 1013: ! 1014: assert (tess_vpos + bezier_steps < MAX_TESS_VERTICES); ! 1015: delta = 1.0f/bezier_steps; ! 1016: ! 1017: if (use_renderer == R_GLWIRE) { ! 1018: tess_vertices[tess_vpos][0] = ctrlpoints[0][0]; ! 1019: tess_vertices[tess_vpos][1] = ctrlpoints[0][1]; ! 1020: tess_vertices[tess_vpos++][2] = ctrlpoints[0][2]; ! 1021: for (i=0; i<=bezier_steps; i++) { ! 1022: eval_bezier (v, i*delta, ctrlpoints); ! 1023: glVertex3dv (v); ! 1024: } ! 1025: return; ! 1026: } ! 1027: /* the tessellator prefers it :-) */ ! 1028: eval_bezier (&tess_vertices[tess_vpos][0], 0.001, ctrlpoints); ! 1029: gluTessVertex (tobj, tess_vertices[tess_vpos], tess_vertices[tess_vpos]); ! 1030: tess_vpos++; ! 1031: ! 1032: for (i=1; i<bezier_steps; i++) { ! 1033: eval_bezier (&tess_vertices[tess_vpos][0], i*delta, ctrlpoints); ! 1034: gluTessVertex (tobj, tess_vertices[tess_vpos], tess_vertices[tess_vpos]); ! 1035: tess_vpos++; ! 1036: } ! 1037: eval_bezier (&tess_vertices[tess_vpos][0], 0.999, ctrlpoints); ! 1038: gluTessVertex (tobj, tess_vertices[tess_vpos], tess_vertices[tess_vpos]); ! 1039: tess_vpos++; ! 1040: } ! 1041: ! 1042: ! 1043: /* For engines and industry chimney flares. ! 1044: * This is a bit crap, as you will see by panning around the effect. */ ! 1045: void Nu_PutTeardrop () ! 1046: { ! 1047: if (use_renderer == R_OLD) return; ! 1048: znode_wrlong (NU_TEARDROP); ! 1049: znode_wrvertex (GetReg (REG_A0)+4); ! 1050: znode_wrvertex (GetReg (REG_A1)+4); ! 1051: znode_wrcolor (GetReg (REG_D6)); ! 1052: } ! 1053: void Nu_DrawTeardrop (void **data) ! 1054: { ! 1055: int i; ! 1056: float delta; ! 1057: GLfloat ctrlpoints[4][3]; ! 1058: GLfloat dir[3], ppd[3]; ! 1059: GLdouble out[3]; ! 1060: int r, g, b; ! 1061: ! 1062: #define TD_STRETCH 1.3333333333 ! 1063: #define TD_BROADEN 0.33 ! 1064: #define TD_BEZIER_STEPS 40 ! 1065: ! 1066: if (use_renderer == R_OLD) return; ! 1067: znode_rdvertexf (data, dir); ! 1068: znode_rdvertexf (data, ctrlpoints[0]); ! 1069: znode_rdcolor (data, &r, &g, &b); ! 1070: ! 1071: dir[0] -= ctrlpoints[0][0]; ! 1072: dir[1] -= ctrlpoints[0][1]; ! 1073: dir[2] -= ctrlpoints[0][2]; ! 1074: ! 1075: ppd[0] = -dir[1]; ! 1076: ppd[1] = dir[0]; ! 1077: ppd[2] = dir[2]; ! 1078: ! 1079: //h = sqrt (dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]); ! 1080: ! 1081: ctrlpoints[1][0] = ctrlpoints[0][0] + TD_STRETCH*dir[0] + TD_BROADEN*ppd[0]; ! 1082: ctrlpoints[1][1] = ctrlpoints[0][1] + TD_STRETCH*dir[1] + TD_BROADEN*ppd[1]; ! 1083: ctrlpoints[1][2] = ctrlpoints[0][2] + dir[2]; ! 1084: ! 1085: ctrlpoints[2][0] = ctrlpoints[0][0] + TD_STRETCH*dir[0] - TD_BROADEN*ppd[0]; ! 1086: ctrlpoints[2][1] = ctrlpoints[0][1] + TD_STRETCH*dir[1] - TD_BROADEN*ppd[1]; ! 1087: ctrlpoints[2][2] = ctrlpoints[0][2] + dir[2]; ! 1088: ! 1089: ctrlpoints[3][0] = ctrlpoints[0][0]; ! 1090: ctrlpoints[3][1] = ctrlpoints[0][1]; ! 1091: ctrlpoints[3][2] = ctrlpoints[0][2]; ! 1092: ! 1093: delta = 1.0f/TD_BEZIER_STEPS; ! 1094: glColor3ub (r, g, b); ! 1095: glBegin (GL_TRIANGLE_FAN); ! 1096: /* the tessellator prefers it :-) */ ! 1097: for (i=0; i<=TD_BEZIER_STEPS; i++) { ! 1098: eval_bezier (out, i*delta, ctrlpoints); ! 1099: glVertex3dv (out); ! 1100: } ! 1101: glEnd (); ! 1102: } ! 1103: ! 1104: ! 1105: void Nu_PutBezierLine () ! 1106: { ! 1107: if (use_renderer == R_OLD) return; ! 1108: znode_wrlong (NU_BEZIER_LINE); ! 1109: znode_wrvertex (GetReg (REG_A0)+4); ! 1110: znode_wrvertex (GetReg (REG_A1)+4); ! 1111: znode_wrvertex (GetReg (REG_A2)+4); ! 1112: znode_wrvertex (GetReg (REG_A3)+4); ! 1113: znode_wrcolor (GetReg (REG_D6)); ! 1114: } ! 1115: void Nu_DrawBezierLine (void **data) ! 1116: { ! 1117: int i, r, g, b; ! 1118: GLfloat ctrlpoints[4][3]; ! 1119: GLfloat delta; ! 1120: GLdouble out[3]; ! 1121: ! 1122: znode_rdvertexf (data, ctrlpoints[0]); ! 1123: znode_rdvertexf (data, ctrlpoints[1]); ! 1124: znode_rdvertexf (data, ctrlpoints[2]); ! 1125: znode_rdvertexf (data, ctrlpoints[3]); ! 1126: znode_rdcolor (data, &r, &g, &b); ! 1127: ! 1128: delta = 1.0f/20; ! 1129: glColor3ub (r, g, b); ! 1130: glBegin (GL_LINE_STRIP); ! 1131: for (i=0; i<=20; i++) { ! 1132: eval_bezier (out, i*delta, ctrlpoints); ! 1133: glVertex3dv (out); ! 1134: } ! 1135: glEnd (); ! 1136: } ! 1137: ! 1138: void Nu_PutTriangle () ! 1139: { ! 1140: if (use_renderer == R_OLD) return; ! 1141: znode_wrlong (NU_TRIANGLE); ! 1142: znode_wrvertex (GetReg (REG_A0)+4); ! 1143: znode_wrvertex (GetReg (REG_A1)+4); ! 1144: znode_wrvertex (GetReg (REG_A2)+4); ! 1145: znode_wrcolor (GetReg (REG_D6)); ! 1146: } ! 1147: void Nu_DrawTriangle (void **data) ! 1148: { ! 1149: float v1[3], v2[3], v3[3]; ! 1150: int rgb[3]; ! 1151: ! 1152: znode_rdvertexf (data, v1); ! 1153: znode_rdvertexf (data, v2); ! 1154: znode_rdvertexf (data, v3); ! 1155: znode_rdcolorv (data, rgb); ! 1156: glColor3ub (rgb[0], rgb[1], rgb[2]); ! 1157: if (use_renderer == R_GLWIRE) { ! 1158: glBegin (GL_LINE_STRIP); ! 1159: glVertex3fv (v1); ! 1160: glVertex3fv (v2); ! 1161: glVertex3fv (v3); ! 1162: glVertex3fv (v1); ! 1163: glEnd (); ! 1164: } else { ! 1165: glBegin (GL_TRIANGLES); ! 1166: glVertex3fv (v1); ! 1167: glVertex3fv (v2); ! 1168: glVertex3fv (v3); ! 1169: glEnd (); ! 1170: } ! 1171: } ! 1172: ! 1173: void Nu_PutQuad () ! 1174: { ! 1175: if (use_renderer == R_OLD) return; ! 1176: znode_wrlong (NU_QUAD); ! 1177: znode_wrvertex (GetReg (REG_A0)+4); ! 1178: znode_wrvertex (GetReg (REG_A1)+4); ! 1179: znode_wrvertex (GetReg (REG_A2)+4); ! 1180: znode_wrvertex (GetReg (REG_A3)+4); ! 1181: znode_wrcolor (GetReg (REG_D6)); ! 1182: } ! 1183: void Nu_DrawQuad (void **data) ! 1184: { ! 1185: int v1[3], v2[3], v3[3], v4[3]; ! 1186: int r, g, b; ! 1187: ! 1188: znode_rdvertex (data, v1); ! 1189: znode_rdvertex (data, v2); ! 1190: znode_rdvertex (data, v3); ! 1191: znode_rdvertex (data, v4); ! 1192: znode_rdcolor (data, &r, &g, &b); ! 1193: ! 1194: glColor3ub (r, g, b); ! 1195: if (use_renderer == R_GLWIRE) { ! 1196: glBegin (GL_LINE_STRIP); ! 1197: glVertex3iv (v1); ! 1198: glVertex3iv (v2); ! 1199: glVertex3iv (v3); ! 1200: glVertex3iv (v4); ! 1201: glVertex3iv (v1); ! 1202: glEnd (); ! 1203: } else { ! 1204: glBegin (GL_TRIANGLE_STRIP); ! 1205: glVertex3iv (v1); ! 1206: glVertex3iv (v2); ! 1207: glVertex3iv (v4); ! 1208: glVertex3iv (v3); ! 1209: glEnd (); ! 1210: } ! 1211: } ! 1212: void Nu_PutTwinklyCircle () ! 1213: { ! 1214: if (use_renderer == R_OLD) return; ! 1215: znode_wrlong (NU_TWINKLYCIRCLE); ! 1216: znode_wrlong (GetReg (REG_D2)); ! 1217: znode_wrvertex (GetReg (REG_A0)+4); ! 1218: znode_wrcolor (GetReg (REG_D6)); ! 1219: } ! 1220: void Nu_DrawTwinklyCircle (void **data) ! 1221: { ! 1222: int v1[3]; ! 1223: unsigned int dreg2, isize; ! 1224: float size; ! 1225: int r, g, b; ! 1226: ! 1227: dreg2 = znode_rdlong (data); ! 1228: znode_rdvertex (data, v1); ! 1229: znode_rdcolor (data, &r, &g, &b); ! 1230: ! 1231: glColor3ub (r, g, b); ! 1232: ! 1233: isize = (dreg2 << 16) | (dreg2 >> 16); ! 1234: //printf ("%x (%x)\n", GetReg (2), isize); ! 1235: ! 1236: size = -0.002*((short)dreg2)*v1[2]; ! 1237: ! 1238: glPushMatrix (); ! 1239: glTranslatef (v1[0], v1[1], v1[2]); ! 1240: ! 1241: if (size > 0.0f) gluDisk (qobj, 0.0, size, 32, 1); ! 1242: ! 1243: size = -0.002*((short) dreg2)*v1[2] - 0.016*v1[2]; ! 1244: ! 1245: //printf ("Size %.2f\n", size); ! 1246: if (size > 0.0f) { ! 1247: glBegin (GL_LINES); ! 1248: glVertex3f (-size, 0.0f, 0.0f); ! 1249: glVertex3f (+size, 0.0f, 0.0f); ! 1250: glVertex3f (0.0f, -size, 0.0f); ! 1251: glVertex3f (0.0f, +size, 0.0f); ! 1252: glEnd (); ! 1253: } ! 1254: glPopMatrix (); ! 1255: } ! 1256: ! 1257: #define NUS_X 0.525731112119133606 ! 1258: #define NUS_Z 0.850650808352039932 ! 1259: ! 1260: static float nus_vdata[12][3] = { ! 1261: {-NUS_X, 0.0, NUS_Z}, {NUS_X, 0.0, NUS_Z}, {-NUS_X, 0.0, -NUS_Z}, {NUS_X, 0.0, -NUS_Z}, ! 1262: {0.0, NUS_Z, NUS_X}, {0.0, NUS_Z, -NUS_X}, {0.0, -NUS_Z, NUS_X}, {0.0, -NUS_Z, -NUS_X}, ! 1263: {NUS_Z, NUS_X, 0.0}, {-NUS_Z, NUS_X, 0.0}, {NUS_Z, -NUS_X, 0.0}, {-NUS_Z, -NUS_X, 0.0} ! 1264: }; ! 1265: ! 1266: static int nus_tindices[20][3] = { ! 1267: {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1}, ! 1268: {8,10,1}, {8,3,10},{5,3,8}, {5,2,3}, {2,7,3}, ! 1269: {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, ! 1270: {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} ! 1271: }; ! 1272: ! 1273: static void Normalise (float v[3]) ! 1274: { ! 1275: float d = sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); ! 1276: d = 1.0f / d; ! 1277: v[0] *= d; ! 1278: v[1] *= d; ! 1279: v[2] *= d; ! 1280: } ! 1281: ! 1282: static void nuSubdivide (float v1[3], float v2[3], float v3[3], int depth) ! 1283: { ! 1284: float v12[3], v23[3], v31[3]; ! 1285: int i; ! 1286: ! 1287: if (depth == 0) { ! 1288: glBegin (GL_POLYGON); ! 1289: glNormal3fv (v1); glVertex3fv (v1); ! 1290: glNormal3fv (v2); glVertex3fv (v2); ! 1291: glNormal3fv (v3); glVertex3fv (v3); ! 1292: glEnd (); ! 1293: return; ! 1294: } ! 1295: ! 1296: for (i=0; i<3; i++) { ! 1297: v12[i] = v1[i]+v2[i]; ! 1298: v23[i] = v2[i]+v3[i]; ! 1299: v31[i] = v3[i]+v1[i]; ! 1300: } ! 1301: Normalise (v12); ! 1302: Normalise (v23); ! 1303: Normalise (v31); ! 1304: nuSubdivide(v1, v12, v31, depth-1); ! 1305: nuSubdivide(v2, v23, v12, depth-1); ! 1306: nuSubdivide(v3, v31, v23, depth-1); ! 1307: nuSubdivide(v12, v23, v31, depth-1); ! 1308: } ! 1309: ! 1310: /* ! 1311: static void NormCrossProd (float v1[3], float v2[3], float vout[3]) ! 1312: { ! 1313: vout[0] = v1[1]*v2[2] - v1[2]*v2[1]; ! 1314: vout[1] = v1[2]*v2[0] - v1[0]*v2[2]; ! 1315: vout[2] = v1[0]*v2[1] - v1[1]*v2[0]; ! 1316: Normalise (vout); ! 1317: }*/ ! 1318: ! 1319: #define NUSPHERE_SUBDIVS 4 ! 1320: ! 1321: void nuSphere (float size) ! 1322: { ! 1323: int i; ! 1324: glScalef (size, size, size); ! 1325: for (i=0; i<20; i++) { ! 1326: nuSubdivide (nus_vdata[nus_tindices[i][0]], ! 1327: nus_vdata[nus_tindices[i][1]], ! 1328: nus_vdata[nus_tindices[i][2]], ! 1329: NUSPHERE_SUBDIVS); ! 1330: } ! 1331: } ! 1332: ! 1333: /* not finished by a long shot */ ! 1334: void Nu_PutPlanet () ! 1335: { ! 1336: if (use_renderer == R_OLD) return; ! 1337: ! 1338: /*{ ! 1339: int cunt, i; ! 1340: cunt = GetReg (REG_A6); ! 1341: cunt -= 36; ! 1342: printf ("Cuntrix:"); ! 1343: for (i=0; i<9; i++) { ! 1344: if (((i)%3) == 0) printf ("\n"); ! 1345: printf ("%04hx ", STMemory_ReadWord (cunt)); ! 1346: cunt += 2; ! 1347: } ! 1348: printf ("\n"); ! 1349: }*/ ! 1350: ! 1351: znode_wrlong (NU_PLANET); ! 1352: znode_wrlong (GetReg (REG_D6)); ! 1353: znode_wrlong (GetReg (REG_D1)); ! 1354: znode_wrlong (GetReg (REG_D0)); ! 1355: /* lighting vector */ ! 1356: znode_wrlightsource (GetReg (REG_A1)); ! 1357: znode_wrvertex (GetReg (REG_A0)+4); ! 1358: znode_wrmatrix (GetReg (REG_A6)-36); ! 1359: } ! 1360: void Nu_DrawPlanet (void **data) ! 1361: { ! 1362: int v1[3]; ! 1363: int size; ! 1364: float light_vec[4]; ! 1365: GLfloat rot_matrix[16]; ! 1366: unsigned int obj_col[4], light_col[4]; ! 1367: ! 1368: /*obj_col[0] = 1000000000; ! 1369: obj_col[1] = 1000000000; ! 1370: obj_col[2] = 1000000000; ! 1371: obj_col[3] = 0;*/ ! 1372: split_rgb444i (znode_rdlong (data), &obj_col[0], &obj_col[1], &obj_col[2]); ! 1373: obj_col[3] = 0; ! 1374: split_rgb444i (znode_rdlong (data), &light_col[0], &light_col[1], &light_col[2]); ! 1375: light_col[3] = 0; ! 1376: ! 1377: size = znode_rdlong (data); ! 1378: ! 1379: znode_rdvertexf (data, light_vec); ! 1380: light_vec[3] = 0.0f; ! 1381: ! 1382: glLightfv (GL_LIGHT1, GL_POSITION, light_vec); ! 1383: ! 1384: glLightiv (GL_LIGHT1, GL_DIFFUSE, light_col); ! 1385: glLightiv (GL_LIGHT1, GL_AMBIENT, obj_col); ! 1386: ! 1387: // glMaterialiv (GL_FRONT, GL_AMBIENT, obj_col); ! 1388: glEnable (GL_LIGHTING); ! 1389: glEnable (GL_LIGHT1); ! 1390: glEnable (GL_NORMALIZE); ! 1391: ! 1392: glShadeModel (GL_SMOOTH); ! 1393: // glColor3uiv (obj_col); ! 1394: znode_rdvertex (data, v1); ! 1395: znode_rdmatrix (data, rot_matrix); ! 1396: ! 1397: //printf ("planet size %d, pos (%d,%d,%d)\n", size,v1[0],v1[1],v1[2]); ! 1398: ! 1399: glPushMatrix (); ! 1400: glTranslatef (v1[0], v1[1], v1[2]); ! 1401: glRotatef (180.0f, 1, 0, 0); ! 1402: glRotatef (180.0f, 0, 1, 0); ! 1403: glMultMatrixf (rot_matrix); ! 1404: glCullFace (GL_BACK); ! 1405: glEnable (GL_CULL_FACE); ! 1406: /* why the fucking fudge factor?? */ ! 1407: nuSphere (size*1.0080); ! 1408: //gluSphere (qobj, size, 100, 100); ! 1409: glDisable (GL_CULL_FACE); ! 1410: glPopMatrix (); ! 1411: ! 1412: glDisable (GL_NORMALIZE); ! 1413: glDisable (GL_LIGHTING); ! 1414: glDisable (GL_LIGHT1); ! 1415: } ! 1416: ! 1417: void Nu_PutCircle () ! 1418: { ! 1419: if (use_renderer == R_OLD) return; ! 1420: znode_wrlong (NU_CIRCLE); ! 1421: znode_wrlong (GetReg (REG_D2)); ! 1422: znode_wrvertex (GetReg (REG_A0)+4); ! 1423: znode_wrcolor (GetReg (REG_D6)); ! 1424: } ! 1425: void Nu_DrawCircle (void **data) ! 1426: { ! 1427: int v1[3]; ! 1428: unsigned int dreg2, isize; ! 1429: float size; ! 1430: int r, g, b; ! 1431: ! 1432: dreg2 = znode_rdlong (data); ! 1433: znode_rdvertex (data, v1); ! 1434: znode_rdcolor (data, &r, &g, &b); ! 1435: ! 1436: glColor3ub (r, g, b); ! 1437: ! 1438: isize = (dreg2 << 16) | (dreg2 >> 16); ! 1439: //printf ("%x (%x)\n", GetReg (2), isize); ! 1440: ! 1441: size = -0.002*((short)dreg2)*v1[2]; ! 1442: ! 1443: glPushMatrix (); ! 1444: glTranslatef (v1[0], v1[1], v1[2]); ! 1445: gluDisk (qobj, 0.0, size, 32, 1); ! 1446: glPopMatrix (); ! 1447: } ! 1448: ! 1449: /* life is so strange */ ! 1450: void Nu_PutCylinder () ! 1451: { ! 1452: if (use_renderer == R_OLD) return; ! 1453: znode_wrlong (NU_CYLINDER); ! 1454: znode_wrlightsource (GetReg (REG_A4)); ! 1455: znode_wrlong (GetReg (REG_D3)); ! 1456: znode_wrlong (GetReg (REG_D2)); ! 1457: znode_wrlong (GetReg (REG_D6)); ! 1458: znode_wrvertex (GetReg (REG_A2)+4); ! 1459: znode_wrvertex (GetReg (REG_A3)+4); ! 1460: znode_wrlong (GetReg (REG_D0)); ! 1461: znode_wrlong (GetReg (REG_D1)); ! 1462: znode_wrlong (GetReg (REG_D5)); ! 1463: znode_wrlong (GetReg (REG_D4)); ! 1464: } ! 1465: void Nu_DrawCylinder (void **data) ! 1466: { ! 1467: float light_vec[4]; ! 1468: int v1[3], v2[3]; ! 1469: float vdiff[3]; ! 1470: int rad1, rad2; ! 1471: int light_col, obj_col, extra_col; ! 1472: float h; ! 1473: ! 1474: znode_rdvertexf (data, light_vec); ! 1475: light_col = znode_rdlong (data); ! 1476: obj_col = znode_rdlong (data); ! 1477: extra_col = znode_rdlong (data); ! 1478: ! 1479: znode_rdvertex (data, v1); ! 1480: znode_rdvertex (data, v2); ! 1481: ! 1482: vdiff[0] = v2[0] - v1[0]; ! 1483: vdiff[1] = v2[1] - v1[1]; ! 1484: vdiff[2] = v2[2] - v1[2]; ! 1485: ! 1486: h = sqrt (vdiff[0]*vdiff[0] + vdiff[1]*vdiff[1] + vdiff[2]*vdiff[2]); ! 1487: ! 1488: rad1 = znode_rdlong (data) & 0xffff; ! 1489: rad2 = znode_rdlong (data) & 0xffff; ! 1490: ! 1491: glShadeModel (GL_SMOOTH); ! 1492: ! 1493: glPushMatrix (); ! 1494: glTranslatef (v1[0], v1[1], v1[2]); ! 1495: glRotatef (-RAD_2_DEG * (atan2 (vdiff[2], vdiff[0]) - M_PI/2), 0.0f, 1.0f, 0.0f); ! 1496: glRotatef (-RAD_2_DEG * asin (vdiff[1]/h), 1.0f, 0.0f, 0.0f); ! 1497: #define CYLINDER_POOP 20 ! 1498: ! 1499: lighting_on (light_vec, light_col, extra_col, znode_rdlong (data)); ! 1500: gluDisk (qobj, 0.0, rad1, CYLINDER_POOP, 1); ! 1501: glTranslatef (0, 0, h); ! 1502: ! 1503: lighting_on (light_vec, light_col, extra_col, znode_rdlong (data)); ! 1504: gluDisk (qobj, 0.0, rad2, CYLINDER_POOP, 1); ! 1505: glTranslatef (0, 0, -h); ! 1506: ! 1507: glEnable (GL_CULL_FACE); ! 1508: lighting_on (light_vec, light_col, extra_col, obj_col); ! 1509: gluCylinder (qobj, rad1, rad2, h, CYLINDER_POOP, 1); ! 1510: glDisable (GL_CULL_FACE); ! 1511: ! 1512: glPopMatrix (); ! 1513: lighting_off (); ! 1514: } ! 1515: ! 1516: /* ! 1517: * this primitive is WRONG. ! 1518: */ ! 1519: void Nu_PutOval () ! 1520: { ! 1521: if (use_renderer == R_OLD) return; ! 1522: znode_wrlong (NU_OVALTHINGY); ! 1523: znode_wrvertex (GetReg (REG_A0)+4); ! 1524: ! 1525: znode_wrlong (GetReg (REG_D3)); ! 1526: znode_wrlong (GetReg (REG_D4)); ! 1527: znode_wrlong (GetReg (REG_D5)); ! 1528: ! 1529: znode_wrlong (GetReg (REG_D6)); ! 1530: } ! 1531: void Nu_DrawOval (void **data) ! 1532: { ! 1533: int v1[3]; ! 1534: int rad, r, g, b; ! 1535: unsigned short d,e,f; ! 1536: ! 1537: znode_rdvertex (data, v1); ! 1538: ! 1539: r = 0; ! 1540: g = 0; ! 1541: b = 0; ! 1542: ! 1543: d = (short) znode_rdlong (data); ! 1544: e = (short) znode_rdlong (data); ! 1545: f = (short) znode_rdlong (data); ! 1546: rad = (short) znode_rdlong (data); ! 1547: ! 1548: glColor3ub (r, g, b); ! 1549: glPushMatrix (); ! 1550: glTranslatef (v1[0], v1[1], v1[2]); ! 1551: //printf ("%d,%d,%d\n", d,e,f); ! 1552: //glRotatef (RAD_2_DEG*M_PI*(d/32768.0f), 0.0f, 1.0f, 0.0f); ! 1553: //glRotatef (RAD_2_DEG*M_PI*(e/32768.0f), 1.0f, 0.0f, 0.0f); ! 1554: //glRotatef (-RAD_2_DEG*M_PI*(f/65536.0f), 0.0f, 1.0f, 0.0f); ! 1555: gluDisk (qobj, 0.0, rad, 32, 1); ! 1556: glPopMatrix (); ! 1557: } ! 1558: ! 1559: void Nu_PutBlob () ! 1560: { ! 1561: if (use_renderer == R_OLD) return; ! 1562: znode_wrlong (NU_BLOB); ! 1563: znode_wrvertex (GetReg (REG_A0)+4); ! 1564: znode_wrlong (GetReg (REG_D0)); ! 1565: znode_wrlong (GetReg (REG_D1)); ! 1566: } ! 1567: void Nu_DrawBlob (void **data) ! 1568: { ! 1569: int v1[3]; ! 1570: unsigned int r, g, b; ! 1571: int rad; ! 1572: int edges; ! 1573: ! 1574: znode_rdvertex (data, v1); ! 1575: split_rgb444i (znode_rdlong (data), &r, &g, &b); ! 1576: rad = znode_rdlong (data) & 0xffff; ! 1577: edges = rad+4; ! 1578: ! 1579: glColor3ui (r, g, b); ! 1580: if (rad < 3) { ! 1581: glPointSize ((rad/2)+1); ! 1582: glBegin (GL_POINTS); ! 1583: glVertex3iv (v1); ! 1584: glEnd (); ! 1585: } else { ! 1586: glPushMatrix (); ! 1587: glTranslatef (v1[0], v1[1], v1[2]); ! 1588: gluDisk (qobj, 0.0, -0.002*(rad)*v1[2], edges, 1); ! 1589: glPopMatrix (); ! 1590: } ! 1591: } ! 1592: void Nu_PutColoredPoint () ! 1593: { ! 1594: if (use_renderer == R_OLD) return; ! 1595: znode_wrlong (NU_POINT); ! 1596: znode_wrvertex (GetReg (REG_A0)+4); ! 1597: znode_wrcolor (GetReg (REG_D0)); ! 1598: znode_wrlong (2); ! 1599: } ! 1600: ! 1601: void Nu_PutPoint () ! 1602: { ! 1603: if (use_renderer == R_OLD) return; ! 1604: znode_wrlong (NU_POINT); ! 1605: znode_wrvertex (GetReg (REG_A0)+4); ! 1606: znode_wrcolor (0xfff); ! 1607: znode_wrlong (1); ! 1608: } ! 1609: void Nu_DrawPoint (void **data) ! 1610: { ! 1611: int v1[3]; ! 1612: int point_size, r, g, b; ! 1613: ! 1614: if (use_renderer == R_OLD) return; ! 1615: znode_rdvertex (data, v1); ! 1616: znode_rdcolor (data, &r, &g, &b); ! 1617: point_size = znode_rdlong (data); ! 1618: ! 1619: glPointSize (point_size); ! 1620: glColor3ub (r, g, b); ! 1621: glBegin (GL_POINTS); ! 1622: glVertex3iv (v1); ! 1623: glEnd (); ! 1624: } ! 1625: ! 1626: void Nu_PutLine () ! 1627: { ! 1628: if (use_renderer == R_OLD) return; ! 1629: znode_wrlong (NU_LINE); ! 1630: znode_wrvertex (GetReg (REG_A0)+4); ! 1631: znode_wrvertex (GetReg (REG_A1)+4); ! 1632: znode_wrcolor (GetReg (REG_D6)); ! 1633: } ! 1634: void Nu_DrawLine (void **data) ! 1635: { ! 1636: int v1[3], v2[3]; ! 1637: int r, g, b; ! 1638: ! 1639: znode_rdvertex (data, v1); ! 1640: znode_rdvertex (data, v2); ! 1641: znode_rdcolor (data, &r, &g, &b); ! 1642: ! 1643: glColor3ub (r, g, b); ! 1644: glBegin (GL_LINES); ! 1645: glVertex3iv (v1); ! 1646: glVertex3iv (v2); ! 1647: glEnd (); ! 1648: } ! 1649: ! 1650: void Nu_IsGLRenderer () ! 1651: { ! 1652: if (use_renderer == R_OLD) { ! 1653: SetReg (0, 0); ! 1654: } else { ! 1655: SetReg (0, 1); ! 1656: } ! 1657: } ! 1658: ! 1659: void Nu_GLClearArea () ! 1660: { ! 1661: unsigned char *screen, *screen2; ! 1662: int x,y,x1,x2,y1,y2; ! 1663: ! 1664: if (use_renderer == R_OLD) return; ! 1665: x1 = GetReg (0)&0xffff; ! 1666: y1 = GetReg (1)&0xffff; ! 1667: x2 = GetReg (2)&0xffff; ! 1668: y2 = GetReg (3)&0xffff; ! 1669: ! 1670: push_ortho (); ! 1671: set_ctrl_viewport (); ! 1672: glColor3f (0.0f, 0.0f, 0.0f); ! 1673: glBegin (GL_TRIANGLE_STRIP); ! 1674: glVertex3f (x1, 200-y1, 0); ! 1675: glVertex3f (x2, 200-y1, 0); ! 1676: glVertex3f (x1, 200-y2, 0); ! 1677: glVertex3f (x2, 200-y2, 0); ! 1678: glEnd (); ! 1679: set_main_viewport (); ! 1680: pop_ortho (); ! 1681: ! 1682: /* and then we wipe the bit of the ST framebuffer (on both buffers) ! 1683: * to transparent/unset */ ! 1684: screen = (unsigned char *)PHYSCREEN; ! 1685: screen += SCREENBYTES_LINE * y1; ! 1686: screen2 = (unsigned char *)LOGSCREEN; ! 1687: screen2 += SCREENBYTES_LINE * y1; ! 1688: ! 1689: for (y=y1; y<y2; y++) { ! 1690: for (x=x1; x<x2; x++) { ! 1691: *(screen+x) = 255; ! 1692: *(screen2+x) = 255; ! 1693: } ! 1694: screen += SCREENBYTES_LINE; ! 1695: screen2 += SCREENBYTES_LINE; ! 1696: } ! 1697: } ! 1698: ! 1699: typedef void (*NU_DRAWFUNC) (void **); ! 1700: NU_DRAWFUNC nu_drawfuncs[NU_MAX] = { ! 1701: NULL, ! 1702: &Nu_DrawTriangle, ! 1703: &Nu_DrawQuad, ! 1704: &Nu_DrawLine, ! 1705: &Nu_DrawBezierLine, ! 1706: &Nu_DrawTeardrop, ! 1707: &Nu_DrawComplexSNext, // 6 ! 1708: &Nu_DrawComplexStart, ! 1709: &Nu_DrawComplexEnd, ! 1710: &Nu_DrawComplexStartInner, // 9 ! 1711: &Nu_DrawComplexBezier, ! 1712: &Nu_DrawTwinklyCircle, ! 1713: &Nu_DrawPlanet, ! 1714: &Nu_DrawCircle, ! 1715: &Nu_DrawCylinder, ! 1716: &Nu_DrawBlob, ! 1717: &Nu_DrawOval, ! 1718: &Nu_DrawPoint ! 1719: }; ! 1720: ! 1721: static void Nu_DrawPrimitive (void *data) ! 1722: { ! 1723: int fnum; ! 1724: ! 1725: for (;;) { ! 1726: fnum = znode_rdlong (&data); ! 1727: //fprintf (stderr, "%d ", fnum); ! 1728: if (!fnum) return; ! 1729: nu_drawfuncs[fnum] (&data); ! 1730: } ! 1731: } ! 1732: ! 1733: /* ! 1734: * znode_start is the head of a btree of znodes, each with a linked list ! 1735: * of GL display lists to draw (in list order). ! 1736: * ! 1737: * Draw this crap starting from biggest value znodes. ! 1738: */ ! 1739: static void draw_3dview (struct ZNode *node) ! 1740: { ! 1741: if (node == NULL) return; ! 1742: if (node->more) draw_3dview (node->more); ! 1743: ! 1744: if (use_renderer) { ! 1745: //fprintf (stderr, "Z=%d ", node->z); ! 1746: Nu_DrawPrimitive (node->data); ! 1747: } ! 1748: ! 1749: if (node->less) draw_3dview (node->less); ! 1750: } ! 1751: ! 1752: static void set_gl_clear_col (int rgb) ! 1753: { ! 1754: float r,g,b; ! 1755: r = (rgb&0xff)/255.0f; ! 1756: g = (rgb&0xff00)/65280.0f; ! 1757: b = (rgb&0xff0000)/16711680.0f; ! 1758: glClearColor (r,g,b,0); ! 1759: } ! 1760: ! 1761: void Nu_DrawScreen () ! 1762: { ! 1763: //fprintf (stderr, "Render: "); ! 1764: if (znode_cur) end_node (); ! 1765: //printf ("Frame: %d znodes.\n", znode_buf_pos); ! 1766: draw_3dview (znode_start); ! 1767: //fprintf (stderr, "\n"); ! 1768: ! 1769: if (mouse_shown) { ! 1770: SDL_ShowCursor (SDL_ENABLE); ! 1771: mouse_shown = 0; ! 1772: } else { ! 1773: SDL_ShowCursor (SDL_DISABLE); ! 1774: } ! 1775: /* build RGB palettes */ ! 1776: _BuildRGBPalette (MainRGBPalette, MainPalette, len_main_palette); ! 1777: _BuildRGBPalette (CtrlRGBPalette, CtrlPalette, 16); ! 1778: ! 1779: draw_control_panel (); ! 1780: glFlush (); ! 1781: ! 1782: SDL_GL_SwapBuffers (); ! 1783: ! 1784: /* frontier background color... */ ! 1785: set_gl_clear_col (MainRGBPalette[fe2_bgcol]); ! 1786: ! 1787: glMatrixMode (GL_MODELVIEW); ! 1788: glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ! 1789: glLoadIdentity (); ! 1790: ! 1791: set_main_viewport (); ! 1792: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.