billk@pnet01.UUCP (Bill Kelly) (07/18/87)
[Note that I changed Bill's method of sending the files, so his README file is not quite accurate. I split the sources from the objects and posted the objects in comp.binaries.amiga -Doc] # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # README # Warp.c # WarpC.asm # WarpText.asm # WarpText.doc # WarpText.h # WarpText.i # This archive created: Sat Jul 18 02:45:19 1987 # By: Craig Norborg (Purdue University Computing Center) cat << \SHAR_EOF > README ReadMe for WarpText version 2.0 Bill Kelly 07Jul87 Hi. I've been having a few problems with my assembler. I wrote an example program to open up a window and a screen and then do some WarpText into it. For some reason, the assembler would do strange things to the code on the second pass, including not assembling the data. After a while it would give up with some "Error 500" which it said was an unknown error and that I should report it. I didn't see anything about this kind of thing in the manual and haven't been able to make it work. It did assemble WarpText, however, and I was able to test the routines interactively with Forth. They all work fine. Here is a list of the files that should be in WarpText.ARC: WarpText.doc WarpText.asm WarpText.h WarpText.i Warp.C WarpC.asm Warp WarpText.obj README WarpText.doc: A small bit of documentation on the routines, plus a copyright notice, thank-you notes, information on distributing WarpText, my address, etc. Please read this file. (At least the first part, anyway...) Thanks. WarpText.asm: The WarpText routines. There is documentation telling how to call each routine at the beginning of each routine. WarpText.h: The 'C' include for WarpText, written by Anson Mah. WarpText.i: The assembler include for WarpText. Warp.C: A quick test of the original WarpText routines, written by Anson Mah. WarpC.asm: A 'C' interface to the WarpText routines. Makes them easily callable from 'C' -- written by Anson Mah. Warp: Executable for the file "Warp.C" -- this program only demonstrates the pre-release WarpText routines. The NewWarp (version 2.0) routines did not exixt when Anson wrote Warp.C. NewWarp is close to twice as fast as the routines demoed by this program. WarpText.obj: Assembley of the file "WarpText.asm" -- assembled with the symbols, and ready to link! :-) README: Exactly. That's just what you're doing. Enjoy the routines -- I hope they will be useful! Bill Kelly. SHAR_EOF cat << \SHAR_EOF > Warp.c /* WarpText Quickie Test Anson Mah 06/08/87 * For Lattice C * * NOTE: This test does not use any of the WarpText 2.0 routines as * they did not exist when Anson wrote this. * I made an example program for all of the routines but I * couldn't get the $#%! assembler to assembler it! It kept * giving me all sorts of strange errors on the second pass. * I was able to test all the routines interactively in Forth * so, while I know the new (and old) routines work, I have no * program to give out that demonstrates them... Sorry, * Bill. */ #include <exec/types.h> #include <exec/memory.h> #include <intuition/intuition.h> #include "graphics/WarpText.h" extern void InitWarpInfo(), GotoXY(), GetXY(), WarpText(); struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase = NULL; struct Window *w = NULL; struct WarpInfo *winfo = NULL; struct TextAttr taTopaz80 = { "topaz.font", 8, FS_NORMAL, FPF_ROMFONT }; struct NewWindow wdef = { 0,0,640,200, 0,1, CLOSEWINDOW, WINDOWDRAG | WINDOWCLOSE | WINDOWDEPTH | SMART_REFRESH | ACTIVATE, NULL, NULL, "WarpText Test", NULL, NULL, 0,0,640,200, WBENCHSCREEN }; void closestuff() { if (winfo) FreeMem(winfo, sizeof(struct WarpInfo)); if (w) CloseWindow(w); if (GfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibrary(IntuitionBase); XCEXIT(0); } void openstuff() { if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 33))) closestuff(); if (!(GfxBase = (struct GfxBase *)OpenLibrary( "graphics.library", 33))) closestuff(); if (!(winfo = (struct WarpInfo *)AllocMem(sizeof(struct WarpInfo), MEMF_PUBLIC))) closestuff(); if (!(w = (struct Window *)OpenWindow(&wdef))) closestuff(); } ULONG strlen(s) char *s; { ULONG i = 0; while (*s++) i++; return(i); } void _main() { static char *text[17]; struct IntuiMessage *msg; ULONG class; UWORD i; openstuff(); text[0] = "Hi, Bill!\n"; text[1] = " Thanx for your WarpText routines. As you can see, this\n"; text[2] = "is a quick test of 'em. The only routine I don't use is\n"; text[3] = "GetXY. Also note that I have created a WarpText.h file for\n"; text[4] = "C programmers like yours truly and also a C interface\n"; text[5] = "module for the same people! Please do what you will with\n"; text[6] = "them.\n"; text[7] = " Right. I've looked over your code and can't see any\n"; text[8] = "immediate improvements, but I may if I study them longer.\n"; text[9] = "Actually, I believe you might gain some more speed if you\n"; text[10] = "start using the Blitter instead. It was made to handle\n"; text[11] = "stuff like this. You should be able to get upward of\n"; text[12] = "30,000 chars/sec if you use it. This number was measured\n"; text[13] = "with the set of routines my friends came up with a while\n"; text[14] = "back. It's fairly accurate.\n"; text[15] = " Anyway, more when I have more time to hack!\n"; text[16] = " Anson"; /* set up WarpInfo */ winfo->wi_TextFont = (APTR)OpenFont(&taTopaz80); winfo->wi_BitMap = (APTR)&w->WScreen->BitMap; winfo->wi_WhichPlane = 0; winfo->wi_Left = 10; winfo->wi_Top = 3; winfo->wi_Width = 60; winfo->wi_Height = 21; InitWarpInfo(winfo); /* warp out text */ for (i = 0; i < 17; i++) WarpText(winfo, text[i], strlen(text[i])); GotoXY(winfo, 25, 19); WarpText(winfo, "Hey, I'm here!", 14); GotoXY(winfo, 10, 20); WarpText(winfo, "And here!!", 10); CloseFont(winfo->wi_TextFont); for (;;) { WaitPort(w->UserPort); msg = (struct IntuiMessage *)GetMsg(w->UserPort); ReplyMsg(msg); class = msg->Class; switch (class) { case CLOSEWINDOW: closestuff(); break; } } } void MemCleanup() {} /* Lattice stub */ SHAR_EOF cat << \SHAR_EOF > WarpC.asm * ------------------------------------------------------- * WarpC.asm -- C Interface For WarpText Routines * Written by Anson Mah 06/08/87 * * Interface to WarpText 2.0 added 06Jul87 by billk. * Actually, I don't think the 2.0 interface I just wrote * will be very useful. Ah well. It's there, do what you * will with it... Bill. * ------------------------------------------------------- XDEF _InitWarpInfo XDEF _GotoXY XDEF _GetXY XDEF _WarpText XDEF _SetupFont ;WarpText 2.0 XDEF _NewWarp ;WarpText 2.0 XDEF _XORCursor ;WarpText 2.0 XREF InitWarpInfo XREF GotoXY XREF GetXY XREF WarpText XREF SetupFont ;WarpText 2.0 XREF NewWarp ;WarpText 2.0 XREF XORCursor ;WarpText 2.0 * ---------------------------------------------------- * Call: InitWarpInfo(winfo); * struct WarpInfo *winfo; * ---------------------------------------------------- _InitWarpInfo: move.l 4(a7),a0 ; get pointer to WarpInfo jsr InitWarpInfo rts * ---------------------------------------------------- * Call: GotoXY(winfo, x, y); * struct WarpInfo *winfo; * UWORD x, y; * ---------------------------------------------------- _GotoXY: move.l 04(a7),a0 ; get pointer to WarpInfo move.l 08(a7),d0 ; get new X position move.l 12(a7),d1 ; get new Y position jsr GotoXY rts * ---------------------------------------------------- * Call: GetXY(winfo, &x, &y); * struct WarpInfo *winfo; * UWORD x, y; * ---------------------------------------------------- _GetXY: move.l 04(a7),a0 ; get pointer to WarpInfo jsr GetXY move.l 08(a7),a0 ; get address of x variable move.w d0,(a0) ; store x coordinate move.l 12(a7),a0 ; get address of y variable move.w d1,(a0) ; store y coordinate rts * ---------------------------------------------------- * Call: WarpText(winfo, text, len); * struct WarpInfo *winfo; * char *text; /* pointer to string */ * ULONG len; /* length of string */ * ---------------------------------------------------- _WarpText: move.l 04(a7),a0 move.l 08(a7),a1 move.l 12(a7),d0 jsr WarpText rts * ------------------------------------------------------ * Call: SetupFont(nwinfo, tf); WT 2.0 * struct NewWarpInfo *nwinfo; billk * struct TextFont *tf; /* pointer to open font */ * ------------------------------------------------------ _SetupFont: jmp SetupFont rts * ------------------------------------------------------ * Call: NewWarp(nwinfo, text, len); WT 2.0 * struct NewWarpInfo *nwinfo; billk * char *text; /* pointer to string */ * ULONG len; /* length of string */ * ------------------------------------------------------ _NewWarp: jmp NewWarp rts * ------------------------------------------------------ * Call: XORCursor(nwinfo, text, len); WT 2.0 * struct NewWarpInfo *nwinfo; billk * ------------------------------------------------------ _XORCursor: jmp XORCursor rts END * ------------------ * * End of "WarpC.asm" * * ------------------ * SHAR_EOF cat << \SHAR_EOF > WarpText.asm * -------------------------------------------------------------------------- * WarpText.asm Version 2.0 Bill Kelly * 07/07/87 * * Copyright 1987 by Bill W. Kelly. * XDEF InitWarpInfo XDEF GotoXY XDEF GetXY XDEF WarpText XDEF SetupFont XDEF NewWarp XDEF XORCursor NOLIST ; I don't want to see all of this junque... INCLUDE "graphics/text.i" INCLUDE "graphics/gfx.i" INCLUDE "graphics/WarpText.i" LIST ; Turn listing back on... CODE ; WarpText begins... * ========================================================================== * * | __ ___ __ __ | * | / \ / / \ / / /| / \ / \ | * \|/ / / / / / / / / /_| /\__/ /\__/ \|/ * V \__/ /___ /___/ \/\/ / | / \ / V * * -------------------------------------------------------------------------- * InitWarpInfo: * ------------- * * INITWARPINFO NEEDS: * * a0 - Pointer to an instance of the WarpInfo structure, with the following * fields initialized: * * wi_TextFont: Pointer to an open font. (I.e. what OpenFont() returns * to you, other than NULL.) * wi_BitMap: Pointer to an initialized, 'working' BitMap structure. * (E.g. Open a window. Get the pointer to the screen * out of wd_WScreen. From there the BitMap structure is * at sc_BitMap, which is an offset, not a pointer, into * the Screen structure.) * wi_WhichPlane: Which bitplane you want the routine to draw into. * Numbering begins at zero. On the Workbench screen * (or any two-bitplane screen) the possible numbers for * wi_WhichPlane are 0 and 1. * wi_Left: Left edge of the 'window' (in character locations) * you want the routine to write into. * wi_Top: Top edge of the 'window' in character locations. * wi_Width: Width of 'window' (also on character locations). * wi_Height: Height of 'window' -- guess what? Character locations. * * REGISTER USAGE FOR INITWARPINFO: * * d0 - Left, Top, Width, Height, etc. * d1 - wi_Modulo * d2 - Scratch * d3 - Y size of font * d4 - Scratch * * a0 - Pointer to WarpInfo structure with above fields initialized. * a1 - Addr of top of bitplane, wi_WindowTop, etc. * a2 - Scratch * InitWarpInfo: movem.l d0-d4/a1-a2,-(sp) moveq #0,d4 ; Clear scratch. move.w d4,wi_CurX(a0) ; Store it in WarpInfo. move.w wi_Width(a0),wi_LastX(a0) ; Max X position. sub.w #1,wi_LastX(a0) ; make it 0-relative. move.l wi_BitMap(a0),a1 ; Get some stuff from bmap. moveq #0,d2 move.w bm_BytesPerRow(a1),d2 ; #bytes per row in d2 move.w d2,wi_BPMod(a0) ; #bytes per row->wi_BPMod move.w wi_WhichPlane(a0),d4 ; Get bitplane#. asl.l #2,d4 ; Multiply plane# by four. move.l bm_Planes(a1,d4.l),a1 ; Get address of bitplane. moveq #0,d3 move.l wi_TextFont(a0),a2 move.w tf_YSize(a2),d3 ; Get YSize of font. moveq #0,d1 move.l d2,d1 ; Copy bytesperrow to d1. mulu.w d3,d1 ; YSize*BytesPerRow. move.w d1,wi_Modulo(a0) ; Store it in WarpInfo. moveq #0,d4 move.l d1,d4 ; Copy wi_modulo to scratch. mulu.w wi_Top(a0),d4 ; Mul by Y offset. add.w wi_Left(a0),d4 ; Add X offset. move.l a1,a2 ; BPlane addr to scratch. add.l d4,a2 ; Add offset to btpln addr. move.l a2,wi_WindowTop(a0) ; Stick in WarpInfo. move.l a2,wi_CurLine(a0) ; Stick in WarpInfo. moveq #0,d2 move.w wi_Top(a0),d2 ; Copy Y top to scratch. add.w wi_Height(a0),d2 ; Add Y height to Y top. move.l d1,d4 ; Copy wi_modulo to scratch. mulu.w d2,d4 ; Mul by Y offset. add.w wi_Left(a0),d4 ; Add X offset. move.l a1,a2 ; BPlane addr to scratch. add.l d4,a2 ; Add offset to btpln addr. move.l a2,wi_LastLine(a0) ; Stick in WarpInfo. movem.l (sp)+,d0-d4/a1-a2 rts * * -------------------------------------------------------------------------- * -------------------------------------------------------------------------- * GotoXY: * ------- * * GOTOXY NEEDS: * * d0 - New X position. \ All regs. but d1 preserved, * d1 - New Y position. * * a0 - Pointer to initialized WarpInfo structure. * * NOTE: These positions are given in character locations, like everything * else... The positions are relative to the 'window' you have * defined using InitWarpInfo. Position 0,0 is the character in the * top left corner of the window. * This routine does no error checking. (You're supposed to know * how big your window is...) * GotoXY: move.w d0,wi_CurX(a0) ; Set new X position. mulu.w wi_Modulo(a0),d1 ; Make Y an offset into window add.l wi_WindowTop(a0),d1 ; Add this offset to the window move.l d1,wi_CurLine(a0) ; to make it the new Y position. rts * * -------------------------------------------------------------------------- * -------------------------------------------------------------------------- * GetXY: * ------ * * GETXY NEEDS: * * a0 - Pointer to an initialized WarpInfo structure. * * It returns the current X position in d0 and the current Y * position in d1. * GetXY: move.l wi_CurLine(a0),d1 ; Get current Y addr sub.l wi_WindowTop(a0),d1 ; Sub window to get Y offset. divu.w wi_Modulo(a0),d1 ; Should not be a remainder. moveq #0,d0 move.w wi_CurX(a0),d0 ; Get current X position. rts * * -------------------------------------------------------------------------- * -------------------------------------------------------------------------- * WarpText: * --------- * * WARPTEXT NEEDS: * * d0 - Number of characters to type. (count) * * a0 - Pointer to an initialized WarpInfo structure. (See InitWarpInfo) * a1 - Address of string of characters to type. * * REGISTER USAGE FOR WARPTEXT: (All regs preserved but d0 which will be 0) * * d0 - Number of characters to type (count) * d1 - Character to be emitted * d2 - LoChar * d3 - HiChar * d4 - Current X position * d5 - Scratch * d7 - Bitplane modulo: add to get to next raster line in bitplane. * * a0 - Pointer to WarpInfo structure * a1 - Address of string of characters to type * a2 - Pointer to TextFont structure, address of tf_CharData * a3 - Addr of Current line. * a4 - Scratch * a5 - Scratch * * STACK USAGE FOR WARPTEXT: * * 0(sp) - Last line * 4(sp) - Top line * 8(sp) - tf_YSize * 12(sp) - tf_Modulo: add it to get to next line in font data * 16(sp) - wi_Modulo: add it to get to next line in bitplane 'window' * 20(sp) - Maximum (last) possible X position on a line * sp_LastLine: equ 0 ; Offsets into stack to get at this data. sp_TopLine: equ 4 sp_YSize: equ 8 sp_tf_Mod: equ 12 sp_wi_Mod: equ 16 sp_LastX: equ 20 NoChar: equ 256 ; I thought this was where the "empty-box" ; character was. It isn't. Anyone know where ; it is? Or am I supposed to generate it ; myself???? WarpText: movem.l d1-d5/d7/a2-a5,-(sp) moveq #0,d4 move.w wi_CurX(a0),d4 ; Get current X position. moveq #0,d5 move.w wi_LastX(a0),d5 ; Get maximum X position. move.l d5,-(sp) ; Stick it on stack. (1st item) move.w wi_Modulo(a0),d5 ; Get wi_Modulo. move.l d5,-(sp) ; Stick it on stack. (2nd item) move.l wi_TextFont(a0),a2 ; Use TextFont to get some stuff: moveq #0,d2 move.b tf_LoChar(a2),d2 ; Get tf_LoChar. moveq #0,d3 move.b tf_HiChar(a2),d3 ; Get tf_HiChar. move.w tf_Modulo(a2),d5 ; Get tf_Modulo. move.l d5,-(sp) ; Stick it on stack. (3rd item) move.w tf_YSize(a2),d5 ; Get tf_YSize move.l d5,-(sp) ; Stick it on stack. (4th item) move.l tf_CharData(a2),a2 ; Replace textfont w/ tf_Chardata. move.l wi_WindowTop(a0),a4 ; Get addr of wi_WindowTop. move.l a4,-(sp) ; Stick it on stack. (5th item) move.l wi_LastLine(a0),a4 ; Get addr of wi_LastLine. move.l a4,-(sp) ; Stick it on stack. (6th item) move.l wi_CurLine(a0),a3 ; Get addr of wi_CurLine. moveq #0,d7 move.w wi_BPMod(a0),d7 ; Get wi_BPMod. subq #1,d0 ; Take one from count. moveq #0,d1 ; Clear d1 because using .b size. subq #1,d4 ; Take one from Current X. DoNextChar: addq #1,d4 ; Add 1 to Current X. DoNextSinAdd: move.b (a1)+,d1 ; Move char to emit to d1. cmpi.b #32,d1 ; Is it a space? beq Blank cmp.b d2,d1 ; Compare with LoChar. blt BoffoChar ; May be a LF, FF, CR, etc. cmp.b d3,d1 ; Compare with HiChar. blt DoNoChar move.l a2,a4 ; Copy tf_CharData to scratch. sub.l d2,d1 ; Sub LoChar from char. adda.l d1,a4 ; Add char to tf_CharData. DoChar: move.l a3,a5 ; Copy current line to scratch. adda.l d4,a5 ; Add XPos to current line. move.l sp_YSize(sp),d5 ; YSize is loop count. subq.l #1,d5 MoveChar: move.b (a4),(a5) ; Move line of char to bitplane. adda.l sp_tf_Mod(sp),a4 ; Add tf_Modulo to tf_Chardata. adda.l d7,a5 ; Add wi_BPMod to bitplane. dbra d5,MoveChar Blank: cmp.l sp_LastX(sp),d4 ; Compare max X and Current X... blt GotoDoNext ; Do next if current < max. DoLF: moveq #0,d4 ; Xpos is zero now. DoCR: cmpa.l (sp),a3 ; CMP sp_LastLine with current. beq GotoNSA ; Wrap on line if equ. adda.l sp_wi_Mod(sp),a3 ; Point at next line. bra GotoNSA ; Do another character. DoNoChar: move.l a2,a4 ; Copy tf_Chardata to scratch. add.l #NoChar,a4 ; Point at empty-box char. bra DoChar ; Do the empty-box char. BoffoChar: cmpi.l #10,d1 ; Is is a linefeed? beq DoLF cmpi.l #12,d1 ; Is it a formfeed? beq DoFF cmpi.l #13,d1 ; Is it a CR? beq DoCR bra DoNoChar ; Fine. Put up the box. DoFF: moveq #0,d4 ; Make X pos zero. | It doesn't move.l sp_TopLine(sp),a3 ; Point at top | CLS yet. bra GotoNSA GotoDoNext: dbra d0,DoNextChar ; Keep looping? bra WindUp ; Loop is done. Clean up & bail. GotoNSA: dbra d0,DoNextSinAdd ; Do NextChar without adding. WindUp: addq.l #8,sp ; Get rid of stuff kept on stack. addq.l #8,sp addq.l #8,sp move.w d4,wi_CurX(a0) ; Store current X for next time. move.l a3,wi_CurLine(a0) ; Store current Y for next time. movem.l (sp)+,d1-d5/d7/a2-a5 rts * * ========================================================================== * ========================================================================== * * | ___ __ __ | * | /| / / / / / / /| / \ / \ | * \|/ / | / /--- / / / / / / /_| /\__/ /\__/ \|/ * V / |/ /___ \/\/ \/\/ / | / \ / V * * -------------------------------------------------------------------------- * SetupFont: * ---------- * Call with NewWarpInfo and TextFont on the stack. * (TextFont should be on top) * * You must allocate a 2048 byte buffer (does not have to reside in CHIP RAM) * and store its address into the nwi_FontData field of the NewWarpInfo * structure prior to calling SetupFont. * SetupFont will take the font data from the pointer to the FontData * structure you supply on the stack and rearrange it into the 2048 byte * array. It is not a smart routine -- it is set up to unpack only the * Topaz 8 font, or any 8x8 font with the same number of characters as topaz * and the same modulo. If you want to use an 8x8 font that has different * number of characters defined and a different modulo, you will have to * modify the SetupFont code. * SetupFont: movem.l d0/a0-a3,-(sp) ;Save used regs move.l 24(sp),a2 ;FontData kept in a2 move.l 28(sp),a1 ;NewWarpInfo kept in a1 move.l nwi_FontData(a1),a0 ;array to rearrange font into move.l #31,d0 ;number of blank chars. TheUnCola: move.b #$FE,(a0)+ ;$FE = %11111110 move.b #$C6,(a0)+ ;$C6 = %11000110 move.b #$C6,(a0)+ ;$C6 = %11000110 move.b #$C6,(a0)+ ;$C6 = %11000110 move.b #$C6,(a0)+ ;$C6 = %11000110 move.b #$C6,(a0)+ ;$C6 = %11000110 move.b #$FE,(a0)+ ;$FE = %11111110 move.b #$00,(a0)+ ;$00 = %00000000 dbf d0,TheUnCola ;Get the picture? :-) move.l tf_CharData(a2),a2 ;get addr of the font data move.l a2,a3 ;save for later loops moveq #0,d0 ;zero is 1st char in chardata DoAnother: add.w d0,a2 ;add char offset to chardata move.b (a2),(a0)+ ;begin copying char into array add.w #192,a2 ;add tf_modulo for next byte move.b (a2),(a0)+ add.w #192,a2 move.b (a2),(a0)+ add.w #192,a2 move.b (a2),(a0)+ add.w #192,a2 move.b (a2),(a0)+ add.w #192,a2 move.b (a2),(a0)+ add.w #192,a2 move.b (a2),(a0)+ add.w #192,a2 move.b (a2),(a0)+ ;finished copying this character move.l a3,a2 ;point to chardata again addq.b #1,d0 ;add one for next character cmp.w #223,d0 ;need to stop after 223rd char ble.s DoAnother movem.l (sp)+,d0/a0-a3 ;restore used regs rts * * -------------------------------------------------------------------------- * -------------------------------------------------------------------------- * NewWarp: * -------- * Call with NewWarpInfo, String-address, and String-count on the stack. * (String-count should be on top) * * You must have called SetupFont AND have filled in the nwi_BitPlane * field in the NewWarpInfo structure before you call NewWarp. * It would be a good idea, also, to make sure you've set up nwi_XLoc * and nwi_YLoc to the correct places before you go writing text. * They are character-position relative, rather than pixel relative. * Setting nwi_XLoc and nwi_XLoc to 8,8 for example, would be like telling * the Graphics library Text() routine to write text at 80,80. * Another note: Unlike Text(), NewWarp writes directly into a bitplane * and does not do clipping at the edges of rastports. This makes * NewWarp very fast, but less flexible. I have found it easiest to * use the WarpText routines in SUPER_BITMAP windows. * NewWarp: movem.l d0-d3/a0-a4,-(sp) ;save used registers move.l 40(sp),d3 ;String-count kept in d3 move.l 44(sp),a2 ;String-addr kept in a2 move.l 48(sp),a4 ;NewWarpInfo kept in a4 move.w nwi_XLoc(a4),d0 ;move to d0 before incrementing add.w d3,nwi_XLoc(a4) ;increment XLoc like Text() subq.w #1,d3 ;adjust count for dbf move.w nwi_YLoc(a4),d1 move.l nwi_BitPlane(a4),a0 move.l nwi_FontData(a4),a1 move.l a1,a3 ;safe keeping of FontData asl.w #7,d1 ;This multiplies YLoc move.w d1,d2 ;times 640 in 26 cycles asl.w #2,d1 ;instead of the 74 cycles add.w d2,d1 ;a MULU would take. add.w d0,d1 ;Add XLOC to expanded YLOC. add.w d1,a0 ;Add LOC offset to bitplane. OnceAgain: moveq #0,d0 move.b (a2)+,d0 ;Put character in d0. asl.w #3,d0 ;Make offset into FontData add.w d0,a1 ;Add offset to fontData address. move.b (a1)+,(a0) ;Start moving the font data add.w #80,a0 ;into the bitmap... move.b (a1)+,(a0) add.w #80,a0 move.b (a1)+,(a0) add.w #80,a0 move.b (a1)+,(a0) add.w #80,a0 move.b (a1)+,(a0) add.w #80,a0 move.b (a1)+,(a0) add.w #80,a0 move.b (a1)+,(a0) add.w #80,a0 move.b (a1)+,(a0) ;Finished moving data. sub.w #559,a0 ;restore a0 to next char loc move.l a3,a1 ;restore a1 to FontData dbf d3,OnceAgain movem.l (sp)+,d0-d3/a0-a4 ;restore used registers rts * * -------------------------------------------------------------------------- * -------------------------------------------------------------------------- * XORCursor: * ---------- * Call with NewWarpInfo on the stack. * * You must have called SetupFont AND have filled in the nwi_BitPlane * field in the NewWarpInfo structure before you call XORCursor. * XORCursor XOR's a console-device-like cursor to the current xy location. * To get the cursor to be a different color than the Text you've been * emitting with NewWarp you have to change the bitplane being pointed to * by nwi_BitPlane. I thought of adding another APTR to the end of * the NewWarpInfo structure called nwi_CursorPlane that you could set * to point to a different bitplane which would only be used only * by XORCursor. I haven't yet, as I want to get this stuff out. * If you would like to, feel free to do so. * XORCursor: movem.l d0-d1/a0-a1,-(sp) ;Save used registers move.l 20(sp),a1 ;NewWarpInfo kept in a1 move.w nwi_YLoc(a1),d0 move.l nwi_BitPlane(a1),a0 asl.w #7,d0 ;This multiplies YLoc move.w d0,d1 ;times 640 in 26 cycles asl.w #2,d0 ;instead of the 74 cycles add.w d1,d0 ;a MULU would take. add.w nwi_XLoc(a1),d0 ;Add XLOC to expanded YLOC. add.w d0,a0 ;Add LOC offset to bitplane. eor.b #$FF,(a0) ;XOR the cursor... add.w #80,a0 eor.b #$FF,(a0) add.w #80,a0 eor.b #$FF,(a0) add.w #80,a0 eor.b #$FF,(a0) add.w #80,a0 eor.b #$FF,(a0) add.w #80,a0 eor.b #$FF,(a0) add.w #80,a0 eor.b #$FF,(a0) add.w #80,a0 eor.b #$FF,(a0) movem.l (sp)+,d0-d1/a0-a1 ;restore used registers rts * * ========================================================================== END ; WarpText ends. * --------------------- * * End of "WarpText.asm" * * --------------------- * SHAR_EOF cat << \SHAR_EOF > WarpText.doc WarpText.doc WT 2.0 Bill Kelly 07/06/87 // // ////// ////// ////// //////// ////// ||// //////// // // // // // // // // // // |// // // / // ////// ////// ////// // ///// // // // /// // // // // // // // // //| // /// /// // // // // // // ////// //|| // THANK YOU'S: (in alphabetical order) Thanks to Anson Mah for writing the WarpText 'C' interface. Without him, there wouldn't be one -- I don't speak C! Thanks to Aaron Avery for taking my original unreleased WarpText routine, which was fast but not fancy, and speeding it up immensely. This routine, (after I sped it up even more by rearranging the font data), and Aaron's cursor routine, are WarpText 2.0. Thanks to Hayes C. Haugen who, by writing Blitz, reminded me of what text on a computer like this *ought* to be like and so got me started on WarpText. Thanks to Leon Frankel (sorry if I got the name wrong -- that's what it sounded like over the phone) for reporting a bug in the wi_Width handling in the WarpText prerelease routines. (Please see "BUGS:" for more information.) If I forgot anyone -- sorry. Thanks to you, too! COPYRIGHT NOTICE: The WarpText code, and the name "WarpText," is Copyright 1987 by Bill W. Kelly. DISTRIBUTION INFORMATION: Feel free to distribute this code, complying with the following restriction: Since there are many files in this release of WarpText, please distribute them in ARCed form so that no files get lost. (If you need to UUEncode, please UUEncode the ARC file.) Thanks! NOTE: IF YOU ARE GOING TO MODIFY THE CODE, please make a little note containing the date, your comments, and what the original code was. Thanks. USING WARPTEXT IN A PROGRAM: That's why I wrote it! If you are going to distribute the WarpText source code with your program please also follow the directions under "DISTRIBUTION INFORMATION." It would be neat, especially if you aren't distributing the source with your program, if you could find a place somewhere in your program (the "ABOUT" menu, for instance) to say something like, "Using Bill Kelly's WarpText routines for speed!," however if you don't seem to be able to do this... don't worry about it. I would really appreciate it, though! Thanks! PLEASE CONTACT ME BEFORE USING THIS CODE IN A COMMERCIAL PROGRAM! (My address can be found at the end of this file.) GENERAL INFORMATION: The "Old Warp" routines use the WarpInfo structure to keep track of which bitplane they're writing into, the current X and Y locations, the TextFont data, etc. STRUCTURE WarpInfo,0 ; ...the <I> denotes internal use. APTR wi_TextFont ; Pointer to a TextFont structure. APTR wi_BitMap ; Pointer to a BitMap structure. WORD wi_WhichPlane ; Which bitplane to render into. WORD wi_Left ; Left edge of 'window' in char loc's. WORD wi_Top ; Top edge of 'window' in char loc's. WORD wi_Width ; Width of 'window' in char loc's. WORD wi_Height ; Height of 'window' in char loc's. APTR wi_WindowTop ; <I> Address of top of 'window.' APTR wi_CurLine ; <I> Address of start of current line. APTR wi_LastLine ; <I> Address of start of last line. WORD wi_CurX ; <I> Current X position. WORD wi_LastX ; <I> Maximum X position on a line. WORD wi_BPMod ; <I> # total possible chars on a line in bp WORD wi_Modulo ; <I> Add this to get to next line. LABEL wi_SIZE Call the InitWarpInfo routine before calling any of the other "Old Warp" routines. The WarpInfo structure you pass InitWarpInfo must be partially initialized before calling InitWarpInfo. InitWarpInfo prepares the parts WarpInfo structure marked with "<I>" so that the WarpInfo structure can be used with GetXY, GotoXY, and WarpText. The "New Warp" routines use NewWarpInfo structure. It's a lot smaller than WarpInfo because the new routines have sacrificed features for speed. STRUCTURE NewWarpInfo,0 WORD nwi_XLoc ; Current X position in char. loc's. WORD nwi_YLoc ; Current Y position in char. loc's. APTR nwi_BitPlane ; Address of bitplane to render text into. APTR nwi_FontData ; Address of 2048 byte array for font data. LABEL nwi_SIZE Call the SetupFont routine before calling any of the other "New Warp" routines. SetupFont unpacks the font passed to it into the 2048 byte array, the address of which is kept in nwi_FontData. You must allocate this 2048 byte array and store its address into nwi_FontData before calling SetupFont. Pass the pointer to an open font to SetupFont on the stack. The 2048 byte array does not have to be in CHIP ram because the routines do not use the blitter. After calling SetupFont, the NewWarpInfo structure can be used with NewWarp and XORCursor. Please see the file "WarpText.asm" for more information about each routine. BUGS: Known Bugs: Fixed: ----------- ------ WarpText writes to two more columns per line / than it should. If you specify 10 for wi_Width \/ Yes. you will get 12 characters per line. _ If WarpText encounters a character that has not |\ | / \ been defined in the font it's using it will not | \| \_/ Not yet. output the empty-box character. A garbage character-pattern will appear. BUG REPORTS: I would really appreciate hearing about any problems you find in my code! Please don't hesitate to drop me a line or send me mail if you have any suggestions, questions, or comments. I welcome your input. Enjoy, Bill Kelly. MY ADDRESS: NAME: Bill W. Kelly UUCP: {hplabs!hp-sdd, sdcsvax, ihnp4}!crash!pnet01!billk ARPA: crash!pnet01!billk@nosc INET: billk@pnet01.CTS.COM | For UUCP, don't do just pnet01!billk; USPS: 2507 Caminito La Paz | please include the crash!pnet01!billk. La Jolla, CA 92037 | Thanks! FONE: (619) 454-1307 * --------------------- * * End of "WarpText.doc" * * --------------------- * SHAR_EOF cat << \SHAR_EOF > WarpText.h /* ------------------------------------------------------------------------ * graphics/WarpText.h -- 'C' include for WarpText Bill Kelly * text routines. WT 2.0 07/06/87 * * Copyright 1987 by Bill W. Kelly. All Rights Reserved. * * This is meant to go in the Graphics directory of the C includes. * Made for C by Anson Mah 06/08/87 | 06Jun87 added NewWarpInfo (billk) * ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------- * The following structure, WarpInfo, is used by these four routines: * InitWarpInfo (Initializes the WarpInfo structure for use) * GetXY (Returns current cursor position) * GotoXY (Sets cursor to given position) * WarpText (Emits text at ~13,500 characters per second) */ struct WarpInfo { /* ...the <I> denotes internal use */ APTR wi_TextFont; /* Pointer to a TextFont structure */ APTR wi_BitMap; /* Pointer to a BitMap structure */ UWORD wi_WhichPlane; /* Which bitplane to render into */ UWORD wi_Left; /* Left edge of 'window' in char loc's */ UWORD wi_Top; /* Top edge of 'window' in char loc's */ UWORD wi_Width; /* Width of 'window' in char loc's */ UWORD wi_Height; /* Height of 'window' in char loc's */ APTR wi_WindowTop; /* <I> Address of top of 'window' */ APTR wi_CurLine; /* <I> Address of start of current line */ APTR wi_LastLine; /* <I> Address of start of last line */ UWORD wi_CurX; /* <I> Current X position */ UWORD wi_LastX; /* <I> Maximum X position on a line */ UWORD wi_BPMod; /* <I> # total possible chars on a line in bp */ UWORD wi_Modulo; /* <I> Add this to get to next line */ }; /* ------------------------------------------------------------------------- * The following structure, NewWarpInfo, is used by these three routines: * SetupFont (Copies font to given 2048 byte array for faster access) * NewWarp (Emits text at ~30,000 characters per second) * XORCursor (XOR's a visible cursor to the current xy location) */ struct NewWarpInfo { UWORD nwi_XLoc; /* Current X position in char. loc's. */ UWORD nwi_YLoc; /* Current Y position in char. loc's. */ APTR nwi_BitPlane; /* Address of bitplane to render text into. */ APTR nwi_FontData; /* Address of 2048 byte array for font data. */ }; * ---------------------------- * * End of "graphics/WarpText.h" * * ---------------------------- * SHAR_EOF cat << \SHAR_EOF > WarpText.i * ------------------------------------------------------------------------ * graphics/WarpText.i -- Assembler include file for Bill Kelly * WarpText text routines. 07/07/87 * * Copyright 1987 by Bill W. Kelly. All Rights Reserved. * * This is meant to go in the Graphics directory of the assembler includes. * When you assemble WarpText.asm, it will include: "graphics/WarpText.i" * ------------------------------------------------------------------------ * -------------------------------------------------------------------------- * The following structure, WarpInfo, is used by these four routines: * InitWarpInfo (Initializes the WarpInfo structure for use) * GetXY (Returns current cursor position) * GotoXY (Sets cursor to given position) * WarpText (Emits text at ~13,500 characters per second) STRUCTURE WarpInfo,0 ;...the <I> denotes internal use. APTR wi_TextFont ;Pointer to a TextFont structure. APTR wi_BitMap ;Pointer to a BitMap structure. UWORD wi_WhichPlane ;Which bitplane to render into. UWORD wi_Left ;Left edge of 'window' in char loc's. UWORD wi_Top ;Top edge of 'window' in char loc's. UWORD wi_Width ;Width of 'window' in char loc's. UWORD wi_Height ;Height of 'window' in char loc's. APTR wi_WindowTop ;<I> Address of top of 'window.' APTR wi_CurLine ;<I> Address of start of current line. APTR wi_LastLine ;<I> Address of start of last line. UWORD wi_CurX ;<I> Current X position. UWORD wi_LastX ;<I> Maximum X position on a line. UWORD wi_BPMod ;<I> # total possible chars on a line in bp UWORD wi_Modulo ;<I> Add this to get to next line. LABEL wi_SIZE * -------------------------------------------------------------------------- * The following structure, NewWarpInfo, is used by these three routines: * SetupFont (Copies font to given 2048 byte array for faster access) * NewWarp (Emits text at ~30,000 characters per second) * XORCursor (XOR's a visible cursor to the current xy location) STRUCTURE NewWarpInfo,0 UWORD nwi_XLoc ;Current X position in char. loc's. UWORD nwi_YLoc ;Current Y position in char. loc's. APTR nwi_BitPlane ;Address of bitplane to render text into. APTR nwi_FontData ;Address of 2048 byte array for font data. LABEL nwi_SIZE * ---------------------------- * * End of "graphics/WarpText.i" * * ---------------------------- * SHAR_EOF # End of shell archive exit 0