From b72bb023fe0813b9c3e44325ee8554199a2a0629 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Fri, 28 Aug 2026 15:36:15 +0200
Subject: [PATCH 1/4] Translate the VQ block decoders to C++
No documentation update: tests/unvqdec checks the C++ decoders against golden vectors recorded from the original assembly, so documented behavior is unchanged.
---
code/unvq_asm.asm | 1906 ----------------------------------
code/unvqdec.cpp | 428 ++++++++
tests/CMakeLists.txt | 1 +
tests/unvqdec/CMakeLists.txt | 30 +
tests/unvqdec/unvqgolden.h | 174 ++++
tests/unvqdec/unvqparity.cpp | 172 +++
6 files changed, 805 insertions(+), 1906 deletions(-)
delete mode 100644 code/unvq_asm.asm
create mode 100644 code/unvqdec.cpp
create mode 100644 tests/unvqdec/CMakeLists.txt
create mode 100644 tests/unvqdec/unvqgolden.h
create mode 100644 tests/unvqdec/unvqparity.cpp
diff --git a/code/unvq_asm.asm b/code/unvq_asm.asm
deleted file mode 100644
index 08f61d2db..000000000
--- a/code/unvq_asm.asm
+++ /dev/null
@@ -1,1906 +0,0 @@
-;******************************************************************************
-;* O P E N T S
-;******************************************************************************
-;* SPDX-License-Identifier: GPL-3.0-or-later
-;* Copyright 2025 Electronic Arts Inc.
-;* Copyright 2026 OpenTS contributors
-;*
-;* Contains material derived from Electronic Arts source code.
-;* Modified by OpenTS contributors, 2026.
-;* EA's GPLv3 Section 7 additional terms and supplemental warranty
-;* disclaimers apply; see LICENSE.md.
-;******************************************************************************
-
-.386
-.model flat, C
-
-PHARLAP_TNT equ 0
-VQABLOCK_4X2 EQU 1 ;4x2 block decode enable/disable
-VQABLOCK_4X4 EQU 1 ;4x4 block decode enable/disable
-
-;----------------------------------------------------------------------------
-;
-; These are VQA UnVQ1 full-frame decoders -- assembly-optimized routines
-; for drawing VQ-compressed video frames into a pixel buffer.
-;
-; Naming convention from VQALib:
-; UnVQ1 = full-frame decoder (processes every pointer)
-; C0 = ColorMode 0 (8-bit palette, 1 byte/pixel)
-; C1 = ColorMode 1 (15-bit hicolor via HicolorTable lookup)
-; TABLE = uses HicolorTable for single-color block fill
-; HALF = half-resolution output (samples every-other pixel)
-;
-; Function map (10 functions, all share the same signature):
-;
-; Name | Block | ColorMode | 1-Color Source | Block Type Check
-; ASM_UnVQ1_C1_TABLE | 4x4 | C1 table | HicolorTable[idx] | test bh, 80h
-; ASM_UnVQ1_C1_TABLE_ALT | 4x2 | C1 table | HicolorTable[idx] | test bh, 80h
-; ASM_UnVQ_4x2 | 4x2 | C0 (8bit) | byte duplication | cmp bh, 0FFh
-; ASM_UnVQ_4x4 | 4x4 | C0 (8bit) | byte duplication | cmp bh, 0FFh
-; ASM_UnVQ_4x4_HALF | 4x4>2 | C0 half | byte duplication | cmp bh, 0FFh
-; ASM_UnVQ_6 | 4x2>2 | C0 half | byte duplication | cmp bh, 0FFh
-; ASM_UnVQ1_C1_4x4 | 4x4 | C1 direct | value & 0x7FFF | test bh, 80h
-; ASM_UnVQ_8 | 4x2 | C1 direct | value & 0x7FFF | test bh, 80h
-; ASM_UnVQ_9 | 4x8 | C0 (8bit) | byte duplication | cmp bh, 0FFh
-; ASM_UnVQ_10 | 4x4w | C0 (8bit) | byte duplication | cmp bh, 0FFh
-;
-; Paired functions (same logic, different color source):
-; ASM_UnVQ1_C1_TABLE <-> ASM_UnVQ1_C1_4x4 (4x4, table vs direct)
-; ASM_UnVQ1_C1_TABLE_ALT <-> ASM_UnVQ_8 (4x2, table vs direct)
-; ASM_UnVQ_4x2 <-> ASM_UnVQ_6 (4x2 full vs half-res)
-; ASM_UnVQ_4x4 <-> ASM_UnVQ_4x4_HALF (4x4 full vs half-res)
-; ASM_UnVQ_9 <-> ASM_UnVQ_10 (large: 4x8 vs 4x4-wide)
-;
-; HicolorTable (global): 15-bit RGB to 16-bit pixel lookup table.
-; Initialized by Hicolor_Init_Table() in unvqtblc.cpp.
-;----------------------------------------------------------------------------
-
-externdef C ASM_UnVQ1_C1_TABLE:NEAR
-externdef C ASM_UnVQ1_C1_TABLE_ALT:NEAR
-externdef C ASM_UnVQ_4x2:NEAR
-externdef C ASM_UnVQ_4x4:NEAR
-externdef C ASM_UnVQ_4x4_HALF:NEAR
-externdef C ASM_UnVQ_6:NEAR
-externdef C ASM_UnVQ1_C1_4x4:NEAR
-externdef C ASM_UnVQ_8:NEAR
-externdef C ASM_UnVQ_9:NEAR
-externdef C ASM_UnVQ_10:NEAR
-EXTERN C HicolorTable:DWORD ; USHORT * [65535-1];
-
-.CODE
-
-;****************************************************************************
-;*
-;* NAME
-;* ASM_UnVQ1_C1_TABLE - Draw XxX block VQ frame to a buffer.
-;*
-;* SYNOPSIS
-;* ASM_UnVQ1_C1_TABLE(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
-;*
-;* void ASM_UnVQ1_C1_TABLE(unsigned char *, unsigned char *, unsigned char *,
-;* long, long, long);
-;*
-;* FUNCTION
-;* This function draws an image into the specified buffer from the
-;* pointers and codebook provided. This routine has been optimized for
-;* a 320x200 image.
-;*
-;* INPUTS
-;* Codebook - Pointer to codebook used to draw image.
-;* Pointers - Pointer to vector pointer data.
-;* Buffer - Pointer to buffer to draw image into.
-;* BPR - Number of blocks per row.
-;* Rows - Number of rows.
-;* BufWidth - Width of destination buffer in pixels.
-;*
-;* RESULT
-;* NONE
-;*
-;****************************************************************************
-
- PUBLIC ASM_UnVQ1_C1_TABLE
- ASM_UnVQ1_C1_TABLE PROC C USES ebx ecx edx esi edi \
- \
- codebook:DWORD, \
- pointers:DWORD, \
- buffer:DWORD, \
- blocksperrow:DWORD, \
- numrows:DWORD, \
- bufwidth:DWORD
-
- LOCAL data_end:DWORD
- ;LOCAL cb_offset:DWORD
- LOCAL edi_startval:DWORD
- LOCAL rowoffset:DWORD
- LOCAL unknown:DWORD
- LOCAL entries:DWORD
-
-;----------------------------------------------------------------------------
-; Initialize
-;----------------------------------------------------------------------------
-
-; mov eax,[codebook] ;Adjust the codebook address so
-; sub eax,4 ; that the pointer offsets will
-; mov [cb_offset],eax ; point directly at the codeword.
-
- shl [bufwidth],1
- mov eax,[bufwidth] ;Compute the offset to the next
- shl eax,2 ; row of blocks.
- mov [rowoffset],eax
-
- mov esi,[pointers]
- mov eax,[numrows] ;Compute the end address of the
- mul [blocksperrow] ; pointer data.
- mov [entries],eax
- add eax,esi
- mov [data_end],eax
-
- mov edi,[buffer]
- mov [edi_startval],edi
-
-;----------------------------------------------------------------------------
-; Drawing loop
-;----------------------------------------------------------------------------
-
-??Start_row:
- mov ecx,[blocksperrow] ;Number of blocks in a line
-
-??Not_finished_a_line:
- mov eax,[entries]
- xor ebx,ebx
- mov bh,[esi + eax] ;Get the codebook pointer value
- mov bl,[esi]
- inc esi ; then advance to the next one.
-
- test bh,080h ;Is it a one color block?
- js short ??One_color
-
-; Draw multi-color block
-
- shl ebx,5
- add ebx,[codebook] ;Codeword address
- mov eax,[ebx] ;Read 1st row of codeword
- mov edx,[ebx+4] ;Read 2nd row of codeword
-
- mov [edi],eax
- mov [edi+4],edx
-
- mov eax,[ebx+8]
- mov edx,[ebx+12]
- mov [unknown],ebx
- mov ebx,[bufwidth]
- mov [edi+ebx],eax
- mov [edi+ebx+4],edx
-
- mov ebx,[unknown]
- mov eax,[ebx+16]
- mov edx,[ebx+20]
- mov ebx,[bufwidth]
- shl ebx,1
- mov [edi+ebx],eax
- mov [edi+ebx+4],edx
-
- mov ebx,[unknown]
- mov eax,[ebx+24]
- mov edx,[ebx+28]
- mov ebx,[bufwidth]
- shl ebx,1
- add ebx,[bufwidth]
- mov [edi+ebx],eax
- mov [edi+ebx+4],edx
-
- add edi,8 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-; Draw 1-color block
-
-??One_color:
-; cmp bx,SKIP_PTR ;Is this a skip block?
-; jne ??Draw_One_Color
-;
-; add edi,4 ;Move to next dest block position
-; dec ecx ;More blocks for this row?
-; jnz short ??Not_finished_a_line
-; jmp ??Next_row
-
-??Draw_One_Color:
-; not bx ;NOT pointer value to get color
- and ebx,07FFFh
- shl ebx,1
- mov edx,[HicolorTable]
- mov ax,[edx+ebx]
- mov bx,ax
- shl eax,16
- mov ax,bx
-
- mov [edi],eax
- mov [edi+4],eax
-
- mov ebx,[bufwidth]
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- add ebx,[bufwidth]
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- add ebx,[bufwidth]
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- add edi,8 ;Next dest block positionw
- dec ecx ;More blocks for this row?
- jnz ??Not_finished_a_line ;jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
-??Next_row:
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-??End_of_data:
- ret
-
- ASM_UnVQ1_C1_TABLE ENDP
-
-
-;****************************************************************************
-;*
-;* NAME
-;* ASM_UnVQ1_C1_TABLE_ALT - Draw XxX block VQ frame to a buffer.
-;*
-;* SYNOPSIS
-;* ASM_UnVQ1_C1_TABLE_ALT(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
-;*
-;* void ASM_UnVQ1_C1_TABLE_ALT(unsigned char *, unsigned char *, unsigned char *,
-;* long, long, long);
-;*
-;* FUNCTION
-;* This function draws an image into the specified buffer from the
-;* pointers and codebook provided. This routine has been optimized for
-;* a 320x200 image.
-;*
-;* INPUTS
-;* Codebook - Pointer to codebook used to draw image.
-;* Pointers - Pointer to vector pointer data.
-;* Buffer - Pointer to buffer to draw image into.
-;* BPR - Number of blocks per row.
-;* Rows - Number of rows.
-;* BufWidth - Width of destination buffer in pixels.
-;*
-;* RESULT
-;* NONE
-;*
-;****************************************************************************
-
- PUBLIC ASM_UnVQ1_C1_TABLE_ALT
- ASM_UnVQ1_C1_TABLE_ALT PROC C USES ebx ecx edx esi edi \
- \
- codebook:DWORD, \
- pointers:DWORD, \
- buffer:DWORD, \
- blocksperrow:DWORD, \
- numrows:DWORD, \
- bufwidth:DWORD
-
- LOCAL data_end:DWORD
- ;LOCAL cb_offset:DWORD
- LOCAL edi_startval:DWORD
- LOCAL rowoffset:DWORD
- LOCAL unknown:DWORD
- LOCAL entries:DWORD
-
-;----------------------------------------------------------------------------
-; Initialize
-;----------------------------------------------------------------------------
-
-; mov eax,[codebook] ;Adjust the codebook address so
-; sub eax,4 ; that the pointer offsets will
-; mov [cb_offset],eax ; point directly at the codeword.
-
- shl [bufwidth],1
- mov eax,[bufwidth] ;Compute the offset to the next
- shl eax,2 ; row of blocks.
- mov [rowoffset],eax
-
- mov esi,[pointers]
- mov eax,[numrows] ;Compute the end address of the
- mul [blocksperrow] ; pointer data.
- mov [entries],eax
- add eax,esi
- mov [data_end],eax
-
- mov edi,[buffer]
- mov [edi_startval],edi
-
-;----------------------------------------------------------------------------
-; Drawing loop
-;----------------------------------------------------------------------------
-
-??Start_row:
- mov ecx,[blocksperrow] ;Number of blocks in a line
-
-??Not_finished_a_line:
- mov eax,[entries]
- xor ebx,ebx
- mov bh,[esi + eax] ;Get the codebook pointer value
- mov bl,[esi]
- inc esi ; then advance to the next one.
-
- test bh,080h ;Is it a one color block?
- js short ??One_color
-
-; Draw multi-color block
-
- shl ebx,5
- add ebx,[codebook] ;Codeword address
- mov eax,[ebx] ;Read 1st row of codeword
- mov edx,[ebx+4] ;Read 2nd row of codeword
- mov [edi],eax
- mov [edi+4],edx
- mov eax,[ebx+16]
- mov edx,[ebx+20]
- mov ebx,[bufwidth]
- shl ebx,1
- mov [edi+ebx],eax
- mov [edi+ebx+4],edx
-
- add edi,8 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-; Draw 1-color block
-
-??One_color:
-; cmp bx,SKIP_PTR ;Is this a skip block?
-; jne ??Draw_One_Color
-;
-; add edi,4 ;Move to next dest block position
-; dec ecx ;More blocks for this row?
-; jnz short ??Not_finished_a_line
-; jmp ??Next_row
-
-??Draw_One_Color:
-; not bx ;NOT pointer value to get color
- and ebx,07FFFh
- shl ebx,1
- mov edx,[HicolorTable]
- mov ax,[edx+ebx]
- mov bx,ax
- shl eax,16
- mov ax,bx
-
- mov [edi],eax
- mov [edi+4],eax
-
- mov ebx,[bufwidth]
- add ebx,[bufwidth]
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- add edi,8 ;Next dest block positionw
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
-??Next_row:
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-??End_of_data:
- ret
-
- ASM_UnVQ1_C1_TABLE_ALT ENDP
-
-
- IF VQABLOCK_4X2
-;****************************************************************************
-;*
-;* NAME
-;* UnVQ_4x2 - Draw 4x2 block VQ frame to a buffer.
-;*
-;* SYNOPSIS
-;* UnVQ_4x2(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
-;*
-;* void UnVQ_4x2(unsigned char *, unsigned char *, unsigned char *,
-;* long, long, long);
-;*
-;* FUNCTION
-;* This function draws an image into the specified buffer from the
-;* pointers and codebook provided. This routine has been optimized for
-;* a 320x200 image.
-;*
-;* INPUTS
-;* Codebook - Pointer to codebook used to draw image.
-;* Pointers - Pointer to vector pointer data.
-;* Buffer - Pointer to buffer to draw image into.
-;* BPR - Number of blocks per row.
-;* Rows - Number of rows.
-;* BufWidth - Width of destination buffer in pixels.
-;*
-;* RESULT
-;* NONE
-;*
-;****************************************************************************
-
- PUBLIC ASM_UnVQ_4x2
- ASM_UnVQ_4x2 PROC C USES ebx ecx edx esi edi \
- \
- codebook:DWORD, \
- pointers:DWORD, \
- buffer:DWORD, \
- blocksperrow:DWORD, \
- numrows:DWORD, \
- bufwidth:DWORD
-
- LOCAL data_end:DWORD
- ;LOCAL cb_offset:DWORD
- LOCAL edi_startval:DWORD
- LOCAL rowoffset:DWORD
- LOCAL entries:DWORD
-
-;----------------------------------------------------------------------------
-; Initialize
-;----------------------------------------------------------------------------
-
-; mov eax,[codebook] ;Adjust the codebook address so
-; sub eax,4 ; that the pointer offsets will
-; mov [cb_offset],eax ; point directly at the codeword.
-
- mov eax,[bufwidth] ;Compute the offset to the next
- shl eax,1 ; row of blocks.
- mov [rowoffset],eax
-
- mov esi,[pointers]
- mov eax,[numrows] ;Compute the end address of the
- mul [blocksperrow] ; pointer data.
- mov [entries],eax
- add eax,esi
- mov [data_end],eax
-
- mov edi,[buffer]
- mov [edi_startval],edi
-
-;----------------------------------------------------------------------------
-; Drawing loop
-;----------------------------------------------------------------------------
-
-??Start_row:
- mov ecx,[blocksperrow] ;Number of blocks in a line
-
-??Not_finished_a_line:
- mov eax,[entries]
- xor ebx,ebx
- mov bh,[esi + eax] ;Get the codebook pointer value
- mov bl,[esi]
- inc esi ; then advance to the next one.
-
- cmp bh,0FFh ;Is it a one color block?
- je short ??One_color
-
-; Draw multi-color block
-
- shl ebx,3
- add ebx,[codebook] ;Codeword address
- mov eax,[ebx] ;Read 1st row of codeword
- mov edx,[ebx+4] ;Read 2nd row of codeword
- mov ebx,[bufwidth]
- mov [edi],eax ;Write 1st row to dest
- mov [edi+ebx],edx ;Write 2nd row to dest
-
- add edi,4 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-; Draw 1-color block
-
-??One_color:
-; cmp bx,SKIP_PTR ;Is this a skip block?
-; jne ??Draw_One_Color
-;
-; add edi,4 ;Move to next dest block position
-; dec ecx ;More blocks for this row?
-; jnz short ??Not_finished_a_line
-; jmp ??Next_row
-
-??Draw_One_Color:
-; not bx ;NOT pointer value to get color
- mov bh,bl ;Duplicate color through the
- mov ax,bx ; entire dword register.
- rol eax,16
- mov ax,bx
- mov ebx,[bufwidth]
- mov [edi],eax ;Write 1st row to dest
- mov [edi+ebx],eax ;Write 2nd row to dest
-
- add edi,4 ;Next dest block positionw
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
-??Next_row:
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-??End_of_data:
- ret
-
- ASM_UnVQ_4x2 ENDP
- ENDIF ;VQABLOCK_4X2
-
-
- IF VQABLOCK_4X4
-;****************************************************************************
-;*
-;* NAME
-;* UnVQ_4x4 - Draw 4x4 block VQ frame to a buffer.
-;*
-;* SYNOPSIS
-;* UnVQ_4x4(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
-;*
-;* void UnVQ_4x4(unsigned char *, unsigned char *, unsigned char *,
-;* unsigned short, unsigned short, unsigned short);
-;*
-;* FUNCTION
-;* This function draws an image into the specified buffer from the
-;* pointers and codebook provided. This routine has been optimized for
-;* a 320x200 image.
-;*
-;* INPUTS
-;* Codebook - Pointer to codebook used to draw image.
-;* Pointers - Pointer to vector pointer data.
-;* Buffer - Pointer to buffer to draw image into.
-;* BPR - Number of blocks per row.
-;* Rows - Number of rows.
-;* BufWidth - Width of destination buffer in pixels.
-;*
-;* RESULT
-;* NONE
-;*
-;****************************************************************************
-
- PUBLIC ASM_UnVQ_4x4
- ASM_UnVQ_4x4 PROC C USES ebx ecx edx esi edi \
- \
- codebook:DWORD, \
- pointers:DWORD, \
- buffer:DWORD, \
- blocksperrow:DWORD, \
- numrows:DWORD, \
- bufwidth:DWORD
-
- LOCAL data_end:DWORD
- ;LOCAL cb_offset:DWORD
- LOCAL edi_startval:DWORD
- LOCAL rowoffset:DWORD
- LOCAL entries:DWORD
-
-;----------------------------------------------------------------------------
-; Initialize
-;----------------------------------------------------------------------------
-
-; mov eax,[codebook] ;Adjust the codebook address so
-; sub eax,4 ; that the pointer offsets will
-; mov [cb_offset],eax ; point directly at the codeword.
-
- mov eax,[bufwidth] ;Compute the offset to the next
- shl eax,2 ; row of blocks
- mov [rowoffset],eax
-
- mov esi,[pointers]
- mov eax,[numrows] ;Compute the end address of the
- mul [blocksperrow] ; pointer data.
- mov [entries],eax
- add eax,esi
- mov [data_end],eax
-
- IF PHARLAP_TNT
- push es
- les edi,[FWORD buffer] ;KLUDGE - bcc32 pads FARPTR
- ELSE
- mov edi,[buffer]
- ENDIF
-
- mov [edi_startval],edi
-
-;----------------------------------------------------------------------------
-; Drawing loop
-;----------------------------------------------------------------------------
-
-??Start_row:
- mov ecx,[blocksperrow] ;Number of blocks in a line
-
-??Not_finished_a_line:
- mov eax,[entries]
- xor ebx,ebx
- mov bh,[esi + eax] ;Get the codebook pointer value
- mov bl,[esi]
- inc esi ; then advance to the next one.
-
- cmp bh,0FFh ;Is it a one color block?
- je short ??One_color
-
-; Draw multi-color block
-
- shl ebx,4
- add ebx,[codebook] ;Codeword address
- mov eax,[ebx] ;Read 1st row of codeword
- mov edx,[ebx+4] ;Read 2nd row of codeword
-
- IF PHARLAP_TNT
- mov [es:edi],eax ;Write 1st row to dest
- ELSE
- mov [edi],eax ;Write 1st row to dest
- ENDIF
-
- mov eax,ebx
- mov ebx,[bufwidth]
-
- IF PHARLAP_TNT
- mov [es:edi+ebx],edx ;Write 2nd row to dest
- ELSE
- mov [edi+ebx],edx ;Write 2nd row to dest
- ENDIF
-
- mov ebx,eax
- mov eax,[ebx+8]
- mov edx,[ebx+12]
- mov ebx,[bufwidth]
- shl ebx,1
-
- IF PHARLAP_TNT
- mov [es:edi+ebx],eax ;Write 2nd row to dest
- ELSE
- mov [edi+ebx],eax ;Write 2nd row to dest
- ENDIF
-
- add ebx,[bufwidth]
-
- IF PHARLAP_TNT
- mov [es:edi+ebx],edx ;Write 2nd row to dest
- ELSE
- mov [edi+ebx],edx ;Write 2nd row to dest
- ENDIF
-
- add edi,4 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-; Draw 1-color block
-
-??One_color:
-; cmp bx,SKIP_PTR ;Is this a skip block?
-; jne ??Draw_One_Color
-;
-; add edi,4 ;Move to next dest block position
-; dec ecx ;More blocks for this row?
-; jnz short ??Not_finished_a_line
-; jmp ??Next_row
-
-??Draw_One_Color:
-; not bx ;NOT pointer value to get color
- mov bh,bl ;Duplicate color through the
- mov ax,bx ; entire dword register.
- rol eax,16
- mov ax,bx
-
- IF PHARLAP_TNT
- mov [es:edi],eax ;Write 1st row to dest
- mov ebx,[bufwidth]
- mov [es:edi+ebx],eax ;Write 2nd row to dest
- ELSE
- mov [edi],eax ;Write 1st row to dest
- mov ebx,[bufwidth]
- mov [edi+ebx],eax ;Write 2nd row to dest
- ENDIF
-
- add ebx,[bufwidth]
-
- IF PHARLAP_TNT
- mov [es:edi+ebx],eax ;Write 3rd row to dest
- ELSE
- mov [edi+ebx],eax ;Write 3rd row to dest
- ENDIF
-
- add ebx,[bufwidth]
-
- IF PHARLAP_TNT
- mov [es:edi+ebx],eax ;Write 4th row to dest
- ELSE
- mov [edi+ebx],eax ;Write 4th row to dest
- ENDIF
-
- add edi,4 ;Next dest block positionw
- dec ecx ;More blocks for this row?
- jnz ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
-??Next_row:
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-??End_of_data:
- IF PHARLAP_TNT
- pop es
- ENDIF
-
- ret
-
- ASM_UnVQ_4x4 ENDP
- ENDIF ;VQABLOCK_4X4
-
-
-;;;; this is very close to UnVQ_2x2 in unvqbuff.asm ;;;;
-;****************************************************************************
-;*
-;* NAME
-;* ASM_UnVQ_4x4_HALF - Draw 4x4 block VQ frame to a buffer.
-;*
-;* SYNOPSIS
-;* ASM_UnVQ_4x4_HALF(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
-;*
-;* void ASM_UnVQ_4x4_HALF(unsigned char *, unsigned char *, unsigned char *,
-;* long, long, long);
-;*
-;* FUNCTION
-;* This function draws an image into the specified buffer from the
-;* pointers and codebook provided. This routine has been optimized for
-;* a 320x200 image.
-;*
-;* INPUTS
-;* Codebook - Pointer to codebook used to draw image.
-;* Pointers - Pointer to vector pointer data.
-;* Buffer - Pointer to buffer to draw image into.
-;* BPR - Number of blocks per row.
-;* Rows - Number of rows.
-;* BufWidth - Width of destination buffer in pixels.
-;*
-;* RESULT
-;* NONE
-;*
-;****************************************************************************
-
- PUBLIC ASM_UnVQ_4x4_HALF
- ASM_UnVQ_4x4_HALF PROC C USES ebx ecx edx esi edi \
- \
- codebook:DWORD, \
- pointers:DWORD, \
- buffer:DWORD, \
- blocksperrow:DWORD, \
- numrows:DWORD, \
- bufwidth:DWORD
-
- LOCAL data_end:DWORD
- ;LOCAL cb_offset:DWORD
- LOCAL edi_startval:DWORD
- LOCAL rowoffset:DWORD
- LOCAL entries:DWORD
-
-;----------------------------------------------------------------------------
-; Initialize
-;----------------------------------------------------------------------------
-
-; mov eax,[codebook] ;Adjust the codebook address so
-; sub eax,4 ; that the pointer offsets will
-; mov [cb_offset],eax ; point directly at the codeword.
-
- mov eax,[bufwidth] ;Compute the offset to the next
- shl eax,1 ; row of blocks.
- mov [rowoffset],eax
-
- mov esi,[pointers]
- mov eax,[numrows] ;Compute the end address of the
- mul [blocksperrow] ; pointer data.
- mov [entries],eax
- add eax,esi
- mov [data_end],eax
-
- IF PHARLAP_TNT
- push es
- les edi,[FWORD buffer] ;KLUDGE - bcc32 pads FARPTR
- ELSE
- mov edi,[buffer]
- ENDIF
-
- mov [edi_startval],edi
-
-;----------------------------------------------------------------------------
-; Drawing loop
-;----------------------------------------------------------------------------
-
-??Start_row:
- mov ecx,[blocksperrow] ;Number of blocks in a line
-
-??Not_finished_a_line:
- mov eax,[entries]
- xor ebx,ebx
- mov bh,[esi + eax] ;Get the codebook pointer value
- mov bl,[esi]
- inc esi ; then advance to the next one.
-
- cmp bh,0FFh ;Is it a one color block?
- je short ??One_color
-
-; Draw multi-color block
-
- shl ebx,4
- add ebx,[codebook] ;Codeword address
- mov al,[ebx]
- mov ah,[ebx+2]
-
- IF PHARLAP_TNT
- mov [es:edi],ax ;Write 1st row to dest
- ELSE
- mov [edi],ax ;Write 1st row to dest
- ENDIF
-
- mov al,[ebx+8]
- mov ah,[ebx+10]
- mov ebx,[bufwidth]
-
- IF PHARLAP_TNT
- mov [es:edi+ebx],ax ;Write 2nd row to dest
- ELSE
- mov [edi+ebx],ax ;Write 2nd row to dest
- ENDIF
-
-
- add edi,2 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-; Draw 1-color block
-
-??One_color:
-; cmp bx,SKIP_PTR ;Is this a skip block?
-; jne ??Draw_One_Color
-;
-; add edi,4 ;Move to next dest block position
-; dec ecx ;More blocks for this row?
-; jnz short ??Not_finished_a_line
-; jmp ??Next_row
-
-??Draw_One_Color:
-; not bx ;NOT pointer value to get color
- mov bh,bl ;Duplicate color through the
- mov ax,bx ; entire dword register.
-
- IF PHARLAP_TNT
- mov [es:edi],ax ;Write 1st row to dest
- mov ebx,[bufwidth]
- mov [es:edi+ebx],ax ;Write 2nd row to dest
- ELSE
- mov [edi],ax ;Write 1st row to dest
- mov ebx,[bufwidth]
- mov [edi+ebx],ax ;Write 2nd row to dest
- ENDIF
-
- add edi,2 ;Next dest block positionw
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
-??Next_row:
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-??End_of_data:
- IF PHARLAP_TNT
- pop es
- ENDIF
-
- ret
-
- ASM_UnVQ_4x4_HALF ENDP
-
-
-;;;; this is very close to UnVQ_2x2 in unvqbuff.asm ;;;;
-;****************************************************************************
-;*
-;* NAME
-;* ASM_UnVQ_6 - Draw XxX block VQ frame to a buffer.
-;*
-;* SYNOPSIS
-;* ASM_UnVQ_6(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
-;*
-;* void ASM_UnVQ_6(unsigned char *, unsigned char *, unsigned char *,
-;* long, long, long);
-;*
-;* FUNCTION
-;* This function draws an image into the specified buffer from the
-;* pointers and codebook provided. This routine has been optimized for
-;* a 320x200 image.
-;*
-;* INPUTS
-;* Codebook - Pointer to codebook used to draw image.
-;* Pointers - Pointer to vector pointer data.
-;* Buffer - Pointer to buffer to draw image into.
-;* BPR - Number of blocks per row.
-;* Rows - Number of rows.
-;* BufWidth - Width of destination buffer in pixels.
-;*
-;* RESULT
-;* NONE
-;*
-;****************************************************************************
-
- PUBLIC ASM_UnVQ_6
- ASM_UnVQ_6 PROC C USES ebx ecx edx esi edi \
- \
- codebook:DWORD, \
- pointers:DWORD, \
- buffer:DWORD, \
- blocksperrow:DWORD, \
- numrows:DWORD, \
- bufwidth:DWORD
-
- LOCAL data_end:DWORD
- ;LOCAL cb_offset:DWORD
- LOCAL edi_startval:DWORD
- LOCAL rowoffset:DWORD
- LOCAL entries:DWORD
-
-;----------------------------------------------------------------------------
-; Initialize
-;----------------------------------------------------------------------------
-
-; mov eax,[codebook] ;Adjust the codebook address so
-; sub eax,4 ; that the pointer offsets will
-; mov [cb_offset],eax ; point directly at the codeword.
-
- mov eax,[bufwidth] ;Compute the offset to the next
- shl eax,1 ; row of blocks.
- mov [rowoffset],eax
-
- mov esi,[pointers]
- mov eax,[numrows] ;Compute the end address of the
- mul [blocksperrow] ; pointer data.
- mov [entries],eax
- add eax,esi
- mov [data_end],eax
-
- IF PHARLAP_TNT
- push es
- les edi,[FWORD buffer] ;KLUDGE - bcc32 pads FARPTR
- ELSE
- mov edi,[buffer]
- ENDIF
-
- mov [edi_startval],edi
-
-;----------------------------------------------------------------------------
-; Drawing loop
-;----------------------------------------------------------------------------
-
-??Start_row:
- mov ecx,[blocksperrow] ;Number of blocks in a line
-
-??Not_finished_a_line:
- mov eax,[entries]
- xor ebx,ebx
- mov bh,[esi + eax] ;Get the codebook pointer value
- mov bl,[esi]
- inc esi ; then advance to the next one.
-
- cmp bh,0FFh ;Is it a one color block?
- je short ??One_color
-
-; Draw multi-color block
-
- shl ebx,3
- add ebx,[codebook] ;Codeword address
- mov al,[ebx]
- mov ah,[ebx+2]
-
- IF PHARLAP_TNT
- mov [es:edi],ax ;Write 1st row to dest
- ELSE
- mov [edi],ax ;Write 1st row to dest
- ENDIF
-
- mov al,[ebx+8]
- mov ah,[ebx+10]
-
- IF PHARLAP_TNT
- mov ebx,[bufwidth]
- mov [es:edi+ebx],ax ;Write 2nd row to dest
- ELSE
- mov ebx,[bufwidth]
- mov [edi+ebx],ax ;Write 2nd row to dest
- ENDIF
-
-
- add edi,2 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-; Draw 1-color block
-
-??One_color:
-; cmp bx,SKIP_PTR ;Is this a skip block?
-; jne ??Draw_One_Color
-;
-; add edi,4 ;Move to next dest block position
-; dec ecx ;More blocks for this row?
-; jnz short ??Not_finished_a_line
-; jmp ??Next_row
-
-??Draw_One_Color:
-; not bx ;NOT pointer value to get color
- mov bh,bl ;Duplicate color through the
- mov ax,bx ; entire dword register.
-
- IF PHARLAP_TNT
- mov [es:edi],ax ;Write 1st row to dest
- mov ebx,[bufwidth]
- mov [es:edi+ebx],ax ;Write 2nd row to dest
- ELSE
- mov [edi],ax ;Write 1st row to dest
- mov ebx,[bufwidth]
- mov [edi+ebx],ax ;Write 2nd row to dest
- ENDIF
-
- add edi,2 ;Next dest block positionw
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
-??Next_row:
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-??End_of_data:
- ret
-
- ASM_UnVQ_6 ENDP
-
-
-;;;; same as UnVQ_1 except fetches from buffer instead of HicolorTable ;;;;
-;****************************************************************************
-;*
-;* NAME
-;* ASM_UnVQ1_C1_4x4 - Draw 4x4 block VQ frame to a buffer.
-;*
-;* SYNOPSIS
-;* ASM_UnVQ1_C1_4x4(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
-;*
-;* void ASM_UnVQ1_C1_4x4(unsigned char *, unsigned char *, unsigned char *,
-;* long, long, long);
-;*
-;* FUNCTION
-;* This function draws an image into the specified buffer from the
-;* pointers and codebook provided. This routine has been optimized for
-;* a 320x200 image.
-;*
-;* INPUTS
-;* Codebook - Pointer to codebook used to draw image.
-;* Pointers - Pointer to vector pointer data.
-;* Buffer - Pointer to buffer to draw image into.
-;* BPR - Number of blocks per row.
-;* Rows - Number of rows.
-;* BufWidth - Width of destination buffer in pixels.
-;*
-;* RESULT
-;* NONE
-;*
-;****************************************************************************
-
- PUBLIC ASM_UnVQ1_C1_4x4
- ASM_UnVQ1_C1_4x4 PROC C USES ebx ecx edx esi edi \
- \
- codebook:DWORD, \
- pointers:DWORD, \
- buffer:DWORD, \
- blocksperrow:DWORD, \
- numrows:DWORD, \
- bufwidth:DWORD
-
- LOCAL data_end:DWORD
- ;LOCAL cb_offset:DWORD
- LOCAL edi_startval:DWORD
- LOCAL rowoffset:DWORD
- LOCAL unknown:DWORD
- LOCAL entries:DWORD
-
-;----------------------------------------------------------------------------
-; Initialize
-;----------------------------------------------------------------------------
-
-; mov eax,[codebook] ;Adjust the codebook address so
-; sub eax,4 ; that the pointer offsets will
-; mov [cb_offset],eax ; point directly at the codeword.
-
- shl [bufwidth],1
- mov eax,[bufwidth] ;Compute the offset to the next
- shl eax,2 ; row of blocks
- mov [rowoffset],eax
-
- mov esi,[pointers]
- mov eax,[numrows] ;Compute the end address of the
- mul [blocksperrow] ; pointer data.
- mov [entries],eax
- add eax,esi
- mov [data_end],eax
-
- IF PHARLAP_TNT
- push es
- les edi,[FWORD buffer] ;KLUDGE - bcc32 pads FARPTR
- ELSE
- mov edi,[buffer]
- ENDIF
-
- mov [edi_startval],edi
-
-;----------------------------------------------------------------------------
-; Drawing loop
-;----------------------------------------------------------------------------
-
-??Start_row:
- mov ecx,[blocksperrow] ;Number of blocks in a line
-
-??Not_finished_a_line:
- mov eax,[entries]
- xor ebx,ebx
- mov bh,[esi + eax] ;Get the codebook pointer value
- mov bl,[esi]
- inc esi ; then advance to the next one.
-
- test bh,080h ;Is it a one color block?
- js short ??One_color
-
-; Draw multi-color block
-
- shl ebx,5
- add ebx,[codebook] ;Codeword address
- mov eax,[ebx] ;Read 1st row of codeword
- mov edx,[ebx+4] ;Read 2nd row of codeword
-
- mov [edi],eax
- mov [edi+4],edx
-
- mov eax,[ebx+8]
- mov edx,[ebx+12]
- mov [unknown],ebx
- mov ebx,[bufwidth]
- mov [edi+ebx],eax
- mov [edi+ebx+4],edx
-
- mov ebx,[unknown]
- mov eax,[ebx+16]
- mov edx,[ebx+20]
- mov ebx,[bufwidth]
- shl ebx,1
- mov [edi+ebx],eax
- mov [edi+ebx+4],edx
- mov ebx,[unknown]
-
- mov eax,[ebx+24]
- mov edx,[ebx+28]
- mov ebx,[bufwidth]
- shl ebx,1
- add ebx,[bufwidth]
- mov [edi+ebx],eax
- mov [edi+ebx+4],edx
-
- add edi,8 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-; Draw 1-color block
-
-??One_color:
-; cmp bx,SKIP_PTR ;Is this a skip block?
-; jne ??Draw_One_Color
-;
-; add edi,4 ;Move to next dest block position
-; dec ecx ;More blocks for this row?
-; jnz short ??Not_finished_a_line
-; jmp ??Next_row
-
-??Draw_One_Color:
-; not bx ;NOT pointer value to get color
- and bx,07FFFh
- mov ax,bx
- shl eax,16
- mov ax,bx
-
- mov [edi],eax
- mov [edi+4],eax
-
- mov ebx,[bufwidth]
-
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- add ebx,[bufwidth]
-
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- add ebx,[bufwidth]
-
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- add edi,8 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz ??Not_finished_a_line; jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
-??Next_row:
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-??End_of_data:
- ret
-
- ASM_UnVQ1_C1_4x4 ENDP
-
-
-;****************************************************************************
-;*
-;* NAME
-;* ASM_UnVQ_8 - Draw XxX block VQ frame to a buffer.
-;*
-;* SYNOPSIS
-;* ASM_UnVQ_8(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
-;*
-;* void ASM_UnVQ_8(unsigned char *, unsigned char *, unsigned char *,
-;* long, long, long);
-;*
-;* FUNCTION
-;* This function draws an image into the specified buffer from the
-;* pointers and codebook provided. This routine has been optimized for
-;* a 320x200 image.
-;*
-;* INPUTS
-;* Codebook - Pointer to codebook used to draw image.
-;* Pointers - Pointer to vector pointer data.
-;* Buffer - Pointer to buffer to draw image into.
-;* BPR - Number of blocks per row.
-;* Rows - Number of rows.
-;* BufWidth - Width of destination buffer in pixels.
-;*
-;* RESULT
-;* NONE
-;*
-;****************************************************************************
-
- PUBLIC ASM_UnVQ_8
- ASM_UnVQ_8 PROC C USES ebx ecx edx esi edi \
- \
- codebook:DWORD, \
- pointers:DWORD, \
- buffer:DWORD, \
- blocksperrow:DWORD, \
- numrows:DWORD, \
- bufwidth:DWORD
-
- LOCAL data_end:DWORD
- ;LOCAL cb_offset:DWORD
- LOCAL edi_startval:DWORD
- LOCAL rowoffset:DWORD
- LOCAL unknown:DWORD
- LOCAL entries:DWORD
-
-;----------------------------------------------------------------------------
-; Initialize
-;----------------------------------------------------------------------------
-
-; mov eax,[codebook] ;Adjust the codebook address so
-; sub eax,4 ; that the pointer offsets will
-; mov [cb_offset],eax ; point directly at the codeword.
-
- shl [bufwidth],1
- mov eax,[bufwidth] ;Compute the offset to the next
- shl eax,1 ; row of blocks.
- mov [rowoffset],eax
-
- mov esi,[pointers]
- mov eax,[numrows] ;Compute the end address of the
- mul [blocksperrow] ; pointer data.
- mov [entries],eax
- add eax,esi
- mov [data_end],eax
-
- mov edi,[buffer]
- mov [edi_startval],edi
-
-;----------------------------------------------------------------------------
-; Drawing loop
-;----------------------------------------------------------------------------
-
-??Start_row:
- mov ecx,[blocksperrow] ;Number of blocks in a line
-
-??Not_finished_a_line:
- mov eax,[entries]
- xor ebx,ebx
- mov bh,[esi + eax] ;Get the codebook pointer value
- mov bl,[esi]
- inc esi ; then advance to the next one.
-
- test bh,080h ;Is it a one color block?
- js short ??One_color
-
-; Draw multi-color block
-
- shl ebx,4
- add ebx,[codebook] ;Codeword address
- mov eax,[ebx] ;Read 1st row of codeword
- mov edx,[ebx+4] ;Read 2nd row of codeword
-
- mov [edi],eax
- mov [edi+4],edx
-
- mov eax,[ebx+8]
- mov edx,[ebx+12]
-
- mov ebx,[bufwidth]
-
- mov [edi+ebx],eax
- mov [edi+ebx+4],edx
-
- add edi,8 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-; Draw 1-color block
-
-??One_color:
-; cmp bx,SKIP_PTR ;Is this a skip block?
-; jne ??Draw_One_Color
-;
-; add edi,4 ;Move to next dest block position
-; dec ecx ;More blocks for this row?
-; jnz short ??Not_finished_a_line
-; jmp ??Next_row
-
-??Draw_One_Color:
-; not bx ;NOT pointer value to get color
- and bx,07FFFh
- mov ax,bx
- shl eax,16
- mov ax,bx
-
- mov [edi],eax
- mov [edi+4],eax
-
- mov ebx,[bufwidth]
-
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- add edi,8 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
-??Next_row:
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-??End_of_data:
- ret
-
- ASM_UnVQ_8 ENDP
-
-
-;****************************************************************************
-;*
-;* NAME
-;* ASM_UnVQ_9 - Draw XxX block VQ frame to a buffer.
-;*
-;* SYNOPSIS
-;* ASM_UnVQ_9(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
-;*
-;* void ASM_UnVQ_9(unsigned char *, unsigned char *, unsigned char *,
-;* long, long, long);
-;*
-;* FUNCTION
-;* This function draws an image into the specified buffer from the
-;* pointers and codebook provided. This routine has been optimized for
-;* a 320x200 image.
-;*
-;* INPUTS
-;* Codebook - Pointer to codebook used to draw image.
-;* Pointers - Pointer to vector pointer data.
-;* Buffer - Pointer to buffer to draw image into.
-;* BPR - Number of blocks per row.
-;* Rows - Number of rows.
-;* BufWidth - Width of destination buffer in pixels.
-;*
-;* RESULT
-;* NONE
-;*
-;****************************************************************************
-
- PUBLIC ASM_UnVQ_9
- ASM_UnVQ_9 PROC C USES ebx ecx edx esi edi \
- \
- codebook:DWORD, \
- pointers:DWORD, \
- buffer:DWORD, \
- blocksperrow:DWORD, \
- numrows:DWORD, \
- bufwidth:DWORD
-
- LOCAL data_end:DWORD
- ;LOCAL cb_offset:DWORD
- LOCAL edi_startval:DWORD
- LOCAL rowoffset:DWORD
- LOCAL entries:DWORD
-
-;----------------------------------------------------------------------------
-; Initialize
-;----------------------------------------------------------------------------
-
-; mov eax,[codebook] ;Adjust the codebook address so
-; sub eax,4 ; that the pointer offsets will
-; mov [cb_offset],eax ; point directly at the codeword.
-
- mov eax,[bufwidth] ;Compute the offset to the next
- shl eax,3 ; row of blocks.
- mov [rowoffset],eax
-
- mov esi,[pointers]
- mov eax,[numrows] ;Compute the end address of the
- mul [blocksperrow] ; pointer data.
- mov [entries],eax
- add eax,esi
- mov [data_end],eax
-
- mov edi,[buffer]
- mov [edi_startval],edi
-
-;----------------------------------------------------------------------------
-; Drawing loop
-;----------------------------------------------------------------------------
-
-??Start_row:
- mov ecx,[blocksperrow] ;Number of blocks in a line
-
-??Not_finished_a_line:
- mov eax,[entries]
- xor ebx,ebx
- mov bl,[esi]
- mov bh,[esi + eax] ;Get the codebook pointer value
- inc esi ; then advance to the next one.
-
- cmp bh,0FFh ;Is it a one color block?
- je short ??One_color
-
-; Draw multi-color block
-
- shl ebx,5
- add ebx,[codebook] ;Codeword address
- mov eax,[ebx]
- mov edx,[bufwidth]
-
- mov [edi],eax
-
- mov eax,[ebx+4]
- mov [edi+edx],eax
-
- shl edx,1
-
- mov eax,[ebx+8]
- mov [edi+edx],eax
-
- add edx,[bufwidth]
-
- mov eax,[ebx+12]
- mov [edi+edx],eax
-
- add edx,[bufwidth]
-
- mov eax,[ebx+16]
- mov [edi+edx],eax
-
- add edx,[bufwidth]
-
- mov eax,[ebx+20]
- mov [edi+edx],eax
-
- add edx,[bufwidth]
-
- mov eax,[ebx+24]
- mov [edi+edx],eax
-
- add edx,[bufwidth]
-
- mov eax,[ebx+28]
- mov [edi+edx],eax
-
- add edi,4 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-; Draw 1-color block
-
-??One_color:
-; cmp bx,SKIP_PTR ;Is this a skip block?
-; jne ??Draw_One_Color
-;
-; add edi,4 ;Move to next dest block position
-; dec ecx ;More blocks for this row?
-; jnz short ??Not_finished_a_line
-; jmp ??Next_row
-
-??Draw_One_Color:
-; not bx ;NOT pointer value to get color
- mov bh,bl ;Duplicate color through the
- mov ax,bx ; entire dword register.
- rol eax,16
- mov ax,bx
- mov ebx,[bufwidth]
-
- mov [edi],eax
-
- mov [edi+ebx],eax
-
- shl ebx,1
- mov [edi+ebx],eax
-
- add ebx,[bufwidth]
- mov [edi+ebx],eax
-
- add ebx,[bufwidth]
- mov [edi+ebx],eax
-
- add ebx,[bufwidth]
- mov [edi+ebx],eax
-
- add ebx,[bufwidth]
- mov [edi+ebx],eax
-
- add ebx,[bufwidth]
- mov [edi+ebx],eax
-
- add edi,4 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz ??Not_finished_a_line ;jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
-??Next_row:
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-??End_of_data:
- ret
-
- ASM_UnVQ_9 ENDP
-
-
-;****************************************************************************
-;*
-;* NAME
-;* ASM_UnVQ_10 - Draw XxX block VQ frame to a buffer.
-;*
-;* SYNOPSIS
-;* ASM_UnVQ_10(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
-;*
-;* void ASM_UnVQ_10(unsigned char *, unsigned char *, unsigned char *,
-;* long, long, long);
-;*
-;* FUNCTION
-;* This function draws an image into the specified buffer from the
-;* pointers and codebook provided. This routine has been optimized for
-;* a 320x200 image.
-;*
-;* INPUTS
-;* Codebook - Pointer to codebook used to draw image.
-;* Pointers - Pointer to vector pointer data.
-;* Buffer - Pointer to buffer to draw image into.
-;* BPR - Number of blocks per row.
-;* Rows - Number of rows.
-;* BufWidth - Width of destination buffer in pixels.
-;*
-;* RESULT
-;* NONE
-;*
-;****************************************************************************
-
- PUBLIC ASM_UnVQ_10
- ASM_UnVQ_10 PROC C USES ebx ecx edx esi edi \
- \
- codebook:DWORD, \
- pointers:DWORD, \
- buffer:DWORD, \
- blocksperrow:DWORD, \
- numrows:DWORD, \
- bufwidth:DWORD
-
- LOCAL data_end:DWORD
- ;LOCAL cb_offset:DWORD
- LOCAL edi_startval:DWORD
- LOCAL rowoffset:DWORD
- LOCAL entries:DWORD
-
-;----------------------------------------------------------------------------
-; Initialize
-;----------------------------------------------------------------------------
-
-; mov eax,[codebook] ;Adjust the codebook address so
-; sub eax,4 ; that the pointer offsets will
-; mov [cb_offset],eax ; point directly at the codeword.
-
- mov eax,[bufwidth] ;Compute the offset to the next
- shl eax,2 ; row of blocks.
- mov [rowoffset],eax
-
- mov esi,[pointers]
- mov eax,[numrows] ;Compute the end address of the
- mul [blocksperrow] ; pointer data.
- mov [entries],eax
- add eax,esi
- mov [data_end],eax
-
- mov edi,[buffer]
- mov [edi_startval],edi
-
-;----------------------------------------------------------------------------
-; Drawing loop
-;----------------------------------------------------------------------------
-
-??Start_row:
- mov ecx,[blocksperrow] ;Number of blocks in a line
-
-??Not_finished_a_line:
- mov eax,[entries]
- xor ebx,ebx
- mov bl,[esi]
- mov bh,[esi + eax] ;Get the codebook pointer value
- inc esi ; then advance to the next one.
-
- cmp bh,0FFh ;Is it a one color block?
- je short ??One_color
-
-; Draw multi-color block
-
- shl ebx,5
- add ebx,[codebook] ;Codeword address
- mov eax,[ebx]
- mov edx,[bufwidth]
-
- mov [edi],eax
-
- mov eax,[ebx+4]
- mov [edi+4],eax
-
- mov eax,[ebx+8]
- mov [edi+edx],eax
-
- mov eax,[ebx+12]
- mov [edi+edx+4],eax
-
- shl edx,1
-
- mov eax,[ebx+16]
- mov [edi+edx],eax
-
- mov eax,[ebx+20]
- mov [edi+edx+4],eax
-
- add edx,[bufwidth]
-
- mov eax,[ebx+24]
- mov [edi+edx],eax
-
- mov eax,[ebx+28]
- mov [edi+edx+4],eax
-
- add edi,8 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-; Draw 1-color block
-
-??One_color:
-; cmp bx,SKIP_PTR ;Is this a skip block?
-; jne ??Draw_One_Color
-;
-; add edi,4 ;Move to next dest block position
-; dec ecx ;More blocks for this row?
-; jnz short ??Not_finished_a_line
-; jmp ??Next_row
-
-??Draw_One_Color:
-; not bx ;NOT pointer value to get color
- mov bh,bl ;Duplicate color through the
- mov ax,bx ; entire dword register.
- rol eax,16
- mov ax,bx
- mov ebx,[bufwidth]
-
- mov [edi],eax
- mov [edi+4],eax
-
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- shl ebx,1
-
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- add ebx,[bufwidth]
-
- mov [edi+ebx],eax
- mov [edi+ebx+4],eax
-
- add edi,8 ;Next dest block position
- dec ecx ;More blocks for this row?
- jnz ??Not_finished_a_line ;jnz short ??Not_finished_a_line
-
-; Advance to the next destination row of blocks.
-
-??Next_row:
- mov edi,[edi_startval]
- add edi,[rowoffset]
- mov [edi_startval],edi
-
- cmp esi,[data_end] ;Have we reached the end of the
- jnb short ??End_of_data ; pointers buffer?
- jmp ??Start_row
-
-??End_of_data:
- ret
-
- ASM_UnVQ_10 ENDP
-
-END
diff --git a/code/unvqdec.cpp b/code/unvqdec.cpp
new file mode 100644
index 000000000..9e2ceba7a
--- /dev/null
+++ b/code/unvqdec.cpp
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * O P E N T S
+ *******************************************************************************
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright 2025 Electronic Arts Inc.
+ * Copyright 2026 OpenTS contributors
+ *
+ * Contains material derived from Electronic Arts source code.
+ * Modified by OpenTS contributors, 2026.
+ * EA's GPLv3 Section 7 additional terms and supplemental warranty
+ * disclaimers apply; see LICENSE.md.
+ ******************************************************************************/
+
+/****************************************************************************
+*
+* File : unvq_asm.asm
+* Description : VQA UnVQ1 full-frame decoders, drawing a VQ compressed
+* video frame into a pixel buffer.
+*
+****************************************************************************/
+
+#include "always.h"
+
+#include "vqalib/unvq.h"
+
+#include "_vqa.h"
+
+/*
+ * Six full-frame decoders, each replacing an assembly routine of the same name. They share a
+ * shape: a frame is a grid of blocks, and every block carries a pointer into the codebook.
+ *
+ * The pointers arrive as two planes rather than as pairs -- every block's low byte first, then
+ * every block's high byte -- so a block's codebook index is assembled from the two.
+ *
+ * A block is either a codebook entry copied out, or a single colour filling the whole block.
+ * The two families differ in how they say which: an 8 bit frame marks a solid block with a
+ * high byte of 0xFF and takes the colour from the low byte, while a 16 bit frame marks it with
+ * the top bit and takes the remaining 15 as the colour. Of the 16 bit decoders, the two named
+ * TABLE run that colour through HicolorTable; ASM_UnVQ1_C1_4x4 uses it as the pixel directly.
+ *
+ * Names carry the block size the codebook holds, not always the size written: 4x4_HALF reads a
+ * 4x4 entry and writes every other pixel of every other row, and TABLE_ALT reads a 4x4 entry
+ * and writes its first and third rows two screen rows apart.
+ */
+
+namespace {
+
+///
+/// Assembles one block's codebook index from the two pointer planes.
+///
+/// Base of the pointer data.
+/// Total block count, which is where the high plane starts.
+/// Which block to read.
+/// unsigned int; The codebook index.
+inline unsigned int Block_Index(unsigned char const * pointers, unsigned long entries, unsigned long block)
+{
+ return(((unsigned int)pointers[entries + block] << 8) | (unsigned int)pointers[block]);
+}
+
+
+inline void Put32(unsigned char * dest, unsigned char const * source)
+{
+ dest[0] = source[0];
+ dest[1] = source[1];
+ dest[2] = source[2];
+ dest[3] = source[3];
+}
+
+
+inline void Fill32(unsigned char * dest, unsigned int value)
+{
+ dest[0] = (unsigned char)(value & 0xFF);
+ dest[1] = (unsigned char)((value >> 8) & 0xFF);
+ dest[2] = (unsigned char)((value >> 16) & 0xFF);
+ dest[3] = (unsigned char)((value >> 24) & 0xFF);
+}
+
+
+inline void Put16(unsigned char * dest, unsigned char const * source)
+{
+ dest[0] = source[0];
+ dest[1] = source[1];
+}
+
+
+inline void Fill16(unsigned char * dest, unsigned int value)
+{
+ dest[0] = (unsigned char)(value & 0xFF);
+ dest[1] = (unsigned char)((value >> 8) & 0xFF);
+}
+
+
+/*
+ * Spreads a 16 bit pixel across a doubleword so a solid block is filled four bytes at a time,
+ * the way the assembly did it.
+ */
+inline unsigned int Pair16(unsigned int pixel)
+{
+ return((pixel << 16) | pixel);
+}
+
+
+inline unsigned int Quad8(unsigned int colour)
+{
+ unsigned int const pair = (colour << 8) | colour;
+ return((pair << 16) | pair);
+}
+
+} // namespace
+
+
+///
+/// Draws a 16 bit frame from 4x4 codebook entries, taking a solid block's colour from
+/// HicolorTable.
+///
+/// Codebook the blocks are drawn from.
+/// Block pointer data, low plane then high plane.
+/// Destination pixel buffer.
+/// Blocks across one row of the frame.
+/// Rows of blocks in the frame.
+/// Destination width in pixels.
+void __cdecl ASM_UnVQ1_C1_TABLE(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+ unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+{
+ if (blocksperrow == 0) {
+ return;
+ }
+
+ unsigned long const pitch = bufwidth * 2;
+ unsigned long const rowoffset = pitch * 4;
+ unsigned long const entries = numrows * blocksperrow;
+
+ unsigned char * rowstart = buffer;
+ unsigned long block = 0;
+
+ do {
+ unsigned char * dest = rowstart;
+
+ for (unsigned long i = 0; i < blocksperrow; i++) {
+ unsigned int const index = Block_Index(pointers, entries, block);
+ block++;
+
+ if ((index & 0x8000) != 0) {
+ unsigned int const pixels = Pair16(HicolorTable[index & 0x7FFF]);
+
+ for (int row = 0; row < 4; row++) {
+ Fill32(dest + row * pitch, pixels);
+ Fill32(dest + row * pitch + 4, pixels);
+ }
+ } else {
+ unsigned char const * word = codebook + index * 32;
+
+ for (int row = 0; row < 4; row++) {
+ Put32(dest + row * pitch, word + row * 8);
+ Put32(dest + row * pitch + 4, word + row * 8 + 4);
+ }
+ }
+
+ dest += 8;
+ }
+
+ rowstart += rowoffset;
+ } while (block < entries);
+}
+
+
+///
+/// Draws a 16 bit frame from the first and third rows of 4x4 codebook entries, written two
+/// screen rows apart. A solid block's colour comes from HicolorTable.
+///
+/// Codebook the blocks are drawn from.
+/// Block pointer data, low plane then high plane.
+/// Destination pixel buffer.
+/// Blocks across one row of the frame.
+/// Rows of blocks in the frame.
+/// Destination width in pixels.
+void __cdecl ASM_UnVQ1_C1_TABLE_ALT(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+ unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+{
+ if (blocksperrow == 0) {
+ return;
+ }
+
+ unsigned long const pitch = bufwidth * 2;
+ unsigned long const rowoffset = pitch * 4;
+ unsigned long const entries = numrows * blocksperrow;
+
+ unsigned char * rowstart = buffer;
+ unsigned long block = 0;
+
+ do {
+ unsigned char * dest = rowstart;
+
+ for (unsigned long i = 0; i < blocksperrow; i++) {
+ unsigned int const index = Block_Index(pointers, entries, block);
+ block++;
+
+ if ((index & 0x8000) != 0) {
+ unsigned int const pixels = Pair16(HicolorTable[index & 0x7FFF]);
+
+ Fill32(dest, pixels);
+ Fill32(dest + 4, pixels);
+ Fill32(dest + pitch * 2, pixels);
+ Fill32(dest + pitch * 2 + 4, pixels);
+ } else {
+ unsigned char const * word = codebook + index * 32;
+
+ Put32(dest, word);
+ Put32(dest + 4, word + 4);
+ Put32(dest + pitch * 2, word + 16);
+ Put32(dest + pitch * 2 + 4, word + 20);
+ }
+
+ dest += 8;
+ }
+
+ rowstart += rowoffset;
+ } while (block < entries);
+}
+
+
+///
+/// Draws an 8 bit frame from 4x2 codebook entries.
+///
+/// Codebook the blocks are drawn from.
+/// Block pointer data, low plane then high plane.
+/// Destination pixel buffer.
+/// Blocks across one row of the frame.
+/// Rows of blocks in the frame.
+/// Destination width in pixels.
+void __cdecl ASM_UnVQ_4x2(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+ unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+{
+ if (blocksperrow == 0) {
+ return;
+ }
+
+ unsigned long const rowoffset = bufwidth * 2;
+ unsigned long const entries = numrows * blocksperrow;
+
+ unsigned char * rowstart = buffer;
+ unsigned long block = 0;
+
+ do {
+ unsigned char * dest = rowstart;
+
+ for (unsigned long i = 0; i < blocksperrow; i++) {
+ unsigned int const index = Block_Index(pointers, entries, block);
+ block++;
+
+ if ((index >> 8) == 0xFF) {
+ unsigned int const pixels = Quad8(index & 0xFF);
+
+ Fill32(dest, pixels);
+ Fill32(dest + bufwidth, pixels);
+ } else {
+ unsigned char const * word = codebook + index * 8;
+
+ Put32(dest, word);
+ Put32(dest + bufwidth, word + 4);
+ }
+
+ dest += 4;
+ }
+
+ rowstart += rowoffset;
+ } while (block < entries);
+}
+
+
+///
+/// Draws an 8 bit frame from 4x4 codebook entries.
+///
+/// Codebook the blocks are drawn from.
+/// Block pointer data, low plane then high plane.
+/// Destination pixel buffer.
+/// Blocks across one row of the frame.
+/// Rows of blocks in the frame.
+/// Destination width in pixels.
+void __cdecl ASM_UnVQ_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+ unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+{
+ if (blocksperrow == 0) {
+ return;
+ }
+
+ unsigned long const rowoffset = bufwidth * 4;
+ unsigned long const entries = numrows * blocksperrow;
+
+ unsigned char * rowstart = buffer;
+ unsigned long block = 0;
+
+ do {
+ unsigned char * dest = rowstart;
+
+ for (unsigned long i = 0; i < blocksperrow; i++) {
+ unsigned int const index = Block_Index(pointers, entries, block);
+ block++;
+
+ if ((index >> 8) == 0xFF) {
+ unsigned int const pixels = Quad8(index & 0xFF);
+
+ for (int row = 0; row < 4; row++) {
+ Fill32(dest + row * bufwidth, pixels);
+ }
+ } else {
+ unsigned char const * word = codebook + index * 16;
+
+ for (int row = 0; row < 4; row++) {
+ Put32(dest + row * bufwidth, word + row * 4);
+ }
+ }
+
+ dest += 4;
+ }
+
+ rowstart += rowoffset;
+ } while (block < entries);
+}
+
+
+///
+/// Draws an 8 bit frame at half size, reading 4x4 codebook entries but keeping every other
+/// pixel of every other row.
+///
+/// Codebook the blocks are drawn from.
+/// Block pointer data, low plane then high plane.
+/// Destination pixel buffer.
+/// Blocks across one row of the frame.
+/// Rows of blocks in the frame.
+/// Destination width in pixels.
+void __cdecl ASM_UnVQ_4x4_HALF(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+ unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+{
+ if (blocksperrow == 0) {
+ return;
+ }
+
+ unsigned long const rowoffset = bufwidth * 2;
+ unsigned long const entries = numrows * blocksperrow;
+
+ unsigned char * rowstart = buffer;
+ unsigned long block = 0;
+
+ do {
+ unsigned char * dest = rowstart;
+
+ for (unsigned long i = 0; i < blocksperrow; i++) {
+ unsigned int const index = Block_Index(pointers, entries, block);
+ block++;
+
+ if ((index >> 8) == 0xFF) {
+ unsigned char const colour = (unsigned char)(index & 0xFF);
+
+ dest[0] = colour;
+ dest[1] = colour;
+ dest[bufwidth] = colour;
+ dest[bufwidth + 1] = colour;
+ } else {
+ unsigned char const * word = codebook + index * 16;
+
+ dest[0] = word[0];
+ dest[1] = word[2];
+ dest[bufwidth] = word[8];
+ dest[bufwidth + 1] = word[10];
+ }
+
+ dest += 2;
+ }
+
+ rowstart += rowoffset;
+ } while (block < entries);
+}
+
+
+///
+/// Draws a 16 bit frame from 4x4 codebook entries, taking a solid block's colour from the
+/// pointer value itself rather than through HicolorTable.
+///
+/// Codebook the blocks are drawn from.
+/// Block pointer data, low plane then high plane.
+/// Destination pixel buffer.
+/// Blocks across one row of the frame.
+/// Rows of blocks in the frame.
+/// Destination width in pixels.
+void __cdecl ASM_UnVQ1_C1_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+ unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+{
+ if (blocksperrow == 0) {
+ return;
+ }
+
+ unsigned long const pitch = bufwidth * 2;
+ unsigned long const rowoffset = pitch * 4;
+ unsigned long const entries = numrows * blocksperrow;
+
+ unsigned char * rowstart = buffer;
+ unsigned long block = 0;
+
+ do {
+ unsigned char * dest = rowstart;
+
+ for (unsigned long i = 0; i < blocksperrow; i++) {
+ unsigned int const index = Block_Index(pointers, entries, block);
+ block++;
+
+ if ((index & 0x8000) != 0) {
+ unsigned int const pixels = Pair16(index & 0x7FFF);
+
+ for (int row = 0; row < 4; row++) {
+ Fill32(dest + row * pitch, pixels);
+ Fill32(dest + row * pitch + 4, pixels);
+ }
+ } else {
+ unsigned char const * word = codebook + index * 32;
+
+ for (int row = 0; row < 4; row++) {
+ Put32(dest + row * pitch, word + row * 8);
+ Put32(dest + row * pitch + 4, word + row * 8 + 4);
+ }
+ }
+
+ dest += 8;
+ }
+
+ rowstart += rowoffset;
+ } while (block < entries);
+}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 003214f46..e56c05c37 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -8,3 +8,4 @@ add_subdirectory(spawner)
add_subdirectory(syncrec)
add_subdirectory(colorops)
add_subdirectory(voxeldraw)
+add_subdirectory(unvqdec)
diff --git a/tests/unvqdec/CMakeLists.txt b/tests/unvqdec/CMakeLists.txt
new file mode 100644
index 000000000..5b94bcd16
--- /dev/null
+++ b/tests/unvqdec/CMakeLists.txt
@@ -0,0 +1,30 @@
+# The decoders are compiled straight into the harness. It lives outside code/ so that the
+# recursive glob building OpenTS cannot pick this target's entry point up.
+add_executable(UnvqDec
+ "${CMAKE_CURRENT_SOURCE_DIR}/unvqparity.cpp"
+ "${CMAKE_SOURCE_DIR}/code/unvqdec.cpp"
+)
+
+target_compile_features(UnvqDec PRIVATE cxx_std_20)
+
+target_include_directories(UnvqDec PRIVATE
+ "${CMAKE_SOURCE_DIR}/code"
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+target_compile_definitions(UnvqDec PRIVATE WIN32 _WINDOWS _MBCS)
+
+# The engine builds this source with SSE2 and precise floating point. The harness matches that
+# so a result here carries over to the engine.
+target_compile_options(UnvqDec PRIVATE
+ $<$:/MTd /EHsc /Zc:__cplusplus /arch:SSE2 /fp:precise>
+ $<$:/MT /EHsc /Zc:__cplusplus /arch:SSE2 /fp:precise>
+)
+
+target_link_libraries(UnvqDec PRIVATE kernel32 user32 shell32)
+
+set_target_properties(UnvqDec PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
+)
+
+add_test(NAME unvqdec COMMAND UnvqDec)
diff --git a/tests/unvqdec/unvqgolden.h b/tests/unvqdec/unvqgolden.h
new file mode 100644
index 000000000..bc67a1968
--- /dev/null
+++ b/tests/unvqdec/unvqgolden.h
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * O P E N T S
+ *******************************************************************************
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright 2026 OpenTS contributors
+ *
+ * See LICENSE.md for applicable additional terms and warranty disclaimers.
+ ******************************************************************************/
+
+// Generated from the UnVQ1 block decoders while they were still hand-written assembly,
+// and kept so the C++ that replaced them can be held to the same output.
+//
+// Generated file. Do not hand-edit.
+
+#pragma once
+
+struct UnVQGoldenCase {
+ int Which;
+ unsigned long BlocksPerRow;
+ unsigned long NumRows;
+ unsigned long BufWidth;
+ unsigned int Seed;
+ int Solid;
+ unsigned long long Hash;
+};
+
+static UnVQGoldenCase const UnVQGoldenCases[] = {
+ {0, 1ul, 1ul, 8ul, 39256u, 0, 2895180338204187794ULL},
+ {0, 1ul, 1ul, 8ul, 47175u, 3, 17757882376145931266ULL},
+ {0, 1ul, 1ul, 8ul, 55094u, 6, 1310722270548503139ULL},
+ {0, 2ul, 1ul, 16ul, 63013u, 0, 13290677462593678327ULL},
+ {0, 2ul, 1ul, 16ul, 70932u, 3, 18036005907330044508ULL},
+ {0, 2ul, 1ul, 16ul, 78851u, 6, 13899957888247383084ULL},
+ {0, 1ul, 2ul, 8ul, 86770u, 0, 16205816349972030866ULL},
+ {0, 1ul, 2ul, 8ul, 94689u, 3, 2089316313385929475ULL},
+ {0, 1ul, 2ul, 8ul, 102608u, 6, 176863261255263274ULL},
+ {0, 4ul, 3ul, 32ul, 110527u, 0, 11407330926932259914ULL},
+ {0, 4ul, 3ul, 32ul, 118446u, 3, 9095622258641437780ULL},
+ {0, 4ul, 3ul, 32ul, 126365u, 6, 12123533738725787750ULL},
+ {0, 8ul, 5ul, 64ul, 134284u, 0, 6234379622060752775ULL},
+ {0, 8ul, 5ul, 64ul, 142203u, 3, 5384650114977810682ULL},
+ {0, 8ul, 5ul, 64ul, 150122u, 6, 18341148558070273986ULL},
+ {0, 16ul, 4ul, 128ul, 158041u, 0, 9489199241227354259ULL},
+ {0, 16ul, 4ul, 128ul, 165960u, 3, 410521912332868001ULL},
+ {0, 16ul, 4ul, 128ul, 173879u, 6, 16714704385500838210ULL},
+ {0, 40ul, 8ul, 320ul, 181798u, 0, 1680827606164676883ULL},
+ {0, 40ul, 8ul, 320ul, 189717u, 3, 9918701732719108227ULL},
+ {0, 40ul, 8ul, 320ul, 197636u, 6, 4093886688550579255ULL},
+ {0, 80ul, 6ul, 640ul, 205555u, 0, 1728636679431568073ULL},
+ {0, 80ul, 6ul, 640ul, 213474u, 3, 9815469616241825781ULL},
+ {0, 80ul, 6ul, 640ul, 221393u, 6, 15879347310269872882ULL},
+ {1, 1ul, 1ul, 8ul, 229312u, 0, 6904545672353592445ULL},
+ {1, 1ul, 1ul, 8ul, 237231u, 3, 7572489033761486867ULL},
+ {1, 1ul, 1ul, 8ul, 245150u, 6, 10460081396690070835ULL},
+ {1, 2ul, 1ul, 16ul, 253069u, 0, 4346579680639647831ULL},
+ {1, 2ul, 1ul, 16ul, 260988u, 3, 13358952695467658649ULL},
+ {1, 2ul, 1ul, 16ul, 268907u, 6, 15231705630455511699ULL},
+ {1, 1ul, 2ul, 8ul, 276826u, 0, 11399492110333932431ULL},
+ {1, 1ul, 2ul, 8ul, 284745u, 3, 14527847966156556939ULL},
+ {1, 1ul, 2ul, 8ul, 292664u, 6, 4593385139775936671ULL},
+ {1, 4ul, 3ul, 32ul, 300583u, 0, 7916149013438277554ULL},
+ {1, 4ul, 3ul, 32ul, 308502u, 3, 5723184743254390524ULL},
+ {1, 4ul, 3ul, 32ul, 316421u, 6, 14361154402489545643ULL},
+ {1, 8ul, 5ul, 64ul, 324340u, 0, 2598479551401106955ULL},
+ {1, 8ul, 5ul, 64ul, 332259u, 3, 6011383005848795415ULL},
+ {1, 8ul, 5ul, 64ul, 340178u, 6, 10350345297621128583ULL},
+ {1, 16ul, 4ul, 128ul, 348097u, 0, 659948498303876753ULL},
+ {1, 16ul, 4ul, 128ul, 356016u, 3, 16557186128372377563ULL},
+ {1, 16ul, 4ul, 128ul, 363935u, 6, 12903925725161468289ULL},
+ {1, 40ul, 8ul, 320ul, 371854u, 0, 16836206211057703994ULL},
+ {1, 40ul, 8ul, 320ul, 379773u, 3, 6555152581767122262ULL},
+ {1, 40ul, 8ul, 320ul, 387692u, 6, 5914197655047528973ULL},
+ {1, 80ul, 6ul, 640ul, 395611u, 0, 1860580819577028376ULL},
+ {1, 80ul, 6ul, 640ul, 403530u, 3, 273668743315395098ULL},
+ {1, 80ul, 6ul, 640ul, 411449u, 6, 3274477421171696524ULL},
+ {2, 1ul, 1ul, 8ul, 419368u, 0, 7319516721727266879ULL},
+ {2, 1ul, 1ul, 8ul, 427287u, 3, 2692286575745468862ULL},
+ {2, 1ul, 1ul, 8ul, 435206u, 6, 9835579519873410565ULL},
+ {2, 2ul, 1ul, 16ul, 443125u, 0, 9560146741277564686ULL},
+ {2, 2ul, 1ul, 16ul, 451044u, 3, 2702462808681971654ULL},
+ {2, 2ul, 1ul, 16ul, 458963u, 6, 17530099301393760915ULL},
+ {2, 1ul, 2ul, 8ul, 466882u, 0, 15290904700629570014ULL},
+ {2, 1ul, 2ul, 8ul, 474801u, 3, 14945406362136875703ULL},
+ {2, 1ul, 2ul, 8ul, 482720u, 6, 13687515445097241811ULL},
+ {2, 4ul, 3ul, 32ul, 490639u, 0, 7767801254153680791ULL},
+ {2, 4ul, 3ul, 32ul, 498558u, 3, 6790497685525502818ULL},
+ {2, 4ul, 3ul, 32ul, 506477u, 6, 12622260113368074327ULL},
+ {2, 8ul, 5ul, 64ul, 514396u, 0, 16331290944465145099ULL},
+ {2, 8ul, 5ul, 64ul, 522315u, 3, 227455183991645826ULL},
+ {2, 8ul, 5ul, 64ul, 530234u, 6, 9709753186217421527ULL},
+ {2, 16ul, 4ul, 128ul, 538153u, 0, 7460992342372724961ULL},
+ {2, 16ul, 4ul, 128ul, 546072u, 3, 6622418918924008381ULL},
+ {2, 16ul, 4ul, 128ul, 553991u, 6, 15190498848712983205ULL},
+ {2, 40ul, 8ul, 320ul, 561910u, 0, 444001270176792181ULL},
+ {2, 40ul, 8ul, 320ul, 569829u, 3, 18418762446303843907ULL},
+ {2, 40ul, 8ul, 320ul, 577748u, 6, 322233945295055196ULL},
+ {2, 80ul, 6ul, 640ul, 585667u, 0, 18041946778258598643ULL},
+ {2, 80ul, 6ul, 640ul, 593586u, 3, 14299794166472370116ULL},
+ {2, 80ul, 6ul, 640ul, 601505u, 6, 7650313287078190776ULL},
+ {3, 1ul, 1ul, 8ul, 609424u, 0, 8336221726965572926ULL},
+ {3, 1ul, 1ul, 8ul, 617343u, 3, 14357669097801118602ULL},
+ {3, 1ul, 1ul, 8ul, 625262u, 6, 11888461547242737411ULL},
+ {3, 2ul, 1ul, 16ul, 633181u, 0, 12451402414277933228ULL},
+ {3, 2ul, 1ul, 16ul, 641100u, 3, 14031562617456302358ULL},
+ {3, 2ul, 1ul, 16ul, 649019u, 6, 12682485296615916062ULL},
+ {3, 1ul, 2ul, 8ul, 656938u, 0, 17025345068406506660ULL},
+ {3, 1ul, 2ul, 8ul, 664857u, 3, 14855605504341511520ULL},
+ {3, 1ul, 2ul, 8ul, 672776u, 6, 8439885122264472260ULL},
+ {3, 4ul, 3ul, 32ul, 680695u, 0, 8823368132228201645ULL},
+ {3, 4ul, 3ul, 32ul, 688614u, 3, 14331363456787526435ULL},
+ {3, 4ul, 3ul, 32ul, 696533u, 6, 3263843499962730247ULL},
+ {3, 8ul, 5ul, 64ul, 704452u, 0, 334276754665621425ULL},
+ {3, 8ul, 5ul, 64ul, 712371u, 3, 17406228746353370517ULL},
+ {3, 8ul, 5ul, 64ul, 720290u, 6, 2412999515486084193ULL},
+ {3, 16ul, 4ul, 128ul, 728209u, 0, 6515991890092044561ULL},
+ {3, 16ul, 4ul, 128ul, 736128u, 3, 14862942283240370395ULL},
+ {3, 16ul, 4ul, 128ul, 744047u, 6, 11418913403603726657ULL},
+ {3, 40ul, 8ul, 320ul, 751966u, 0, 1520305175013350579ULL},
+ {3, 40ul, 8ul, 320ul, 759885u, 3, 5503740123338513368ULL},
+ {3, 40ul, 8ul, 320ul, 767804u, 6, 15730164623780678191ULL},
+ {3, 80ul, 6ul, 640ul, 775723u, 0, 1082841911554596682ULL},
+ {3, 80ul, 6ul, 640ul, 783642u, 3, 5163514330395019813ULL},
+ {3, 80ul, 6ul, 640ul, 791561u, 6, 37323671311232753ULL},
+ {4, 1ul, 1ul, 8ul, 799480u, 0, 1810900035607166633ULL},
+ {4, 1ul, 1ul, 8ul, 807399u, 3, 5422460428662588071ULL},
+ {4, 1ul, 1ul, 8ul, 815318u, 6, 9890215725304960084ULL},
+ {4, 2ul, 1ul, 16ul, 823237u, 0, 12872001784068871327ULL},
+ {4, 2ul, 1ul, 16ul, 831156u, 3, 6794633583440300094ULL},
+ {4, 2ul, 1ul, 16ul, 839075u, 6, 7053783228759131829ULL},
+ {4, 1ul, 2ul, 8ul, 846994u, 0, 16029464194912996640ULL},
+ {4, 1ul, 2ul, 8ul, 854913u, 3, 4061107708200613361ULL},
+ {4, 1ul, 2ul, 8ul, 862832u, 6, 4287611396669678951ULL},
+ {4, 4ul, 3ul, 32ul, 870751u, 0, 17589643954509062724ULL},
+ {4, 4ul, 3ul, 32ul, 878670u, 3, 13894740507817048105ULL},
+ {4, 4ul, 3ul, 32ul, 886589u, 6, 4051733282120936329ULL},
+ {4, 8ul, 5ul, 64ul, 894508u, 0, 10873377070287797979ULL},
+ {4, 8ul, 5ul, 64ul, 902427u, 3, 10458937627385746432ULL},
+ {4, 8ul, 5ul, 64ul, 910346u, 6, 1070299413120541637ULL},
+ {4, 16ul, 4ul, 128ul, 918265u, 0, 7965563385219278396ULL},
+ {4, 16ul, 4ul, 128ul, 926184u, 3, 13262030059095557298ULL},
+ {4, 16ul, 4ul, 128ul, 934103u, 6, 3969192512777103613ULL},
+ {4, 40ul, 8ul, 320ul, 942022u, 0, 6680452675702737586ULL},
+ {4, 40ul, 8ul, 320ul, 949941u, 3, 14168562727132037992ULL},
+ {4, 40ul, 8ul, 320ul, 957860u, 6, 5969306658812640273ULL},
+ {4, 80ul, 6ul, 640ul, 965779u, 0, 9614296579228538735ULL},
+ {4, 80ul, 6ul, 640ul, 973698u, 3, 16362478091999660680ULL},
+ {4, 80ul, 6ul, 640ul, 981617u, 6, 3759891232464906609ULL},
+ {5, 1ul, 1ul, 8ul, 989536u, 0, 9562682815685531595ULL},
+ {5, 1ul, 1ul, 8ul, 997455u, 3, 3713967301877667905ULL},
+ {5, 1ul, 1ul, 8ul, 1005374u, 6, 15825502959710816937ULL},
+ {5, 2ul, 1ul, 16ul, 1013293u, 0, 18092955949082007219ULL},
+ {5, 2ul, 1ul, 16ul, 1021212u, 3, 5049477157122299998ULL},
+ {5, 2ul, 1ul, 16ul, 1029131u, 6, 12138214995037531598ULL},
+ {5, 1ul, 2ul, 8ul, 1037050u, 0, 5011464688791974774ULL},
+ {5, 1ul, 2ul, 8ul, 1044969u, 3, 16671972731677576087ULL},
+ {5, 1ul, 2ul, 8ul, 1052888u, 6, 13814250979399252388ULL},
+ {5, 4ul, 3ul, 32ul, 1060807u, 0, 1316452514753016705ULL},
+ {5, 4ul, 3ul, 32ul, 1068726u, 3, 7728036922611984938ULL},
+ {5, 4ul, 3ul, 32ul, 1076645u, 6, 15758488203009734528ULL},
+ {5, 8ul, 5ul, 64ul, 1084564u, 0, 4686816581985809121ULL},
+ {5, 8ul, 5ul, 64ul, 1092483u, 3, 8615585687532332172ULL},
+ {5, 8ul, 5ul, 64ul, 1100402u, 6, 8465735642007006319ULL},
+ {5, 16ul, 4ul, 128ul, 1108321u, 0, 16606183072978705678ULL},
+ {5, 16ul, 4ul, 128ul, 1116240u, 3, 6751492619167284339ULL},
+ {5, 16ul, 4ul, 128ul, 1124159u, 6, 13600317944702643181ULL},
+ {5, 40ul, 8ul, 320ul, 1132078u, 0, 17852441066602527924ULL},
+ {5, 40ul, 8ul, 320ul, 1139997u, 3, 12864533129715870536ULL},
+ {5, 40ul, 8ul, 320ul, 1147916u, 6, 17944196833427838413ULL},
+ {5, 80ul, 6ul, 640ul, 1155835u, 0, 11902721631645551582ULL},
+ {5, 80ul, 6ul, 640ul, 1163754u, 3, 15019696812734146483ULL},
+ {5, 80ul, 6ul, 640ul, 1171673u, 6, 8790841772678952242ULL},
+};
+
+static int const UnVQGoldenCaseCount = 144;
diff --git a/tests/unvqdec/unvqparity.cpp b/tests/unvqdec/unvqparity.cpp
new file mode 100644
index 000000000..673733895
--- /dev/null
+++ b/tests/unvqdec/unvqparity.cpp
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * O P E N T S
+ *******************************************************************************
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright 2026 OpenTS contributors
+ *
+ * See LICENSE.md for applicable additional terms and warranty disclaimers.
+ ******************************************************************************/
+
+// Holds the UnVQ1 block decoders in unvqdec.cpp to the output the assembly they replaced
+// produced. The vectors in unvqgolden.h were recorded from that assembly before it was
+// removed. Needs no game data.
+
+#include
+#include
+
+#include "vqalib/unvq.h"
+
+#include "unvqgolden.h"
+
+extern "C" unsigned short * HicolorTable = 0;
+
+namespace {
+
+int const CBMAX = 65536;
+int const DSTMAX = 1048576;
+int const PTRMAX = 8192;
+unsigned char const GUARD = 0xA5;
+
+unsigned char Codebook[CBMAX];
+unsigned char Pointers[PTRMAX * 2];
+unsigned char DestStore[DSTMAX];
+unsigned short HicolorStore[32768];
+
+unsigned int Seed = 0;
+
+int Failures = 0;
+int Checked = 0;
+
+
+unsigned int Next_Random(void)
+{
+ Seed = Seed * 1103515245u + 12345u;
+ return(Seed >> 8);
+}
+
+
+unsigned long long Hash(unsigned char const * data, int size)
+{
+ unsigned long long hash = 1469598103934665603ULL;
+ for (int i = 0; i < size; i++) {
+ hash ^= (unsigned long long)data[i];
+ hash *= 1099511628211ULL;
+ }
+ return(hash);
+}
+
+
+/*
+ * Must build byte for byte what the generator built, or the recorded output describes a
+ * different frame than the one replayed here.
+ */
+void Build_Pointers(unsigned int seed, unsigned long entries, int maxindex, bool hicolour, int solid)
+{
+ Seed = seed;
+
+ for (unsigned long i = 0; i < entries; i++) {
+ unsigned int index = 0;
+
+ if ((int)(Next_Random() % 10) < solid) {
+ index = hicolour ? (0x8000 | (Next_Random() & 0x7FFF)) : (0xFF00 | (Next_Random() & 0xFF));
+ } else {
+ index = Next_Random() % (unsigned int)maxindex;
+
+ if (hicolour) {
+ index &= 0x7FFF;
+ } else if ((index >> 8) == 0xFF) {
+ index = 0;
+ }
+ }
+
+ Pointers[i] = (unsigned char)(index & 0xFF);
+ Pointers[entries + i] = (unsigned char)((index >> 8) & 0xFF);
+ }
+}
+
+
+int Span(UnVQGoldenCase const & test, int bytesperpixel, int rowsperblock)
+{
+ return((int)(test.BufWidth * bytesperpixel * test.NumRows * rowsperblock) + 256);
+}
+
+} // namespace
+
+
+int main(void)
+{
+ HicolorTable = HicolorStore;
+
+ Seed = 777;
+ for (int i = 0; i < 32768; i++) {
+ HicolorStore[i] = (unsigned short)(Next_Random() & 0xFFFF);
+ }
+
+ Seed = 555;
+ for (int i = 0; i < CBMAX; i++) {
+ Codebook[i] = (unsigned char)(Next_Random() & 0xFF);
+ }
+
+ for (int i = 0; i < UnVQGoldenCaseCount; i++) {
+ UnVQGoldenCase const & test = UnVQGoldenCases[i];
+ unsigned long const entries = test.BlocksPerRow * test.NumRows;
+
+ std::memset(DestStore, GUARD, sizeof(DestStore));
+
+ int span = 0;
+ int const solid = test.Solid;
+
+ switch (test.Which) {
+ case 0:
+ Build_Pointers(test.Seed, entries, 2048, true, solid);
+ ASM_UnVQ1_C1_TABLE(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ span = Span(test, 2, 4);
+ break;
+
+ case 1:
+ Build_Pointers(test.Seed, entries, 2048, true, solid);
+ ASM_UnVQ1_C1_TABLE_ALT(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ span = Span(test, 2, 4);
+ break;
+
+ case 2:
+ Build_Pointers(test.Seed, entries, 8192, false, solid);
+ ASM_UnVQ_4x2(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ span = Span(test, 1, 2);
+ break;
+
+ case 3:
+ Build_Pointers(test.Seed, entries, 4096, false, solid);
+ ASM_UnVQ_4x4(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ span = Span(test, 1, 4);
+ break;
+
+ case 4:
+ Build_Pointers(test.Seed, entries, 4096, false, solid);
+ ASM_UnVQ_4x4_HALF(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ span = Span(test, 1, 2);
+ break;
+
+ default:
+ Build_Pointers(test.Seed, entries, 2048, true, solid);
+ ASM_UnVQ1_C1_4x4(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ span = Span(test, 2, 4);
+ break;
+ }
+
+ unsigned long long const hash = Hash(DestStore, span);
+
+ if (hash != test.Hash) {
+ std::printf("FAILED decoder %d blocks %lu rows %lu width %lu: expected %llu, got %llu\n",
+ test.Which, test.BlocksPerRow, test.NumRows, test.BufWidth, test.Hash, hash);
+ Failures++;
+ }
+
+ Checked++;
+ }
+
+ std::printf("%-52s %s\n", "UnVQ block decode matches the recorded assembly", Failures == 0 ? "ok" : "FAILED");
+ std::printf("checked %d cases, %d mismatches\n", Checked, Failures);
+
+ return(Failures == 0 ? 0 : 1);
+}
From bc682d2ba08a4e5591ab48853d75ff161b981445 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Tue, 1 Sep 2026 16:03:56 +0200
Subject: [PATCH 2/4] Cleanup VQ method naming
---
code/unvqdec.cpp | 58 ++++--------------------------------
code/vqa.cpp | 6 ++--
code/vqalib/drawer.cpp | 8 ++---
code/vqalib/unvq.h | 12 ++++----
tests/unvqdec/unvqparity.cpp | 12 ++++----
5 files changed, 25 insertions(+), 71 deletions(-)
diff --git a/code/unvqdec.cpp b/code/unvqdec.cpp
index 9e2ceba7a..11e359e50 100644
--- a/code/unvqdec.cpp
+++ b/code/unvqdec.cpp
@@ -10,41 +10,12 @@
* EA's GPLv3 Section 7 additional terms and supplemental warranty
* disclaimers apply; see LICENSE.md.
******************************************************************************/
-
-/****************************************************************************
-*
-* File : unvq_asm.asm
-* Description : VQA UnVQ1 full-frame decoders, drawing a VQ compressed
-* video frame into a pixel buffer.
-*
-****************************************************************************/
-
#include "always.h"
#include "vqalib/unvq.h"
#include "_vqa.h"
-/*
- * Six full-frame decoders, each replacing an assembly routine of the same name. They share a
- * shape: a frame is a grid of blocks, and every block carries a pointer into the codebook.
- *
- * The pointers arrive as two planes rather than as pairs -- every block's low byte first, then
- * every block's high byte -- so a block's codebook index is assembled from the two.
- *
- * A block is either a codebook entry copied out, or a single colour filling the whole block.
- * The two families differ in how they say which: an 8 bit frame marks a solid block with a
- * high byte of 0xFF and takes the colour from the low byte, while a 16 bit frame marks it with
- * the top bit and takes the remaining 15 as the colour. Of the 16 bit decoders, the two named
- * TABLE run that colour through HicolorTable; ASM_UnVQ1_C1_4x4 uses it as the pixel directly.
- *
- * Names carry the block size the codebook holds, not always the size written: 4x4_HALF reads a
- * 4x4 entry and writes every other pixel of every other row, and TABLE_ALT reads a 4x4 entry
- * and writes its first and third rows two screen rows apart.
- */
-
-namespace {
-
///
/// Assembles one block's codebook index from the two pointer planes.
///
@@ -76,20 +47,6 @@ inline void Fill32(unsigned char * dest, unsigned int value)
}
-inline void Put16(unsigned char * dest, unsigned char const * source)
-{
- dest[0] = source[0];
- dest[1] = source[1];
-}
-
-
-inline void Fill16(unsigned char * dest, unsigned int value)
-{
- dest[0] = (unsigned char)(value & 0xFF);
- dest[1] = (unsigned char)((value >> 8) & 0xFF);
-}
-
-
/*
* Spreads a 16 bit pixel across a doubleword so a solid block is filled four bytes at a time,
* the way the assembly did it.
@@ -106,9 +63,6 @@ inline unsigned int Quad8(unsigned int colour)
return((pair << 16) | pair);
}
-} // namespace
-
-
///
/// Draws a 16 bit frame from 4x4 codebook entries, taking a solid block's colour from
/// HicolorTable.
@@ -119,7 +73,7 @@ inline unsigned int Quad8(unsigned int colour)
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl ASM_UnVQ1_C1_TABLE(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+void __cdecl UnVQ1_C1_TABLE(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
{
if (blocksperrow == 0) {
@@ -174,7 +128,7 @@ void __cdecl ASM_UnVQ1_C1_TABLE(unsigned char * codebook, unsigned char * pointe
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl ASM_UnVQ1_C1_TABLE_ALT(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+void __cdecl UnVQ1_C1_TABLE_ALT(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
{
if (blocksperrow == 0) {
@@ -228,7 +182,7 @@ void __cdecl ASM_UnVQ1_C1_TABLE_ALT(unsigned char * codebook, unsigned char * po
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl ASM_UnVQ_4x2(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+void __cdecl UnVQ_4x2(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
{
if (blocksperrow == 0) {
@@ -277,7 +231,7 @@ void __cdecl ASM_UnVQ_4x2(unsigned char * codebook, unsigned char * pointers, un
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl ASM_UnVQ_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+void __cdecl UnVQ_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
{
if (blocksperrow == 0) {
@@ -329,7 +283,7 @@ void __cdecl ASM_UnVQ_4x4(unsigned char * codebook, unsigned char * pointers, un
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl ASM_UnVQ_4x4_HALF(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+void __cdecl UnVQ_4x4_HALF(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
{
if (blocksperrow == 0) {
@@ -383,7 +337,7 @@ void __cdecl ASM_UnVQ_4x4_HALF(unsigned char * codebook, unsigned char * pointer
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl ASM_UnVQ1_C1_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
+void __cdecl UnVQ1_C1_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
{
if (blocksperrow == 0) {
diff --git a/code/vqa.cpp b/code/vqa.cpp
index dd2672372..b1ec53c51 100644
--- a/code/vqa.cpp
+++ b/code/vqa.cpp
@@ -495,9 +495,9 @@ int VQAClass::Play_VQA(int last_frame_to_play, bool nobreakout)
if (cmode == 1) {
Hicolor_Init_Table(PrimaryColorMode);
if (Get_Option(OPTION_ALTERNATE_UNVQ)) {
- VQA_SetUnVQ(Handle, ASM_UnVQ1_C1_TABLE_ALT, UnVQ2_4x2_Table);
+ VQA_SetUnVQ(Handle, UnVQ1_C1_TABLE_ALT, UnVQ2_4x2_Table);
} else {
- VQA_SetUnVQ(Handle, ASM_UnVQ1_C1_TABLE, UnVQ2_4x4_Table);
+ VQA_SetUnVQ(Handle, UnVQ1_C1_TABLE, UnVQ2_4x4_Table);
}
} else if (cmode == 4) {
Hicolor_Init_Table(PrimaryColorMode);
@@ -629,7 +629,7 @@ bool VQAClass::Advance_Frame(bool & finished)
if (cmode == 1 || cmode == 4) {
Hicolor_Init_Table(PrimaryColorMode);
if (cmode == 1) {
- VQA_SetUnVQ(Handle, ASM_UnVQ1_C1_TABLE, UnVQ2_4x4_Table);
+ VQA_SetUnVQ(Handle, UnVQ1_C1_TABLE, UnVQ2_4x4_Table);
}
}
}
diff --git a/code/vqalib/drawer.cpp b/code/vqalib/drawer.cpp
index 6ad5564d0..b65e0f35b 100644
--- a/code/vqalib/drawer.cpp
+++ b/code/vqalib/drawer.cpp
@@ -185,7 +185,7 @@ long VQA_Configure_Drawer(VQAHandleP *vqap)
case BLOCK_4X2:
switch (header->ColorMode) {
case 0:
- vqap->UnVQ1 = ASM_UnVQ_4x2;
+ vqap->UnVQ1 = UnVQ_4x2;
if (header->Flags & VQAHDF_TRANS) {
if (vqap->Config.DrawFlags & VQACFGF_NOTRANS) {
@@ -214,12 +214,12 @@ long VQA_Configure_Drawer(VQAHandleP *vqap)
break;
case 1:
- vqap->UnVQ1 = ASM_UnVQ1_C1_4x4;
+ vqap->UnVQ1 = UnVQ1_C1_4x4;
vqap->UnVQ2 = UnVQ2_C1_4x4;
break;
case 0:
- vqap->UnVQ1 = ASM_UnVQ_4x4;
+ vqap->UnVQ1 = UnVQ_4x4;
if (header->Flags & VQAHDF_TRANS) {
if (vqap->Config.DrawFlags & VQACFGF_NOTRANS) {
@@ -231,7 +231,7 @@ long VQA_Configure_Drawer(VQAHandleP *vqap)
}
} else {
if (vqap->Config.DrawFlags & VQACFGF_HALFSIZE) {
- vqap->UnVQ1 = ASM_UnVQ_4x4_HALF;
+ vqap->UnVQ1 = UnVQ_4x4_HALF;
}
}
break;
diff --git a/code/vqalib/unvq.h b/code/vqalib/unvq.h
index d4acfe73c..69e6012b1 100644
--- a/code/vqalib/unvq.h
+++ b/code/vqalib/unvq.h
@@ -84,27 +84,27 @@ void __cdecl UnVQ2_C0_4x2_KEY(unsigned char *codebook, unsigned char *pointers,
#ifdef __cplusplus
extern "C" {
#endif
-void __cdecl ASM_UnVQ1_C1_TABLE(unsigned char *codebook, unsigned char *pointers,
+void __cdecl UnVQ1_C1_TABLE(unsigned char *codebook, unsigned char *pointers,
unsigned char *buffer, unsigned long blocksperrow,
unsigned long numrows, unsigned long bufwidth);
-void __cdecl ASM_UnVQ1_C1_TABLE_ALT(unsigned char *codebook, unsigned char *pointers,
+void __cdecl UnVQ1_C1_TABLE_ALT(unsigned char *codebook, unsigned char *pointers,
unsigned char *buffer, unsigned long blocksperrow,
unsigned long numrows, unsigned long bufwidth);
-void __cdecl ASM_UnVQ_4x2(unsigned char *codebook, unsigned char *pointers,
+void __cdecl UnVQ_4x2(unsigned char *codebook, unsigned char *pointers,
unsigned char *buffer, unsigned long blocksperrow,
unsigned long numrows, unsigned long bufwidth);
-void __cdecl ASM_UnVQ_4x4(unsigned char *codebook, unsigned char *pointers,
+void __cdecl UnVQ_4x4(unsigned char *codebook, unsigned char *pointers,
unsigned char *buffer, unsigned long blocksperrow,
unsigned long numrows, unsigned long bufwidth);
-void __cdecl ASM_UnVQ_4x4_HALF(unsigned char *codebook, unsigned char *pointers,
+void __cdecl UnVQ_4x4_HALF(unsigned char *codebook, unsigned char *pointers,
unsigned char *buffer, unsigned long blocksperrow,
unsigned long numrows, unsigned long bufwidth);
-void __cdecl ASM_UnVQ1_C1_4x4(unsigned char *codebook, unsigned char *pointers,
+void __cdecl UnVQ1_C1_4x4(unsigned char *codebook, unsigned char *pointers,
unsigned char *buffer, unsigned long blocksperrow,
unsigned long numrows, unsigned long bufwidth);
diff --git a/tests/unvqdec/unvqparity.cpp b/tests/unvqdec/unvqparity.cpp
index 673733895..fd8d08331 100644
--- a/tests/unvqdec/unvqparity.cpp
+++ b/tests/unvqdec/unvqparity.cpp
@@ -119,37 +119,37 @@ int main(void)
switch (test.Which) {
case 0:
Build_Pointers(test.Seed, entries, 2048, true, solid);
- ASM_UnVQ1_C1_TABLE(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ UnVQ1_C1_TABLE(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
span = Span(test, 2, 4);
break;
case 1:
Build_Pointers(test.Seed, entries, 2048, true, solid);
- ASM_UnVQ1_C1_TABLE_ALT(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ UnVQ1_C1_TABLE_ALT(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
span = Span(test, 2, 4);
break;
case 2:
Build_Pointers(test.Seed, entries, 8192, false, solid);
- ASM_UnVQ_4x2(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ UnVQ_4x2(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
span = Span(test, 1, 2);
break;
case 3:
Build_Pointers(test.Seed, entries, 4096, false, solid);
- ASM_UnVQ_4x4(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ UnVQ_4x4(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
span = Span(test, 1, 4);
break;
case 4:
Build_Pointers(test.Seed, entries, 4096, false, solid);
- ASM_UnVQ_4x4_HALF(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ UnVQ_4x4_HALF(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
span = Span(test, 1, 2);
break;
default:
Build_Pointers(test.Seed, entries, 2048, true, solid);
- ASM_UnVQ1_C1_4x4(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
+ UnVQ1_C1_4x4(Codebook, Pointers, DestStore, test.BlocksPerRow, test.NumRows, test.BufWidth);
span = Span(test, 2, 4);
break;
}
From 8a8ba73c635d7f33f5e0ab94900a00c56c572151 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Wed, 2 Sep 2026 08:17:27 +0200
Subject: [PATCH 3/4] Widen the VQ decoder interface to uint8_t and size_t
---
code/unvqdec.cpp | 189 +++++++++++++++++++----------------------
code/unvqtblc.cpp | 9 +-
code/unvqtblc.h | 11 ++-
code/vqalib/drawer.cpp | 12 +--
code/vqalib/task.cpp | 6 +-
code/vqalib/unvq.cpp | 20 ++---
code/vqalib/unvq.h | 99 ++++++++++-----------
code/vqalib/vqaplay.h | 5 +-
8 files changed, 173 insertions(+), 178 deletions(-)
diff --git a/code/unvqdec.cpp b/code/unvqdec.cpp
index 11e359e50..e72768eca 100644
--- a/code/unvqdec.cpp
+++ b/code/unvqdec.cpp
@@ -13,6 +13,8 @@
#include "always.h"
#include "vqalib/unvq.h"
+#include
+#include
#include "_vqa.h"
@@ -22,28 +24,17 @@
/// Base of the pointer data.
/// Total block count, which is where the high plane starts.
/// Which block to read.
-/// unsigned int; The codebook index.
-inline unsigned int Block_Index(unsigned char const * pointers, unsigned long entries, unsigned long block)
+/// uint32_t; The codebook index.
+inline uint32_t Block_Index(uint8_t const * pointers, size_t entries, size_t block)
{
- return(((unsigned int)pointers[entries + block] << 8) | (unsigned int)pointers[block]);
+ return((static_cast(pointers[entries + block]) << 8) | static_cast(pointers[block]));
}
-inline void Put32(unsigned char * dest, unsigned char const * source)
+inline void Fill32(uint8_t * dest, uint32_t value)
{
- dest[0] = source[0];
- dest[1] = source[1];
- dest[2] = source[2];
- dest[3] = source[3];
-}
-
-
-inline void Fill32(unsigned char * dest, unsigned int value)
-{
- dest[0] = (unsigned char)(value & 0xFF);
- dest[1] = (unsigned char)((value >> 8) & 0xFF);
- dest[2] = (unsigned char)((value >> 16) & 0xFF);
- dest[3] = (unsigned char)((value >> 24) & 0xFF);
+ // memcpy folds to one store where MSVC won't optimize a byte-wise copy; assumes a little-endian host.
+ std::memcpy(dest, reinterpret_cast(&value), 4);
}
@@ -51,15 +42,15 @@ inline void Fill32(unsigned char * dest, unsigned int value)
* Spreads a 16 bit pixel across a doubleword so a solid block is filled four bytes at a time,
* the way the assembly did it.
*/
-inline unsigned int Pair16(unsigned int pixel)
+inline uint32_t Pair16(uint16_t pixel)
{
- return((pixel << 16) | pixel);
+ return((static_cast(pixel) << 16) | pixel);
}
-inline unsigned int Quad8(unsigned int colour)
+inline uint32_t Quad8(uint8_t colour)
{
- unsigned int const pair = (colour << 8) | colour;
+ uint32_t const pair = (static_cast(colour) << 8) | colour;
return((pair << 16) | pair);
}
@@ -73,40 +64,39 @@ inline unsigned int Quad8(unsigned int colour)
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl UnVQ1_C1_TABLE(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
- unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ1_C1_TABLE(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer,
+ size_t blocksperrow, size_t numrows, size_t bufwidth)
{
if (blocksperrow == 0) {
return;
}
- unsigned long const pitch = bufwidth * 2;
- unsigned long const rowoffset = pitch * 4;
- unsigned long const entries = numrows * blocksperrow;
+ size_t const pitch = bufwidth * 2;
+ size_t const rowoffset = pitch * 4;
+ size_t const entries = numrows * blocksperrow;
- unsigned char * rowstart = buffer;
- unsigned long block = 0;
+ uint8_t * rowstart = buffer;
+ size_t block = 0;
do {
- unsigned char * dest = rowstart;
+ uint8_t * dest = rowstart;
- for (unsigned long i = 0; i < blocksperrow; i++) {
- unsigned int const index = Block_Index(pointers, entries, block);
+ for (size_t i = 0; i < blocksperrow; i++) {
+ uint32_t const index = Block_Index(pointers, entries, block);
block++;
if ((index & 0x8000) != 0) {
- unsigned int const pixels = Pair16(HicolorTable[index & 0x7FFF]);
+ uint32_t const pixels = Pair16(HicolorTable[index & 0x7FFF]);
for (int row = 0; row < 4; row++) {
Fill32(dest + row * pitch, pixels);
Fill32(dest + row * pitch + 4, pixels);
}
} else {
- unsigned char const * word = codebook + index * 32;
+ uint8_t const * word = codebook + index * 32;
for (int row = 0; row < 4; row++) {
- Put32(dest + row * pitch, word + row * 8);
- Put32(dest + row * pitch + 4, word + row * 8 + 4);
+ std::memcpy(dest + row * pitch, word + row * 8, 8);
}
}
@@ -128,41 +118,39 @@ void __cdecl UnVQ1_C1_TABLE(unsigned char * codebook, unsigned char * pointers,
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl UnVQ1_C1_TABLE_ALT(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
- unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ1_C1_TABLE_ALT(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer,
+ size_t blocksperrow, size_t numrows, size_t bufwidth)
{
if (blocksperrow == 0) {
return;
}
- unsigned long const pitch = bufwidth * 2;
- unsigned long const rowoffset = pitch * 4;
- unsigned long const entries = numrows * blocksperrow;
+ size_t const pitch = bufwidth * 2;
+ size_t const rowoffset = pitch * 4;
+ size_t const entries = numrows * blocksperrow;
- unsigned char * rowstart = buffer;
- unsigned long block = 0;
+ uint8_t * rowstart = buffer;
+ size_t block = 0;
do {
- unsigned char * dest = rowstart;
+ uint8_t * dest = rowstart;
- for (unsigned long i = 0; i < blocksperrow; i++) {
- unsigned int const index = Block_Index(pointers, entries, block);
+ for (size_t i = 0; i < blocksperrow; i++) {
+ uint32_t const index = Block_Index(pointers, entries, block);
block++;
if ((index & 0x8000) != 0) {
- unsigned int const pixels = Pair16(HicolorTable[index & 0x7FFF]);
+ uint32_t const pixels = Pair16(HicolorTable[index & 0x7FFF]);
Fill32(dest, pixels);
Fill32(dest + 4, pixels);
Fill32(dest + pitch * 2, pixels);
Fill32(dest + pitch * 2 + 4, pixels);
} else {
- unsigned char const * word = codebook + index * 32;
+ uint8_t const * word = codebook + index * 32;
- Put32(dest, word);
- Put32(dest + 4, word + 4);
- Put32(dest + pitch * 2, word + 16);
- Put32(dest + pitch * 2 + 4, word + 20);
+ std::memcpy(dest, word, 8);
+ std::memcpy(dest + pitch * 2, word + 16, 8);
}
dest += 8;
@@ -182,36 +170,36 @@ void __cdecl UnVQ1_C1_TABLE_ALT(unsigned char * codebook, unsigned char * pointe
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl UnVQ_4x2(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
- unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ_4x2(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer,
+ size_t blocksperrow, size_t numrows, size_t bufwidth)
{
if (blocksperrow == 0) {
return;
}
- unsigned long const rowoffset = bufwidth * 2;
- unsigned long const entries = numrows * blocksperrow;
+ size_t const rowoffset = bufwidth * 2;
+ size_t const entries = numrows * blocksperrow;
- unsigned char * rowstart = buffer;
- unsigned long block = 0;
+ uint8_t * rowstart = buffer;
+ size_t block = 0;
do {
- unsigned char * dest = rowstart;
+ uint8_t * dest = rowstart;
- for (unsigned long i = 0; i < blocksperrow; i++) {
- unsigned int const index = Block_Index(pointers, entries, block);
+ for (size_t i = 0; i < blocksperrow; i++) {
+ uint32_t const index = Block_Index(pointers, entries, block);
block++;
if ((index >> 8) == 0xFF) {
- unsigned int const pixels = Quad8(index & 0xFF);
+ uint32_t const pixels = Quad8(index & 0xFF);
Fill32(dest, pixels);
Fill32(dest + bufwidth, pixels);
} else {
- unsigned char const * word = codebook + index * 8;
+ uint8_t const * word = codebook + index * 8;
- Put32(dest, word);
- Put32(dest + bufwidth, word + 4);
+ std::memcpy(dest, word, 4);
+ std::memcpy(dest + bufwidth, word + 4, 4);
}
dest += 4;
@@ -231,37 +219,37 @@ void __cdecl UnVQ_4x2(unsigned char * codebook, unsigned char * pointers, unsign
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl UnVQ_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
- unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ_4x4(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer,
+ size_t blocksperrow, size_t numrows, size_t bufwidth)
{
if (blocksperrow == 0) {
return;
}
- unsigned long const rowoffset = bufwidth * 4;
- unsigned long const entries = numrows * blocksperrow;
+ size_t const rowoffset = bufwidth * 4;
+ size_t const entries = numrows * blocksperrow;
- unsigned char * rowstart = buffer;
- unsigned long block = 0;
+ uint8_t * rowstart = buffer;
+ size_t block = 0;
do {
- unsigned char * dest = rowstart;
+ uint8_t * dest = rowstart;
- for (unsigned long i = 0; i < blocksperrow; i++) {
- unsigned int const index = Block_Index(pointers, entries, block);
+ for (size_t i = 0; i < blocksperrow; i++) {
+ uint32_t const index = Block_Index(pointers, entries, block);
block++;
if ((index >> 8) == 0xFF) {
- unsigned int const pixels = Quad8(index & 0xFF);
+ uint32_t const pixels = Quad8(index & 0xFF);
for (int row = 0; row < 4; row++) {
Fill32(dest + row * bufwidth, pixels);
}
} else {
- unsigned char const * word = codebook + index * 16;
+ uint8_t const * word = codebook + index * 16;
for (int row = 0; row < 4; row++) {
- Put32(dest + row * bufwidth, word + row * 4);
+ std::memcpy(dest + row * bufwidth, word + row * 4, 4);
}
}
@@ -283,35 +271,35 @@ void __cdecl UnVQ_4x4(unsigned char * codebook, unsigned char * pointers, unsign
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl UnVQ_4x4_HALF(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
- unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ_4x4_HALF(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer,
+ size_t blocksperrow, size_t numrows, size_t bufwidth)
{
if (blocksperrow == 0) {
return;
}
- unsigned long const rowoffset = bufwidth * 2;
- unsigned long const entries = numrows * blocksperrow;
+ size_t const rowoffset = bufwidth * 2;
+ size_t const entries = numrows * blocksperrow;
- unsigned char * rowstart = buffer;
- unsigned long block = 0;
+ uint8_t * rowstart = buffer;
+ size_t block = 0;
do {
- unsigned char * dest = rowstart;
+ uint8_t * dest = rowstart;
- for (unsigned long i = 0; i < blocksperrow; i++) {
- unsigned int const index = Block_Index(pointers, entries, block);
+ for (size_t i = 0; i < blocksperrow; i++) {
+ uint32_t const index = Block_Index(pointers, entries, block);
block++;
if ((index >> 8) == 0xFF) {
- unsigned char const colour = (unsigned char)(index & 0xFF);
+ uint8_t const colour = static_cast(index & 0xFF);
dest[0] = colour;
dest[1] = colour;
dest[bufwidth] = colour;
dest[bufwidth + 1] = colour;
} else {
- unsigned char const * word = codebook + index * 16;
+ uint8_t const * word = codebook + index * 16;
dest[0] = word[0];
dest[1] = word[2];
@@ -337,40 +325,39 @@ void __cdecl UnVQ_4x4_HALF(unsigned char * codebook, unsigned char * pointers, u
/// Blocks across one row of the frame.
/// Rows of blocks in the frame.
/// Destination width in pixels.
-void __cdecl UnVQ1_C1_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer,
- unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ1_C1_4x4(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer,
+ size_t blocksperrow, size_t numrows, size_t bufwidth)
{
if (blocksperrow == 0) {
return;
}
- unsigned long const pitch = bufwidth * 2;
- unsigned long const rowoffset = pitch * 4;
- unsigned long const entries = numrows * blocksperrow;
+ size_t const pitch = bufwidth * 2;
+ size_t const rowoffset = pitch * 4;
+ size_t const entries = numrows * blocksperrow;
- unsigned char * rowstart = buffer;
- unsigned long block = 0;
+ uint8_t * rowstart = buffer;
+ size_t block = 0;
do {
- unsigned char * dest = rowstart;
+ uint8_t * dest = rowstart;
- for (unsigned long i = 0; i < blocksperrow; i++) {
- unsigned int const index = Block_Index(pointers, entries, block);
+ for (size_t i = 0; i < blocksperrow; i++) {
+ uint32_t const index = Block_Index(pointers, entries, block);
block++;
if ((index & 0x8000) != 0) {
- unsigned int const pixels = Pair16(index & 0x7FFF);
+ uint32_t const pixels = Pair16(index & 0x7FFF);
for (int row = 0; row < 4; row++) {
Fill32(dest + row * pitch, pixels);
Fill32(dest + row * pitch + 4, pixels);
}
} else {
- unsigned char const * word = codebook + index * 32;
+ uint8_t const * word = codebook + index * 32;
for (int row = 0; row < 4; row++) {
- Put32(dest + row * pitch, word + row * 8);
- Put32(dest + row * pitch + 4, word + row * 8 + 4);
+ std::memcpy(dest + row * pitch, word + row * 8, 8);
}
}
diff --git a/code/unvqtblc.cpp b/code/unvqtblc.cpp
index 29e45f33e..fbaa28135 100644
--- a/code/unvqtblc.cpp
+++ b/code/unvqtblc.cpp
@@ -110,8 +110,7 @@ static inline void memset32(void * D, unsigned int val, unsigned int n)
for (i = 0; i < n; i++) dst[i] = val;
}
-
-void __cdecl UnVQ2_4x4_Table(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ2_4x4_Table(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
assert(HicolorTable != 0);
assert(codebook != 0);
@@ -298,7 +297,7 @@ void __cdecl UnVQ2_4x4_Table(unsigned char * codebook, unsigned char * pointers,
}
-void __cdecl UnVQ2_4x2_Table(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ2_4x2_Table(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
assert(HicolorTable != 0);
assert(codebook != 0);
@@ -481,7 +480,7 @@ void __cdecl UnVQ2_4x2_Table(unsigned char * codebook, unsigned char * pointers,
#define __int16 short
#define __int32 long
-void __cdecl UnVQ1_4x4_Table(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ1_4x4_Table(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
assert(codebook != 0);
assert(pointers != 0);
@@ -568,7 +567,7 @@ void __cdecl UnVQ1_4x4_Table(unsigned char * codebook, unsigned char * pointers,
}
-void __cdecl UnVQ1_4x2_Table(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ1_4x2_Table(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
assert(codebook != 0);
assert(pointers != 0);
diff --git a/code/unvqtblc.h b/code/unvqtblc.h
index 2d889b01d..6e9fc5646 100644
--- a/code/unvqtblc.h
+++ b/code/unvqtblc.h
@@ -9,12 +9,15 @@
#pragma once
+#include
+#include
+
bool Hicolor_Init_Table(int cmode);
void Hicolor_Clear_Table(void);
void Hicolor_Translate(void *buffer, int size);
-void __cdecl UnVQ2_4x4_Table(unsigned char *codebook, unsigned char *pointers, unsigned char *buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth);
-void __cdecl UnVQ2_4x2_Table(unsigned char *codebook, unsigned char *pointers, unsigned char *buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ2_4x4_Table(uint8_t *codebook, uint8_t *pointers, uint8_t *buffer, size_t blocksperrow, size_t numrows, size_t bufwidth);
+void __cdecl UnVQ2_4x2_Table(uint8_t *codebook, uint8_t *pointers, uint8_t *buffer, size_t blocksperrow, size_t numrows, size_t bufwidth);
-void __cdecl UnVQ1_4x4_Table(unsigned char *codebook, unsigned char *pointers, unsigned char *buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth);
-void __cdecl UnVQ1_4x2_Table(unsigned char *codebook, unsigned char *pointers, unsigned char *buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ1_4x4_Table(uint8_t *codebook, uint8_t *pointers, uint8_t *buffer, size_t blocksperrow, size_t numrows, size_t bufwidth);
+void __cdecl UnVQ1_4x2_Table(uint8_t *codebook, uint8_t *pointers, uint8_t *buffer, size_t blocksperrow, size_t numrows, size_t bufwidth);
diff --git a/code/vqalib/drawer.cpp b/code/vqalib/drawer.cpp
index b65e0f35b..6264750f7 100644
--- a/code/vqalib/drawer.cpp
+++ b/code/vqalib/drawer.cpp
@@ -82,7 +82,7 @@ long PageFlip_MCGABuf(VQAHandle *vqa);
long DrawFrame_MCGA(VQAHandle *vqa);
long PageFlip_MCGA(VQAHandle *vqa);
-void __cdecl UnVQ_Nop(unsigned char *codebook, unsigned char *pointers, unsigned char *buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ_Nop(uint8_t *codebook, uint8_t *pointers, uint8_t *buffer, size_t blocksperrow, size_t numrows, size_t bufwidth);
long PageFlip_Nop(VQAHandle *vqa);
void VQA_SetTimer(VQAHandleP *vqap, long time);
@@ -1187,8 +1187,8 @@ STATIC long PageFlip_MCGABuf(VQAHandle *vqa)
* SYNOPSIS
* UnVQ_Nop(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
*
-* void UnVQ_Nop(unsigned char *, unsigned char *, unsigned char *,
-* unsigned long, unsigned long, unsigned long);
+* void UnVQ_Nop(uint8_t *, uint8_t *, uint8_t *,
+* size_t, size_t, size_t);
* FUNCTION
*
* INPUTS
@@ -1204,9 +1204,9 @@ STATIC long PageFlip_MCGABuf(VQAHandle *vqa)
*
****************************************************************************/
-STATIC void __cdecl UnVQ_Nop(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth)
+STATIC void __cdecl UnVQ_Nop(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth)
{
/* Suppress compiler warnings */
codebook = codebook;
diff --git a/code/vqalib/task.cpp b/code/vqalib/task.cpp
index 6cdc73919..73bf4cbb0 100644
--- a/code/vqalib/task.cpp
+++ b/code/vqalib/task.cpp
@@ -103,9 +103,9 @@ long __cdecl Disk_VQA_Stream_Handler(VQAHandle *vqa, long action, void *buffer,
long VQA_LargestLoop(VQAHandleP *vqap, long);
-extern void __cdecl UnVQ_Nop(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+extern void __cdecl UnVQ_Nop(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
/****************************************************************************
*
diff --git a/code/vqalib/unvq.cpp b/code/vqalib/unvq.cpp
index f218874ef..2ecc99fb4 100644
--- a/code/vqalib/unvq.cpp
+++ b/code/vqalib/unvq.cpp
@@ -21,7 +21,7 @@ typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
-void __cdecl UnVQ2_C1_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ2_C1_4x4(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
bufwidth *= 2u;
uint32_t block_row_stride = bufwidth * 4u;
@@ -287,7 +287,7 @@ void __cdecl UnVQ2_C1_4x4(unsigned char * codebook, unsigned char * pointers, un
}
-void __cdecl UnVQ1_C4_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ1_C4_4x4(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
bufwidth *= 2u;
uint32_t block_row_stride = bufwidth * 4u;
@@ -383,7 +383,7 @@ void __cdecl UnVQ1_C4_4x4(unsigned char * codebook, unsigned char * pointers, un
}
-void __cdecl UnVQ2_C4_4x4(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ2_C4_4x4(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
bufwidth *= 2u;
uint32_t block_row_stride = bufwidth * 4u;
@@ -619,7 +619,7 @@ void __cdecl UnVQ2_C4_4x4(unsigned char * codebook, unsigned char * pointers, un
}
-void __cdecl UnVQ1_C4_4x2(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ1_C4_4x2(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
bufwidth *= 2u;
uint32_t block_row_stride = bufwidth * 2u;
@@ -715,7 +715,7 @@ void __cdecl UnVQ1_C4_4x2(unsigned char * codebook, unsigned char * pointers, un
}
-void __cdecl UnVQ2_C4_4x2(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ2_C4_4x2(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
bufwidth *= 2u;
uint32_t block_row_stride = bufwidth * 2u;
@@ -952,7 +952,7 @@ void __cdecl UnVQ2_C4_4x2(unsigned char * codebook, unsigned char * pointers, un
}
-void __cdecl UnVQ2_C0_4x4_TRANS(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ2_C0_4x4_TRANS(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
uint8_t * dst = (uint8_t *)buffer;
uint8_t * row_base = (uint8_t *)buffer;
@@ -1218,7 +1218,7 @@ void __cdecl UnVQ2_C0_4x4_TRANS(unsigned char * codebook, unsigned char * pointe
}
-void __cdecl UnVQ2_C0_4x4_KEY(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ2_C0_4x4_KEY(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
uint8_t * dst = (uint8_t *)buffer;
uint8_t * row_base = (uint8_t *)buffer;
@@ -1470,7 +1470,7 @@ void __cdecl UnVQ2_C0_4x4_KEY(unsigned char * codebook, unsigned char * pointers
}
-void __cdecl UnVQ2_C0_4x4_TRANS_HALF(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ2_C0_4x4_TRANS_HALF(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
uint8_t * dst = (uint8_t *)buffer;
uint8_t * row_base = (uint8_t *)buffer;
@@ -1738,7 +1738,7 @@ void __cdecl UnVQ2_C0_4x4_TRANS_HALF(unsigned char * codebook, unsigned char * p
}
-void __cdecl UnVQ2_C0_4x2_TRANS(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ2_C0_4x2_TRANS(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
uint8_t * dst = (uint8_t *)buffer;
uint16_t * src = (uint16_t *)pointers;
@@ -2006,7 +2006,7 @@ void __cdecl UnVQ2_C0_4x2_TRANS(unsigned char * codebook, unsigned char * pointe
}
-void __cdecl UnVQ2_C0_4x2_KEY(unsigned char * codebook, unsigned char * pointers, unsigned char * buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth)
+void __cdecl UnVQ2_C0_4x2_KEY(uint8_t * codebook, uint8_t * pointers, uint8_t * buffer, size_t blocksperrow, size_t numrows, size_t bufwidth)
{
uint8_t * dst = (uint8_t *)buffer;
uint8_t * row_base = (uint8_t *)buffer;
diff --git a/code/vqalib/unvq.h b/code/vqalib/unvq.h
index 69e6012b1..981720dea 100644
--- a/code/vqalib/unvq.h
+++ b/code/vqalib/unvq.h
@@ -13,6 +13,9 @@
#ifndef VQAUNVQ_H
#define VQAUNVQ_H
+
+#include
+#include
/****************************************************************************
*
* 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
@@ -40,73 +43,73 @@
* FUNCTION PROTOTYPES
*-------------------------------------------------------------------------*/
-void __cdecl UnVQ2_C1_4x4(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ2_C1_4x4(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ1_C4_4x4(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ1_C4_4x4(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ2_C4_4x4(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ2_C4_4x4(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ1_C4_4x2(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ1_C4_4x2(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ2_C4_4x2(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ2_C4_4x2(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ2_C0_4x4_TRANS(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ2_C0_4x4_TRANS(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ2_C0_4x4_KEY(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ2_C0_4x4_KEY(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ2_C0_4x4_TRANS_HALF(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ2_C0_4x4_TRANS_HALF(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ2_C0_4x2_TRANS(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ2_C0_4x2_TRANS(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ2_C0_4x2_KEY(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ2_C0_4x2_KEY(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
#ifdef __cplusplus
extern "C" {
#endif
-void __cdecl UnVQ1_C1_TABLE(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ1_C1_TABLE(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ1_C1_TABLE_ALT(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ1_C1_TABLE_ALT(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ_4x2(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ_4x2(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ_4x4(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ_4x4(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ_4x4_HALF(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ_4x4_HALF(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
-void __cdecl UnVQ1_C1_4x4(unsigned char *codebook, unsigned char *pointers,
- unsigned char *buffer, unsigned long blocksperrow,
- unsigned long numrows, unsigned long bufwidth);
+void __cdecl UnVQ1_C1_4x4(uint8_t *codebook, uint8_t *pointers,
+ uint8_t *buffer, size_t blocksperrow,
+ size_t numrows, size_t bufwidth);
#ifdef __cplusplus
}
diff --git a/code/vqalib/vqaplay.h b/code/vqalib/vqaplay.h
index 7fe06ad73..2204872cf 100644
--- a/code/vqalib/vqaplay.h
+++ b/code/vqalib/vqaplay.h
@@ -13,6 +13,9 @@
#ifndef VQAPLAY_H
#define VQAPLAY_H
+
+#include
+#include
/****************************************************************************
*
* 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
@@ -158,7 +161,7 @@ class VQAClass;
typedef struct _VQAHandle VQAHandle;
// UnVQ functions must be this type
-typedef void (__cdecl *UNVQ_FUNC)(unsigned char *codebook, unsigned char *pointers, unsigned char *buffer, unsigned long blocksperrow, unsigned long numrows, unsigned long bufwidth);
+typedef void (__cdecl *UNVQ_FUNC)(uint8_t *codebook, uint8_t *pointers, uint8_t *buffer, size_t blocksperrow, size_t numrows, size_t bufwidth);
// Handlers must be this type
typedef long (__cdecl *VQA_H_FUNC)(VQAHandle *vqa, long action, void *buffer, long nbytes);
From a5ca474dea7bd98e58072d8e7c5fab50bc3e5d06 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Thu, 3 Sep 2026 18:48:33 +0200
Subject: [PATCH 4/4] Formatting cleanup
---
code/unvqdec.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/code/unvqdec.cpp b/code/unvqdec.cpp
index e72768eca..38f36b9f3 100644
--- a/code/unvqdec.cpp
+++ b/code/unvqdec.cpp
@@ -10,13 +10,14 @@
* EA's GPLv3 Section 7 additional terms and supplemental warranty
* disclaimers apply; see LICENSE.md.
******************************************************************************/
+
#include "always.h"
+#include "_vqa.h"
#include "vqalib/unvq.h"
-#include
-#include
-#include "_vqa.h"
+#include
+#include
///
/// Assembles one block's codebook index from the two pointer planes.