Return to Home Page
Greg Santo's Game Programming Portfolio
   
T*LiB


Game Description

T*LiB is a graphics, memory and mouse library for QBasic. T*LiB was created to aid in the development of The Twigz Engine. Due to QBasic's serious limitations in physical memory and extremely slow and primitive graphic operations T*LiB was developed.

Programming Challenges

MS-DOS was quite outdated while The TWIGZ Engine and T*LiB were in development. Also, EMS and XMS memory were well on their way to becoming obsolete.

Resurrecting these outdated technologies and creating a seamless and custom tailored library to aid in my development The TWIGZ Engine was a great difficulty.


Features

Graphics
  • PUT with transparency and clipping
  • Page copying routines for the full screen or just the map area
  • Transparent page copying routine for parallax scrolling
  • Fill function for either the screen or an EMS memory page
  • PSET
  • Masking routine which interacts with both EMS and XMS
  • Scrolling routine for a maximum of 960 pixels (3 map screens) in XMS memory
EMS
  • Detect EMS
  • Get EMS version
  • Get total & free EMS pages
  • Get total & free EMS memory
  • Get EMS handles in use
  • Allocate EMS
  • Deallocate EMS
  • Map a layer (4 EMS pages) or a single EMS page to the EMS Page Frame
  • Resize an allocated block of EMS memory
  • Move to EMS
  • Get from EMS
XMS
  • Detect XMS
  • Get XMS version
  • Get total & free XMS
  • Allocate XMS
  • Deallocate XMS
  • Move to XMS
  • Get from XMS
Text
  • Bitmap font routine with color feature
  • Dialogue font routine (for the dialogue engine)
Mouse
  • Show mouse
  • Hide mouse
  • Get mouse state & position
  • Reposition mouse
  • Set mouse boundaries


Code Sample
TwigzClipPut is a graphical PUT function (or a blit function) which clips the sprite based on the screen's edges and also supports transparency.

;-----------------[ TwigzClipPut ]----------------

;==[Pushed on by call to routine]=============

;   28    Display Buffer Segment

;   26    Display Buffer Offset

;   24    Sprite Buffer Segment

;   22    Sprite Buffer Offset

;   20    X position

;   18    Y position

;   16    Invisible Color                     

;==[Pushed on by BASIC]=======================

;   14    BASIC Return Segment

;   12    BASIC Return Offset

;==[Pushed on by routine]=====================

;   10    DS Register

;   08    BP Register

;   06    Width + X Position

;   04    Height + Y Position

;   02    Width

;   00    Height

;--------------------------------------------------

PUBLIC TwigzClipPut

TwigzClipPut PROC

 

        PUSH   DS           ;Save the DS register for BASIC

        PUSH   BP           ;Save the BP register for BASIC

 

Init:   MOV    BP,SP        ;Get the stack pointer

        MOV    AX,[BP+12]   ;Get the X position

        PUSH   AX           ;Put the X position on the stack

        MOV    AX,[BP+10]   ;Get the Y position

        PUSH   AX           ;Put the Y position on the stack

        MOV    AX,[BP+16]   ;Get the sprite buffer segment

        MOV    DS,AX        ;Point the DS (sprite Segment) to it

        MOV    SI,[BP+14]   ;Get the sprite buffer offset

        MOV    AX,[SI]      ;Get the width, and divide by 8

        MOV    CL,03        ;(using SHR for speed) to obtain the

        SHR    AX,CL        ;true width in pixels

        PUSH   AX           ;Put the width on the stack

        MOV    BX,[BP-02]   ;Get the X position

        ADD    BX,AX        ;Add width to the X position

        MOV    [BP-02],BX   ;and put it back on the stack

        MOV    AX,[SI+02]   ;Get the height

        PUSH   AX           ;Put the height the stack

        MOV    BX,[BP-04]   ;Get the Y position

        ADD    BX,AX        ;Add height to the Y position

        MOV    [BP-04],BX   ;and put it back on the stack

        ADD    SI,04        ;Reset the sprite buffer offset

        MOV    [BP+14],SI   ;to the start of the pixel data

        MOV    BP,SP        ;Retrieve stack pointer

 

Plot:   MOV    AX,[BP+24]   ;Get the sprite buffer segment and

        MOV    DS,AX        ;point the DS (Dest. Segment) to it

        MOV    SI,[BP+22]   ;Now get the sprite buffer offset

        MOV    AL,[SI]      ;Then get the color of the pixel

        INC    SI           ;Add 1 to our sprite buffer offset

        MOV    [BP+22],SI   ;and place it back on the stack

        CMP    AL,[BP+16]   ;Is our pixel invisible?

        JZ     Done         ;If it is, then don't plot it.

        MOV    BX,0000      ;Set up minimum position (X and Y).

        CMP    [BP+20],BX   ;Is the X position less than 0?

        JL     Done         ;Yes? Then don't plot it.

        CMP    [BP+18],BX   ;Is the Y position less than 0?

        JL     Done         ;Yes? Then don't plot it.

        MOV    BX,319       ;Set up maximum position (X only).

        CMP    [BP+20],BX   ;Is the X position greater than 319?

        JG     Done         ;Yes? Then don't plot it.

        MOV    BX,199       ;Set up maximum position (Y only).

        CMP    [BP+18],BX   ;Is the Y position greater than 199?

        JG     Done         ;Yes? Then don't plot it.

        MOV    BX,[BP+28]   ;Otherwise, get the display buffer

        MOV    DS,BX        ;segment, and point DS to it

        MOV    SI,[BP+18]   ;Then get the Y position

        MOV    CL,06        ;Multiply it by 64 by using a Shift

        SHL    SI,CL        ;Left (SHL) for speed

        MOV    BX,SI        ;Save the result temporarily

        MOV    CL,02        ;Shift left again to multiply the

        SHL    SI,CL        ;Y position by 256, then add that

        ADD    SI,BX        ;value to our saved result

        MOV    BX,[BP+20]   ;Now get the X position and add it

        ADD    SI,BX        ;to the result to get our final

        MOV    BX,[BP+26]   ;offset. Then get the display buffer

        ADD    SI,BX        ;offset and add the pixel offset.

        MOV    [SI],AL      ;Plot the pixel.

 

Done:   MOV    AX,[BP+20]   ;Get the X position

        INC    AX           ;Increment the X position by 1

        MOV    [BP+20],AX   ;and put back on the stack

        MOV    AX,[BP+06]   ;Check to see if the width has been

        CMP    [BP+20],AX   ;reached. If it hasn't, then plot the

        JNZ    Plot         ;next column, otherwise reset the

        MOV    AX,[BP+20]   ;X position back to the left edge

        SUB    AX,[BP+02]   ;of the sprite by subtracting the

        MOV    [BP+20],AX   ;width.

        MOV    AX,[BP+18]   ;Get the Y position, then increment

        INC    AX           ;it by 1, and place it back on the

        MOV    [BP+18],AX   ;stack. Then check to see if we have

        MOV    AX,[BP+04]   ;finished drawing the sprite (Are

        CMP    [BP+18],AX   ;we at the bottom?) If not, then do   

        JNZ    Plot         ;another line...

 

Exit:   POP    AX           ;Pop the height off the stack

        POP    AX           ;Pop the width off the stack

        POP    AX           ;Pop the height + y off the stack

        POP    AX           ;Pop the width + x off the stack

        POP    BP           ;Restore our registers for BASIC,

        POP    DS           ;the exit the routine, cleaning up

        RETF   14           ;the stack at the end...

 

TwigzClipPut ENDP


Downloads

T*LiB.zip - The T*LiB Library for QBasic 4.5.
   
Copyright © 2006 Greg Santo