INCLUDE "FileIO.i" INCLUDE "IFF.i" ;CAPE Directives OBJFILE "rad:ANIMInfo.o" OPTIMON SMALLOBJ ADDSYM SECTION CopyLibCode,CODE ;from SmallStart.o XREF _DOSBase,_SysBase,_BUFFER ;from functions.o XREF asprintf,multiply ;from amiga.lib or small.lib XREF _LVOOpenLibrary,_LVOCloseLibrary,_LVOOpenWindow,_LVOCloseWindow XREF _LVOAllocMem,_LVOFreeMem XREF _LVOGetMsg,_LVOReplyMsg,_LVOWait,_LVOWaitPort XREF _LVOMove,_LVOText,_LVOSetAPen,_LVORectFill XREF _LVOOpen,_LVORead,_LVOWrite,_LVOClose,_LVODelay XREF _LVOLock,_LVOUnLock,_LVOExamine XREF _LVOClearPointer MODE_OLDFILE equ 1005 MODE_NEWFILE equ 1006 LIB_VERSION equ 33 XDEF print_line print_line: movem.l a2/a4,-(sp) movea.l a0,a4 movea.l RastPort,a2 moveq #5,d0 moveq #26,d1 ;allow for window title bar lea yPos,a1 add.w (a1),d1 ;get y position to print at addq.w #8,(a1) ;increment 1 line down for next time movea.l a2,a1 ;our window's RastPort movea.l _GfxBase,a6 jsr _LVOMove(a6) movea.l a4,a0 len move.b (a4)+,d0 bne.s len subq.l #1,a4 move.l a4,d0 sub.l a0,d0 ;length of string movea.l a2,a1 movem.l (sp)+,a2/a4 jmp _LVOText(a6) print_and_delay: bsr.s print_line ;fall through to delay delay_msg: ;---Leave the msg displayed for a while moveq #100,d1 movea.l _DOSBase,a6 jsr _LVODelay(a6) ;---clear msg moveq #5,d0 moveq #26-8,d1 add.w yPos,d1 movea.l RastPort,a2 movea.l a2,a1 movea.l _GfxBase,a6 jsr _LVOMove(a6) moveq #36,d0 lea Spaces,a0 movea.l a2,a1 jmp _LVOText(a6) XDEF clear_window clear_window: movem.l d2/d3/a2/a6,-(sp) movea.l _GfxBase,a6 moveq #0,d0 movea.l RastPort,a1 movea.l a1,a2 jsr _LVOSetAPen(a6) moveq #4,d0 moveq #15,d1 move.w #636,d2 moveq #80,d3 movea.l a2,a1 jsr _LVORectFill(a6) moveq #1,d0 movea.l a2,a1 jsr _LVOSetAPen(a6) movem.l (sp)+,d2/d3/a2/a6 rts XDEF _main _main: ;---Open Gfx Library movea.l _SysBase,a6 moveq #LIB_VERSION,d0 lea GfxName,a1 jsr _LVOOpenLibrary(a6) move.l d0,_GfxBase bne.s xxx rts ;---Open Intuition xxx moveq #LIB_VERSION,d0 lea IntuitionName,a1 jsr _LVOOpenLibrary(a6) move.l d0,_IntuitionBase beq clG ;---Open the main window lea newWindow,a0 move.l a6,-(sp) movea.l d0,a6 jsr _LVOOpenWindow(a6) move.l (sp)+,a6 move.l d0,WindowPtr beq clI movea.l d0,a0 move.l 50(a0),RastPort ;---Open the dissidents FileIO (requester) library moveq #0,d0 ;any version (for now) lea RequesterName,a1 movea.l _SysBase,a6 jsr _LVOOpenLibrary(a6) move.l d0,_RequesterBase bne.s gotRQ lea CantFindFileIO,a0 bsr print_and_delay bra clW ;---Get the FileIO Structure gotRQ movea.l d0,a6 jsr _LVOGetFileIO(a6) move.l d0,FileIO bne gotIO lea IOerR,a0 bsr print_and_delay bra clF ;---Set up certain options in the FileIO gotIO movea.l d0,a0 Bset.b #INFO_SUPPRESS,1(a0) ;INFO_SUPPRESS ON ;--Set up the XY co-ordinates of where the requester will open ; If we used DoFileIOWindow(), we wouldn't need to set co-ordinates. moveq #6,d0 move.w d0,FILEIO_X(a0) ;x position moveq #11,d0 move.w d0,FILEIO_Y(a0) ;y position ;---Mandatory setup: The drawmodes and buffer move.l #_BUFFER,FILEIO_BUFFER(a0) moveq #2,d0 move.b d0,FILEIO_DRAWMODE(a0) move.b d0,FILEIO_PENA(a0) ;---Open the dissidents ilbm.library moveq #0,d0 ;any version (for now) lea ILBMName,a1 movea.l _SysBase,a6 jsr _LVOOpenLibrary(a6) move.l d0,_ILBMBase bne.s E3 lea CantFindIlbm,a0 bsr print_and_delay bra delFile ;********************** ANIMInfo IDCMP LOOP ****************************** ;---Create a mask of the Window's UserPort's mp_Sigbit (to wait on) E3 movea.l WindowPtr,a3 movea.l 86(a3),a0 move.b 15(a0),d0 moveq #0,d7 Bset.l d0,d7 ;---Get the next message queued at our UserPort E4 movea.l 86(a3),a0 movea.l _SysBase,a6 jsr _LVOGetMsg(a6) move.l d0,d1 bne.s E7 ;---If no more msgs, check if we are ready to exit the program E5 Btst.b #0,Quit beq clILBM ;---Wait for a message sent to our Window (from Intuition)=== E6 move.l d7,d0 ; movea.l _SysBase,a6 jsr _LVOWait(a6) bra.s E4 ;---Copy all the info we want from the IntuiMessage E7 movea.l d0,a1 lea 20(a1),a0 ;get the address of the first field to copy. move.l (a0)+,d6 ;Copy the Class field to d6 move.w (a0)+,d5 ;Copy the Code field to d5 move.w (a0)+,d4 ;Copy the qualifier field to d4 movea.l (a0)+,a2 ;Copy the IAddress field to a2 move.w (a0)+,d3 ;Copy MouseX position to d3 move.w (a0)+,d2 ;Copy MouseY position to d2 ;---Now reply to the message so Intuition can dispose of it E8 ;Address of the message is in a1. jsr _LVOReplyMsg(a6) ;---What type of msg? Handle it. Bclr.l #3,d6 ;MOUSEBUTTONS bne.s BUT Bclr.l #9,d6 ;CLOSEWINDOW beq.s E4 ;=========CLOSEWINDOW============ Bclr.b #0,Quit bra.s E4 ;=========MOUSEBUTTONS=========== ;---Make sure that it's an UP select if MOUSEBUTTONS BUT subi.b #$68,d5 beq.s E4 ;ignore down clr.w yPos ;reset to top of window bsr clear_window ;---Allow the user to choose the file, and then examine it bsr.s show_info bra.s E4 ;*************************** Exit Routine ***************************** ;---Close the ilbm lib clILBM movea.l _ILBMBase,a1 movea.l _SysBase,a6 jsr _LVOCloseLibrary(a6) ;---Release the FileIO delFile movea.l FileIO,a1 movea.l _RequesterBase,a6 jsr _LVOReleaseFileIO(a6) ;---Close the requester lib clF movea.l _RequesterBase,a1 movea.l _SysBase,a6 jsr _LVOCloseLibrary(a6) ;---Close the window clW movea.l WindowPtr,a0 movea.l _IntuitionBase,a6 jsr _LVOCloseWindow(a6) ;---Close the Intuition Lib clI movea.l _SysBase,a6 movea.l _IntuitionBase,a1 jsr _LVOCloseLibrary(a6) ;---Close the graphics lib clG movea.l _GfxBase,a1 jmp _LVOCloseLibrary(a6) ;returns to startup code ;========================================================================== ;show_info(window) ; a3 XDEF show_info show_info: movem.l d2/d3/d4/d5/a4,-(sp) ;---DoFileIO(FileIO, window) movea.l a3,a1 movea.l FileIO,a0 movea.l _RequesterBase,a6 jsr _LVODoFileIO(a6) move.l d0,d1 beq L92 ;Error in Filename selection (shouldn't happen, but...) addq.l #1,d0 beq L92 ;If -1, user must have selected CANCEL ;Buffer address in d1 ;---Check FileSize movea.l FileIO,a0 move.l FILEIO_FILESIZE(a0),d0 beq L92 ;must be a dir or disk that was chosen ;---Get a lock on the full pathname moveq #-2,d2 ;Buffer address in d1 movea.l _DOSBase,a6 jsr _LVOLock(a6) move.l d0,d5 beq L92 ;---Open the File for Reading moveq #0,d2 move.w #MODE_OLDFILE,d2 lea _BUFFER,a0 move.l a0,d1 jsr _LVOOpen(a6) move.l d0,d4 beq L92 ;---Set the WAIT mouse pointer movea.l _RequesterBase,a6 movea.l a3,a0 jsr _LVOSetWaitPointer(a6) ;---Examine the File (ExamineFORM is our installed custom FORMhandler) ;---IFFP = LoadILBM(file, Vectors, ILBMFrame) lea Vectors,a0 movea.l _ILBMBase,a6 lea ILBMFrame,a1 Bclr.b #ANIMFLAG,iUserFlags(a1) moveq #-1,d0 move.l d0,NumOfFrames ;initially, -1 move.l d4,d1 jsr _LVOLoadILBM(a6) ;---Did we find an ILBM or ANIM? If so, LoadILBM() returned IFF_DONE move.l d0,d1 addq.l #2,d1 bne.s erriff ;---Print out the number of frames if an ANIM lea ItsILBM,a0 Btst.b #ANIMFLAG,ILBMFrame+iUserFlags beq.s pfnum move.l NumOfFrames,-(sp) addq.l #1,(sp) lea _BUFFER,a0 lea FramePrint,a1 jsr asprintf addq.l #4,sp bra.s pfnum ;---Display the returned IFFP code erriff: jsr _LVOGetIFFPMsg(a6) movea.l d0,a0 pfnum bsr print_line ;---Restore mouse pointer movea.l a3,a0 movea.l _IntuitionBase,a6 jsr _LVOClearPointer(a6) ;---Close File, Free lock move.l d4,d1 movea.l _DOSBase,a6 jsr _LVOClose(a6) move.l d5,d1 jsr _LVOUnLock(a6) L92 movem.l (sp)+,d2/d3/d4/d5/a4 rts ;========================================================================= ;This is the custom FORMhandler we installed in the Vectors Structure ;passed to LoadILBM(). The lib routine LoadILBM() will call this routine ;for every FORM it encounters in the opened file with the following ;registers as follows: ; ; IFFP = ExamineFORM(ID, Context, Vectors, ILBMFrame, PROPList) ; d0 d0 a0 a2 a3 a4 ; ; Our routine is going to check for ANIMs or ILBMs, (ignoring all other ; FORMs), and print out info about the ILBM (or first Frame of the ANIM ; and total # of Frames). XDEF ExamineFORM ExamineFORM: movem.l d2/a2/a5/a6,-(sp) movea.l _ILBMBase,a6 ;---Put the Context in a convenient register movea.l a0,a5 ;---if ID = ANIM, set ANIM flag and do anim parse cmpi.l #ID_ANIM,d0 beq.s animf ;---if ID = ILBM (this will be an ANIM frame if we're inside of an ANIM) cmpi.l #ID_ILBM,d0 bne.s nonif ;---If an ILBM, increment NumOfFrames addq.l #1,NumOfFrames ;---If we haven't displayed the info on an ILBM yet, do so. Otherwise, ; just exit. bne.s Aout ;returning an ID, or IFF_OKAY continues to next group bra.s ilBm animf Bset.b #ANIMFLAG,iUserFlags(a3) ;**********Open a non-ILBM FORM and recursively scan it for ILBMs.******** ;The initial 'ANIM' header chunk executes here. ;---While IFFP = IFF_OKAY, do GetF1ChunkHdr(Context) nonif movea.l a5,a0 jsr _LVOGetF1ChunkHdr(a6) move.l d0,d1 bpl.s nonif ;---If IFFP = END_MARK, then return IFF_OKAY (to continue scanning file) ; unless this was an ANIM. For ANIM, return IFF_DONE instead of IFF_OKAY ; (because we hit END_MARK, so we got to the end of the FORM without error) addq.l #1,d1 bne.s Aout Btst.b #ANIMFLAG,iUserFlags(a3) bne.s aok moveq #IFF_OKAY,d0 Aout movem.l (sp)+,d2/a2/a5/a6 rts aok moveq #IFF_DONE,d0 bra.s Aout ;*******************Load a Frame (ILBM)******************************** ;---See if there is an ILBM PROP in PROPList ilBm movea.l a4,a1 ;ILBM ID in d0 jsr _LVOSearchPROP(a6) beq.s nAck ;---copy PROP ILBMFrame to our master ILBMFrame ;data (frame) part of ILBMPropFrame in d0 movea.l a3,a1 jsr _LVOCopyILBMProp(a6) ;---Get the next chunk ID and process it nAck movea.l a5,a0 jsr _LVOGetFChunkHdr(a6) move.l d0,d2 bmi L334 ;IFFP error cmpi.l #'ANHD',d2 beq Anhdh cmpi.l #'BMHD',d2 beq Bmhdh cmpi.l #'CAMG',d2 beq Camgh cmpi.l #'CMAP',d2 beq Cmaph cmpi.l #'BODY',d2 bne.s nAck ;=========case ID_BODY: (assume this is the last chunk in the ILBM) ; Here we print out all of the info we collected in the ILBMFrame. ;---Print out info in BMHD Bclr.b #BMHDFLAG,iFlags(a3) beq CLER ;first frame must have a BMHD lea iBMHD(a3),a2 moveq #0,d1 moveq #0,d0 move.w BMHD_pageH(a2),d1 move.l d1,-(sp) ;---d2 = pageHeight or h, whichever is larger move.w BMHD_h(a2),d0 move.l d0,-(sp) cmp.w d0,d1 bcc.s larh move.w d0,d1 larh move.w d1,d2 moveq #0,d0 move.b BMHD_nPlanes(a2),d0 move.l d0,-(sp) mulu.w d0,d2 ;planeS = nPlanes * pageHeight move.w BMHD_pageW(a2),d1 move.l d1,-(sp) move.w (a2),d0 ;w move.l d0,-(sp) ;---d0 = pageWidth or w, whichever is larger cmp.w d0,d1 bcc.s larw move.w d0,d1 ;---RasterSize = planeS * RowBytes(pageWidth) larw moveq #15,d0 add.w d1,d0 lsr.w #3,d0 Bclr.l #0,d0 move.l d2,d1 jsr multiply move.l d0,-(sp) lea BMHDinfo,a1 lea _BUFFER,a0 jsr asprintf lea 24(sp),sp bsr print_line ;---Print out more BMHD info moveq #0,d0 move.b BMHD_yAspect(a2),d0 move.l d0,-(sp) move.b BMHD_xAspect(a2),d0 move.l d0,-(sp) move.b BMHD_compress(a2),d0 move.l d0,-(sp) move.b BMHD_masking(a2),d0 move.l d0,-(sp) move.w BMHD_color(a2),d0 move.l d0,-(sp) move.w BMHD_y(a2),d0 move.l d0,-(sp) move.w BMHD_x(a2),d0 move.l d0,-(sp) lea BMHDinfo2,a1 lea _BUFFER,a0 jsr asprintf lea 28(sp),sp bsr print_line ;---Print CAMG viewmodes, or "None" pCamg lea None,a0 lea ViewModePrint,a1 Btst.b #CAMGFLAG,iFlags(a3) beq.s Ncamg lea INTERLACE,a0 move.l iViewModes(a3),d1 btst.l #2,d1 bne.s Ncamg lea HAM,a0 btst.l #7,d1 bne.s Ncamg lea HIRES,a0 btst.l #15,d0 bne.s Ncamg lea DUAL,a0 btst.l #10,d0 bne.s Ncamg lea LORES,a0 Ncamg move.l a0,-(sp) lea _BUFFER,a0 jsr asprintf addq.l #4,sp bsr print_line ;---Print number of colors in table moveq #0,d0 move.b iNumColors(a3),d0 move.l d0,-(sp) lea NCPrint,a1 lea _BUFFER,a0 jsr asprintf addq.l #4,sp bsr print_line ;---If an ANHD, print out the opmode Bclr.b #ANHDFLAG,iFlags(a3) beq.s nopm moveq #0,d0 move.b ANHDchunk,d0 move.l d0,-(sp) lea OpMode,a1 lea _BUFFER,a0 jsr asprintf addq.l #4,sp bsr print_line ;---IFFP = IFF_OKAY (to continue the load) if an ANIM. If an ILBM outside ; of an ANIM (by itself), then return IFF_DONE. nopm moveq #IFF_OKAY,d0 Btst.b #ANIMFLAG,iUserFlags(a3) bne.s L321 moveq #IFF_DONE,d0 bra.s L321 CLER moveq #BAD_FORM,d0 bra.s L321 ;===============case ID_BMHD: ;---Set BMHDFLAG, and read chunk Bmhdh Bset.b #BMHDFLAG,iFlags(a3) moveq #sizeofBMHD,d0 lea iBMHD(a3),a1 readChunk: movea.l a5,a0 jsr _LVOIFFReadBytes(a6) IFfp move.l d0,d2 ;---while IFFP >= IFF_OKAY, (loop if valid ID of ignored chunk, or a ; subroutine returned IFF_OKAY (no errors)) L334 move.l d2,d0 bpl nAck L321 movem.l (sp)+,d2/a2/a5/a6 rts ;=============case ID_ANHD: ;---store data in global ANHD, and set ANHDflag Anhdh Bset.b #ANHDFLAG,iUserFlags ;---Read in ANHD chunk lea ANHDchunk,a1 moveq #sizeofANHD,d0 bra.s readChunk ;=============case ID_CAMG: Camgh jsr _LVOHandleCAMG(a6) bra.s readChunk ;=================case ID_CMAP: Cmaph lea iNumColors(a3),a1 moveq #maxColorReg,d0 move.b d0,(a1) move.l a5,d0 lea iColorTable(a3),a0 ;NumColors address in a1 jsr _LVOGetCMAP(a6) bra IFfp ;SECTION IFFdata,DATA ;some assemblers may need this un-commented XDEF Vectors ;the initialized Vectors structure with custom FORMhandler Vectors: dc.l 0 dc.l ExamineFORM dc.l 0 dc.l 0 XDEF NumOfFrames NumOfFrames dc.l 0 XDEF yPos yPos dc.w 0 XDEF ANHDchunk ANHDchunk ds.b 40 XDEF ILBMFrame ILBMFrame ds.b sizeofILBMFrame XDEF newWindow newWindow: dc.w 0,0 dc.w 640,200 dc.b 0,1 ;IDCMP = MOUSEBUTTONS|CLOSEWINDOW dc.l $208 ;WindowFlags = WINDOWSIZE|WINDOWDRAG|WINDOWDEPTH|SMART_REFRESH|ACTIVATE dc.l $100F dc.l 0 dc.l 0 dc.l WINTITLE dc.l 0 dc.l 0 dc.w 306,145 dc.w 640,200 dc.w 1 TextAttr: ;Topaz 8 is a ROM font so doesn't need to be opened dc.l FONTNAME dc.w 8 ;TOPAZ_EIGHTY dc.b 0,0 XDEF _GfxBase,_IntuitionBase,_RequesterBase,WindowPtr,RastPort,_ILBMBase XDEF FileIO,RequesterName,ILBMName _GfxBase dc.l 0 _IntuitionBase dc.l 0 _RequesterBase dc.l 0 _ILBMBase dc.l 0 WindowPtr dc.l 0 RastPort dc.l 0 FileIO dc.l 0 Spaces dc.b ' ',0 FONTNAME dc.b 'topaz.font',0 IOerR dc.b 'Cannot get a FileIO structure.',0 GfxName dc.b 'graphics.library',0 IntuitionName dc.b 'intuition.library',0 CantFindFileIO dc.b 'Cannot find the ' RequesterName dc.b 'requester.library',0 CantFindIlbm dc.b 'Cannot find the ' ILBMName dc.b 'ilbm.library',0 WINTITLE dc.b 'ANIMInfo ® 1989 dissidents',0 Quit dc.b 1 FramePrint dc.b 'Number of Frames = %-11lu',0 ItsILBM dc.b 'This is an ILBM file. ',0 BMHDinfo dc.b 'Raster=%-7lu w=%-4lu pageW=%-4lu Planes=%-2lu h=%-4lu' dc.b ' pageH=%-4lu',0 BMHDinfo2 dc.b 'XY=(%-5lu,%-5lu) TransColor=%-5lu Masking=%1lu ' dc.b 'Compression=%1lu Aspect=%2lu/%-2lu',0 ViewModePrint dc.b 'ViewModes=%-16s',0 DUAL dc.b 'Dual Playfield',0 HAM dc.b 'Ham',0 INTERLACE dc.b 'InterLace',0 HIRES dc.b 'Hi-Res',0 LORES dc.b 'Lo-Res',0 NCPrint dc.b 'Number of Colors = %-4lu',0 None dc.b 'Not Specified',0 OpMode dc.b 'ANHD opmode = %-3lu',0