home *** CD-ROM | disk | FTP | other *** search
- /*
- * editpal.c
- *
- * Edits VGA 256-color palettes.
- *
- * Key to initials:
- *
- * EAN - Ethan Nagel [70022,2552]
- *
- * JJB - Juan J. Buhler [jbuhler@gidef.edu.ar]
- *
- * TIW - Tim Wegner
- *
- * Revision History:
- *
- * 10-22-90 EAN Initial release.
- *
- * 10-23-90 EAN "Discovered" get_line/put_line functions, integrated
- * them in (instead of only getcolor/putcolor). Much
- * faster!
- * Redesigned color editors (now at top of palette) and
- * re-assigned some keys.
- * Added (A)uto option.
- * Fixed memory allocation problem. Now uses shared
- * FRACTINT data area (strlocn). Uses 6 bytes DS.
- *
- * 10-27-90 EAN Added save to memory option - will save screen image to
- * memory, if enough mem avail. (disk otherwise).
- * Added s(T)ripe mode - works like (S)hade except only
- * changes every n'th entry.
- * Added temporary palette save/restore. (Can work like
- * an undo feature.) Thanks to Pieter Branderhorst for
- * idea.
- *
- * 10-28-90 EAN The (H)ide function now makes the palette invisible,
- * while allowing any other operations (except '\\' -
- * move/resize) to continue.
- *
- * 10-29-90 PB (in EAN's absence, <grin>)
- * Change 'c' to 'd' and 's' to '=' for below.
- * Add 'l' to load palette from .map, 's' to store .map.
- * Add 'c' to invoke color cycling.
- * Change cursor to use whatever colors it can from
- * the palette (not fixed 0 and 255).
- * Restore colors 0 and 255 to real values whenever
- * palette is not on display.
- * Rotate 255 colors instead of 254.
- * Reduce cursor blink rate.
- *
- * 11-15-90 EAN Minor "bug" fixes. Continuous rotation now at a fixed
- * rate - once every timer tick (18.2 sec); Blanks out
- * color samples when rotating; Editors no longer rotate
- * with the colors in color rotation mode; Eliminated
- * (Z)oom mode; other minor fixes.
- *
- * 01-05-91 PB Add 'w' function to convert to greyscale.
- *
- * 01-16-91 PB Change rotate function to use new cyclerange stuff.
- *
- * 01-29-91 EAN Made all colors editable. The two reserved colors are
- * X'ed out. They can be edited but the color is not
- * visible. (There is an X over the sample instead.)
- * Changed default reserved colors to 254 & 255.
- * Added 'v' command to set the reserved colors to those
- * under the editors.
- * Added 'o' command to set the rotate range to between
- * the two editors.
- * Modified 'w' function:
- * uses internal function to do conversion (not BIOS)
- * will convert only current color if in 'x' mode or
- * range between editors in 'y' mode or entire palette
- * if in "normal" mode.
- *
- * 02-08-91 EAN Improved 16 color support. In 16 color mode, colors
- * 16-255 have a dot over them and are editable but not
- * visible (like the two reserved colors).
- *
- * 09-08-91 SWT Added 'n' command to make a negative color palette:
- * will convert only current color if in 'x' mode or
- * range between editors in 'y' mode or entire palette
- * if in "normal" mode.
- *
- * 03-03-92 JJB Added '!', '@' and '#' commands to swap RG, GB and
- * RB columns (sorry, I didn't find better keys)
- *
- * 10-03-92 TIW Minor changes for Jiim support, primarily changing
- * variables from static to global.
- *
- * 2-11-93 EAN Added full Undo ('U' key) and Redo ('E' key)
- * capability. Works pretty much as you'd expect
- * it to.
- *
- * 3-6-93 EAN Modified "freestyle" mode, written by RB, to integrate
- * into palette editor more completely and work with
- * undo logic.
- * Added status area under the "fractint" message to
- * display current state of editor. A = Auto mode,
- * X, Y = exclusion modes, F = freesyle mode, T = stripe
- * mode is waiting for #.
- *
- */
-
- #ifdef DEBUG_UNDO
- #include "mdisp.h" /* EAN 930211 *** Debug Only *** */
- #endif
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #ifndef XFRACT
- #include <stdarg.h>
- #include <dos.h> /* for FP_SEG & FP_OFF */
- #else
- #include <varargs.h>
- #endif
- #include <math.h>
-
- #ifdef __TURBOC__
- # include <mem.h> /* to get mem...() declarations */
- #endif
-
- #include "fractint.h" /* for overlay stuff */
- #include "prototyp.h"
-
-
- /*
- * misc. #defines
- */
-
- #define FONT_DEPTH 8 /* font size */
-
- #define CSIZE_MIN 8 /* csize cannot be smaller than this */
-
- #define CURSOR_SIZE 5 /* length of one side of the x-hair cursor */
-
- #ifndef XFRACT
- #define CURSOR_BLINK_RATE 3 /* timer ticks between cursor blinks */
- #else
- #define CURSOR_BLINK_RATE 300 /* timer ticks between cursor blinks */
- #endif
-
- #define FAR_RESERVE 8192L /* amount of far mem we will leave avail. */
-
- #define MAX_WIDTH 1024 /* palette editor cannot be wider than this */
-
- char scrnfile[] = "FRACTINT.$$1"; /* file where screen portion is */
- /* stored */
- char undofile[] = "FRACTINT.$$2"; /* file where undo list is stored */
- #define TITLE "FRACTINT"
-
- #define TITLE_LEN (8)
-
-
- #define newx(size) mem_alloc(size)
- #define new(class) (class *)(mem_alloc(sizeof(class)))
- #define delete(block) block=NULL /* just for warning */
-
- #ifdef XFRACT
- int editpal_cursor = 0;
- #endif
-
-
- /*
- * Stuff from fractint
- */
-
- #if 0
- /* declarations moved to PRORTOTYPE.H - this left for docs */
- BYTE dacbox[256][3]; /* DAC spindac() will use */
- int sxdots; /* width of physical screen */
- int sydots; /* depth of physical screen */
- int sxoffs; /* start of logical screen */
- int syoffs; /* start of logical screen */
- int lookatmouse; /* mouse mode for getakey(), etc */
- int strlocn[]; /* 10K buffer to store classes in */
- int colors; /* # colors avail. */
- int color_bright; /* brightest color in palette */
- int color_dark; /* darkest color in palette */
- int color_medium; /* nearest to medbright gray color */
- int rotate_lo, rotate_hi;
- int debugflag;
- #endif
- int using_jiim = 0;
-
- /*
- * basic data types
- */
-
-
- typedef struct
- {
- BYTE red,
- green,
- blue;
- } PALENTRY;
-
-
-
- /*
- * static data
- */
-
-
- static BYTE far *font8x8 = NULL;
- BYTE *line_buff; /* must be alloced!!! */
- static BYTE fg_color,
- bg_color;
- static BOOLEAN reserve_colors;
- static BOOLEAN inverse;
-
- static float gamma_val = 1;
-
-
- /*
- * Interface to FRACTINT's graphics stuff
- */
-
-
- static void setpal(int pal, int r, int g, int b)
- {
- dacbox[pal][0] = (BYTE)r;
- dacbox[pal][1] = (BYTE)g;
- dacbox[pal][2] = (BYTE)b;
- spindac(0,1);
- }
-
-
- static void setpalrange(int first, int how_many, PALENTRY *pal)
- {
- memmove(dacbox+first, pal, how_many*3);
- spindac(0,1);
- }
-
-
- static void getpalrange(int first, int how_many, PALENTRY *pal)
- {
- memmove(pal, dacbox+first, how_many*3);
- }
-
-
- static void rotatepal(PALENTRY *pal, int dir, int lo, int hi)
- { /* rotate in either direction */
- PALENTRY hold;
- int size;
-
- size = 1 + (hi-lo);
-
- if ( dir > 0 )
- {
- while ( dir-- > 0 )
- {
- memmove(&hold, &pal[hi], 3);
- memmove(&pal[lo+1], &pal[lo], 3*(size-1));
- memmove(&pal[lo], &hold, 3);
- }
- }
-
- else if ( dir < 0 )
- {
- while ( dir++ < 0 )
- {
- memmove(&hold, &pal[lo], 3);
- memmove(&pal[lo], &pal[lo+1], 3*(size-1));
- memmove(&pal[hi], &hold, 3);
- }
- }
- }
-
-
- static void clip_put_line(int row, int start, int stop, BYTE *pixels)
- {
- if ( row < 0 || row >= sydots || start > sxdots || stop < 0 )
- return ;
-
- if ( start < 0 )
- {
- pixels += -start;
- start = 0;
- }
-
- if ( stop >= sxdots )
- stop = sxdots - 1;
-
- if ( start > stop )
- return ;
-
- put_line(row, start, stop, pixels);
- }
-
-
- static void clip_get_line(int row, int start, int stop, BYTE *pixels)
- {
- if ( row < 0 || row >= sydots || start > sxdots || stop < 0 )
- return ;
-
- if ( start < 0 )
- {
- pixels += -start;
- start = 0;
- }
-
- if ( stop >= sxdots )
- stop = sxdots - 1;
-
- if ( start > stop )
- return ;
-
- get_line(row, start, stop, pixels);
- }
-
-
- void clip_putcolor(int x, int y, int color)
- {
- if ( x < 0 || y < 0 || x >= sxdots || y >= sydots )
- return ;
-
- putcolor(x, y, color);
- }
-
-
- int clip_getcolor(int x, int y)
- {
- if ( x < 0 || y < 0 || x >= sxdots || y >= sydots )
- return (0);
-
- return ( getcolor(x, y) );
- }
-
-
- void hline(int x, int y, int width, int color)
- {
- memset(line_buff, color, width);
- clip_put_line(y, x, x+width-1, line_buff);
- }
-
-
- void vline(int x, int y, int depth, int color)
- {
- while (depth-- > 0)
- clip_putcolor(x, y++, color);
- }
-
-
- void getrow(int x, int y, int width, char *buff)
- {
- clip_get_line(y, x, x+width-1, (BYTE *)buff);
- }
-
-
- void putrow(int x, int y, int width, char *buff)
- {
- clip_put_line(y, x, x+width-1, (BYTE *)buff);
- }
-
-
- static void vgetrow(int x, int y, int depth, char *buff)
- {
- while (depth-- > 0)
- *buff++ = (char)clip_getcolor(x, y++);
- }
-
-
- static void vputrow(int x, int y, int depth, char *buff)
- {
- while (depth-- > 0)
- clip_putcolor(x, y++, (BYTE)(*buff++));
- }
-
-
- static void fillrect(int x, int y, int width, int depth, int color)
- {
- while (depth-- > 0)
- hline(x, y++, width, color);
- }
-
-
- static void rect(int x, int y, int width, int depth, int color)
- {
- hline(x, y, width, color);
- hline(x, y+depth-1, width, color);
-
- vline(x, y, depth, color);
- vline(x+width-1, y, depth, color);
- }
-
-
- void displayc(int x, int y, int fg, int bg, int ch)
- {
- int xc, yc;
- BYTE t;
- BYTE far *ptr;
-
- if( font8x8 == NULL)
- if ( (font8x8 = findfont(0)) == NULL )
- return ;
-
- ptr = ((BYTE far *)font8x8) + ch*FONT_DEPTH;
-
- for (yc=0; yc<FONT_DEPTH; yc++, y++, ++ptr)
- {
- for (xc=0, t= *ptr; xc<8; xc++, t<<=1)
- line_buff[xc] = (BYTE)((t&0x80) ? fg : bg);
- putrow(x, y, 8, (char *)line_buff);
- }
- }
-
-
- #ifndef XFRACT
- static void displayf(int x, int y, int fg, int bg, char *format, ...)
- #else
- static void displayf(va_alist)
- va_dcl
- #endif
- {
- char buff[81];
- int ctr;
-
- va_list arg_list;
-
- #ifndef XFRACT
- va_start(arg_list, format);
- #else
- int x,y,fg,bg;
- char *format;
-
- va_start(arg_list);
- x = va_arg(arg_list,int);
- y = va_arg(arg_list,int);
- fg = va_arg(arg_list,int);
- bg = va_arg(arg_list,int);
- format = va_arg(arg_list,char *);
- #endif
- vsprintf(buff, format, arg_list);
- va_end(arg_list);
-
- for(ctr=0; buff[ctr]!='\0'; ctr++, x+=8)
- displayc(x, y, fg, bg, buff[ctr]);
- }
-
-
- /*
- * create smooth shades between two colors
- */
-
-
- static void mkpalrange(PALENTRY *p1, PALENTRY *p2, PALENTRY pal[], int num, int skip)
- {
- int curr;
- double rm = (double)((int) p2->red - (int) p1->red ) / num,
- gm = (double)((int) p2->green - (int) p1->green) / num,
- bm = (double)((int) p2->blue - (int) p1->blue ) / num;
-
- for (curr=0; curr<num; curr+=skip)
- {
- if (gamma_val == 1)
- {
- pal[curr].red = (BYTE)((p1->red == p2->red ) ? p1->red :
- (int) p1->red + (int) ( rm * curr ));
- pal[curr].green = (BYTE)((p1->green == p2->green) ? p1->green :
- (int) p1->green + (int) ( gm * curr ));
- pal[curr].blue = (BYTE)((p1->blue == p2->blue ) ? p1->blue :
- (int) p1->blue + (int) ( bm * curr ));
- }
- else
- {
- pal[curr].red = (BYTE)((p1->red == p2->red ) ? p1->red :
- (int) (p1->red + pow(curr/(double)(num-1),gamma_val)*num*rm));
- pal[curr].green = (BYTE)((p1->green == p2->green) ? p1->green :
- (int) (p1->green + pow(curr/(double)(num-1),gamma_val)*num*gm));
- pal[curr].blue = (BYTE)((p1->blue == p2->blue ) ? p1->blue :
- (int) (p1->blue + pow(curr/(double)(num-1),gamma_val)*num*bm));
- }
- }
- }
-
-
-
- /* Swap RG GB & RB columns */
-
- static void rotcolrg(PALENTRY pal[], int num)
- {
- int curr;
- int dummy;
-
- for (curr=0; curr<=num; curr++)
- {
- dummy = pal[curr].red;
- pal[curr].red = pal[curr].green;
- pal[curr].green = (BYTE)dummy;
- }
- }
-
-
- static void rotcolgb(PALENTRY pal[], int num)
- {
- int curr;
- int dummy;
-
- for (curr=0; curr<=num; curr++)
- {
- dummy = pal[curr].green;
- pal[curr].green = pal[curr].blue;
- pal[curr].blue = (BYTE)dummy;
- }
- }
-
- static void rotcolbr(PALENTRY pal[], int num)
- {
- int curr;
- int dummy;
-
- for (curr=0; curr<=num; curr++)
- {
- dummy = pal[curr].red;
- pal[curr].red = pal[curr].blue;
- pal[curr].blue = (BYTE)dummy;
- }
- }
-
-
- /*
- * convert a range of colors to grey scale
- */
-
-
- static void palrangetogrey(PALENTRY pal[], int first, int how_many)
- {
- PALENTRY *curr;
- BYTE val;
-
-
- for (curr = &pal[first]; how_many>0; how_many--, curr++)
- {
- val = (BYTE) ( ((int)curr->red*30 + (int)curr->green*59 + (int)curr->blue*11) / 100 );
- curr->red = curr->green = curr->blue = (BYTE)val;
- }
- }
-
- /*
- * convert a range of colors to their inverse
- */
-
-
- static void palrangetonegative(PALENTRY pal[], int first, int how_many)
- {
- PALENTRY *curr;
-
- for (curr = &pal[first]; how_many>0; how_many--, curr++)
- {
- curr->red = (BYTE)(63 - curr->red);
- curr->green = (BYTE)(63 - curr->green);
- curr->blue = (BYTE)(63 - curr->blue);
- }
- }
-
-
- /*
- * draw and horizontal/vertical dotted lines
- */
-
-
- static void hdline(int x, int y, int width)
- {
- int ctr;
- BYTE *ptr;
-
- for (ctr=0, ptr=line_buff; ctr<width; ctr++, ptr++)
- *ptr = (BYTE)((ctr&2) ? bg_color : fg_color);
-
- putrow(x, y, width, (char *)line_buff);
- }
-
-
- static void vdline(int x, int y, int depth)
- {
- int ctr;
-
- for (ctr=0; ctr<depth; ctr++, y++)
- clip_putcolor(x, y, (ctr&2) ? bg_color : fg_color);
- }
-
-
- static void drect(int x, int y, int width, int depth)
- {
- hdline(x, y, width);
- hdline(x, y+depth-1, width);
-
- vdline(x, y, depth);
- vdline(x+width-1, y, depth);
- }
-
-
- /*
- * A very simple memory "allocator".
- *
- * Each call to mem_alloc() returns size bytes from the array mem_block.
- *
- * Be sure to call mem_init() before using mem_alloc()!
- *
- */
-
- static char *mem_block;
- static unsigned mem_avail;
-
-
- void mem_init(VOIDPTR block, unsigned size)
- {
- mem_block = (char *)block;
- mem_avail = size;
- }
-
-
- VOIDPTR mem_alloc(unsigned size)
- {
- VOIDPTR block;
-
- #ifndef XFRACT
- if (size & 1)
- ++size; /* allocate even sizes */
- #else
- size = (size+3)&~3; /* allocate word-aligned memory */
- #endif
-
- if (mem_avail < size) /* don't let this happen! */
- {
- static FCODE msg[] = "editpal.c: Out of memory!\n";
-
- stopmsg(0, msg);
- exit(1);
- }
-
- block = mem_block;
- mem_avail -= size;
- mem_block += size;
-
- return(block);
- }
-
-
-
- /*
- * misc. routines
- *
- */
-
-
- static BOOLEAN is_reserved(int color)
- {
- return ((BOOLEAN) ((reserve_colors && (color==(int)fg_color || color==(int)bg_color) ) ? TRUE : FALSE) );
- }
-
-
-
- static BOOLEAN is_in_box(int x, int y, int bx, int by, int bw, int bd)
- {
- return ((BOOLEAN) ((x >= bx) && (y >= by) && (x < bx+bw) && (y < by+bd)) );
- }
-
-
-
- static void draw_diamond(int x, int y, int color)
- {
- putcolor (x+2, y+0, color);
- hline (x+1, y+1, 3, color);
- hline (x+0, y+2, 5, color);
- hline (x+1, y+3, 3, color);
- putcolor (x+2, y+4, color);
- }
-
-
-
- /*
- * Class: Cursor
- *
- * Purpose: Draw the blinking cross-hair cursor.
- *
- * Note: Only one Cursor can exist (referenced through the_cursor).
- * IMPORTANT: Call Cursor_Construct before you use any other
- * Cursor_ function! Call Cursor_Destroy before exiting to
- * deallocate memory.
- */
-
- struct _Cursor
- {
-
- int x, y;
- int hidden; /* >0 if mouse hidden */
- long last_blink;
- BOOLEAN blink;
- #if 0
- char t[CURSOR_SIZE], /* save line segments here */
- b[CURSOR_SIZE],
- l[CURSOR_SIZE],
- r[CURSOR_SIZE];
- #endif
- char t[CURSOR_SIZE]; /* save line segments here */
- char b[CURSOR_SIZE];
- char l[CURSOR_SIZE];
- char r[CURSOR_SIZE];
- } ;
-
- #define Cursor struct _Cursor
-
- /* private: */
-
- static void Cursor__Draw (void);
- static void Cursor__Save (void);
- static void Cursor__Restore (void);
-
- /* public: */
- #ifdef NOT_USED
- static BOOLEAN Cursor_IsHidden (void);
- #endif
-
-
-
- static Cursor *the_cursor = NULL;
-
-
- BOOLEAN Cursor_Construct(void)
- {
- if (the_cursor != NULL)
- return(FALSE);
-
- the_cursor = new(Cursor);
-
- the_cursor->x = sxdots/2;
- the_cursor->y = sydots/2;
- the_cursor->hidden = 1;
- the_cursor->blink = FALSE;
- the_cursor->last_blink = 0;
-
- return (TRUE);
- }
-
-
- void Cursor_Destroy(void)
- {
- if (the_cursor != NULL)
- delete(the_cursor);
-
- the_cursor = NULL;
- }
-
-
-
- static void Cursor__Draw(void)
- {
- int color;
-
- find_special_colors();
- color = (the_cursor->blink) ? color_medium : color_dark;
-
- vline(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, color);
- vline(the_cursor->x, the_cursor->y+2, CURSOR_SIZE, color);
-
- hline(the_cursor->x-CURSOR_SIZE-1, the_cursor->y, CURSOR_SIZE, color);
- hline(the_cursor->x+2, the_cursor->y, CURSOR_SIZE, color);
- }
-
-
- static void Cursor__Save(void)
- {
- vgetrow(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, the_cursor->t);
- vgetrow(the_cursor->x, the_cursor->y+2, CURSOR_SIZE, the_cursor->b);
-
- getrow(the_cursor->x-CURSOR_SIZE-1, the_cursor->y, CURSOR_SIZE, the_cursor->l);
- getrow(the_cursor->x+2, the_cursor->y, CURSOR_SIZE, the_cursor->r);
- }
-
-
- static void Cursor__Restore(void)
- {
- vputrow(the_cursor->x, the_cursor->y-CURSOR_SIZE-1, CURSOR_SIZE, the_cursor->t);
- vputrow(the_cursor->x, the_cursor->y+2, CURSOR_SIZE, the_cursor->b);
-
- putrow(the_cursor->x-CURSOR_SIZE-1, the_cursor->y, CURSOR_SIZE, the_cursor->l);
- putrow(the_cursor->x+2, the_cursor->y, CURSOR_SIZE, the_cursor->r);
- }
-
-
-
- void Cursor_SetPos(int x, int y)
- {
- if (!the_cursor->hidden)
- Cursor__Restore();
-
- the_cursor->x = x;
- the_cursor->y = y;
-
- if (!the_cursor->hidden)
- {
- Cursor__Save();
- Cursor__Draw();
- }
- }
-
- #ifdef NOT_USED
-
- static int Cursor_IsHidden(void)
- {
- return ( the_cursor->hidden );
- }
-
-
- #endif
-
-
- void Cursor_Move(int xoff, int yoff)
- {
- if ( !the_cursor->hidden )
- Cursor__Restore();
-
- the_cursor->x += xoff;
- the_cursor->y += yoff;
-
- if (the_cursor->x < 0) the_cursor->x = 0;
- if (the_cursor->y < 0) the_cursor->y = 0;
- if (the_cursor->x >= sxdots) the_cursor->x = sxdots-1;
- if (the_cursor->y >= sydots) the_cursor->y = sydots-1;
-
- if ( !the_cursor->hidden )
- {
- Cursor__Save();
- Cursor__Draw();
- }
- }
-
-
- int Cursor_GetX(void) { return(the_cursor->x); }
-
- int Cursor_GetY(void) { return(the_cursor->y); }
-
-
- void Cursor_Hide(void)
- {
- if ( the_cursor->hidden++ == 0 )
- Cursor__Restore();
- }
-
-
- void Cursor_Show(void)
- {
- if ( --the_cursor->hidden == 0)
- {
- Cursor__Save();
- Cursor__Draw();
- }
- }
-
- #ifdef XFRACT
- void Cursor_StartMouseTracking()
- {
- editpal_cursor = 1;
- }
-
- void Cursor_EndMouseTracking()
- {
- editpal_cursor = 0;
- }
- #endif
-
- /* See if the cursor should blink yet, and blink it if so */
- void Cursor_CheckBlink(void)
- {
- long tick;
- tick = readticker();
-
- if ( (tick - the_cursor->last_blink) > CURSOR_BLINK_RATE )
- {
- the_cursor->blink = (BOOLEAN)((the_cursor->blink) ? FALSE : TRUE);
- the_cursor->last_blink = tick;
- if ( !the_cursor->hidden )
- Cursor__Draw();
- }
- else if ( tick < the_cursor->last_blink )
- the_cursor->last_blink = tick;
- }
-
- int Cursor_WaitKey(void) /* blink cursor while waiting for a key */
- {
-
- #ifndef XFRACT
- while ( !keypressed() ) {
- Cursor_CheckBlink();
- }
- #else
- while ( !waitkeypressed(1) ) {
- Cursor_CheckBlink();
- }
- #endif
-
- return( keypressed() );
- }
-
-
-
- /*
- * Class: MoveBox
- *
- * Purpose: Handles the rectangular move/resize box.
- */
-
- struct _MoveBox
- {
- int x, y;
- int base_width,
- base_depth;
- int csize;
- BOOLEAN moved;
- BOOLEAN should_hide;
- char *t, *b,
- *l, *r;
- } ;
-
- #define MoveBox struct _MoveBox
-
- /* private: */
-
- static void MoveBox__Draw (MoveBox *this);
- static void MoveBox__Erase (MoveBox *this);
- static void MoveBox__Move (MoveBox *this, int key);
-
- /* public: */
-
- static MoveBox *MoveBox_Construct (int x, int y, int csize, int base_width,
- int base_depth);
- static void MoveBox_Destroy (MoveBox *this);
- static BOOLEAN MoveBox_Process (MoveBox *this); /* returns FALSE if ESCAPED */
- static BOOLEAN MoveBox_Moved (MoveBox *this);
- static BOOLEAN MoveBox_ShouldHide (MoveBox *this);
- static int MoveBox_X (MoveBox *this);
- static int MoveBox_Y (MoveBox *this);
- static int MoveBox_CSize (MoveBox *this);
-
- static void MoveBox_SetPos (MoveBox *this, int x, int y);
- static void MoveBox_SetCSize (MoveBox *this, int csize);
-
-
-
- static MoveBox *MoveBox_Construct(int x, int y, int csize, int base_width, int base_depth)
- {
- MoveBox *this = new(MoveBox);
-
- this->x = x;
- this->y = y;
- this->csize = csize;
- this->base_width = base_width;
- this->base_depth = base_depth;
- this->moved = FALSE;
- this->should_hide = FALSE;
- this->t = newx(sxdots);
- this->b = newx(sxdots);
- this->l = newx(sydots);
- this->r = newx(sydots);
-
- return(this);
- }
-
-
- static void MoveBox_Destroy(MoveBox *this)
- {
- delete(this->t);
- delete(this->b);
- delete(this->l);
- delete(this->r);
- delete(this);
- }
-
-
- static BOOLEAN MoveBox_Moved(MoveBox *this) { return(this->moved); }
-
- static BOOLEAN MoveBox_ShouldHide(MoveBox *this) { return(this->should_hide); }
-
- static int MoveBox_X(MoveBox *this) { return(this->x); }
-
- static int MoveBox_Y(MoveBox *this) { return(this->y); }
-
- static int MoveBox_CSize(MoveBox *this) { return(this->csize); }
-
-
- static void MoveBox_SetPos(MoveBox *this, int x, int y)
- {
- this->x = x;
- this->y = y;
- }
-
-
- static void MoveBox_SetCSize(MoveBox *this, int csize)
- {
- this->csize = csize;
- }
-
-
- static void MoveBox__Draw(MoveBox *this) /* private */
- {
- int width = this->base_width + this->csize*16+1,
- depth = this->base_depth + this->csize*16+1;
- int x = this->x,
- y = this->y;
-
-
- getrow (x, y, width, this->t);
- getrow (x, y+depth-1, width, this->b);
-
- vgetrow(x, y, depth, this->l);
- vgetrow(x+width-1, y, depth, this->r);
-
- hdline(x, y, width);
- hdline(x, y+depth-1, width);
-
- vdline(x, y, depth);
- vdline(x+width-1, y, depth);
- }
-
-
- static void MoveBox__Erase(MoveBox *this) /* private */
- {
- int width = this->base_width + this->csize*16+1,
- depth = this->base_depth + this->csize*16+1;
-
- vputrow(this->x, this->y, depth, this->l);
- vputrow(this->x+width-1, this->y, depth, this->r);
-
- putrow(this->x, this->y, width, this->t);
- putrow(this->x, this->y+depth-1, width, this->b);
- }
-
-
- #define BOX_INC 1
- #define CSIZE_INC 2
-
- static void MoveBox__Move(MoveBox *this, int key)
- {
- BOOLEAN done = FALSE;
- BOOLEAN first = TRUE;
- int xoff = 0,
- yoff = 0;
-
- while ( !done )
- {
- switch(key)
- {
- case RIGHT_ARROW_2: xoff += BOX_INC*4; break;
- case RIGHT_ARROW: xoff += BOX_INC; break;
- case LEFT_ARROW_2: xoff -= BOX_INC*4; break;
- case LEFT_ARROW: xoff -= BOX_INC; break;
- case DOWN_ARROW_2: yoff += BOX_INC*4; break;
- case DOWN_ARROW: yoff += BOX_INC; break;
- case UP_ARROW_2: yoff -= BOX_INC*4; break;
- case UP_ARROW: yoff -= BOX_INC; break;
-
- default:
- done = TRUE;
- }
-
- if (!done)
- {
- if (!first)
- getakey(); /* delete key from buffer */
- else
- first = FALSE;
- key = keypressed(); /* peek at the next one... */
- }
- }
-
- xoff += this->x;
- yoff += this->y; /* (xoff,yoff) = new position */
-
- if (xoff < 0) xoff = 0;
- if (yoff < 0) yoff = 0;
-
- if (xoff+this->base_width+this->csize*16+1 > sxdots)
- xoff = sxdots - (this->base_width+this->csize*16+1);
-
- if (yoff+this->base_depth+this->csize*16+1 > sydots)
- yoff = sydots - (this->base_depth+this->csize*16+1);
-
- if ( xoff!=this->x || yoff!=this->y )
- {
- MoveBox__Erase(this);
- this->y = yoff;
- this->x = xoff;
- MoveBox__Draw(this);
- }
- }
-
-
- static BOOLEAN MoveBox_Process(MoveBox *this)
- {
- int key;
- int orig_x = this->x,
- orig_y = this->y,
- orig_csize = this->csize;
-
- MoveBox__Draw(this);
-
- #ifdef XFRACT
- Cursor_StartMouseTracking();
- #endif
- for(;;)
- {
- Cursor_WaitKey();
- key = getakey();
-
- if (key==ENTER || key==ENTER_2 || key==ESC || key=='H' || key=='h')
- {
- if (this->x != orig_x || this->y != orig_y || this->csize != orig_csize)
- this->moved = TRUE;
- else
- this->moved = FALSE;
- break;
- }
-
- switch(key)
- {
- case UP_ARROW:
- case DOWN_ARROW:
- case LEFT_ARROW:
- case RIGHT_ARROW:
- case UP_ARROW_2:
- case DOWN_ARROW_2:
- case LEFT_ARROW_2:
- case RIGHT_ARROW_2:
- MoveBox__Move(this, key);
- break;
-
- case PAGE_UP: /* shrink */
- if (this->csize > CSIZE_MIN)
- {
- int t = this->csize - CSIZE_INC;
- int change;
-
- if (t < CSIZE_MIN)
- t = CSIZE_MIN;
-
- MoveBox__Erase(this);
-
- change = this->csize - t;
- this->csize = t;
- this->x += (change*16) / 2;
- this->y += (change*16) / 2;
- MoveBox__Draw(this);
- }
- break;
-
- case PAGE_DOWN: /* grow */
- {
- int max_width = min(sxdots, MAX_WIDTH);
-
- if (this->base_depth+(this->csize+CSIZE_INC)*16+1 < sydots &&
- this->base_width+(this->csize+CSIZE_INC)*16+1 < max_width )
- {
- MoveBox__Erase(this);
- this->x -= (CSIZE_INC*16) / 2;
- this->y -= (CSIZE_INC*16) / 2;
- this->csize += CSIZE_INC;
- if (this->y+this->base_depth+this->csize*16+1 > sydots)
- this->y = sydots - (this->base_depth+this->csize*16+1);
- if (this->x+this->base_width+this->csize*16+1 > max_width)
- this->x = max_width - (this->base_width+this->csize*16+1);
- if (this->y < 0)
- this->y = 0;
- if (this->x < 0)
- this->x = 0;
- MoveBox__Draw(this);
- }
- }
- break;
- }
- }
-
- #ifdef XFRACT
- Cursor_EndMouseTracking();
- #endif
-
- MoveBox__Erase(this);
-
- this->should_hide = (BOOLEAN)((key == 'H' || key == 'h') ? TRUE : FALSE);
-
- return( (BOOLEAN)((key==ESC) ? FALSE : TRUE) );
- }
-
-
-
- /*
- * Class: CEditor
- *
- * Purpose: Edits a single color component (R, G or B)
- *
- * Note: Calls the "other_key" function to process keys it doesn't use.
- * The "change" function is called whenever the value is changed
- * by the CEditor.
- */
-
- struct _CEditor
- {
- int x, y;
- char letter;
- int val;
- BOOLEAN done;
- BOOLEAN hidden;
- #ifndef XFRACT
- void (*other_key)(int key, struct _CEditor *ce, VOIDPTR info);
- void (*change)(struct _CEditor *ce, VOIDPTR info);
- #else
- void (*other_key)();
- void (*change)();
- #endif
- void *info;
-
- } ;
-
- #define CEditor struct _CEditor
-
- /* public: */
-
- #ifndef XFRACT
- static CEditor *CEditor_Construct( int x, int y, char letter,
- void (*other_key)(int,CEditor*,void*),
- void (*change)(CEditor*,void*), VOIDPTR info);
- static void CEditor_Destroy (CEditor *this);
- static void CEditor_Draw (CEditor *this);
- static void CEditor_SetPos (CEditor *this, int x, int y);
- static void CEditor_SetVal (CEditor *this, int val);
- static int CEditor_GetVal (CEditor *this);
- static void CEditor_SetDone (CEditor *this, BOOLEAN done);
- static void CEditor_SetHidden (CEditor *this, BOOLEAN hidden);
- static int CEditor_Edit (CEditor *this);
- #else
- static CEditor *CEditor_Construct( int , int , char ,
- void (*other_key)(),
- void (*change)(), VOIDPTR );
- static void CEditor_Destroy (CEditor *);
- static void CEditor_Draw (CEditor *);
- static void CEditor_SetPos (CEditor *, int , int );
- static void CEditor_SetVal (CEditor *, int );
- static int CEditor_GetVal (CEditor *);
- static void CEditor_SetDone (CEditor *, BOOLEAN );
- static void CEditor_SetHidden (CEditor *, BOOLEAN );
- static int CEditor_Edit (CEditor *);
- #endif
-
- #define CEditor_WIDTH (8*3+4)
- #define CEditor_DEPTH (8+4)
-
-
-
- #ifndef XFRACT
- static CEditor *CEditor_Construct( int x, int y, char letter,
- void (*other_key)(int,CEditor*,VOIDPTR),
- void (*change)(CEditor*, VOIDPTR), VOIDPTR info)
- #else
- static CEditor *CEditor_Construct( int x, int y, char letter,
- void (*other_key)(),
- void (*change)(), VOIDPTR info)
- #endif
- {
- CEditor *this = new(CEditor);
-
- this->x = x;
- this->y = y;
- this->letter = letter;
- this->val = 0;
- this->other_key = other_key;
- this->hidden = FALSE;
- this->change = change;
- this->info = info;
-
- return(this);
- }
-
- #ifdef __TURBOC__
- # pragma argsused /* kills "arg not used" warning */
- #endif
- #ifdef __CLINT__
- # pragma argsused /* kills "arg not used" warning */
- #endif
-
- static void CEditor_Destroy(CEditor *this)
- {
- delete(this);
- }
-
-
- static void CEditor_Draw(CEditor *this)
- {
- if (this->hidden)
- return;
-
- Cursor_Hide();
- displayf(this->x+2, this->y+2, fg_color, bg_color, "%c%02d", this->letter, this->val);
- Cursor_Show();
- }
-
-
- static void CEditor_SetPos(CEditor *this, int x, int y)
- {
- this->x = x;
- this->y = y;
- }
-
-
- static void CEditor_SetVal(CEditor *this, int val)
- {
- this->val = val;
- }
-
-
- static int CEditor_GetVal(CEditor *this)
- {
- return(this->val);
- }
-
-
- static void CEditor_SetDone(CEditor *this, BOOLEAN done)
- {
- this->done = done;
- }
-
-
- static void CEditor_SetHidden(CEditor *this, BOOLEAN hidden)
- {
- this->hidden = hidden;
- }
-
-
- static int CEditor_Edit(CEditor *this)
- {
- int key;
- int diff;
-
- this->done = FALSE;
-
- if (!this->hidden)
- {
- Cursor_Hide();
- rect(this->x, this->y, CEditor_WIDTH, CEditor_DEPTH, fg_color);
- Cursor_Show();
- }
-
- #ifdef XFRACT
- Cursor_StartMouseTracking();
- #endif
- while ( !this->done )
- {
- Cursor_WaitKey();
- key = getakey();
-
- switch( key )
- {
- case PAGE_UP:
- if (this->val < 63)
- {
- this->val += 5;
- if (this->val > 63)
- this->val = 63;
- CEditor_Draw(this);
- this->change(this, this->info);
- }
- break;
-
- case '+':
- case CTL_PLUS: /*RB*/
- diff = 1;
- while ( keypressed() == key )
- {
- getakey();
- ++diff;
- }
- if (this->val < 63)
- {
- this->val += diff;
- if (this->val > 63)
- this->val = 63;
- CEditor_Draw(this);
- this->change(this, this->info);
- }
- break;
-
- case PAGE_DOWN:
- if (this->val > 0)
- {
- this->val -= 5;
- if (this->val < 0)
- this->val = 0;
- CEditor_Draw(this);
- this->change(this, this->info);
- } break;
-
- case '-':
- case CTL_MINUS: /*RB*/
- diff = 1;
- while ( keypressed() == key )
- {
- getakey();
- ++diff;
- }
- if (this->val > 0)
- {
- this->val -= diff;
- if (this->val < 0)
- this->val = 0;
- CEditor_Draw(this);
- this->change(this, this->info);
- }
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- this->val = (key - '0') * 10;
- if (this->val > 63)
- this->val = 63;
- CEditor_Draw(this);
- this->change(this, this->info);
- break;
-
- default:
- this->other_key(key, this, this->info);
- break;
- } /* switch */
- } /* while */
- #ifdef XFRACT
- Cursor_EndMouseTracking();
- #endif
-
- if (!this->hidden)
- {
- Cursor_Hide();
- rect(this->x, this->y, CEditor_WIDTH, CEditor_DEPTH, bg_color);
- Cursor_Show();
- }
-
- return(key);
- }
-
-
-
- /*
- * Class: RGBEditor
- *
- * Purpose: Edits a complete color using three CEditors for R, G and B
- */
-
- struct _RGBEditor
- {
- int x, y; /* position */
- int curr; /* 0=r, 1=g, 2=b */
- int pal; /* palette number */
- BOOLEAN done;
- BOOLEAN hidden;
- CEditor *color[3]; /* color editors 0=r, 1=g, 2=b */
- #ifndef XFRACT
- void (*other_key)(int key, struct _RGBEditor *e, VOIDPTR info);
- void (*change)(struct _RGBEditor *e, VOIDPTR info);
- #else
- void (*other_key)();
- void (*change)();
- #endif
- void *info;
- } ;
-
- #define RGBEditor struct _RGBEditor
-
- /* private: */
-
- static void RGBEditor__other_key (int key, CEditor *ceditor, VOIDPTR info);
- static void RGBEditor__change (CEditor *ceditor, VOIDPTR info);
-
- /* public: */
-
- #ifndef XFRACT
- static RGBEditor *RGBEditor_Construct(int x, int y,
- void (*other_key)(int,RGBEditor*,void*),
- void (*change)(RGBEditor*,void*), VOIDPTR info);
- #else
- static RGBEditor *RGBEditor_Construct(int x, int y,
- void (*other_key)(),
- void (*change)(), VOIDPTR info);
- #endif
-
- static void RGBEditor_Destroy (RGBEditor *this);
- static void RGBEditor_SetPos (RGBEditor *this, int x, int y);
- static void RGBEditor_SetDone (RGBEditor *this, BOOLEAN done);
- static void RGBEditor_SetHidden(RGBEditor *this, BOOLEAN hidden);
- static void RGBEditor_BlankSampleBox(RGBEditor *this);
- static void RGBEditor_Update (RGBEditor *this);
- static void RGBEditor_Draw (RGBEditor *this);
- static int RGBEditor_Edit (RGBEditor *this);
- static void RGBEditor_SetRGB (RGBEditor *this, int pal, PALENTRY *rgb);
- static PALENTRY RGBEditor_GetRGB (RGBEditor *this);
-
- #define RGBEditor_WIDTH 62
- #define RGBEditor_DEPTH (1+1+CEditor_DEPTH*3-2+2)
-
- #define RGBEditor_BWIDTH ( RGBEditor_WIDTH - (2+CEditor_WIDTH+1 + 2) )
- #define RGBEditor_BDEPTH ( RGBEditor_DEPTH - 4 )
-
-
-
- #ifndef XFRACT
- static RGBEditor *RGBEditor_Construct(int x, int y, void (*other_key)(int,RGBEditor*,void*),
- void (*change)(RGBEditor*,void*), VOIDPTR info)
- #else
- static RGBEditor *RGBEditor_Construct(int x, int y, void (*other_key)(),
- void (*change)(), VOIDPTR info)
- #endif
- {
- RGBEditor *this = new(RGBEditor);
- static FCODE letter[] = "RGB";
- int ctr;
-
- for (ctr=0; ctr<3; ctr++)
- this->color[ctr] = CEditor_Construct(0, 0, letter[ctr], RGBEditor__other_key,
- RGBEditor__change, this);
-
- RGBEditor_SetPos(this, x, y);
- this->curr = 0;
- this->pal = 1;
- this->hidden = FALSE;
- this->other_key = other_key;
- this->change = change;
- this->info = info;
-
- return(this);
- }
-
-
- static void RGBEditor_Destroy(RGBEditor *this)
- {
- CEditor_Destroy(this->color[0]);
- CEditor_Destroy(this->color[1]);
- CEditor_Destroy(this->color[2]);
- delete(this);
- }
-
-
- static void RGBEditor_SetDone(RGBEditor *this, BOOLEAN done)
- {
- this->done = done;
- }
-
-
- static void RGBEditor_SetHidden(RGBEditor *this, BOOLEAN hidden)
- {
- this->hidden = hidden;
- CEditor_SetHidden(this->color[0], hidden);
- CEditor_SetHidden(this->color[1], hidden);
- CEditor_SetHidden(this->color[2], hidden);
- }
-
-
- static void RGBEditor__other_key(int key, CEditor *ceditor, VOIDPTR info) /* private */
- {
- RGBEditor *this = (RGBEditor *)info;
-
- switch( key )
- {
- case 'R':
- case 'r':
- if (this->curr != 0)
- {
- this->curr = 0;
- CEditor_SetDone(ceditor, TRUE);
- }
- break;
-
- case 'G':
- case 'g':
- if (this->curr != 1)
- {
- this->curr = 1;
- CEditor_SetDone(ceditor, TRUE);
- }
- break;
-
- case 'B':
- case 'b':
- if (this->curr != 2)
- {
- this->curr = 2;
- CEditor_SetDone(ceditor, TRUE);
- }
- break;
-
- case DELETE: /* move to next CEditor */
- case CTL_ENTER_2: /*double click rt mouse also! */
- if ( ++this->curr > 2)
- this->curr = 0;
- CEditor_SetDone(ceditor, TRUE);
- break;
-
- case INSERT: /* move to prev CEditor */
- if ( --this->curr < 0)
- this->curr = 2;
- CEditor_SetDone(ceditor, TRUE);
- break;
-
- default:
- this->other_key(key, this, this->info);
- if (this->done)
- CEditor_SetDone(ceditor, TRUE);
- break;
- }
- }
-
- #ifdef __TURBOC__
- # pragma argsused /* kills "arg not used" warning */
- #endif
- #ifdef __CLINT__
- # pragma argsused /* kills "arg not used" warning */
- #endif
-
- static void RGBEditor__change(CEditor *ceditor, VOIDPTR info) /* private */
- {
- RGBEditor *this = (RGBEditor *)info;
-
- ceditor = NULL; /* just for warning */
- if ( this->pal < colors && !is_reserved(this->pal) )
- setpal(this->pal, CEditor_GetVal(this->color[0]),
- CEditor_GetVal(this->color[1]), CEditor_GetVal(this->color[2]));
-
- this->change(this, this->info);
- }
-
-
- static void RGBEditor_SetPos(RGBEditor *this, int x, int y)
- {
- this->x = x;
- this->y = y;
-
- CEditor_SetPos(this->color[0], x+2, y+2);
- CEditor_SetPos(this->color[1], x+2, y+2+CEditor_DEPTH-1);
- CEditor_SetPos(this->color[2], x+2, y+2+CEditor_DEPTH-1+CEditor_DEPTH-1);
- }
-
-
- static void RGBEditor_BlankSampleBox(RGBEditor *this)
- {
- if (this->hidden)
- return ;
-
- Cursor_Hide();
- fillrect(this->x+2+CEditor_WIDTH+1+1, this->y+2+1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color);
- Cursor_Show();
- }
-
-
- static void RGBEditor_Update(RGBEditor *this)
- {
- int x1 = this->x+2+CEditor_WIDTH+1+1,
- y1 = this->y+2+1;
-
- if (this->hidden)
- return ;
-
- Cursor_Hide();
-
- if ( this->pal >= colors )
- {
- fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color);
- draw_diamond(x1+(RGBEditor_BWIDTH-5)/2, y1+(RGBEditor_BDEPTH-5)/2, fg_color);
- }
-
- else if ( is_reserved(this->pal) )
- {
- int x2 = x1+RGBEditor_BWIDTH-3,
- y2 = y1+RGBEditor_BDEPTH-3;
-
- fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, bg_color);
- draw_line(x1, y1, x2, y2, fg_color);
- draw_line(x1, y2, x2, y1, fg_color);
- }
- else
- fillrect(x1, y1, RGBEditor_BWIDTH-2, RGBEditor_BDEPTH-2, this->pal);
-
- CEditor_Draw(this->color[0]);
- CEditor_Draw(this->color[1]);
- CEditor_Draw(this->color[2]);
- Cursor_Show();
- }
-
-
- static void RGBEditor_Draw(RGBEditor *this)
- {
- if (this->hidden)
- return ;
-
- Cursor_Hide();
- drect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH);
- fillrect(this->x+1, this->y+1, RGBEditor_WIDTH-2, RGBEditor_DEPTH-2, bg_color);
- rect(this->x+1+CEditor_WIDTH+2, this->y+2, RGBEditor_BWIDTH, RGBEditor_BDEPTH, fg_color);
- RGBEditor_Update(this);
- Cursor_Show();
- }
-
-
- static int RGBEditor_Edit(RGBEditor *this)
- {
- int key;
-
- this->done = FALSE;
-
- if (!this->hidden)
- {
- Cursor_Hide();
- rect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH, fg_color);
- Cursor_Show();
- }
-
- while ( !this->done )
- key = CEditor_Edit( this->color[this->curr] );
-
- if (!this->hidden)
- {
- Cursor_Hide();
- drect(this->x, this->y, RGBEditor_WIDTH, RGBEditor_DEPTH);
- Cursor_Show();
- }
-
- return (key);
- }
-
-
- static void RGBEditor_SetRGB(RGBEditor *this, int pal, PALENTRY *rgb)
- {
- this->pal = pal;
- CEditor_SetVal(this->color[0], rgb->red);
- CEditor_SetVal(this->color[1], rgb->green);
- CEditor_SetVal(this->color[2], rgb->blue);
- }
-
-
- static PALENTRY RGBEditor_GetRGB(RGBEditor *this)
- {
- PALENTRY pal;
-
- pal.red = (BYTE)CEditor_GetVal(this->color[0]);
- pal.green = (BYTE)CEditor_GetVal(this->color[1]);
- pal.blue = (BYTE)CEditor_GetVal(this->color[2]);
-
- return(pal);
- }
-
-
-
- /*
- * Class: PalTable
- *
- * Purpose: This is where it all comes together. Creates the two RGBEditors
- * and the palette. Moves the cursor, hides/restores the screen,
- * handles (S)hading, (C)opying, e(X)clude mode, the "Y" exclusion
- * mode, (Z)oom option, (H)ide palette, rotation, etc.
- *
- */
-
- enum stored_at_values
- {
- NOWHERE,
- DISK,
- MEMORY
- } ;
-
- /*
-
- Modes:
- Auto: "A", " "
- Exclusion: "X", "Y", " "
- Freestyle: "F", " "
- S(t)ripe mode: "T", " "
-
- */
-
-
-
- struct _PalTable
- {
- int x, y;
- int csize;
- int active; /* which RGBEditor is active (0,1) */
- int curr[2];
- RGBEditor *rgb[2];
- MoveBox *movebox;
- BOOLEAN done;
- BOOLEAN exclude;
- BOOLEAN auto_select;
- PALENTRY pal[256];
- FILE *undo_file;
- BOOLEAN curr_changed;
- int num_redo;
- int hidden;
- int stored_at;
- FILE *file;
- char far *memory;
-
- PALENTRY far *save_pal[8];
-
- PALENTRY fs_color;
- int top,bottom; /* top and bottom colours of freestyle band */
- int bandwidth; /*size of freestyle colour band */
- BOOLEAN freestyle;
- } ;
-
- #define PalTable struct _PalTable
-
- /* private: */
-
- static void PalTable__DrawStatus (PalTable *this, BOOLEAN stripe_mode);
- static void PalTable__HlPal (PalTable *this, int pnum, int color);
- static void PalTable__Draw (PalTable *this);
- static BOOLEAN PalTable__SetCurr (PalTable *this, int which, int curr);
- static BOOLEAN PalTable__MemoryAlloc (PalTable *this, long size);
- static void PalTable__SaveRect (PalTable *this);
- static void PalTable__RestoreRect (PalTable *this);
- static void PalTable__SetPos (PalTable *this, int x, int y);
- static void PalTable__SetCSize (PalTable *this, int csize);
- static int PalTable__GetCursorColor(PalTable *this);
- static void PalTable__DoCurs (PalTable *this, int key);
- static void PalTable__Rotate (PalTable *this, int dir, int lo, int hi);
- static void PalTable__UpdateDAC (PalTable *this);
- static void PalTable__other_key (int key, RGBEditor *rgb, VOIDPTR info);
- static void PalTable__SaveUndoData(PalTable *this, int first, int last);
- static void PalTable__SaveUndoRotate(PalTable *this, int dir, int first, int last);
- static void PalTable__UndoProcess (PalTable *this, int delta);
- static void PalTable__Undo (PalTable *this);
- static void PalTable__Redo (PalTable *this);
- static void PalTable__change (RGBEditor *rgb, VOIDPTR info);
-
- /* public: */
-
- static PalTable *PalTable_Construct (void);
- static void PalTable_Destroy (PalTable *this);
- static void PalTable_Process (PalTable *this);
- static void PalTable_SetHidden (PalTable *this, BOOLEAN hidden);
- static void PalTable_Hide (PalTable *this, RGBEditor *rgb, BOOLEAN hidden);
-
-
- #define PalTable_PALX (1)
- #define PalTable_PALY (2+RGBEditor_DEPTH+2)
-
- #define UNDO_DATA (1)
- #define UNDO_DATA_SINGLE (2)
- #define UNDO_ROTATE (3)
-
- /* - Freestyle code - */
-
- static void PalTable__CalcTopBottom(PalTable *this)
- {
- if (this->curr[this->active] < this->bandwidth )
- this->bottom = 0;
- else
- this->bottom = (this->curr[this->active]) - this->bandwidth;
-
- if (this->curr[this->active] > (255-this->bandwidth) )
- this->top = 255;
- else
- this->top = (this->curr[this->active]) + this->bandwidth;
- }
-
- static void PalTable__PutBand(PalTable *this, PALENTRY *pal)
- {
- int r,b,a;
-
- /* clip top and bottom values to stop them running off the end of the DAC */
-
- PalTable__CalcTopBottom(this);
-
- /* put bands either side of current colour */
-
- a = this->curr[this->active];
- b = this->bottom;
- r = this->top;
-
- pal[a] = this->fs_color;
-
- if (r != a && a != b)
- {
- mkpalrange(&pal[a], &pal[r], &pal[a], r-a, 1);
- mkpalrange(&pal[b], &pal[a], &pal[b], a-b, 1);
- }
-
- }
-
-
- /* - Undo.Redo code - */
-
-
- static void PalTable__SaveUndoData(PalTable *this, int first, int last)
- {
- int num;
-
- if ( this->undo_file == NULL )
- return ;
-
- num = (last - first) + 1;
-
- #ifdef DEBUG_UNDO
- mprintf("%6ld Writing Undo DATA from %d to %d (%d)", ftell(this->undo_file), first, last, num);
- #endif
-
- fseek(this->undo_file, 0, SEEK_CUR);
- if ( num == 1 )
- {
- putc(UNDO_DATA_SINGLE, this->undo_file);
- putc(first, this->undo_file);
- fwrite(this->pal+first, 3, 1, this->undo_file);
- putw( 1 + 1 + 3 + sizeof(int), this->undo_file);
- }
- else
- {
- putc(UNDO_DATA, this->undo_file);
- putc(first, this->undo_file);
- putc(last, this->undo_file);
- fwrite(this->pal+first, 3, num, this->undo_file);
- putw(1 + 2 + (num*3) + sizeof(int), this->undo_file);
- }
-
- this->num_redo = 0;
- }
-
-
- static void PalTable__SaveUndoRotate(PalTable *this, int dir, int first, int last)
- {
- if ( this->undo_file == NULL )
- return ;
-
- #ifdef DEBUG_UNDO
- mprintf("%6ld Writing Undo ROTATE of %d from %d to %d", ftell(this->undo_file), dir, first, last);
- #endif
-
- fseek(this->undo_file, 0, SEEK_CUR);
- putc(UNDO_ROTATE, this->undo_file);
- putc(first, this->undo_file);
- putc(last, this->undo_file);
- putw(dir, this->undo_file);
- putw(1 + 2 + sizeof(int), this->undo_file);
-
- this->num_redo = 0;
- }
-
-
- static void PalTable__UndoProcess(PalTable *this, int delta) /* undo/redo common code */
- { /* delta = -1 for undo, +1 for redo */
- int cmd = getc(this->undo_file);
-
- switch( cmd )
- {
- case UNDO_DATA:
- case UNDO_DATA_SINGLE:
- {
- int first, last, num;
- PALENTRY temp[256];
-
- if ( cmd == UNDO_DATA )
- {
- first = (unsigned char)getc(this->undo_file);
- last = (unsigned char)getc(this->undo_file);
- }
- else /* UNDO_DATA_SINGLE */
- first = last = (unsigned char)getc(this->undo_file);
-
- num = (last - first) + 1;
-
- #ifdef DEBUG_UNDO
- mprintf(" Reading DATA from %d to %d", first, last);
- #endif
-
- fread(temp, 3, num, this->undo_file);
-
- fseek(this->undo_file, -(num*3), SEEK_CUR); /* go to start of undo/redo data */
- fwrite(this->pal+first, 3, num, this->undo_file); /* write redo/undo data */
-
- memmove(this->pal+first, temp, num*3);
-
- PalTable__UpdateDAC(this);
-
- RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
- RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
- RGBEditor_Update(this->rgb[0]);
- RGBEditor_Update(this->rgb[1]);
- break;
- }
-
- case UNDO_ROTATE:
- {
- int first = (unsigned char)getc(this->undo_file);
- int last = (unsigned char)getc(this->undo_file);
- int dir = getw(this->undo_file);
-
- #ifdef DEBUG_UNDO
- mprintf(" Reading ROTATE of %d from %d to %d", dir, first, last);
- #endif
- PalTable__Rotate(this, delta*dir, first, last);
- break;
- }
-
- default:
- #ifdef DEBUG_UNDO
- mprintf(" Unknown command: %d", cmd);
- #endif
- break;
- }
-
- fseek(this->undo_file, 0, SEEK_CUR); /* to put us in read mode */
- getw(this->undo_file); /* read size */
- }
-
-
- static void PalTable__Undo(PalTable *this)
- {
- int size;
- long pos;
-
- if ( ftell(this->undo_file) <= 0 ) /* at beginning of file? */
- { /* nothing to undo -- exit */
- return ;
- }
-
- fseek(this->undo_file, -(int)sizeof(int), SEEK_CUR); /* go back to get size */
-
- size = getw(this->undo_file);
- fseek(this->undo_file, -size, SEEK_CUR); /* go to start of undo */
-
- #ifdef DEBUG_UNDO
- mprintf("%6ld Undo:", ftell(this->undo_file));
- #endif
-
- pos = ftell(this->undo_file);
-
- PalTable__UndoProcess(this, -1);
-
- fseek(this->undo_file, pos, SEEK_SET); /* go to start of this block */
-
- ++this->num_redo;
- }
-
-
- static void PalTable__Redo(PalTable *this)
- {
- if ( this->num_redo <= 0 )
- return ;
-
- #ifdef DEBUG_UNDO
- mprintf("%6ld Redo:", ftell(this->undo_file));
- #endif
-
- fseek(this->undo_file, 0, SEEK_CUR); /* to make sure we are in "read" mode */
- PalTable__UndoProcess(this, 1);
-
- --this->num_redo;
- }
-
-
- /* - everything else - */
-
-
- #define STATUS_LEN (4)
-
- static void PalTable__DrawStatus(PalTable *this, BOOLEAN stripe_mode)
- {
- int width = 1+(this->csize*16)+1+1;
-
- if ( !this->hidden && ( width - (RGBEditor_WIDTH*2+4) >= STATUS_LEN*8 ) )
- {
- int x = this->x + 2 + RGBEditor_WIDTH,
- y = this->y + PalTable_PALY - 10;
-
- Cursor_Hide();
-
- displayc(x+(0*8), y, fg_color, bg_color, (this->auto_select) ? 'A' : 254);
- displayc(x+(1*8), y, fg_color, bg_color, (this->exclude==1) ? 'X' :
- (this->exclude==2) ? 'Y' : 254);
- displayc(x+(2*8), y, fg_color, bg_color, (this->freestyle) ? 'F' : 254);
- displayc(x+(3*8), y, fg_color, bg_color, (stripe_mode) ? 'T' : 254);
-
- Cursor_Show();
- }
- }
-
-
- static void PalTable__HlPal(PalTable *this, int pnum, int color)
- {
- int x = this->x + PalTable_PALX + (pnum%16)*this->csize,
- y = this->y + PalTable_PALY + (pnum/16)*this->csize,
- size = this->csize;
-
- if (this->hidden)
- return ;
-
- Cursor_Hide();
-
- if (color < 0)
- drect(x, y, size+1, size+1);
- else
- rect(x, y, size+1, size+1, color);
-
- Cursor_Show();
- }
-
-
- static void PalTable__Draw(PalTable *this)
- {
- int pal;
- int xoff, yoff;
- int width;
-
- if (this->hidden)
- return ;
-
- Cursor_Hide();
-
- width = 1+(this->csize*16)+1+1;
-
- rect(this->x, this->y, width, 2+RGBEditor_DEPTH+2+(this->csize*16)+1+1, fg_color);
-
- fillrect(this->x+1, this->y+1, width-2, 2+RGBEditor_DEPTH+2+(this->csize*16)+1+1-2, bg_color);
-
- hline(this->x, this->y+PalTable_PALY-1, width, fg_color);
-
- if ( width - (RGBEditor_WIDTH*2+4) >= TITLE_LEN*8 )
- {
- int center = (width - TITLE_LEN*8) / 2;
-
- displayf(this->x+center, this->y+2+RGBEditor_DEPTH/2-4, fg_color, bg_color, TITLE);
- }
-
- RGBEditor_Draw(this->rgb[0]);
- RGBEditor_Draw(this->rgb[1]);
-
- for (pal=0; pal<256; pal++)
- {
- xoff = PalTable_PALX + (pal%16) * this->csize;
- yoff = PalTable_PALY + (pal/16) * this->csize;
-
- if ( pal >= colors )
- {
- fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, bg_color);
- draw_diamond(this->x + xoff + this->csize/2 - 1, this->y + yoff + this->csize/2 - 1, fg_color);
- }
-
- else if ( is_reserved(pal) )
- {
- int x1 = this->x + xoff + 1,
- y1 = this->y + yoff + 1,
- x2 = x1 + this->csize - 2,
- y2 = y1 + this->csize - 2;
- fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, bg_color);
- draw_line(x1, y1, x2, y2, fg_color);
- draw_line(x1, y2, x2, y1, fg_color);
- }
- else
- fillrect(this->x + xoff + 1, this->y + yoff + 1, this->csize-1, this->csize-1, pal);
-
- }
-
- if (this->active == 0)
- {
- PalTable__HlPal(this, this->curr[1], -1);
- PalTable__HlPal(this, this->curr[0], fg_color);
- }
- else
- {
- PalTable__HlPal(this, this->curr[0], -1);
- PalTable__HlPal(this, this->curr[1], fg_color);
- }
-
- PalTable__DrawStatus(this, FALSE);
-
- Cursor_Show();
- }
-
-
-
- static BOOLEAN PalTable__SetCurr(PalTable *this, int which, int curr)
- {
- BOOLEAN redraw = (BOOLEAN)((which < 0) ? TRUE : FALSE);
-
- if ( redraw )
- {
- which = this->active;
- curr = this->curr[which];
- }
- else
- if ( curr == this->curr[which] || curr < 0 )
- return (FALSE);
-
- Cursor_Hide();
-
- PalTable__HlPal(this, this->curr[0], bg_color);
- PalTable__HlPal(this, this->curr[1], bg_color);
- PalTable__HlPal(this, this->top, bg_color);
- PalTable__HlPal(this, this->bottom, bg_color);
-
- if ( this->freestyle )
- {
- this->curr[which] = curr;
-
- PalTable__CalcTopBottom(this);
-
- PalTable__HlPal(this, this->top, -1);
- PalTable__HlPal(this, this->bottom, -1);
- PalTable__HlPal(this, this->curr[this->active], fg_color);
-
- RGBEditor_SetRGB(this->rgb[which], this->curr[which], &this->fs_color);
- RGBEditor_Update(this->rgb[which]);
-
- PalTable__UpdateDAC(this);
-
- Cursor_Show();
-
- return (TRUE);
- }
-
- this->curr[which] = curr;
-
- if (this->curr[0] != this->curr[1])
- PalTable__HlPal(this, this->curr[this->active==0?1:0], -1);
- PalTable__HlPal(this, this->curr[this->active], fg_color);
-
- RGBEditor_SetRGB(this->rgb[which], this->curr[which], &(this->pal[this->curr[which]]));
-
- if (redraw)
- {
- int other = (which==0) ? 1 : 0;
- RGBEditor_SetRGB(this->rgb[other], this->curr[other], &(this->pal[this->curr[other]]));
- RGBEditor_Update(this->rgb[0]);
- RGBEditor_Update(this->rgb[1]);
- }
- else
- RGBEditor_Update(this->rgb[which]);
-
- if (this->exclude)
- PalTable__UpdateDAC(this);
-
- Cursor_Show();
-
- this->curr_changed = FALSE;
-
- return(TRUE);
- }
-
-
- static BOOLEAN PalTable__MemoryAlloc(PalTable *this, long size)
- {
- char far *temp;
-
- if (debugflag == 420)
- {
- this->stored_at = NOWHERE;
- return (FALSE); /* can't do it */
- }
- temp = farmemalloc(FAR_RESERVE); /* minimum free space */
-
- if (temp == NULL)
- {
- this->stored_at = NOWHERE;
- return (FALSE); /* can't do it */
- }
-
- this->memory = farmemalloc( size );
-
- farmemfree(temp);
-
- if ( this->memory == NULL )
- {
- this->stored_at = NOWHERE;
- return (FALSE);
- }
- else
- {
- this->stored_at = MEMORY;
- return (TRUE);
- }
- }
-
-
- static void PalTable__SaveRect(PalTable *this)
- {
- char buff[MAX_WIDTH];
- int width = PalTable_PALX + this->csize*16 + 1 + 1,
- depth = PalTable_PALY + this->csize*16 + 1 + 1;
- int yoff;
-
-
- /* first, do any de-allocationg */
-
- switch( this->stored_at )
- {
- case NOWHERE:
- break;
-
- case DISK:
- break;
-
- case MEMORY:
- if (this->memory != NULL)
- farmemfree(this->memory);
- this->memory = NULL;
- break;
- } ;
-
- /* allocate space and store the rect */
-
- if ( PalTable__MemoryAlloc(this, (long)width*depth) )
- {
- char far *ptr = this->memory;
- char far *bufptr = buff; /* MSC needs this indirection to get it right */
-
- Cursor_Hide();
- for (yoff=0; yoff<depth; yoff++)
- {
- getrow(this->x, this->y+yoff, width, buff);
- hline (this->x, this->y+yoff, width, bg_color);
- movedata(FP_SEG(bufptr), FP_OFF(bufptr), FP_SEG(ptr), FP_OFF(ptr), width);
- ptr = (char far *)normalize(ptr+width);
- }
- Cursor_Show();
- }
-
- else /* to disk */
- {
- this->stored_at = DISK;
-
- if ( this->file == NULL )
- {
- this->file = dir_fopen(tempdir,scrnfile, "w+b");
- if (this->file == NULL)
- {
- this->stored_at = NOWHERE;
- buzzer(3);
- return ;
- }
- }
-
- rewind(this->file);
- Cursor_Hide();
- for (yoff=0; yoff<depth; yoff++)
- {
- getrow(this->x, this->y+yoff, width, buff);
- hline (this->x, this->y+yoff, width, bg_color);
- if ( fwrite(buff, width, 1, this->file) != 1 )
- {
- buzzer(3);
- break;
- }
- }
- Cursor_Show();
- }
-
- }
-
-
- static void PalTable__RestoreRect(PalTable *this)
- {
- char buff[MAX_WIDTH];
- int width = PalTable_PALX + this->csize*16 + 1 + 1,
- depth = PalTable_PALY + this->csize*16 + 1 + 1;
- int yoff;
-
- if (this->hidden)
- return;
-
- switch ( this->stored_at )
- {
- case DISK:
- rewind(this->file);
- Cursor_Hide();
- for (yoff=0; yoff<depth; yoff++)
- {
- if ( fread(buff, width, 1, this->file) != 1 )
- {
- buzzer(3);
- break;
- }
- putrow(this->x, this->y+yoff, width, buff);
- }
- Cursor_Show();
- break;
-
- case MEMORY:
- {
- char far *ptr = this->memory;
- char far *bufptr = buff; /* MSC needs this indirection to get it right */
-
- Cursor_Hide();
- for (yoff=0; yoff<depth; yoff++)
- {
- movedata(FP_SEG(ptr), FP_OFF(ptr), FP_SEG(bufptr), FP_OFF(bufptr), width);
- putrow(this->x, this->y+yoff, width, buff);
- ptr = (char far *)normalize(ptr+width);
- }
- Cursor_Show();
- break;
- }
-
- case NOWHERE:
- break;
- } /* switch */
- }
-
-
- static void PalTable__SetPos(PalTable *this, int x, int y)
- {
- int width = PalTable_PALX + this->csize*16 + 1 + 1;
-
- this->x = x;
- this->y = y;
-
- RGBEditor_SetPos(this->rgb[0], x+2, y+2);
- RGBEditor_SetPos(this->rgb[1], x+width-2-RGBEditor_WIDTH, y+2);
- }
-
-
- static void PalTable__SetCSize(PalTable *this, int csize)
- {
- this->csize = csize;
- PalTable__SetPos(this, this->x, this->y);
- }
-
-
- static int PalTable__GetCursorColor(PalTable *this)
- {
- int x = Cursor_GetX(),
- y = Cursor_GetY(),
- size;
- int color = getcolor(x, y);
-
- if ( is_reserved(color) )
- {
- 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) )
- { /* is the cursor over the editor? */
- x -= this->x + PalTable_PALX;
- y -= this->y + PalTable_PALY;
- size = this->csize;
-
- if (x < 0 || y < 0 || x > size*16 || y > size*16)
- return (-1);
-
- if ( x == size*16 )
- --x;
- if ( y == size*16 )
- --y;
-
- return ( (y/size)*16 + x/size );
- }
- else
- return (color);
- }
-
- return (color);
- }
-
-
-
- #define CURS_INC 1
-
- static void PalTable__DoCurs(PalTable *this, int key)
- {
- BOOLEAN done = FALSE;
- BOOLEAN first = TRUE;
- int xoff = 0,
- yoff = 0;
-
- while ( !done )
- {
- switch(key)
- {
- case RIGHT_ARROW_2: xoff += CURS_INC*4; break;
- case RIGHT_ARROW: xoff += CURS_INC; break;
- case LEFT_ARROW_2: xoff -= CURS_INC*4; break;
- case LEFT_ARROW: xoff -= CURS_INC; break;
- case DOWN_ARROW_2: yoff += CURS_INC*4; break;
- case DOWN_ARROW: yoff += CURS_INC; break;
- case UP_ARROW_2: yoff -= CURS_INC*4; break;
- case UP_ARROW: yoff -= CURS_INC; break;
-
- default:
- done = TRUE;
- }
-
- if (!done)
- {
- if (!first)
- getakey(); /* delete key from buffer */
- else
- first = FALSE;
- key = keypressed(); /* peek at the next one... */
- }
- }
-
- Cursor_Move(xoff, yoff);
-
- if (this->auto_select)
- PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
- }
-
-
- #ifdef __TURBOC__
- # pragma argsused
- #endif
- #ifdef __CLINT__
- # pragma argsused
- #endif
-
- static void PalTable__change(RGBEditor *rgb, VOIDPTR info)
- {
- PalTable *this = (PalTable *)info;
- int pnum = this->curr[this->active];
-
- if ( this->freestyle )
- {
- this->fs_color = RGBEditor_GetRGB(rgb);
- PalTable__UpdateDAC(this);
- return ;
- }
-
- if ( !this->curr_changed )
- {
- PalTable__SaveUndoData(this, pnum, pnum);
- this->curr_changed = TRUE;
- }
-
- this->pal[pnum] = RGBEditor_GetRGB(rgb);
-
- if (this->curr[0] == this->curr[1])
- {
- int other = this->active==0 ? 1 : 0;
- PALENTRY color;
-
- color = RGBEditor_GetRGB(this->rgb[this->active]);
- RGBEditor_SetRGB(this->rgb[other], this->curr[other], &color);
-
- Cursor_Hide();
- RGBEditor_Update(this->rgb[other]);
- Cursor_Show();
- }
-
- }
-
-
- static void PalTable__UpdateDAC(PalTable *this)
- {
- if ( this->exclude )
- {
- memset(dacbox, 0, 256*3);
- if (this->exclude == 1)
- {
- int a = this->curr[this->active];
- memmove(dacbox[a], &this->pal[a], 3);
- }
- else
- {
- int a = this->curr[0],
- b = this->curr[1];
-
- if (a>b)
- {
- int t=a;
- a=b;
- b=t;
- }
-
- memmove(dacbox[a], &this->pal[a], 3*(1+(b-a)));
- }
- }
- else
- {
- memmove(dacbox[0], this->pal, 3*colors);
-
- if ( this->freestyle )
- PalTable__PutBand(this, (PALENTRY *)dacbox); /* apply band to dacbox */
- }
-
- if ( !this->hidden )
- {
- if (inverse)
- {
- memset(dacbox[fg_color], 0, 3); /* dacbox[fg] = (0,0,0) */
- memset(dacbox[bg_color], 48, 3); /* dacbox[bg] = (48,48,48) */
- }
- else
- {
- memset(dacbox[bg_color], 0, 3); /* dacbox[bg] = (0,0,0) */
- memset(dacbox[fg_color], 48, 3); /* dacbox[fg] = (48,48,48) */
- }
- }
-
- spindac(0,1);
- }
-
-
- static void PalTable__Rotate(PalTable *this, int dir, int lo, int hi)
- {
-
- rotatepal(this->pal, dir, lo, hi);
-
- Cursor_Hide();
-
- /* update the DAC. */
-
- PalTable__UpdateDAC(this);
-
- /* update the editors. */
-
- RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
- RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
- RGBEditor_Update(this->rgb[0]);
- RGBEditor_Update(this->rgb[1]);
-
- Cursor_Show();
- }
-
-
- static void PalTable__other_key(int key, RGBEditor *rgb, VOIDPTR info)
- {
- PalTable *this = (PalTable *)info;
-
- switch(key)
- {
- case '\\': /* move/resize */
- {
- if (this->hidden)
- break; /* cannot move a hidden pal */
- Cursor_Hide();
- PalTable__RestoreRect(this);
- MoveBox_SetPos(this->movebox, this->x, this->y);
- MoveBox_SetCSize(this->movebox, this->csize);
- if ( MoveBox_Process(this->movebox) )
- {
- if ( MoveBox_ShouldHide(this->movebox) )
- PalTable_SetHidden(this, TRUE);
- else if ( MoveBox_Moved(this->movebox) )
- {
- PalTable__SetPos(this, MoveBox_X(this->movebox), MoveBox_Y(this->movebox));
- PalTable__SetCSize(this, MoveBox_CSize(this->movebox));
- PalTable__SaveRect(this);
- }
- }
- PalTable__Draw(this);
- Cursor_Show();
-
- RGBEditor_SetDone(this->rgb[this->active], TRUE);
-
- if (this->auto_select)
- PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
- break;
- }
-
- case 'Y': /* exclude range */
- case 'y':
- if ( this->exclude==2 )
- this->exclude = 0;
- else
- this->exclude = 2;
- PalTable__UpdateDAC(this);
- PalTable__DrawStatus(this, FALSE);
- break;
-
- case 'X':
- case 'x': /* exclude current entry */
- if ( this->exclude==1 )
- this->exclude = 0;
- else
- this->exclude = 1;
- PalTable__UpdateDAC(this);
- PalTable__DrawStatus(this, FALSE);
- break;
-
- case RIGHT_ARROW:
- case LEFT_ARROW:
- case UP_ARROW:
- case DOWN_ARROW:
- case RIGHT_ARROW_2:
- case LEFT_ARROW_2:
- case UP_ARROW_2:
- case DOWN_ARROW_2:
- PalTable__DoCurs(this, key);
- break;
-
- case ESC:
- this->done = TRUE;
- RGBEditor_SetDone(rgb, TRUE);
- break;
-
- case ' ': /* select the other palette register */
- this->active = (this->active==0) ? 1 : 0;
- if (this->auto_select)
- PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
- else
- PalTable__SetCurr(this, -1, 0);
-
- if (this->exclude || this->freestyle)
- PalTable__UpdateDAC(this);
-
- RGBEditor_SetDone(rgb, TRUE);
- break;
-
- case ENTER: /* set register to color under cursor. useful when not */
- case ENTER_2: /* in auto_select mode */
-
- if ( this->freestyle )
- {
- PalTable__SaveUndoData(this, this->bottom, this->top);
- PalTable__PutBand(this, this->pal);
- }
-
- PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
-
- if (this->exclude || this->freestyle )
- PalTable__UpdateDAC(this);
-
- RGBEditor_SetDone(rgb, TRUE);
- break;
-
- case 'D': /* copy (Duplicate?) color in inactive to color in active */
- case 'd':
- {
- int a = this->active,
- b = (a==0) ? 1 : 0;
- PALENTRY t;
-
- t = RGBEditor_GetRGB(this->rgb[b]);
- Cursor_Hide();
-
- RGBEditor_SetRGB(this->rgb[a], this->curr[a], &t);
- RGBEditor_Update(this->rgb[a]);
- PalTable__change(this->rgb[a], this);
- PalTable__UpdateDAC(this);
-
- Cursor_Show();
- break;
- }
-
- case '=': /* create a shade range between the two entries */
- {
- int a = this->curr[0],
- b = this->curr[1];
-
- if (a > b)
- {
- int t = a;
- a = b;
- b = t;
- }
-
- PalTable__SaveUndoData(this, a, b);
-
- if (a != b)
- {
- mkpalrange(&this->pal[a], &this->pal[b], &this->pal[a], b-a, 1);
- PalTable__UpdateDAC(this);
- }
-
- break;
- }
-
- case '!': /* swap r<->g */
- {
- int a = this->curr[0],
- b = this->curr[1];
-
- if (a > b)
- {
- int t = a;
- a = b;
- b = t;
- }
-
- PalTable__SaveUndoData(this, a, b);
-
- if (a != b)
- {
- rotcolrg(&this->pal[a], b-a);
- PalTable__UpdateDAC(this);
- }
-
-
- break;
- }
-
- case '@': /* swap g<->b */
- {
- int a = this->curr[0],
- b = this->curr[1];
-
- if (a > b)
- {
- int t = a;
- a = b;
- b = t;
- }
-
- PalTable__SaveUndoData(this, a, b);
-
- if (a != b)
- {
- rotcolgb(&this->pal[a], b-a);
- PalTable__UpdateDAC(this);
- }
-
- break;
- }
-
- case '#': /* swap r<->b */
- {
- int a = this->curr[0],
- b = this->curr[1];
-
- if (a > b)
- {
- int t = a;
- a = b;
- b = t;
- }
-
- PalTable__SaveUndoData(this, a, b);
-
- if (a != b)
- {
- rotcolbr(&this->pal[a], b-a);
- PalTable__UpdateDAC(this);
- }
-
- break;
- }
-
-
- case 'T':
- case 't': /* s(T)ripe mode */
- {
- int key;
-
- Cursor_Hide();
- PalTable__DrawStatus(this, TRUE);
- key = getakeynohelp();
- PalTable__DrawStatus(this, FALSE);
- Cursor_Show();
-
- if (key >= '1' && key <= '9')
- {
- int a = this->curr[0],
- b = this->curr[1];
-
- if (a > b)
- {
- int t = a;
- a = b;
- b = t;
- }
-
- PalTable__SaveUndoData(this, a, b);
-
- if (a != b)
- {
- mkpalrange(&this->pal[a], &this->pal[b], &this->pal[a], b-a, key-'0');
- PalTable__UpdateDAC(this);
- }
- }
-
- break;
- }
-
- case 'M': /* set gamma */
- case 'm':
- {
- static FCODE o_msg[] = {"Enter gamma value"};
- char msg[sizeof(o_msg)];
- int i;
- char buf[20];
- far_strcpy(msg,o_msg);
- sprintf(buf,"%.3f",1./gamma_val);
- stackscreen();
- i = field_prompt(0,msg,NULL,buf,20,NULL);
- unstackscreen();
- if (i != -1) {
- sscanf(buf,"%f",&gamma_val);
- if (gamma_val==0) {
- gamma_val = (float)0.0000000001;
- }
- gamma_val = (float)(1./gamma_val);
- }
- }
- break;
- case 'A': /* toggle auto-select mode */
- case 'a':
- this->auto_select = (BOOLEAN)((this->auto_select) ? FALSE : TRUE);
- if (this->auto_select)
- {
- PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
- if (this->exclude)
- PalTable__UpdateDAC(this);
- }
- PalTable__DrawStatus(this, FALSE);
- break;
-
- case 'H':
- case 'h': /* toggle hide/display of palette editor */
- Cursor_Hide();
- PalTable_Hide(this, rgb, (BOOLEAN)((this->hidden) ? FALSE : TRUE));
- Cursor_Show();
- break;
-
- case '.': /* rotate once */
- case ',':
- {
- int dir = (key=='.') ? 1 : -1;
-
- PalTable__SaveUndoRotate(this, dir, rotate_lo, rotate_hi);
- PalTable__Rotate(this, dir, rotate_lo, rotate_hi);
- break;
- }
-
- case '>': /* continuous rotation (until a key is pressed) */
- case '<':
- {
- int dir;
- long tick;
- int diff = 0;
-
- Cursor_Hide();
-
- if ( !this->hidden )
- {
- RGBEditor_BlankSampleBox(this->rgb[0]);
- RGBEditor_BlankSampleBox(this->rgb[1]);
- RGBEditor_SetHidden(this->rgb[0], TRUE);
- RGBEditor_SetHidden(this->rgb[1], TRUE);
- }
-
- do
- {
- dir = (key=='>') ? 1 : -1;
-
- while ( !keypressed() )
- {
- tick = readticker();
- PalTable__Rotate(this, dir, rotate_lo, rotate_hi);
- diff += dir;
- while (readticker() == tick) ; /* wait until a tick passes */
- }
-
- key = getakey();
- }
- while (key=='<' || key=='>');
-
- if ( !this->hidden )
- {
- RGBEditor_SetHidden(this->rgb[0], FALSE);
- RGBEditor_SetHidden(this->rgb[1], FALSE);
- RGBEditor_Update(this->rgb[0]);
- RGBEditor_Update(this->rgb[1]);
- }
-
- if ( diff != 0 )
- PalTable__SaveUndoRotate(this, diff, rotate_lo, rotate_hi);
-
- Cursor_Show();
- break;
- }
-
- case 'I': /* invert the fg & bg colors */
- case 'i':
- inverse = (BOOLEAN)!inverse;
- PalTable__UpdateDAC(this);
- break;
-
- case 'V':
- case 'v': /* set the reserved colors to the editor colors */
- if ( this->curr[0] >= colors || this->curr[1] >= colors ||
- this->curr[0] == this->curr[1] )
- {
- buzzer(2);
- break;
- }
-
- fg_color = (BYTE)this->curr[0];
- bg_color = (BYTE)this->curr[1];
-
- if ( !this->hidden )
- {
- Cursor_Hide();
- PalTable__UpdateDAC(this);
- PalTable__Draw(this);
- Cursor_Show();
- }
-
- RGBEditor_SetDone(this->rgb[this->active], TRUE);
- break;
-
- case 'O': /* set rotate_lo and rotate_hi to editors */
- case 'o':
- if (this->curr[0] > this->curr[1])
- {
- rotate_lo = this->curr[1];
- rotate_hi = this->curr[0];
- }
- else
- {
- rotate_lo = this->curr[0];
- rotate_hi = this->curr[1];
- }
- break;
-
- case F2: /* restore a palette */
- case F3:
- case F4:
- case F5:
- case F6:
- case F7:
- case F8:
- case F9:
- {
- int which = key - F2;
-
- if ( this->save_pal[which] != NULL )
- {
- struct SREGS seg;
-
- Cursor_Hide();
-
- PalTable__SaveUndoData(this, 0, 255);
-
- segread(&seg);
- movedata(FP_SEG(this->save_pal[which]), FP_OFF(this->save_pal[which]),
- seg.ds, (USEGTYPE)(this->pal), 256*3);
-
- PalTable__UpdateDAC(this);
-
- PalTable__SetCurr(this, -1, 0);
- Cursor_Show();
- RGBEditor_SetDone(this->rgb[this->active], TRUE);
- }
- else
- buzzer(3); /* error buzz */
- break;
- }
-
- case SF2: /* save a palette */
- case SF3:
- case SF4:
- case SF5:
- case SF6:
- case SF7:
- case SF8:
- case SF9:
- {
- int which = key - SF2;
-
- if ( this->save_pal[which] != NULL )
- {
- struct SREGS seg;
-
- segread(&seg);
- movedata(seg.ds, (USEGTYPE)(this->pal), FP_SEG(this->save_pal[which]),
- FP_OFF(this->save_pal[which]), 256*3);
- }
- else
- buzzer(3); /* oops! short on memory! */
- break;
- }
-
- case 'L': /* load a .map palette */
- case 'l':
- {
- PalTable__SaveUndoData(this, 0, 255);
-
- load_palette();
- #ifndef XFRACT
- getpalrange(0, colors, this->pal);
- #else
- getpalrange(0, 256, this->pal);
- #endif
- PalTable__UpdateDAC(this);
- RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
- RGBEditor_Update(this->rgb[0]);
- RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
- RGBEditor_Update(this->rgb[1]);
- break;
- }
-
- case 'S': /* save a .map palette */
- case 's':
- {
- #ifndef XFRACT
- setpalrange(0, colors, this->pal);
- #else
- setpalrange(0, 256, this->pal);
- #endif
- save_palette();
- PalTable__UpdateDAC(this);
- break;
- }
-
- case 'C': /* color cycling sub-mode */
- case 'c':
- {
- BOOLEAN oldhidden = (BOOLEAN)this->hidden;
-
- PalTable__SaveUndoData(this, 0, 255);
-
- Cursor_Hide();
- if ( !oldhidden )
- PalTable_Hide(this, rgb, TRUE);
- setpalrange(0, colors, this->pal);
- rotate(0);
- getpalrange(0, colors, this->pal);
- PalTable__UpdateDAC(this);
- if ( !oldhidden )
- {
- RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
- RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
- PalTable_Hide(this, rgb, FALSE);
- }
- Cursor_Show();
- break;
- }
-
- case 'F':
- case 'f': /* toggle freestyle palette edit mode */
- this->freestyle= (BOOLEAN)((this->freestyle) ? FALSE :TRUE);
-
- PalTable__SetCurr(this, -1, 0);
-
- if ( !this->freestyle ) /* if turning off... */
- PalTable__UpdateDAC(this);
-
- PalTable__DrawStatus(this, FALSE);
- break;
-
- case CTL_DEL: /* rt plus down */
- if (this->bandwidth >0 )
- this->bandwidth --;
- else
- this->bandwidth=0;
- PalTable__SetCurr(this, -1, 0);
- break;
-
- case CTL_INSERT: /* rt plus up */
- if (this->bandwidth <255 )
- this->bandwidth ++;
- else
- this->bandwidth = 255;
- PalTable__SetCurr(this, -1, 0);
- break;
-
- case 'W': /* convert to greyscale */
- case 'w':
- {
- switch ( this->exclude )
- {
- case 0: /* normal mode. convert all colors to grey scale */
- PalTable__SaveUndoData(this, 0, 255);
- palrangetogrey(this->pal, 0, 256);
- break;
-
- case 1: /* 'x' mode. convert current color to grey scale. */
- PalTable__SaveUndoData(this, this->curr[this->active], this->curr[this->active]);
- palrangetogrey(this->pal, this->curr[this->active], 1);
- break;
-
- case 2: /* 'y' mode. convert range between editors to grey. */
- {
- int a = this->curr[0],
- b = this->curr[1];
-
- if (a > b)
- {
- int t = a;
- a = b;
- b = t;
- }
-
- PalTable__SaveUndoData(this, a, b);
- palrangetogrey(this->pal, a, 1+(b-a));
- break;
- }
- }
-
- PalTable__UpdateDAC(this);
- RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
- RGBEditor_Update(this->rgb[0]);
- RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
- RGBEditor_Update(this->rgb[1]);
- break;
- }
-
- case 'N': /* convert to negative color */
- case 'n':
- {
- switch ( this->exclude )
- {
- case 0: /* normal mode. convert all colors to grey scale */
- PalTable__SaveUndoData(this, 0, 255);
- palrangetonegative(this->pal, 0, 256);
- break;
-
- case 1: /* 'x' mode. convert current color to grey scale. */
- PalTable__SaveUndoData(this, this->curr[this->active], this->curr[this->active]);
- palrangetonegative(this->pal, this->curr[this->active], 1);
- break;
-
- case 2: /* 'y' mode. convert range between editors to grey. */
- {
- int a = this->curr[0],
- b = this->curr[1];
-
- if (a > b)
- {
- int t = a;
- a = b;
- b = t;
- }
-
- PalTable__SaveUndoData(this, a, b);
- palrangetonegative(this->pal, a, 1+(b-a));
- break;
- }
- }
-
- PalTable__UpdateDAC(this);
- RGBEditor_SetRGB(this->rgb[0], this->curr[0], &(this->pal[this->curr[0]]));
- RGBEditor_Update(this->rgb[0]);
- RGBEditor_SetRGB(this->rgb[1], this->curr[1], &(this->pal[this->curr[1]]));
- RGBEditor_Update(this->rgb[1]);
- break;
- }
-
- case 'U': /* Undo */
- case 'u':
- PalTable__Undo(this);
- break;
-
- case 'e': /* Redo */
- case 'E':
- PalTable__Redo(this);
- break;
-
- } /* switch */
- }
-
-
- static void PalTable__MkDefaultPalettes(PalTable *this) /* creates default Fkey palettes */
- {
- PALENTRY black,
- white;
- PALENTRY temp[256];
- int ctr;
- struct SREGS seg;
-
- black.red = black.green = black.blue = 0;
- white.red = white.green = white.blue = 63;
- mkpalrange(&black, &white, temp, 256, 1); /* boring! */
-
- segread(&seg);
-
- for (ctr=0; ctr<8; ctr++) /* copy temp into all fkey saves */
- movedata(seg.ss, (USEGTYPE)(temp), FP_SEG(this->save_pal[ctr]),
- FP_OFF(this->save_pal[ctr]), 256*3);
- }
-
-
-
- static PalTable *PalTable_Construct(void)
- {
- PalTable *this = new(PalTable);
- int csize;
- int ctr;
- PALENTRY far *mem_block;
- void far *temp;
-
- temp = farmemalloc(FAR_RESERVE);
-
- if ( temp != NULL )
- {
- mem_block = (PALENTRY far *)farmemalloc(256L*3 * 8);
-
- if ( mem_block == NULL )
- {
- for (ctr=0; ctr<8; ctr++)
- this->save_pal[ctr] = NULL;
- }
- else
- {
- for (ctr=0; ctr<8; ctr++)
- this->save_pal[ctr] = mem_block + (256*ctr);
-
- PalTable__MkDefaultPalettes(this);
- }
- farmemfree(temp);
- }
-
- this->rgb[0] = RGBEditor_Construct(0, 0, PalTable__other_key,
- PalTable__change, this);
- this->rgb[1] = RGBEditor_Construct(0, 0, PalTable__other_key,
- PalTable__change, this);
-
- this->movebox = MoveBox_Construct(0,0,0, PalTable_PALX+1, PalTable_PALY+1);
-
- this->active = 0;
- this->curr[0] = 1;
- this->curr[1] = 1;
- this->auto_select = TRUE;
- this->exclude = FALSE;
- this->hidden = FALSE;
- this->stored_at = NOWHERE;
- this->file = NULL;
- this->memory = NULL;
-
- this->fs_color.red = 42;
- this->fs_color.green = 42;
- this->fs_color.blue = 42;
- this->freestyle = FALSE;
- this->bandwidth = 15;
- this->top = 255;
- this->bottom = 0 ;
-
- this->undo_file = dir_fopen(tempdir,undofile, "w+b");
- this->curr_changed = FALSE;
- this->num_redo = 0;
-
- RGBEditor_SetRGB(this->rgb[0], this->curr[0], &this->pal[this->curr[0]]);
- RGBEditor_SetRGB(this->rgb[1], this->curr[1], &this->pal[this->curr[0]]);
-
- PalTable__SetPos(this, 0, 0);
-
- csize = ( (sydots-(PalTable_PALY+1+1)) / 2 ) / 16;
- if (csize<CSIZE_MIN)
- csize = CSIZE_MIN;
- PalTable__SetCSize(this, csize);
-
- return(this);
- }
-
-
- static void PalTable_SetHidden(PalTable *this, BOOLEAN hidden)
- {
- this->hidden = hidden;
- RGBEditor_SetHidden(this->rgb[0], hidden);
- RGBEditor_SetHidden(this->rgb[1], hidden);
- PalTable__UpdateDAC(this);
- }
-
-
-
- static void PalTable_Hide(PalTable *this, RGBEditor *rgb, BOOLEAN hidden)
- {
- if (hidden)
- {
- PalTable__RestoreRect(this);
- PalTable_SetHidden(this, TRUE);
- reserve_colors = FALSE;
- if (this->auto_select)
- PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
- }
- else
- {
- PalTable_SetHidden(this, FALSE);
- reserve_colors = TRUE;
- if (this->stored_at == NOWHERE) /* do we need to save screen? */
- PalTable__SaveRect(this);
- PalTable__Draw(this);
- if (this->auto_select)
- PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
- RGBEditor_SetDone(rgb, TRUE);
- }
- }
-
-
- static void PalTable_Destroy(PalTable *this)
- {
-
- if (this->file != NULL)
- {
- fclose(this->file);
- dir_remove(tempdir,scrnfile);
- }
-
- if (this->undo_file != NULL)
- {
- fclose(this->undo_file);
- dir_remove(tempdir,undofile);
- }
-
- if (this->memory != NULL)
- farmemfree(this->memory);
-
- if (this->save_pal[0] != NULL)
- farmemfree((BYTE far *)this->save_pal[0]);
-
- RGBEditor_Destroy(this->rgb[0]);
- RGBEditor_Destroy(this->rgb[1]);
- MoveBox_Destroy(this->movebox);
- delete(this);
- }
-
-
- static void PalTable_Process(PalTable *this)
- {
- int ctr;
-
- getpalrange(0, colors, this->pal);
-
- /* Make sure all palette entries are 0-63 */
-
- for(ctr=0; ctr<768; ctr++)
- ((char *)this->pal)[ctr] &= 63;
-
- PalTable__UpdateDAC(this);
-
- RGBEditor_SetRGB(this->rgb[0], this->curr[0], &this->pal[this->curr[0]]);
- RGBEditor_SetRGB(this->rgb[1], this->curr[1], &this->pal[this->curr[0]]);
-
- if (!this->hidden)
- {
- MoveBox_SetPos(this->movebox, this->x, this->y);
- MoveBox_SetCSize(this->movebox, this->csize);
- if ( !MoveBox_Process(this->movebox) )
- {
- setpalrange(0, colors, this->pal);
- return ;
- }
-
- PalTable__SetPos(this, MoveBox_X(this->movebox), MoveBox_Y(this->movebox));
- PalTable__SetCSize(this, MoveBox_CSize(this->movebox));
-
- if ( MoveBox_ShouldHide(this->movebox) )
- {
- PalTable_SetHidden(this, TRUE);
- reserve_colors = FALSE; /* <EAN> */
- }
- else
- {
- reserve_colors = TRUE; /* <EAN> */
- PalTable__SaveRect(this);
- PalTable__Draw(this);
- }
- }
-
- PalTable__SetCurr(this, this->active, PalTable__GetCursorColor(this));
- PalTable__SetCurr(this, (this->active==1)?0:1, PalTable__GetCursorColor(this));
- Cursor_Show();
-
- this->done = FALSE;
-
- while ( !this->done )
- RGBEditor_Edit(this->rgb[this->active]);
-
- Cursor_Hide();
- PalTable__RestoreRect(this);
- setpalrange(0, colors, this->pal);
- }
-
-
- /*
- * interface to FRACTINT
- */
-
-
-
- void EditPalette(void) /* called by fractint */
- {
- int oldlookatmouse = lookatmouse;
- int oldsxoffs = sxoffs;
- int oldsyoffs = syoffs;
- PalTable *pt;
-
- mem_init(strlocn, 10*1024);
-
- if ( (font8x8 = findfont(0)) == NULL )
- return ;
-
- plot = putcolor;
-
- line_buff = newx(max(sxdots,sydots));
-
- lookatmouse = 3;
- sxoffs = syoffs = 0;
-
- reserve_colors = TRUE;
- inverse = FALSE;
- fg_color = (BYTE)(255%colors);
- bg_color = (BYTE)(fg_color-1);
-
- Cursor_Construct();
- pt = PalTable_Construct();
- PalTable_Process(pt);
- PalTable_Destroy(pt);
- Cursor_Destroy();
-
- lookatmouse = oldlookatmouse;
- sxoffs = oldsxoffs;
- syoffs = oldsyoffs;
- delete(line_buff);
- }
-
-