home *** CD-ROM | disk | FTP | other *** search
- ────────────────────────────────────────────────────────────────────
- ; Return of the jedi- type credits. Written by Draeden of VLA
- ; Started on 08.10.1993 Finished on 08.10.1993
- ;
- ; Copyright 1993 by VLA ■ Use by permission only!
- ────────────────────────────────────────────────────────────────────
- IDEAL
- DOSSEG
- MODEL SMALL
- STACK 400h
-
- CODESEG
- P386N
- ASSUME CS:@CODE, DS:@CODE
- LOCALS
- ────────────────────────────────────────────────────────────────────────────
- STRUC VGALINE
- Dest dw 0 ;offset of left of line on screen
- Source dw 0 ;offset to source for this line
- Indent dw 0 ;amt indented from edge to start of line
- Old_Indent dw 0 ;last indent so we know to erase
- Real_Width dw 0 ;between 0 and 320 if Virt_Width < 320 then
- ; Real = Virt
- Virt_Width dw 0 ;Virtual width of line, is the index into
- ; step chart pointers - only even values are
- ENDS ; are permitted (and with 0FFFEh)
- ────────────────────────────────────────────────────────────────────────────
- Step_Chart dw 183 dup (?) ;the max width for a line is 366 bytes
- ;(virtual) cause that's all that would fit
- ; in 64k
-
- LABEL TheLines VGALINE
- i=0
- REPT 200
- VGALINE <i*320,?,160,160,0>
- i=i + 1
- ENDM ;have all 200 so we have the possibility of
- ; full screen action
- Step_Seg dw 0 ;segment of step chart
- VGASeg dw 0A000h
- Image_Seg dw 0 ;source for GFX
- ────────────────────────────────────────────────────────────────────────────
- ────────────────────────────────────────────────────────────────────
- ;Takes the info for each line and displays the whole screen cleaning
- ;up after the last one as it goes. This routine REALLY pushes the
- ;limits... May be damaging to your health. Way complex. =)
- ────────────────────────────────────────────────────────────────────
- PROC Display_Lines NEAR
- pusha
- push ds es fs gs ;save everything
- mov ax,cs
- mov ds,ax ;setup all the segments
- mov es,[VGAseg]
- mov fs,[Step_Seg]
- mov gs,[Image_Seg]
-
- xor bx,bx ;start on line 0
- @@DrawLineLoop:
- mov cx,[bx + TheLines.Indent]
- sub cx,[bx + TheLines.Old_Indent] ;if old>=new then we dont erase
- jle @@NoErase ; otherwise, CX = # bytes to del
-
- mov di,[bx + TheLines.Dest] ;erase the front
- add di,[bx + TheLines.Old_Indent]
- xor al,al
- push cx
- rep stosb
- pop cx
- add di,[bx + TheLines.Real_Width] ;and erase the end
- rep stosb
-
- @@NoErase:
- cmp [bx + TheLines.Virt_Width],0 ;dont draw width 0
- je @@DoneLine
-
- mov di,[bx + TheLines.Dest]
- add di,[bx + TheLines.Indent] ;point to the beginning of Dest
-
- mov bp,[bx + TheLines.Source] ;grab the base for source
- push bx
- mov cx,[bx + TheLines.Real_Width] ;grab real width in CX
- mov bx,[bx + TheLines.Virt_Width] ;grab virtual width of line
- and bx,0fffeh
- mov bx,[bx + Step_Chart] ;get the offset to the step stuff
-
- @@Little_Loop:
- mov si,[fs:bx] ;grab source offset
- add bx,2 ;point to next offset
-
- mov al,[gs:bp + si] ;grab the byte
- stosb ;store it - if you run a 486
- ; mov [es:di],al inc di
- ;MAY be faster
- loop @@Little_Loop
-
- pop bx ;done, restore BX
-
- @@DoneLine:
- mov ax,[bx + TheLines.Indent] ;copy over indent and that's that
- mov [bx + TheLines.Old_Indent],ax
-
- add bx,(size VGALine)
- cmp bx,(size VGALine)*200
- jb @@DrawLineLoop
-
- pop gs fs es ds
- popa
- ret
- ENDP
- ────────────────────────────────────────────────────────────────────
- ; This sets up the step charts for each width from 0 to 366, only
- ;doing even values. Also fills in the step offset chart.
- ────────────────────────────────────────────────────────────────────
- Pic_Width = 320
-
- PROC Setup_Step NEAR
- pushad
- push ds es
- mov ax,cs
- mov ds,ax
- mov es,[Step_Seg]
-
- xor ebp,ebp ;current width
- xor si,si ;Step offset index
- xor di,di ;offset in Step_Seg
- @@StepLoop:
- mov [si + Step_Chart],di ;save offset for current one
- or bp,bp
- je @@Null
-
- mov eax,320 * 10000h
- xor edx,edx
- div ebp
-
- mov edx,eax
- ror edx,16 ;dx= int step, high EDX = fractional step
-
- mov cx,bp ;get the width
- xor eax,eax ;int low, frac hi current offset
- cmp cx,320
- jbe @@StoreLoop
-
- sub cx,320
- movzx ecx,cx
- mov eax,edx
- ror eax,16
- push edx
- mul ecx
- shr eax,1
- ror eax,16
- pop edx
- mov cx,318
- @@StoreLoop:
- stosw ;store current offset
- add eax,edx ;increase the offset
- adc eax,0 ;let fractions carry over..
- loop @@StoreLoop
-
- @@Null:
- add si,2
- add bp,2
- cmp bp,366 ;max that can fit in 64k
- jb @@StepLoop
-
- pop es ds
- popad
- ret
- ENDP
- ────────────────────────────────────────────────────────────────────
- ;Sets up the widths and indent of all TheLines so that it makes
- ; it look like text going back into the distance..
- ────────────────────────────────────────────────────────────────────
- PROC Setup_Screen NEAR
- pusha
- push ds
- mov ax,cs
- mov ds,ax
-
- mov si,(size VGALine) * 80
- mov cx,150
- mov bx,30 ;width
- mov ax,160 ;indent
- xor dx,dx ;source
- @@FillLoop:
- mov [si + TheLines.Virt_Width],bx
- mov [si + TheLines.Real_Width],bx
- cmp bx,320
- jbe @@WOK
- mov [si + TheLines.Real_Width],320
- @@WOK:
- mov [si + TheLines.Indent],ax
- mov [si + TheLines.Old_Indent],ax
- or ax,ax
- jns @@Iok
- mov [si + TheLines.Indent],0
- mov [si + TheLines.Old_Indent],0
- @@Iok:
- mov [si + TheLines.Source],dx
-
- add dx,320
- add bx,2
- dec ax
- add si,(size VGAline)
- cmp si,(size VGAline)*200
- jae @@BYE
- loop @@FillLoop
-
- @@BYE:
-
- pop ds
- popa
- ret
- ENDP
- ────────────────────────────────────────────────────────────────────
- ; Scrolls the data up by one line, adjusting all the source pointers
- ;in TheLines. Also writes one additional line somewhere.
- ────────────────────────────────────────────────────────────────────
- PROC Scroll_Text
- pusha
- push ds
- mov ax,cs
- mov ds,ax
-
- mov si,0
- mov cx,200
- @@IncLoop:
- mov ax,[si + TheLines.Source]
- add ax,320
- cmp ax,64000
- jb @@NotOver
- xor ax,ax
- @@NotOver:
- mov [si + TheLines.Source],ax
- add si,(size VGALine)
- loop @@IncLoop
-
- pop ds
- popa
- ret
- ENDP
- ────────────────────────────────────────────────────────────────────
- ;Loads in a TGA picture to display
- ────────────────────────────────────────────────────────────────────
- STRUC Pal
- R db ?
- G db ?
- B db ?
- ENDS
-
- FileName_TGA db "Test2.TGA",0
- Palette Pal 256 dup (<>)
-
- PROC Load_TGA NEAR
- pusha
- push ds
- mov ax,cs
- mov ds,ax
-
- mov dx,offset FileName_TGA
- mov ax,3d00h
- int 21h
- jc @@BYE
- mov bx,ax
-
- mov ax,4200h ;move FP rel to start
- xor cx,cx ; get past header
- mov dx,18
- int 21h
-
- mov dx,offset Palette ;read in palette
- mov cx,768
- mov ah,3fh
- int 21h
-
- mov si,offset Palette ;fix palette
- mov cx,256
- @@FPL:
- mov al,[(Pal PTR si).R] ;switch R&B and make 6bit
- mov ah,[(Pal PTR si).G]
- mov dl,[(Pal PTR si).B]
- shr al,2
- shr ah,2
- shr dl,2
- mov [(Pal PTR si).R],dl
- mov [(Pal PTR si).G],ah
- mov [(Pal PTR si).B],al
- add si,(size Pal)
- loop @@FPL
-
- mov si,offset Palette ;write palette
- mov dx,3c8h
- xor al,al
- out dx,al
- inc dx
- mov cx,256*3
- rep outsb
-
- mov ds,[Image_Seg] ;read in picture
- xor dx,dx
- mov cx,64000
- mov ah,3fh
- int 21h
-
- mov ah,3eh ;close it up
- int 21h
-
- @@BYE:
- pop ds
- popa
- ret
- ENDP
- ────────────────────────────────────────────────────────────────────────────
- START:
- mov ax,cs
- mov es,ax
- mov ds,ax
-
- mov ax,ss
- mov bx,sp
- shr bx,4
- inc bx
- add ax,bx ;find 1st available seg after Stack
-
- mov [Step_Seg],ax
- add ax,1000h
- mov [Image_Seg],ax
-
- mov ax,0013h ;change to 320x200x256 graph
- int 10h
-
- call Load_Tga
- call Setup_Step
- call Setup_Screen
-
- @@MainLoop:
- call Scroll_Text
- call Display_Lines
- mov ah,1
- int 16h
- jz @@MainLoop
-
- mov ah,0 ;wait for a key press
- int 16h
- mov ax,0003h ;reset to 80x25x16 Char
- int 10h
-
- mov ax,4c00h ;back to DOS
- int 21h
- END START
-