|
|
1.1 ! root 1: #import <AppKit/AppKit.h> ! 2: #import <Interceptor/NSDirectScreen.h> ! 3: #import <AppKit/NSColor.h> ! 4: #include "../ref_soft/r_local.h" ! 5: ! 6: @interface QuakeView : NSView ! 7: @end ! 8: ! 9: NSWindow *vid_window_i; ! 10: QuakeView *vid_view_i; ! 11: NSDirectScreen *vid_screen; ! 12: byte *vid_buffer; // real framebuffer ! 13: int vid_rowbytes; // framebuffer rowbytes ! 14: ! 15: unsigned *buffernative; // 24 bit off-screen back buffer for window ! 16: unsigned swimp_palette[256]; ! 17: ! 18: typedef enum { ! 19: rhap_shutdown, ! 20: rhap_windowed, ! 21: rhap_fullscreen ! 22: } rhapMode_t; ! 23: ! 24: rhapMode_t rhap_mode; ! 25: ! 26: /* ! 27: ======================================================================= ! 28: ! 29: FULLSCREEN ! 30: ! 31: ======================================================================= ! 32: */ ! 33: ! 34: /* ! 35: ** InitFullscreen ! 36: */ ! 37: rserr_t InitFullscreen (int width, int height) ! 38: { ! 39: NSDictionary *mode, *bestMode; ! 40: int modeWidth, bestWidth; ! 41: int modeHeight, bestHeight; ! 42: NSArray *modes; ! 43: int i; ! 44: NSString *string; ! 45: ! 46: ! 47: vid_screen = [[NSDirectScreen alloc] initWithScreen:[NSScreen mainScreen]]; ! 48: ! 49: // search for an apropriate mode ! 50: modes = [vid_screen availableDisplayModes]; ! 51: bestMode = NULL; ! 52: bestWidth = 99999; ! 53: bestHeight = 99999; ! 54: for (i=0 ; i<[modes count] ; i++) { ! 55: mode = [modes objectAtIndex: i]; ! 56: string = [mode objectForKey: @"NSDirectScreenPixelEncoding"]; ! 57: if ( ![string isEqualToString: @"PPPPPPPP"] ) ! 58: continue; // only look at paletted modes ! 59: modeWidth = [[mode objectForKey: @"NSDirectScreenWidth"] intValue]; ! 60: modeHeight = [[mode objectForKey: @"NSDirectScreenHeight"] intValue]; ! 61: if (modeWidth < width || modeHeight < height) ! 62: continue; ! 63: if (modeWidth < bestWidth) { ! 64: bestWidth = modeWidth; ! 65: bestHeight = modeHeight; ! 66: bestMode = mode; ! 67: } ! 68: } ! 69: ! 70: // if there wasn't any paletted mode of that res or greater, fail ! 71: if (!bestMode) ! 72: return rserr_invalid_fullscreen; ! 73: ! 74: ri.Con_Printf (PRINT_ALL, "SheildDisplay\n"); ! 75: [vid_screen shieldDisplay]; ! 76: ! 77: // hide the cursor in all fullscreen modes ! 78: [NSCursor hide]; ! 79: ! 80: vid_window_i = [vid_screen shieldingWindow]; ! 81: ! 82: ri.Con_Printf (PRINT_ALL, "switchToDisplayMode\n"); ! 83: [vid_screen switchToDisplayMode:bestMode]; ! 84: // [vid_screen fadeDisplayOutToColor:[NSColor blackColor]]; ! 85: // [vid_screen fadeDisplayInFromColor:[NSColor blackColor]]; ! 86: ! 87: vid_buffer = [vid_screen data]; ! 88: vid_rowbytes = [vid_screen bytesPerRow]; ! 89: ! 90: return rserr_ok; ! 91: } ! 92: ! 93: void ShutdownFullscreen (void) ! 94: { ! 95: [vid_screen dealloc]; ! 96: [NSCursor unhide]; ! 97: } ! 98: ! 99: void SetPaletteFullscreen (const unsigned char *palette) { ! 100: #if 0 ! 101: byte *p; ! 102: int i; ! 103: NSDirectPalette *pal; ! 104: ! 105: pal = [NSDirectPalette init]; ! 106: for (i=0 ; i<256 ; i++) ! 107: [pal setRed: palette[0]*(1.0/255) ! 108: green: palette[1]*(1.0/255) ! 109: blue: palette[2]*(1.0/255) ! 110: atIndex: i]; ! 111: [vid_screen setPalette: pal]; ! 112: [pal release]; ! 113: #endif ! 114: } ! 115: ! 116: ! 117: ! 118: void BlitFullscreen (void) ! 119: { ! 120: int i, j; ! 121: int w; ! 122: int *dest, *source; ! 123: ! 124: w = vid.width>>2; ! 125: ! 126: source = (int *)vid.buffer; // off-screen buffer ! 127: dest = (int *)vid_buffer; // directly on screen ! 128: for (j=0 ; j<vid.height ; j++ ! 129: , source += (vid.rowbytes>>2), dest += (vid_rowbytes>>2) ) { ! 130: for (i=0 ; i<w ; i++ ) { ! 131: dest[i] = source[i]; ! 132: } ! 133: } ! 134: } ! 135: ! 136: /* ! 137: ======================================================================= ! 138: ! 139: WINDOWED ! 140: ! 141: ======================================================================= ! 142: */ ! 143: ! 144: /* ! 145: ** InitWindowed ! 146: */ ! 147: rserr_t InitWindowed (int width, int height) ! 148: { ! 149: rserr_t retval = rserr_ok; ! 150: NSRect content; ! 151: cvar_t *vid_xpos; ! 152: cvar_t *vid_ypos; ! 153: ! 154: // ! 155: // open a window ! 156: // ! 157: vid_xpos = ri.Cvar_Get ("vid_xpos", "0", 0); ! 158: vid_ypos = ri.Cvar_Get ("vid_ypos", "0", 0); ! 159: ! 160: content = NSMakeRect (vid_xpos->value,vid_ypos->value, width, height); ! 161: vid_window_i = [[NSWindow alloc] ! 162: initWithContentRect: content ! 163: styleMask: NSTitledWindowMask ! 164: backing: NSBackingStoreRetained ! 165: defer: NO ! 166: ]; ! 167: ! 168: // [vid_window_i addToEventMask: NS_FLAGSCHANGEDMASK]; ! 169: [vid_window_i setTitle: @"Quake2"]; ! 170: ! 171: buffernative = malloc(width * height * 4); ! 172: ! 173: return retval; ! 174: } ! 175: ! 176: void ShutdownWindowed (void) ! 177: { ! 178: if (vid_window_i) ! 179: { ! 180: [vid_window_i release]; ! 181: vid_window_i = NULL; ! 182: } ! 183: if (buffernative) ! 184: { ! 185: free (buffernative); ! 186: buffernative = NULL; ! 187: } ! 188: } ! 189: ! 190: void SetPaletteWindowed (const unsigned char *palette) { ! 191: byte *p; ! 192: int i; ! 193: ! 194: p = (byte *)swimp_palette; ! 195: for (i=0 ; i<256 ; i++, p+=4, palette+=4) ! 196: { ! 197: p[0] = palette[0]; ! 198: p[1] = palette[1]; ! 199: p[2] = palette[2]; ! 200: p[3] = 0xff; ! 201: } ! 202: } ! 203: ! 204: ! 205: void BlitWindowed (void) ! 206: { ! 207: int i, c; ! 208: int bps, spp, bpp, bpr; ! 209: unsigned char *planes[5]; ! 210: NSRect bounds; ! 211: ! 212: if (!vid_view_i) ! 213: return; ! 214: ! 215: // translate to 24 bit color ! 216: c = vid.width*vid.height; ! 217: for (i=0 ; i<c ; i++) ! 218: buffernative[i] = swimp_palette[vid.buffer[i]]; ! 219: ! 220: bps = 8; ! 221: spp = 3; ! 222: bpp = 32; ! 223: bpr = vid.width * 4; ! 224: planes[0] = (unsigned char *)buffernative; ! 225: ! 226: bounds = [vid_view_i bounds]; ! 227: ! 228: [vid_view_i lockFocus]; ! 229: ! 230: NSDrawBitmap( ! 231: bounds, ! 232: vid.width, ! 233: vid.height, ! 234: bps, ! 235: spp, ! 236: bpp, ! 237: bpr, ! 238: NO, ! 239: NO, ! 240: @"NSDeviceRGBColorSpace", ! 241: planes ! 242: ); ! 243: ! 244: [vid_view_i unlockFocus]; ! 245: PSWait (); ! 246: } ! 247: ! 248: ! 249: //====================================================================== ! 250: ! 251: /* ! 252: ** RW_IMP.C ! 253: ** ! 254: ** This file contains ALL Win32 specific stuff having to do with the ! 255: ** software refresh. When a port is being made the following functions ! 256: ** must be implemented by the port: ! 257: ** ! 258: ** SWimp_EndFrame ! 259: ** SWimp_Init ! 260: ** SWimp_SetPalette ! 261: ** SWimp_Shutdown ! 262: */ ! 263: ! 264: ! 265: /* ! 266: ** SWimp_Init ! 267: ** ! 268: ** This routine is responsible for initializing the implementation ! 269: ** specific stuff in a software rendering subsystem. ! 270: */ ! 271: int SWimp_Init( void *hInstance, void *wndProc ) ! 272: { ! 273: if (!NSApp) ! 274: { ! 275: [NSApplication sharedApplication]; ! 276: [NSApp finishLaunching]; ! 277: } ! 278: ! 279: return true; ! 280: } ! 281: ! 282: ! 283: /* ! 284: ** SWimp_SetMode ! 285: */ ! 286: rserr_t SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen) ! 287: { ! 288: const char *win_fs[] = { "W", "FS" }; ! 289: NSRect content; ! 290: rserr_t ret; ! 291: ! 292: // free resources in use ! 293: SWimp_Shutdown (); ! 294: ! 295: ri.Con_Printf (PRINT_ALL, "setting mode %d:", mode ); ! 296: ! 297: if ( !ri.Vid_GetModeInfo( pwidth, pheight, mode ) ) ! 298: { ! 299: ri.Con_Printf( PRINT_ALL, " invalid mode\n" ); ! 300: return rserr_invalid_mode; ! 301: } ! 302: ! 303: ri.Con_Printf( PRINT_ALL, " %d %d %s\n", *pwidth, *pheight, win_fs[fullscreen] ); ! 304: ! 305: vid.buffer = malloc(*pwidth * *pheight); ! 306: vid.rowbytes = *pwidth; ! 307: ! 308: if (fullscreen) { ! 309: rhap_mode = rhap_fullscreen; ! 310: ret = InitFullscreen (*pwidth, *pheight); ! 311: } else { ! 312: rhap_mode = rhap_windowed; ! 313: ret = InitWindowed (*pwidth, *pheight); ! 314: } ! 315: ! 316: if (ret != rserr_ok) { ! 317: SWimp_Shutdown (); ! 318: return ret; ! 319: } ! 320: ! 321: /* ! 322: ** the view is identical in windowed and fullscreen modes ! 323: */ ! 324: content.origin.x = content.origin.y = 0; ! 325: content.size.width = *pwidth; ! 326: content.size.height = *pheight; ! 327: vid_view_i = [[QuakeView alloc] initWithFrame: content]; ! 328: [vid_window_i setContentView: vid_view_i]; ! 329: [vid_window_i makeFirstResponder: vid_view_i]; ! 330: [vid_window_i setDelegate: vid_view_i]; ! 331: ! 332: [NSApp activateIgnoringOtherApps: YES]; ! 333: [vid_window_i makeKeyAndOrderFront: nil]; ! 334: [vid_window_i display]; ! 335: ! 336: return ret; ! 337: } ! 338: ! 339: /* ! 340: ** SWimp_Shutdown ! 341: ** ! 342: ** System specific graphics subsystem shutdown routine ! 343: */ ! 344: void SWimp_Shutdown( void ) ! 345: { ! 346: if (rhap_mode == rhap_windowed) ! 347: ShutdownWindowed (); ! 348: else if (rhap_mode == rhap_fullscreen) ! 349: ShutdownFullscreen (); ! 350: ! 351: rhap_mode = rhap_shutdown; ! 352: ! 353: if (vid.buffer) ! 354: { ! 355: free (vid.buffer); ! 356: vid.buffer = NULL; ! 357: } ! 358: } ! 359: ! 360: ! 361: /* ! 362: ** SWimp_SetPalette ! 363: ** ! 364: ** System specific palette setting routine. A NULL palette means ! 365: ** to use the existing palette. The palette is expected to be in ! 366: ** a padded 4-byte xRGB format. ! 367: */ ! 368: void SWimp_SetPalette( const unsigned char *palette ) ! 369: { ! 370: if (rhap_mode == rhap_windowed) ! 371: SetPaletteWindowed (palette); ! 372: else if (rhap_mode == rhap_fullscreen) ! 373: SetPaletteFullscreen (palette); ! 374: } ! 375: ! 376: ! 377: /* ! 378: ** SWimp_EndFrame ! 379: ** ! 380: ** This does an implementation specific copy from the backbuffer to the ! 381: ** front buffer. In the Win32 case it uses BitBlt or BltFast depending ! 382: ** on whether we're using DIB sections/GDI or DDRAW. ! 383: */ ! 384: void SWimp_EndFrame (void) ! 385: { ! 386: if (rhap_mode == rhap_windowed) ! 387: BlitWindowed (); ! 388: else if (rhap_mode == rhap_fullscreen) ! 389: BlitFullscreen (); ! 390: } ! 391: ! 392: ! 393: /* ! 394: ** SWimp_AppActivate ! 395: */ ! 396: void SWimp_AppActivate( qboolean active ) ! 397: { ! 398: } ! 399: ! 400: ! 401: /* ! 402: ========================================================================== ! 403: ! 404: NEXTSTEP VIEW CLASS ! 405: ! 406: ========================================================================== ! 407: */ ! 408: #include "../client/keys.h" ! 409: ! 410: void IN_ActivateMouse (void); ! 411: void IN_DeactivateMouse (void); ! 412: ! 413: @implementation QuakeView ! 414: ! 415: -(BOOL) acceptsFirstResponder ! 416: { ! 417: return YES; ! 418: } ! 419: ! 420: - (void)windowDidMove: (NSNotification *)note ! 421: { ! 422: NSRect r; ! 423: ! 424: r = [vid_window_i frame]; ! 425: ri.Cmd_ExecuteText (EXEC_NOW, va("vid_xpos %i", (int)r.origin.x+1)); ! 426: ri.Cmd_ExecuteText (EXEC_NOW, va("vid_ypos %i", (int)r.origin.y+1)); ! 427: } ! 428: ! 429: - (void)becomeKeyWindow ! 430: { ! 431: IN_ActivateMouse (); ! 432: } ! 433: ! 434: - (void)resignKeyWindow ! 435: { ! 436: IN_DeactivateMouse (); ! 437: } ! 438: ! 439: ! 440: typedef struct ! 441: { ! 442: int source, dest; ! 443: } keymap_t; ! 444: ! 445: keymap_t keymaps[] = ! 446: { ! 447: {0xf703, K_RIGHTARROW}, ! 448: {0xf702, K_LEFTARROW}, ! 449: {0xf700, K_UPARROW}, ! 450: {0xf701, K_DOWNARROW}, ! 451: ! 452: {0xf704, K_F1}, ! 453: {0xf705, K_F2}, ! 454: {0xf706, K_F3}, ! 455: {0xf707, K_F4}, ! 456: {0xf708, K_F5}, ! 457: {0xf709, K_F6}, ! 458: {0xf70a, K_F7}, ! 459: {0xf70b, K_F8}, ! 460: {0xf70c, K_F9}, ! 461: {0xf70d, K_F10}, ! 462: {0xf70e, K_F11}, ! 463: {0xf70f, K_F12}, ! 464: ! 465: {-1,-1} ! 466: }; ! 467: ! 468: keymap_t flagmaps[] = ! 469: { ! 470: {NSShiftKeyMask, K_SHIFT}, ! 471: {NSControlKeyMask, K_CTRL}, ! 472: {NSAlternateKeyMask, K_ALT}, ! 473: {NSCommandKeyMask, K_ALT}, ! 474: ! 475: {-1,-1} ! 476: }; ! 477: ! 478: - (void)mouseDown:(NSEvent *)theEvent ! 479: { ! 480: Key_Event (K_MOUSE1, true, 0); ! 481: } ! 482: - (void)mouseUp:(NSEvent *)theEvent ! 483: { ! 484: Key_Event (K_MOUSE1, false, 0); ! 485: } ! 486: - (void)rightMouseDown:(NSEvent *)theEvent ! 487: { ! 488: Key_Event (K_MOUSE2, true, 0); ! 489: } ! 490: - (void)rightMouseUp:(NSEvent *)theEvent ! 491: { ! 492: Key_Event (K_MOUSE2, false, 0); ! 493: } ! 494: ! 495: ! 496: /* ! 497: =================== ! 498: keyboard methods ! 499: =================== ! 500: */ ! 501: - (void)keyDown:(NSEvent *)theEvent ! 502: { ! 503: int ch; ! 504: keymap_t *km; ! 505: ! 506: // PSobscurecursor (); ! 507: ! 508: ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; ! 509: // check for non-ascii first ! 510: for (km=keymaps;km->source!=-1;km++) ! 511: if (ch == km->source) ! 512: { ! 513: Key_Event (km->dest, true, 0); ! 514: return; ! 515: } ! 516: ! 517: if (ch >= 'A' && ch <= 'Z') ! 518: ch += 'a' - 'A'; ! 519: if (ch>=256) ! 520: return; ! 521: ! 522: Key_Event (ch, true, 0); ! 523: } ! 524: ! 525: - (void)flagsChanged:(NSEvent *)theEvent ! 526: { ! 527: static int oldflags; ! 528: int newflags; ! 529: int delta; ! 530: keymap_t *km; ! 531: int i; ! 532: ! 533: // PSobscurecursor (); ! 534: newflags = [theEvent modifierFlags]; ! 535: delta = newflags ^ oldflags; ! 536: for (i=0 ; i<32 ; i++) ! 537: { ! 538: if ( !(delta & (1<<i))) ! 539: continue; ! 540: // changed ! 541: for (km=flagmaps;km->source!=-1;km++) ! 542: if ( (1<<i) == km->source) ! 543: { ! 544: if (newflags & (1<<i)) ! 545: Key_Event (km->dest, true, 0); ! 546: else ! 547: Key_Event (km->dest, false, 0); ! 548: } ! 549: ! 550: } ! 551: ! 552: oldflags = newflags; ! 553: } ! 554: ! 555: ! 556: - (void)keyUp:(NSEvent *)theEvent ! 557: { ! 558: int ch; ! 559: keymap_t *km; ! 560: ! 561: ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; ! 562: ! 563: // check for non-ascii first ! 564: for (km=keymaps;km->source!=-1;km++) ! 565: if (ch == km->source) ! 566: { ! 567: Key_Event (km->dest, false, 0); ! 568: return; ! 569: } ! 570: ! 571: if (ch >= 'A' && ch <= 'Z') ! 572: ch += 'a' - 'A'; ! 573: if (ch>=256) ! 574: return; ! 575: Key_Event (ch, false, 0); ! 576: } ! 577: ! 578: @end ! 579: ! 580:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.