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