Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

r_next.m (14811B)


      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