📄 editpal.c
字号:
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 = CEditor_GetVal(this->color[0]);
pal.green = CEditor_GetVal(this->color[1]);
pal.blue = 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 - */
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;
}
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
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -