|
|
1.1 root 1:
2: #import <AppKit/AppKit.h>
3: #include "../ref_soft/r_local.h"
4:
5: /*
6: ====================================================================
7:
8: OPENSTEP specific stuff
9:
10: ====================================================================
11: */
12:
13: @interface QuakeView : NSView
14: @end
15:
16: NSWindow *vid_window_i;
17: QuakeView *vid_view_i;
18:
19: unsigned *buffernative;
20:
21: //===========================================================
22:
23:
24: int Draw_SetResolution (void);
25:
26: #define TYPE_FULLSCREEN 0
27: #define TYPE_WINDOWED 1
28: #define TYPE_STRETCHED 2
29:
30: #define NUM_RESOLUTIONS 7
31: int resolutions[NUM_RESOLUTIONS][2] = {
32: {320,200}, {320,240}, {400,300}, {512,384}, {640,480}, {800,600}, {1024,768} };
33:
34: qboolean available[NUM_RESOLUTIONS][3];
35: int mode_res = 0, mode_type = TYPE_WINDOWED;
36:
37: byte gammatable[256]; // palette is sent through this
38: unsigned current_palette[256];
39: unsigned gamma_palette[256];
40:
41: int cursor_res, cursor_type;
42:
43: cvar_t *vid_x;
44: cvar_t *vid_y;
45: cvar_t *vid_mode;
46: cvar_t *vid_stretched;
47: cvar_t *vid_fullscreen;
48: cvar_t *draw_gamma;
49:
50: void Draw_BuildGammaTable (void);
51:
52: /*
53: ====================================================================
54:
55: MENU INTERACTION
56:
57: ====================================================================
58: */
59:
60: void FindModes (void)
61: {
62: if (mode_res < 0 || mode_res >= NUM_RESOLUTIONS)
63: mode_res = 0;
64: if (mode_type < 0 || mode_type > 3)
65: mode_type = 1;
66:
67: }
68:
69: void RM_Print (int x, int y, char *s)
70: {
71: while (*s)
72: {
73: Draw_Char (x, y, (*s)+128);
74: s++;
75: x += 8;
76: }
77: }
78:
79: /*
80: ================
81: Draw_MenuDraw
82: ================
83: */
84: void Draw_MenuDraw (void)
85: {
86: int i, j;
87: int y;
88: char string[32];
89:
90: Draw_Pic ( 4, 4, "vidmodes");
91:
92: RM_Print (80, 32, "fullscreen windowed stretched");
93: RM_Print (80, 40, "---------- -------- ---------");
94: y = 50;
95:
96: // draw background behind selected mode
97: Draw_Fill ( (mode_type+1)*80, y+(mode_res)*10, 40,10, 8);
98:
99: // draw available grid
100: for (i=0 ; i<NUM_RESOLUTIONS ; i++, y+= 10)
101: {
102: sprintf (string, "%ix%i", resolutions[i][0], resolutions[i][1]);
103: RM_Print (0, y, string);
104: for (j=0 ; j<3 ; j++)
105: if (available[i][j])
106: RM_Print ( 80 + j*80, y, "*");
107: }
108:
109: // draw the cursor
110: Draw_Char (80 + cursor_type*80, 50 + cursor_res*10, 128 + 12+((int)(r_newrefdef.time*4)&1));
111: }
112:
113:
114: #define K_TAB 9
115: #define K_ENTER 13
116: #define K_ESCAPE 27
117: #define K_SPACE 32
118:
119: // normal keys should be passed as lowercased ascii
120:
121: #define K_BACKSPACE 127
122: #define K_UPARROW 128
123: #define K_DOWNARROW 129
124: #define K_LEFTARROW 130
125: #define K_RIGHTARROW 131
126:
127: /*
128: ================
129: Draw_MenuKey
130: ================
131: */
132: void Draw_MenuKey (int key)
133: {
134: switch (key)
135: {
136: case K_LEFTARROW:
137: cursor_type--;
138: if (cursor_type < 0)
139: cursor_type = 2;
140: break;
141:
142: case K_RIGHTARROW:
143: cursor_type++;
144: if (cursor_type > 2)
145: cursor_type = 0;
146: break;
147:
148: case K_UPARROW:
149: cursor_res--;
150: if (cursor_res < 0)
151: cursor_res = NUM_RESOLUTIONS-1;
152: break;
153:
154: case K_DOWNARROW:
155: cursor_res++;
156: if (cursor_res >= NUM_RESOLUTIONS)
157: cursor_res = 0;
158: break;
159:
160: case K_ENTER:
161: ri.Cmd_ExecuteText (EXEC_NOW, va("vid_mode %i", cursor_res));
162: switch (cursor_type)
163: {
164: case TYPE_FULLSCREEN:
165: ri.Cmd_ExecuteText (EXEC_NOW, "vid_fullscreen 1");
166: ri.Cmd_ExecuteText (EXEC_NOW, "vid_stretched 0");
167: break;
168: case TYPE_WINDOWED:
169: ri.Cmd_ExecuteText (EXEC_NOW, "vid_fullscreen 0");
170: ri.Cmd_ExecuteText (EXEC_NOW, "vid_stretched 0");
171: break;
172: case TYPE_STRETCHED:
173: ri.Cmd_ExecuteText (EXEC_NOW, "vid_fullscreen 0");
174: ri.Cmd_ExecuteText (EXEC_NOW, "vid_stretched 1");
175: break;
176: }
177:
178: mode_res = cursor_res;
179: mode_type = cursor_type;
180: Draw_SetResolution ();
181: break;
182:
183: default:
184: break;
185: }
186: }
187:
188: //===========================================================
189:
190:
191: /*
192: ================
193: Draw_SetResolution
194:
195: The vid structure will be filled in on return
196: Also allocates the z buffer and surface cache
197: ================
198: */
199: int Draw_SetResolution (void)
200: {
201: NSRect content;
202:
203: if (vid_mode->value < 0)
204: ri.Cmd_ExecuteText (EXEC_NOW, "vid_mode 0");
205: if (vid_mode->value >= NUM_RESOLUTIONS)
206: ri.Cmd_ExecuteText (EXEC_NOW, va("vid_mode %i", NUM_RESOLUTIONS-1));
207:
208: vid_mode->modified = false;
209: vid_fullscreen->modified = false;
210: vid_stretched->modified = false;
211:
212: // free nativebuffer
213: if (buffernative)
214: {
215: free (buffernative);
216: buffernative = NULL;
217: }
218:
219: // free z buffer
220: if (d_pzbuffer)
221: {
222: free (d_pzbuffer);
223: d_pzbuffer = NULL;
224: }
225: // free surface cache
226: if (sc_base)
227: {
228: D_FlushCaches ();
229: free (sc_base);
230: sc_base = NULL;
231: }
232:
233: vid.width = resolutions[(int)(vid_mode->value)][0];
234: vid.height = resolutions[(int)(vid_mode->value)][1];
235:
236: vid.win_width = vid.width;
237: vid.win_height = vid.height;
238: if (vid_stretched->value)
239: {
240: vid.win_width <<= 1;
241: vid.win_height <<= 1;
242: }
243:
244: vid.aspect = 1;
245: vid.buffer = malloc (vid.width*vid.height);
246: vid.rowbytes = vid.width;
247: d_pzbuffer = malloc(vid.width*vid.height*2);
248: buffernative = malloc(vid.width*vid.height*4);
249:
250: D_InitCaches ();
251:
252: Sys_SetPalette ((byte *)d_8to24table);
253:
254: if (vid_view_i)
255: [vid_view_i unlockFocus];
256: if (vid_window_i)
257: [vid_window_i close];
258: //
259: // open a window
260: //
261: content = NSMakeRect (vid_x->value,vid_y->value,vid.win_width, vid.win_height);
262: vid_window_i = [[NSWindow alloc]
263: initWithContentRect: content
264: styleMask: NSTitledWindowMask
265: backing: NSBackingStoreRetained
266: defer: NO
267: ];
268:
269: [vid_window_i setDelegate: vid_window_i];
270: [vid_window_i display];
271: [NSApp activateIgnoringOtherApps: YES];
272: [vid_window_i makeKeyAndOrderFront: nil];
273:
274: // NSPing ();
275:
276: content.origin.x = content.origin.y = 0;
277: vid_view_i = [[QuakeView alloc] initWithFrame: content];
278: [vid_window_i setContentView: vid_view_i];
279: [vid_window_i makeFirstResponder: vid_view_i];
280: [vid_window_i setDelegate: vid_view_i];
281:
282: // [vid_window_i addToEventMask: NS_FLAGSCHANGEDMASK];
283: [vid_window_i setTitle: @"Bitmap Quake Console"];
284: [vid_window_i makeKeyAndOrderFront: nil];
285:
286: // leave focus locked forever
287: [vid_view_i lockFocus];
288:
289: ri.VID_SetSize (vid.width, vid.height);
290:
291: return 0;
292: }
293:
294: /*
295: @@@@@@@@@@@@@@@@@@@@@
296: Draw_Init
297:
298: @@@@@@@@@@@@@@@@@@@@@
299: */
300: int Draw_Init (void *window)
301: {
302: [NSApplication sharedApplication];
303: [NSApp finishLaunching];
304:
305: ri.Con_Printf (PRINT_ALL, "refresh version: "REF_VERSION"\n");
306:
307: vid_x = ri.Cvar_Get ("vid_x", "0", CVAR_ARCHIVE);
308: vid_y = ri.Cvar_Get ("vid_y", "0", CVAR_ARCHIVE);
309: vid_mode = ri.Cvar_Get ("vid_mode", "0", CVAR_ARCHIVE);
310: vid_fullscreen = ri.Cvar_Get ("vid_fullscreen", "0", CVAR_ARCHIVE);
311: vid_stretched = ri.Cvar_Get ("vid_stretched", "0", CVAR_ARCHIVE);
312: draw_gamma = ri.Cvar_Get ("gamma", "1", CVAR_ARCHIVE);
313:
314: Draw_GetPalette ();
315:
316: Draw_BuildGammaTable ();
317:
318: // get the lighting colormap
319: ri.FS_LoadFile ("gfx/colormap.lmp", (void **)&vid.colormap);
320: if (!vid.colormap)
321: {
322: ri.Con_Printf (PRINT_ALL, "ERROR: Couldn't load gfx/colormap.lmp");
323: return -1;
324: }
325:
326: Draw_SetResolution ();
327:
328: R_Init ();
329:
330: return 0;
331: }
332:
333:
334: /*
335: @@@@@@@@@@@@@@@@@@@@@
336: Draw_Shutdown
337:
338: @@@@@@@@@@@@@@@@@@@@@
339: */
340: void Draw_Shutdown (void)
341: {
342: R_Shutdown ();
343: }
344:
345:
346: /*
347: @@@@@@@@@@@@@@@@@@@@@
348: Draw_BuildGammaTable
349:
350: @@@@@@@@@@@@@@@@@@@@@
351: */
352: void Draw_BuildGammaTable (void)
353: {
354: int i, inf;
355: float g;
356:
357: draw_gamma->modified = false;
358: g = draw_gamma->value;
359:
360: if (g == 1.0)
361: {
362: for (i=0 ; i<256 ; i++)
363: gammatable[i] = i;
364: return;
365: }
366:
367: for (i=0 ; i<256 ; i++)
368: {
369: inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5;
370: if (inf < 0)
371: inf = 0;
372: if (inf > 255)
373: inf = 255;
374: gammatable[i] = inf;
375: }
376: }
377:
378:
379: /*
380: @@@@@@@@@@@@@@@@@@@@@
381: Draw_BeginFram
382:
383: @@@@@@@@@@@@@@@@@@@@@
384: */
385: void Draw_BeginFrame (void)
386: {
387: if (vid_mode->modified || vid_fullscreen->modified
388: || vid_stretched->modified)
389: Draw_SetResolution ();
390:
391: if (draw_gamma->modified)
392: {
393: Draw_BuildGammaTable ();
394: Sys_SetPalette ((byte *)current_palette);
395: }
396:
397: // MGL_beginDirectAccess();
398: // vid.buffer = mgldc->surface;
399: // vid.rowbytes = mgldc->mi.bytesPerLine;
400: }
401:
402:
403: /*
404: @@@@@@@@@@@@@@@@@@@@@
405: Draw_EndFrame
406:
407: @@@@@@@@@@@@@@@@@@@@@
408: */
409: void Draw_EndFrame (void)
410: {
411: int i, c;
412: int bps, spp, bpp, bpr;
413: unsigned char *planes[5];
414: NSRect bounds;
415:
416: // translate to 24 bit color
417: c = vid.width*vid.height;
418: for (i=0 ; i<c ; i++)
419: buffernative[i] = gamma_palette[vid.buffer[i]];
420:
421: bps = 8;
422: spp = 3;
423: bpp = 32;
424: bpr = vid.width * 4;
425: planes[0] = (unsigned char *)buffernative;
426:
427: bounds = [vid_view_i bounds];
428:
429: NSDrawBitmap(
430: bounds,
431: vid.width,
432: vid.height,
433: bps,
434: spp,
435: bpp,
436: bpr,
437: NO,
438: NO,
439: @"NSDeviceRGBColorSpace",
440: planes
441: );
442: }
443:
444:
445: //===============================================================================
446:
447: #define HUNK_MAGIC 0xffaffaff
448: typedef struct
449: {
450: int magic;
451: int length;
452: int pad[6];
453: } hunkheader_t;
454:
455: hunkheader_t *membase;
456: int maxsize;
457: int cursize;
458:
459: void *Hunk_Begin (void)
460: {
461: kern_return_t r;
462:
463: // reserve a huge chunk of memory, but don't commit any yet
464: maxsize = 16*1024*1024;
465: cursize = 0;
466: membase = NULL;
467: r = vm_allocate(task_self(), (vm_address_t *)&membase, maxsize, 1);
468: if (!membase || r != KERN_SUCCESS)
469: ri.Sys_Error (ERR_FATAL,"vm_allocate failed");
470: membase->magic = HUNK_MAGIC;
471: membase->length = maxsize;
472: cursize = 32;
473: return (void *)((byte *)membase + cursize);
474: }
475:
476: void *Hunk_Alloc (int size)
477: {
478: // round to cacheline
479: size = (size+31)&~31;
480:
481: cursize += size;
482:
483: if (cursize > maxsize)
484: ri.Sys_Error (ERR_DROP, "Hunk_Alloc overflow");
485:
486: memset ((byte *)membase+cursize-size,0,size);
487:
488: return (void *)((byte *)membase+cursize-size);
489: }
490:
491: int Hunk_End (void)
492: {
493: kern_return_t r;
494:
495: // round to pagesize
496: cursize = (cursize+vm_page_size)&~(vm_page_size-1);
497: membase->length = cursize;
498: r = vm_deallocate(task_self(),
499: (vm_address_t)((byte *)membase + cursize),
500: maxsize - cursize);
501: if ( r != KERN_SUCCESS )
502: ri.Sys_Error (ERR_DROP, "vm_deallocate failed");
503: return cursize;
504: }
505:
506: void Hunk_Free (void *base)
507: {
508: hunkheader_t *h;
509: kern_return_t r;
510:
511: h = ((hunkheader_t *)base) - 1;
512: if (h->magic != HUNK_MAGIC)
513: ri.Sys_Error (ERR_FATAL, "Hunk_Free: bad magic");
514:
515: r = vm_deallocate(task_self(), (vm_address_t)h, h->length);
516: if ( r != KERN_SUCCESS )
517: ri.Sys_Error (ERR_DROP, "vm_deallocate failed");
518: }
519:
520:
521: /*
522: ================
523: Sys_MakeCodeWriteable
524: ================
525: */
526: void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
527: {
528: }
529:
530:
531: /*
532: ================
533: Sys_SetPalette
534: ================
535: */
536: void Sys_SetPalette (byte *palette)
537: {
538: byte *p;
539: int i;
540:
541: memcpy (current_palette, palette, sizeof(current_palette));
542: p = (byte *)gamma_palette;
543: // gamma correct and byte swap
544: for (i=0 ; i<256 ; i++, p+=4, palette+=4)
545: {
546: p[0] = gammatable[palette[0]];
547: p[1] = gammatable[palette[1]];
548: p[2] = gammatable[palette[2]];
549: p[3] = 0xff;
550: }
551:
552: }
553:
554:
555: /*
556: ==========================================================================
557:
558: NEXTSTEP VIEW CLASS
559:
560: ==========================================================================
561: */
562: #include "../client/keys.h"
563:
564: void IN_ActivateMouse (void);
565: void IN_DeactivateMouse (void);
566:
567: @implementation QuakeView
568:
569: -(BOOL) acceptsFirstResponder
570: {
571: return YES;
572: }
573:
574: - (void)windowDidMove: (NSNotification *)note
575: {
576: NSRect r;
577:
578: r = [vid_window_i frame];
579: ri.Cmd_ExecuteText (EXEC_NOW, va("vid_x %i", (int)r.origin.x+1));
580: ri.Cmd_ExecuteText (EXEC_NOW, va("vid_y %i", (int)r.origin.y+1));
581: }
582:
583: - (void)becomeKeyWindow
584: {
585: IN_ActivateMouse ();
586: }
587:
588: - (void)resignKeyWindow
589: {
590: IN_DeactivateMouse ();
591: }
592:
593:
594: typedef struct
595: {
596: int source, dest;
597: } keymap_t;
598:
599: keymap_t keymaps[] =
600: {
601: {103, K_RIGHTARROW},
602: {102, K_LEFTARROW},
603: {100, K_UPARROW},
604: {101, K_DOWNARROW},
605:
606: {59, K_F1},
607: {60, K_F2},
608: {61, K_F3},
609: {62, K_F4},
610: {63, K_F5},
611: {64, K_F6},
612: {65, K_F7},
613: {66, K_F8},
614: {67, K_F9},
615: {68, K_F10},
616: {87, K_F11},
617: {88, K_F12},
618:
619: {-1,-1}
620: };
621:
622: keymap_t flagmaps[] =
623: {
624: {NSShiftKeyMask, K_SHIFT},
625: {NSControlKeyMask, K_CTRL},
626: {NSAlternateKeyMask, K_ALT},
627: {NSCommandKeyMask, K_ALT},
628:
629: {-1,-1}
630: };
631:
632: - (void)mouseDown:(NSEvent *)theEvent
633: {
634: Key_Event (K_MOUSE1, true);
635: }
636: - (void)mouseUp:(NSEvent *)theEvent
637: {
638: Key_Event (K_MOUSE1, false);
639: }
640: - (void)rightMouseDown:(NSEvent *)theEvent
641: {
642: Key_Event (K_MOUSE2, true);
643: }
644: - (void)rightMouseUp:(NSEvent *)theEvent
645: {
646: Key_Event (K_MOUSE2, false);
647: }
648:
649:
650: /*
651: ===================
652: keyboard methods
653: ===================
654: */
655: - (void)keyDown:(NSEvent *)theEvent
656: {
657: int ch;
658: keymap_t *km;
659:
660: // PSobscurecursor ();
661:
662: // check for non-ascii first
663: ch = [theEvent keyCode];
664: for (km=keymaps;km->source!=-1;km++)
665: if (ch == km->source)
666: {
667: Key_Event (km->dest, true);
668: return;
669: }
670:
671: ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
672: if (ch >= 'A' && ch <= 'Z')
673: ch += 'a' - 'A';
674: if (ch>=256)
675: return;
676:
677: Key_Event (ch, true);
678: }
679:
680: - (void)flagsChanged:(NSEvent *)theEvent
681: {
682: static int oldflags;
683: int newflags;
684: int delta;
685: keymap_t *km;
686: int i;
687:
688: // PSobscurecursor ();
689: newflags = [theEvent modifierFlags];
690: delta = newflags ^ oldflags;
691: for (i=0 ; i<32 ; i++)
692: {
693: if ( !(delta & (1<<i)))
694: continue;
695: // changed
696: for (km=flagmaps;km->source!=-1;km++)
697: if ( (1<<i) == km->source)
698: {
699: if (newflags & (1<<i))
700: Key_Event (km->dest, true);
701: else
702: Key_Event (km->dest, false);
703: }
704:
705: }
706:
707: oldflags = newflags;
708: }
709:
710:
711: - (void)keyUp:(NSEvent *)theEvent
712: {
713: int ch;
714: keymap_t *km;
715:
716: // check for non-ascii first
717: ch = [theEvent keyCode];
718: for (km=keymaps;km->source!=-1;km++)
719: if (ch == km->source)
720: {
721: Key_Event (km->dest, false);
722: return;
723: }
724:
725: ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
726: if (ch >= 'A' && ch <= 'Z')
727: ch += 'a' - 'A';
728: if (ch>=256)
729: return;
730: Key_Event (ch, false);
731: }
732:
733: @end
734:
735:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.