'=========================================================================== ' Subject: MODE-X PCX DISPLAY Date: 06-01-96 (00:00) ' Author: Steven Sensarn Code: QB, QBasic, PDS ' Origin: The Basix Fanzine Issue 5 Packet: GRAPHICS.ABC '=========================================================================== '//MODEXPCX.BAS -- CREATED IN QBASIC 1.1 BY STEVEN SENSARN '//SPEED HAS BEEN COMPROMISED FOR SIZE '//FUNCTION PROTOTYPES DECLARE SUB X.PLANE (P AS INTEGER) 'USE THIS TO CHANGE PLANES DECLARE SUB X.PIXEL (X AS LONG, Y AS LONG, CLR AS INTEGER) 'PLOTS PIXEL DECLARE SUB MODEX () 'CHANGES TO MODE X 320x240x256 DECLARE SUB WAIT.KEY () 'PRESS ANY KEY TO CONTINUE DECLARE SUB OPEN.FILE () 'USED TO LOAD THE PCX FILE '//STRUCTURES TYPE THEADER MAN AS STRING * 1 'MANUFACTURER -- 10 VER AS STRING * 1 'VERSION -- 5+ ENC AS STRING * 1 'ENCODING -- 1 (RLE) BPP AS STRING * 1 'BITS PER PIXEL PER PLANE -- 8 MNX AS INTEGER 'MINIMUM X SIZE MNY AS INTEGER 'MINIMUM Y SIZE MAX AS INTEGER 'MAXIMUM X SIZE MAY AS INTEGER 'MAXIMUM Y SIZE HRS AS INTEGER 'HORIZONTAL RESOLUTION VRS AS INTEGER 'VERTICAL RESOLUTION COL AS STRING * 48 'EGA COLOR PALETTE -- IGNORE RES AS STRING * 1 'RESERVED NMP AS STRING * 1 'NUMBER OF PLANES -- 1 BPL AS INTEGER 'BYTES PER SCANLINE PAL AS INTEGER 'PALETTE INFO -- IGNORE FIL AS STRING * 58 'FILLUP SPACE END TYPE '//VARIABLE DECLARATIONS DIM BYTE AS STRING * 1 'USED TO READ BYTES DIM HEADER AS THEADER 'USED FOR HEADER INFORMATION DIM SHARED FILE AS STRING * 50 'USED TO HOLD FILE NAME DIM INDEX AS LONG 'USED TO CONTROL DECODING DIM SIZE AS LONG 'USED TO CONTROL DECODING DIM XSIZE AS INTEGER, YSIZE AS INTEGER 'USED TO MEASURE IMAGE DIM TOTALBYTES AS INTEGER 'USED TO MEASUER SCAN LINES DIM VALUE AS INTEGER 'USED FOR CONVERTING CHAR TO INT DIM RLP 'USED FOR RUN LENGTH LOOP DIM X AS LONG, Y AS LONG 'USED FOR PIXEL TRACKING '//VARIABLE INITIALIZATIONS INDEX = 1 'BE ON THE SAFE SIDE '//MAIN ON ERROR GOTO ERROR.HANDLER 'JUST IN CASE... CLS CALL OPEN.FILE 'OPEN THE FILE GET #1, 1, HEADER 'LOAD HEADER '//BASIC TEST (NOT FOOL-PROOF) -- REQUIREMENTS IF ASC(HEADER.MAN) <> 10 THEN CLOSE #1: END 'NOT PCX IF ASC(HEADER.VER) < 5 THEN CLOSE #1: END 'NOT 256 COLOR IF ASC(HEADER.ENC) <> 1 THEN CLOSE #1: END 'NOT RLE IF ASC(HEADER.NMP) <> 1 THEN CLOSE #1: END 'NOT SUPPORTIVE OF MODE X PLANES '//LOAD WHILE LOOP INFORMATION XSIZE = HEADER.MAX - HEADER.MNX + 1 'LOAD HORIZONTAL GRAPHIC SIZE YSIZE = HEADER.MAY - HEADER.MNY + 1 'LOAD VERTICAL GRAPHIC SIZE TOTALBYTES = HEADER.BPL 'USED TO TRACK END-OF-SCANLINE SIZE = 1& * XSIZE * YSIZE 'LOAD SIZE -- FORCE LONG IF SIZE > 76800 THEN CLOSE : END 'GRAPHIC TOO LARGE -- WON'T FIT ON SCREEN '//DISPLAY STATUS TO THE USER CLS : SCREEN 0: WIDTH 80 PRINT "FILENAME: ", , " "; FILE: PRINT PRINT "MANUFACTURER: ", ASC(HEADER.MAN) PRINT "VERSION: ", , ASC(HEADER.VER) PRINT "RLE ENCODING: ", ASC(HEADER.ENC) PRINT "BITS PER PIXEL PER PLANE: ", ASC(HEADER.BPP) PRINT "WINDOW X MIN: ", HEADER.MNX PRINT "WINDOW Y MIN: ", HEADER.MNY PRINT "WINDOW X MAX: ", HEADER.MAX PRINT "WINDOW Y MAX: ", HEADER.MAY PRINT "HORIZONTAL RESOLUTION: ", HEADER.HRS PRINT "VERTICAL RESOLUTION: ", HEADER.VRS PRINT "NUMBER OF PLANES: ", ASC(HEADER.NMP) PRINT "BYTES PER LINE: ", HEADER.BPL PRINT IF NOT HEADER.HRS / 320 = INT(HEADER.HRS / 320) THEN PRINT "ASPECT RATIO MISMATCH ", " -- X AXIS" 'WARPED IMAGE -- NO BIG DEAL ELSE PRINT END IF IF NOT HEADER.VRS / 240 = INT(HEADER.VRS / 240) THEN PRINT "ASPECT RATIO MISMATCH ", " -- Y AXIS" 'WARPED IMAGE -- NO BIG DEAL END IF WAIT.KEY 'PRESS ANY KEY TO CONTINUE MODEX 'SWITCH TO MODE X -- 320x240x256 DEF SEG = &HA000 'VIDEO MEMORY ACCESS '//DECODE AND DISPLAY WHILE INDEX <= SIZE 'WHILE PICTURE ISN'T DONE LOADING... GET #1, , BYTE 'READ BYTE IF (ASC(BYTE) AND &HC0) = &HC0 THEN 'TEST TOP TWO BITS FOR 1'S RLP = ASC(BYTE) AND &H3F 'SET RUN LENGTH GET #1, , BYTE 'READ DATA BYTE WHILE RLP > 0 'WHILE RUN LENGTH HAS NOT YET FINISHED DUPLICATION IF NOT X > XSIZE THEN CALL X.PIXEL(X, Y, ASC(BYTE)) 'PLOT PIXEL X = X + 1 'RENEW PIXEL POSITION IF X >= TOTALBYTES THEN X = 0: Y = Y + 1 'TEST FOR END OF SCANLINE RLP = RLP - 1 'REDUCE RUN LENGTH LOOP VARIABLE INDEX = INDEX + 1 'INCREASE TOTAL WEND ELSE 'IF THE BYTE IS NOT ENCODED IF NOT X > XSIZE THEN CALL X.PIXEL(X, Y, ASC(BYTE)) 'PLOT PIXEL X = X + 1 'RENEW PIXEL POSITION IF X >= TOTALBYTES THEN X = 0: Y = Y + 1 'TEST FOR END OF SCANLINE INDEX = INDEX + 1 'INCREASE TOTAL END IF WEND '//CHANGE PALETTE GET #1, LOF(1) - 768, BYTE IF ASC(BYTE) <> 12 THEN CLOSE : END 'NO 256 COLOR PALETTE FOR INDEX = 0 TO 255 OUT &H3C6, &HFF 'INITIALIZE VGA PALETTE OUT &H3C8, INDEX 'SELECT COLOR INDEX GET #1, , BYTE OUT &H3C9, INT(ASC(BYTE) / 4) 'SEND RED VALUE -- ONLY NEED TOP 6 BITS GET #1, , BYTE OUT &H3C9, INT(ASC(BYTE) / 4) 'SEND GREEN VALUE -- ONLY NEED TOP 6 BITS GET #1, , BYTE OUT &H3C9, INT(ASC(BYTE) / 4) 'SEND BLUE VALUE -- ONLY NEED TOP 6 BITS NEXT INDEX SOUND 3000, .25 'DONE -- YOU WILL NOT SEE THE 'PRESS ANY KEY TO CONTINUE' END '//ERRORS ERROR.HANDLER: SCREEN 0: WIDTH 80 CLS PRINT : PRINT "SOMETHING HAS OCCURED IN THE PROGRAM THAT HAS" PRINT "CAUSED IT TO HALT. TERMINATING..." WAIT.KEY END '//DONE CLOSE #1 'CLOSE THE FILE SOUND 3000, .25 'SIGNAL USER END 'END THE PROGRAM '//NOTICE 'I HAVE ABSOLUTELY NO EXPERIENCE WITH PLANE BASED PCX FILES BECAUSE I USE 'MICROSOFT WINDOWS 3.1 PAINTBRUSH AND I CAN'T SEEM TO CREATE ONE. IF 'ANYBODY WOULD BE WILLING TO DRAW ME ONE THAT USES PLANES, I WOULD GREATLY 'APPRECIATE IT. SENT TO "txs53132@bayou.uh.edu" VIA BINHEX OR MIME. SUB MODEX SCREEN 13 DEF SEG = &HA000 OUT &H3C4, &H4 OUT &H3C5, &H6 OUT &H3C4, &H2 OUT &H3C5, &HF CLS OUT &H3D4, &H14 OUT &H3D5, &H0 OUT &H3D4, &H17 OUT &H3D5, &HE3 OUT &H3C2, &HE3 OUT &H3D4, &H11 OUT &H3D5, &H2C OUT &H3D4, &H6 OUT &H3D5, &HD OUT &H3D4, &H7 OUT &H3D5, &H3E OUT &H3D4, &H10 OUT &H3D5, &HEA OUT &H3D4, &H11 OUT &H3D5, &HAC OUT &H3D4, &H12 OUT &H3D5, &HDF OUT &H3D4, &H15 OUT &H3D5, &HE7 OUT &H3D4, &H16 OUT &H3D5, &H6 END SUB SUB OPEN.FILE PRINT "<>/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\<>" PRINT "<> PLEASE NOTE THAT THE FILE THAT IS TO BE LOADED MUST HAVE A <>" PRINT "<> SIZE NO LARGER THAN 320x240. IF YOU WOULD LIKE TO TERMINATE <>" PRINT "<> THIS PROGRAM, DO SO ENTERING AN EMPTY FILENAME. <>" PRINT "<>\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/<>" PRINT INPUT "FILENAME: ", FILE FILE = RTRIM$(FILE) FILE = UCASE$(FILE) IF NOT RIGHT$(RTRIM$(FILE), 4) = ".PCX" THEN END 'NO VALID EXTENSION OPEN FILE FOR BINARY AS #1 IF LOF(1) = 0 THEN CLOSE #1: KILL FILE: END 'FILE EMPTY OR NOT FOUND END SUB SUB WAIT.KEY WHILE LEN(INKEY$) = 0: WEND END SUB '//ASSUMING CURRENT SEGMENT IS A000:0000H SUB X.PIXEL (X AS LONG, Y AS LONG, CLR AS INTEGER) CALL X.PLANE(X AND 3) POKE INT(Y * 80 + X / 4), CLR END SUB '//USED TO CHANGE PLANE SUB X.PLANE (P AS INTEGER) OUT &H3C4, 2 OUT &H3C5, 2 ^ P END SUB