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 11int BASEWIDTH = 320; 12int BASEHEIGHT = 200; 13 14void SetupBitmap (void); 15void SetupFramebuffer (void); 16void UpdateBitmap (void); 17void UpdateFramebuffer (vrect_t *vrect); 18void SetVideoEncoding (char *encoding); 19void Update8_1 (pixel_t *src, byte *dest, int width, 20 int height, int destrowbytes); 21void Update16_1 (pixel_t *src, unsigned short *dest, int width, 22 int height, int destrowbytes); 23void 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 33unsigned short d_8to16table[256]; // not used in 8 bpp mode 34unsigned d_8to24table[256]; // not used in 8 bpp mode 35 36 37/* 38========================================================================== 39 40 API FUNCTIONS 41 42========================================================================== 43*/ 44 45typedef enum {disp_bitmap, disp_framebuffer} display_t; 46 47pixel_t *vid_buffer; 48pixel_t *buffernative; 49unsigned pcolormap[4][256]; // map from quake pixels to native pixels 50unsigned pixbytesnative; 51unsigned rowbytesnative; 52int dither; 53 54int drawdirect = 0; 55 56int d_con_indirect = 0; 57 58display_t vid_display; 59 60byte vid_palette[768]; // saved for restarting vid system 61 62id vid_window_i; 63id vid_view_i; 64#ifdef INTERCEPTOR 65NXDirectBitmap *vid_dbitmap_i; 66NXFramebuffer *vid_framebuffer_i; 67#endif 68 69NXRect screenBounds; // only valid in framebuffer mode 70 71int vid_scale; 72 73char *vid_encodingstring; 74 75int vid_fullscreen; 76int vid_screen; 77 78int vid_high_hunk_mark; 79 80typedef 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 93typedef struct 94{ 95 char *string; 96 int pixelbytes; 97 void (*colormap) (void); 98 vid_encoding_t name; 99} vidtype_t; 100 101vid_encoding_t vid_encoding; 102 103void Table8 (void); 104void Table15 (void); 105void Table12 (void); 106void Table12Swap (void); 107void Table24 (void); 108void Table24Swap (void); 109 110vidtype_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 123vidtype_t *vid_type; 124void InitNS8Bit (void); 125 126/* 127================ 128D_BeginDirectRect 129================ 130*/ 131void 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================ 139D_EndDirectRect 140================ 141*/ 142void 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============== 150VID_Restart 151 152internal call only 153=============== 154*/ 155void 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================= 173VID_Scale_f 174 175Keybinding command 176================= 177*/ 178void 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================= 197VID_Mode_f 198 199Keybinding command 200================= 201*/ 202void 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================= 231VID_Size_f 232 233Keybinding command 234================= 235*/ 236void 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================ 251VID_Init 252================ 253*/ 254void 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================ 299VID_Shutdown 300================ 301*/ 302void 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================ 323VID_Update 324================ 325*/ 326void 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================ 344VID_SetPalette 345================ 346*/ 347void VID_SetPalette (unsigned char *palette) 348{ 349 Q_memcpy (vid_palette, palette, sizeof(vid_palette)); 350 vid_type->colormap (); 351} 352 353 354/* 355================ 356VID_ShiftPalette 357================ 358*/ 359void 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================= 377SetVideoEncoding 378================= 379*/ 380void 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================= 404AllocBuffers 405================= 406*/ 407void 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================= 449SetupFramebuffer 450================= 451*/ 452void 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================= 547SetupBitmap 548================= 549*/ 550void 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================= 617UpdateFramebuffer 618================= 619*/ 620void 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================= 654UpdateBitmap 655================= 656*/ 657void 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 725int redramp[] = {0, 19, 59, 113, 178, 255, 300}; 726int greenramp[] = {0, 11, 34, 66, 104, 149, 199, 255, 300}; 727int blueramp[] = {0, 28, 84, 161, 255, 300}; 728int greyramp[] = { 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 729 221, 238, 255, 300}; 730 731byte greytable[256]; 732byte redtable[256]; 733byte greentable[256]; 734byte bluetable[256]; 735 736void 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 749void 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 758byte ns8trans[256] = // FIXME: dynamically calc this so palettes work 759{ 7600,241,242,243,244,244,245,246,247,248,249,250,251,252,253,254, 76145,241,241,242,91,91,91,96,96,136,136,136,141,141,141,141, 762241,46,242,243,243,97,97,97,245,246,143,143,143,143,148,148, 7630,5,45,45,50,50,90,90,95,95,95,95,95,140,140,141, 7640,40,40,40,40,80,80,80,80,80,120,120,120,120,120,120, 76545,50,50,90,90,95,95,135,135,135,136,141,141,181,181,181, 76645,90,91,91,131,131,136,136,136,176,181,181,186,226,231,236, 76745,45,91,91,96,96,136,136,137,142,182,182,187,188,188,233, 768188,249,248,247,246,137,137,137,244,243,243,91,242,241,241,45, 769183,183,183,247,137,137,137,137,137,244,91,91,91,241,241,45, 770252,251,188,188,248,248,142,142,142,244,244,243,91,242,241,45, 771247,247,246,246,245,245,244,244,243,243,242,242,51,241,241,5, 772236,231,231,191,186,185,185,140,140,135,135,95,90,90,45,45, 7734,49,49,53,53,93,93,93,93,92,92,92,243,242,46,241, 774239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, 775239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,182 776}; 777 778/* 779=================== 780Table8 781=================== 782*/ 783void 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=================== 820Table24 821=================== 822*/ 823void 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=================== 851Table24Swap 852=================== 853*/ 854void 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=================== 883Table15 884=================== 885*/ 886void 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=================== 929Table12 930=================== 931*/ 932void 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=================== 973Table12Swap 974=================== 975*/ 976void 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=================== 1027Update8_1 1028=================== 1029*/ 1030void 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=================== 1225Update16_1 1226=================== 1227*/ 1228void 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=================== 1408Update32_1 1409=================== 1410*/ 1411void 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================= 1504windowDidMove 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 1582typedef struct 1583{ 1584 int source, dest; 1585} keymap_t; 1586 1587keymap_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 1611keymap_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=================== 1623keyboard 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 1790