home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 2
/
crawlyvol2.bin
/
apps
/
dtp
/
ghost
/
gs301src
/
atari
/
gdevvdi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-11
|
28KB
|
1,161 lines
/* Copyright (C) 1991 Aladdin Enterprises. All rights reserved.
Distributed by Free Software Foundation, Inc.
This file is part of Ghostscript.
Ghostscript is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing. Refer
to the Ghostscript General Public License for full details.
Everyone is granted permission to copy, modify and redistribute
Ghostscript, but only under the conditions described in the Ghostscript
General Public License. A copy of this license is supposed to have been
given to you along with Ghostscript so you can know your rights and
responsibilities. It should be in a file named COPYING. Among other
things, the copyright notice and this notice must be preserved on all
copies. */
/* gdevvdi.c */
/* Bitmapped screen device for the Atari ST. This driver contains
* portions of code originally written by Hauke Hess. It uses the
* vdi for all screen operations. It recognizes and supports 1, 2,
* 4, 8, 16, and 24 bit color. Tim Gallivan 5/94.
*/
/* For monochrome, Ghostscript produces a bitmap in memory which
* is referenced directly by 'base'. For color images, GS produces
* a bitmap at 'base' with each pixel represented by several
* consecutive bits (packed or chunky pixel format). The routine
* 'pack_to_plane()' copies the GS "packed" image format into the
* appropriate number of color planes, referenced by 'cbase'. The
* image in 'cbase' is then copied back to 'base' with the vdi routine
* 'vr_trnfm()', and is then copied to the screen. This is rather
* convoluted, but is needed for portability.
*/
#include "gdevvdi.h"
/* External Variables */
extern VWRK VWork; /* from gp_atar1.c */
extern PSTATE State; /* from gp_atar1.c */
extern OBJECT menuobj[]; /* from gp_atar1.h */
extern WINDOW imagwin; /* from gp_atar3.c */
extern WINLIST *WList, *WinListAdd(), *WinListDelete();
/* General screen driver variables. */
byte *cbase=0; /* pointer to the color buffer */
byte **lineptr; /* pointer for each scan line in bitmap */
ushort *plane[16]; /* addresses of each color plane */
ushort *tbase; /* copy of base accessed by assembly routines */
uint csize; /* size of the color buffer referenced by cbase */
ulong mem_space; /* amount of memory taken by the bitmap */
int words;
int ByteWidth, WordWidth, Raster, CopyWidth, CopyHeight;
MFDB plane_image;
GRAPHIC Graphic = {
0, /* PlotX */
0, /* PlotY */
0, /* XRes */
0, /* YRes */
0, /* Width */
0, /* Height */
0, /* StepX */
0, /* StepY */
{0, 0, 0, 0, 0, 0}, /* image */
{0, 0, 0, 0, 0, 0} /* screen */
};
private dev_proc_open_device(stvdi_open);
private dev_proc_close_device(stvdi_close);
private dev_proc_output_page(stvdi_output_page);
private dev_proc_print_page(stvdi_print_page);
private dev_proc_map_rgb_color(stvdi_map_rgb_color);
private dev_proc_map_color_rgb(stvdi_map_color_rgb);
private gx_device_procs stvdi_procs =
prn_color_procs(stvdi_open, stvdi_output_page, stvdi_close,
stvdi_map_rgb_color, stvdi_map_color_rgb);
gx_device_printer gs_stvdi_device =
prn_device(stvdi_procs, "stvdi",
WIDTH_10THS, HEIGHT_10THS,
X_DPI, Y_DPI,
0,0,0,0, /* margins */
1, stvdi_print_page); /* default to monochrome */
/* Open the stvdi device--get the resolution, allocate memory, etc. */
int
stvdi_open(gx_device *pdev)
{
byte *base=0;
char *left = 0;
const gx_device_memory *mdev;
/* gx_device_procs *pprocs = pdev->procs; */
static short AspectAdjusted=0;
int ret;
if (State.Gdebug) eprintf("stvdi_open ...");
/* Adjust the image for the hardware's aspect ratio, but
* only once. If the device is initialized a second time,
* the aspect ratio will already be taken into account.
*/
if (!AspectAdjusted) {
pdev->y_pixels_per_inch =
nint(VWork.AspectRatio * pdev->y_pixels_per_inch);
pdev->height = nint(VWork.AspectRatio * pdev->height);
AspectAdjusted = 1;
}
/* Get an appropriate memory device. */
if ((mdev = gdev_mem_device_for_bits(VWork.ColorBits)) == 0)
return_error(gs_error_rangecheck);
Graphic.XRes = pmemdev->x_pixels_per_inch; /* x dpi */
Graphic.YRes = pmemdev->y_pixels_per_inch; /* y dpi */
Graphic.Width = pmemdev->width; /* width in pixels */
Graphic.Height = pmemdev->height; /* height in pixels */
ByteWidth = (Graphic.Width + 7) >> 3; /* pixel width / 8 */
WordWidth = (ByteWidth + 1) >> 1; /* pixel width / 16 */
/* Ensure that the width is a multiple of 16 pixels. */
pmemdev->width = Graphic.Width = 16 * WordWidth;
if (VWork.ColorBits > 1) {
int MaxGray = (int)(pow(2, VWork.ColorBits) - .5);
/* Fill the color_info structure. */
ppdev->color_info.num_components = 3;
ppdev->color_info.depth = mdev->color_info.depth;
ppdev->color_info.max_gray = MaxGray;
ppdev->color_info.max_rgb = VWork.MaxRGB;
ppdev->color_info.dither_gray = DITH_GRAY(VWork.ColorBits);
ppdev->color_info.dither_rgb = DITH_RGB(VWork.ColorBits);
if (State.Gdebug) {
eprintf1("Depth = %ld\n", ppdev->color_info.depth);
eprintf1("Max Gray = %ld\n", ppdev->color_info.max_gray);
eprintf1("Max RGB = %ld\n", ppdev->color_info.max_rgb);
eprintf1("Dither Gray = %ld\n", ppdev->color_info.dither_gray);
eprintf1("Dither RGB = %ld\n", ppdev->color_info.dither_rgb);
}
}
/* Begin code included from gdevprn.c. */
memset(ppdev->skip, 0, sizeof(ppdev->skip));
ppdev->orig_procs = pdev->std_procs;
ppdev->file = ppdev->ccfile = ppdev->cbfile = NULL;
mem_space = gdev_mem_bitmap_size(pmemdev);
/* Base points to a buffer that GS uses to construct the image. */
if ( mem_space >= ppdev->max_bitmap ||
mem_space != (uint)mem_space || /* too big to allocate */
(base = (byte *)gs_malloc((uint)mem_space, 1,
"printer buffer(open)")) == 0 || /* can't allocate */
(PRN_MIN_MEMORY_LEFT != 0 &&
(left = gs_malloc(PRN_MIN_MEMORY_LEFT, 1,
"printer memory left")) == 0) /* not enough left */
) {
eprintf("stvdi_open: Malloc for printer buffer failed.\n");
return_error(gs_error_VMerror);
}
/* End code included from gdevprn.c. */
/* Cbase points to a buffer that holds the standard GEM
* color plane image.
*/
if ((VWork.ColorBits > 1) && !State.Chunky8 && !VWork.TrueColor) {
csize = (uint)(2 * WordWidth * Graphic.Height * VWork.ColorBits);
if ((cbase = (byte *)gs_malloc(csize, 1, "color buffer")) == 0) {
eprintf("stvdi_open: Malloc for color buffer failed.\n");
return_error(gs_error_VMerror);
}
}
/* Begin more code from gdevprn.c. */
/* Render the image entirely in memory. */
/* Release the leftover memory. */
gs_free(left, PRN_MIN_MEMORY_LEFT, 1, "printer memory left");
ppdev->buffer_space = 0;
pmemdev->base = base;
ppdev->std_procs = mdev->std_procs;
ppdev->std_procs.get_page_device = gx_page_device_get_page_device;
/* Synthesize the procedure vector. */
/* Rendering operations come from the memory or clist device, */
/* non-rendering come from the printer device. */
#define copy_proc(p) set_dev_proc(ppdev, p, ppdev->orig_procs.p)
copy_proc(get_initial_matrix);
copy_proc(output_page);
copy_proc(close_device);
copy_proc(map_rgb_color);
copy_proc(map_color_rgb);
copy_proc(get_params);
copy_proc(put_params);
copy_proc(map_cmyk_color);
copy_proc(get_xfont_procs);
copy_proc(get_xfont_device);
copy_proc(map_rgb_alpha_color);
copy_proc(get_page_device);
#undef copy_proc
/* End code included from gdevprn.c. */
/* Open the memory device. */
if ((ret = (*pdev->procs->open_device)(pdev)) != 0) {
return ret;
}
Raster = pmemdev->raster;
/* Set up the MFDBs for the GS image and the screen. */
Graphic.screen.fd_addr = (long)NULL;
Graphic.image.fd_addr = (long)base;
Graphic.image.fd_w = (VWork.ColorBits > 1) ? 16 * WordWidth:
8 * Raster;
Graphic.image.fd_h = Graphic.Height;
Graphic.image.fd_wdwidth = Graphic.image.fd_w/16;
Graphic.image.fd_stand = 0;
Graphic.image.fd_nplanes = VWork.ColorBits;
if (VWork.ColorBits > 1 && cbase) {
/* Set up the MFDB for the color image buffer. */
plane_image.fd_addr = (long)cbase;
plane_image.fd_w = 16 * WordWidth;
plane_image.fd_h = Graphic.Height;
plane_image.fd_wdwidth = Graphic.image.fd_w/16;
plane_image.fd_stand = 1;
plane_image.fd_nplanes = VWork.ColorBits;
}
return 0;
}
/* Close the stvdi device--free memory, close workstations, etc. */
int
stvdi_close(gx_device *pdev)
{
WINLIST *wl = WList;
/* Close the image window. */
if (imagwin.opened || imagwin.iconified) {
WinClose(&imagwin);
WinListDelete(wl, &imagwin);
WinListRedraw(wl, &State);
}
/* Free the memory device bitmap. */
gs_free((char *)pmemdev->base, (uint)gdev_mem_bitmap_size(pmemdev),
1, "printer buffer");
/* Free the memory for the color image buffer. */
if (VWork.ColorBits > 1 && cbase) {
gs_free((char *)cbase, csize, 1, "color buffer");
}
pdev->std_procs = ppdev->orig_procs;
return 0;
}
int
stvdi_output_page(gx_device *pdev, int num_copies, int flush)
{
int code;
ppdev->page_count++;
/* Print the accumulated page description. */
code = (*ppdev->print_page)(ppdev, ppdev->file);
/* Make palette entries available to the next page. */
State.PaletteCount = 1;
if ( code < 0 ) return code;
return 0;
}
/* Print the bitmap for the current page to the screen. */
private int
stvdi_print_page(gx_device_printer *pdev, FILE *dummy)
{
byte *base;
int count, show_end, pad, length, top, empty;
long ch;
show_end = 0;
/* Calculate the number of padding bits in the last byte
* of each scan line.
*/
pad = (8 * ByteWidth - Graphic.Width) * VWork.ColorBits;
length = ByteWidth * VWork.ColorBits;
Graphic.PlotY = 0;
lineptr = pmemdev->line_ptrs;
base = *lineptr;
tbase = (ushort *)base; /* accessed from assembly routines */
/* Find the first line containing nonzero bits. */
while (Graphic.PlotY < Graphic.Height) {
/* Search the scanline for a nonzero bit. */
for (count=0; (count < length)
&& (base[count] == 0); ++count) ;
if (count >= length) { /* Empty line, continue. */
Graphic.PlotY++;
base = lineptr[Graphic.PlotY];
}
else if ((count==length-1) && (base[count]>>pad == 0)) {
Graphic.PlotY++; /* nonzero bits in padding, continue */
base = lineptr[Graphic.PlotY];
}
else { /* Nonzero bits found, break loop. */
if (--Graphic.PlotY < 0) {
Graphic.PlotY = 0;
}
break;
}
}
/* Skip transformation and display of modes my hardware
* doesn't support.
*/
if (State.Debug8 || State.Debug16) {
dprintf1("%s\n", "Done!");
return 0;
}
/* Convert the packed image to standard GEM color planes,
* then convert the plane image to the final platform-dependent
* screen format. If the platform-dependent format is chunky,
* then do nothing.
*/
if (VWork.TrueColor) {
;
}
else if (VWork.ColorBits == 8 && State.Chunky8) {
;
}
else {
stvdi_pack_to_plane();
vr_trnfm(VWork.VdiHandle, &plane_image, &Graphic.image);
}
/* Open a window and display the image. */
if (State.Windows) {
graf_mouse(M_OFF, 0L );
if (imagwin.opened) { /* Already opened. */
State.Event->Message[3] = imagwin.handle;
HandleRedraw(FULL_WIN, &State);
update_scroll(imagwin.handle);
}
else { /* Window closed or iconified. */
if ((menuobj[NEXT].ob_state & DISABLED) &&
(menuobj[PREV].ob_state & DISABLED)) {
menu_ienable(menuobj, NEXT, 1);
}
WinListAdd(WList, &imagwin);
BitWinOpen(&imagwin, &VWork, &State);
}
graf_mouse(BUSY_BEE, 0L);
graf_mouse(M_ON, 0L);
}
else {
/* Display the image with no windows. */
CopyWidth = MIN(VWork.XRes, Graphic.Width-1); /* in pixels */
CopyHeight = MIN(VWork.YRes, Graphic.Height-1); /* in pixels */
Graphic.StepX = .9 * CopyWidth;
Graphic.StepY = .9 * CopyHeight;
if (Graphic.PlotY < 0)
Graphic.PlotY = 0;
if (Graphic.PlotY >= Graphic.Height - CopyHeight)
Graphic.PlotY = (Graphic.Height - 1) - CopyHeight;
v_exit_cur(VWork.VdiHandle);
}
while (!show_end && !State.Windows) {
State.pxy[0] = Graphic.PlotX;
State.pxy[1] = Graphic.PlotY;
State.pxy[2] = State.pxy[0] + CopyWidth;
State.pxy[3] = State.pxy[1] + CopyHeight;
State.pxy[4] = 0;
State.pxy[5] = 0;
State.pxy[6] = State.pxy[4] + CopyWidth;
State.pxy[7] = State.pxy[5] + CopyHeight;
graf_mouse(M_OFF, 0L );
vs_clip(VWork.VdiHandle, 1, &State.pxy[4]);
wind_update(BEG_UPDATE); /* lock the screen */
vro_cpyfm(VWork.VdiHandle, 3, State.pxy,
&Graphic.image, &Graphic.screen);
wind_update(END_UPDATE); /* release screen */
vs_clip(VWork.VdiHandle, 0, &State.pxy[4]);
graf_mouse(ARROW, 0L );
graf_mouse(M_ON, 0L );
/* Accept keyboard commands to manipulate the screen image. */
ch = (Bconin(2) >> 16) & 255; /* Get key scancode */
switch(ch) {
case 16: /* Q */
show_end = 1;
break;
case 71: /* Clr/Home */
Graphic.StepX /= 2; Graphic.StepY /= 2;
if (Graphic.StepX < 2) Graphic.StepX = 1;
if (Graphic.StepY < 2) Graphic.StepY = 1;
break;
case 72: /* Up cursor */
Graphic.PlotY = MAX(Graphic.PlotY - Graphic.StepY, 0);
break;
case 75: /* Left cursor */
Graphic.PlotX = MAX(Graphic.PlotX - Graphic.StepX, 0);
break;
case 77: /* Right cursor */
Graphic.PlotX = Graphic.PlotX + Graphic.StepX;
if (Graphic.PlotX >= Graphic.Width - CopyWidth)
Graphic.PlotX = (Graphic.Width - 1) - CopyWidth;
if (Graphic.PlotX < 0) Graphic.PlotX = 0;
break;
case 80: /* Down cursor */
Graphic.PlotY = Graphic.PlotY + Graphic.StepY;
if (Graphic.PlotY >= Graphic.Height - CopyHeight)
Graphic.PlotY = (Graphic.Height - 1) - CopyHeight;
if (Graphic.PlotY < 0) Graphic.PlotY = 0;
break;
case 82: /* Insert */
Graphic.StepX *= 2; Graphic.StepY *= 2;
if (Graphic.StepX > CopyWidth) Graphic.StepX = CopyWidth;
if (Graphic.StepY > CopyHeight) Graphic.StepY = CopyHeight;
break;
case 97: /* Undo */
Graphic.PlotX = 0;
Graphic.PlotY = 0;
break;
case 98: /* Help */
stvdi_DisplayHelp();
Bconin(2);
stvdi_clear_screen(0);
break;
}
}
if (!State.Windows) {
v_enter_cur(VWork.VdiHandle);
}
return (0);
}
int stvdi_DisplayHelp()
{
dprintf2("%c%c Help for GhostScript Screen Driver\n", 27, 'E');
dprintf(" Original Code by Hauke Hess.\n\n");
dprintf(" Q: Quit this page (to next page or GS prompt).\n");
dprintf(" Cursor Keys: Scroll screen in direction of cursor.\n");
dprintf(" Help: Display help screen.\n");
dprintf(" Undo: Move to upper-left corner of page.\n");
dprintf(" Insert: Multiply scroll incrememt by 2.\n");
dprintf(" Clr/Home: Divide scroll increment by 2.\n");
dprintf("\n Command line option -r<XDPI>x<YDPI> sets resolution.\n");
#if 0
dprintf("\n Helpseite des GhostScript Previewers no(c)\n");
dprintf(" Hauke Heß 1991\n");
dprintf(" Cursortasten: bewegen in entsprechender Richtung\n");
dprintf(" Undo: Zurück nach links oben auf der Seite\n");
dprintf(" Insert: Schrittweiter vergrößern\n");
dprintf(" Clr/Home: Schrittweite verkleinern\n");
dprintf("\n Kommandozeilenparameter -r<XDPI>x<YDPI> setzt die Auflösung\n");
#endif
dprintf("\n >> Hit any key to continue. <<");
return(0);
}
int
stvdi_clear_screen(int cursor)
{
if (cursor) {
v_enter_cur(VWork.VdiHandle);
}
else {
v_exit_cur(VWork.VdiHandle);
}
}
/* Map a r-g-b color to a color index. */
/* Ghostscript asks this routine which color index should be associated
* with a given RGB triplet. The palette is set from the high end as GS
* requests colors. Black and white, however, always reside at color
* indices 1 and 0. When the palette is full and a new color is requested,
* the closest color in the palette is returned.
*/
#define BK 0
#define WT 3000
gx_color_index
stvdi_map_rgb_color(gx_device *pdev, gx_color_value r, gx_color_value g,
gx_color_value b) {
register int diff;
register int *pptr = VWork.Palette + VWork.PaletteSize;
static int BlackSet=0, WhiteSet=0;
gx_color_index Pixel;
int *which, Index;
int rgb[3], red, grn, blu;
int best = 1000*3, psize = (VWork.PaletteSize/3 - 2);
float max_value = (float)gx_max_color_value;
if (VWork.ColorBits == 1) { /* monochrome */
return ((r | g | b) > gx_max_color_value / 2 ?
(gx_color_index)0 : (gx_color_index)1);
}
else if (VWork.TrueColor) {
IndexToPixel(&Pixel, 1);
return Pixel;
}
/* Change GS rgb values to ST vdi rgb values. */
red = rgb[0] = 1000 * ((float)r / max_value);
grn = rgb[1] = 1000 * ((float)g / max_value);
blu = rgb[2] = 1000 * ((float)b / max_value);
Index = State.PaletteCount;
switch (red + grn + blu) {
case WT: /* white -- keep at vdi index 0 */
if (!WhiteSet) {
VWork.Palette[0] = rgb[0];
VWork.Palette[1] = rgb[1];
VWork.Palette[2] = rgb[2];
vs_color(VWork.VdiHandle, 0, rgb);
WhiteSet = 1;
}
return (gx_color_index)VWork.ColorReg[0];
case BK: /* black -- keep at vdi index 1 */
if (!BlackSet) {
VWork.Palette[3] = rgb[0];
VWork.Palette[4] = rgb[1];
VWork.Palette[5] = rgb[2];
vs_color(VWork.VdiHandle, 1, rgb);
BlackSet = 1;
}
return (gx_color_index)VWork.ColorReg[1];
default: /* Search for color from end of palette. */
while ( Index-- > 1 ) {
pptr -= 3;
diff = *pptr - red;
if ( diff < 0 ) diff = -diff;
if ( diff < best ) { /* quick rejection */
int dg = pptr[1] - grn;
if ( dg < 0 ) dg = -dg;
if ( (diff += dg) < best ) { /* quick rejection */
int db = pptr[2] - blu;
if ( db < 0 ) db = -db;
if ( (diff += db) < best )
which = pptr, best = diff;
if (best == 0) break;
}
}
}
/* If the color is found or the palette is full, return
* the result of the palette search. Otherwise, set the
* next palette entry to the requested color.
*/
if (best == 0 || State.PaletteCount >= psize) {
Index = (which - VWork.Palette)/3;
return (gx_color_index)VWork.ColorReg[Index];
}
else {
int i = VWork.PaletteSize - 3 * State.PaletteCount;
Index = i/3;
VWork.Palette[i] = rgb[0];
VWork.Palette[i+1] = rgb[1];
VWork.Palette[i+2] = rgb[2];
vs_color(VWork.VdiHandle, Index, rgb);
++State.PaletteCount;
return (gx_color_index)VWork.ColorReg[Index];
}
break;
}
}
/* Map a color index to a r-g-b color. */
int
stvdi_map_color_rgb(gx_device *pdev, gx_color_index color,
gx_color_value prgb[3])
{
int *pptr;
int max_value = gx_max_color_value;
/* HACK ALERT! The manner for extracting RGB values for
* true color modes uses information which may be hardware
* dependent or may change in the future. This routine never
* seems to be called anyway, so it doesn't seem too critical.
*/
if (VWork.ColorBits == 1) { /* monochrome */
return gdev_prn_map_color_rgb(pdev, color, prgb);
}
else if (VWork.TrueColor) {
if (VWork.ColorBits == 16) {
prgb[0] = (color & 0xf800) << (gx_color_value_bits - 16);
prgb[1] = (color & 0x07e0) << (gx_color_value_bits - 11);
prgb[2] = (color & 0x001f) << (gx_color_value_bits - 5);
}
else {
int shift = gx_color_value_bits - 24;
if (shift >= 0) {
prgb[0] = (color & 0x00ff0000L) << shift;
}
else {
prgb[0] = (color & 0x00ff0000L) >> (-shift);
}
prgb[1] = (color & 0x0000ff00L) << (gx_color_value_bits - 16);
prgb[2] = (color & 0x000000ffL) << (gx_color_value_bits - 8);
}
return 0;
}
pptr = VWork.Palette + (int)color * 3;
prgb[0] = (pptr[0] * max_value) / 1000;
prgb[1] = (pptr[1] * max_value) / 1000;
prgb[2] = (pptr[2] * max_value) / 1000;
return 0;
}
/* Copy an image from Ghostscript's format to standard color planes. */
int
stvdi_pack_to_plane(void)
{
int i, plane_size;
words = Graphic.Height * WordWidth - 1; /* pixels/16 - 1 */
plane_size = 2 * WordWidth * Graphic.Height;
/* Plane[i] holds the address of the ith color plane. */
for (i=0; i<VWork.ColorBits; i++) {
plane[i] = (ushort *)(cbase + i * plane_size);
}
/* Jump to the appropriate assembler image transformation. */
switch (VWork.ColorBits) {
case 2: /* Two-bit color. */
trans_2();
break;
case 4: /* Four-bit color. */
trans_4();
break;
case 8: /* Eight-bit color. */
trans_8();
break;
case 16: /* 16-bit color. */
trans_16();
break;
}
return (0);
}
/* This routine is necessary because the vdi color indices are not
* the same as the color register numbers used by the hardware.
* It figures out the color register number associated with each
* color index by writing each color index to the screen and then
* examining which color register was used.
*/
int IndexToPixel(gx_color_index *index_array, int p_size)
{
int i, index, xy_pos[2], LoWord, HiWord;
/* Screen position to write pixel. */
xy_pos[0] = 0;
xy_pos[1] = 0;
vswr_mode(VWork.VdiHandle, 1); /* overwrite mode */
vsm_type(VWork.VdiHandle, 1); /* marker type "dot" */
for (index=0; p_size--; index++) {
vsm_color(VWork.VdiHandle, index); /* set pixel color */
v_pmarker(VWork.VdiHandle, 1, xy_pos); /* write pixel to screen */
/* get the pixel -- put in LoWord */
v_get_pixel(VWork.VdiHandle, xy_pos[0], xy_pos[1], &LoWord, &HiWord);
if (VWork.ColorBits <= 16) {
index_array[index] = (gx_color_index)LoWord;
}
else {
index_array[index] = 65536 * (gx_color_index)HiWord + LoWord;
}
}
}
__asm__("
.globl _trans_2, _trans_4, _trans_8, _trans_16
_trans_2:
| a0 address of plane 0
| a1 address of plane 1
| a4 address of source pixels
| d7 #pixels/16 - 1
moveml a0-a5/d0-d7, sp@- | save the registers
movel _plane, a0
movel _plane+4, a1
movel _tbase, a4
movel _words, d7
next_block2:
moveq #1, d6 | 2 words for 16 pixels
next_word2:
movew a4@+, d4 | get 8 pixels
moveq #7, d5 | 8 pixels/word
next_pixel2:
addw d4, d4 | scatter pixels to 2 planes
addxw d0, d0
addw d4, d4
addxw d1, d1
dbra d5, next_pixel2
dbra d6, next_word2
movew d0, a1@+ | store 1 word of each bit plane
movew d1, a0@+
subql #1, d7
bpl next_block2
moveml sp@+, a0-a5/d0-d7 | restore the registers
rts
_trans_4:
| a0 address of plane 0
| a1 address of plane 1
| a2 address of plane 2
| a3 address of plane 3
| a4 address of source pixels
| d7 #pixels/16 - 1
moveml d0-d7/a0-a5, sp@- | save registers
movel _plane, a0
movel _plane+4, a1
movel _plane+8, a2
movel _plane+12, a3
movel _tbase, a4
movel _words, d7
next_block4:
moveq #3,d6 | 4 words for 16 pixels
next_word4:
movew a4@+,d4 | get 4 pixels
moveq #3,d5 | 4 pixels/word
next_pixel4:
addw d4,d4 | scatter pixels to four planes
addxw d0,d0
addw d4,d4
addxw d1,d1
addw d4,d4
addxw d2,d2
addw d4,d4
addxw d3,d3
dbra d5,next_pixel4
dbra d6,next_word4
movew d0,a3@+ | store 1 word of each bit plane
movew d1,a2@+
movew d2,a1@+
movew d3,a0@+
subql #1,d7
bpl next_block4
moveml sp@+, d0-d7/a0-a5 | restore registers
rts
_trans_8:
| a0 address of planes 0 & 4
| a1 address of planes 1 & 5
| a2 address of planes 2 & 6
| a3 address of planes 3 & 7
| a4 address of source pixels
| a5 pointer to array containing addresses of color planes
| d7 #pixels/16 - 1
moveml d0-d7/a0-a5, sp@- | save registers
movel _tbase, a4
movel #_plane, a5
movel _words, d7
pass_one8: | first pass through the image
moveml a5@(16), a0-a3 | get addresses of second 4 planes
next_block8:
moveq #7, d6 | 8 words for 16 pixels
next_word8:
movew a4@+, d4 | get 2 pixels
addw d4, d4 | scatter to first 4 planes
addxw d0, d0
addw d4, d4
addxw d1, d1
addw d4, d4
addxw d2, d2
addw d4, d4
addxw d3, d3
rolw #4, d4
addw d4, d4
addxw d0, d0
addw d4, d4
addxw d1, d1
addw d4, d4
addxw d2, d2
addw d4, d4
addxw d3, d3
dbra d6, next_word8
movew d0, a3@+ | store 1 word of each bit plane
movew d1, a2@+
movew d2, a1@+
movew d3, a0@+
subql #1, d7
bpl next_block8
pass_two8: | second pass through the image
moveml a5@, a0-a3 | get addresses of first 4 planes
movel _words, d7 | get #pixels/16 - 1
movel _tbase, a4 | get address of source pixels
next_block8_2:
moveq #7, d6 | 8 words for 16 pixels
next_word8_2:
movew a4@+, d4 | get 2 pixels
rolw #4, d4
addw d4, d4 | scatter to last 4 planes
addxw d0, d0
addw d4, d4
addxw d1, d1
addw d4, d4
addxw d2, d2
addw d4, d4
addxw d3, d3
rolw #4, d4
addw d4, d4
addxw d0, d0
addw d4, d4
addxw d1, d1
addw d4, d4
addxw d2, d2
addw d4, d4
addxw d3, d3
dbra d6, next_word8_2
movew d0, a3@+ | store 1 word of each bit plane
movew d1, a2@+
movew d2, a1@+
movew d3, a0@+
subql #1,d7
bpl next_block8_2
moveml sp@+, d0-d7/a0-a5 | restore registers
rts
_trans_16:
| a0 address of planes 0, 4, 8, & 12
| a1 address of planes 1, 5, 9, & 13
| a2 address of planes 2, 6, 10, & 14
| a3 address of planes 3, 7, 11, & 15
| a4 address of source pixels
| a5 pointer to array containing addresses of color planes
| d7 #pixels/16 - 1
moveml d0-d7/a0-a5, sp@- | save registers
movel _tbase, a4
movel #_plane, a5
movel _words, d7
pass_one16: | first pass through the image
moveml a5@(48), a0-a3 | get addresses of last 4 planes
next_block16:
moveq #15, d6 | 16 words for 16 pixels
next_word16:
movew a4@+, d4 | get 1 pixel
addw d4, d4 | scatter to first 4 planes
addxw d0, d0
addw d4, d4
addxw d1, d1
addw d4, d4
addxw d2, d2
addw d4, d4
addxw d3, d3
dbra d6, next_word16
movew d0, a3@+ | store 1 word of each bit plane
movew d1, a2@+
movew d2, a1@+
movew d3, a0@+
subql #1, d7
bpl next_block16
pass_two16: | second pass through the image
moveml a5@(32), a0-a3 | get addresses of next 4 planes
movel _words, d7 | get #pixels/16 - 1
movel _tbase, a4 | get address of source pixels
next_block16_2:
moveq #15, d6 | 16 words for 16 pixels
next_word16_2:
movew a4@+, d4 | get 1 pixel
rolw #4, d4
addw d4, d4 | scatter to last 4 planes
addxw d0, d0
addw d4, d4
addxw d1, d1
addw d4, d4
addxw d2, d2
addw d4, d4
addxw d3, d3
dbra d6, next_word16_2
movew d0, a3@+ | store 1 word of each bit plane
movew d1, a2@+
movew d2, a1@+
movew d3, a0@+
subql #1,d7
bpl next_block16_2
pass_three16: | third pass through the image
moveml a5@(16), a0-a3 | get addresses of next 4 planes
movel _words, d7 | get #pixels/16 - 1
movel _tbase, a4 | get address of source pixels
next_block16_3:
moveq #15, d6 | 16 words for 16 pixels
next_word16_3:
movew a4@+, d4 | get 1 pixel
rolw #8, d4
addw d4, d4 | scatter to last 4 planes
addxw d0, d0
addw d4, d4
addxw d1, d1
addw d4, d4
addxw d2, d2
addw d4, d4
addxw d3, d3
dbra d6, next_word16_3
movew d0, a3@+ | store 1 word of each bit plane
movew d1, a2@+
movew d2, a1@+
movew d3, a0@+
subql #1,d7
bpl next_block16_3
pass_four16: | fourth pass through the image
moveml a5@, a0-a3 | get addresses of first 4 planes
movel _words, d7 | get #pixels/16 - 1
movel _tbase, a4 | get address of source pixels
next_block16_4:
moveq #15, d6 | 16 words for 16 pixels
next_word16_4:
movew a4@+, d4 | get 1 pixel
rorw #4, d4
addw d4, d4 | scatter to last 4 planes
addxw d0, d0
addw d4, d4
addxw d1, d1
addw d4, d4
addxw d2, d2
addw d4, d4
addxw d3, d3
dbra d6, next_word16_4
movew d0, a3@+ | store 1 word of each bit plane
movew d1, a2@+
movew d2, a1@+
movew d3, a0@+
subql #1,d7
bpl next_block16_4
moveml sp@+, d0-d7/a0-a5 | restore registers
rts
");