mirror of
https://github.com/electronicarts/CnC_Red_Alert.git
synced 2025-12-16 15:41:39 -05:00
Initial commit of Command & Conquer Red Alert source code.
This commit is contained in:
380
WINVQ/VQA32/OLD/UNVQVESA.ASM
Normal file
380
WINVQ/VQA32/OLD/UNVQVESA.ASM
Normal file
@@ -0,0 +1,380 @@
|
||||
;
|
||||
; Command & Conquer Red Alert(tm)
|
||||
; Copyright 2025 Electronic Arts Inc.
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* C O N F I D E N T I A L -- W E S T W O O D S T U D I O S
|
||||
;*
|
||||
;*---------------------------------------------------------------------------
|
||||
;*
|
||||
;* PROJECT
|
||||
;* VQAPlay32 library.
|
||||
;*
|
||||
;* FILE
|
||||
;* unvqvesa.asm
|
||||
;*
|
||||
;* DESCRIPTION
|
||||
;* VESA VQ decompress/draw routines. (32-Bit protected mode)
|
||||
;*
|
||||
;* PROGRAMMER
|
||||
;* Denzil E. Long, Jr.
|
||||
;*
|
||||
;*---------------------------------------------------------------------------
|
||||
;*
|
||||
;* PUBLIC
|
||||
;* UnVQ_4x2_VESA320_32K - Draw 4x2 VQ frame to VESA320 32k color.
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
LOCALS ??
|
||||
INCLUDE "vga.i"
|
||||
INCLUDE "vesavid.i"
|
||||
INCLUDE "vqaplay.i"
|
||||
CODESEG
|
||||
|
||||
SKIP_PTR EQU 8000h
|
||||
|
||||
IF VQAVESA_ON
|
||||
IF VQABLOCK_4X2
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* NAME
|
||||
;* UnVQ_4x2_VESA320_32K - Draw 4x2 VQ frame to VESA320 32k color.
|
||||
;*
|
||||
;* SYNOPSIS
|
||||
;* UnVQ_4x2_VESA320_32K(Codebook, Pointers, Palette, GrainPerWin)
|
||||
;*
|
||||
;* void UnVQ_4x2_VESA320_32K(char *, char *, char *, long);
|
||||
;*
|
||||
;* FUNCTION
|
||||
;*
|
||||
;* INPUTS
|
||||
;* Codebook - Pointer to codebook.
|
||||
;* Pointers - Pointer to vector pointer data to unvq.
|
||||
;* Palette - Pointer to 15-bit palette.
|
||||
;* GrainPerWin - Granularity units for 64k window.
|
||||
;*
|
||||
;* RESULT
|
||||
;* NONE
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; SET_2_PIXELS:
|
||||
; - Loads 2 bytes from codebook, expands them into words in eax
|
||||
; - Sets them on the screen
|
||||
; cb_index: offset into codebook of start of 2 bytes to load
|
||||
; di_index: offset from current di to draw 2 pixels
|
||||
; BX: offset into codebook of this block
|
||||
; Uses: EAX, DX, SI!
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
MACRO SET_2_PIXELS cb_index,edi_index
|
||||
xor edx,edx
|
||||
mov dl,[BYTE PTR ebx+1+cb_index]
|
||||
shl edx,1
|
||||
add edx,[palette]
|
||||
mov esi,edx
|
||||
mov ax,[WORD PTR esi]
|
||||
shl eax,16
|
||||
xor edx,edx
|
||||
mov dl,[BYTE PTR ebx+cb_index]
|
||||
shl edx,1
|
||||
add edx,[palette]
|
||||
mov esi,edx
|
||||
mov ax,[WORD PTR esi]
|
||||
|
||||
IF PHARLAP_TNT
|
||||
mov [DWORD PTR es:edi+edi_index],eax
|
||||
ELSE
|
||||
mov [DWORD PTR edi+edi_index],eax
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; DRAW_BLOCK_ROWS macro:
|
||||
; Draws 'numrows' rows of 'blocksperrow' blocks each
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
MACRO DRAW_BLOCK_ROWS numrows,blocksperrow
|
||||
LOCAL ??Start_row
|
||||
LOCAL ??Not_finished_a_line
|
||||
LOCAL ??One_color
|
||||
LOCAL ??Draw_One_Color
|
||||
LOCAL ??Next_row
|
||||
LOCAL ??Done
|
||||
|
||||
mov [rowcount],numrows ; initialize row counter
|
||||
|
||||
;---------------------------------------- Start a new row:
|
||||
??Start_row:
|
||||
mov ecx,blocksperrow ; # blocks to fill a line
|
||||
|
||||
;---------------------------------------- Start a new block:
|
||||
??Not_finished_a_line:
|
||||
;........................................ Get next pointer word:
|
||||
xor ebx,ebx
|
||||
mov bx,[WORD PTR esi] ; BX = pointer word
|
||||
add esi,2
|
||||
|
||||
;........................................ Check for a 1-color block:
|
||||
or bx,bx ; see if high bit is set
|
||||
js ??One_color
|
||||
|
||||
;---------------------------------------- Multi-color block:
|
||||
mov [esi_save],esi ; save current SI
|
||||
add ebx,[cb_offset] ; get codebook offset
|
||||
SET_2_PIXELS 0,0
|
||||
SET_2_PIXELS 2,4
|
||||
SET_2_PIXELS 4,640
|
||||
SET_2_PIXELS 6,644
|
||||
add edi,8 ; next block position
|
||||
mov esi,[esi_save] ; get current SI
|
||||
|
||||
;........................................ Check block count
|
||||
dec ecx ; decrement block count
|
||||
jnz ??Not_finished_a_line
|
||||
|
||||
;---------------------------------------- Next block row:
|
||||
add edi,640
|
||||
;
|
||||
;............ see if we're past the end of the ptr data ............
|
||||
;
|
||||
dec [rowcount]
|
||||
jnz ??Start_row
|
||||
jmp ??Done
|
||||
|
||||
;---------------------------------------- 1-color block:
|
||||
??One_color:
|
||||
;................... skip ptr value SKIP_PTR .......................
|
||||
cmp bx,SKIP_PTR
|
||||
jne ??Draw_One_Color
|
||||
add edi,8
|
||||
dec ecx
|
||||
jnz ??Not_finished_a_line
|
||||
jmp ??Next_row
|
||||
??Draw_One_Color:
|
||||
not bx ; get palette index
|
||||
shl bx,1 ; convert to WORD offset
|
||||
add ebx,[palette]
|
||||
mov ax,[WORD PTR ebx] ; get 15-bit palette value
|
||||
mov dx,ax ; copy it into dx
|
||||
shl eax,16
|
||||
mov ax,dx ; eax = 2 pixels, same color
|
||||
mov edx,eax ; edx = 2 pixels, same color
|
||||
|
||||
IF PHARLAP_TNT
|
||||
mov [DWORD PTR es:edi],eax ; set 2 pixels
|
||||
mov [DWORD PTR es:edi+4],edx ; set 2 pixels
|
||||
mov [DWORD PTR es:edi+640],eax ; set 2 pixels
|
||||
mov [DWORD PTR es:edi+644],edx ; set 2 pixels
|
||||
ELSE
|
||||
mov [DWORD PTR edi],eax ; set 2 pixels
|
||||
mov [DWORD PTR edi+4],edx ; set 2 pixels
|
||||
mov [DWORD PTR edi+640],eax ; set 2 pixels
|
||||
mov [DWORD PTR edi+644],edx ; set 2 pixels
|
||||
ENDIF
|
||||
|
||||
add edi,8 ; next block position
|
||||
|
||||
;........................................ Check block count
|
||||
dec ecx ; decrement block count
|
||||
jnz ??Not_finished_a_line
|
||||
|
||||
;---------------------------------------- Next block row:
|
||||
??Next_row:
|
||||
add edi,640
|
||||
;
|
||||
;............ see if we're past the end of the ptr data ............
|
||||
;
|
||||
dec [rowcount]
|
||||
jnz ??Start_row
|
||||
??Done:
|
||||
ENDM
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; DRAW_BLOCK_PART_ROW macro:
|
||||
; Draws top or bottom half of blocks on a row
|
||||
; 'numblocks' = # blocks to draw
|
||||
; 'cb_add' = amt to add to codebook (0=top half, 4=bottom half)
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
MACRO DRAW_BLOCK_PART_ROW numblocks,cb_add
|
||||
LOCAL ??Not_finished_a_line
|
||||
LOCAL ??One_color
|
||||
LOCAL ??Draw_One_Color
|
||||
LOCAL ??Done
|
||||
|
||||
mov ecx,numblocks
|
||||
|
||||
;---------------------------------------- Start a new block:
|
||||
??Not_finished_a_line:
|
||||
;........................................ Get next pointer word:
|
||||
xor ebx,ebx
|
||||
mov bx,[WORD PTR esi] ; BX = pointer word
|
||||
add esi,2
|
||||
|
||||
;........................................ Check for a 1-color block:
|
||||
or bx,bx ; see if high bit is set
|
||||
js short ??One_color
|
||||
|
||||
;---------------------------------------- Multi-color block:
|
||||
mov [esi_save],esi ; save current SI
|
||||
add ebx,[cb_offset] ; get codebook offset
|
||||
SET_2_PIXELS cb_add,0
|
||||
SET_2_PIXELS cb_add+2,4
|
||||
add edi,8 ; next block position
|
||||
mov esi,[esi_save] ; get current SI
|
||||
|
||||
;........................................ Check block count
|
||||
dec ecx ; decrement block count
|
||||
jnz short ??Not_finished_a_line
|
||||
jmp ??Done
|
||||
|
||||
;---------------------------------------- 1-color block:
|
||||
??One_color:
|
||||
;................... skip ptr value SKIP_PTR .......................
|
||||
cmp bx,SKIP_PTR
|
||||
jne ??Draw_One_Color
|
||||
add edi,8
|
||||
dec ecx
|
||||
jnz short ??Not_finished_a_line
|
||||
jmp ??Done
|
||||
??Draw_One_Color:
|
||||
not bx ; get palette index
|
||||
shl bx,1 ; convert to WORD offset
|
||||
add ebx,[palette]
|
||||
mov ax,[WORD PTR ebx] ; get 15-bit palette value
|
||||
mov dx,ax ; copy it into dx
|
||||
shl eax,16
|
||||
mov ax,dx ; eax = 2 pixels, same color
|
||||
mov edx,eax ; edx = 2 pixels, same color
|
||||
|
||||
IF PHARLAP_TNT
|
||||
mov [DWORD PTR es:edi],eax ; set 2 pixels
|
||||
mov [DWORD PTR es:edi+4],edx ; set 2 pixels
|
||||
ELSE
|
||||
mov [DWORD PTR edi],eax ; set 2 pixels
|
||||
mov [DWORD PTR edi+4],edx ; set 2 pixels
|
||||
ENDIF
|
||||
|
||||
add edi,8 ; next block position
|
||||
|
||||
;........................................ Check block count
|
||||
dec ecx ; decrement block count
|
||||
jnz ??Not_finished_a_line
|
||||
??Done:
|
||||
ENDM
|
||||
|
||||
;===========================================================================
|
||||
; The actual procedure:
|
||||
;===========================================================================
|
||||
|
||||
GLOBAL C UnVQ_4x2_VESA320_32K:NEAR
|
||||
PROC UnVQ_4x2_VESA320_32K C NEAR
|
||||
|
||||
ARG codebook:NEAR PTR
|
||||
ARG pointers:NEAR PTR
|
||||
|
||||
IF PHARLAP_TNT
|
||||
ARG pal:QWORD ;KLUDGE - bcc32 pads FARPTR
|
||||
ELSE
|
||||
ARG palette:NEAR PTR
|
||||
ENDIF
|
||||
|
||||
ARG grains_per_win:DWORD
|
||||
ARG dummy1:DWORD
|
||||
ARG dummy2:DWORD
|
||||
|
||||
LOCAL rowcount:DWORD ; # rows drawn
|
||||
LOCAL esi_save:DWORD
|
||||
LOCAL cb_offset:DWORD
|
||||
|
||||
IF PHARLAP_TNT
|
||||
LOCAL palette:NEAR PTR
|
||||
ENDIF
|
||||
|
||||
;-------------------------------------------------------------------
|
||||
; Save registers
|
||||
;-------------------------------------------------------------------
|
||||
pushad
|
||||
|
||||
;-------------------------------------------------------------------
|
||||
; Set GS:[cb_offset] to codebook
|
||||
;-------------------------------------------------------------------
|
||||
mov eax,[codebook]
|
||||
sub eax,4
|
||||
mov [cb_offset],eax
|
||||
mov esi,[pointers]
|
||||
|
||||
;-------------------------------------------------------------------
|
||||
; Set ES:DI to screen
|
||||
;-------------------------------------------------------------------
|
||||
|
||||
IF PHARLAP_TNT
|
||||
push es
|
||||
les edi,[FWORD pal]
|
||||
mov [palette],edi
|
||||
mov eax,01Ch
|
||||
mov es,ax
|
||||
mov edi,0
|
||||
ELSE
|
||||
mov edi,0A0000h
|
||||
ENDIF
|
||||
|
||||
;-------------------------------------------------------------------
|
||||
; Do Bank 0:
|
||||
; - 102 full scanlines (51 rows of blocks)
|
||||
; - 128 pixels of the top half of blocks (32 top-half blocks)
|
||||
;-------------------------------------------------------------------
|
||||
SET_WINDOW 0
|
||||
DRAW_BLOCK_ROWS 51,80
|
||||
DRAW_BLOCK_PART_ROW 32,0 ; do top half
|
||||
|
||||
;-------------------------------------------------------------------
|
||||
; Do Bank 1:
|
||||
; - 128 pixels of the bottom half of the previous 32 blocks
|
||||
; - 192 pixels of full blocks (1 row of 48 blocks)
|
||||
; - 96 full scanlines (48 rows of blocks)
|
||||
;-------------------------------------------------------------------
|
||||
SET_WINDOW [grains_per_win]
|
||||
sub esi,64 ; subtract word size of last 32 blks
|
||||
mov edi,384
|
||||
DRAW_BLOCK_PART_ROW 32,4 ; do bottom half
|
||||
mov edi,0
|
||||
DRAW_BLOCK_ROWS 1,48 ; draw one row of 48 full blocks
|
||||
DRAW_BLOCK_ROWS 48,80 ; draw 48 full block rows
|
||||
|
||||
??End_of_data:
|
||||
IF PHARLAP_TNT
|
||||
pop es
|
||||
ENDIF
|
||||
|
||||
popad
|
||||
ret
|
||||
|
||||
ENDP UnVQ_4x2_VESA320_32K
|
||||
|
||||
ENDIF ;VQABLOCK_4X2
|
||||
ENDIF ;VQAVESA_ON
|
||||
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user