home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
375.lha
/
HAM-E_DEV_PACKAGE
/
hame.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-02
|
58KB
|
1,971 lines
/*
* source file - "hame.c" - for public release
* Written by Ben Williams, AA7AS - January thru April 1990
* This source code is released into the public domain.
* Release 1 of example code: April 19th, 1990
*
* This file contains C code that is for handling the HAM-E mode screens.
*
* The HAM-E is a device that is scheduled to become available in June 1990
* from:
* Black Belt Systems
* 398 Johnson Road
* Glasgow, MT, USA
* 59230
*
* US Sales: (800) TK-AMIGA
* International Sales: (406) 367-5513
* Technical Support: (406) 367-5509
* G3 Office FAX: (406) 367-AFAX
*
* This source code should be freely used to develop your own routines
* in any language that work in conjunction with the HAM-E device.
* That is the entire intention of publishing this source.
*
* Please note that the Save IFF C source was originally written by
* Matt Dillon; only small changes were done to this at Black Belt to
* make it work in this context. Essentially, we're saving 640x200 or
* 640x400 standard IFF images. Because Matt's source uses functions
* from his personal library of functions, to compile this you need to
* link using "my.lib" which has been included in this archive. Only
* for the IFF code do you need to link with this, so if you're using
* other source and not the IFF source, you do NOT need to link in my.lib
* at all.
*
* This source was written to compile and run under Lattice C v5.04; It
* was not written to conform to MANX C at all. We do not use MANX C
* at Black Belt and so cannot answer questions as to compatability
* issues. In general, we're compiling this way:
*
* lc -v -d -b0 -ohame.o - hame
*
* and linking this way:
*
* blink WITH hame_list LIBRARY lib:lcm.lib+lib:lcnb_S.lib+
* lib:amiga.lib+lib:my.lib TO 'OutName' MAP nil: VERBOSE NODEBUG
*
* Where the file hame_list contains the following:
*
* lib:c.o
* hame.o
* iff.o
*
* If you have specific questions about the source code, call Black
* Belt Systems technical support line and we will assist you as best
* we can.
*
* Samples of program use as written:
*
* 'hame -o -c' Generates color diagram
* 'hame -o -s' Generates multiple mode sample image
* 'hame -o -c -i ram:test' Generates color diagram, saves iff to ram:test
* 'hame ?' Lists command switches
* 'hame -o -l -x 320 -y 400 -n df0:newtek' Shows 320x400 B&W NewTek IP file
* 'hame -o -x 320 -y 200 -r (address) -g (address) -b (address)'
* Generates picture from buffers located
* at these addresses - expects 6 bits/byte
* right (lsb) justified. Uses 'REG' mode.
* 'hame -o -h -x 320 -y 200 -r (address) -g (address) -b (address)'
* Generates picture from buffers located
* at these addresses - expects 6 bits/byte
* right (lsb) justified. Uses 'HAM-E' mode.
* 'hame -o -c -d 500' Generates color diagram, waits 10 seconds
*
* You will note that all of the above examples use the '-o' switch. This
* causes the software to write to the 640 resolution screen on ODD pixel
* boundries. This is currently the way that the HAM-E expects to find it's
* data. We may change this - make sure that your rendering software can
* cope with it. If the data is not located on the correct boundry, then
* the image will NOT render in the new modes. Contact Black Belt Systems
* technical support in June for the final decision on odd/even pixel
* rendering.
*
*/
/*
*
* Includes:
*
*/
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <stdio.h>
#include <fcntl.h>
#include <exec/types.h> /* all this exec stuff is so I can find MemList */
#include <exec/ports.h>
#include <exec/memory.h>
#include <exec/io.h>
#include <exec/tasks.h>
#include <exec/lists.h>
#include <exec/nodes.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <intuition/preferences.h>
#include <rexx/storage.h>
#include <intuition/intuition.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>
/*
*
* Defines:
*
*/
/* program error codes: */
/* 0 - program is happy */
#define HAPPY 0
/* 1 - program happy, but suicidal - user probably asked for help */
#define DIE_QUIETLY 1
/* 2-20 program warnings */
/* 21-39 program failure */
#define XDIM_NOGOOD 21
#define YDIM_NOGOOD 22
#define RBUF_NOGOOD 23
#define GBUF_NOGOOD 24
#define BBUF_NOGOOD 25
#define DLY_NOGOOD 26
#define UNKNOWN_OPT 27
#define SHIFT_NOGOOD 28
#define XOFF_NOGOOD 29
#define YOFF_NOGOOD 30
#define IP_NOGOOD 31
#define IF_NOGOOD 32
#define NO_PARAMS 33
/* 40... system problem aborts */
#define NO_INTUILIB 40
#define NO_GFXLIB 41
#define NO_EXECLIB 42
#define NO_ICONLIB 43
#define NO_SCREEN 44
/*
*
* Macros:
*
*/
/*
*
* External Casts:
*
*/
struct Library *OpenLibrary();
struct IntuiMessage *GetMsg();
struct Window *OpenWindow();
struct Screen *OpenScreen();
/*
* External definitions:
*/
extern struct WBStartup *WBenchMsg;
/*
* Local structure defs
*/
struct Problems
{
unsigned char ProbID;
char *ProbText;
};
/*
* Globals:
*/
struct Problems our_problem[] =
{
NO_EXECLIB, "exec.library not found",
NO_SCREEN, "Unable to open screen",
NO_GFXLIB, "graphics.library not found",
NO_ICONLIB, "icon.library not found",
NO_INTUILIB,"intuition.library not found",
UNKNOWN_OPT,"Unknown Option",
DLY_NOGOOD, "delay time invalid",
XDIM_NOGOOD,"x dimension no good",
YDIM_NOGOOD,"y dimension no good",
RBUF_NOGOOD,"red buffer address no good",
GBUF_NOGOOD,"green buffer address no good",
BBUF_NOGOOD,"blue buffer address no good",
XOFF_NOGOOD,"X offset no good",
YOFF_NOGOOD,"Y offset no good",
IF_NOGOOD, "IFF Filename no good",
NO_PARAMS, "no parameters - use 'hame ?' for info",
0,0 /* end of table of error #/strings */
};
unsigned char from_cli;
struct Library *IntuitionBase;
struct Library *GfxBase;
struct Library *IconBase;
struct Library *ExecBase;
struct Window *win; /* power windows sample window */
int we_ownit;
unsigned short rdm;
int delay_time,hidden,sample,ham_reg,lacer,luma_mode,shifter,chroma,get_ip;
short write_odd,even_steven,iff_flag;
int xdim,ydim,x_offset,y_offset;
unsigned char *red,*green,*blue;
struct Screen *scr;
char ip_file[200];
char iff_file[200];
static struct NewScreen NewScreenStructure = {
0,0,
640,200,
4,
0,1,
HIRES,
CUSTOMSCREEN,
NULL,
"HAM-E 256 mode",
NULL,
NULL
};
unsigned char *fp0,*fp1,*fp2,*fp3; /* bitplane pointers - fast ones. */
/* pattern of bits within a byte to be used as ~masks and OR sources. */
unsigned char bitpat[] =
{
128,64,32,16,8,4,2,1,
};
/* register mode cookie */
unsigned char ham_cookie[] =
{
0xA2,0xF5,0x84,0xDC,
0x6D,0xB0,0x7F,0x18
};
/* ham mode cookie */
unsigned char reg_cookie[] =
{
0xA2,0xF5,0x84,0xDC,
0x6D,0xB0,0x7F,0x14
};
/* format is: string matching option, string describing option */
char *opts[] =
{
"?", "' ...for info",
"h", "' ...for info",
"help", "' ...for info",
"-x", " [dimension]' ...set X dimension",
"-y", " [dimension]' ...set Y dimension",
"-r", " [red buff pointer]' ...hexidecimal address of data buffer",
"-g", " [green buff pointer]' ...hexidecimal address of data buffer",
"-b", " [blue buff pointer]' ...hexidecimal address of data buffer",
"-o", "' ...write starting at ODD pixels instead of even",
"-d", " [jiffies]' ... delay time for test screen to persist",
"-v", "' ...hide view while creating",
"-s", "' ...generate sample screen",
"-h", "' ...create HAM'ed image",
"-p", "' ...create Palette REG image",
"-l", "' ...luma mode",
"-m", " [shift]' ...multiply grey level (shift left N bits)",
"-xo", " [offset]' ...enter x offset into luma buffer",
"-yo", " [offset]' ...enter Y offset into luma buffer",
"-c", " ...chromasticity diagram",
"-n", " [filename]' ...read NewTek ip file as B&W",
"-e", "' ... use EVEN palette in -s sample screen",
"-i", " [filename]' ... save IFF file from generated image",
0,0
};
int do_help();
int do_xdim();
int do_ydim();
int do_rbuf();
int do_gbuf();
int do_bbuf();
int do_wodd();
int do_dt();
int do_hide();
int do_sample();
int do_ham();
int do_reg();
int do_luma();
int do_shift();
int do_xo();
int do_yo();
int do_chroma();
int do_ip();
int do_even();
int do_iff();
/* refer to the "opts" table for corresponding CLI/shell options */
int (*opt_name[])() =
{
do_help,
do_help,
do_help,
do_xdim,
do_ydim,
do_rbuf,
do_gbuf,
do_bbuf,
do_wodd,
do_dt,
do_hide,
do_sample,
do_ham,
do_reg,
do_luma,
do_shift,
do_xo,
do_yo,
do_chroma,
do_ip,
do_even,
do_iff,
0
};
/*
* Code (finally!) :^)
*/
/*
* The "do_xxxxx()" proceedures are called when a command line
* parameter is encountered. They parse the line, setup variables
* accordingly, and return to the CLI handler. None of them are
* directly involved with handling the HAM-E device; only in
* program initialization.
*/
void safe_line(ptr)
char *ptr;
{
if (from_cli)
{
printf("%s\n",ptr);
}
}
rdmgen() /* easy, fast pseudo-rdm number generator (16k sequence) */
{
register unsigned short foo;
foo = rdm;
foo <<= 2;
rdm += foo;
return(rdm >> 8);
}
/* parameter handling... */
int do_even(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
even_steven=1;
return(0);
}
int do_chroma(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
chroma=1;
return(0);
}
int do_wodd(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
write_odd=1;
return(0);
}
int do_luma(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
luma_mode=1;
return(0);
}
int do_sample(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
sample=1;
return(0);
}
int do_ham(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
ham_reg=1;
return(0);
}
int do_reg(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
ham_reg=0;
return(0);
}
/* parameter sucking... */
int do_hide(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
hidden=1;
return(0);
}
int do_iff(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(IF_NOGOOD);
}
strcpy(&iff_file[0],argv[*index_ptr++]); /* get incoming parameter */
iff_flag=1;
return(0); /* we're all happy here... :^) */
}
int do_ip(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(IP_NOGOOD);
}
strcpy(&ip_file[0],argv[*index_ptr++]); /* get incoming parameter */
get_ip=1;
return(0); /* we're all happy here... :^) */
}
int do_xo(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
char argbuf[25];
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(XOFF_NOGOOD);
}
strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
sscanf(argbuf,"%d",&x_offset);
return(0); /* we're all happy here... :^) */
}
int do_yo(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
char argbuf[25];
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(YOFF_NOGOOD);
}
strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
sscanf(argbuf,"%d",&y_offset);
return(0); /* we're all happy here... :^) */
}
int do_dt(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
char argbuf[25];
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(DLY_NOGOOD);
}
strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
sscanf(argbuf,"%d",&delay_time);
return(0); /* we're all happy here... :^) */
}
int do_shift(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
char argbuf[25];
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(SHIFT_NOGOOD);
}
strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
sscanf(argbuf,"%d",&shifter);
return(0); /* we're all happy here... :^) */
}
int do_xdim(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
char argbuf[25];
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(XDIM_NOGOOD);
}
strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
sscanf(argbuf,"%d",&xdim);
return(0); /* we're all happy here... :^) */
}
int do_ydim(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
char argbuf[25];
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(YDIM_NOGOOD);
}
strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
sscanf(argbuf,"%d",&ydim);
return(0); /* we're all happy here... :^) */
}
int do_rbuf(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
char argbuf[25];
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(RBUF_NOGOOD);
}
strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
sscanf(argbuf,"%x",((int*)(&red)));
return(0); /* we're all happy here... :^) */
}
int do_gbuf(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
char argbuf[25];
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(GBUF_NOGOOD);
}
strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
sscanf(argbuf,"%x",((int*)(&green)));
return(0); /* we're all happy here... :^) */
}
int do_bbuf(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this option's position */
int limit; /* indicates total number of opts on cmd line */
{
char argbuf[25];
if (++(*index_ptr) > limit) /* index to our keyword after switch */
{
return(BBUF_NOGOOD);
}
strcpy(argbuf,argv[*index_ptr++]); /* get incoming parameter */
sscanf(argbuf,"%x",((int*)(&blue)));
return(0); /* we're all happy here... :^) */
}
int do_help(argv,index_ptr,limit)
char *argv[]; /* cmd line arguments */
int *index_ptr; /* points to this options position */
int limit; /* indicates total number of opts on cmd line */
{
int index;
char buffer[100];
sprintf(&buffer[0],"%s. Usage is:",argv[0]);
safe_line(&buffer[0]);
for (index=0; opts[index]; index+=2)
{
sprintf(&buffer[0],"'
1>
%s %s%s",argv[0],opts[index],opts[index+1]);
safe_line(&buffer[0]);
}
safe_line("");
safe_line("(c) Black Belt Systems, 1990 - ALL RIGHTS RESERVED");
safe_line("Written by Ben Williams, ars:AA7AS");
return(DIE_QUIETLY);
}
/*
* do_cli_args()
*
* This proceedure parses the command line arguments and calls other
* proceedures based upon what is encountered in the command line.
* This is considered an initialization step (many of them). Once all
* CLI parameters have been handled, error status (or success) is returned
* to the main() proceedure, which then passes it on to the runner()
* proceedure. If an error is encountered, runner() returns immediately
* and cleanup() is called, which will cleanup (obviously) and also
* report the error.
*/
int do_cli_args(argc,argv)
int argc;
char *argv[];
{
int arg_index,arg_limit,opt_index;
int parm;
unsigned char found;
from_cli=1; /* global info for later printfs and the like */
parm=0; /* no errors - yet. */
arg_limit = argc-1; /* argv[0] is the programs NAME */
arg_index = 1;
while(arg_index <= arg_limit )
{
found=0;
opt_index=0;
while((!found) && (opts[opt_index]))
{
if (strnicmp(argv[arg_index],opts[opt_index])==0)
{
found=1;
/* call FN via table, pass position in parameters */
if (parm=(*opt_name[opt_index >> 1])(argv,&arg_index,arg_limit))
{
return(parm);
}
}
opt_index += 2;
}
if (!found)
{
return(UNKNOWN_OPT);
}
arg_index++;
}
return(0);
}
int init(argc,argv)
int argc;
char *argv[];
{
int parm;
iff_flag=0;
iff_file[0]=0;
even_steven=0;
ip_file[0]=0;
get_ip=0;
chroma=0;
x_offset=0;
y_offset=0;
shifter=0;
luma_mode=0;
lacer=0;
delay_time=0;
write_odd=0;
rdm=1; /* seed! */
hidden=0;
red = NULL;
green = NULL;
blue = NULL;
if (!(ExecBase = OpenLibrary("exec.library",0)))
{
return(NO_EXECLIB);
}
if (!(IntuitionBase = OpenLibrary("intuition.library",0)))
{
return(NO_INTUILIB);
}
if (!(GfxBase = OpenLibrary("graphics.library",0)))
{
return(NO_GFXLIB);
}
if (!(IconBase = OpenLibrary(ICONNAME,0)))
{
return(NO_ICONLIB);
}
/* now we parse the arguments, if any, from the parent environment: */
parm=NO_PARAMS;
if (argc)
{
parm=do_cli_args(argc,argv);
}
return(parm);
}
/*
* cleanup()
*
* This routine close libraries and so on; if there was an error
* encountered in the program, it is looked up and printed out here.
*/
void cleanup(parm)
int parm;
{
char ebuff[80];
int i;
if (parm == DIE_QUIETLY) parm=HAPPY; /* no errors generated */
if (GfxBase) CloseLibrary(GfxBase);
if (IconBase) CloseLibrary(IconBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (ExecBase) CloseLibrary(ExecBase);
if (parm) /* get system problem from table up front */
{
i=0; /* look up error # linearly */
while ((parm != our_problem[i].ProbID) && (our_problem[i].ProbID))
{
i++;
}
if (!our_problem[i].ProbID) /* then error # isn't in the table */
{
sprintf(&ebuff[0],"Unknown Internal Error #%d",parm);
safe_line(&ebuff[0]);
}
else /* we found the error, signal it. */
{
safe_line(our_problem[i].ProbText);
}
}
exit(parm);
}
/*
* write_byte() - lowest level routine
*
* This routine actually writes bytes to the target screen; all other
* routines vector thru it. Why? Because we need to control how the
* bytes are written to the screen; at the current time,
* a byte must be written to an odd pixel and then an even one,
* which is a little unusual. We're looking at the hardware to see
* if we can change this. If not, you'll need a global flag that
* the user can set (here, it's called "write_odd") for their particular
* machine... hopefully, this will not be a variable, it could be a pain
* in the ribs. But for the moment, the variable is needed in case there
* is variation.
*
* This routine (obviously) isn't particularly optomized, it's just very
* straightforward code. Since it is the bottom level routine, you'll
* almost certainly want to replace it with in line code or at the
* very least fast external ASM code. We leave all that fun up to
* you for now, although we'll try to provide that stuff too, if we
* get time.
*/
void write_byte(x,y,n)
short x;
int y;
unsigned char n;
{
int ypos,byte_offset;
short bit_offset;
ypos = y * 80; /* index to correct scan line */
bit_offset = ((x << 1) & 7) | write_odd; /* find base bit position */
byte_offset = (x >> 2); /* find base byte offset */
if (n & 128) *(fp3 + ypos + byte_offset) |= bitpat[bit_offset];
else *(fp3 + ypos + byte_offset) &= ~bitpat[bit_offset];
if (n & 64) *(fp2 + ypos + byte_offset) |= bitpat[bit_offset];
else *(fp2 + ypos + byte_offset) &= ~bitpat[bit_offset];
if (n & 32) *(fp1 + ypos + byte_offset) |= bitpat[bit_offset];
else *(fp1 + ypos + byte_offset) &= ~bitpat[bit_offset];
if (n & 16) *(fp0 + ypos + byte_offset) |= bitpat[bit_offset];
else *(fp0 + ypos + byte_offset) &= ~bitpat[bit_offset];
bit_offset++; /* to next nybble */
if (bit_offset == 8) /* carry into next byte? */
{
bit_offset=0;
byte_offset++;
}
if (n & 8) *(fp3 + ypos + byte_offset) |= bitpat[bit_offset];
else *(fp3 + ypos + byte_offset) &= ~bitpat[bit_offset];
if (n & 4) *(fp2 + ypos + byte_offset) |= bitpat[bit_offset];
else *(fp2 + ypos + byte_offset) &= ~bitpat[bit_offset];
if (n & 2) *(fp1 + ypos + byte_offset) |= bitpat[bit_offset];
else *(fp1 + ypos + byte_offset) &= ~bitpat[bit_offset];
if (n & 1) *(fp0 + ypos + byte_offset) |= bitpat[bit_offset];
else *(fp0 + ypos + byte_offset) &= ~bitpat[bit_offset];
}
/*
* SetRGB8();
*
* This routine is similar to SetRGB4() in the Amiga's "normal" gfx library.
* You pass it the register number, the RGB value, and a parameter that tells
* it which line the palette starts on and it will set the register for you.
* For most screens, the starting line will be ZERO, as that leaves the most
* room for futzing about with images; however, in the test software, we
* sometimes reload the palette on the same screen. This means that the
* second palette will begin on a line other than zero.
*
* If the global variable "lacer" is set, this routine will write the color
* register data in two places - one for each 200 line section of the
* interlace image. If you need different color registers for each field,
* then you'll need to modify this routine - that would be an unusual
* situation, even though it's perfectly feasible.
*/
void SetRGB8(reg,rr,gg,bb,base)
short reg;
unsigned char rr,gg,bb;
short base;
{
short p_row,p_index;
p_row = (reg >> 6) + base; /* palette row 0-3. */
p_index = ((reg & 0x3f) * 3) + 8; /* reg 0-63 in p_row */
if (lacer) /* then we need both fields! */
{
write_byte(p_index, p_row*2, rr); /* put RED value */
write_byte(p_index+1, p_row*2, gg); /* put GREEN value */
write_byte(p_index+2, p_row*2, bb); /* put BLUE value */
write_byte(p_index, (p_row*2)+1, rr); /* put RED value */
write_byte(p_index+1, (p_row*2)+1, gg); /* put GREEN value */
write_byte(p_index+2, (p_row*2)+1, bb); /* put BLUE value */
}
else /* just write to one field */
{
write_byte(p_index, p_row, rr); /* put RED value */
write_byte(p_index+1, p_row, gg); /* put GREEN value */
write_byte(p_index+2, p_row, bb); /* put BLUE value */
}
}
/*
* gen_even_palette()
*
* This routine creates a special palette; it's extremely useful for
* drawing images of unknown color composition quickly. See the
* WriteRGB() routine, just following.
*
* This palette essentially gives you 6 levels of red, 7 levels of
* green, and 6 levels of blue. If you were to do a binary distribution,
* you'd get 8 of red, 8 of green, and 4 of blue, which leaves images
* with any blue detail at all looking like trash. This distribution
* and the accompaning write routine evens the score between the colors.
*/
void gen_even_palette(base)
int base;
{
int rr,gg,bb,i;
i=0;
for (rr=0; rr<252; rr+=42)
{
for (gg=0; gg<252; gg+=36)
{
for (bb=0; bb<252; bb+=42)
{
SetRGB8(i++,rr,gg,bb,base);
}
}
}
}
/*
* write_RGB()
*
* This routine is used after calling "gen_even_palette()", above.
* gen_even_palette() sets up 252 color registers such that they are
* pretty evenly distributed accross the color spectrum. Given a 24
* bit input, this routine maps the image colors to the palette
* colors evenly. Very useful as a general "show" routine. Most images
* look very nice indeed... 256 colors, no fringing.
*/
void write_RGB(x,y,rr,gg,bb)
int x,y,rr,gg,bb;
{
write_byte(x,y,((rr/43)*42) + ((gg/37)*6) + (bb/43) );
}
/*
* write_cookie()
*
* This function writes the cookie on a particular line. The variable
* "brand" is a pointer to an arrary of data that contains the particular
* cookie for the mode you want. Call as:
* write_cookie(ham_cookie,line);
* -or-
* write_cookie(reg_cookie,line);
* If you have a four line palette, you need to call this function for
* each successive line the palette exists upon.
*
* See the next set of proceedures: WriteRegCookie() and WriteHamCookie()
* for a higher level approach to this.
*
* If the global variable "lacer" is set, this function will write the cookie
* data on TWO lines... sending four lines of cookie to the function with the
* lines 0,1,2,3 will write cookies on line pairs 0,1 2,3 4,5 and 6,7.
*/
void write_cookie(brand,line)
unsigned char *brand;
int line;
{
int i;
if (lacer) /* we need double the cookie data! */
{
for (i=0; i<8; i++)
{
write_byte(i,line*2,brand[i]);
write_byte(i,(line*2)+1,brand[i]);
}
}
else
{
for (i=0; i<8; i++)
{
write_byte(i,line,brand[i]);
}
}
}
/*
* WriteHamCookie(), WriteRegCookie()
*
* More specific versions of cookie handling...
*/
void WriteHamCookie(lines,base)
int lines,base;
{
int i;
for (i=base; i<(base+lines); i++)
{
write_cookie(ham_cookie,i);
}
}
void WriteRegCookie(lines,base)
int lines,base;
{
int i;
for (i=base; i<(base+lines); i++)
{
write_cookie(reg_cookie,i);
}
}
/*
* Sets palette for Amiga side of hardware: The palette here is designed
* to achieve two independant goals. First, and most importantly, it creates
* a situation where the IRGB lines at the Amiga's data port will exactly
* mirror the data in the bitplanes of the screen as each pixel is emitted.
* Secondly, this palette makes the images visible, if not sensible, on a
* non HAM-e equipped Amiga... Hopefully this distinctive color palette will
* quickly cue the user that they are missing something good. :^)
*
* IRGB to 12 bit correspondence:
*
* bit 8 - b3 of red
* bit 4 - b3 of green
* bit 2 - b3 of blue
* bit 1 - b0 of blue
*/
void make_hame_palette()
{
register struct ViewPort *vp;
register int rr,gg,bb,i;
int col;
col=0;
vp = &scr->ViewPort;
for (i=0; i<16; i++)
{
rr=0; gg=0; bb=0;
if (i & 8) rr = 8; /* this builds the IRGB bit outputs. */
if (i & 4) gg = 8;
if (i & 2) bb = 8;
if (i & 1) bb |= 1;
rr += (col & 7); /* build strange colors in there, too... */
col += 2;
gg += (col & 7); /* ... so "normal view" is interesting */
col += 2;
bb += (col & 6);
col += 2;
/* Set_v_RGB4() is in iff.c - almost the same as SetRGB4() */
Set_v_RGB4(vp,i,rr,gg,bb); /* actually set the Amiga colors */
}
}
/*
* grey_palette();
*
* Writes 256 register palette using the ri, gi, and bi variables as
* addends for each register. calling with 1,1,1 creates a palette that
* goes from 0:0:0, 1:1:1, 2:2:2.... 255:255:255 Calling with with
* the values 1,0,1 would create a palette that goes from 0:0:0, 1:0:1,
* 2:0:2... 255:0:255 The function is intended to provide an easy way
* to generate linear 256 level palettes of the seven major colors:
* R, G, B, RG, RB, GB, RGB.
*/
void grey_palette(base,ri,gi,bi)
int base;
{
int i,rv,gv,bv;
rv=0; gv=0; bv=0;
for (i=0; i<256; i++)
{
SetRGB8(i,rv,gv,bv,base);
rv += ri;
gv += gi;
bv += bi;
}
}
/*
* make_luma_palette()
*
* This routine creates 256 grey levels using the grey_palette routine,
* intended for use in register mode.
*/
void make_luma_palette()
{
grey_palette(0,1,1,1);
}
/*
* inc_palette();
*
* Writes 256 register palette, intended for use in register mode...
* Creates 256 colors arranged such that there are 8 levels of red,
* 8 levels of green, and 4 levels of blue - the typical 8 bit RGB
* distribution. A much better choice is "gen_even_palette()", but
* this is the "typical" industry way of distributing colors.
*/
void inc_palette(base)
int base;
{
int i;
unsigned char pred,pgreen,pblue;
for (i=0; i<256; i++)
{
pred = (i & 0xE0) + ((i & 0xE0)>>3);
pgreen = ((i & 0x1C) << 3) + (((i & 0x1C) << 3) >> 3);
pblue = ((i & 0x03) << 6) + ((i & 0x03) << 4) + ((i >> 1)&1);
SetRGB8(i,pred,pgreen,pblue,base);
}
}
/*
* This function simply writes a block of a particular value. Intended
* for generating into a REG mode screen. Used in Bugger();
*/
void write_block(bx,by,value,base)
short bx,by;
unsigned char value;
short base;
{
short xbase,ybase,xi,yi;
xbase = bx * 10; /* determine starting x,y */
ybase = (by * 8)+base;
for (yi=ybase; yi<(ybase+8); yi++)
{
for (xi=xbase; xi<(xbase+10); xi++)
{
write_byte(xi,yi,value);
}
}
}
/*
* Bugger()
*
* This function writes a number of different patterns into the screen
* that are useful when working with the board (diagnostics). Various
* techniques, mostly quick and dirty, are used to create these patterns.
* Bugger is not "nice" code - sorry.
*/
void bugger(srow)
int srow;
{
int i,vx;
int vy;
if (hidden) ScreenToBack(scr);
WriteHamCookie(4,0);
/* write palette at ham cookie starting row */
if (even_steven) gen_even_palette(0); /* 6r 7g 6b */
else inc_palette(0); /* 8r 8g 4b */
WriteRegCookie(4,65);
grey_palette(65,1,1,1); /* 256 grey levels */
WriteRegCookie(4,73);
grey_palette(73,1,0,0); /* 256 RED levels */
WriteRegCookie(4,81);
grey_palette(81,0,1,0); /* 256 GREEN levels */
WriteRegCookie(4,89);
grey_palette(89,0,0,1); /* 256 BLUE levels */
WriteRegCookie(4,100);
if (even_steven) gen_even_palette(100); /* 6r 7g 6b */
else inc_palette(100); /* 8r 8g 4b */
for (vx=0; vx<256; vx++)
{
write_byte(vx,69,vx); /* writes for linear grey scale */
write_byte(vx,70,vx);
write_byte(vx,71,vx);
write_byte(vx,72,vx);
write_byte(vx,77,vx); /* red */
write_byte(vx,78,vx);
write_byte(vx,79,vx);
write_byte(vx,80,vx);
write_byte(vx,85,vx); /* green */
write_byte(vx,86,vx);
write_byte(vx,87,vx);
write_byte(vx,88,vx);
write_byte(vx,93,vx); /* blue */
write_byte(vx,94,vx);
write_byte(vx,95,vx);
write_byte(vx,96,vx);
}
i=1;
vx=1; vy=0;
while(i < 60) /* show registers in HAM-E mode */
{
write_block(vx,vy,i++,24); /* place reg block */
vx++;
if (vx == 32)
{
vx=0;
vy++;
}
}
i=0;
if (even_steven) /* using 6r 7g 6b color distribution */
{
for (vy=0; vy<9; vy++) /* generates 9 rows of reg loads */
{
for (vx=0; vx<30; vx++)
{
write_block(vx,vy,i,srow);
i++;
if (i == 252)
{
vx=30; vy=9;
}
}
}
i=2;
/* write RGB color distribution bar */
write_block(i++,10,0,srow); /* black (0) */
write_block(i++,10,1,srow); /* blue (5) */
write_block(i++,10,2,srow);
write_block(i++,10,3,srow);
write_block(i++,10,4,srow);
write_block(i++,10,5,srow);
i++;
write_block(i++,10,0,srow); /* black (0) */
write_block(i++,10,6,srow);
write_block(i++,10,12,srow); /* green (6) */
write_block(i++,10,18,srow);
write_block(i++,10,24,srow);
write_block(i++,10,30,srow);
write_block(i++,10,36,srow);
i++;
write_block(i++,10,0,srow); /* black (0) */
write_block(i++,10,42,srow); /* red (5) */
write_block(i++,10,84,srow);
write_block(i++,10,126,srow);
write_block(i++,10,168,srow);
write_block(i++,10,210,srow);
}
else /* using 8r 8g 4b color distribution */
{
for (vy=0; vy<8; vy++) /* generates 9 rows of reg loads */
{
for (vx=0; vx<32; vx++)
{
write_block(vx,vy,i,srow);
i++;
}
}
/* write RGB color distribution bar */
i=3;
write_block(i++,9,0,srow); /* black (0) */
write_block(i++,9,1,srow); /* blue (3) */
write_block(i++,9,2,srow);
write_block(i++,9,3,srow);
i++;
write_block(i++,9,0,srow); /* black (0) */
write_block(i++,9,4,srow); /* green (7) */
write_block(i++,9,8,srow);
write_block(i++,9,12,srow);
write_block(i++,9,16,srow);
write_block(i++,9,20,srow);
write_block(i++,9,24,srow);
write_block(i++,9,28,srow);
i++;
write_block(i++,9,0,srow); /* black (0) */
write_block(i++,9,32,srow); /* red (7) */
write_block(i++,9,64,srow);
write_block(i++,9,96,srow);
write_block(i++,9,128,srow);
write_block(i++,9,160,srow);
write_block(i++,9,192,srow);
write_block(i++,9,224,srow);
}
/* write buncha colors in HAM mode */
write_byte(0,50,0x40); /* hamming test - load color reg 0:0 first... */
write_byte(0,51,0x40);
write_byte(0,52,0x40);
write_byte(1,50,0x80); /* hamming test - load color reg 0:0 first... */
write_byte(1,51,0x80);
write_byte(1,52,0x80);
write_byte(2,50,0xC0); /* hamming test - load color reg 0:0 first... */
write_byte(2,51,0xC0);
write_byte(2,52,0xC0);
/* ramp up colors using "pure" RGB ham loads */
for (vx=0; vx<256; vx++) /* then build 0-63 each of three ways */
{
write_byte(vx+3,50,(vx >> 2)+0x80); /* write LOTS of HAM data! */
write_byte(vx+3,51,(vx >> 2)+0xC0);
write_byte(vx+3,52,(vx >> 2)+0x40);
}
write_byte(0,55,0x40); /* hamming test - load color reg 0:0 first... */
write_byte(0,56,0x40);
write_byte(0,57,0x40);
write_byte(1,55,0x80); /* hamming test - load color reg 0:0 first... */
write_byte(1,56,0x80);
write_byte(1,57,0x80);
write_byte(2,55,0xC0); /* hamming test - load color reg 0:0 first... */
write_byte(2,56,0xC0);
write_byte(2,57,0xC0);
for (vx=0; vx<256; vx++) /* then build 63-0 each of three ways */
{
write_byte(vx+3,55,((255-vx) >> 2)+0x80); /* write LOTS of HAM data! */
write_byte(vx+3,56,((255-vx) >> 2)+0xC0);
write_byte(vx+3,57,((255-vx) >> 2)+0x40);
}
/* write hammed grey scale... */
write_byte(0,60,0x80); /* hamming test - load color reg 0:0 first... */
write_byte(1,60,0xC0); /* hamming test - load color reg 0:0 first... */
write_byte(2,60,0x40); /* hamming test - load color reg 0:0 first... */
i=3;
for (vx=0; vx<64; vx++)
{
write_byte(i++,60,vx+0x80);
write_byte(i++,60,vx+0xC0);
write_byte(i++,60,vx+0x40);
}
write_byte(0,63,0x80); /* hamming test - load color reg 0:0 first... */
write_byte(1,63,0xC0); /* hamming test - load color reg 0:0 first... */
write_byte(2,63,0x40); /* hamming test - load color reg 0:0 first... */
i=3;
for (vx=63; vx>=0; vx--)
{
write_byte(i++,63,vx+0x80);
write_byte(i++,63,vx+0xC0);
write_byte(i++,63,vx+0x40);
}
if (hidden) ScreenToFront(scr);
}
/*
* show_luma_pic()
*
* Use the GREEN buffer pointer to generate a B&W rendering. Color registers
* are set to 256 grey levels in the "runner()" routine.
*/
void show_luma_pic()
{
int h,v,hl,vl,lbase,start;
WriteRegCookie(4,0);
make_luma_palette();
start=4;
if (lacer) start=8;
hl = xdim; vl = ydim; /* requested dimensions */
if (lacer) /* is this an interlace screen? */
{
if (vl > 400) vl = 400;
}
else
{
if (vl > 200) vl = 200;
}
if (hl > 320) hl = 320;
for(v=start; v<vl; v++)
{
lbase = (v+y_offset)*xdim;
write_byte(0,v,0x01); /* this prevents a full like of color zero. */
for (h=1; h<hl; h++)
{
write_byte(h,v,*(green+lbase+h+x_offset) << shifter);
}
}
}
/*
* show_ip_file()
*
* This routine will show a NewTek format "ip" picture; it's a _very_
* simple routine, but serves to show a nice easy application.
*/
void show_ip_file()
{
int h,v,hl,vl,start;
char mybyte;
FILE *fp;
WriteRegCookie(4,0);
make_luma_palette();
start=4;
if (!xdim) hl=320;
if (!ydim) vl=200;
if (!(fp=fopen(&ip_file[0],"r")))
{
return;
}
for(v=start; v<vl; v++)
{
write_byte(0,v,0x01); /* Dummy pixel to handle turn off problems */
if (fread(&mybyte,1,1,fp) != 1)
{
fclose(fp);
return;
}
for (h=1; h<hl; h++)
{
if (fread(&mybyte,1,1,fp) != 1)
{
fclose(fp);
return;
}
write_byte(h,v,mybyte);
}
}
fclose(fp);
get_ip=0;
}
/*
* showregpic6()
*
* This function will attempt to display buffers that were (presumably)
* passed in at the commands startup. See the -r, -g and -b options, as
* well as the -x and -y options.
*
* 18 bit
*/
void showregpic6()
{
int h,v,hl,vl,lbase,start;
start=4;
WriteRegCookie(4,0);
gen_even_palette(0);
if (lacer) start=8;
hl = xdim; vl = ydim; /* requested dimensions */
if (lacer)
{
if (vl > 400) vl = 400;
}
else
{
if (vl > 200) vl = 200;
}
if (hl > 320) hl = 320;
for(v=start; v<vl; v++)
{
lbase = v*xdim;
write_byte(0,v,0x01);
for (h=1; h<hl; h++)
{
write_byte(h,v,((red[lbase+h]/43)*42) +
((green[lbase+h]/37)*6) +
(blue[lbase+h]/43) );
}
}
}
/*
* showregpic8()
*
* This function will attempt to display buffers that were (presumably)
* passed in at the commands startup. See the -r, -g and -b options, as
* well as the -x and -y options.
*
* 24 bit
*/
void showregpic8()
{
int h,v,hl,vl,lbase,start;
WriteRegCookie(4,0);
gen_even_palette(0);
start=4;
if (lacer) start=8;
hl = xdim; vl = ydim; /* requested dimensions */
if (lacer)
{
if (vl > 400) vl = 400;
}
else
{
if (vl > 200) vl = 200;
}
if (hl > 320) hl = 320;
for(v=start; v<vl; v++)
{
lbase = v*xdim;
write_byte(0,v,0x01);
for (h=1; h<hl; h++)
{
write_byte(h,v,((red[lbase+h]/43)*42) +
((green[lbase+h]/37)*6) +
(blue[lbase+h]/43) );
}
}
}
/*
* showhampic()
*
* This function is a "pure" ham display routine. It does NOT use the
* registers - only hamming techniques. It's also (if only because it's
* in 'c') not an optomized display routine by any means. That's up to you.
*
* write_byte(h,v,0x80+currr);
* write_byte(h,v,0xC0+currg);
* write_byte(h,v,0x40+currb);
*
* This routine expects you to have provided the RGB buffer pointers
* (the -r -g and -b cmd line switches) and looks at those points
* using dimensions gleaned from the -x and -y switches to generate
* a complete HAM (no register calls at all) image. This means that
* fringing is at a maximum; there are so many ways to allocate
* registers for a HAM display, we just wanted to make clear how
* HAM displays are handled in general, here. Another piece of
* source code will detail register-fixup HAM mode handling all
* by itself - it's not the only way, but it will be one way.
*
* 18 bit buffer data
*/
void showhampic6()
{
int h,v,hl,vl,lbase,start;
short last_color,spinner;
unsigned char lastr,lastg,lastb;
unsigned char currr,currg,currb;
unsigned char dr,dg,db;
WriteHamCookie(4,0);
inc_palette(0); /* write palette at ham cookie starting row */
last_color=0;
start=4;
if (lacer) start = 8;
hl = xdim; vl = ydim; /* requested dimensions */
if (lacer)
{
if (vl > 400) vl = 400;
}
else
{
if (vl > 200) vl = 200;
}
if (hl > 320) hl = 320;
spinner=0;
for(v=start; v<vl; v++)
{
lbase = v*xdim;
write_byte(0,v,0x80); /* begin as BLACK */
write_byte(0,v,0xC0);
write_byte(0,v,0x40);
lastr=0; lastg=0; lastb=0;
for (h=3; h<hl; h++)
{
currr = red[lbase+h] & 0x3f;
currg = green[lbase+h] & 0x3f;
currb = blue[lbase+h] & 0x3f;
if (currr > lastr) dr = currr-lastr; else dr = lastr - currr;
if (currg > lastg) dg = currg-lastg; else dg = lastg - currg;
if (currb > lastb) db = currb-lastb; else db = lastb - currb;
if ((dr > dg) && (dr > db))
{
write_byte(h,v,0x80+currr);
lastr = currr;
}
else if ((dg > dr) && (dg > db))
{
write_byte(h,v,0xC0+currg);
lastg = currg;
}
else if ((db > dr) && (db > dg))
{
write_byte(h,v,0x40+currb);
lastb = currb;
}
else if ((dr > dg) || (dr > db))
{
write_byte(h,v,0x80+currr);
lastr = currr;
}
else if ((dg > dr) || (dg > db))
{
write_byte(h,v,0xC0+currg);
lastg = currg;
}
else if ((db > dg) || (db > dr))
{
write_byte(h,v,0x40+currb);
lastb = currb;
}
else
{
switch(spinner)
{
case 0:
{
spinner=1;
write_byte(h,v,0x80+currr);
lastr = currr;
break;
}
case 1:
{
write_byte(h,v,0xC0+currg);
lastg = currg;
spinner=2;
break;
}
case 2:
{
write_byte(h,v,0x40+currb);
lastg = currb;
spinner=0;
break;
}
}
}
}
}
}
/*
* showhampic8()
*
* This routine expects you to have provided the RGB buffer pointers
* (the -r -g and -b cmd line switches) and looks at those points
* using dimensions gleaned from the -x and -y switches to generate
* complete HAM (no register calls at all) image. This means that
* fringing is at a maximum; there are so many ways to allocate
* registers for a HAM display, we just wanted to make clear how
* HAM displays are handled in general, here. Another piece of
* source code will detail register-fixup HAM mode handling all
* by itself - it's not the only way, but it will be one way.
*
* 24 bit buffer data
*/
void showhampic8()
{
int h,v,hl,vl,lbase,start;
short last_color,spinner;
unsigned char lastr,lastg,lastb;
unsigned char currr,currg,currb;
unsigned char dr,dg,db;
WriteHamCookie(4,0);
inc_palette(0); /* write palette at ham cookie starting row */
last_color=0;
start=4;
if (lacer) start = 8;
hl = xdim; vl = ydim; /* requested dimensions */
if (lacer)
{
if (vl > 400) vl = 400;
}
else
{
if (vl > 200) vl = 200;
}
if (hl > 320) hl = 320;
spinner=0;
for(v=start; v<vl; v++)
{
lbase = v*xdim;
write_byte(0,v,0x80); /* begin as BLACK */
write_byte(0,v,0xC0);
write_byte(0,v,0x40);
lastr=0; lastg=0; lastb=0;
for (h=3; h<hl; h++)
{
currr = (red[lbase+h]>>2) & 0x3f;
currg = (green[lbase+h]>>2) & 0x3f;
currb = (blue[lbase+h]>>2) & 0x3f;
if (currr > lastr) dr = currr-lastr; else dr = lastr - currr;
if (currg > lastg) dg = currg-lastg; else dg = lastg - currg;
if (currb > lastb) db = currb-lastb; else db = lastb - currb;
if ((dr > dg) && (dr > db))
{
write_byte(h,v,0x80+currr);
lastr = currr;
}
else if ((dg > dr) && (dg > db))
{
write_byte(h,v,0xC0+currg);
lastg = currg;
}
else if ((db > dr) && (db > dg))
{
write_byte(h,v,0x40+currb);
lastb = currb;
}
else if ((dr > dg) || (dr > db))
{
write_byte(h,v,0x80+currr);
lastr = currr;
}
else if ((dg > dr) || (dg > db))
{
write_byte(h,v,0xC0+currg);
lastg = currg;
}
else if ((db > dg) || (db > dr))
{
write_byte(h,v,0x40+currb);
lastb = currb;
}
else
{
switch(spinner)
{
case 0:
{
spinner=1;
write_byte(h,v,0x80+currr);
lastr = currr;
break;
}
case 1:
{
write_byte(h,v,0xC0+currg);
lastg = currg;
spinner=2;
break;
}
case 2:
{
write_byte(h,v,0x40+currb);
lastg = currb;
spinner=0;
break;
}
}
}
}
}
}
/*
* make_cie()
*
* maps 3-dimensional [(R:G:B)] color map to two dimensional
* screen (memory) space. Big hack.. but it sure is pretty!
* If the rgb buffer pointers are initialized, it'll write the
* image to 6 bits precision to those buffers... this essentially
* passes the color map "out" to the calling program IF the -r -g and -b
* switches are specifed. If not, it just gets drawn to the screen.
*/
void make_cie()
{
int r_dim, g_dim, b_dim;
int px,py,ymul,diag,base;
int rd,bd,rv,bv;
float gv,gd;
int diag_len;
WriteRegCookie(4,0);
gen_even_palette(0);
b_dim=0;
for (r_dim=0; r_dim<64; r_dim++)
{
for (g_dim=0; g_dim<64; g_dim++)
{
px = 132 + r_dim;
py = 132 - g_dim;
write_RGB(px,py,r_dim << 2,g_dim << 2, b_dim <<2);
ymul = (py*xdim)+px;
if (red) *(red +ymul) = r_dim;
if (green) *(green+ymul) = g_dim;
if (blue) *(blue +ymul) = b_dim;
}
}
g_dim=0;
for (r_dim=0; r_dim<64; r_dim++)
{
for (b_dim=0; b_dim<64; b_dim++)
{
px = 132 + r_dim;
py = 132 + b_dim;
write_RGB(px,py,r_dim << 2,g_dim << 2, b_dim <<2);
ymul = (py*xdim)+px;
if (red) *(red +ymul) = r_dim;
if (green) *(green+ymul) = g_dim;
if (blue) *(blue +ymul) = b_dim;
}
}
r_dim=0;
for (g_dim=0; g_dim<64; g_dim++)
{
for (b_dim=0; b_dim<64; b_dim++)
{
px = 132 - g_dim;
py = 132 + b_dim;
write_RGB(px,py,r_dim << 2,g_dim << 2, b_dim <<2);
ymul = (py*xdim)+px;
if (red) *(red +ymul) = r_dim;
if (green) *(green+ymul) = g_dim;
if (blue) *(blue +ymul) = b_dim;
}
}
/* second quadrant: */
b_dim=0;
for (r_dim=0; r_dim<64; r_dim++)
{
for (g_dim=0; g_dim<64; g_dim++)
{
px = 68 + g_dim;
py = 68 - r_dim;
write_RGB(px,py,(63-r_dim) << 2,(63-g_dim) << 2, (63-b_dim) <<2);
ymul = (py*xdim)+px;
if (red) *(red +ymul) = (63-r_dim);
if (green) *(green+ymul) = (63-g_dim);
if (blue) *(blue +ymul) = (63-b_dim);
}
}
g_dim=0;
for (r_dim=0; r_dim<64; r_dim++)
{
for (b_dim=0; b_dim<64; b_dim++)
{
px = 68 - b_dim;
py = 68 - r_dim;
write_RGB(px,py,(63-r_dim) << 2,(63-g_dim) << 2, (63-b_dim) <<2);
ymul = (py*xdim)+px;
if (red) *(red +ymul) = (63-r_dim);
if (green) *(green+ymul) = (63-g_dim);
if (blue) *(blue +ymul) = (63-b_dim);
}
}
r_dim=0;
for (g_dim=0; g_dim<64; g_dim++)
{
for (b_dim=0; b_dim<64; b_dim++)
{
px = 68 - b_dim;
py = 68 + g_dim;
write_RGB(px,py,(63-r_dim) << 2,(63-g_dim) << 2, (63-b_dim) <<2);
ymul = (py*xdim)+px;
if (red) *(red +ymul) = (63-r_dim);
if (green) *(green+ymul) = (63-g_dim);
if (blue) *(blue +ymul) = (63-b_dim);
}
}
/* diagonal space! */
for (base=0; base<64; base++) /* x diagonals */
{
diag_len = 64-base; /* <-- note! not base of ZERO */
rd = (63/diag_len);
gd = ((63-((float)base)) - ((float)base)) / ((float)diag_len);
bd = (63/diag_len);
rv = 63; gv=63-base; bv=63;
px = base+68;
py = 68;
for (diag=base; diag<64; diag++)
{
write_RGB(px,py,rv << 2,((int)gv) << 2,bv <<2);
ymul = (py*xdim)+px;
if (red) *(red +ymul) = rv;
if (green) *(green+ymul) = gv;
if (blue) *(blue +ymul) = bv;
rv -= rd;
gv -= gd;
bv -= bd;
px++; py++;
}
}
for (base=0; base<64; base++) /* x diagonals */
{
diag_len = 64-base; /* <-- note! not base of ZERO */
rd = (63/diag_len);
gd = ((63-((float)base)) - ((float)base)) / ((float)diag_len);
bd = (63/diag_len);
rv = 63; gv=63-base; bv=63;
px = 68;
py = base+68;
for (diag=base; diag<64; diag++)
{
write_RGB(px,py,rv << 2,((int)gv) << 2,bv <<2);
ymul = (py*xdim)+px;
if (red) *(red +ymul) = rv;
if (green) *(green+ymul) = gv;
if (blue) *(blue +ymul) = bv;
rv -= rd;
gv -= gd;
bv -= bd;
px++; py++;
}
}
for (base=0; base<64; base++)
{
write_RGB(base+68,base+68,(63-base) << 2,(63-base) << 2,(63-base) << 2);
ymul = ((base+68)*xdim)+base+68;
if (red) *(red +ymul) = 63-base;
if (green) *(green+ymul) = 63-base;
if (blue) *(blue +ymul) = 63-base;
}
}
/*
* This handles the various options and runs the program.
*/
runner(parm)
int parm;
{
int i,j;
unsigned char k;
if (parm) return(parm); /* watch for setup/parm errors */
if (ydim > 240)
{
NewScreenStructure.ViewModes |= LACE;
NewScreenStructure.Height = 400;
lacer=1;
}
if (!(scr=OpenScreen(&NewScreenStructure))) return(NO_SCREEN);
fp0 = (unsigned char*)scr->BitMap.Planes[0]; /* get quick bitplane ptrs */
fp1 = (unsigned char*)scr->BitMap.Planes[1];
fp2 = (unsigned char*)scr->BitMap.Planes[2];
fp3 = (unsigned char*)scr->BitMap.Planes[3];
j=16000;
k=0x55;
if (write_odd) k=0xaa;
if (lacer) j=32000;
for (i=0; i<j; i++) /* fills a bitplane so no C0 detection */
{
*(fp0+i) = k;
}
make_hame_palette(); /* this sets up our AMIGA palette */
/*
* now we're set up to run in HAM-E _or_ REG mode. what to
* do (for this program) depends on the incoming cmd line
* options; these set various flags - we test them now, and
* call routines as appropriate for the flags.
*/
if (sample) /* this is all a huge hack, here. :^) */
{
bugger(104); /* generates data to view of various types */
}
else if (ham_reg) /* want a ham drawing */
{
showhampic6();
}
else if (get_ip) /* want to read in an IP file */
{
show_ip_file();
}
else if (luma_mode) /* want a registered, 256 grey level drawing */
{
show_luma_pic();
}
else if (chroma)
{
make_cie();
}
else /* want a register drawing */
{
showregpic6();
}
if (iff_flag) /* user want iff file saved from this??? */
{
WBenchToFront(); /* get WB for faster saves in chip-only amiga */
writeiff(&iff_file[0]);
ScreenToFront(scr);
}
/*
* after display, we may want to delay - if you don't want this,
* then place a "get_ip=1;" in your new routine.
*/
if (!get_ip)
{
if (delay_time) /* set by "-d" cmd line switch */
{
if (delay_time < 50) delay_time=50;
Delay(delay_time);
}
else
{
Delay(500); /* wait 10 seconds to see "stuff" */
}
}
CloseScreen(scr); /* and bail out. */
return(0);
}
/*
* main()
*
* runs the whole show, more or less.
*/
void main(argc,argv)
int argc;
char *argv[];
{
cleanup(runner(init(argc,argv)));
}