pcx viewer help

Please use this Board for QBasic related requests ( file research, programming, etc.)

Moderators:Administrator, Global Moderator

Post Reply
Guest
pcx viewer help

Post by Guest » Sat Feb 08, 2003 8:42 am

I've got a subprogram that shows pcx files, and what I want to do is send it, the pcx, to a buffer and get it from there somehow. Here's the sub program:

SUB showpcx (file$)

SCREEN 13

DIM pcxpal AS STRING * 768, pcxversion AS STRING * 1

pcxnum = FREEFILE
OPEN file$ FOR BINARY AS #pcxnum

  '*** Get the PCX version from the header.
  GET #pcxnum, 2, pcxversion

  '*** If we're using version 5, then load the palette.
  IF ASC(pcxversion) = 5 THEN
     '*** Grab the palette out of the file.
     GET #1, LOF(pcxnum) - 767, pcxpal

     '*** Start with color 0.
     pal = 0

     '*** Grab the red/green/blue value from our palette (PCXPAL) and
     '*** send them to the monitor using OUT.
     FOR p = 1 TO 768 STEP 3
        OUT &H3C8, pal
        red% = INT(ASC(MID$(pcxpal, p, 1)) / 4)
        OUT &H3C9, red%
        green% = INT(ASC(MID$(pcxpal, p + 1, 1)) / 4)
        OUT &H3C9, green%
        blue% = INT(ASC(MID$(pcxpal, p + 2, 1)) / 4)
        OUT &H3C9, blue%
        pal = pal + 1
     NEXT p

  END IF
 
  '*** Jump past the file header.
  SEEK #pcxnum, 129

  '*** We'll be sending the output the the screen, so our segment
  '*** is &HA000 (VGA screen memory) and our offset is 0.  You can
  '*** change these values to, say, decompress the image into an
  '*** array or something.
  fxoffset = 0: fxsegment = &HA000

  '*** We'll be reading chunks of 2,000 bytes.  You can increase or
  '*** decrease this depending on your needs.  I noticed little or
  '*** no difference when the chunk size went past 2,000, so I left
  '*** it at 2,000 to add as little over-head as possible with maximum
  '*** speed.
  datasize = 2000

  '*** Load our first chunk of data and point to the beginning of that
  '*** data.
  pcxdata$ = INPUT$(datasize, pcxnum)
  datacount = 1

  '*** To increase speed, we'll be drawing the screen in two loops,
  '*** that way we can use integers to point to the next pixel instead
  '*** of long integers.  Doing this gains tremendous speed.
  FOR half = 1 TO 2

     '*** On the second loop, this will add &H7D0 (32000) to our
     '*** segment so we'll be writing to the second half of the screen.
     '*** On the first loop, this will simply set our segment to &HA000.
     fxtotal = fxsegment + fxoffset
     DEF SEG = fxtotal

     FOR c = 0 TO 31999

        '*** If we're out of data, then we need to load the next chunk.
        IF datacount > datasize THEN
           pcxdata$ = INPUT$(datasize, pcxnum)
           datacount = 1
        END IF

        '*** Get the next byte from our data chunk.
        clr = ASC(MID$(pcxdata$, datacount, 1))
        datacount = datacount + 1

        '*** If we're out of data, then we load the next chunk.
        IF datacount > datasize THEN
           pcxdata$ = INPUT$(datasize, pcxnum)
           datacount = 1
        END IF
       
        '*** If the byte we pulled from the data has bit 6 and 7 set,
        '*** (which would make the value greater than 192), then that
        '*** means we'll be repeating a color.  So we pull the next
        '*** byte from our data chunk (which is the color), and put
        '*** it on the screen CLR - 192 times (in other words, we
        '*** take the value of the first 5 bits in the byte and put
        '*** the pixel to the screen that many times.)
        IF clr > 192 THEN
           LPS = clr - 192
           clr = ASC(MID$(pcxdata$, datacount, 1))
           datacount = datacount + 1
           FOR L = LPS TO 1 STEP -1
              POKE c, clr
              c = c + 1
           NEXT L
           c = c - 1
        ELSE
        '*** Since the byte was less than 192, then we just poke the
        '*** pixel to the screen.
           POKE c, clr
        END IF
     NEXT c
     '*** We'll move to the second half of the screen by adding 32,000
     '*** (HEX = 7D0) bytes to our segment value.
     fxoffset = fxoffset + &H7D0
  NEXT half

'*** All done!  Close the file.
CLOSE pcxnum

'*** Return to BASIC's default segment. Very important!
DEF SEG

END SUB

User avatar
frankiebaby
Global Moderator
Posts:95
Joined:Tue Apr 30, 2002 1:38 am
Location:Pennsylvania
Contact:

Re: pcx viewer help

Post by frankiebaby » Sat Feb 08, 2003 8:25 pm

Ok, well basically the guy who wrote that was very kool and gave ya the easy ability to do just what ya want. see this part here:

  '*** change these values to, say, decompress the image into an
  '*** array or something.
  fxoffset = 0: fxsegment = &HA000  'THIS PART

create an array for the video mem like this

DIM SHARED VPage(31999)

then do this :

fxoffset = varptr(VPage(0))
fxsegment = varseg(VPage(0))

User avatar
Josh01
Newbie
Posts:1
Joined:Sat Feb 08, 2003 8:44 am

Re: pcx viewer help

Post by Josh01 » Sun Feb 09, 2003 10:18 am

Thanks for the help, here's the next hurdle though, how do I get parts of the picture (like sprites) from the array and into something like a GET statement so I can PUT it to the screen?

User avatar
frankiebaby
Global Moderator
Posts:95
Joined:Tue Apr 30, 2002 1:38 am
Location:Pennsylvania
Contact:

Re: pcx viewer help

Post by frankiebaby » Sun Feb 09, 2003 6:55 pm

well, that would be a bit complicated, but, the AF library already has a tool for that. I cant remember where i got it, but i found a game/tutorial that uses it, i can send it to va via email if ya'd like, it basically gives you better sprite routines and allows you to use double buffering in screen 13. it uses in-line assembly for speed, works very well. Send me a message @ ten2sk8@aol.com

Guest

Re: pcx viewer help

Post by Guest » Tue Feb 11, 2003 12:07 pm

It's nice to know you use AFlib.. :*)

I developed it as a Call Absolute Lib that is so easy to use.

It uses PP256 sprites(compatible with GET/PUT).

here:

http://relsoft.ath.cx/

Check it out from the Junkyard as Zeldatut.bas

Post Reply