|
|
1.1 root 1: // vid_next.m -- NEXTSTEP video driver
2:
3: #define INTERCEPTOR
4:
5: #import <appkit/appkit.h>
6: #import <string.h>
7: #import "intercep.h"
8: #include "quakedef.h"
9: #include "d_local.h"
10:
11: int BASEWIDTH = 320;
12: int BASEHEIGHT = 200;
13:
14: void SetupBitmap (void);
15: void SetupFramebuffer (void);
16: void UpdateBitmap (void);
17: void UpdateFramebuffer (vrect_t *vrect);
18: void SetVideoEncoding (char *encoding);
19: void Update8_1 (pixel_t *src, byte *dest, int width,
20: int height, int destrowbytes);
21: void Update16_1 (pixel_t *src, unsigned short *dest, int width,
22: int height, int destrowbytes);
23: void Update32_1 (pixel_t *src, unsigned *dest, int width,
24: int height, int destrowbytes);
25:
26: void (*vid_menudrawfn)(void);
27: void (*vid_menukeyfn)(int key);
28:
29: @interface QuakeView : View
30: @end
31:
32: @interface FrameWindow:Window
33: @end
34:
35: unsigned short d_8to16table[256]; // not used in 8 bpp mode
36: unsigned d_8to24table[256]; // not used in 8 bpp mode
37:
38:
39: /*
40: ==========================================================================
41:
42: API FUNCTIONS
43:
44: ==========================================================================
45: */
46:
47: typedef enum {disp_bitmap, disp_framebuffer} display_t;
48:
49: pixel_t *vid_buffer;
50: pixel_t *buffernative;
51: unsigned pcolormap[4][256]; // map from quake pixels to native pixels
52: unsigned pixbytesnative;
53: unsigned rowbytesnative;
54: int dither;
55:
56: int drawdirect = 0;
57:
58: int d_con_indirect = 0;
59:
60: display_t vid_display;
61:
62: byte vid_palette[768]; // saved for restarting vid system
63:
64: id vid_window_i;
65: id vid_view_i;
66: #ifdef INTERCEPTOR
67: NXDirectBitmap *vid_dbitmap_i;
68: NXFramebuffer *vid_framebuffer_i;
69: #endif
70:
71: NXRect screenBounds; // only valid in framebuffer mode
72:
73: int vid_scale;
74:
75: char *vid_encodingstring;
76:
77: int vid_fullscreen;
78: int vid_screen;
79:
80: int vid_high_hunk_mark;
81:
82: typedef enum
83: {
84: enc_24_rgba,
85: enc_24_0rgb,
86: enc_24_rgb0,
87: enc_12_rgba,
88: enc_12_rgb0,
89: enc_15_0rgb,
90: enc_564,
91: enc_8_gray,
92: enc_8_rgb
93: } vid_encoding_t;
94:
95: typedef struct
96: {
97: char *string;
98: int pixelbytes;
99: void (*colormap) (void);
100: vid_encoding_t name;
101: } vidtype_t;
102:
103: vid_encoding_t vid_encoding;
104:
105: void Table8 (void);
106: void Table15 (void);
107: void Table12 (void);
108: void Table12Swap (void);
109: void Table24 (void);
110: void Table24Swap (void);
111:
112: vidtype_t vid_encodingtable[]=
113: {
114: {"RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA",4, Table24Swap, enc_24_rgba},
115: {"--------RRRRRRRRGGGGGGGGBBBBBBBB",4, Table24, enc_24_0rgb},
116: {"RRRRRRRRGGGGGGGGBBBBBBBB--------",4, Table24Swap, enc_24_rgb0},
117: {"RRRRGGGGBBBBAAAA",2, Table12Swap, enc_12_rgba},
118: {"RRRRGGGGBBBB----",2, Table12, enc_12_rgb0},
119: {"-RRRRRGGGGGBBBBB",2, Table15, enc_15_0rgb},
120: {"WWWWWWWW",1, Table8, enc_8_gray},
121: {"PPPPPPPP",1, Table8, enc_8_rgb},
122: {NULL,0, 0, 0}
123: };
124:
125: vidtype_t *vid_type;
126: void InitNS8Bit (void);
127:
128: /*
129: ================
130: D_BeginDirectRect
131: ================
132: */
133: void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
134: {
135: // direct drawing of the "accessing disk" icon isn't supported under Nextstep
136: }
137:
138:
139: /*
140: ================
141: D_EndDirectRect
142: ================
143: */
144: void D_EndDirectRect (int x, int y, int width, int height)
145: {
146: // direct drawing of the "accessing disk" icon isn't supported under Nextstep
147: }
148:
149:
150: /*
151: ==============
152: VID_Restart
153:
154: internal call only
155: ===============
156: */
157: void VID_Restart (display_t mode, int scale)
158: {
159: vid_display = mode;
160: vid_scale = scale;
161:
162: [NXApp activateSelf:YES];
163:
164: if (vid_display == disp_framebuffer)
165: SetupFramebuffer ();
166: else
167: SetupBitmap ();
168:
169: vid.recalc_refdef = 1;
170: }
171:
172:
173: /*
174: =================
175: VID_Scale_f
176:
177: Keybinding command
178: =================
179: */
180: void VID_Scale_f (void)
181: {
182: int scale;
183:
184: if (Cmd_Argc () != 2)
185: return;
186:
187: scale = atoi (Cmd_Argv(1));
188: if (scale != 1 && scale != 2)
189: {
190: Con_Printf ("scale must be 1 or 2\n");
191: return;
192: }
193: VID_Shutdown ();
194: VID_Restart (vid_display, scale);
195: }
196:
197: /*
198: =================
199: VID_Mode_f
200:
201: Keybinding command
202: =================
203: */
204: void VID_Mode_f (void)
205: {
206: int mode;
207:
208: if (Cmd_Argc () != 2)
209: return;
210:
211: mode = atoi (Cmd_Argv(1));
212:
213: VID_Shutdown ();
214: if (mode == 0)
215: {
216: drawdirect = 0;
217: VID_Restart (disp_bitmap, vid_scale);
218: }
219: else if (mode == 1)
220: {
221: drawdirect = 0;
222: VID_Restart (disp_framebuffer, vid_scale);
223: }
224: else
225: {
226: drawdirect = 1;
227: VID_Restart (disp_framebuffer, vid_scale);
228: }
229: }
230:
231: /*
232: =================
233: VID_Size_f
234:
235: Keybinding command
236: =================
237: */
238: void VID_Size_f (void)
239: {
240: if (Cmd_Argc () != 3)
241: return;
242:
243: VID_Shutdown ();
244:
245: BASEWIDTH = atoi (Cmd_Argv(1));
246: BASEHEIGHT = atoi (Cmd_Argv(2));
247:
248: VID_Restart (vid_display, vid_scale);
249: }
250:
251: /*
252: ================
253: VID_Init
254: ================
255: */
256: void VID_Init (unsigned char *palette)
257: {
258: InitNS8Bit (); // fixed palette lookups
259:
260: Q_memcpy (vid_palette, palette, sizeof(vid_palette));
261:
262: if (COM_CheckParm ("-bitmap"))
263: vid_display = disp_bitmap;
264: else
265: vid_display = disp_framebuffer;
266:
267: if (COM_CheckParm ("-screen2"))
268: vid_screen = 1;
269: else
270: vid_screen = 0;
271:
272: if (COM_CheckParm ("-direct"))
273: drawdirect = 1;
274:
275: Cmd_AddCommand ("vid_scale", VID_Scale_f);
276: Cmd_AddCommand ("vid_mode", VID_Mode_f);
277: Cmd_AddCommand ("vid_size", VID_Size_f);
278:
279: vid.width = BASEWIDTH;
280: vid.height = BASEHEIGHT;
281: vid.aspect = 1.0;
282: vid.numpages = 1;
283: vid.colormap = host_colormap;
284: vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
285: vid.maxwarpwidth = WARP_WIDTH;
286: vid.maxwarpheight = WARP_HEIGHT;
287:
288: if (COM_CheckParm ("-scale2"))
289: vid_scale = 2;
290: else
291: vid_scale = 1;
292:
293: [Application new];
294:
295: VID_Restart (vid_display, vid_scale);
296: }
297:
298:
299: /*
300: ================
301: VID_Shutdown
302: ================
303: */
304: void VID_Shutdown (void)
305: {
306: #ifdef INTERCEPTOR
307: if (vid_dbitmap_i)
308: {
309: [vid_dbitmap_i free];
310: vid_dbitmap_i = 0;
311: }
312: if (vid_framebuffer_i)
313: {
314: [vid_framebuffer_i free];
315: vid_framebuffer_i = 0;
316: }
317: #endif
318: [vid_window_i close];
319: [vid_window_i free];
320: }
321:
322:
323: /*
324: ================
325: VID_Update
326: ================
327: */
328: void VID_Update (vrect_t *rects)
329: {
330: if (drawdirect)
331: return;
332:
333: while (rects)
334: {
335: UpdateFramebuffer (rects);
336: rects = rects->pnext;
337: }
338:
339: if (vid_display == disp_bitmap)
340: UpdateBitmap ();
341: }
342:
343:
344: /*
345: ================
346: VID_SetPalette
347: ================
348: */
349: void VID_SetPalette (unsigned char *palette)
350: {
351: Q_memcpy (vid_palette, palette, sizeof(vid_palette));
352: vid_type->colormap ();
353: }
354:
355:
356: /*
357: ================
358: VID_ShiftPalette
359: ================
360: */
361: void VID_ShiftPalette (unsigned char *palette)
362: {
363:
364: VID_SetPalette (palette);
365: }
366:
367:
368: /*
369: ==========================================================================
370:
371: NS STUFF
372:
373: ==========================================================================
374: */
375:
376:
377: /*
378: =================
379: SetVideoEncoding
380: =================
381: */
382: void SetVideoEncoding (char *encoding)
383: {
384: vidtype_t *type;
385:
386: Sys_Printf ("SetVideoEncoding: %s\n",encoding);
387: vid_encodingstring = encoding;
388:
389: for (type = vid_encodingtable ; type->string ; type++)
390: {
391: if (strcmp(type->string, encoding) == 0)
392: {
393: pixbytesnative = type->pixelbytes;
394: vid_encoding = type->name;
395: type->colormap ();
396: vid_type = type;
397: return;
398: }
399: }
400:
401: Sys_Error ("Unsupported video encoding: %s\n",encoding);
402: }
403:
404: /*
405: =================
406: AllocBuffers
407: =================
408: */
409: void AllocBuffers (qboolean withnative)
410: {
411: int surfcachesize;
412: void *surfcache;
413: int pixels;
414: int pixbytes;
415: int vid_buffersize;
416:
417: if (vid_buffer)
418: {
419: D_FlushCaches ();
420: Hunk_FreeToHighMark (vid_high_hunk_mark);
421: vid_high_hunk_mark = 0;
422: vid_buffer = NULL;
423: }
424:
425: pixels = vid.width * vid.height;
426:
427: pixbytes = 1 +sizeof (*d_pzbuffer);
428: if (withnative)
429: pixbytes += pixbytesnative;
430:
431: surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height);
432: vid_buffersize = pixels * pixbytes + surfcachesize;
433:
434: vid_high_hunk_mark = Hunk_HighMark ();
435: vid_buffer = Hunk_HighAllocName (vid_buffersize, "video");
436: if (!vid_buffer)
437: Sys_Error ("Couldn't alloc video buffers");
438:
439: vid.buffer = vid_buffer;
440:
441: d_pzbuffer = (unsigned short *)((byte *)vid_buffer + pixels);
442: surfcache = (byte *)d_pzbuffer + pixels * sizeof (*d_pzbuffer);
443: if (withnative)
444: buffernative = (byte *)surfcache + surfcachesize;
445:
446: D_InitCaches (surfcache, surfcachesize);
447: }
448:
449: /*
450: =================
451: SetupFramebuffer
452: =================
453: */
454: void SetupFramebuffer (void)
455: {
456: #ifdef INTERCEPTOR
457: int windowNum;
458: NXRect cont;
459: NXScreen const *screens;
460: int screencount;
461:
462: //
463: // get the screen list
464: //
465: [NXApp getScreens:&screens count:&screencount];
466:
467: //
468: // create vid_framebuffer_i
469: //
470: vid_framebuffer_i = [[NXFramebuffer alloc]
471: initFromScreen:screens[vid_screen].screenNumber andMapIfPossible:YES];
472: [vid_framebuffer_i screenBounds:&screenBounds];
473:
474: SetVideoEncoding ([vid_framebuffer_i pixelEncoding]);
475:
476: buffernative = [vid_framebuffer_i data];
477: rowbytesnative = [vid_framebuffer_i bytesPerRow];
478:
479: //
480: // create window
481: //
482: if (vid_fullscreen)
483: {
484: vid.height = screenBounds.size.height / vid_scale;
485: vid.width = screenBounds.size.width / vid_scale;
486: cont.origin.x = 0;
487: cont.origin.y = 0;
488: cont.size.width = screenBounds.size.width;
489: cont.size.height = screenBounds.size.height;
490: }
491: else
492: {
493: buffernative = (unsigned char *)buffernative + 8 * rowbytesnative +
494: 8 * pixbytesnative;
495: vid.width = BASEWIDTH;
496: vid.height = BASEHEIGHT;
497: cont.origin.x = 8;
498: cont.origin.y = screenBounds.size.height - (vid.height*vid_scale) - 8;
499: cont.size.width = vid.width * vid_scale;
500: cont.size.height = vid.height * vid_scale;
501: }
502:
503: vid_window_i = [[FrameWindow alloc]
504: initContent: &cont
505: style: NX_PLAINSTYLE
506: backing: NX_NONRETAINED
507: buttonMask: 0
508: defer: NO
509: screen: screens+vid_screen];
510: windowNum = [vid_window_i windowNum];
511: PSsetwindowlevel(40, windowNum);
512: PSsetautofill(YES, windowNum);
513: PSgsave();
514: PSwindowdeviceround(windowNum);
515: PSsetgray(NX_BLACK);
516: PSsetexposurecolor();
517: PSgrestore();
518:
519: //
520: // create view
521: //
522: vid_view_i = [[QuakeView alloc] initFrame: &screenBounds];
523: [[vid_window_i setContentView: vid_view_i] free];
524: [vid_window_i makeFirstResponder: vid_view_i];
525: [vid_window_i setDelegate: vid_view_i];
526: [vid_window_i display];
527: [vid_window_i makeKeyAndOrderFront: nil];
528: NXPing ();
529:
530: AllocBuffers (false); // no native buffer
531:
532: if (drawdirect)
533: { // the direct drawing mode to NeXT colorspace
534: vid.buffer = buffernative;
535: vid.rowbytes = rowbytesnative;
536: }
537: else
538: vid.rowbytes = vid.width;
539:
540: vid.conbuffer = vid.buffer;
541: vid.conrowbytes = vid.rowbytes;
542: vid.conwidth = vid.width;
543: vid.conheight = vid.height;
544: #endif
545: }
546:
547: /*
548: =================
549: SetupBitmap
550: =================
551: */
552: void SetupBitmap (void)
553: {
554: int depth;
555: NXRect content;
556:
557: //
558: // open a window
559: //
560: NXSetRect (&content, 8,136, vid.width*vid_scale, vid.height*vid_scale);
561: vid_window_i = [[Window alloc]
562: initContent: &content
563: style: NX_RESIZEBARSTYLE
564: backing: NX_RETAINED
565: buttonMask: 0
566: defer: NO
567: ];
568: [vid_window_i display];
569: [vid_window_i makeKeyAndOrderFront: nil];
570:
571: NXPing ();
572:
573: content.origin.x = content.origin.y = 0;
574: vid_view_i = [[QuakeView alloc] initFrame: &content];
575: [[vid_window_i setContentView: vid_view_i] free];
576: [vid_window_i makeFirstResponder: vid_view_i];
577: [vid_window_i setDelegate: vid_view_i];
578:
579: [vid_window_i addToEventMask: NX_FLAGSCHANGEDMASK];
580:
581: //
582: // find video info
583: //
584: depth = [Window defaultDepthLimit];
585: switch (depth) {
586: case NX_EightBitGrayDepth:
587: SetVideoEncoding ("WWWWWWWW");
588: break;
589: case NX_TwelveBitRGBDepth:
590: SetVideoEncoding ("RRRRGGGGBBBBAAAA");
591: break;
592: default:
593: case NX_TwentyFourBitRGBDepth:
594: SetVideoEncoding ("RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA");
595: break;
596: // default: // 8 bit color shows up as an unknown...
597: Sys_Error ("Unsupported window depth");
598: }
599:
600: [vid_window_i setTitle: "Bitmap Quake Console"];
601:
602: //
603: // allocate memory for the back and translation buffers
604: //
605: vid.rowbytes = vid.width;
606: rowbytesnative = vid.width * pixbytesnative;
607:
608: AllocBuffers (true);
609:
610: vid.conbuffer = vid.buffer;
611: vid.conrowbytes = vid.rowbytes;
612: vid.conwidth = vid.width;
613: vid.conheight = vid.height;
614: }
615:
616:
617: /*
618: =================
619: UpdateFramebuffer
620: =================
621: */
622: void UpdateFramebuffer (vrect_t *vrect)
623: {
624: byte *psourcebase;
625: byte *pdestbase;
626: int scale;
627:
628: psourcebase = vid.buffer + vrect->x + vrect->y * vid.rowbytes;
629:
630: if (vid_display == disp_bitmap)
631: scale = 1; // let NS do the scaling
632: else
633: scale = vid_scale;
634:
635: pdestbase = buffernative + scale *
636: (vrect->x * pixbytesnative + vrect->y * rowbytesnative);
637:
638: //
639: // translate from ideal to native (except 8 bpp direct) and copy to screen
640: //
641:
642: if (pixbytesnative == 1)
643: Update8_1 (psourcebase, pdestbase, vrect->width, vrect->height,
644: rowbytesnative);
645: else if (pixbytesnative == 2)
646: Update16_1 (psourcebase, (unsigned short *)pdestbase, vrect->width, vrect->height,
647: rowbytesnative);
648: else
649: Update32_1 (psourcebase, (unsigned *)pdestbase, vrect->width, vrect->height,
650: rowbytesnative);
651: }
652:
653:
654: /*
655: =================
656: UpdateBitmap
657: =================
658: */
659: void UpdateBitmap (void)
660: {
661: unsigned char *planes[5];
662: NXRect bounds;
663: int bpp, spp, bps, bpr, colorspace;
664:
665: //
666: // flush the screen with an image call
667: //
668: if (pixbytesnative == 1)
669: {
670: bps = 8;
671: spp = 1;
672: bpp = 8;
673: bpr = vid.width;
674: colorspace = NX_OneIsWhiteColorSpace;
675: planes[0] = vid.buffer;
676: }
677: else if (pixbytesnative == 2)
678: {
679: bps = 4;
680: spp = 3;
681: bpp = 16;
682: bpr = vid.width * 2;
683: colorspace = NX_RGBColorSpace;
684: planes[0] = buffernative;
685: }
686: else
687: {
688: bps = 8;
689: spp = 3;
690: bpp = 32;
691: bpr = vid.width * 4;
692: colorspace = NX_RGBColorSpace;
693: planes[0] = buffernative;
694: }
695:
696: [vid_view_i getBounds: &bounds];
697: [vid_view_i lockFocus];
698:
699: NXDrawBitmap(
700: &bounds,
701: vid.width,
702: vid.height,
703: bps,
704: spp,
705: bpp,
706: bpr,
707: NO,
708: NO,
709: colorspace,
710: planes
711: );
712:
713: [vid_view_i unlockFocus];
714: NXPing ();
715: }
716:
717:
718:
719: /*
720: ==========================================================================
721:
722: TRANSLATION TABLE BUILDING
723:
724: ==========================================================================
725: */
726:
727: int redramp[] = {0, 19, 59, 113, 178, 255, 300};
728: int greenramp[] = {0, 11, 34, 66, 104, 149, 199, 255, 300};
729: int blueramp[] = {0, 28, 84, 161, 255, 300};
730: int greyramp[] = { 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204,
731: 221, 238, 255, 300};
732:
733: byte greytable[256];
734: byte redtable[256];
735: byte greentable[256];
736: byte bluetable[256];
737:
738: void FillTable (byte *table, int *ramp, int base)
739: {
740: int i, j, o;
741:
742: o = 0;
743: for (i=0 ; i<16 && o < 256; i++)
744: {
745: j = ramp[i];
746: for ( ; o<=j ; o++)
747: table[o] = base + i;
748: }
749: }
750:
751: void InitNS8Bit (void)
752: {
753: FillTable (greytable, greyramp, 240);
754: FillTable (redtable, redramp, 0);
755: FillTable (greentable, greenramp, 0);
756: FillTable (bluetable, blueramp, 0);
757: }
758:
759:
760: byte ns8trans[256] = // FIXME: dynamically calc this so palettes work
761: {
762: 0,241,242,243,244,244,245,246,247,248,249,250,251,252,253,254,
763: 45,241,241,242,91,91,91,96,96,136,136,136,141,141,141,141,
764: 241,46,242,243,243,97,97,97,245,246,143,143,143,143,148,148,
765: 0,5,45,45,50,50,90,90,95,95,95,95,95,140,140,141,
766: 0,40,40,40,40,80,80,80,80,80,120,120,120,120,120,120,
767: 45,50,50,90,90,95,95,135,135,135,136,141,141,181,181,181,
768: 45,90,91,91,131,131,136,136,136,176,181,181,186,226,231,236,
769: 45,45,91,91,96,96,136,136,137,142,182,182,187,188,188,233,
770: 188,249,248,247,246,137,137,137,244,243,243,91,242,241,241,45,
771: 183,183,183,247,137,137,137,137,137,244,91,91,91,241,241,45,
772: 252,251,188,188,248,248,142,142,142,244,244,243,91,242,241,45,
773: 247,247,246,246,245,245,244,244,243,243,242,242,51,241,241,5,
774: 236,231,231,191,186,185,185,140,140,135,135,95,90,90,45,45,
775: 4,49,49,53,53,93,93,93,93,92,92,92,243,242,46,241,
776: 239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
777: 239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,182
778: };
779:
780: /*
781: ===================
782: Table8
783: ===================
784: */
785: void Table8 (void)
786: {
787: byte *pal;
788: int r,g,b,v;
789: int i;
790: byte *table;
791:
792: pal = vid_palette;
793: table = (byte *)pcolormap[0];
794:
795: for (i=0 ; i<256 ; i++)
796: {
797: r = pal[0];
798: g = pal[1];
799: b = pal[2];
800: pal += 3;
801:
802: // use the grey ramp if all indexes are close
803:
804: if (r-g < 16 && r-g > -16 && r-b < 16 && r-b > -16)
805: {
806: v = (r+g+b)/3;
807: *table++ = greytable[v];
808: continue;
809: }
810:
811: r = redtable[r];
812: g = greentable[g];
813: b = bluetable[b];
814:
815: // otherwise use the color cube
816: *table++ = r*(8*5) + g*5 + b;
817: }
818: }
819:
820: /*
821: ===================
822: Table24
823: ===================
824: */
825: void Table24 (void)
826: {
827: byte *pal;
828: int r,g,b,v;
829: int i;
830: unsigned *table;
831:
832:
833: //
834: // 8 8 8 encoding
835: //
836: pal = vid_palette;
837: table = (unsigned *)pcolormap[0];
838:
839: for (i=0 ; i<256 ; i++)
840: {
841: r = pal[0];
842: g = pal[1];
843: b = pal[2];
844: pal += 3;
845:
846: v = (r<<16) + (g<<8) + b;
847: *table++ = v;
848: }
849: }
850:
851: /*
852: ===================
853: Table24Swap
854: ===================
855: */
856: void Table24Swap (void)
857: {
858: byte *pal;
859: int r,g,b,v;
860: int i;
861: unsigned *table;
862:
863: //
864: // 8 8 8 encoding
865: //
866: pal = vid_palette;
867: table = (unsigned *)pcolormap[0];
868:
869: for (i=0 ; i<256 ; i++)
870: {
871: r = pal[0];
872: g = pal[1];
873: b = pal[2];
874: pal += 3;
875:
876: v = (r<<24) + (g<<16) + (b<<8) /*+ 255*/;
877: v = NXSwapBigLongToHost (v);
878: *table++ = v;
879: }
880: }
881:
882:
883: /*
884: ===================
885: Table15
886: ===================
887: */
888: void Table15 (void)
889: {
890: byte *pal;
891: int r,g,b,v;
892: int i, k;
893: unsigned char *palette;
894: unsigned short *table;
895: int dadj;
896: int ditheradjust[4] = {(1 << 9) * 3 / 8,
897: (1 << 9) * 5 / 8,
898: (1 << 9) * 7 / 8,
899: (1 << 9) * 1 / 8};
900:
901: palette = vid_palette;
902: table = (unsigned short *)pcolormap;
903:
904: //
905: // 5 5 5 encoding
906: //
907: for (k=0 ; k<4 ; k++)
908: {
909: dadj = ditheradjust[k];
910:
911: pal = vid_palette;
912:
913: for (i=0 ; i<256 ; i++)
914: {
915: // shift 6 bits to get back to 0-255, & 3 more for 5 bit color
916: // FIXME: scale intensity levels properly
917: r = (pal[0] + dadj) >> 3;
918: g = (pal[1] + dadj) >> 3;
919: b = (pal[2] + dadj) >> 3;
920: pal += 3;
921:
922: v = (r<<10) + (g<<5) + b;
923:
924: *table++ = v;
925: }
926: }
927: }
928:
929: /*
930: ===================
931: Table12
932: ===================
933: */
934: void Table12 (void)
935: {
936: byte *pal;
937: int r,g,b,v;
938: int i, k;
939: unsigned short *table;
940: int dadj;
941: static int ditheradjust[4] = {(1 << 9) * 3 / 8,
942: (1 << 9) * 5 / 8,
943: (1 << 9) * 7 / 8,
944: (1 << 9) * 1 / 8};
945:
946: table = (unsigned short *)pcolormap;
947:
948: //
949: // 4 4 4 encoding
950: //
951: for (k=0 ; k<4 ; k++)
952: {
953: dadj = ditheradjust[k];
954:
955: pal = vid_palette;
956:
957: for (i=0 ; i<256 ; i++)
958: {
959: // shift 5 bits to get back to 0-255, & 4 more for 4 bit color
960: // FIXME: scale intensity levels properly
961: r = (pal[0] + dadj) >> 4;
962: g = (pal[1] + dadj) >> 4;
963: b = (pal[2] + dadj) >> 4;
964: pal += 3;
965:
966: v = ((r<<12) + (g<<8) + (b<<4) /*+ 15*/);
967:
968: *table++ = v;
969: }
970: }
971: }
972:
973: /*
974: ===================
975: Table12Swap
976: ===================
977: */
978: void Table12Swap (void)
979: {
980: byte *pal;
981: int r,g,b,v;
982: int i, k;
983: unsigned short *table;
984: int dadj;
985: static int ditheradjust[4] = {(1 << 9) * 3 / 8,
986: (1 << 9) * 5 / 8,
987: (1 << 9) * 7 / 8,
988: (1 << 9) * 1 / 8};
989:
990: table = (unsigned short *)pcolormap;
991:
992: //
993: // 4 4 4 encoding
994: //
995: for (k=0 ; k<4 ; k++)
996: {
997: dadj = ditheradjust[k];
998:
999: pal = vid_palette;
1000:
1001: for (i=0 ; i<256 ; i++)
1002: {
1003: // shift 5 bits to get back to 0-255, & 4 more for 4 bit color
1004: // FIXME: scale intensity levels properly
1005: r = (pal[0] + dadj) >> 4;
1006: g = (pal[1] + dadj) >> 4;
1007: b = (pal[2] + dadj) >> 4;
1008: pal += 3;
1009:
1010: v = ((r<<12) + (g<<8) + (b<<4) /*+ 15*/);
1011: v = NXSwapBigShortToHost (v);
1012:
1013: *table++ = v;
1014: }
1015: }
1016: }
1017:
1018:
1019: /*
1020: ==========================================================================
1021:
1022: GENERIC IMAGING FUNCTIONS
1023:
1024: ==========================================================================
1025: */
1026:
1027: /*
1028: ===================
1029: Update8_1
1030: ===================
1031: */
1032: void Update8_1 (pixel_t *src, byte *dest, int width, int height,
1033: int destrowbytes)
1034: {
1035: int x,y;
1036: unsigned rowdelta, srcdelta;
1037: unsigned xcount;
1038: byte *pdest;
1039: int xwidth;
1040:
1041: pdest = dest;
1042:
1043: xcount = width >> 3;
1044: srcdelta = vid.width - width;
1045:
1046: xwidth = width - (xcount << 3);
1047: if (xwidth)
1048: Sys_Error ("Width not multiple of 8");
1049:
1050: if ((vid_display == disp_framebuffer) && (vid_scale == 2))
1051: {
1052: int nextrow = destrowbytes;
1053:
1054: rowdelta = destrowbytes - (width << 1) + destrowbytes;
1055:
1056: if (dither)
1057: {
1058: unsigned short *psrc;
1059:
1060: psrc = (unsigned short *)src;
1061:
1062: for (y = height ; y ; y--)
1063: {
1064: for (x = xcount ; x ;x--)
1065: {
1066: unsigned temp;
1067:
1068: temp = psrc[0];
1069: pdest[0] = ((byte *)pcolormap[0])[temp];
1070: pdest[1] = ((byte *)pcolormap[1])[temp];
1071: pdest[nextrow] = ((byte *)pcolormap[2])[temp];
1072: pdest[nextrow + 1] = ((byte *)pcolormap[3])[temp];
1073: temp = psrc[1];
1074: pdest[2] = ((byte *)pcolormap[0])[temp];
1075: pdest[3] = ((byte *)pcolormap[1])[temp];
1076: pdest[nextrow + 2] = ((byte *)pcolormap[2])[temp];
1077: pdest[nextrow + 3] = ((byte *)pcolormap[3])[temp];
1078: temp = psrc[2];
1079: pdest[4] = ((byte *)pcolormap[0])[temp];
1080: pdest[5] = ((byte *)pcolormap[1])[temp];
1081: pdest[nextrow + 4] = ((byte *)pcolormap[2])[temp];
1082: pdest[nextrow + 5] = ((byte *)pcolormap[3])[temp];
1083: temp = psrc[3];
1084: pdest[6] = ((byte *)pcolormap[0])[temp];
1085: pdest[7] = ((byte *)pcolormap[1])[temp];
1086: pdest[nextrow + 6] = ((byte *)pcolormap[2])[temp];
1087: pdest[nextrow + 7] = ((byte *)pcolormap[3])[temp];
1088: temp = psrc[4];
1089: pdest[8] = ((byte *)pcolormap[0])[temp];
1090: pdest[9] = ((byte *)pcolormap[1])[temp];
1091: pdest[nextrow + 8] = ((byte *)pcolormap[2])[temp];
1092: pdest[nextrow + 9] = ((byte *)pcolormap[3])[temp];
1093: temp = psrc[5];
1094: pdest[10] = ((byte *)pcolormap[0])[temp];
1095: pdest[11] = ((byte *)pcolormap[1])[temp];
1096: pdest[nextrow + 10] = ((byte *)pcolormap[2])[temp];
1097: pdest[nextrow + 11] = ((byte *)pcolormap[3])[temp];
1098: temp = psrc[6];
1099: pdest[12] = ((byte *)pcolormap[0])[temp];
1100: pdest[13] = ((byte *)pcolormap[1])[temp];
1101: pdest[nextrow + 12] = ((byte *)pcolormap[2])[temp];
1102: pdest[nextrow + 13] = ((byte *)pcolormap[3])[temp];
1103: temp = psrc[7];
1104: pdest[14] = ((byte *)pcolormap[0])[temp];
1105: pdest[15] = ((byte *)pcolormap[1])[temp];
1106: pdest[nextrow + 14] = ((byte *)pcolormap[2])[temp];
1107: pdest[nextrow + 15] = ((byte *)pcolormap[3])[temp];
1108: pdest += 16; psrc += 8;
1109: }
1110:
1111: psrc += srcdelta;
1112: pdest += rowdelta;
1113: }
1114: }
1115: else
1116: {
1117: byte *psrc;
1118:
1119: psrc = (byte *)src;
1120:
1121: for (y = height ; y ; y--)
1122: {
1123: for (x = xcount ; x ;x--)
1124: {
1125: pdest[0] = pdest[1] = pdest[nextrow] =
1126: pdest[nextrow + 1] = ((byte *)pcolormap[0])[psrc[0]];
1127: pdest[2] = pdest[3] = pdest[nextrow + 2] =
1128: pdest[nextrow + 3] = ((byte *)pcolormap[0])[psrc[1]];
1129: pdest[4] = pdest[5] = pdest[nextrow + 4] =
1130: pdest[nextrow + 5] = ((byte *)pcolormap[0])[psrc[2]];
1131: pdest[6] = pdest[7] = pdest[nextrow + 6] =
1132: pdest[nextrow + 7] = ((byte *)pcolormap[0])[psrc[3]];
1133: pdest[8] = pdest[9] = pdest[nextrow + 8] =
1134: pdest[nextrow + 9] = ((byte *)pcolormap[0])[psrc[4]];
1135: pdest[10] = pdest[11] = pdest[nextrow + 10] =
1136: pdest[nextrow + 11] = ((byte *)pcolormap[0])[psrc[5]];
1137: pdest[12] = pdest[13] = pdest[nextrow + 12] =
1138: pdest[nextrow + 13] = ((byte *)pcolormap[0])[psrc[6]];
1139: pdest[14] = pdest[15] = pdest[nextrow + 14] =
1140: pdest[nextrow + 15] = ((byte *)pcolormap[0])[psrc[7]];
1141: pdest += 16; psrc += 8;
1142: }
1143:
1144: psrc += srcdelta;
1145: pdest += rowdelta;
1146: }
1147: }
1148: }
1149: else
1150: {
1151: rowdelta = destrowbytes - width;
1152:
1153: if (dither)
1154: {
1155: unsigned short *psrc;
1156:
1157: psrc = (unsigned short *)src;
1158:
1159: for (y = height ; y>0 ; y -= 2)
1160: {
1161: for (x = xcount ; x ;x--)
1162: {
1163: pdest[0] = ((byte *)pcolormap[0])[psrc[0]];
1164: pdest[1] = ((byte *)pcolormap[1])[psrc[1]];
1165: pdest[2] = ((byte *)pcolormap[0])[psrc[2]];
1166: pdest[3] = ((byte *)pcolormap[1])[psrc[3]];
1167: pdest[4] = ((byte *)pcolormap[0])[psrc[4]];
1168: pdest[5] = ((byte *)pcolormap[1])[psrc[5]];
1169: pdest[6] = ((byte *)pcolormap[0])[psrc[6]];
1170: pdest[7] = ((byte *)pcolormap[1])[psrc[7]];
1171: pdest += 8; psrc += 8;
1172: }
1173:
1174: psrc += srcdelta;
1175: pdest += rowdelta;
1176:
1177: for (x = xcount ; x ;x--)
1178: {
1179: pdest[0] = ((byte *)pcolormap[2])[psrc[0]];
1180: pdest[1] = ((byte *)pcolormap[3])[psrc[1]];
1181: pdest[2] = ((byte *)pcolormap[2])[psrc[2]];
1182: pdest[3] = ((byte *)pcolormap[3])[psrc[3]];
1183: pdest[4] = ((byte *)pcolormap[2])[psrc[4]];
1184: pdest[5] = ((byte *)pcolormap[3])[psrc[5]];
1185: pdest[6] = ((byte *)pcolormap[2])[psrc[6]];
1186: pdest[7] = ((byte *)pcolormap[3])[psrc[7]];
1187: pdest += 8; psrc += 8;
1188: }
1189:
1190: psrc += srcdelta;
1191: pdest += rowdelta;
1192: }
1193: }
1194: else
1195: {
1196: byte *psrc;
1197:
1198: psrc = (byte *)src;
1199: // srcdelta += width;
1200: // rowdelta += width;
1201:
1202: for (y = height ; y ; y--)
1203: {
1204: for (x = xcount ; x ;x--)
1205: {
1206: pdest[0] = ((byte *)pcolormap[0])[psrc[0]];
1207: pdest[1] = ((byte *)pcolormap[0])[psrc[1]];
1208: pdest[2] = ((byte *)pcolormap[0])[psrc[2]];
1209: pdest[3] = ((byte *)pcolormap[0])[psrc[3]];
1210: pdest[4] = ((byte *)pcolormap[0])[psrc[4]];
1211: pdest[5] = ((byte *)pcolormap[0])[psrc[5]];
1212: pdest[6] = ((byte *)pcolormap[0])[psrc[6]];
1213: pdest[7] = ((byte *)pcolormap[0])[psrc[7]];
1214: pdest += 8; psrc += 8;
1215: }
1216:
1217: psrc += srcdelta;
1218: pdest += rowdelta;
1219: }
1220: }
1221: }
1222: }
1223:
1224:
1225: /*
1226: ===================
1227: Update16_1
1228: ===================
1229: */
1230: void Update16_1 (pixel_t *src, unsigned short *dest, int width,
1231: int height, int destrowbytes)
1232: {
1233: int x,y;
1234: unsigned rowdelta, srcdelta;
1235: unsigned xcount;
1236: pixel_t *psrc;
1237: unsigned short *pdest;
1238: int xwidth;
1239:
1240:
1241: psrc = src;
1242: pdest = dest;
1243:
1244: xcount = width >> 3;
1245: srcdelta = vid.width - width;
1246:
1247: xwidth = width - (xcount << 3);
1248: if (xwidth)
1249: Sys_Error ("Width not multiple of 8");
1250:
1251: if ((vid_display == disp_framebuffer) && (vid_scale == 2))
1252: {
1253: int nextrow = destrowbytes >> 1;
1254:
1255: rowdelta = (destrowbytes - ((width << 1) << 1) + destrowbytes) >> 1;
1256:
1257: if (dither)
1258: {
1259: for (y = height ; y ; y--)
1260: {
1261: for (x = xcount ; x ;x--)
1262: {
1263: unsigned temp;
1264:
1265: temp = psrc[0];
1266: pdest[0] = ((unsigned short *)pcolormap[0])[temp];
1267: pdest[1] = ((unsigned short *)pcolormap[1])[temp];
1268: pdest[nextrow] = ((unsigned short *)pcolormap[2])[temp];
1269: pdest[nextrow + 1] = ((unsigned short *)pcolormap[3])[temp];
1270: temp = psrc[1];
1271: pdest[2] = ((unsigned short *)pcolormap[0])[temp];
1272: pdest[3] = ((unsigned short *)pcolormap[1])[temp];
1273: pdest[nextrow + 2] = ((unsigned short *)pcolormap[2])[temp];
1274: pdest[nextrow + 3] = ((unsigned short *)pcolormap[3])[temp];
1275: temp = psrc[2];
1276: pdest[4] = ((unsigned short *)pcolormap[0])[temp];
1277: pdest[5] = ((unsigned short *)pcolormap[1])[temp];
1278: pdest[nextrow + 4] = ((unsigned short *)pcolormap[2])[temp];
1279: pdest[nextrow + 5] = ((unsigned short *)pcolormap[3])[temp];
1280: temp = psrc[3];
1281: pdest[6] = ((unsigned short *)pcolormap[0])[temp];
1282: pdest[7] = ((unsigned short *)pcolormap[1])[temp];
1283: pdest[nextrow + 6] = ((unsigned short *)pcolormap[2])[temp];
1284: pdest[nextrow + 7] = ((unsigned short *)pcolormap[3])[temp];
1285: temp = psrc[4];
1286: pdest[8] = ((unsigned short *)pcolormap[0])[temp];
1287: pdest[9] = ((unsigned short *)pcolormap[1])[temp];
1288: pdest[nextrow + 8] = ((unsigned short *)pcolormap[2])[temp];
1289: pdest[nextrow + 9] = ((unsigned short *)pcolormap[3])[temp];
1290: temp = psrc[5];
1291: pdest[10] = ((unsigned short *)pcolormap[0])[temp];
1292: pdest[11] = ((unsigned short *)pcolormap[1])[temp];
1293: pdest[nextrow + 10] = ((unsigned short *)pcolormap[2])[temp];
1294: pdest[nextrow + 11] = ((unsigned short *)pcolormap[3])[temp];
1295: temp = psrc[6];
1296: pdest[12] = ((unsigned short *)pcolormap[0])[temp];
1297: pdest[13] = ((unsigned short *)pcolormap[1])[temp];
1298: pdest[nextrow + 12] = ((unsigned short *)pcolormap[2])[temp];
1299: pdest[nextrow + 13] = ((unsigned short *)pcolormap[3])[temp];
1300: temp = psrc[7];
1301: pdest[14] = ((unsigned short *)pcolormap[0])[temp];
1302: pdest[15] = ((unsigned short *)pcolormap[1])[temp];
1303: pdest[nextrow + 14] = ((unsigned short *)pcolormap[2])[temp];
1304: pdest[nextrow + 15] = ((unsigned short *)pcolormap[3])[temp];
1305: pdest += 16; psrc += 8;
1306: }
1307:
1308: psrc += srcdelta;
1309: pdest += rowdelta;
1310: }
1311: }
1312: else
1313: {
1314: for (y = height ; y ; y--)
1315: {
1316: for (x = xcount ; x ;x--)
1317: {
1318: pdest[0] = pdest[1] = pdest[nextrow] =
1319: pdest[nextrow + 1] = pcolormap[0][psrc[0]];
1320: pdest[2] = pdest[3] = pdest[nextrow + 2] =
1321: pdest[nextrow + 3] = pcolormap[0][psrc[1]];
1322: pdest[4] = pdest[5] = pdest[nextrow + 4] =
1323: pdest[nextrow + 5] = pcolormap[0][psrc[2]];
1324: pdest[6] = pdest[7] = pdest[nextrow + 6] =
1325: pdest[nextrow + 7] = pcolormap[0][psrc[3]];
1326: pdest[8] = pdest[9] = pdest[nextrow + 8] =
1327: pdest[nextrow + 9] = pcolormap[0][psrc[4]];
1328: pdest[10] = pdest[11] = pdest[nextrow + 10] =
1329: pdest[nextrow + 11] = pcolormap[0][psrc[5]];
1330: pdest[12] = pdest[13] = pdest[nextrow + 12] =
1331: pdest[nextrow + 13] = pcolormap[0][psrc[6]];
1332: pdest[14] = pdest[15] = pdest[nextrow + 14] =
1333: pdest[nextrow + 15] = pcolormap[0][psrc[7]];
1334: pdest += 16; psrc += 8;
1335: }
1336:
1337: psrc += srcdelta;
1338: pdest += rowdelta;
1339: }
1340: }
1341: }
1342: else
1343: {
1344: rowdelta = (destrowbytes - (width<<1))>>1;
1345:
1346: if (dither)
1347: {
1348: for (y = height ; y>0 ; y -= 2)
1349: {
1350: for (x = xcount ; x ;x--)
1351: {
1352: pdest[0] = ((unsigned short *)pcolormap[0])[psrc[0]];
1353: pdest[1] = ((unsigned short *)pcolormap[1])[psrc[1]];
1354: pdest[2] = ((unsigned short *)pcolormap[0])[psrc[2]];
1355: pdest[3] = ((unsigned short *)pcolormap[1])[psrc[3]];
1356: pdest[4] = ((unsigned short *)pcolormap[0])[psrc[4]];
1357: pdest[5] = ((unsigned short *)pcolormap[1])[psrc[5]];
1358: pdest[6] = ((unsigned short *)pcolormap[0])[psrc[6]];
1359: pdest[7] = ((unsigned short *)pcolormap[1])[psrc[7]];
1360: pdest += 8; psrc += 8;
1361: }
1362:
1363: psrc += srcdelta;
1364: pdest += rowdelta;
1365:
1366: for (x = xcount ; x ;x--)
1367: {
1368: pdest[0] = ((unsigned short *)pcolormap[2])[psrc[0]];
1369: pdest[1] = ((unsigned short *)pcolormap[3])[psrc[1]];
1370: pdest[2] = ((unsigned short *)pcolormap[2])[psrc[2]];
1371: pdest[3] = ((unsigned short *)pcolormap[3])[psrc[3]];
1372: pdest[4] = ((unsigned short *)pcolormap[2])[psrc[4]];
1373: pdest[5] = ((unsigned short *)pcolormap[3])[psrc[5]];
1374: pdest[6] = ((unsigned short *)pcolormap[2])[psrc[6]];
1375: pdest[7] = ((unsigned short *)pcolormap[3])[psrc[7]];
1376: pdest += 8; psrc += 8;
1377: }
1378:
1379: psrc += srcdelta;
1380: pdest += rowdelta;
1381: }
1382: }
1383: else
1384: {
1385: for (y = height ; y ; y--)
1386: {
1387: for (x = xcount ; x ;x--)
1388: {
1389: pdest[0] = pcolormap[0][psrc[0]];
1390: pdest[1] = pcolormap[0][psrc[1]];
1391: pdest[2] = pcolormap[0][psrc[2]];
1392: pdest[3] = pcolormap[0][psrc[3]];
1393: pdest[4] = pcolormap[0][psrc[4]];
1394: pdest[5] = pcolormap[0][psrc[5]];
1395: pdest[6] = pcolormap[0][psrc[6]];
1396: pdest[7] = pcolormap[0][psrc[7]];
1397: pdest += 8; psrc += 8;
1398: }
1399:
1400: psrc += srcdelta;
1401: pdest += rowdelta;
1402: }
1403: }
1404: }
1405: }
1406:
1407:
1408: /*
1409: ===================
1410: Update32_1
1411: ===================
1412: */
1413: void Update32_1 (pixel_t *src, unsigned *dest, int width, int height,
1414: int destrowbytes)
1415: {
1416: int x,y;
1417: unsigned rowdelta, srcdelta;
1418: unsigned xcount;
1419: pixel_t *psrc;
1420: unsigned *pdest;
1421: int xwidth;
1422:
1423: psrc = src;
1424: pdest = dest;
1425:
1426: xcount = width >> 3;
1427: srcdelta = vid.width - width;
1428:
1429: xwidth = width - (xcount << 3);
1430: if (xwidth)
1431: Sys_Error ("Width not multiple of 8");
1432:
1433: if ((vid_display == disp_framebuffer) && (vid_scale == 2))
1434: {
1435: int nextrow = destrowbytes >> 2;
1436:
1437: rowdelta = ((destrowbytes - ((width << 1) << 2)) >> 2) +
1438: (destrowbytes >> 2);
1439:
1440: for (y = height ; y ; y--)
1441: {
1442: for (x = xcount ; x ;x--)
1443: {
1444: pdest[0] = pdest[1] = pdest[nextrow] =
1445: pdest[nextrow + 1] = pcolormap[0][psrc[0]];
1446: pdest[2] = pdest[3] = pdest[nextrow + 2] =
1447: pdest[nextrow + 3] = pcolormap[0][psrc[1]];
1448: pdest[4] = pdest[5] = pdest[nextrow + 4] =
1449: pdest[nextrow + 5] = pcolormap[0][psrc[2]];
1450: pdest[6] = pdest[7] = pdest[nextrow + 6] =
1451: pdest[nextrow + 7] = pcolormap[0][psrc[3]];
1452: pdest[8] = pdest[9] = pdest[nextrow + 8] =
1453: pdest[nextrow + 9] = pcolormap[0][psrc[4]];
1454: pdest[10] = pdest[11] = pdest[nextrow + 10] =
1455: pdest[nextrow + 11] = pcolormap[0][psrc[5]];
1456: pdest[12] = pdest[13] = pdest[nextrow + 12] =
1457: pdest[nextrow + 13] = pcolormap[0][psrc[6]];
1458: pdest[14] = pdest[15] = pdest[nextrow + 14] =
1459: pdest[nextrow + 15] = pcolormap[0][psrc[7]];
1460: pdest += 16; psrc += 8;
1461: }
1462:
1463: psrc += srcdelta;
1464: pdest += rowdelta;
1465: }
1466: }
1467: else
1468: {
1469: rowdelta = (destrowbytes - (width<<2))>>2;
1470:
1471: for (y = height ; y ; y--)
1472: {
1473: for (x = xcount ; x ;x--)
1474: {
1475: pdest[0] = pcolormap[0][psrc[0]];
1476: pdest[1] = pcolormap[0][psrc[1]];
1477: pdest[2] = pcolormap[0][psrc[2]];
1478: pdest[3] = pcolormap[0][psrc[3]];
1479: pdest[4] = pcolormap[0][psrc[4]];
1480: pdest[5] = pcolormap[0][psrc[5]];
1481: pdest[6] = pcolormap[0][psrc[6]];
1482: pdest[7] = pcolormap[0][psrc[7]];
1483: pdest += 8; psrc += 8;
1484: }
1485:
1486: psrc += srcdelta;
1487: pdest += rowdelta;
1488: }
1489: }
1490: }
1491:
1492:
1493: /*
1494: ==========================================================================
1495:
1496: NEXTSTEP VIEW CLASS
1497:
1498: ==========================================================================
1499: */
1500:
1501:
1502: @implementation QuakeView
1503:
1504: /*
1505: =================
1506: windowDidMove
1507:
1508: =================
1509: */
1510: - windowDidMove:sender
1511: {
1512: NXPoint aPoint;
1513: NXRect winframe;
1514:
1515: aPoint.x = aPoint.y = 0;
1516: [self convertPoint:&aPoint toView:nil];
1517: [window convertBaseToScreen: &aPoint];
1518: [window getFrame: &winframe];
1519:
1520: if ((int)aPoint.x & 7)
1521: {
1522: [window moveTo:winframe.origin.x - ((int)aPoint.x&7)
1523: :winframe.origin.y];
1524: [window getFrame: &winframe];
1525: }
1526: return self;
1527: }
1528:
1529: - windowWillResize:sender toSize:(NXSize *)frameSize
1530: {
1531: NXRect fr, cont;
1532:
1533: fr.origin.x = fr.origin.y = 0;
1534: fr.size = *frameSize;
1535:
1536: [Window getContentRect:&cont forFrameRect: &fr style:[window style]];
1537:
1538: cont.size.width = (int)cont.size.width & ~15;
1539: if (cont.size.width < 128)
1540: cont.size.width = 128;
1541: cont.size.height = (int)cont.size.height & ~3;
1542: if (cont.size.height < 32)
1543: cont.size.height = 32;
1544:
1545: [Window getFrameRect:&fr forContentRect: &cont style:[window style]];
1546:
1547: *frameSize = fr.size;
1548:
1549: return self;
1550: }
1551:
1552: - windowDidResize:sender
1553: {
1554: if (vid_display == disp_framebuffer)
1555: Sys_Error ("How the heck are you resizing a framebuffer window?!?");
1556:
1557: vid.width = bounds.size.width/vid_scale;
1558: vid.height = bounds.size.height/vid_scale;
1559:
1560: //
1561: // allocate memory for the back and translation buffers
1562: //
1563: vid.rowbytes = vid.width;
1564: rowbytesnative = vid.width * pixbytesnative;
1565:
1566: AllocBuffers (true);
1567:
1568: vid.conbuffer = vid.buffer;
1569: vid.conrowbytes = vid.rowbytes;
1570: vid.conwidth = vid.width;
1571: vid.conheight = vid.height;
1572:
1573: vid.recalc_refdef = 1;
1574:
1575: return self;
1576: }
1577:
1578: -(BOOL) acceptsFirstResponder
1579: {
1580: return YES;
1581: }
1582:
1583:
1584: typedef struct
1585: {
1586: int source, dest;
1587: } keymap_t;
1588:
1589: keymap_t keymaps[] =
1590: {
1591: {103, K_RIGHTARROW},
1592: {102, K_LEFTARROW},
1593: {100, K_UPARROW},
1594: {101, K_DOWNARROW},
1595: {111, K_PAUSE},
1596:
1597: {59, K_F1},
1598: {60, K_F2},
1599: {61, K_F3},
1600: {62, K_F4},
1601: {63, K_F5},
1602: {64, K_F6},
1603: {65, K_F7},
1604: {66, K_F8},
1605: {67, K_F9},
1606: {68, K_F10},
1607: {87, K_F11},
1608: {88, K_F12},
1609:
1610: {-1,-1}
1611: };
1612:
1613: keymap_t flagmaps[] =
1614: {
1615: {NX_SHIFTMASK, K_SHIFT},
1616: {NX_CONTROLMASK, K_CTRL},
1617: {NX_ALTERNATEMASK, K_ALT},
1618: {NX_COMMANDMASK, K_ALT},
1619:
1620: {-1,-1}
1621: };
1622:
1623: /*
1624: ===================
1625: keyboard methods
1626: ===================
1627: */
1628: - keyDown:(NXEvent *)theEvent
1629: {
1630: int ch;
1631: keymap_t *km;
1632:
1633: PSobscurecursor ();
1634:
1635: // check for non-ascii first
1636: ch = theEvent->data.key.keyCode;
1637: for (km=keymaps;km->source!=-1;km++)
1638: if (ch == km->source)
1639: {
1640: Key_Event (km->dest, true);
1641: return self;
1642: }
1643:
1644: ch = theEvent->data.key.charCode;
1645: if (ch >= 'A' && ch <= 'Z')
1646: ch += 'a' - 'A';
1647: if (ch>=256)
1648: return self;
1649:
1650: Key_Event (ch, true);
1651: return self;
1652: }
1653:
1654: - flagsChanged:(NXEvent *)theEvent
1655: {
1656: static int oldflags;
1657: int newflags;
1658: int delta;
1659: keymap_t *km;
1660: int i;
1661:
1662: PSobscurecursor ();
1663: newflags = theEvent->flags;
1664: delta = newflags ^ oldflags;
1665: for (i=0 ; i<32 ; i++)
1666: {
1667: if ( !(delta & (1<<i)))
1668: continue;
1669: // changed
1670: for (km=flagmaps;km->source!=-1;km++)
1671: if ( (1<<i) == km->source)
1672: {
1673: if (newflags & (1<<i))
1674: Key_Event (km->dest, true);
1675: else
1676: Key_Event (km->dest, false);
1677: }
1678:
1679: }
1680:
1681: oldflags = newflags;
1682:
1683: return self;
1684: }
1685:
1686:
1687: - keyUp:(NXEvent *)theEvent
1688: {
1689: int ch;
1690: keymap_t *km;
1691:
1692: // check for non-ascii first
1693: ch = theEvent->data.key.keyCode;
1694: for (km=keymaps;km->source!=-1;km++)
1695: if (ch == km->source)
1696: {
1697: Key_Event (km->dest, false);
1698: return self;
1699: }
1700:
1701: ch = theEvent->data.key.charCode;
1702: if (ch >= 'A' && ch <= 'Z')
1703: ch += 'a' - 'A';
1704: if (ch>=256)
1705: return self;
1706: Key_Event (ch, false);
1707: return self;
1708: }
1709:
1710:
1711: - tiffShot
1712: {
1713: id imagerep, image;
1714: NXRect r;
1715: NXStream *stream;
1716: int fd;
1717: int i;
1718: char tiffname[80];
1719:
1720: [vid_window_i getFrame: &r];
1721: r.origin.x = r.origin.y = 0;
1722: image = [[NXImage alloc] initSize: &r.size];
1723: imagerep = [[NXCachedImageRep alloc] initFromWindow:vid_window_i rect:&r];
1724:
1725: [image lockFocus];
1726: [imagerep draw];
1727: [image unlockFocus];
1728:
1729: //
1730: // find a file name to save it to
1731: //
1732: strcpy(tiffname,"quake00.tif");
1733:
1734: for (i=0 ; i<=99 ; i++)
1735: {
1736: tiffname[5] = i/10 + '0';
1737: tiffname[6] = i%10 + '0';
1738: if (Sys_FileTime(tiffname) == -1)
1739: break; // file doesn't exist
1740: }
1741: if (i==100)
1742: Sys_Error ("SCR_ScreenShot_f: Couldn't create a tiff");
1743:
1744: fd = open (tiffname, O_RDWR|O_CREAT|O_TRUNC, 0666);
1745: stream = NXOpenFile (fd, NX_READWRITE);
1746: [image writeTIFF: stream];
1747: NXClose (stream);
1748: close (fd);
1749: printf ("wrote %s\n", tiffname);
1750:
1751: [image free];
1752: [imagerep free];
1753: return self;
1754:
1755: }
1756:
1757: - screenShot: sender
1758: {
1759: return [self tiffShot];
1760: }
1761:
1762: - setScaleFullScreen: sender
1763: {
1764: VID_Shutdown ();
1765: if (vid_fullscreen)
1766: {
1767: vid_fullscreen = 0;
1768: VID_Restart (vid_display, vid_scale);
1769: }
1770: else
1771: {
1772: vid_fullscreen = 1;
1773: VID_Restart (vid_display, vid_scale);
1774: }
1775: return self;
1776: }
1777:
1778: @end
1779:
1780: //============================================================================
1781:
1782: @implementation FrameWindow
1783:
1784: - windowExposed:(NXEvent *)theEvent
1785: {
1786: return self;
1787: }
1788:
1789: @end
1790:
1791:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.