File: common\editpal.c

    1 /*
    2  * editpal.c
    3  *
    4  * Edits VGA 256-color palettes.
    5  *
    6  * Key to initials:
    7  *
    8  *    EAN - Ethan Nagel [70022,2552]
    9  *
   10  *    JJB - Juan J. Buhler [jbuhler@gidef.edu.ar]
   11  *
   12  *    TIW - Tim Wegner
   13  *
   14  *    AMC - Andrew McCarthy [andrewmc@netsoc.ucd.ie]
   15  *
   16  * Revision History:
   17  *
   18  *   10-22-90 EAN     Initial release.
   19  *
   20  *   10-23-90 EAN     "Discovered" get_line/put_line functions, integrated
   21  *                      them in (instead of only getcolor/putcolor). Much
   22  *                      faster!
   23  *                    Redesigned color editors (now at top of palette) and
   24  *                      re-assigned some keys.
   25  *                    Added (A)uto option.
   26  *                    Fixed memory allocation problem.  Now uses shared
   27  *                      FRACTINT data area (strlocn).  Uses 6 bytes DS.
   28  *
   29  *   10-27-90 EAN     Added save to memory option - will save screen image to
   30  *                      memory, if enough mem avail.  (disk otherwise).
   31  *                    Added s(T)ripe mode - works like (S)hade except only
   32  *                      changes every n'th entry.
   33  *                    Added temporary palette save/restore.  (Can work like
   34  *                      an undo feature.)  Thanks to Pieter Branderhorst for
   35  *                      idea.
   36  *
   37  *   10-28-90 EAN     The (H)ide function now makes the palette invisible,
   38  *                      while allowing any other operations (except '\\' -
   39  *                      move/resize) to continue.
   40  *
   41  *   10-29-90 PB (in EAN's absence, <grin>)
   42  *                    Change 'c' to 'd' and 's' to '=' for below.
   43  *                    Add 'l' to load palette from .map, 's' to store .map.
   44  *                    Add 'c' to invoke color cycling.
   45  *                    Change cursor to use whatever colors it can from
   46  *                    the palette (not fixed 0 and 255).
   47  *                    Restore colors 0 and 255 to real values whenever
   48  *                    palette is not on display.
   49  *                    Rotate 255 colors instead of 254.
   50  *                    Reduce cursor blink rate.
   51  *
   52  *   11-15-90 EAN     Minor "bug" fixes.  Continuous rotation now at a fixed
   53  *                      rate - once every timer tick (18.2 sec);  Blanks out
   54  *                      color samples when rotating; Editors no longer rotate
   55  *                      with the colors in color rotation mode;  Eliminated
   56  *                      (Z)oom mode; other minor fixes.
   57  *
   58  *   01-05-91 PB      Add 'w' function to convert to greyscale.
   59  *
   60  *   01-16-91 PB      Change rotate function to use new cyclerange stuff.
   61  *
   62  *   01-29-91 EAN     Made all colors editable.  The two reserved colors are
   63  *                       X'ed out.  They can be edited but the color is not
   64  *                       visible.  (There is an X over the sample instead.)
   65  *                    Changed default reserved colors to 254 & 255.
   66  *                    Added 'v' command to set the reserved colors to those
   67  *                       under the editors.
   68  *                    Added 'o' command to set the rotate range to between
   69  *                      the two editors.
   70  *                    Modified 'w' function:
   71  *                      uses internal function to do conversion (not BIOS)
   72  *                      will convert only current color if in 'x' mode or
   73  *                        range between editors in 'y' mode or entire palette
   74  *                        if in "normal" mode.
   75  *
   76  *   02-08-91 EAN     Improved 16 color support.  In 16 color mode, colors
   77  *                      16-255 have a dot over them and are editable but not
   78  *                      visible (like the two reserved colors).
   79  *
   80  *   09-08-91 SWT     Added 'n' command to make a negative color palette:
   81  *                      will convert only current color if in 'x' mode or
   82  *                      range between editors in 'y' mode or entire palette
   83  *                      if in "normal" mode.
   84  *
   85  *   03-03-92 JJB     Added '!', '@' and '#' commands to swap RG, GB and
   86  *                      RB columns (sorry, I didn't find better keys)
   87  *
   88  *  10-03-92 TIW      Minor changes for Jiim support, primarily changing
   89  *                    variables from static to global.
   90  *
   91  *   2-11-93 EAN      Added full Undo ('U' key) and Redo ('E' key)
   92  *                      capability.  Works pretty much as you'd expect
   93  *                      it to.
   94  *
   95  *    3-6-93 EAN      Modified "freestyle" mode, written by RB, to integrate
   96  *                      into palette editor more completely and work with
   97  *                      undo logic.
   98  *                    Added status area under the "fractint" message to
   99  *                      display current state of editor.  A = Auto mode,
  100  *                      X, Y = exclusion modes, F = freesyle mode, T = stripe
  101  *                      mode is waiting for #.
  102  *
  103  *   03-21-97 AMC     Made '"' work the same as '@' and made 'œ' work like
  104  *                      '#' for those of us on this side of the Atlantic!
  105  *                    The original palette is now stored in the other slots
  106  *                      on startup, so you can 'undo all' if you haven't
  107  *                      overwritten them already. Undo could do this, but
  108  *                      this is handy.
  109  *   05-22-97 TIW     Replaced movedata with far_memcopy()
  110  */
  111 
  112 #ifdef DEBUG_UNDO
113 #include "mdisp.h" /* EAN 930211 *** Debug Only *** */
114 #endif 115 116 #include <string.h> 117 118 #ifndef USE_VARARGS 119 #include <stdarg.h>
120 #else 121 #include <varargs.h>
122 #endif 123 124 #ifdef __TURBOC__
125 # include <mem.h> /* to get mem...() declarations */
126 #endif 127 128 /* see Fractint.c for a description of the "include" hierarchy */ 129 #include "port.h" 130 #include "prototyp.h" 131 132 /* 133 * misc. #defines 134 */ 135 136 #define FONT_DEPTH 8 /* font size */ 137 138 #define CSIZE_MIN 8 /* csize cannot be smaller than this */ 139 140 #define CURSOR_SIZE 5 /* length of one side of the x-hair cursor */ 141 142 #ifndef XFRACT 143 #define CURSOR_BLINK_RATE 3 /* timer ticks between cursor blinks */
144 #else 145 #define CURSOR_BLINK_RATE 300 /* timer ticks between cursor blinks */
146 #endif 147 148 #define FAR_RESERVE 8192L /* amount of far mem we will leave avail. */ 149 150 #define MAX_WIDTH 1024 /* palette editor cannot be wider than this */ 151 152 char scrnfile[] = "FRACTINT.$$1"; /* file where screen portion is */ 153 /* stored */ 154 char undofile[] = "FRACTINT.$$2"; /* file where undo list is stored */ 155 #define TITLE "FRACTINT" 156 157 #define TITLE_LEN (8) 158 159 160 #define newx(size) mem_alloc(size) 161 #define new(class) (class *)(mem_alloc(sizeof(class))) 162 #define delete(block) block=NULL /* just for warning */ 163 164 #ifdef XFRACT
165 int editpal_cursor = 0;
166 #endif 167 168 169 /* 170 * Stuff from fractint 171 */ 172 173 #if 0
174 /* declarations moved to PRORTOTYPE.H - this left for docs */ 175 BYTE dacbox[256][3]; /* DAC spindac() will use */ 176 int sxdots; /* width of physical screen */ 177 int sydots; /* depth of physical screen */ 178 int sxoffs; /* start of logical screen */ 179 int syoffs; /* start of logical screen */ 180 int lookatmouse; /* mouse mode for getakey(), etc */ 181 int strlocn[]; /* 10K buffer to store classes in */ 182 int colors; /* # colors avail. */ 183 int color_bright; /* brightest color in palette */ 184 int color_dark; /* darkest color in palette */ 185 int color_medium; /* nearest to medbright gray color */ 186 int rotate_lo, rotate_hi; 187 int debugflag;
188 #endif 189 int using_jiim = 0; 190 191 /* 192 * basic data types 193 */ 194 195 196 typedef struct 197 { 198 BYTE red, 199 green, 200 blue; 201 } PALENTRY; 202 203 204 205 /* 206 * static data 207 */ 208 209 210 static BYTE far *font8x8 = NULL; 211 BYTE *line_buff; /* must be alloced!!! */ 212 static BYTE fg_color, 213 bg_color; 214 static BOOLEAN reserve_colors; 215 static BOOLEAN inverse; 216 217 static float gamma_val = 1; 218 219 220 /* 221 * Interface to FRACTINT's graphics stuff 222 */ 223 224 225 static void setpal(int pal, int r, int g, int b) 226 { 227 dacbox[pal][0] = (BYTE)r; 228 dacbox[pal][1] = (BYTE)g; 229 dacbox[pal][2] = (BYTE)b; 230 spindac(0,1); 231 } 232 233 234 static void setpalrange(int first, int how_many, PALENTRY *pal) 235 { 236 memmove(dacbox+first, pal, how_many*3); 237 spindac(0,1); 238 } 239 240 241 static void getpalrange(int first, int how_many, PALENTRY *pal) 242 { 243 memmove(pal, dacbox+first, how_many*3); 244 } 245 246 247 static void rotatepal(PALENTRY *pal, int dir, int lo, int hi) 248 { /* rotate in either direction */ 249 PALENTRY hold; 250 int size; 251 252 size = 1 + (hi-lo); 253 254 if ( dir > 0 ) 255 { 256 while ( dir-- > 0 ) 257 { 258 memmove(&hold, &pal[hi], 3); 259 memmove(&pal[lo+1], &pal[lo], 3*(size-1)); 260 memmove(&pal[lo], &hold, 3); 261 } 262 } 263 264 else if ( dir < 0 ) 265 { 266 while ( dir++ < 0 ) 267 { 268 memmove(&hold, &pal[lo], 3); 269 memmove(&pal[lo], &pal[lo+1], 3*(size-1)); 270 memmove(&pal[hi], &hold, 3); 271 } 272 } 273 } 274 275 276 static void clip_put_line(int row, int start, int stop, BYTE *pixels) 277 { 278 if ( row < 0 || row >= sydots || start > sxdots || stop < 0 ) 279 return ; 280 281 if ( start < 0 ) 282 { 283 pixels += -start; 284 start = 0; 285 } 286 287 if ( stop >= sxdots ) 288 stop = sxdots - 1; 289 290 if ( start > stop ) 291 return ; 292 293 put_line(row, start, stop, pixels); 294 } 295 296 297 static void clip_get_line(int row, int start, int stop, BYTE *pixels) 298 { 299 if ( row < 0 || row >= sydots || start > sxdots || stop < 0 ) 300 return ; 301 302 if ( start < 0 ) 303 { 304 pixels += -start; 305 start = 0; 306 } 307 308 if ( stop >= sxdots ) 309 stop = sxdots - 1; 310 311 if ( start > stop ) 312 return ; 313 314 get_line(row, start, stop, pixels); 315 } 316 317 318 void clip_putcolor(int x, int y, int color) 319 { 320 if ( x < 0 || y < 0 || x >= sxdots || y >= sydots ) 321 return ; 322 323 putcolor(x, y, color); 324 } 325 326 327 int clip_getcolor(int x, int y) 328 { 329 if ( x < 0 || y < 0 || x >= sxdots || y >= sydots ) 330 return (0); 331 332 return ( getcolor(x, y) ); 333 } 334 335 336 static void hline(int x, int y, int width, int color) 337 { 338 memset(line_buff, color, width); 339 clip_put_line(y, x, x+width-1, line_buff); 340 } 341 342 343 static void vline(int x, int y, int depth, int color) 344 { 345 while (depth-- > 0) 346 clip_putcolor(x, y++, color); 347 } 348 349 350 void getrow(int x, int y, int width, char *buff) 351 { 352 clip_get_line(y, x, x+width-1, (BYTE *)buff); 353 } 354 355 356 void putrow(int x, int y, int width, char *buff) 357 { 358 clip_put_line(y, x, x+width-1, (BYTE *)buff); 359 } 360 361 362 static void vgetrow(int x, int y, int depth, char *buff) 363 { 364 while (depth-- > 0) 365 *buff++ = (char)clip_getcolor(x, y++); 366 } 367 368 369 static void vputrow(int x, int y, int depth, char *buff) 370 { 371 while (depth-- > 0) 372 clip_putcolor(x, y++, (BYTE)(*buff++)); 373 } 374 375 376 static void fillrect(int x, int y, int width, int depth, int color) 377 { 378 while (depth-- > 0) 379 hline(x, y++, width, color); 380 } 381 382 383 static void rect(int x, int y, int width, int depth, int color) 384 { 385 hline(x, y, width, color); 386 hline(x, y+depth-1, width, color); 387 388 vline(x, y, depth, color); 389 vline(x+width-1, y, depth, color); 390 } 391 392 393 void displayc(int x, int y, int fg, int bg, int ch) 394 { 395 int xc, yc; 396 BYTE t; 397 BYTE far *ptr; 398 399 if( font8x8 == NULL) 400 if ( (font8x8 = findfont(0)) == NULL ) 401 return ; 402 403 ptr = ((BYTE far *)font8x8) + ch*FONT_DEPTH; 404 405 for (yc=0; yc<FONT_DEPTH; yc++, y++, ++ptr) 406 { 407 for (xc=0, t= *ptr; xc<8; xc++, t<<=1) 408 line_buff[xc] = (BYTE)((t&0x80) ? fg : bg); 409 putrow(x, y, 8, (char *)line_buff); 410 } 411 } 412 413 414 #ifndef USE_VARARGS 415 static void displayf(int x, int y, int fg, int bg, char *format, ...)
416 #else 417 static void displayf(va_alist) 418 va_dcl
419 #endif 420 { 421 char buff[81]; 422 int ctr; 423 424 va_list arg_list; 425 426 #ifndef USE_VARARGS 427 va_start(arg_list, format);
428 #else 429 int x,y,fg,bg; 430 char *format; 431 432 va_start(arg_list); 433 x = va_arg(arg_list,int); 434 y = va_arg(arg_list,int); 435 fg = va_arg(arg_list,int); 436 bg = va_arg(arg_list,int); 437 format = va_arg(arg_list,char *);
438 #endif 439 vsprintf(buff, format, arg_list); 440 va_end(arg_list); 441 442 for(ctr=0; buff[ctr]!='\0'; ctr++, x+=8) 443 displayc(x, y, fg, bg, buff[ctr]); 444 } 445 446 447 /* 448 * create smooth shades between two colors 449 */ 450 451 452 static void mkpalrange(PALENTRY *p1, PALENTRY *p2, PALENTRY pal[], int num, int skip) 453 { 454 int curr; 455 double rm = (double)((int) p2->red - (int) p1->red ) / num, 456 gm = (double)((int) p2->green - (int) p1->green) / num, 457 bm = (double)((int) p2->blue - (int) p1->blue ) / num; 458 459 for (curr=0; curr<num; curr+=skip) 460 { 461 if (gamma_val == 1) 462 { 463 pal[curr].red = (BYTE)((p1->red == p2->red ) ? p1->red : 464 (int) p1->red + (int) ( rm * curr )); 465 pal[curr].green = (BYTE)((p1->green == p2->green) ? p1->green : 466 (int) p1->green + (int) ( gm * curr )); 467 pal[curr].blue = (BYTE)((p1->blue == p2->blue ) ? p1->blue : 468 (int) p1->blue + (int) ( bm * curr )); 469 } 470 else 471 { 472 pal[curr].red = (BYTE)((p1->red == p2->red ) ? p1->red : 473 (int) (p1->red + pow(curr/(double)(num-1),gamma_val)*num*rm)); 474 pal[curr].green = (BYTE)((p1->green == p2->green) ? p1->green : 475 (int) (p1->green + pow(curr/(double)(num-1),gamma_val)*num*gm)); 476 pal[curr].blue = (BYTE)((p1->blue == p2->blue ) ? p1->blue : 477 (int) (p1->blue + pow(curr/(double)(num-1),gamma_val)*num*bm)); 478 } 479 } 480 } 481 482 483 484 /* Swap RG GB & RB columns */ 485 486 static void rotcolrg(PALENTRY pal[], int num) 487 { 488 int curr; 489 int dummy; 490 491 for (curr=0; curr<=num; curr++) 492 { 493 dummy = pal[curr].red; 494 pal[curr].red = pal[curr].green; 495 pal[curr].green = (BYTE)dummy; 496 } 497 } 498 499 500 static void rotcolgb(PALENTRY pal[], int num) 501 { 502 int curr; 503 int dummy; 504 505 for (curr=0; curr<=num; curr++) 506 { 507 dummy = pal[curr].green; 508 pal[curr].green = pal[curr].blue; 509 pal[curr].blue = (BYTE)dummy; 510 } 511 } 512 513 static void rotcolbr(PALENTRY pal[], int num) 514 { 515 int curr; 516 int dummy; 517 518 for (curr=0; curr<=num; curr++) 519 { 520 dummy = pal[curr].red; 521 pal[curr].red = pal[curr].blue; 522 pal[curr].blue = (BYTE)dummy; 523 } 524 } 525 526 527 /* 528 * convert a range of colors to grey scale 529 */ 530 531 532 static void palrangetogrey(PALENTRY pal[], int first, int how_many) 533 { 534 PALENTRY *curr; 535 BYTE val; 536 537 538 for (curr = &pal[first]; how_many>0; how_many--, curr++) 539 { 540 val = (BYTE) ( ((int)curr->red*30 + (int)curr->green*59 + (int)curr->blue*11) / 100 ); 541 curr->red = curr->green = curr->blue = (BYTE)val; 542 } 543 } 544 545 /* 546 * convert a range of colors to their inverse 547 */ 548 549 550 static void palrangetonegative(PALENTRY pal[], int first, int how_many) 551 { 552 PALENTRY *curr; 553 554 for (curr = &pal[first]; how_many>0; how_many--, curr++) 555 { 556 curr->red = (BYTE)(63 - curr->red); 557 curr->green = (BYTE)(63 - curr->green); 558 curr->blue = (BYTE)(63 - curr->blue); 559 } 560 } 561 562 563 /* 564 * draw and horizontal/vertical dotted lines 565 */ 566 567 568 static void hdline(int x, int y, int width) 569 { 570 int ctr; 571 BYTE *ptr; 572 573 for (ctr=0, ptr=line_buff; ctr<width; ctr++, ptr++) 574 *ptr = (BYTE)((ctr&2) ? bg_color : fg_color); 575 576 putrow(x, y, width, (char *)line_buff); 577 } 578 579 580 static void vdline(int x, int y, int depth) 581 { 582 int ctr; 583 584 for (ctr=0; ctr<depth; ctr++, y++) 585 clip_putcolor(x, y, (ctr&2) ? bg_color : fg_color); 586 } 587 588 589 static void drect(int x, int y, int width, int depth) 590 { 591 hdline(x, y, width); 592 hdline(x, y+depth-1, width); 593 594 vdline(x, y, depth); 595 vdline(x+width-1, y, depth); 596 } 597 598 599 /* 600 * A very simple memory "allocator". 601 * 602 * Each call to mem_alloc() returns size bytes from the array mem_block. 603 * 604 * Be sure to call mem_init() before using mem_alloc()! 605 * 606 */ 607 608 static char *mem_block; 609 static unsigned mem_avail; 610 611 612 void mem_init(VOIDPTR block, unsigned size) 613 { 614 mem_block = (char *)block; 615 mem_avail = size; 616 } 617 618 619 VOIDPTR mem_alloc(unsigned size) 620 { 621 VOIDPTR block; 622 623 #ifndef XFRACT 624 if (size & 1) 625 ++size; /* allocate even sizes */
626 #else 627 size = (size+3)&~3; /* allocate word-aligned memory */
628 #endif 629 630 if (mem_avail < size) /* don't let this happen! */ 631 { 632 static FCODE msg[] = "editpal.c: Out of memory!\n"; 633 634 stopmsg(0, msg); 635 exit(1); 636 } 637 638 block = mem_block; 639 mem_avail -= size; 640 mem_block += size; 641 642 return(block); 643 } 644 645 646 647 /* 648 * misc. routines 649 * 650 */ 651 652 653 static BOOLEAN is_reserved(int color) 654 { 655 return ((BOOLEAN) ((reserve_colors && (color==(int)fg_color || color==(int)bg_color) ) ? TRUE : FALSE) ); 656 } 657 658 659 660 static BOOLEAN is_in_box(int x, int y, int bx, int by, int bw, int bd) 661 { 662 return ((BOOLEAN) ((x >= bx) && (y >= by) && (x < bx+bw) && (y < by+bd)) ); 663 } 664 665 666 667 static void draw_diamond(int x, int y, int color) 668 { 669 putcolor (x+2, y+0, color); 670 hline (x+1, y+1, 3, color); 671 hline (x+0, y+2, 5, color); 672 hline (x+1, y+3, 3, color); 673 putcolor (x+2, y+4, color); 674 } 675 676 677 678 /* 679 * Class: Cursor 680 * 681 * Purpose: Draw the blinking cross-hair cursor. 682 * 683 * Note: Only one Cursor can exist (referenced through the_cursor). 684 * IMPORTANT: Call Cursor_Construct before you use any other 685 * Cursor_ function! Call Cursor_Destroy before exiting to 686 * deallocate memory. 687 */ 688 689 struct _Cursor 690 { 691 692 int x, y; 693 int hidden; /* >0 if mouse hidden */ 694 long last_blink; 695 BOOLEAN blink; 696 #if 0
697 char t[CURSOR_SIZE], /* save line segments here */ 698 b[CURSOR_SIZE], 699 l[CURSOR_SIZE], 700 r[CURSOR_SIZE];
701 #endif 702 char t[CURSOR_SIZE]; /* save line segments here */ 703 char b[CURSOR_SIZE]; 704 char l[CURSOR_SIZE]; 705 char r[CURSOR_SIZE]; 706 } ; 707 708 #define Cursor struct _Cursor 709 710 /* private: */ 711 712 static void Cursor__Draw (void); 713 static void Cursor__Save (void); 714 static void Cursor__Restore (void); 715 716 /* public: */ 717 #ifdef NOT_USED
718 static BOOLEAN Cursor_IsHidden (void);
719 #endif 720 721 722 723 static Cursor *the_cursor = NULL; 724 725 726 BOOLEAN Cursor_Construct(void) 727 { 728 if (the_cursor != NULL) 729 return(FALSE); 730 731 the_cursor = new(Cursor); 732 733 the_cursor->x = sxdots/2; 734 the_cursor->y = sydots/2; 735 the_cursor->hidden = 1; 736 the_cursor->blink = FALSE; 737 the_cursor->last_blink = 0; 738 739 return (TRUE); 740 } 741 742 743 void Cursor_Destroy(void) 744 { 745 if (the_cursor != NULL) 746 delete(the_cursor); 747 748 the_cursor = NULL; 749 } 750 751 752 753 static void Cursor__Draw(void) 754 { 755 int color; 756 757 find_special_colors(); 758 color = (the_cursor->blink) ? color_medium : color_dark; 759 760 vline(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, color); 761 vline(the_cursor->x, the_cursor->y+2, CURSOR_SIZE, color); 762 763 hline(the_cursor->x-CURSOR_SIZE-1, the_cursor->y, CURSOR_SIZE, color); 764 hline(the_cursor->x+2, the_cursor->y, CURSOR_SIZE, color); 765 } 766 767 768 static void Cursor__Save(void) 769 { 770 vgetrow(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, the_cursor->t); 771 vgetrow(the_cursor->x, the_cursor->y+2, CURSOR_SIZE, the_cursor->b); 772 773 getrow(the_cursor->x-CURSOR_SIZE-1, the_cursor->y, CURSOR_SIZE, the_cursor->l); 774 getrow(the_cursor->x+2, the_cursor->y, CURSOR_SIZE, the_cursor->r); 775 } 776 777 778 static void Cursor__Restore(void) 779 { 780 vputrow(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, the_cursor->t); 781 vputrow(the_cursor->x, the_cursor->y+2, CURSOR_SIZE, the_cursor->b); 782 783 putrow(the_cursor->x-CURSOR_SIZE-1, the_cursor->y, CURSOR_SIZE, the_cursor->l); 784 putrow(the_cursor->x+2, the_cursor->y, CURSOR_SIZE, the_cursor->r); 785 } 786 787 788 789 void Cursor_SetPos(int x, int y) 790 { 791 if (!the_cursor->hidden) 792 Cursor__Restore(); 793 794 the_cursor->x = x; 795 the_cursor->y = y; 796 797 if (!the_cursor->hidden) 798 { 799 Cursor__Save(); 800 Cursor__Draw(); 801 } 802 } 803 804 #ifdef NOT_USED
805 806 static int Cursor_IsHidden(void) 807 { 808 return ( the_cursor->hidden ); 809 } 810 811
812 #endif 813 814 815 void Cursor_Move(int xoff, int yoff) 816 { 817 if ( !the_cursor->hidden ) 818 Cursor__Restore(); 819 820 the_cursor->x += xoff; 821 the_cursor->y += yoff; 822 823 if (the_cursor->x < 0) the_cursor->x = 0; 824 if (the_cursor->y < 0) the_cursor->y = 0; 825 if (the_cursor->x >= sxdots) the_cursor->x = sxdots-1; 826 if (the_cursor->y >= sydots) the_cursor->y = sydots-1; 827 828 if ( !the_cursor->hidden ) 829 { 830 Cursor__Save(); 831 Cursor__Draw(); 832 } 833 } 834 835 836 int Cursor_GetX(void) { return(the_cursor->x); } 837 838 int Cursor_GetY(void) { return(the_cursor->y); } 839 840 841 void Cursor_Hide(void) 842 { 843 if ( the_cursor->hidden++ == 0 ) 844 Cursor__Restore(); 845 } 846 847 848 void Cursor_Show(void) 849 { 850 if ( --the_cursor->hidden == 0) 851 { 852 Cursor__Save(); 853 Cursor__Draw(); 854 } 855 } 856 857 #ifdef XFRACT
858 void Cursor_StartMouseTracking() 859 { 860 editpal_cursor = 1; 861 } 862 863 void Cursor_EndMouseTracking() 864 { 865 editpal_cursor = 0; 866 }
867 #endif 868 869 /* See if the cursor should blink yet, and blink it if so */ 870 void Cursor_CheckBlink(void) 871 { 872 long tick; 873 tick = readticker(); 874 875 if ( (tick - the_cursor->last_blink) > CURSOR_BLINK_RATE ) 876 { 877 the_cursor->blink = (BOOLEAN)((the_cursor->blink) ? FALSE : TRUE); 878 the_cursor->last_blink = tick; 879 if ( !the_cursor->hidden ) 880 Cursor__Draw(); 881 } 882 else if ( tick < the_cursor->last_blink ) 883 the_cursor->last_blink = tick; 884 } 885 886 int Cursor_WaitKey(void) /* blink cursor while waiting for a key */ 887 { 888 889 #ifndef XFRACT 890 while ( !keypressed() ) { 891 Cursor_CheckBlink(); 892 }
893 #else 894 while ( !waitkeypressed(1) ) { 895 Cursor_CheckBlink(); 896 }
897 #endif 898 899 return( keypressed() ); 900 } 901 902 903 904 /* 905 * Class: MoveBox 906 * 907 * Purpose: Handles the rectangular move/resize box. 908 */ 909 910 struct _MoveBox 911 { 912 int x, y; 913 int base_width, 914 base_depth; 915 int csize; 916 BOOLEAN moved; 917 BOOLEAN should_hide; 918 char *t, *b, 919 *l, *r; 920 } ; 921 922 #define MoveBox struct _MoveBox 923 924 /* private: */ 925 926 static void MoveBox__Draw (MoveBox *this); 927 static void MoveBox__Erase (MoveBox *this); 928 static void MoveBox__Move (MoveBox *this, int key); 929 930 /* public: */ 931 932 static MoveBox *MoveBox_Construct (int x, int y, int csize, int base_width, 933 int base_depth); 934 static void MoveBox_Destroy (MoveBox *this); 935 static BOOLEAN MoveBox_Process (MoveBox *this); /* returns FALSE if ESCAPED */ 936 static BOOLEAN MoveBox_Moved (MoveBox *this); 937 static BOOLEAN MoveBox_ShouldHide (MoveBox *this); 938 static int MoveBox_X (MoveBox *this); 939 static int MoveBox_Y (MoveBox *this); 940 static int MoveBox_CSize (MoveBox *this); 941 942 static void MoveBox_SetPos (MoveBox *this, int x, int y); 943 static void MoveBox_SetCSize (MoveBox *this, int csize); 944 945 946 947 static MoveBox *MoveBox_Construct(int x, int y, int csize, int base_width, int base_depth) 948 { 949 MoveBox *this = new(MoveBox); 950 951 this->x = x; 952 this->y = y; 953 this->csize = csize; 954 this->base_width = base_width; 955 this->base_depth = base_depth; 956 this->moved = FALSE; 957 this->should_hide = FALSE; 958 this->t = newx(sxdots); 959 this->b = newx(sxdots); 960 this->l = newx(sydots); 961 this->r = newx(sydots); 962 963 return(this); 964 } 965 966 967 static void MoveBox_Destroy(MoveBox *this) 968 { 969 delete(this->t); 970 delete(this->b); 971 delete(this->l); 972 delete(this->r); 973 delete(this); 974 } 975 976 977 static BOOLEAN MoveBox_Moved(MoveBox *this) { return(this->moved); } 978 979 static BOOLEAN MoveBox_ShouldHide(MoveBox *this) { return(this->should_hide); } 980 981 static int MoveBox_X(MoveBox *this) { return(this->x); } 982 983 static int MoveBox_Y(MoveBox *this) { return(this->y); } 984 985 static int MoveBox_CSize(MoveBox *this) { return(this->csize); } 986 987 988 static void MoveBox_SetPos(MoveBox *this, int x, int y) 989 { 990 this->x = x; 991 this->y = y; 992 } 993 994 995 static void MoveBox_SetCSize(MoveBox *this, int csize) 996 { 997 this->csize = csize; 998 } 999 1000 1001 static void MoveBox__Draw(MoveBox *this) /* private */ 1002 { 1003 int width = this->base_width + this->csize*16+1, 1004 depth = this->base_depth + this->csize*16+1; 1005 int x = this->x, 1006 y = this->y; 1007 1008 1009 getrow (x, y, width, this->t); 1010 getrow (x, y+depth-1, width, this->b); 1011 1012 vgetrow(x, y, depth, this->l); 1013 vgetrow(x+width-1, y, depth, this->r); 1014 1015 hdline(x, y, width); 1016 hdline(x, y+depth-1, width); 1017 1018 vdline(x, y, depth); 1019 vdline(x+width-1, y, depth); 1020 } 1021 1022 1023 static void MoveBox__Erase(MoveBox *this) /* private */ 1024 { 1025 int width = this->base_width + this->csize*16+1, 1026 depth = this->base_depth + this->csize*16+1; 1027 1028 vputrow(this->x, this->y, depth, this->l); 1029 vputrow(this->x+width-1, this->y, depth, this->r); 1030 1031 putrow(this->x, this->y, width, this->t); 1032 putrow(this->x, this->y+depth-1, width, this->b); 1033 } 1034 1035 1036 #define BOX_INC 1 1037 #define CSIZE_INC 2 1038 1039 static void MoveBox__Move(MoveBox *this, int key) 1040 { 1041 BOOLEAN done = FALSE; 1042 BOOLEAN first = TRUE; 1043 int xoff = 0, 1044 yoff = 0; 1045 1046 while ( !done ) 1047 { 1048 switch(key) 1049 { 1050 case RIGHT_ARROW_2: xoff += BOX_INC*4; break; 1051 case RIGHT_ARROW: xoff += BOX_INC; break; 1052 case LEFT_ARROW_2: xoff -= BOX_INC*4; break; 1053 case LEFT_ARROW: xoff -= BOX_INC; break; 1054 case DOWN_ARROW_2: yoff += BOX_INC*4; break; 1055 case DOWN_ARROW: yoff += BOX_INC; break; 1056 case UP_ARROW_2: yoff -= BOX_INC*4; break; 1057 case UP_ARROW: yoff -= BOX_INC; break; 1058 1059 default: 1060 done = TRUE; 1061 } 1062 1063 if (!done) 1064 { 1065 if (!first) 1066 getakey(); /* delete key from buffer */ 1067 else 1068 first = FALSE; 1069 key = keypressed(); /* peek at the next one... */ 1070 } 1071 } 1072 1073 xoff += this->x; 1074 yoff += this->y; /* (xoff,yoff) = new position */ 1075 1076 if (xoff < 0) xoff = 0; 1077 if (yoff < 0) yoff = 0; 1078 1079 if (xoff+this->base_width+this->csize*16+1 > sxdots) 1080 xoff = sxdots - (this->base_width+this->csize*16+1); 1081 1082 if (yoff+this->base_depth+this->csize*16+1 > sydots) 1083 yoff = sydots - (this->base_depth+this->csize*16+1); 1084 1085 if ( xoff!=this->x || yoff!=this->y ) 1086 { 1087 MoveBox__Erase(this); 1088 this->y = yoff; 1089 this->x = xoff; 1090 MoveBox__Draw(this); 1091 } 1092 } 1093 1094 1095 static BOOLEAN MoveBox_Process(MoveBox *this) 1096 { 1097 int key; 1098 int orig_x = this->x, 1099 orig_y = this->y, 1100 orig_csize = this->csize; 1101 1102 MoveBox__Draw(this); 1103 1104 #ifdef XFRACT
1105 Cursor_StartMouseTracking();
1106 #endif 1107 for(;;) 1108 { 1109 Cursor_WaitKey(); 1110 key = getakey(); 1111 1112 if (key==ENTER || key==ENTER_2 || key==ESC || key=='H' || key=='h') 1113 { 1114 if (this->x != orig_x || this->y != orig_y || this->csize != orig_csize) 1115 this->moved = TRUE; 1116 else 1117 this->moved = FALSE; 1118 break; 1119 } 1120 1121 switch(key) 1122 { 1123 case UP_ARROW: 1124 case DOWN_ARROW: 1125 case LEFT_ARROW: 1126 case RIGHT_ARROW: 1127 case UP_ARROW_2: 1128 case DOWN_ARROW_2: 1129 case LEFT_ARROW_2: 1130 case RIGHT_ARROW_2: 1131 MoveBox__Move(this, key); 1132 break; 1133 1134 case PAGE_UP: /* shrink */ 1135 if (this->csize > CSIZE_MIN) 1136 { 1137 int t = this->csize - CSIZE_INC; 1138 int change; 1139 1140 if (t < CSIZE_MIN) 1141 t = CSIZE_MIN; 1142 1143 MoveBox__Erase(this); 1144 1145 change = this->csize - t; 1146 this->csize = t; 1147 this->x += (change*16) / 2; 1148 this->y += (change*16) / 2; 1149 MoveBox__Draw(this); 1150 } 1151 break; 1152 1153 case PAGE_DOWN: /* grow */ 1154 { 1155 int max_width = min(sxdots, MAX_WIDTH); 1156 1157 if (this->base_depth+(this->csize+CSIZE_INC)*16+1 < sydots && 1158 this->base_width+(this->csize+CSIZE_INC)*16+1 < max_width ) 1159 { 1160 MoveBox__Erase(this); 1161 this->x -= (CSIZE_INC*16) / 2; 1162 this->y -= (CSIZE_INC*16) / 2; 1163 this->csize += CSIZE_INC; 1164 if (this->y+this->base_depth+this->csize*16+1 > sydots) 1165 this->y = sydots - (this->base_depth+this->csize*16+1); 1166 if (this->x+this->base_width+this->csize*16+1 > max_width) 1167 this->x = max_width - (this->base_width+this->csize*16+1); 1168 if (this->y < 0) 1169 this->y = 0; 1170 if (this->x < 0) 1171 this->x = 0; 1172 MoveBox__Draw(this); 1173 } 1174 } 1175 break; 1176 } 1177 } 1178 1179 #ifdef XFRACT
1180 Cursor_EndMouseTracking();
1181 #endif 1182 1183 MoveBox__Erase(this); 1184 1185 this->should_hide = (BOOLEAN)((key == 'H' || key == 'h') ? TRUE : FALSE); 1186 1187 return( (BOOLEAN)((key==ESC) ? FALSE : TRUE) ); 1188 } 1189 1190 1191 1192 /* 1193 * Class: CEditor 1194 * 1195 * Purpose: Edits a single color component (R, G or B) 1196 * 1197 * Note: Calls the "other_key" function to process keys it doesn't use. 1198 * The "change" function is called whenever the value is changed 1199 * by the CEditor. 1200 */ 1201 1202 struct _CEditor 1203 { 1204 int x, y; 1205 char letter; 1206 int val; 1207 BOOLEAN done; 1208 BOOLEAN hidden; 1209 #ifndef XFRACT 1210 void (*other_key)(int key, struct _CEditor *ce, VOIDPTR info); 1211 void (*change)(struct _CEditor *ce, VOIDPTR info);
1212 #else 1213 void (*other_key)(); 1214 void (*change)();
1215 #endif 1216 void *info; 1217 1218 } ; 1219 1220 #define CEditor struct _CEditor 1221 1222 /* public: */ 1223 1224 #ifndef XFRACT 1225 static CEditor *CEditor_Construct( int x, int y, char letter, 1226 void (*other_key)(int,CEditor*,void*), 1227 void (*change)(CEditor*,void*), VOIDPTR info); 1228 static void CEditor_Destroy (CEditor *this); 1229 static void CEditor_Draw (CEditor *this); 1230 static void CEditor_SetPos (CEditor *this, int x, int y); 1231 static void CEditor_SetVal (CEditor *this, int val); 1232 static int CEditor_GetVal (CEditor *this); 1233 static void CEditor_SetDone (CEditor *this, BOOLEAN done); 1234 static void CEditor_SetHidden (CEditor *this, BOOLEAN hidden); 1235 static int CEditor_Edit (CEditor *this);
1236 #else 1237 static CEditor *CEditor_Construct( int , int , char , 1238 void (*other_key)(), 1239 void (*change)(), VOIDPTR ); 1240 static void CEditor_Destroy (CEditor *); 1241 static void CEditor_Draw (CEditor *); 1242 static void CEditor_SetPos (CEditor *, int , int ); 1243 static void CEditor_SetVal (CEditor *, int ); 1244 static int CEditor_GetVal (CEditor *); 1245 static void CEditor_SetDone (CEditor *, BOOLEAN ); 1246 static void CEditor_SetHidden (CEditor *, BOOLEAN ); 1247 static int CEditor_Edit (CEditor *);
1248 #endif 1249 1250 #define CEditor_WIDTH (8*3+4) 1251 #define CEditor_DEPTH (8+4) 1252 1253 1254 1255 #ifndef XFRACT 1256 static CEditor *CEditor_Construct( int x, int y, char letter, 1257 void (*other_key)(int,CEditor*,VOIDPTR), 1258 void (*change)(CEditor*, VOIDPTR), VOIDPTR info)
1259 #else 1260 static CEditor *CEditor_Construct( int x, int y, char letter, 1261 void (*other_key)(), 1262 void (*change)(), VOIDPTR info)
1263 #endif 1264 { 1265 CEditor *this = new(CEditor); 1266 1267 this->x = x; 1268 this->y = y; 1269 this->letter = letter; 1270 this->val = 0; 1271 this->other_key = other_key; 1272 this->hidden = FALSE; 1273 this->change = change; 1274 this->info = info; 1275 1276 return(this); 1277 } 1278 1279 #ifdef __TURBOC__
1280 # pragma argsused /* kills "arg not used" warning */
1281 #endif 1282 #ifdef __CLINT__
1283 # pragma argsused /* kills "arg not used" warning */
1284 #endif 1285 1286 static void CEditor_Destroy(CEditor *this) 1287 { 1288 delete(this); 1289 } 1290 1291 1292 static void CEditor_Draw(CEditor *this) 1293 { 1294 if (this->hidden) 1295 return; 1296 1297 Cursor_Hide(); 1298 displayf(this->x+2, this->y+2, fg_color, bg_color, "%c%02d", this->letter, this->val); 1299 Cursor_Show(); 1300 } 1301 1302 1303 static void CEditor_SetPos(CEditor *this, int x, int y) 1304 { 1305 this->x = x; 1306 this->y = y; 1307 } 1308 1309 1310 static void CEditor_SetVal(CEditor *this, int val) 1311 { 1312 this->val = val; 1313 } 1314 1315 1316 static int CEditor_GetVal(CEditor *this) 1317 { 1318 return(this->val); 1319 } 1320 1321 1322 static void CEditor_SetDone(CEditor *this, BOOLEAN done) 1323 { 1324 this->done = done; 1325 } 1326 1327 1328 static void CEditor_SetHidden(CEditor *this, BOOLEAN hidden) 1329 { 1330 this->hidden = hidden; 1331 } 1332 1333 1334 static int CEditor_Edit(CEditor *this) 1335 { 1336 int key = 0; 1337 int diff; 1338 1339 this->done = FALSE; 1340 1341 if (!this->hidden) 1342 { 1343 Cursor_Hide(); 1344 rect(this->x, this->y, CEditor_WIDTH, CEditor_DEPTH, fg_color); 1345 Cursor_Show(); 1346 } 1347 1348 #ifdef XFRACT
1349 Cursor_StartMouseTracking();
1350 #endif 1351 while ( !this->done ) 1352 { 1353 Cursor_WaitKey(); 1354 key = getakey(); 1355 1356 switch( key ) 1357 { 1358 case PAGE_UP: 1359 if (this->val < 63) 1360 { 1361 this->val += 5; 1362 if (this->val > 63) 1363 this->val = 63; 1364 CEditor_Draw(this); 1365 this->change(this, this->info); 1366 } 1367 break; 1368 1369 case '+': 1370 case CTL_PLUS: /*RB*/ 1371 diff = 1; 1372 while ( keypressed() == key ) 1373 { 1374 getakey(); 1375 ++diff; 1376 } 1377 if (this->val < 63) 1378 { 1379 this->val += diff; 1380 if (this->val > 63) 1381 this->val = 63; 1382 CEditor_Draw(this); 1383 this->change(this, this->info); 1384 } 1385 break; 1386 1387 case PAGE_DOWN: 1388 if (this->val > 0) 1389 { 1390 this->val -= 5; 1391 if (this->val < 0) 1392 this->val = 0; 1393 CEditor_Draw(this); 1394 this->change(this, this->info); 1395 } break; 1396 1397 case '-': 1398 case CTL_MINUS: /*RB*/ 1399 diff = 1; 1400 while ( keypressed() == key ) 1401 { 1402 getakey(); 1403 ++diff; 1404 } 1405 if (this->val > 0) 1406 { 1407 this->val -= diff; 1408 if (this->val < 0) 1409 this->val = 0; 1410 CEditor_Draw(this); 1411 this->change(this, this->info); 1412 } 1413 break; 1414 1415 case '0': 1416 case '1': 1417 case '2': 1418 case '3': 1419 case '4': 1420 case '5': 1421 case '6': 1422 case '7': 1423 case '8': 1424 case '9': 1425 this->val = (key - '0') * 10; 1426 if (this->val > 63) 1427 this->val = 63; 1428 CEditor_Draw(this); 1429 this->change(this, this->info); 1430 break; 1431 1432 default: 1433 this->other_key(key, this, this->info); 1434 break; 1435 } /* switch */ 1436 } /* while */ 1437 #ifdef XFRACT
1438 Cursor_EndMouseTracking();
1439 #endif 1440 1441 if (!this->hidden) 1442 { 1443 Cursor_Hide(); 1444 rect(this->x, this->y, CEditor_WIDTH, CEditor_DEPTH, bg_color); 1445 Cursor_Show(); 1446 } 1447 1448 return(key); 1449 } 1450 1451 1452 1453 /* 1454 * Class: RGBEditor 1455 * 1456 * Purpose: Edits a complete color using three CEditors for R, G and B 1457 */ 1458 1459 struct _RGBEditor 1460 { 1461 int x, y; /* position */ 1462 int curr; /* 0=r, 1=g, 2=b */ 1463 int pal; /* palette number */ 1464 BOOLEAN done; 1465 BOOLEAN hidden; 1466 CEditor *color[3]; /* color editors 0=r, 1=g, 2=b */ 1467 #ifndef XFRACT 1468 void (*other_key)(int key, struct _RGBEditor *e, VOIDPTR info); 1469 void (*change)(struct _RGBEditor *e, VOIDPTR info);
1470 #else 1471 void (*other_key)(); 1472 void (*change)();
1473 #endif 1474 void *info; 1475 } ; 1476 1477 #define RGBEditor struct _RGBEditor 1478 1479 /* private: */ 1480 1481 static void RGBEditor__other_key (int key, CEditor *ceditor, VOIDPTR info); 1482 static void RGBEditor__change (CEditor *ceditor, VOIDPTR info); 1483 1484 /* public: */ 1485 1486 #ifndef XFRACT 1487 static RGBEditor *RGBEditor_Construct(int x, int y, 1488 void (*other_key)(int,RGBEditor*,void*), 1489 void (*change)(RGBEditor*,void*), VOIDPTR info);
1490 #else 1491 static RGBEditor *RGBEditor_Construct(int x, int y, 1492 void (*other_key)(), 1493 void (*change)(), VOIDPTR info);
1494 #endif 1495 1496 static void RGBEditor_Destroy (RGBEditor *this); 1497 static void RGBEditor_SetPos (RGBEditor *this, int x, int y); 1498 static void RGBEditor_SetDone (RGBEditor *this, BOOLEAN done); 1499 static void RGBEditor_SetHidden(RGBEditor *this, BOOLEAN hidden); 1500 static void RGBEditor_BlankSampleBox(RGBEditor *this); 1501 static void RGBEditor_Update (RGBEditor *this); 1502 static void RGBEditor_Draw (RGBEditor *this); 1503 static int RGBEditor_Edit (RGBEditor *this); 1504 static void RGBEditor_SetRGB (RGBEditor *this, int pal, PALENTRY *rgb); 1505 static PALENTRY RGBEditor_GetRGB (RGBEditor *this); 1506 1507 #define RGBEditor_WIDTH 62 1508 #define RGBEditor_DEPTH (1+1+CEditor_DEPTH*3-2+2) 1509 1510 #define RGBEditor_BWIDTH ( RGBEditor_WIDTH - (2+CEditor_WIDTH+1 + 2) ) 1511 #define RGBEditor_BDEPTH ( RGBEditor_DEPTH - 4 ) 1512 1513 1514 1515 #ifndef XFRACT 1516 static RGBEditor *RGBEditor_Construct(int x, int y, void (*other_key)(int,RGBEditor*,void*), 1517 void (*change)(RGBEditor*,void*), VOIDPTR info)
1518 #else 1519 static RGBEditor *RGBEditor_Construct(int x, int y, void (*other_key)(), 1520 void (*change)(), VOIDPTR info)
1521 #endif 1522 { 1523 RGBEditor *this = new(RGBEditor); 1524 static FCODE letter[] = "RGB"; 1525 int ctr; 1526 1527 for (ctr=0; ctr<3; ctr++) 1528 this->color[ctr] = CEditor_Construct(0, 0, letter[ctr], RGBEditor__other_key, 1529 RGBEditor__change, this); 1530 1531 RGBEditor_SetPos(this, x, y); 1532 this->curr = 0; 1533 this->pal = 1; 1534 this->hidden = FALSE; 1535 this->other_key = other_key; 1536 this->change = change; 1537 this->info = info; 1538 1539 return(this); 1540 } 1541 1542 1543 static void RGBEditor_Destroy(RGBEditor *this) 1544 { 1545 CEditor_Destroy(this->color[0]); 1546 CEditor_Destroy(this->color[1]); 1547 CEditor_Destroy(this->color[2]); 1548 delete(this); 1549 } 1550 1551 1552 static void RGBEditor_SetDone(RGBEditor *this, BOOLEAN done) 1553 { 1554 this->done = done; 1555 } 1556 1557 1558 static void RGBEditor_SetHidden(RGBEditor *this, BOOLEAN hidden) 1559 { 1560 this->hidden = hidden; 1561 CEditor_SetHidden(this->color[0], hidden); 1562 CEditor_SetHidden(this->color[1], hidden); 1563 CEditor_SetHidden(this->color[2], hidden); 1564 } 1565 1566 1567 static void RGBEditor__other_key(int key, CEditor *ceditor, VOIDPTR info) /* private */ 1568 { 1569 RGBEditor *this = (RGBEditor *)info; 1570 1571 switch( key ) 1572 { 1573 case 'R': 1574 case 'r': 1575 if (this->curr != 0) 1576 { 1577 this->curr = 0; 1578 CEditor_SetDone(ceditor, TRUE); 1579 } 1580 break; 1581 1582 case 'G': 1583 case 'g': 1584 if (this->curr != 1) 1585 { 1586 this->curr = 1; 1587 CEditor_SetDone(ceditor, TRUE); 1588 } 1589 break; 1590 1591 case 'B': 1592 case 'b': 1593 if (this->curr != 2) 1594 { 1595 this->curr = 2; 1596 CEditor_SetDone(ceditor, TRUE); 1597 } 1598 break; 1599 1600 case DELETE: /* move to next CEditor */ 1601 case CTL_ENTER_2: /*double click rt mouse also! */ 1602 if ( ++this->curr > 2) 1603 this->curr = 0; 1604 CEditor_SetDone(ceditor, TRUE); 1605 break; 1606 1607 case INSERT: /* move to prev CEditor */ 1608 if ( --this->curr < 0) 1609 this->curr = 2; 1610 CEditor_SetDone(ceditor, TRUE); 1611 break; 1612 1613 default: 1614 this->other_key(key, this, this->info); 1615 if (this->done) 1616 CEditor_SetDone(ceditor, TRUE); 1617 break; 1618 } 1619 } 1620 1621 #ifdef __TURBOC__
1622 # pragma argsused /* kills "arg not used" warning */
1623 #endif 1624 #ifdef __CLINT__
1625 # pragma argsused /* kills "arg not used" warning */
1626 #endif 1627 1628 static void RGBEditor__change(CEditor *ceditor, VOIDPTR info) /* private */ 1629 { 1630 RGBEditor *this = (RGBEditor *)info; 1631 1632 ceditor = NULL; /* just for warning */ 1633 if ( this->pal < colors && !is_reserved(this->pal) ) 1634 setpal(this->pal, CEditor_GetVal(this->color[0]), 1635 CEditor_GetVal(this->color[1]), CEditor_GetVal(this->color[2])); 1636 1637 this->change(this, this->info); 1638 } 1639 1640 1641 static void RGBEditor_SetPos(RGBEditor *this, int x, int y) 1642 { 1643 this->x = x; 1644 this->y = y; 1645 1646 CEditor_SetPos(this->color[0], x+2, y+2); 1647 CEditor_SetPos(this->color[1], x+2, y+2+CEditor_DEPTH-1); 1648 CEditor_SetPos(this->color[2], x+2, y+2+CEditor_DEPTH-1+CEditor_DEPTH-1); 1649 } 1650 1651 1652 static void RGBEditor_BlankSampleBox(RGBEditor *this) 1653 { 1654 if (this->hidden) 1655 return ; 1656 1657 Cursor_Hide(); 1658 fillrect(this->x+2+CEditor_WIDTH+1+1, this->y+2+1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color); 1659 Cursor_Show(); 1660 } 1661 1662 1663 static void RGBEditor_Update(RGBEditor *this) 1664 { 1665 int x1 = this->x+2+CEditor_WIDTH+1+1, 1666 y1 = this->y+2+1; 1667 1668 if (this->hidden) 1669 return ; 1670 1671 Cursor_Hide(); 1672 1673 if ( this->pal >= colors ) 1674 { 1675 fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color); 1676 draw_diamond(x1+(RGBEditor_BWIDTH-5)/2, y1+(RGBEditor_BDEPTH-5)/2, fg_color); 1677 } 1678 1679 else if ( is_reserved(this->pal) ) 1680 { 1681 int x2 = x1+RGBEditor_BWIDTH-3, 1682 y2 = y1+RGBEditor_BDEPTH-3; 1683 1684 fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color); 1685 draw_line(x1, y1, x2, y2, fg_color); 1686 draw_line(x1, y2, x2, y1, fg_color); 1687 } 1688 else 1689 fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, this->pal); 1690 1691 CEditor_Draw(this->color[0]); 1692 CEditor_Draw(this->color[1]); 1693 CEditor_Draw(this->color[2]); 1694 Cursor_Show(); 1695 } 1696 1697 1698 static void RGBEditor_Draw(RGBEditor *this) 1699 { 1700 if (this->hidden) 1701 return ; 1702 1703 Cursor_Hide(); 1704 drect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH); 1705 fillrect(this->x+1, this->y+1, RGBEditor_WIDTH-2, RGBEditor_DEPTH-2, bg_color); 1706 rect(this->x+1+CEditor_WIDTH+2, this->y+2, RGBEditor_BWIDTH, RGBEditor_BDEPTH, fg_color); 1707 RGBEditor_Update(this); 1708 Cursor_Show(); 1709 } 1710 1711 1712 static int RGBEditor_Edit(RGBEditor *this) 1713 { 1714 int key = 0; 1715 1716 this->done = FALSE; 1717 1718 if (!this->hidden) 1719 { 1720 Cursor_Hide(); 1721 rect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH, fg_color); 1722 Cursor_Show(); 1723 } 1724 1725 while ( !this->done ) 1726 key = CEditor_Edit( this->color[this->curr] ); 1727 1728 if (!this->hidden) 1729 { 1730 Cursor_Hide(); 1731 drect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH); 1732 Cursor_Show(); 1733 } 1734 1735 return (key); 1736 } 1737 1738 1739 static void RGBEditor_SetRGB(RGBEditor *this, int pal, PALENTRY *rgb) 1740 { 1741 this->pal = pal; 1742 CEditor_SetVal(this->color[0], rgb->red); 1743 CEditor_SetVal(this->color[1], rgb->green); 1744 CEditor_SetVal(this->color[2], rgb->blue); 1745 } 1746 1747 1748 static PALENTRY RGBEditor_GetRGB(RGBEditor *this) 1749 { 1750 PALENTRY pal; 1751 1752 pal.red = (BYTE)CEditor_GetVal(this->color[0]); 1753 pal.green = (BYTE)CEditor_GetVal(this->color[1]); 1754 pal.blue = (BYTE)CEditor_GetVal(this->color[2]); 1755 1756 return(pal); 1757 } 1758 1759 1760 1761 /* 1762 * Class: PalTable 1763 * 1764 * Purpose: This is where it all comes together. Creates the two RGBEditors 1765 * and the palette. Moves the cursor, hides/restores the screen, 1766 * handles (S)hading, (C)opying, e(X)clude mode, the "Y" exclusion 1767 * mode, (Z)oom option, (H)ide palette, rotation, etc. 1768 * 1769 */ 1770 1771 /* 1772 enum stored_at_values 1773 { 1774 NOWHERE, 1775 DISK, 1776 MEMORY 1777 } ; 1778 */ 1779 1780 /* 1781 1782 Modes: 1783 Auto: "A", " " 1784 Exclusion: "X", "Y", " " 1785 Freestyle: "F", " " 1786 S(t)ripe mode: "T", " " 1787 1788 */ 1789 1790 1791 1792 struct _PalTable 1793 { 1794 int x, y; 1795 int csize; 1796 int active; /* which RGBEditor is active (0,1) */ 1797 int curr[2]; 1798 RGBEditor *rgb[2]; 1799 MoveBox *movebox; 1800 BOOLEAN done; 1801 BOOLEAN exclude; 1802 BOOLEAN auto_select; 1803 PALENTRY pal[256]; 1804 FILE *undo_file; 1805 BOOLEAN curr_changed; 1806 int num_redo; 1807 int hidden; 1808 int stored_at; 1809 FILE *file; 1810 char far *memory; 1811 1812 PALENTRY far *save_pal[8]; 1813 1814 1815 PALENTRY fs_color; 1816 int top,bottom; /* top and bottom colours of freestyle band */ 1817 int bandwidth; /*size of freestyle colour band */ 1818 BOOLEAN freestyle; 1819 } ; 1820 1821 #define PalTable struct _PalTable 1822 1823 /* private: */ 1824 1825 static void PalTable__DrawStatus (PalTable *this, BOOLEAN stripe_mode); 1826 static void PalTable__HlPal (PalTable *this, int pnum, int color); 1827 static void PalTable__Draw (PalTable *this); 1828 static BOOLEAN PalTable__SetCurr (PalTable *this, int which, int curr); 1829 static BOOLEAN PalTable__MemoryAlloc (PalTable *this, long size); 1830 static void PalTable__SaveRect (PalTable *this); 1831 static void PalTable__RestoreRect (PalTable *this); 1832 static void PalTable__SetPos (PalTable *this, int x, int y); 1833 static void PalTable__SetCSize (PalTable *this, int csize); 1834 static int PalTable__GetCursorColor(PalTable *this); 1835 static void PalTable__DoCurs (PalTable *this, int key); 1836 static void PalTable__Rotate (PalTable *this, int dir, int lo, int hi); 1837 static void PalTable__UpdateDAC (PalTable *this); 1838 static void PalTable__other_key (int key, RGBEditor *rgb, VOIDPTR info); 1839 static void PalTable__SaveUndoData(PalTable *this, int first, int last); 1840 static void PalTable__SaveUndoRotate(PalTable *this, int dir, int first, int last); 1841 static void PalTable__UndoProcess (PalTable *this, int delta); 1842 static void PalTable__Undo (PalTable *this); 1843 static void PalTable__Redo (PalTable *this); 1844 static void PalTable__change (RGBEditor *rgb, VOIDPTR info); 1845 1846 /* public: */ 1847 1848 static PalTable *PalTable_Construct (void); 1849 static void PalTable_Destroy (PalTable *this); 1850 static void PalTable_Process (PalTable *this); 1851 static void PalTable_SetHidden (PalTable *this, BOOLEAN hidden); 1852 static void PalTable_Hide (PalTable *this, RGBEditor *rgb, BOOLEAN hidden); 1853 1854 1855 #define PalTable_PALX (1) 1856 #define PalTable_PALY (2+RGBEditor_DEPTH+2) 1857 1858 #define UNDO_DATA (1) 1859 #define UNDO_DATA_SINGLE (2) 1860 #define UNDO_ROTATE (3) 1861 1862 /* - Freestyle code - */ 1863 1864 static void PalTable__CalcTopBottom(PalTable *this) 1865 { 1866 if (this->curr[this->active] < this->bandwidth ) 1867 this->bottom = 0; 1868 else 1869 this->bottom = (this->curr[this->active]) - this->bandwidth; 1870 1871 if (this->curr[this->active] > (255-this->bandwidth) ) 1872 this->top = 255; 1873 else 1874 this->top = (this->curr[this->active]) + this->bandwidth; 1875 } 1876 1877 static void PalTable__PutBand(PalTable *this, PALENTRY *pal) 1878 { 1879 int r,b,a; 1880 1881 /* clip top and bottom values to stop them running off the end of the DAC */ 1882 1883 PalTable__CalcTopBottom(this); 1884 1885 /* put bands either side of current colour */ 1886 1887 a = this->curr[this->active]; 1888 b = this->bottom; 1889 r = this->top; 1890 1891 pal[a] = this->fs_color; 1892 1893 if (r != a && a != b) 1894 { 1895 mkpalrange(&pal[a], &pal[r], &pal[a], r-a, 1); 1896 mkpalrange(&pal[b], &pal[a], &pal[b], a-b, 1); 1897 } 1898 1899 } 1900 1901 1902 /* - Undo.Redo code - */ 1903 1904 1905 static void PalTable__SaveUndoData(PalTable *this, int first, int last) 1906 { 1907 int num; 1908 1909 if ( this->undo_file == NULL ) 1910 return ; 1911 1912 num = (last - first) + 1; 1913 1914 #ifdef DEBUG_UNDO
1915 mprintf("%6ld Writing Undo DATA from %d to %d (%d)", ftell(this->undo_file), first, last, num);
1916 #endif 1917 1918 fseek(this->undo_file, 0, SEEK_CUR); 1919 if ( num == 1 ) 1920 { 1921 putc(UNDO_DATA_SINGLE, this->undo_file); 1922 putc(first, this->undo_file); 1923 fwrite(this->pal+first, 3, 1, this->undo_file); 1924 putw( 1 + 1 + 3 + sizeof(int), this->undo_file); 1925 } 1926 else 1927 { 1928 putc(UNDO_DATA, this->undo_file); 1929 putc(first, this->undo_file); 1930 putc(last, this->undo_file); 1931 fwrite(this->pal+first, 3, num, this->undo_file); 1932 putw(1 + 2 + (num*3) + sizeof(int), this->undo_file); 1933 } 1934 1935 this->num_redo = 0; 1936 } 1937 1938 1939 static void PalTable__SaveUndoRotate(PalTable *this, int dir, int first, int last) 1940 { 1941 if ( this->undo_file == NULL ) 1942 return ; 1943 1944 #ifdef DEBUG_UNDO
1945 mprintf("%6ld Writing Undo ROTATE of %d from %d to %d", ftell(this->undo_file), dir, first, last);
1946 #endif 1947 1948 fseek(this->undo_file, 0, SEEK_CUR); 1949 putc(UNDO_ROTATE, this->undo_file); 1950 putc(first, this->undo_file); 1951 putc(last, this->undo_file); 1952 putw(dir, this->undo_file); 1953 putw(1 + 2 + sizeof(int), this->undo_file); 1954 1955 this->num_redo = 0; 1956 } 1957 1958 1959 static void PalTable__UndoProcess(PalTable *this, int delta) /* undo/redo common code */ 1960 { /* delta = -1 for undo, +1 for redo */ 1961 int cmd = getc(this->undo_file); 1962 1963 switch( cmd ) 1964 { 1965 case UNDO_DATA: 1966 case UNDO_DATA_SINGLE: 1967 { 1968 int first, last, num; 1969 PALENTRY temp[256]; 1970 1971 if ( cmd == UNDO_DATA ) 1972 { 1973 first = (unsigned char)getc(this->undo_file); 1974 last = (unsigned char)getc(this->undo_file); 1975 } 1976 else /* UNDO_DATA_SINGLE */ 1977 first = last = (unsigned char)getc(this->undo_file); 1978 1979 num = (last - first) + 1; 1980 1981 #ifdef DEBUG_UNDO
1982 mprintf(" Reading DATA from %d to %d", first, last);
1983 #endif 1984 1985 fread(temp, 3, num, this->undo_file); 1986 1987 fseek(this->undo_file, -(num*3), SEEK_CUR); /* go to start of undo/redo data */ 1988 fwrite(this->pal+first, 3, num, this->undo_file); /* write redo/undo data */ 1989 1990 memmove(this->pal+first, temp, num*3); 1991 1992 PalTable__UpdateDAC(this); 1993 1994 RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); 1995 RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); 1996 RGBEditor_Update(this->rgb[0]); 1997 RGBEditor_Update(this->rgb[1]); 1998 break; 1999 } 2000 2001 case UNDO_ROTATE: 2002 { 2003 int first = (unsigned char)getc(this->undo_file); 2004 int last = (unsigned char)getc(this->undo_file); 2005 int dir = getw(this->undo_file); 2006 2007 #ifdef DEBUG_UNDO
2008 mprintf(" Reading ROTATE of %d from %d to %d", dir, first, last);
2009 #endif 2010 PalTable__Rotate(this, delta*dir, first, last); 2011 break; 2012 } 2013 2014 default: 2015 #ifdef DEBUG_UNDO
2016 mprintf(" Unknown command: %d", cmd);
2017 #endif 2018 break; 2019 } 2020 2021 fseek(this->undo_file, 0, SEEK_CUR); /* to put us in read mode */ 2022 getw(this->undo_file); /* read size */ 2023 } 2024 2025 2026 static void PalTable__Undo(PalTable *this) 2027 { 2028 int size; 2029 long pos; 2030 2031 if ( ftell(this->undo_file) <= 0 ) /* at beginning of file? */ 2032 { /* nothing to undo -- exit */ 2033 return ; 2034 } 2035 2036 fseek(this->undo_file, -(int)sizeof(int), SEEK_CUR); /* go back to get size */ 2037 2038 size = getw(this->undo_file); 2039 fseek(this->undo_file, -size, SEEK_CUR); /* go to start of undo */ 2040 2041 #ifdef DEBUG_UNDO
2042 mprintf("%6ld Undo:", ftell(this->undo_file));
2043 #endif 2044 2045 pos = ftell(this->undo_file); 2046 2047 PalTable__UndoProcess(this, -1); 2048 2049 fseek(this->undo_file, pos, SEEK_SET); /* go to start of this block */ 2050 2051 ++this->num_redo; 2052 } 2053 2054 2055 static void PalTable__Redo(PalTable *this) 2056 { 2057 if ( this->num_redo <= 0 ) 2058 return ; 2059 2060 #ifdef DEBUG_UNDO
2061 mprintf("%6ld Redo:", ftell(this->undo_file));
2062 #endif 2063 2064 fseek(this->undo_file, 0, SEEK_CUR); /* to make sure we are in "read" mode */ 2065 PalTable__UndoProcess(this, 1); 2066 2067 --this->num_redo; 2068 } 2069 2070 2071 /* - everything else - */ 2072 2073 2074 #define STATUS_LEN (4) 2075 2076 static void PalTable__DrawStatus(PalTable *this, BOOLEAN stripe_mode) 2077 { 2078 int color, hunds, tens, ones; 2079 int width = 1+(this->csize*16)+1+1; 2080 2081 if ( !this->hidden && ( width - (RGBEditor_WIDTH*2+4) >= STATUS_LEN*8 ) ) 2082 { 2083 int x = this->x + 2 + RGBEditor_WIDTH, 2084 y = this->y + PalTable_PALY - 10; 2085 color = PalTable__GetCursorColor(this); 2086 if (color < 0 || color >= colors) /* hmm, the border returns -1 */ 2087 color = 0; 2088 Cursor_Hide(); 2089 2090 displayc(x+(0*8), y, fg_color, bg_color, (this->auto_select) ? 'A' : 254); 2091 displayc(x+(1*8), y, fg_color, bg_color, (this->exclude==1) ? 'X' : 2092 (this->exclude==2) ? 'Y' : 254); 2093 displayc(x+(2*8), y, fg_color, bg_color, (this->freestyle) ? 'F' : 254); 2094 displayc(x+(3*8), y, fg_color, bg_color, (stripe_mode) ? 'T' : 254); 2095 2096 y = y - 10; 2097 hunds = (int)(color/100); 2098 displayc(x+(0*8), y, fg_color, bg_color, (char)(hunds) + '0' ); 2099 tens = (int)((color - (hunds * 100)) / 10); 2100 displayc(x+(1*8), y, fg_color, bg_color, (char)(tens) + '0' ); 2101 ones = (int)(color - (hunds * 100) - (tens * 10)); 2102 displayc(x+(2*8), y, fg_color, bg_color, (char)(ones) + '0' ); 2103 2104 Cursor_Show(); 2105 } 2106 } 2107 2108 2109 static void PalTable__HlPal(PalTable *this, int pnum, int color) 2110 { 2111 int x = this->x + PalTable_PALX + (pnum%16)*this->csize, 2112 y = this->y + PalTable_PALY + (pnum/16)*this->csize, 2113 size = this->csize; 2114 2115 if (this->hidden) 2116 return ; 2117 2118 Cursor_Hide(); 2119 2120 if (color < 0) 2121 drect(x, y, size+1, size+1); 2122 else 2123 rect(x, y, size+1, size+1, color); 2124 2125 Cursor_Show(); 2126 } 2127 2128 2129 static void PalTable__Draw(PalTable *this) 2130 { 2131 int pal; 2132 int xoff, yoff; 2133 int width; 2134 2135 if (this->hidden) 2136 return ; 2137 2138 Cursor_Hide(); 2139 2140 width = 1+(this->csize*16)+1+1; 2141 2142 rect(this->x, this->y, width, 2+RGBEditor_DEPTH+2+(this->csize*16)+1+1, fg_color); 2143 2144 fillrect(this->x+1, this->y+1, width-2, 2+RGBEditor_DEPTH+2+(this->csize*16)+1+1-2, bg_color); 2145 2146 hline(this->x, this->y+PalTable_PALY-1, width, fg_color); 2147 2148 if ( width - (RGBEditor_WIDTH*2+4) >= TITLE_LEN*8 ) 2149 { 2150 int center = (width - TITLE_LEN*8) / 2; 2151 2152 displayf(this->x+center, this->y+RGBEditor_DEPTH/2-6, fg_color, bg_color, TITLE); 2153 } 2154 2155 RGBEditor_Draw(this->rgb[0]); 2156 RGBEditor_Draw(this->rgb[1]); 2157 2158 for (pal=0; pal<256; pal++) 2159 { 2160 xoff = PalTable_PALX + (pal%16) * this->csize; 2161 yoff = PalTable_PALY + (pal/16) * this->csize; 2162 2163 if ( pal >= colors ) 2164 { 2165 fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, bg_color); 2166 draw_diamond(this->x + xoff + this->csize/2 - 1, this->y + yoff + this->csize/2 - 1, fg_color); 2167 } 2168 2169 else if ( is_reserved(pal) ) 2170 { 2171 int x1 = this->x + xoff + 1, 2172 y1 = this->y + yoff + 1, 2173 x2 = x1 + this->csize - 2, 2174 y2 = y1 + this->csize - 2; 2175 fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, bg_color); 2176 draw_line(x1, y1, x2, y2, fg_color); 2177 draw_line(x1, y2, x2, y1, fg_color); 2178 } 2179 else 2180 fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, pal); 2181 2182 } 2183 2184 if (this->active == 0) 2185 { 2186 PalTable__HlPal(this, this->curr[1], -1); 2187 PalTable__HlPal(this, this->curr[0], fg_color); 2188 } 2189 else 2190 { 2191 PalTable__HlPal(this, this->curr[0], -1); 2192 PalTable__HlPal(this, this->curr[1], fg_color); 2193 } 2194 2195 PalTable__DrawStatus(this, FALSE); 2196 2197 Cursor_Show(); 2198 } 2199 2200 2201 2202 static BOOLEAN PalTable__SetCurr(PalTable *this, int which, int curr) 2203 { 2204 BOOLEAN redraw = (BOOLEAN)((which < 0) ? TRUE : FALSE); 2205 2206 if ( redraw ) 2207 { 2208 which = this->active; 2209 curr = this->curr[which]; 2210 } 2211 else 2212 if ( curr == this->curr[which] || curr < 0 ) 2213 return (FALSE); 2214 2215 Cursor_Hide(); 2216 2217 PalTable__HlPal(this, this->curr[0], bg_color); 2218 PalTable__HlPal(this, this->curr[1], bg_color); 2219 PalTable__HlPal(this, this->top, bg_color); 2220 PalTable__HlPal(this, this->bottom, bg_color); 2221 2222 if ( this->freestyle ) 2223 { 2224 this->curr[which] = curr; 2225 2226 PalTable__CalcTopBottom(this); 2227 2228 PalTable__HlPal(this, this->top, -1); 2229 PalTable__HlPal(this, this->bottom, -1); 2230 PalTable__HlPal(this, this->curr[this->active], fg_color); 2231 2232 RGBEditor_SetRGB(this->rgb[which], this->curr[which], &this->fs_color); 2233 RGBEditor_Update(this->rgb[which]); 2234 2235 PalTable__UpdateDAC(this); 2236 2237 Cursor_Show(); 2238 2239 return (TRUE); 2240 } 2241 2242 this->curr[which] = curr; 2243 2244 if (this->curr[0] != this->curr[1]) 2245 PalTable__HlPal(this, this->curr[this->active==0?1:0], -1); 2246 PalTable__HlPal(this, this->curr[this->active], fg_color); 2247 2248 RGBEditor_SetRGB(this->rgb[which], this->curr[which], &(this->pal[this->curr[which]])); 2249 2250 if (redraw) 2251 { 2252 int other = (which==0) ? 1 : 0; 2253 RGBEditor_SetRGB(this->rgb[other], this->curr[other], &(this->pal[this->curr[other]])); 2254 RGBEditor_Update(this->rgb[0]); 2255 RGBEditor_Update(this->rgb[1]); 2256 } 2257 else 2258 RGBEditor_Update(this->rgb[which]); 2259 2260 if (this->exclude) 2261 PalTable__UpdateDAC(this); 2262 2263 Cursor_Show(); 2264 2265 this->curr_changed = FALSE; 2266 2267 return(TRUE); 2268 } 2269 2270 2271 static BOOLEAN PalTable__MemoryAlloc(PalTable *this, long size) 2272 { 2273 char far *temp; 2274 2275 if (debugflag == 420) 2276 { 2277 this->stored_at = NOWHERE; 2278 return (FALSE); /* can't do it */ 2279 } 2280 temp = (char far *)farmemalloc(FAR_RESERVE); /* minimum free space */ 2281 2282 if (temp == NULL) 2283 { 2284 this->stored_at = NOWHERE; 2285 return (FALSE); /* can't do it */ 2286 } 2287 2288 this->memory = (char far *)farmemalloc( size ); 2289 2290 farmemfree(temp); 2291 2292 if ( this->memory == NULL ) 2293 { 2294 this->stored_at = NOWHERE; 2295 return (FALSE); 2296 } 2297 else 2298 { 2299 this->stored_at = FARMEM; 2300 return (TRUE); 2301 } 2302 } 2303 2304 2305 static void PalTable__SaveRect(PalTable *this) 2306 { 2307 char buff[MAX_WIDTH]; 2308 int width = PalTable_PALX + this->csize*16 + 1 + 1, 2309 depth = PalTable_PALY + this->csize*16 + 1 + 1; 2310 int yoff; 2311 2312 2313 /* first, do any de-allocationg */ 2314 2315 switch( this->stored_at ) 2316 { 2317 case NOWHERE: 2318 break; 2319 2320 case DISK: 2321 break; 2322 2323 case FARMEM: 2324 if (this->memory != NULL) 2325 farmemfree(this->memory); 2326 this->memory = NULL; 2327 break; 2328 } ; 2329 2330 /* allocate space and store the rect */ 2331 2332 if ( PalTable__MemoryAlloc(this, (long)width*depth) ) 2333 { 2334 char far *ptr = this->memory; 2335 char far *bufptr = buff; /* MSC needs this indirection to get it right */ 2336 2337 Cursor_Hide(); 2338 for (yoff=0; yoff<depth; yoff++) 2339 { 2340 getrow(this->x, this->y+yoff, width, buff); 2341 hline (this->x, this->y+yoff, width, bg_color); 2342 far_memcpy(ptr,bufptr, width); 2343 ptr = (char far *)normalize(ptr+width); 2344 } 2345 Cursor_Show(); 2346 } 2347 2348 else /* to disk */ 2349 { 2350 this->stored_at = DISK; 2351 2352 if ( this->file == NULL ) 2353 { 2354 this->file = dir_fopen(tempdir,scrnfile, "w+b"); 2355 if (this->file == NULL) 2356 { 2357 this->stored_at = NOWHERE; 2358 buzzer(3); 2359 return ; 2360 } 2361 } 2362 2363 rewind(this->file); 2364 Cursor_Hide(); 2365 for (yoff=0; yoff<depth; yoff++) 2366 { 2367 getrow(this->x, this->y+yoff, width, buff); 2368 hline (this->x, this->y+yoff, width, bg_color); 2369 if ( fwrite(buff, width, 1, this->file) != 1 ) 2370 { 2371 buzzer(3); 2372 break; 2373 } 2374 } 2375 Cursor_Show(); 2376 } 2377 2378 } 2379 2380 2381 static void PalTable__RestoreRect(PalTable *this) 2382 { 2383 char buff[MAX_WIDTH]; 2384 int width = PalTable_PALX + this->csize*16 + 1 + 1, 2385 depth = PalTable_PALY + this->csize*16 + 1 + 1; 2386 int yoff; 2387 2388 if (this->hidden) 2389 return; 2390 2391 switch ( this->stored_at ) 2392 { 2393 case DISK: 2394 rewind(this->file); 2395 Cursor_Hide(); 2396 for (yoff=0; yoff<depth; yoff++) 2397 { 2398 if ( fread(buff, width, 1, this->file) != 1 ) 2399 { 2400 buzzer(3); 2401 break; 2402 } 2403 putrow(this->x, this->y+yoff, width, buff); 2404 } 2405 Cursor_Show(); 2406 break; 2407 2408 case FARMEM: 2409 { 2410 char far *ptr = this->memory; 2411 char far *bufptr = buff; /* MSC needs this indirection to get it right */ 2412 2413 Cursor_Hide(); 2414 for (yoff=0; yoff<depth; yoff++) 2415 { 2416 far_memcpy(bufptr, ptr, width); 2417 putrow(this->x, this->y+yoff, width, buff); 2418 ptr = (char far *)normalize(ptr+width); 2419 } 2420 Cursor_Show(); 2421 break; 2422 } 2423 2424 case NOWHERE: 2425 break; 2426 } /* switch */ 2427 } 2428 2429 2430 static void PalTable__SetPos(PalTable *this, int x, int y) 2431 { 2432 int width = PalTable_PALX + this->csize*16 + 1 + 1; 2433 2434 this->x = x; 2435 this->y = y; 2436 2437 RGBEditor_SetPos(this->rgb[0], x+2, y+2); 2438 RGBEditor_SetPos(this->rgb[1], x+width-2-RGBEditor_WIDTH, y+2); 2439 } 2440 2441 2442 static void PalTable__SetCSize(PalTable *this, int csize) 2443 { 2444 this->csize = csize; 2445 PalTable__SetPos(this, this->x, this->y); 2446 } 2447 2448 2449 static int PalTable__GetCursorColor(PalTable *this) 2450 { 2451 int x = Cursor_GetX(), 2452 y = Cursor_GetY(), 2453 size; 2454 int color = getcolor(x, y); 2455 2456 if ( is_reserved(color) ) 2457 { 2458 if ( is_in_box(x, y, this->x, this->y, 1+(this->csize*16)+1+1, 2+RGBEditor_DEPTH+2+(this->csize*16)+1+1) ) 2459 { /* is the cursor over the editor? */ 2460 x -= this->x + PalTable_PALX; 2461 y -= this->y + PalTable_PALY; 2462 size = this->csize; 2463 2464 if (x < 0 || y < 0 || x > size*16 || y > size*16) 2465 return (-1); 2466 2467 if ( x == size*16 ) 2468 --x; 2469 if ( y == size*16 ) 2470 --y; 2471 2472 return ( (y/size)*16 + x/size ); 2473 } 2474 else 2475 return (color); 2476 } 2477 2478 return (color); 2479 } 2480 2481 2482 2483 #define CURS_INC 1 2484 2485 static void PalTable__DoCurs(PalTable *this, int key) 2486 { 2487 BOOLEAN done = FALSE; 2488 BOOLEAN first = TRUE; 2489 int xoff = 0, 2490 yoff = 0; 2491 2492 while ( !done ) 2493 { 2494 switch(key) 2495 { 2496 case RIGHT_ARROW_2: xoff += CURS_INC*4; break; 2497 case RIGHT_ARROW: xoff += CURS_INC; break; 2498 case LEFT_ARROW_2: xoff -= CURS_INC*4; break; 2499 case LEFT_ARROW: xoff -= CURS_INC; break; 2500 case DOWN_ARROW_2: yoff += CURS_INC*4; break; 2501 case DOWN_ARROW: yoff += CURS_INC; break; 2502 case UP_ARROW_2: yoff -= CURS_INC*4; break; 2503 case UP_ARROW: yoff -= CURS_INC; break; 2504 2505 default: 2506 done = TRUE; 2507 } 2508 2509 if (!done) 2510 { 2511 if (!first) 2512 getakey(); /* delete key from buffer */ 2513 else 2514 first = FALSE; 2515 key = keypressed(); /* peek at the next one... */ 2516 } 2517 } 2518 2519 Cursor_Move(xoff, yoff); 2520 2521 if (this->auto_select) 2522 PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); 2523 } 2524 2525 2526 #ifdef __TURBOC__
2527 # pragma argsused
2528 #endif 2529 #ifdef __CLINT__
2530 # pragma argsused
2531 #endif 2532 2533 static void PalTable__change(RGBEditor *rgb, VOIDPTR info) 2534 { 2535 PalTable *this = (PalTable *)info; 2536 int pnum = this->curr[this->active]; 2537 2538 if ( this->freestyle ) 2539 { 2540 this->fs_color = RGBEditor_GetRGB(rgb); 2541 PalTable__UpdateDAC(this); 2542 return ; 2543 } 2544 2545 if ( !this->curr_changed ) 2546 { 2547 PalTable__SaveUndoData(this, pnum, pnum); 2548 this->curr_changed = TRUE; 2549 } 2550 2551 this->pal[pnum] = RGBEditor_GetRGB(rgb); 2552 2553 if (this->curr[0] == this->curr[1]) 2554 { 2555 int other = this->active==0 ? 1 : 0; 2556 PALENTRY color; 2557 2558 color = RGBEditor_GetRGB(this->rgb[this->active]); 2559 RGBEditor_SetRGB(this->rgb[other], this->curr[other], &color); 2560 2561 Cursor_Hide(); 2562 RGBEditor_Update(this->rgb[other]); 2563 Cursor_Show(); 2564 } 2565 2566 } 2567 2568 2569 static void PalTable__UpdateDAC(PalTable *this) 2570 { 2571 if ( this->exclude ) 2572 { 2573 memset(dacbox, 0, 256*3); 2574 if (this->exclude == 1) 2575 { 2576 int a = this->curr[this->active]; 2577 memmove(dacbox[a], &this->pal[a], 3); 2578 } 2579 else 2580 { 2581 int a = this->curr[0], 2582 b = this->curr[1]; 2583 2584 if (a>b) 2585 { 2586 int t=a; 2587 a=b; 2588 b=t; 2589 } 2590 2591 memmove(dacbox[a], &this->pal[a], 3*(1+(b-a))); 2592 } 2593 } 2594 else 2595 { 2596 memmove(dacbox[0], this->pal, 3*colors); 2597 2598 if ( this->freestyle ) 2599 PalTable__PutBand(this, (PALENTRY *)dacbox); /* apply band to dacbox */ 2600 } 2601 2602 if ( !this->hidden ) 2603 { 2604 if (inverse) 2605 { 2606 memset(dacbox[fg_color], 0, 3); /* dacbox[fg] = (0,0,0) */ 2607 memset(dacbox[bg_color], 48, 3); /* dacbox[bg] = (48,48,48) */ 2608 } 2609 else 2610 { 2611 memset(dacbox[bg_color], 0, 3); /* dacbox[bg] = (0,0,0) */ 2612 memset(dacbox[fg_color], 48, 3); /* dacbox[fg] = (48,48,48) */ 2613 } 2614 } 2615 2616 spindac(0,1); 2617 } 2618 2619 2620 static void PalTable__Rotate(PalTable *this, int dir, int lo, int hi) 2621 { 2622 2623 rotatepal(this->pal, dir, lo, hi); 2624 2625 Cursor_Hide(); 2626 2627 /* update the DAC. */ 2628 2629 PalTable__UpdateDAC(this); 2630 2631 /* update the editors. */ 2632 2633 RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); 2634 RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); 2635 RGBEditor_Update(this->rgb[0]); 2636 RGBEditor_Update(this->rgb[1]); 2637 2638 Cursor_Show(); 2639 } 2640 2641 2642 static void PalTable__other_key(int key, RGBEditor *rgb, VOIDPTR info) 2643 { 2644 PalTable *this = (PalTable *)info; 2645 2646 switch(key) 2647 { 2648 case '\\': /* move/resize */ 2649 { 2650 if (this->hidden) 2651 break; /* cannot move a hidden pal */ 2652 Cursor_Hide(); 2653 PalTable__RestoreRect(this); 2654 MoveBox_SetPos(this->movebox, this->x, this->y); 2655 MoveBox_SetCSize(this->movebox, this->csize); 2656 if ( MoveBox_Process(this->movebox) ) 2657 { 2658 if ( MoveBox_ShouldHide(this->movebox) ) 2659 PalTable_SetHidden(this, TRUE); 2660 else if ( MoveBox_Moved(this->movebox) ) 2661 { 2662 PalTable__SetPos(this, MoveBox_X(this->movebox), MoveBox_Y(this->movebox)); 2663 PalTable__SetCSize(this, MoveBox_CSize(this->movebox)); 2664 PalTable__SaveRect(this); 2665 } 2666 } 2667 PalTable__Draw(this); 2668 Cursor_Show(); 2669 2670 RGBEditor_SetDone(this->rgb[this->active], TRUE); 2671 2672 if (this->auto_select) 2673 PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); 2674 break; 2675 } 2676 2677 case 'Y': /* exclude range */ 2678 case 'y': 2679 if ( this->exclude==2 ) 2680 this->exclude = 0; 2681 else 2682 this->exclude = 2; 2683 PalTable__UpdateDAC(this); 2684 break; 2685 2686 case 'X': 2687 case 'x': /* exclude current entry */ 2688 if ( this->exclude==1 ) 2689 this->exclude = 0; 2690 else 2691 this->exclude = 1; 2692 PalTable__UpdateDAC(this); 2693 break; 2694 2695 case RIGHT_ARROW: 2696 case LEFT_ARROW: 2697 case UP_ARROW: 2698 case DOWN_ARROW: 2699 case RIGHT_ARROW_2: 2700 case LEFT_ARROW_2: 2701 case UP_ARROW_2: 2702 case DOWN_ARROW_2: 2703 PalTable__DoCurs(this, key); 2704 break; 2705 2706 case ESC: 2707 this->done = TRUE; 2708 RGBEditor_SetDone(rgb, TRUE); 2709 break; 2710 2711 case ' ': /* select the other palette register */ 2712 this->active = (this->active==0) ? 1 : 0; 2713 if (this->auto_select) 2714 PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); 2715 else 2716 PalTable__SetCurr(this, -1, 0); 2717 2718 if (this->exclude || this->freestyle) 2719 PalTable__UpdateDAC(this); 2720 2721 RGBEditor_SetDone(rgb, TRUE); 2722 break; 2723 2724 case ENTER: /* set register to color under cursor. useful when not */ 2725 case ENTER_2: /* in auto_select mode */ 2726 2727 if ( this->freestyle ) 2728 { 2729 PalTable__SaveUndoData(this, this->bottom, this->top); 2730 PalTable__PutBand(this, this->pal); 2731 } 2732 2733 PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); 2734 2735 if (this->exclude || this->freestyle ) 2736 PalTable__UpdateDAC(this); 2737 2738 RGBEditor_SetDone(rgb, TRUE); 2739 break; 2740 2741 case 'D': /* copy (Duplicate?) color in inactive to color in active */ 2742 case 'd': 2743 { 2744 int a = this->active, 2745 b = (a==0) ? 1 : 0; 2746 PALENTRY t; 2747 2748 t = RGBEditor_GetRGB(this->rgb[b]); 2749 Cursor_Hide(); 2750 2751 RGBEditor_SetRGB(this->rgb[a], this->curr[a], &t); 2752 RGBEditor_Update(this->rgb[a]); 2753 PalTable__change(this->rgb[a], this); 2754 PalTable__UpdateDAC(this); 2755 2756 Cursor_Show(); 2757 break; 2758 } 2759 2760 case '=': /* create a shade range between the two entries */ 2761 { 2762 int a = this->curr[0], 2763 b = this->curr[1]; 2764 2765 if (a > b) 2766 { 2767 int t = a; 2768 a = b; 2769 b = t; 2770 } 2771 2772 PalTable__SaveUndoData(this, a, b); 2773 2774 if (a != b) 2775 { 2776 mkpalrange(&this->pal[a], &this->pal[b], &this->pal[a], b-a, 1); 2777 PalTable__UpdateDAC(this); 2778 } 2779 2780 break; 2781 } 2782 2783 case '!': /* swap r<->g */ 2784 { 2785 int a = this->curr[0], 2786 b = this->curr[1]; 2787 2788 if (a > b) 2789 { 2790 int t = a; 2791 a = b; 2792 b = t; 2793 } 2794 2795 PalTable__SaveUndoData(this, a, b); 2796 2797 if (a != b) 2798 { 2799 rotcolrg(&this->pal[a], b-a); 2800 PalTable__UpdateDAC(this); 2801 } 2802 2803 2804 break; 2805 } 2806 2807 case '@': /* swap g<->b */ 2808 case '"': /* UK keyboards */ 2809 case 151: /* French keyboards */ 2810 { 2811 int a = this->curr[0], 2812 b = this->curr[1]; 2813 2814 if (a > b) 2815 { 2816 int t = a; 2817 a = b; 2818 b = t; 2819 } 2820 2821 PalTable__SaveUndoData(this, a, b); 2822 2823 if (a != b) 2824 { 2825 rotcolgb(&this->pal[a], b-a); 2826 PalTable__UpdateDAC(this); 2827 } 2828 2829 break; 2830 } 2831 2832 case '#': /* swap r<->b */ 2833 case 156: /* UK keyboards (pound sign) */ 2834 case '$': /* For French keyboards */ 2835 { 2836 int a = this->curr[0], 2837 b = this->curr[1]; 2838 2839 if (a > b) 2840 { 2841 int t = a; 2842 a = b; 2843 b = t; 2844 } 2845 2846 PalTable__SaveUndoData(this, a, b); 2847 2848 if (a != b) 2849 { 2850 rotcolbr(&this->pal[a], b-a); 2851 PalTable__UpdateDAC(this); 2852 } 2853 2854 break; 2855 } 2856 2857 2858 case 'T': 2859 case 't': /* s(T)ripe mode */ 2860 { 2861 int key; 2862 2863 Cursor_Hide(); 2864 PalTable__DrawStatus(this, TRUE); 2865 key = getakeynohelp(); 2866 Cursor_Show(); 2867 2868 if (key >= '1' && key <= '9') 2869 { 2870 int a = this->curr[0], 2871 b = this->curr[1]; 2872 2873 if (a > b) 2874 { 2875 int t = a; 2876 a = b; 2877 b = t; 2878 } 2879 2880 PalTable__SaveUndoData(this, a, b); 2881 2882 if (a != b) 2883 { 2884 mkpalrange(&this->pal[a], &this->pal[b], &this->pal[a], b-a, key-'0'); 2885 PalTable__UpdateDAC(this); 2886 } 2887 } 2888 2889 break; 2890 } 2891 2892 case 'M': /* set gamma */ 2893 case 'm': 2894 { 2895 static FCODE o_msg[] = {"Enter gamma value"}; 2896 char msg[sizeof(o_msg)]; 2897 int i; 2898 char buf[20]; 2899 far_strcpy(msg,o_msg); 2900 sprintf(buf,"%.3f",1./gamma_val); 2901 stackscreen(); 2902 i = field_prompt(0,msg,NULL,buf,20,NULL); 2903 unstackscreen(); 2904 if (i != -1) { 2905 sscanf(buf,"%f",&gamma_val); 2906 if (gamma_val==0) { 2907 gamma_val = (float)0.0000000001; 2908 } 2909 gamma_val = (float)(1./gamma_val); 2910 } 2911 } 2912 break; 2913 case 'A': /* toggle auto-select mode */ 2914 case 'a': 2915 this->auto_select = (BOOLEAN)((this->auto_select) ? FALSE : TRUE); 2916 if (this->auto_select) 2917 { 2918 PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); 2919 if (this->exclude) 2920 PalTable__UpdateDAC(this); 2921 } 2922 break; 2923 2924 case 'H': 2925 case 'h': /* toggle hide/display of palette editor */ 2926 Cursor_Hide(); 2927 PalTable_Hide(this, rgb, (BOOLEAN)((this->hidden) ? FALSE : TRUE)); 2928 Cursor_Show(); 2929 break; 2930 2931 case '.': /* rotate once */ 2932 case ',': 2933 { 2934 int dir = (key=='.') ? 1 : -1; 2935 2936 PalTable__SaveUndoRotate(this, dir, rotate_lo, rotate_hi); 2937 PalTable__Rotate(this, dir, rotate_lo, rotate_hi); 2938 break; 2939 } 2940 2941 case '>': /* continuous rotation (until a key is pressed) */ 2942 case '<': 2943 { 2944 int dir; 2945 long tick; 2946 int diff = 0; 2947 2948 Cursor_Hide(); 2949 2950 if ( !this->hidden ) 2951 { 2952 RGBEditor_BlankSampleBox(this->rgb[0]); 2953 RGBEditor_BlankSampleBox(this->rgb[1]); 2954 RGBEditor_SetHidden(this->rgb[0], TRUE); 2955 RGBEditor_SetHidden(this->rgb[1], TRUE); 2956 } 2957 2958 do 2959 { 2960 dir = (key=='>') ? 1 : -1; 2961 2962 while ( !keypressed() ) 2963 { 2964 tick = readticker(); 2965 PalTable__Rotate(this, dir, rotate_lo, rotate_hi); 2966 diff += dir; 2967 while (readticker() == tick) ; /* wait until a tick passes */ 2968 } 2969 2970 key = getakey(); 2971 } 2972 while (key=='<' || key=='>'); 2973 2974 if ( !this->hidden ) 2975 { 2976 RGBEditor_SetHidden(this->rgb[0], FALSE); 2977 RGBEditor_SetHidden(this->rgb[1], FALSE); 2978 RGBEditor_Update(this->rgb[0]); 2979 RGBEditor_Update(this->rgb[1]); 2980 } 2981 2982 if ( diff != 0 ) 2983 PalTable__SaveUndoRotate(this, diff, rotate_lo, rotate_hi); 2984 2985 Cursor_Show(); 2986 break; 2987 } 2988 2989 case 'I': /* invert the fg & bg colors */ 2990 case 'i': 2991 inverse = (BOOLEAN)!inverse; 2992 PalTable__UpdateDAC(this); 2993 break; 2994 2995 case 'V': 2996 case 'v': /* set the reserved colors to the editor colors */ 2997 if ( this->curr[0] >= colors || this->curr[1] >= colors || 2998 this->curr[0] == this->curr[1] ) 2999 { 3000 buzzer(2); 3001 break; 3002 } 3003 3004 fg_color = (BYTE)this->curr[0]; 3005 bg_color = (BYTE)this->curr[1]; 3006 3007 if ( !this->hidden ) 3008 { 3009 Cursor_Hide(); 3010 PalTable__UpdateDAC(this); 3011 PalTable__Draw(this); 3012 Cursor_Show(); 3013 } 3014 3015 RGBEditor_SetDone(this->rgb[this->active], TRUE); 3016 break; 3017 3018 case 'O': /* set rotate_lo and rotate_hi to editors */ 3019 case 'o': 3020 if (this->curr[0] > this->curr[1]) 3021 { 3022 rotate_lo = this->curr[1]; 3023 rotate_hi = this->curr[0]; 3024 } 3025 else 3026 { 3027 rotate_lo = this->curr[0]; 3028 rotate_hi = this->curr[1]; 3029 } 3030 break; 3031 3032 case F2: /* restore a palette */ 3033 case F3: 3034 case F4: 3035 case F5: 3036 case F6: 3037 case F7: 3038 case F8: 3039 case F9: 3040 { 3041 int which = key - F2; 3042 3043 if ( this->save_pal[which] != NULL ) 3044 { 3045 Cursor_Hide(); 3046 3047 PalTable__SaveUndoData(this, 0, 255); 3048 far_memcpy(this->pal,this->save_pal[which],256*3); 3049 PalTable__UpdateDAC(this); 3050 3051 PalTable__SetCurr(this, -1, 0); 3052 Cursor_Show(); 3053 RGBEditor_SetDone(this->rgb[this->active], TRUE); 3054 } 3055 else 3056 buzzer(3); /* error buzz */ 3057 break; 3058 } 3059 3060 case SF2: /* save a palette */ 3061 case SF3: 3062 case SF4: 3063 case SF5: 3064 case SF6: 3065 case SF7: 3066 case SF8: 3067 case SF9: 3068 { 3069 int which = key - SF2; 3070 3071 if ( this->save_pal[which] != NULL ) 3072 { 3073 far_memcpy(this->save_pal[which],this->pal,256*3); 3074 } 3075 else 3076 buzzer(3); /* oops! short on memory! */ 3077 break; 3078 } 3079 3080 case 'L': /* load a .map palette */ 3081 case 'l': 3082 { 3083 PalTable__SaveUndoData(this, 0, 255); 3084 3085 load_palette(); 3086 #ifndef XFRACT 3087 getpalrange(0, colors, this->pal);
3088 #else 3089 getpalrange(0, 256, this->pal);
3090 #endif 3091 PalTable__UpdateDAC(this); 3092 RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); 3093 RGBEditor_Update(this->rgb[0]); 3094 RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); 3095 RGBEditor_Update(this->rgb[1]); 3096 break; 3097 } 3098 3099 case 'S': /* save a .map palette */ 3100 case 's': 3101 { 3102 #ifndef XFRACT 3103 setpalrange(0, colors, this->pal);
3104 #else 3105 setpalrange(0, 256, this->pal);
3106 #endif 3107 save_palette(); 3108 PalTable__UpdateDAC(this); 3109 break; 3110 } 3111 3112 case 'C': /* color cycling sub-mode */ 3113 case 'c': 3114 { 3115 BOOLEAN oldhidden = (BOOLEAN)this->hidden; 3116 3117 PalTable__SaveUndoData(this, 0, 255); 3118 3119 Cursor_Hide(); 3120 if ( !oldhidden ) 3121 PalTable_Hide(this, rgb, TRUE); 3122 setpalrange(0, colors, this->pal); 3123 rotate(0); 3124 getpalrange(0, colors, this->pal); 3125 PalTable__UpdateDAC(this); 3126 if ( !oldhidden ) 3127 { 3128 RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); 3129 RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); 3130 PalTable_Hide(this, rgb, FALSE); 3131 } 3132 Cursor_Show(); 3133 break; 3134 } 3135 3136 case 'F': 3137 case 'f': /* toggle freestyle palette edit mode */ 3138 this->freestyle= (BOOLEAN)((this->freestyle) ? FALSE :TRUE); 3139 3140 PalTable__SetCurr(this, -1, 0); 3141 3142 if ( !this->freestyle ) /* if turning off... */ 3143 PalTable__UpdateDAC(this); 3144 3145 break; 3146 3147 case CTL_DEL: /* rt plus down */ 3148 if (this->bandwidth >0 ) 3149 this->bandwidth --; 3150 else 3151 this->bandwidth=0; 3152 PalTable__SetCurr(this, -1, 0); 3153 break; 3154 3155 case CTL_INSERT: /* rt plus up */ 3156 if (this->bandwidth <255 ) 3157 this->bandwidth ++; 3158 else 3159 this->bandwidth = 255; 3160 PalTable__SetCurr(this, -1, 0); 3161 break; 3162 3163 case 'W': /* convert to greyscale */ 3164 case 'w': 3165 { 3166 switch ( this->exclude ) 3167 { 3168 case 0: /* normal mode. convert all colors to grey scale */ 3169 PalTable__SaveUndoData(this, 0, 255); 3170 palrangetogrey(this->pal, 0, 256); 3171 break; 3172 3173 case 1: /* 'x' mode. convert current color to grey scale. */ 3174 PalTable__SaveUndoData(this, this->curr[this->active], this->curr[this->active]); 3175 palrangetogrey(this->pal, this->curr[this->active], 1); 3176 break; 3177 3178 case 2: /* 'y' mode. convert range between editors to grey. */ 3179 { 3180 int a = this->curr[0], 3181 b = this->curr[1]; 3182 3183 if (a > b) 3184 { 3185 int t = a; 3186 a = b; 3187 b = t; 3188 } 3189 3190 PalTable__SaveUndoData(this, a, b); 3191 palrangetogrey(this->pal, a, 1+(b-a)); 3192 break; 3193 } 3194 } 3195 3196 PalTable__UpdateDAC(this); 3197 RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); 3198 RGBEditor_Update(this->rgb[0]); 3199 RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); 3200 RGBEditor_Update(this->rgb[1]); 3201 break; 3202 } 3203 3204 case 'N': /* convert to negative color */ 3205 case 'n': 3206 { 3207 switch ( this->exclude ) 3208 { 3209 case 0: /* normal mode. convert all colors to grey scale */ 3210 PalTable__SaveUndoData(this, 0, 255); 3211 palrangetonegative(this->pal, 0, 256); 3212 break; 3213 3214 case 1: /* 'x' mode. convert current color to grey scale. */ 3215 PalTable__SaveUndoData(this, this->curr[this->active], this->curr[this->active]); 3216 palrangetonegative(this->pal, this->curr[this->active], 1); 3217 break; 3218 3219 case 2: /* 'y' mode. convert range between editors to grey. */ 3220 { 3221 int a = this->curr[0], 3222 b = this->curr[1]; 3223 3224 if (a > b) 3225 { 3226 int t = a; 3227 a = b; 3228 b = t; 3229 } 3230 3231 PalTable__SaveUndoData(this, a, b); 3232 palrangetonegative(this->pal, a, 1+(b-a)); 3233 break; 3234 } 3235 } 3236 3237 PalTable__UpdateDAC(this); 3238 RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]])); 3239 RGBEditor_Update(this->rgb[0]); 3240 RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]])); 3241 RGBEditor_Update(this->rgb[1]); 3242 break; 3243 } 3244 3245 case 'U': /* Undo */ 3246 case 'u': 3247 PalTable__Undo(this); 3248 break; 3249 3250 case 'e': /* Redo */ 3251 case 'E': 3252 PalTable__Redo(this); 3253 break; 3254 3255 } /* switch */ 3256 PalTable__DrawStatus(this, FALSE); 3257 } 3258 3259 static void PalTable__MkDefaultPalettes(PalTable *this) /* creates default Fkey palettes */ 3260 { 3261 int i; 3262 for(i=0; i<8; i++) /* copy original palette to save areas */ 3263 { 3264 if (this->save_pal[i] != NULL) 3265 { 3266 far_memcpy(this->save_pal[i], this->pal, 256*3); 3267 } 3268 } 3269 } 3270 3271 3272 3273 static PalTable *PalTable_Construct(void) 3274 { 3275 PalTable *this = new(PalTable); 3276 int csize; 3277 int ctr; 3278 PALENTRY far *mem_block; 3279 void far *temp; 3280 3281 temp = (void far *)farmemalloc(FAR_RESERVE); 3282 3283 if ( temp != NULL ) 3284 { 3285 mem_block = (PALENTRY far *)farmemalloc(256L*3 * 8); 3286 3287 if ( mem_block == NULL ) 3288 { 3289 for (ctr=0; ctr<8; ctr++) 3290 this->save_pal[ctr] = NULL; 3291 } 3292 else 3293 { 3294 for (ctr=0; ctr<8; ctr++) 3295 this->save_pal[ctr] = mem_block + (256*ctr); 3296 } 3297 farmemfree(temp); 3298 } 3299 3300 this->rgb[0] = RGBEditor_Construct(0, 0, PalTable__other_key, 3301 PalTable__change, this); 3302 this->rgb[1] = RGBEditor_Construct(0, 0, PalTable__other_key, 3303 PalTable__change, this); 3304 3305 this->movebox = MoveBox_Construct(0,0,0, PalTable_PALX+1, PalTable_PALY+1); 3306 3307 this->active = 0; 3308 this->curr[0] = 1; 3309 this->curr[1] = 1; 3310 this->auto_select = TRUE; 3311 this->exclude = FALSE; 3312 this->hidden = FALSE; 3313 this->stored_at = NOWHERE; 3314 this->file = NULL; 3315 this->memory = NULL; 3316 3317 this->fs_color.red = 42; 3318 this->fs_color.green = 42; 3319 this->fs_color.blue = 42; 3320 this->freestyle = FALSE; 3321 this->bandwidth = 15; 3322 this->top = 255; 3323 this->bottom = 0 ; 3324 3325 this->undo_file = dir_fopen(tempdir,undofile, "w+b"); 3326 this->curr_changed = FALSE; 3327 this->num_redo = 0; 3328 3329 RGBEditor_SetRGB(this->rgb[0], this->curr[0], &this->pal[this->curr[0]]); 3330 RGBEditor_SetRGB(this->rgb[1], this->curr[1], &this->pal[this->curr[0]]); 3331 3332 if (video_scroll) { 3333 PalTable__SetPos(this, video_startx, video_starty); 3334 csize = ( (vesa_yres-(PalTable_PALY+1+1)) / 2 ) / 16; 3335 } else { 3336 PalTable__SetPos(this, 0, 0); 3337 csize = ( (sydots-(PalTable_PALY+1+1)) / 2 ) / 16; 3338 } 3339 3340 if (csize<CSIZE_MIN) 3341 csize = CSIZE_MIN; 3342 PalTable__SetCSize(this, csize); 3343 3344 return(this); 3345 } 3346 3347 3348 static void PalTable_SetHidden(PalTable *this, BOOLEAN hidden) 3349 { 3350 this->hidden = hidden; 3351 RGBEditor_SetHidden(this->rgb[0], hidden); 3352 RGBEditor_SetHidden(this->rgb[1], hidden); 3353 PalTable__UpdateDAC(this); 3354 } 3355 3356 3357 3358 static void PalTable_Hide(PalTable *this, RGBEditor *rgb, BOOLEAN hidden) 3359 { 3360 if (hidden) 3361 { 3362 PalTable__RestoreRect(this); 3363 PalTable_SetHidden(this, TRUE); 3364 reserve_colors = FALSE; 3365 if (this->auto_select) 3366 PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); 3367 } 3368 else 3369 { 3370 PalTable_SetHidden(this, FALSE); 3371 reserve_colors = TRUE; 3372 if (this->stored_at == NOWHERE) /* do we need to save screen? */ 3373 PalTable__SaveRect(this); 3374 PalTable__Draw(this); 3375 if (this->auto_select) 3376 PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); 3377 RGBEditor_SetDone(rgb, TRUE); 3378 } 3379 } 3380 3381 3382 static void PalTable_Destroy(PalTable *this) 3383 { 3384 3385 if (this->file != NULL) 3386 { 3387 fclose(this->file); 3388 dir_remove(tempdir,scrnfile); 3389 } 3390 3391 if (this->undo_file != NULL) 3392 { 3393 fclose(this->undo_file); 3394 dir_remove(tempdir,undofile); 3395 } 3396 3397 if (this->memory != NULL) 3398 farmemfree(this->memory); 3399 3400 if (this->save_pal[0] != NULL) 3401 farmemfree((BYTE far *)this->save_pal[0]); 3402 3403 RGBEditor_Destroy(this->rgb[0]); 3404 RGBEditor_Destroy(this->rgb[1]); 3405 MoveBox_Destroy(this->movebox); 3406 delete(this); 3407 } 3408 3409 3410 static void PalTable_Process(PalTable *this) 3411 { 3412 int ctr; 3413 3414 getpalrange(0, colors, this->pal); 3415 3416 /* Make sure all palette entries are 0-63 */ 3417 3418 for(ctr=0; ctr<768; ctr++) 3419 ((char *)this->pal)[ctr] &= 63; 3420 3421 PalTable__UpdateDAC(this); 3422 3423 RGBEditor_SetRGB(this->rgb[0], this->curr[0], &this->pal[this->curr[0]]); 3424 RGBEditor_SetRGB(this->rgb[1], this->curr[1], &this->pal[this->curr[0]]); 3425 3426 if (!this->hidden) 3427 { 3428 MoveBox_SetPos(this->movebox, this->x, this->y); 3429 MoveBox_SetCSize(this->movebox, this->csize); 3430 if ( !MoveBox_Process(this->movebox) ) 3431 { 3432 setpalrange(0, colors, this->pal); 3433 return ; 3434 } 3435 3436 PalTable__SetPos(this, MoveBox_X(this->movebox), MoveBox_Y(this->movebox)); 3437 PalTable__SetCSize(this, MoveBox_CSize(this->movebox)); 3438 3439 if ( MoveBox_ShouldHide(this->movebox) ) 3440 { 3441 PalTable_SetHidden(this, TRUE); 3442 reserve_colors = FALSE; /* <EAN> */ 3443 } 3444 else 3445 { 3446 reserve_colors = TRUE; /* <EAN> */ 3447 PalTable__SaveRect(this); 3448 PalTable__Draw(this); 3449 } 3450 } 3451 3452 PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this)); 3453 PalTable__SetCurr(this, (this->active==1)?0:1, PalTable__GetCursorColor(this)); 3454 Cursor_Show(); 3455 PalTable__MkDefaultPalettes(this); 3456 this->done = FALSE; 3457 3458 while ( !this->done ) 3459 RGBEditor_Edit(this->rgb[this->active]); 3460 3461 Cursor_Hide(); 3462 PalTable__RestoreRect(this); 3463 setpalrange(0, colors, this->pal); 3464 } 3465 3466 3467 /* 3468 * interface to FRACTINT 3469 */ 3470 3471 3472 3473 void EditPalette(void) /* called by fractint */ 3474 { 3475 int oldlookatmouse = lookatmouse; 3476 int oldsxoffs = sxoffs; 3477 int oldsyoffs = syoffs; 3478 PalTable *pt; 3479 3480 mem_init(strlocn, 10*1024); 3481 3482 if ( (font8x8 = findfont(0)) == NULL ) 3483 return ; 3484 3485 if (sxdots < 133 || sydots < 174) 3486 return; /* prevents crash when physical screen is too small */ 3487 3488 plot = putcolor; 3489 3490 line_buff = newx(max(sxdots,sydots)); 3491 3492 lookatmouse = 3; 3493 sxoffs = syoffs = 0; 3494 3495 reserve_colors = TRUE; 3496 inverse = FALSE; 3497 fg_color = (BYTE)(255%colors); 3498 bg_color = (BYTE)(fg_color-1); 3499 3500 Cursor_Construct(); 3501 pt = PalTable_Construct(); 3502 PalTable_Process(pt); 3503 PalTable_Destroy(pt); 3504 Cursor_Destroy(); 3505 3506 lookatmouse = oldlookatmouse; 3507 sxoffs = oldsxoffs; 3508 syoffs = oldsyoffs; 3509 delete(line_buff); 3510 } 3511