'=========================================================================== ' Subject: PCX SAVER/LOADER FOR PB Date: 02-08-98 (15:37) ' Author: Marc van den Dikkenberg Code: PB ' Origin: excel@excelsior.xs4all.nl Packet: GRAPHICS.ABC '=========================================================================== 'ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» 'º PB-PCX Version 1.0 8 February 1998 º 'ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ 'º PCX Save: Marc van den Dikkenberg º 'º PCX Load: Dave Navarro, Mark Phillips, Al Musella º 'º º 'º Status: Freeware ---------> internet: pb@excelsior.xs4all.nl º 'º º 'º The PowerBasic Archives -------> http://www.xs4all.nl/~excel/pb.html º 'ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ $LIB ALL - $DYNAMIC DEFINT A - Z TYPE Pcxheader Mfg AS BYTE Ver AS BYTE Enc AS BYTE Bpp AS BYTE Xmin AS INTEGER Ymin AS INTEGER Xmax AS INTEGER Ymax AS INTEGER Hres AS INTEGER Vres AS INTEGER Pal AS STRING * 48 Resrv AS BYTE Colpl AS BYTE Bpl AS INTEGER Paltyp AS INTEGER Filler AS STRING * 58 END TYPE DIM Header AS SHARED Pcxheader DIM Times AS SHARED BYTE DIM Chunksize AS SHARED WORD DIM Maxscrnptr AS SHARED WORD DIM Textofst AS SHARED WORD DIM Handle AS SHARED INTEGER DIM Buffer AS SHARED STRING * 32256 Chunksize = 32256 ' Screen 13 (320 x 200 x 256) ! MOV AX,&H13 ! INT &H10 DEF SEG=&HA000 ' Put some lines on the screen for t=0 to 199 step 2 poke$ t*320,string$(160,t) next t Sound 420,.5 a$=input$(1) ' Use PCXDisplay to view any 320x200x256 PCX file ' ' PCXDisplay("picture.pcx") ' Sound 420,.5 ' ' ' Important! This version of PCXSave will only work with Screen 13h ' ( 320 x 200 x 256 ) See The PowerBasic Archives, ' http://www.xs4all.nl/~excel/pb.html for possible updates. ' PCXSave("PCXSave.pcx") sound 420,.5 END '******************************************************************** '* PCX-Save, By Marc van den Dikkenberg * '******************************************************************** SUB PCXSave(F$) header.mfg=10 header.ver=5 header.enc=1 header.bpp=8 header.xmin=0 header.ymin=0 header.xmax=319 header.ymax=199 header.hres=300 header.vres=300 header.pal=string$(48,0) header.Resrv=0 header.colpl=1 header.bpl=320 header.paltyp=1 header.filler=string$(58,0) filhandle=freefile open f$ for binary as #filhandle put$ #filhandle,header DEF SEG=&HA000 for t=header.YMin to Header.YMax temp$=peek$(t*320+header.XMin,Header.bpl) ' **************** poke$ t*320+header.xmin,string$(header.bpl,0) ' Erase the current line from the screen ' **************** count=0 while len(temp$)>0 CheckFor$=left$(temp$,1) while left$(temp$,1)=CheckFor$ and count<63 count=count+1 temp$=mid$(temp$,2) wend if count=1 then if CheckFor$>chr$(191) then put$ #filhandle,chr$(val("&B11000001"))+CheckFor$ else put$ #filhandle,CheckFor$ end if else temp2$=bin$(count) while len(temp2$)<6 temp2$="0"+temp2$ wend put$ #filhandle,chr$(val("&B11"+temp2$))+CheckFor$ end if count=0 wend next t put$ #filhandle,chr$(12)' Start of Palette Marker OUT &H3C7, 0 FOR T = 0 TO 255 R = (INP(&H3C9) * 65280) \ 16128 G = (INP(&H3C9) * 65280) \ 16128 B = (INP(&H3C9) * 65280) \ 16128 PUT$ #filhandle,chr$(R) PUT$ #filhandle,chr$(G) PUT$ #filhandle,chr$(B) NEXT T close #filhandle END SUB END '******************************************************************** '* FAST PCX * '* Original idea from Dave Navarro. * '* Changes by Mark Phillips and Al Musella, DPM * '* revised 9/23/93 by David Yunker see PCX.BAS for original code * '* Source code formatted by BFLite, by James Davis. * '******************************************************************** SUB PcxDisplay(F$) 'display .pcx f$ on screen - only works for mode 13h now 'Set up the buffer to hold raw data Textofst = VARPTR(Buffer) 'the seg = ds for fixed len string 'Open the file and get the dos handle and file size filhandle=freefile OPEN F$ FOR BINARY ACCESS READ SHARED AS #filhandle Handle = FILEATTR(1, 2) 'The dos handle for this file 'Make sure we can do this file Get# filhandle, , Header IF Header.mfg <> 10 AND Header.ver <> 5 THEN PRINT "Not a 256 color PCX file!" END END IF Wid = Header.xmax - Header.xmin Dep = Header.ymax - Header.ymin IF Wid + 1 > 320 OR Dep + 1 > 200 THEN PRINT "is too big for Mode 13h" END ELSE PRINT END IF 'Load PCX Palette (have to divide the raw values by 4 to 'get them into 256 color format Tmp& = LOF(filhandle) - 768 Seek# filhandle, Tmp& 'this is where the pallette data is stored DIM Palete AS STRING * 768 ' GET$ filhandle, 768, Palete 'read it all in in 1 chunk 'Now divide each entry by 4 to scale to 256 color Paloff?? = VARPTR(Palete) ! mov AX,DS ;set es=ds to set up stosb ! mov ES,AX ! mov CX,768 ! mov AX,Paloff?? ! mov SI,AX ;let si and di point to palete string ! mov DI,AX PalShift: ! Lodsb ;al<-ds:si incr si ! shr AL,1 ! shr AL,1 ;divide by 4 (quickly:) 'shift bug ! Stosb ! loop Palshift Seek# 1, 128 ' go to beginning of graphic data 'Set the graphics mode 320x200x256 ! mov AX,&H0013 ; set mode 13h ! int &H10 'set up the new pallette Palptr = VARPTR(Palete) Palseg = VARSEG(Palete) ! mov AX,&H1012 ;set new palette ! mov BX,0 ! mov CX,256 ! mov DX,Palptr ! mov ES,Palseg ! int &H10 Maxscrnptr?? = (Wid + 1) * (Dep + 1) 'points to the highest posible postion on screen CALL pcxshow 'actually decodes and displays the file CLOSE filhandle END SUB SUB PCXshow() 'must be called from PCXDisplay - not directly! 'Set up es:di to point to next location on screen ! mov AX,&h0A000 ! mov ES,AX ;es points to VGA buffer ! mov DI,0 ;di holds screen offset ! call getchunk ;returns dx=buffersize, si offset of buffer pcx2: ! lodsb ;al now holds the color byte ! dec DX ! jnz pcx2a ! call getchunk pcx2a: ! mov BH,1 ;bh holds run count, assume 1 for now ! mov BL,AL ! and BL,&hc0 ;check if the 2 most sig bits are set ! cmp BL,&hc0 ! jnz pcx3 ;if not run byte, just display color al, bh Times ! and AL,&h3f ! mov BH,AL ! lodsb ;al now holds the color byte ! dec DX ! jnz pcx3 ! call getchunk pcx3: ! xor CX,CX ! mov CL,BH ! rep Stosb ! cmp di,Maxscrnptr?? ! jz pcxdone ! jmp pcx2 GetChunk: ' return dx with # of bytes in the string to process ' return si with start of buffer in ds ! push ax ! push bx ! mov AH,&h3F ! mov BX,Handle ! mov DX,Textofst ! mov CX,Chunksize ! int &h21 ! mov SI,DX ! mov DX,AX ; DX=len si=offset ! pop bx ! pop ax ! retn PCXDone: END SUB SUB PCXResetScreen ! mov AX,3 ;'set text mode and reset palette ! int &h10 CLS END SUB