📄 editpal.c
字号:
/*
* editpal.c
*
* Edits VGA 256-color palettes.
*
* This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
*
*
* 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)
#ifdef XFRACT
int editpal_cursor = 0;
#endif
/*
* Stuff from fractint
*/
extern BYTE dacbox[256][3]; /* DAC spindac() will use */
extern int sxdots; /* width of physical screen */
extern int sydots; /* depth of physical screen */
extern int sxoffs; /* start of logical screen */
extern int syoffs; /* start of logical screen */
extern int lookatmouse; /* mouse mode for getakey(), etc */
extern int strlocn[]; /* 10K buffer to store classes in */
extern int colors; /* # colors avail. */
extern int color_bright; /* brightest color in palette */
extern int color_dark; /* darkest color in palette */
extern int color_medium; /* nearest to medbright gray color */
extern int rotate_lo, rotate_hi;
extern int debugflag;
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.0;
/*
* Interface to FRACTINT's graphics stuff
*/
static void setpal(int pal, int r, int g, int b)
{
dacbox[pal][0] = r;
dacbox[pal][1] = g;
dacbox[pal][2] = 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++ = 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] = (t&0x80) ? (unsigned)fg : (unsigned)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 = (p1->red == p2->red ) ? p1->red :
(int) p1->red + (int) ( rm * curr );
pal[curr].green = (p1->green == p2->green) ? p1->green :
(int) p1->green + (int) ( gm * curr );
pal[curr].blue = (p1->blue == p2->blue ) ? p1->blue :
(int) p1->blue + (int) ( bm * curr );
}
else
{
pal[curr].red = (p1->red == p2->red ) ? p1->red :
(int) p1->red + pow(curr/(double)(num-1),gamma_val)*num*rm;
pal[curr].green = (p1->green == p2->green) ? p1->green :
(int) p1->green + pow(curr/(double)(num-1),gamma_val)*num*gm;
pal[curr].blue = (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 = 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 = 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 = 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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -