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