|
|
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.