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