From 76a54feca05b4d932d950642639a539df19cad19 Mon Sep 17 00:00:00 2001 From: jmcmullan Date: Thu, 14 Feb 2013 05:27:44 +0000 Subject: [PATCH] printer.device: Add TURBOPRINT emulation support Signed-off-by: Jason S. McMullan git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@46596 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- workbench/devs/printer/driver.c | 14 ++ workbench/devs/printer/gfx.c | 155 +++++++++++++++++++- workbench/devs/printer/include/turboprint.h | 41 ++++++ workbench/devs/printer/mmakefile.src | 4 + workbench/devs/printer/printer_intern.h | 2 + workbench/devs/printer/text.c | 6 +- 6 files changed, 216 insertions(+), 6 deletions(-) create mode 100644 workbench/devs/printer/include/turboprint.h diff --git a/workbench/devs/printer/driver.c b/workbench/devs/printer/driver.c index fbfa1a68c0..445be1abed 100644 --- a/workbench/devs/printer/driver.c +++ b/workbench/devs/printer/driver.c @@ -21,6 +21,8 @@ #include #include +#define TPMATCHWORD 0xf10a57ef /* From turboprint's SDK */ + #define CMD_OPENDEVICE (0x100) #define CMD_CLOSEDEVICE (0x101) @@ -537,6 +539,17 @@ static LONG pd_DriverTask(VOID) D(bug("%s: Initializing driver, Unit Port %p\n", __func__, &pd->pd_Unit)); ret = pd_Init(pd); + /* We want to look like a TURBOPRINT driver + * TPMATCHWORD is in the 3rd ULONG in pd_OldStk + * TURBOPRINT was documented as using: + * + * (BOOL)TP_Installed = ( ((ULONG *)(PD->pd_OldStk))[2] == TPMATCHWORD) + * + * So the assumption is that this ULONG is in native endian format. + */ + ((ULONG *)(pd->pd_OldStk))[2] = TPMATCHWORD; + + D(bug("%s: Replying with %d\n", __func__, ret)); msg->mm_Version = ret; ReplyMsg(&msg->mm_Message); @@ -618,6 +631,7 @@ static LONG pd_DriverTask(VOID) err = Printer_Gfx_DumpRPort((struct IODRPReq *)pio, ((struct IODRPTagsReq *)pio)->io_TagList); break; case PRD_DUMPRPORT: + case PRD_TPEXTDUMPRPORT: if (stopped) err = PDERR_CANCEL; else diff --git a/workbench/devs/printer/gfx.c b/workbench/devs/printer/gfx.c index 31013c7810..b98e75551f 100644 --- a/workbench/devs/printer/gfx.c +++ b/workbench/devs/printer/gfx.c @@ -109,6 +109,127 @@ static void pg_FloydDithering(struct driverInfo *di, UBYTE *pdata, LONG width) */ } +ULONG zrgbof(struct ColorMap *cm, ULONG index) +{ + UWORD hibits; + + /* For invalid entries, print white, not black + */ + if (index >= cm->Count) + return 0x00ffffff; + + hibits = cm->ColorTable[index]; + + ULONG red8 = (hibits & 0x0f00) >> 4; + ULONG green8 = (hibits & 0x00f0); + ULONG blue8 = (hibits & 0x000f) << 4; + + if (cm->Type > COLORMAP_TYPE_V1_2) { + UWORD lobits = cm->LowColorBits[index]; + + red8 |= (lobits & 0x0f00) >> 8; + green8 |= (lobits & 0x00f0) >> 4; + blue8 |= (lobits & 0x000f); + } + + return (red8 << 16) | (green8 << 8) | blue8; +} + +/* TurboPrint emulation helper hooks - convert from + * native formats to 0RGB32 longwords + */ +DISPATCHER(TPSlice) +{ + struct DRPSourceMsg *drp = (struct DRPSourceMsg *)msg; + struct IODRPReq *io = (struct IODRPReq *)obj; + struct BitMap *tpbm = io->io_RastPort->BitMap; + UBYTE *src = tpbm->Planes[0]; + ULONG *buf = drp->buf; + UWORD bpr = tpbm->BytesPerRow; + struct ColorMap *cm = io->io_ColorMap; + struct TPExtIODRP *tp = (struct TPExtIODRP *)io->io_Modes; + int w, h; + int bpp; + + switch (tp->Mode) { + case TPFMT_Chunky8: + if (cm == NULL) + return 0; + bpp = 1; + break; + case TPFMT_RGB15: + case TPFMT_BGR15: + case TPFMT_RGB16: + case TPFMT_BGR16: + bpp = 2; + break; + case TPFMT_RGB24: + case TPFMT_BGR24: + bpp = 3; + break; + default: + return 0; + } + + src += (bpr * drp->y); + for (h = 0; h < drp->height; h++, src += bpr) { + UBYTE *sref = src + drp->x * bpp; + for (w = 0; w < drp->width; w++ ) { + ULONG zrgb; + UWORD rgb15, rgb16; + + switch (tp->Mode) { + case TPFMT_Chunky8: + zrgb = zrgbof(cm, *(sref++)); + break; + case TPFMT_RGB15: + rgb15 = (*(sref++)) << 8; + rgb15 |= *(sref++); + goto rgb15; + case TPFMT_BGR15: + rgb15 = *(sref++); + rgb15 |= (*(sref++)) << 8; +rgb15: + zrgb = ((((rgb15 >> 10) & 0x1f)<<3) << 16) | + ((((rgb15 >> 5) & 0x1f)<<3) << 8) | + ((((rgb15 >> 0) & 0x1f)<<3) << 0); + break; + case TPFMT_RGB16: + rgb16 = (*(sref++)) << 8; + rgb16 |= *(sref++); + goto rgb16; + case TPFMT_BGR16: + rgb16 = *(sref++); + rgb16 |= (*(sref++)) << 8; +rgb16: + zrgb = ((((rgb16 >> 11) & 0x1f)<<3) << 16) | + ((((rgb16 >> 5) & 0x3f)<<2) << 8) | + ((((rgb16 >> 0) & 0x1f)<<3) << 0); + break; + case TPFMT_RGB24: + zrgb = (*(sref++) << 16); + zrgb |= (*(sref++) << 8); + zrgb |= (*(sref++) << 0); + break; + case TPFMT_BGR24: + zrgb = (*(sref++) << 0); + zrgb |= (*(sref++) << 8); + zrgb |= (*(sref++) << 16); + break; + default: + zrgb = 0x00ffffff; + break; + } + + *(buf++) = zrgb; + } + } + + return (buf - drp->buf); +} + +MakeStaticHook(TPHook, TPSlice); + LONG Printer_Gfx_DumpRPort(struct IODRPReq *io, struct TagItem *tags) { struct PrinterData *pd = (struct PrinterData *)io->io_Device; @@ -153,7 +274,33 @@ LONG Printer_Gfx_DumpRPort(struct IODRPReq *io, struct TagItem *tags) return err; /* Get the source's aspect ratio */ - if (io->io_Modes != INVALID_ID) { + if (io->io_Command == PRD_TPEXTDUMPRPORT) { + struct TPExtIODRP *tp = (APTR)io->io_Modes; + if (tp == NULL) + return PDERR_NOTGRAPHICS; + aspectXsrc = tp->PixAspX; + aspectYsrc = tp->PixAspY; +bug("tp->Mode = 0x%04x\n", tp->Mode); + switch (tp->Mode) { + case TPFMT_Chunky8: + case TPFMT_BGR15: + case TPFMT_BGR16: + case TPFMT_BGR24: + case TPFMT_RGB15: + case TPFMT_RGB16: + case TPFMT_RGB24: + srcHook = &TPHook; + break; + case TPFMT_CyberGraphX: + case TPFMT_BitPlanes: + case TPFMT_HAM: + case TPFMT_EHB: + srcHook = NULL; /* AROS BitMap object - we can handle this */ + break; + default: + return PDERR_NOTGRAPHICS; + } + } else if (io->io_Modes != INVALID_ID) { struct DisplayInfo dpyinfo; if (GetDisplayInfoData(NULL, (APTR)&dpyinfo, sizeof(dpyinfo), DTAG_DISP, io->io_Modes)) { @@ -451,10 +598,10 @@ LONG Printer_Gfx_DumpRPort(struct IODRPReq *io, struct TagItem *tags) pi->pi_ColorInt = pdata; pi->pi_ColorIntSize = prnW * di.di_ColorSize; - if ((bm = AllocBitMap(prnW, prnH, -1, 0, io->io_RastPort->BitMap))) { + if ((bm = AllocBitMap(prnW, prnH, src_bm->Depth, 0, src_bm))) { /* Render it ourselves */ struct BitScaleArgs bsa = { - .bsa_SrcBitMap = io->io_RastPort->BitMap, + .bsa_SrcBitMap = src_bm, .bsa_SrcX = io->io_SrcX, .bsa_SrcY = io->io_SrcY, .bsa_SrcWidth = io->io_SrcWidth, @@ -518,7 +665,7 @@ LONG Printer_Gfx_DumpRPort(struct IODRPReq *io, struct TagItem *tags) D(bug("\tCan't find nor synthesize a source bitmap\n")); } - RENDER(err, io->io_Special, 0, PRS_CLOSE); + RENDER((SIPTR)err, io->io_Special, 0, PRS_CLOSE); } return err; diff --git a/workbench/devs/printer/include/turboprint.h b/workbench/devs/printer/include/turboprint.h new file mode 100644 index 0000000000..b96b13c44b --- /dev/null +++ b/workbench/devs/printer/include/turboprint.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013, The AROS Development Team + * All right reserved. + * Author: Jason S. McMullan + * + * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1 + */ + +#ifndef TURBOPRINT_H +#define TURBOPRINT_H + +#ifndef DEVICES_PRINTER_H +#include +#endif /* DEVICES_PRINTER_H */ + +#define TPFMT_BitPlanes 0x0000 +#define TPFMT_Chunky8 0x0001 +#define TPFMT_BGR15 0x0002 +#define TPFMT_BGR16 0x0003 +#define TPFMT_BGR24 0x0004 +#define TPFMT_RGB15 0x0012 +#define TPFMT_RGB16 0x0013 +#define TPFMT_RGB24 0x0014 + +#define TPFMT_HAM 0x0800 +#define TPFMT_EHB 0x0080 +#define TPFMT_CyberGraphX 0x0400 + +#define TPMATCHWORD 0xf10a57ef + +#define PRD_TPEXTDUMPRPORT (PRD_DUMPRPORT | 0x80) + +/* struct IODRPReq io_Modes must point to this structure */ + +struct TPExtIODRP { + UWORD PixAspX; /* X Aspect */ + UWORD PixAspY; /* Y Aspect - together they make the acpect ratio */ + UWORD Mode; /* TPFMT_* mode */ +}; + +#endif /* TURBOPRINT_H */ diff --git a/workbench/devs/printer/mmakefile.src b/workbench/devs/printer/mmakefile.src index 818f1b097c..7fb1ecc30a 100644 --- a/workbench/devs/printer/mmakefile.src +++ b/workbench/devs/printer/mmakefile.src @@ -13,4 +13,8 @@ FILES := printer driver prefs gfx text modname=printer modtype=device \ files=$(FILES) +INCLUDE_FILES = include/turboprint.h + +%copy_includes path= dir=include + %common diff --git a/workbench/devs/printer/printer_intern.h b/workbench/devs/printer/printer_intern.h index 4bff1917bc..9749868ba4 100644 --- a/workbench/devs/printer/printer_intern.h +++ b/workbench/devs/printer/printer_intern.h @@ -17,6 +17,8 @@ #include #include +#include + /*********************************************************************************************/ struct PrinterBase; diff --git a/workbench/devs/printer/text.c b/workbench/devs/printer/text.c index cbb8ce118c..8c4ddec439 100644 --- a/workbench/devs/printer/text.c +++ b/workbench/devs/printer/text.c @@ -154,10 +154,12 @@ LONG Printer_Text_Command(struct PrinterData *pd, UWORD command, UBYTE p0, UBYTE CONST_STRPTR *Commands = pd->pd_Device.dd_CmdVectors; LONG CommandMax = pd->pd_Device.dd_NumCommands; /* Use pd_Stack as the command buffer */ - UBYTE *buff[2] = { (UBYTE *)&pd->pd_Stk[0], (UBYTE *)&pd->pd_OldStk }; + /* pd_OldStk[8..11] is used for the 'TPMATCHWORD' magic + */ + UBYTE *buff[2] = { (UBYTE *)&pd->pd_Stk[0], (UBYTE *)&pd->pd_OldStk[12] }; int buffsel = 0; UBYTE *buffer = buff[buffsel]; - LONG buffmax = ((P_STKSIZE > P_OLDSTKSIZE) ? P_OLDSTKSIZE : P_STKSIZE)/2; + LONG buffmax = ((P_STKSIZE > (P_OLDSTKSIZE-12)) ? (P_OLDSTKSIZE-12) : P_STKSIZE)/2; CONST_STRPTR cmd; LONG blen = 0; UBYTE parm[4] = { p0, p1, p2, p3 };