From ed81691dd5f56f89d4b431fb08f75c3df42351d2 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Fri, 28 Aug 2026 15:36:22 +0200
Subject: [PATCH 01/14] Translate voxel drawing and colour operations to C++
No documentation update: tests/colorops and tests/voxeldraw check the C++ port against golden vectors recorded from the original assembly, so documented behavior is unchanged.
---
code/colorops.cpp | 349 +++++++++++++++++++++++++++
code/interpal.cpp | 412 --------------------------------
code/interpal.h | 30 ---
code/voxlib.cpp | 58 ++---
tests/CMakeLists.txt | 3 +-
tests/colorops/CMakeLists.txt | 30 +++
tests/colorops/colorgolden.h | 126 ++++++++++
tests/colorops/coloropstest.cpp | 173 ++++++++++++++
tests/voxeldraw/CMakeLists.txt | 30 +++
tests/voxeldraw/voxeldraw.cpp | 232 ++++++++++++++++++
tests/voxeldraw/voxelgolden.h | 171 +++++++++++++
11 files changed, 1137 insertions(+), 477 deletions(-)
create mode 100644 code/colorops.cpp
delete mode 100644 code/interpal.cpp
delete mode 100644 code/interpal.h
create mode 100644 tests/colorops/CMakeLists.txt
create mode 100644 tests/colorops/colorgolden.h
create mode 100644 tests/colorops/coloropstest.cpp
create mode 100644 tests/voxeldraw/CMakeLists.txt
create mode 100644 tests/voxeldraw/voxeldraw.cpp
create mode 100644 tests/voxeldraw/voxelgolden.h
diff --git a/code/colorops.cpp b/code/colorops.cpp
new file mode 100644
index 00000000..c1648281
--- /dev/null
+++ b/code/colorops.cpp
@@ -0,0 +1,349 @@
+/*******************************************************************************
+ * 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 : winasm.asm
+* Description : Palette tinting and spot light brightening for each of
+* the supported hicolor pixel layouts.
+*
+****************************************************************************/
+
+#include "always.h"
+
+/*
+ * Two families of routine, each replacing four assembly routines of the same names, one per
+ * hicolor layout.
+ *
+ * Adjust_Color_* builds a palette translation table: every colour is scaled and packed into a
+ * pixel. A colour whose mask entry is set is scaled by the separate red, green and blue tints;
+ * one whose entry is clear is scaled by the single intensity instead.
+ *
+ * Brighten_Color_* and MMX_Brighten_Color_* lighten a hicolor image through a per-pixel
+ * multiplier. The two reach the same shape by different routes -- the first unpacks each pixel
+ * with shifts, the second reads the channels out of a caller-supplied 65536 entry table -- and
+ * they are kept apart here rather than folded together, because only the caller knows whether
+ * the table it built agrees with the shifts.
+ *
+ * The assembly had three hand-written paths through Adjust_Color, chosen at run time by the
+ * MMX and CMOV flags. All three computed the same thing, so one routine replaces them.
+ */
+
+namespace {
+
+/*
+ * How one hicolor layout packs a colour. The mask keeps the bits a channel is allowed to
+ * carry, and the shift moves them into place; red and green shift up, blue shifts down.
+ */
+struct PackFormat {
+ unsigned int RedMask;
+ unsigned int RedShift;
+ unsigned int GreenMask;
+ unsigned int GreenShift;
+ unsigned int BlueMask;
+ unsigned int BlueShift;
+};
+
+PackFormat const _Format565 = {0xF8, 8, 0xFC, 3, 0xF8, 3};
+PackFormat const _Format555 = {0xF8, 7, 0xF8, 2, 0xF8, 3};
+PackFormat const _Format556 = {0xF8, 8, 0xF8, 3, 0xFC, 2};
+PackFormat const _Format655 = {0xFC, 8, 0xF8, 2, 0xF8, 3};
+
+
+///
+/// Scales one channel by a fixed point factor and holds the result at 255. The assembly built
+/// the ceiling out of the carry flag; the multiply wraps at 32 bits either way.
+///
+/// The channel value, 0 to 255.
+/// The 16.16 fixed point factor to scale it by.
+/// unsigned int; The scaled channel, at most 255.
+inline unsigned int Scale_Channel(unsigned int channel, unsigned int scale)
+{
+ unsigned int const scaled = (unsigned int)(channel * scale) >> 16;
+ return((scaled > 255) ? 255 : scaled);
+}
+
+
+void Adjust_Color(unsigned char const * palette, unsigned short * translator, int red, int green, int blue,
+ int intensity, unsigned char const * mask, PackFormat const & format)
+{
+ /*
+ * Index zero is the transparent one and is never scaled.
+ */
+ translator[0] = 0;
+
+ for (int i = 1; i < 256; i++) {
+ unsigned int const r = palette[i * 3 + 0];
+ unsigned int const g = palette[i * 3 + 1];
+ unsigned int const b = palette[i * 3 + 2];
+
+ unsigned int redscale = (unsigned int)intensity;
+ unsigned int greenscale = (unsigned int)intensity;
+ unsigned int bluescale = (unsigned int)intensity;
+
+ if (mask[i] != 0) {
+ redscale = (unsigned int)red;
+ greenscale = (unsigned int)green;
+ bluescale = (unsigned int)blue;
+ }
+
+ unsigned int const outr = Scale_Channel(r, redscale);
+ unsigned int const outg = Scale_Channel(g, greenscale);
+ unsigned int const outb = Scale_Channel(b, bluescale);
+
+ translator[i] = (unsigned short)(((outr & format.RedMask) << format.RedShift)
+ | ((outg & format.GreenMask) << format.GreenShift)
+ | ((outb & format.BlueMask) >> format.BlueShift));
+ }
+}
+
+
+/*
+ * How one layout is taken apart and put back together by the brightening routines. The names
+ * follow the order the assembly worked in rather than red, green, blue.
+ */
+struct BrightenFormat {
+ unsigned int ShiftA;
+ unsigned int ShiftB;
+ unsigned int MaskA;
+ unsigned int MaskB;
+ unsigned int ScaleShiftA;
+ unsigned int ScaleShiftB;
+ unsigned int DownA;
+ unsigned int DownB;
+ unsigned int UpA;
+ unsigned int UpB;
+ unsigned int ShiftC;
+ unsigned int ScaleShiftC;
+ unsigned int DownC;
+};
+
+BrightenFormat const _Brighten565 = {8, 3, 0xF8, 0xFC, 8, 8, 3, 2, 11, 5, 3, 8, 3};
+BrightenFormat const _Brighten655 = {8, 2, 0xFC, 0xF8, 8, 8, 2, 3, 10, 5, 3, 8, 3};
+BrightenFormat const _Brighten556 = {8, 3, 0xF8, 0xF8, 8, 8, 3, 3, 11, 6, 2, 8, 2};
+BrightenFormat const _Brighten555 = {7, 2, 0xF8, 0xF8, 8, 8, 3, 3, 10, 5, 3, 8, 3};
+
+
+///
+/// Adds two channel values, holding the result at 255 rather than letting it wrap.
+///
+/// One value.
+/// The other.
+/// unsigned int; The sum, at most 255.
+inline unsigned int Add_Saturated(unsigned int left, unsigned int right)
+{
+ unsigned int const sum = (left & 0xFF) + (right & 0xFF);
+ return((sum > 255) ? 255 : sum);
+}
+
+
+void Brighten_Color(unsigned char const * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth,
+ int colorbuffwidth, int width, int height, BrightenFormat const & format)
+{
+ unsigned char const * mulrow = mulbuffer;
+ unsigned char * colorrow = (unsigned char *)colorbuffer;
+
+ for (int y = 0; y < height; y++) {
+ unsigned char const * mul = mulrow;
+ unsigned short * color = (unsigned short *)colorrow;
+
+ for (int x = 0; x < width; x++) {
+ unsigned int const multiplier = *mul;
+
+ if (multiplier != 0) {
+ unsigned int const pixel = *color;
+
+ unsigned int const a = (pixel >> format.ShiftA) & format.MaskA;
+ unsigned int const b = (pixel >> format.ShiftB) & format.MaskB;
+ unsigned int const c = (pixel << format.ShiftC) & 0xFF;
+
+ unsigned int outa = Add_Saturated((a * multiplier) >> format.ScaleShiftA, a);
+ unsigned int outb = Add_Saturated((b * multiplier) >> format.ScaleShiftB, b);
+ unsigned int outc = Add_Saturated((c * multiplier) >> format.ScaleShiftC, c);
+
+ outa = (outa >> format.DownA) << format.UpA;
+ outb = (outb >> format.DownB) << format.UpB;
+ outc = outc >> format.DownC;
+
+ *color = (unsigned short)(outa | outb | outc);
+ }
+
+ mul++;
+ color++;
+ }
+
+ mulrow += mulbuffwidth;
+ colorrow += colorbuffwidth;
+ }
+}
+
+
+/*
+ * How the table-driven brightening puts a pixel back together. The channels arrive already
+ * separated, so only the reassembly differs between layouts.
+ */
+struct MmxBrightenFormat {
+ unsigned int Down;
+ unsigned int BlueDown;
+ unsigned int GreenUp;
+ unsigned int RedUp;
+ unsigned int Mask;
+};
+
+/*
+ * The 655 entry carries 0x423A0A60 where the others carry a channel mask. The assembly treated
+ * that value as a marker selecting a different reassembly, and then masked green with it as
+ * well. It is preserved because the recorded output depends on it, not because it reads like a
+ * mask anyone intended.
+ */
+unsigned int const MMX_ALTERNATE_MARKER = 0x423A0A60;
+
+MmxBrightenFormat const _MmxBrighten565 = {2, 1, 5, 10, 0xF8};
+MmxBrightenFormat const _MmxBrighten555 = {3, 0, 5, 10, 0x7C};
+MmxBrightenFormat const _MmxBrighten556 = {2, 0, 6, 10, 0xF8};
+MmxBrightenFormat const _MmxBrighten655 = {2, 1, 4, 10, MMX_ALTERNATE_MARKER};
+
+
+void MMX_Brighten_Color(unsigned char const * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth,
+ int colorbuffwidth, int width, int height, int const * mmxbuffer, MmxBrightenFormat const & format)
+{
+ unsigned char const * mulrow = mulbuffer;
+ unsigned char * colorrow = (unsigned char *)colorbuffer;
+
+ for (int y = 0; y < height; y++) {
+ unsigned char const * mul = mulrow;
+ unsigned short * color = (unsigned short *)colorrow;
+
+ for (int x = 0; x < width; x++) {
+ unsigned int const multiplier = *mul;
+
+ if (multiplier != 0) {
+ unsigned int const pixel = *color;
+ unsigned int const entry = (unsigned int)mmxbuffer[pixel];
+
+ /*
+ * The table holds the three channels one per byte, which the assembly
+ * widened to a word each before scaling them together.
+ */
+ unsigned int const blue = entry & 0xFF;
+ unsigned int const green = (entry >> 8) & 0xFF;
+ unsigned int const red = (entry >> 16) & 0xFF;
+
+ unsigned int const outblue = Add_Saturated((blue * multiplier) >> 8, blue) >> format.Down;
+ unsigned int const outgreen = Add_Saturated((green * multiplier) >> 8, green) >> format.Down;
+ unsigned int const outred = Add_Saturated((red * multiplier) >> 8, red) >> format.Down;
+
+ unsigned int result = outblue >> format.BlueDown;
+ unsigned int const greenpart = outgreen << format.GreenUp;
+ unsigned int const redpart = outred << format.RedUp;
+
+ if (format.Mask == MMX_ALTERNATE_MARKER) {
+ result |= (greenpart & MMX_ALTERNATE_MARKER);
+ } else {
+ result |= greenpart;
+ result |= (redpart & (format.Mask * 256));
+ }
+
+ if (format.Mask == MMX_ALTERNATE_MARKER) {
+ result |= redpart;
+ }
+
+ *color = (unsigned short)result;
+ }
+
+ mul++;
+ color++;
+ }
+
+ mulrow += mulbuffwidth;
+ colorrow += colorbuffwidth;
+ }
+}
+
+} // namespace
+
+
+extern "C" {
+
+void __cdecl Adjust_Color_565(void * palette, void * translator, int red, int green, int blue, int intensity, void * mask)
+{
+ Adjust_Color((unsigned char const *)palette, (unsigned short *)translator, red, green, blue, intensity, (unsigned char const *)mask, _Format565);
+}
+
+
+void __cdecl Adjust_Color_555(void * palette, void * translator, int red, int green, int blue, int intensity, void * mask)
+{
+ Adjust_Color((unsigned char const *)palette, (unsigned short *)translator, red, green, blue, intensity, (unsigned char const *)mask, _Format555);
+}
+
+
+void __cdecl Adjust_Color_556(void * palette, void * translator, int red, int green, int blue, int intensity, void * mask)
+{
+ Adjust_Color((unsigned char const *)palette, (unsigned short *)translator, red, green, blue, intensity, (unsigned char const *)mask, _Format556);
+}
+
+
+void __cdecl Adjust_Color_655(void * palette, void * translator, int red, int green, int blue, int intensity, void * mask)
+{
+ Adjust_Color((unsigned char const *)palette, (unsigned short *)translator, red, green, blue, intensity, (unsigned char const *)mask, _Format655);
+}
+
+
+void __cdecl Brighten_Color_565(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height)
+{
+ Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, _Brighten565);
+}
+
+
+void __cdecl Brighten_Color_555(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height)
+{
+ Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, _Brighten555);
+}
+
+
+void __cdecl Brighten_Color_556(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height)
+{
+ Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, _Brighten556);
+}
+
+
+void __cdecl Brighten_Color_655(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height)
+{
+ Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, _Brighten655);
+}
+
+
+void __cdecl MMX_Brighten_Color_565(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height, int * mmxbuffer)
+{
+ MMX_Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, mmxbuffer, _MmxBrighten565);
+}
+
+
+void __cdecl MMX_Brighten_Color_555(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height, int * mmxbuffer)
+{
+ MMX_Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, mmxbuffer, _MmxBrighten555);
+}
+
+
+void __cdecl MMX_Brighten_Color_556(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height, int * mmxbuffer)
+{
+ MMX_Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, mmxbuffer, _MmxBrighten556);
+}
+
+
+void __cdecl MMX_Brighten_Color_655(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height, int * mmxbuffer)
+{
+ MMX_Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, mmxbuffer, _MmxBrighten655);
+}
+
+} // extern "C"
diff --git a/code/interpal.cpp b/code/interpal.cpp
deleted file mode 100644
index 861cf0f7..00000000
--- a/code/interpal.cpp
+++ /dev/null
@@ -1,412 +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.
- ******************************************************************************/
-
-/* $Header: /CounterStrike/INTERPAL.CPP 1 3/03/97 10:24a Joe_bostic $ */
-/***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Command & Conquer *
- * *
- * File Name : INTERPAL.CPP *
- * *
- * Programmer : Steve Tall *
- * *
- * Start Date : December 7th 1995 *
- * *
- *---------------------------------------------------------------------------------------------*
- * Overview: *
- * This module contains functions to allow use of old 320x200 animations on a 640x400 screen *
- * *
- * Functions: *
- * Read_Interpolation_Palette -- reads an interpolation palette table from disk *
- * Write_Interpolation_Palette -- writes an interpolation palette to disk *
- * Create_Palette_Interpolation_Table -- build the palette interpolation table *
- * Increase_Palette_Luminance -- increase the contrast of a palette *
- * Interpolate_2X_Scale -- Stretch a 320x200 graphic buffer into 640x400 *
- * *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#include "always.h"
-
-#include "interpal.h"
-
-#include "ccfile.h"
-#include "hsv.h"
-#include "misc.h"
-#include "palette.h"
-#include "surface.h"
-
-#include
-
-bool InterpolationPaletteChanged = false;
-extern "C" {
-extern void __cdecl Asm_Interpolate (unsigned char* src_ptr ,
- unsigned char* dest_ptr ,
- int lines ,
- int src_width ,
- int dest_width);
-
-extern void __cdecl Asm_Interpolate_Line_Double (unsigned char* src_ptr ,
- unsigned char* dest_ptr ,
- int lines ,
- int src_width ,
- int dest_width);
-
-extern void __cdecl Asm_Interpolate_Line_Interpolate (unsigned char* src_ptr ,
- unsigned char* dest_ptr ,
- int lines ,
- int src_width ,
- int dest_width);
-
-}
-
-extern "C"{
- unsigned char PaletteInterpolationTable[SIZE_OF_PALETTE][SIZE_OF_PALETTE];
- unsigned char * InterpolationPalette;
-}
-
-
-/***********************************************************************************************
- * Read_Interpolation_Palette -- reads an interpolation palette table from disk *
- * *
- * *
- * *
- * INPUT: name of palette file *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 12/12/95 12:15PM ST : Created *
- *=============================================================================================*/
-
-void Read_Interpolation_Palette (char const * palette_file_name)
-{
- CCFileClass palette_file(palette_file_name);
-
- if (palette_file.Is_Available()) {
- palette_file.Open(FileClass::READ);
- palette_file.Read(&PaletteInterpolationTable[0][0], SIZE_OF_PALETTE * SIZE_OF_PALETTE);
- palette_file.Close();
- InterpolationPaletteChanged = FALSE;
- }
-}
-
-
-/***********************************************************************************************
- * Write_Interpolation_Palette -- writes an interpolation palette table to disk *
- * *
- * *
- * *
- * INPUT: name of palette file *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 12/12/95 12:15PM ST : Created *
- *=============================================================================================*/
-
-void Write_Interpolation_Palette (char const * palette_file_name)
-{
- CCFileClass palette_file(palette_file_name);
-
- if (!palette_file.Is_Available()) {
- palette_file.Open(FileClass::WRITE);
- palette_file.Write(&PaletteInterpolationTable[0][0], SIZE_OF_PALETTE * SIZE_OF_PALETTE);
- palette_file.Close();
- }
-}
-
-
-
-
-
-/***************************************************************************
- * CREATE_PALETTE_INTERPOLATION_TABLE *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/06/1995 MG : Created. *
- *=========================================================================*/
-void Create_Palette_Interpolation_Table( void )
-{
-
-// Asm_Create_Palette_Interpolation_Table();
-
- #if (1)
-
- int i;
- int j;
- int p;
- unsigned char * first_palette_ptr;
- unsigned char * second_palette_ptr;
- unsigned char * match_pal_ptr;
- int first_r;
- int first_g;
- int first_b;
- int second_r;
- int second_g;
- int second_b;
- int diff_r;
- int diff_g;
- int diff_b;
- int dest_r;
- int dest_g;
- int dest_b;
- int distance;
- int closest_distance;
- int index_of_closest_color;
-
- //
- // Create an interpolation table for the current palette.
- //
- first_palette_ptr = (unsigned char *) InterpolationPalette;
- for ( i = 0; i < SIZE_OF_PALETTE; i ++ ) {
-
- //
- // Get the first palette entry's RGB.
- //
- first_r = *first_palette_ptr;
- first_palette_ptr ++;
- first_g = *first_palette_ptr;
- first_palette_ptr ++;
- first_b = *first_palette_ptr;
- first_palette_ptr ++;
-
- second_palette_ptr = (unsigned char *) InterpolationPalette;
- for ( j = 0; j < SIZE_OF_PALETTE; j ++ ) {
- //
- // Get the second palette entry's RGB.
- //
- second_r = *second_palette_ptr;
- second_palette_ptr ++;
- second_g = *second_palette_ptr;
- second_palette_ptr ++;
- second_b = *second_palette_ptr;
- second_palette_ptr ++;
-
- //
- // Now calculate the RGB halfway between the first and second colors.
- //
- dest_r = ( first_r + second_r ) >> 1;
- dest_g = ( first_g + second_g ) >> 1;
- dest_b = ( first_b + second_b ) >> 1;
-
- //
- // Now find the color in the palette that most closely matches the interpolated color.
- //
- index_of_closest_color = 0;
-// closest_distance = (256 * 256) * 3;
- closest_distance = 500000;
- match_pal_ptr = (unsigned char *) InterpolationPalette;
- for ( p = 0; p < SIZE_OF_PALETTE; p ++ ) {
- diff_r = ( ((int) (*match_pal_ptr)) - dest_r );
- match_pal_ptr ++;
- diff_g = ( ((int) (*match_pal_ptr)) - dest_g );
- match_pal_ptr ++;
- diff_b = ( ((int) (*match_pal_ptr)) - dest_b );
- match_pal_ptr ++;
-
- distance = ( diff_r * diff_r ) + ( diff_g * diff_g ) + ( diff_b * diff_b );
- if ( distance < closest_distance ) {
- closest_distance = distance;
- index_of_closest_color = p;
- }
- }
-
- PaletteInterpolationTable[ i ][ j ] = (unsigned char) index_of_closest_color;
- }
- }
-
- #endif
- InterpolationPaletteChanged = FALSE;
- return;
-
-}
-
-
-/***********************************************************************************************
- * Increase_Palette_Luminance -- increase contrast of colours in a palette *
- * *
- * *
- * *
- * INPUT: ptr to palette *
- * percentage increase of red *
- * percentage increase of green *
- * percentage increase of blue *
- * cap value for colours *
- * *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 12/12/95 12:16PM ST : Created *
- *=============================================================================================*/
-
-void Increase_Palette_Luminance (PaletteClass & palette , double percentage)
-{
- for (int i=0 ; iLock();
- if (src_ptr != NULL) {
- source_locked = true;
- }
-
- dest_ptr = (unsigned char *)dest->Lock();
- if (dest_ptr != NULL) {
- dest_locked = true;
- }
-
- if (dest_locked && source_locked) {
-
- //
- // Get width of source and dest buffers.
- //
- src_width = source->Get_Width();
- dest_width = 2*(dest->Stride());
-
- /*
- ** Call the appropriate assembly language copy routine
- */
-#if (1)
- switch (CopyType) {
- case 0:
- Asm_Interpolate ( src_ptr , dest_ptr , source->Get_Height() , src_width , dest_width);
- break;
-
- case 1:
- Asm_Interpolate_Line_Double( src_ptr , dest_ptr , source->Get_Height() , src_width , dest_width);
- break;
-
- case 2:
- Asm_Interpolate_Line_Interpolate( src_ptr , dest_ptr , source->Get_Height() , src_width , dest_width);
- break;
- }
-#endif
-
-#if (0)
- //
- // Copy over the first pixel (upper left).
- //
- *dest_ptr = *src_ptr;
-
- src_ptr ++;
- dest_ptr ++;
-
- //
- // Scale copy.
- //
- width_counter = 0;
- while ( src_ptr < end_of_source ) {
-
- //
- // Blend this pixel with the one to the left and place this new color in the dest buffer.
- //
- *dest_ptr = PaletteInterpolationTable[ (*src_ptr) ][ (*( src_ptr - 1 )) ];
- dest_ptr ++;
-
- //
- // Now place the source pixel into the dest buffer.
- //
- *dest_ptr = *src_ptr;
-
- src_ptr ++;
- dest_ptr ++;
-
- width_counter ++;
- if ( width_counter == src_width ) {
- width_counter = 0;
- last_dest_ptr += dest_width;
- dest_ptr = last_dest_ptr;
- }
- }
-#endif
- }
-
- if (source_locked) source->Unlock();
- if (dest_locked) dest->Unlock();
-}
diff --git a/code/interpal.h b/code/interpal.h
deleted file mode 100644
index 0b3f8aa5..00000000
--- a/code/interpal.h
+++ /dev/null
@@ -1,30 +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.
- ******************************************************************************/
-
-#pragma once
-
-class Surface;
-class PaletteClass;
-
-#define SIZE_OF_PALETTE 256
-extern "C" unsigned char *InterpolationPalette;
-extern bool InterpolationPaletteChanged;
-void Interpolate_2X_Scale( Surface * source, Surface * dest , char const * palette_file_name);
-void Read_Interpolation_Palette (char const *palette_file_name);
-void Write_Interpolation_Palette (char const *palette_file_name);
-void Increase_Palette_Luminance (PaletteClass & palette , double percentage);
-extern "C"{
- extern unsigned char PaletteInterpolationTable[SIZE_OF_PALETTE][SIZE_OF_PALETTE];
- extern unsigned char *InterpolationPalette;
- void __cdecl Asm_Create_Palette_Interpolation_Table(void);
-}
diff --git a/code/voxlib.cpp b/code/voxlib.cpp
index 21df08d8..895c50c9 100644
--- a/code/voxlib.cpp
+++ b/code/voxlib.cpp
@@ -36,38 +36,12 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state);
void __cdecl Draw_Voxel_Regular_ZBuffer(VoxelFuncArgumentStruct * state);
void __cdecl Draw_Voxel_Reverse_ZBuffer(VoxelFuncArgumentStruct * state);
-extern "C" {
-void __cdecl Draw_Voxel_Regular_Normals_ASM(VoxelFuncArgumentStruct * state);
-void __cdecl Draw_Voxel_Reverse_Normals_ASM(VoxelFuncArgumentStruct * state);
-void __cdecl Draw_Voxel_Regular_Lighting_Normals_ASM(VoxelFuncArgumentStruct * state);
-void __cdecl Draw_Voxel_Reverse_Lighting_Normals_ASM(VoxelFuncArgumentStruct * state);
-void __cdecl Draw_Voxel_Regular_ASM(VoxelFuncArgumentStruct * state);
-void __cdecl Draw_Voxel_Reverse_ASM(VoxelFuncArgumentStruct * state);
-void __cdecl Draw_Voxel_UNUSED1_ASM(VoxelFuncArgumentStruct * state);
-void __cdecl Draw_Voxel_UNUSED2_ASM(VoxelFuncArgumentStruct * state);
-}
-
-VoxelFuncPtr VoxelDrawFunctions[32] = {
-
- /// Assembly routines
- &Draw_Voxel_Regular_Normals_ASM,
- &Draw_Voxel_Reverse_Normals_ASM,
- &Draw_Voxel_Regular_Normals_ZBuffer,
- &Draw_Voxel_Reverse_Normals_ZBuffer,
- &Draw_Voxel_Regular_Lighting_Normals_ASM,
- &Draw_Voxel_Reverse_Lighting_Normals_ASM,
- &Draw_Voxel_Regular_Normals_ZBuffer_Lighting,
- &Draw_Voxel_Reverse_Normals_ZBuffer_Lighting,
- &Draw_Voxel_Regular_ASM,
- &Draw_Voxel_Reverse_ASM,
- &Draw_Voxel_Regular_ZBuffer,
- &Draw_Voxel_Reverse_ZBuffer,
- &Draw_Voxel_Regular_ASM,
- &Draw_Voxel_Reverse_ASM,
- &Draw_Voxel_Regular_ZBuffer,
- &Draw_Voxel_Reverse_ZBuffer,
-
- /// The same set again, with the C++ drawers in place of the assembly ones.
+/*
+ * Indexed by the orientation's direction together with the depth buffer, lighting and normal
+ * type switches, which is why the last four entries repeat the four before them: the normal
+ * type does not change which drawer is wanted once lighting is off.
+ */
+VoxelFuncPtr VoxelDrawFunctions[16] = {
&Draw_Voxel_Regular_Normals,
&Draw_Voxel_Reverse_Normals,
&Draw_Voxel_Regular_Normals_ZBuffer,
@@ -1120,9 +1094,11 @@ void __cdecl Draw_Voxel_Regular_Normals(VoxelFuncArgumentStruct * state)
*/
ptr++;
- /// Compute buffer index and write color
+ /// Compute buffer index and write color. A voxel covers two
+ /// buffer bytes, so the colour goes down twice.
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
VoxelDrawBuffer[buffer_index] = color_index;
+ VoxelDrawBuffer[buffer_index + 1] = color_index;
pixel_x += state->TransformMatrix[3].I;
pixel_y += state->TransformMatrix[3].J;
@@ -1206,9 +1182,11 @@ void __cdecl Draw_Voxel_Reverse_Normals(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr--;
- /// Compute buffer index and write color
+ /// Compute buffer index and write color. A voxel covers two
+ /// buffer bytes, so the colour goes down twice.
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
VoxelDrawBuffer[buffer_index] = color_index;
+ VoxelDrawBuffer[buffer_index + 1] = color_index;
pixel_x += state->TransformMatrix[3].I;
pixel_y += state->TransformMatrix[3].J;
@@ -1986,10 +1964,16 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr++;
+<<<<<<< HEAD
/// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
VoxelDrawBuffer[buffer_index] = color_index;
VoxelDrawBuffer[buffer_index + 1] = color_index;
+=======
+ /// Compute buffer index and write color. Unlike the shaded
+ /// drawers, this one covers a single buffer byte per voxel.
+ VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00)] = color_index;
+>>>>>>> 0fef683 (Translate voxel drawing and colour operations to C++)
pixel_x += state->TransformMatrix[3].I;
pixel_y += state->TransformMatrix[3].J;
@@ -2067,10 +2051,16 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr--;
+<<<<<<< HEAD
/// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
VoxelDrawBuffer[buffer_index] = color_index;
VoxelDrawBuffer[buffer_index + 1] = color_index;
+=======
+ /// Compute buffer index and write color. Unlike the shaded
+ /// drawers, this one covers a single buffer byte per voxel.
+ VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00)] = color_index;
+>>>>>>> 0fef683 (Translate voxel drawing and colour operations to C++)
pixel_x += state->TransformMatrix[3].I;
pixel_y += state->TransformMatrix[3].J;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 785dd4b5..d7a35e0d 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -5,4 +5,5 @@ add_subdirectory(logstress)
add_subdirectory(netpacket)
add_subdirectory(sosparity)
add_subdirectory(spawner)
-add_subdirectory(syncrec)
+add_subdirectory(colorops)
+add_subdirectory(voxeldraw)
diff --git a/tests/colorops/CMakeLists.txt b/tests/colorops/CMakeLists.txt
new file mode 100644
index 00000000..fcd102ad
--- /dev/null
+++ b/tests/colorops/CMakeLists.txt
@@ -0,0 +1,30 @@
+# The colour routines 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(ColorOps
+ "${CMAKE_CURRENT_SOURCE_DIR}/coloropstest.cpp"
+ "${CMAKE_SOURCE_DIR}/code/colorops.cpp"
+)
+
+target_compile_features(ColorOps PRIVATE cxx_std_20)
+
+target_include_directories(ColorOps PRIVATE
+ "${CMAKE_SOURCE_DIR}/code"
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+target_compile_definitions(ColorOps 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(ColorOps PRIVATE
+ $<$:/MTd /EHsc /Zc:__cplusplus /arch:SSE2 /fp:precise>
+ $<$:/MT /EHsc /Zc:__cplusplus /arch:SSE2 /fp:precise>
+)
+
+target_link_libraries(ColorOps PRIVATE kernel32 user32 shell32)
+
+set_target_properties(ColorOps PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
+)
+
+add_test(NAME colorops COMMAND ColorOps)
diff --git a/tests/colorops/colorgolden.h b/tests/colorops/colorgolden.h
new file mode 100644
index 00000000..fdd1a910
--- /dev/null
+++ b/tests/colorops/colorgolden.h
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * 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 palette tinting and spot light brightening routines 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 AdjustGoldenCase {
+ int Mode;
+ int Tint;
+ unsigned int Seed;
+ unsigned long long Hash;
+};
+
+static AdjustGoldenCase const AdjustGoldenCases[] = {
+ {0, 0, 16110u, 12760808774863403491ULL},
+ {0, 1, 24029u, 11632925425805831495ULL},
+ {0, 2, 31948u, 5925570506153992127ULL},
+ {0, 3, 39867u, 13047089033812385797ULL},
+ {0, 4, 47786u, 16473988446431455303ULL},
+ {1, 0, 55705u, 7840847192367313613ULL},
+ {1, 1, 63624u, 15986945065950998622ULL},
+ {1, 2, 71543u, 16620328751264269474ULL},
+ {1, 3, 79462u, 2197127037031984214ULL},
+ {1, 4, 87381u, 16652304632587527866ULL},
+ {2, 0, 95300u, 2020184679552769531ULL},
+ {2, 1, 103219u, 11395269755789222990ULL},
+ {2, 2, 111138u, 8778564327958451480ULL},
+ {2, 3, 119057u, 11297123781214576017ULL},
+ {2, 4, 126976u, 10099781733166984675ULL},
+ {3, 0, 134895u, 2908014413764433922ULL},
+ {3, 1, 142814u, 3380677557574597077ULL},
+ {3, 2, 150733u, 2032283341979249887ULL},
+ {3, 3, 158652u, 16316237050576502971ULL},
+ {3, 4, 166571u, 15216183069698100778ULL},
+};
+
+static int const AdjustGoldenCaseCount = 20;
+
+struct BrightenGoldenCase {
+ int Mode;
+ int Mmx;
+ int Width;
+ int Height;
+ unsigned int Seed;
+ unsigned long long Hash;
+};
+
+static BrightenGoldenCase const BrightenGoldenCases[] = {
+ {0, 0, 1, 1, 174490u, 9683954061780082186ULL},
+ {0, 0, 2, 1, 182409u, 3585589939020540445ULL},
+ {0, 0, 7, 3, 190328u, 12646124570177522196ULL},
+ {0, 0, 16, 4, 198247u, 8855089449368412364ULL},
+ {0, 0, 33, 9, 206166u, 4161396504343120247ULL},
+ {0, 0, 64, 16, 214085u, 7491337042742393889ULL},
+ {0, 0, 128, 32, 222004u, 1562462105826136594ULL},
+ {0, 0, 255, 64, 229923u, 12977303894793765084ULL},
+ {0, 1, 1, 1, 237842u, 2534684662198146892ULL},
+ {0, 1, 2, 1, 245761u, 9679803194961330382ULL},
+ {0, 1, 7, 3, 253680u, 2549577378279256583ULL},
+ {0, 1, 16, 4, 261599u, 11676825973235883859ULL},
+ {0, 1, 33, 9, 269518u, 13545447451985782494ULL},
+ {0, 1, 64, 16, 277437u, 4102005335375077591ULL},
+ {0, 1, 128, 32, 285356u, 3889344650472255677ULL},
+ {0, 1, 255, 64, 293275u, 3297543697270025883ULL},
+ {1, 0, 1, 1, 301194u, 13186354609198225149ULL},
+ {1, 0, 2, 1, 309113u, 13814059303084228345ULL},
+ {1, 0, 7, 3, 317032u, 10720627840618582556ULL},
+ {1, 0, 16, 4, 324951u, 18012041115974557435ULL},
+ {1, 0, 33, 9, 332870u, 7090443837710868316ULL},
+ {1, 0, 64, 16, 340789u, 7935162482590007511ULL},
+ {1, 0, 128, 32, 348708u, 16754602968852868577ULL},
+ {1, 0, 255, 64, 356627u, 11578321534074525250ULL},
+ {1, 1, 1, 1, 364546u, 10427039056597764142ULL},
+ {1, 1, 2, 1, 372465u, 1748292752117078850ULL},
+ {1, 1, 7, 3, 380384u, 10317547240677326599ULL},
+ {1, 1, 16, 4, 388303u, 16604617947182860757ULL},
+ {1, 1, 33, 9, 396222u, 1318537032546736748ULL},
+ {1, 1, 64, 16, 404141u, 9229413794311576209ULL},
+ {1, 1, 128, 32, 412060u, 7340557553286926667ULL},
+ {1, 1, 255, 64, 419979u, 5071078941017253528ULL},
+ {2, 0, 1, 1, 427898u, 10459444610915521759ULL},
+ {2, 0, 2, 1, 435817u, 9809152111208362860ULL},
+ {2, 0, 7, 3, 443736u, 5974842822965084410ULL},
+ {2, 0, 16, 4, 451655u, 14016269938534619012ULL},
+ {2, 0, 33, 9, 459574u, 11686188751530981124ULL},
+ {2, 0, 64, 16, 467493u, 16824327894963774702ULL},
+ {2, 0, 128, 32, 475412u, 831560034207278086ULL},
+ {2, 0, 255, 64, 483331u, 10597710443419274145ULL},
+ {2, 1, 1, 1, 491250u, 8479100877978498426ULL},
+ {2, 1, 2, 1, 499169u, 7481949699832809259ULL},
+ {2, 1, 7, 3, 507088u, 16607636731006922296ULL},
+ {2, 1, 16, 4, 515007u, 6405581235097048851ULL},
+ {2, 1, 33, 9, 522926u, 822099569615870640ULL},
+ {2, 1, 64, 16, 530845u, 8266273084601642906ULL},
+ {2, 1, 128, 32, 538764u, 8535626501608830796ULL},
+ {2, 1, 255, 64, 546683u, 3737545516508015044ULL},
+ {3, 0, 1, 1, 554602u, 3476118273324028887ULL},
+ {3, 0, 2, 1, 562521u, 3460303321212174411ULL},
+ {3, 0, 7, 3, 570440u, 5507246755901068217ULL},
+ {3, 0, 16, 4, 578359u, 2761380345813287195ULL},
+ {3, 0, 33, 9, 586278u, 14881774169913704698ULL},
+ {3, 0, 64, 16, 594197u, 13329692175776703259ULL},
+ {3, 0, 128, 32, 602116u, 16441757303667149227ULL},
+ {3, 0, 255, 64, 610035u, 2060866494282096795ULL},
+ {3, 1, 1, 1, 617954u, 11405787290677921704ULL},
+ {3, 1, 2, 1, 625873u, 6279770659411831877ULL},
+ {3, 1, 7, 3, 633792u, 10521531452208876928ULL},
+ {3, 1, 16, 4, 641711u, 14797326666873277565ULL},
+ {3, 1, 33, 9, 649630u, 7304885447097531915ULL},
+ {3, 1, 64, 16, 657549u, 15330689263602870827ULL},
+ {3, 1, 128, 32, 665468u, 10892574876935284254ULL},
+ {3, 1, 255, 64, 673387u, 10579957447657776596ULL},
+};
+
+static int const BrightenGoldenCaseCount = 64;
diff --git a/tests/colorops/coloropstest.cpp b/tests/colorops/coloropstest.cpp
new file mode 100644
index 00000000..00d8b941
--- /dev/null
+++ b/tests/colorops/coloropstest.cpp
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * 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 palette tinting and spot light brightening in colorops.cpp to the output the
+// assembly they replaced produced. The vectors in colorgolden.h were recorded from that
+// assembly before it was removed; the three hand-written paths through Adjust_Color agreed
+// with one another when they were recorded, so one set of vectors covers all of them.
+// Needs no game data.
+
+#include
+#include
+
+#include "colorgolden.h"
+
+extern "C" {
+void __cdecl Adjust_Color_565(void *pal, void *xlat, int r, int g, int b, int i, void *mask);
+void __cdecl Adjust_Color_555(void *pal, void *xlat, int r, int g, int b, int i, void *mask);
+void __cdecl Adjust_Color_556(void *pal, void *xlat, int r, int g, int b, int i, void *mask);
+void __cdecl Adjust_Color_655(void *pal, void *xlat, int r, int g, int b, int i, void *mask);
+
+void __cdecl Brighten_Color_565(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h);
+void __cdecl Brighten_Color_555(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h);
+void __cdecl Brighten_Color_556(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h);
+void __cdecl Brighten_Color_655(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h);
+
+void __cdecl MMX_Brighten_Color_565(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
+void __cdecl MMX_Brighten_Color_555(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
+void __cdecl MMX_Brighten_Color_556(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
+void __cdecl MMX_Brighten_Color_655(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
+}
+
+namespace {
+
+unsigned char Palette[256 * 3];
+unsigned char Mask[256];
+unsigned short Translator[256];
+
+unsigned char MulBuffer[256 * 256];
+unsigned short ColorBuffer[512 * 512];
+int MmxBuffer[65536];
+
+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(void const * data, int size)
+{
+ unsigned char const * bytes = (unsigned char const *)data;
+ unsigned long long hash = 1469598103934665603ULL;
+ for (int i = 0; i < size; i++) {
+ hash ^= (unsigned long long)bytes[i];
+ hash *= 1099511628211ULL;
+ }
+ return(hash);
+}
+
+
+typedef void (__cdecl * AdjustFunc)(void *, void *, int, int, int, int, void *);
+typedef void (__cdecl * BrightenFunc)(unsigned char *, unsigned short *, int, int, int, int);
+typedef void (__cdecl * MmxBrightenFunc)(unsigned char *, unsigned short *, int, int, int, int, int *);
+
+AdjustFunc const Adjusts[4] = {Adjust_Color_565, Adjust_Color_555, Adjust_Color_556, Adjust_Color_655};
+BrightenFunc const Brightens[4] = {Brighten_Color_565, Brighten_Color_555, Brighten_Color_556, Brighten_Color_655};
+MmxBrightenFunc const MmxBrightens[4] = {MMX_Brighten_Color_565, MMX_Brighten_Color_555, MMX_Brighten_Color_556, MMX_Brighten_Color_655};
+
+char const * const ModeNames[4] = {"565", "555", "556", "655"};
+
+
+// Must reproduce the generator's inputs exactly or every vector misses.
+void Fill_Adjust_Inputs(unsigned int seed)
+{
+ Seed = seed;
+ for (int i = 0; i < 256 * 3; i++) {
+ Palette[i] = (unsigned char)(Next_Random() & 0xFF);
+ }
+ for (int i = 0; i < 256; i++) {
+ Mask[i] = (unsigned char)((Next_Random() & 1) ? 1 : 0);
+ }
+}
+
+
+struct Tint {
+ int Red;
+ int Green;
+ int Blue;
+ int Intensity;
+};
+
+Tint const Tints[] = {
+ {0x10000, 0x10000, 0x10000, 0x10000},
+ {0x08000, 0x0C000, 0x10000, 0x06000},
+ {0x1FFFF, 0x18000, 0x04000, 0x1C000},
+ {0x00000, 0x10000, 0x20000, 0x00000},
+ {0x30000, 0x30000, 0x30000, 0x02000}
+};
+
+} // namespace
+
+
+int main(void)
+{
+ for (int i = 0; i < AdjustGoldenCaseCount; i++) {
+ AdjustGoldenCase const & test = AdjustGoldenCases[i];
+
+ Fill_Adjust_Inputs(test.Seed);
+ std::memset(Translator, 0xA5, sizeof(Translator));
+
+ Adjusts[test.Mode](Palette, Translator, Tints[test.Tint].Red, Tints[test.Tint].Green,
+ Tints[test.Tint].Blue, Tints[test.Tint].Intensity, Mask);
+
+ unsigned long long const hash = Hash(Translator, sizeof(Translator));
+
+ if (hash != test.Hash) {
+ std::printf("FAILED Adjust_Color_%s tint %d: expected %llu, got %llu\n",
+ ModeNames[test.Mode], test.Tint, test.Hash, hash);
+ Failures++;
+ }
+
+ Checked++;
+ }
+
+ for (int i = 0; i < BrightenGoldenCaseCount; i++) {
+ BrightenGoldenCase const & test = BrightenGoldenCases[i];
+
+ Seed = test.Seed;
+
+ for (int j = 0; j < 256 * 256; j++) {
+ MulBuffer[j] = (unsigned char)(Next_Random() & 0xFF);
+ }
+ for (int j = 0; j < 512 * 512; j++) {
+ ColorBuffer[j] = (unsigned short)(Next_Random() & 0xFFFF);
+ }
+ for (int j = 0; j < 65536; j++) {
+ MmxBuffer[j] = (int)(Next_Random() & 0x00FFFFFF);
+ }
+
+ if (test.Mmx != 0) {
+ MmxBrightens[test.Mode](MulBuffer, ColorBuffer, 256, 512 * 2, test.Width, test.Height, MmxBuffer);
+ } else {
+ Brightens[test.Mode](MulBuffer, ColorBuffer, 256, 512 * 2, test.Width, test.Height);
+ }
+
+ unsigned long long const hash = Hash(ColorBuffer, 512 * 512 * 2);
+
+ if (hash != test.Hash) {
+ std::printf("FAILED %sBrighten_Color_%s %dx%d: expected %llu, got %llu\n",
+ test.Mmx ? "MMX_" : "", ModeNames[test.Mode], test.Width, test.Height, test.Hash, hash);
+ Failures++;
+ }
+
+ Checked++;
+ }
+
+ std::printf("%-52s %s\n", "Colour tinting and brightening match the assembly", Failures == 0 ? "ok" : "FAILED");
+ std::printf("checked %d cases, %d mismatches\n", Checked, Failures);
+
+ return(Failures == 0 ? 0 : 1);
+}
diff --git a/tests/voxeldraw/CMakeLists.txt b/tests/voxeldraw/CMakeLists.txt
new file mode 100644
index 00000000..0a69d368
--- /dev/null
+++ b/tests/voxeldraw/CMakeLists.txt
@@ -0,0 +1,30 @@
+# The voxel library is 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(VoxelDraw
+ "${CMAKE_CURRENT_SOURCE_DIR}/voxeldraw.cpp"
+ "${CMAKE_SOURCE_DIR}/code/voxlib.cpp"
+)
+
+target_compile_features(VoxelDraw PRIVATE cxx_std_20)
+
+target_include_directories(VoxelDraw PRIVATE
+ "${CMAKE_SOURCE_DIR}/code"
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+target_compile_definitions(VoxelDraw 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(VoxelDraw PRIVATE
+ $<$:/MTd /EHsc /Zc:__cplusplus /arch:SSE2 /fp:precise>
+ $<$:/MT /EHsc /Zc:__cplusplus /arch:SSE2 /fp:precise>
+)
+
+target_link_libraries(VoxelDraw PRIVATE kernel32 user32 shell32)
+
+set_target_properties(VoxelDraw PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
+)
+
+add_test(NAME voxeldraw COMMAND VoxelDraw)
diff --git a/tests/voxeldraw/voxeldraw.cpp b/tests/voxeldraw/voxeldraw.cpp
new file mode 100644
index 00000000..ea8e99f9
--- /dev/null
+++ b/tests/voxeldraw/voxeldraw.cpp
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * 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 six voxel drawers in voxlib.cpp to the output the assembly they replaced produced.
+// The vectors in voxelgolden.h were recorded from that assembly before it was removed.
+//
+// These drawers were reached only through entries 16 to 31 of VoxelDrawFunctions, which the
+// dispatch never indexed, so until that table was repointed none of this code had ever run and
+// nothing would have noticed it drawing the wrong thing. Needs no game data.
+
+#include
+#include
+#include
+
+#include "voxdrsys.h"
+#include "voxlib.h"
+
+#include "voxelgolden.h"
+
+void __cdecl Draw_Voxel_Regular_Normals(VoxelFuncArgumentStruct * state);
+void __cdecl Draw_Voxel_Reverse_Normals(VoxelFuncArgumentStruct * state);
+void __cdecl Draw_Voxel_Regular_Normals_Lighting(VoxelFuncArgumentStruct * state);
+void __cdecl Draw_Voxel_Reverse_Normals_Lighting(VoxelFuncArgumentStruct * state);
+void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state);
+void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state);
+
+/*
+ * Standing in for voxdrsys.cpp, which the harness does not build. The draw buffer is larger
+ * than the engine's so that a drawer overrunning it is caught here rather than corrupting
+ * whatever the engine happens to place next to it.
+ */
+extern "C" {
+unsigned char VoxelDrawBuffer[262144];
+unsigned char VoxelDrawZBuffer[262144];
+unsigned char VoxelPaletteTranslateTable[MAX_PALETTE_LOOKUP_ENTRIES][VOXEL_PALETTE_SIZE];
+}
+
+RGBStruct VoxelRGBColors[VOXEL_PALETTE_SIZE];
+
+namespace VoxelDrawSystem {
+ BOOL EnableLighting = 0;
+ BOOL EnableZBuffer = 0;
+}
+
+Matrix3D::Matrix3D(float * const) {}
+VoxelPaletteLibrary::VoxelPaletteLibrary(RGBStruct *, void *) {}
+VoxelPaletteLibrary::~VoxelPaletteLibrary(void) {}
+void VoxelPaletteLibrary::Calculate_Lookup_Table(float *, int) {}
+
+namespace {
+
+int const SPANMAX = 4096;
+int const DATAMAX = 65536;
+
+unsigned char StartOffsets[SPANMAX];
+unsigned char EndOffsets[SPANMAX];
+unsigned char VoxelData[DATAMAX];
+
+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);
+}
+
+typedef void (* Drawer)(VoxelFuncArgumentStruct *);
+
+Drawer const Drawers[6] = {
+ Draw_Voxel_Regular_Normals,
+ Draw_Voxel_Reverse_Normals,
+ Draw_Voxel_Regular_Normals_Lighting,
+ Draw_Voxel_Reverse_Normals_Lighting,
+ Draw_Voxel_Regular,
+ Draw_Voxel_Reverse
+};
+
+char const * const Names[6] = {
+ "Draw_Voxel_Regular_Normals",
+ "Draw_Voxel_Reverse_Normals",
+ "Draw_Voxel_Regular_Normals_Lighting",
+ "Draw_Voxel_Reverse_Normals_Lighting",
+ "Draw_Voxel_Regular",
+ "Draw_Voxel_Reverse"
+};
+
+
+/*
+ * Must build byte for byte what the generator built.
+ *
+ * A column's spans have to account for exactly ZSize voxels between them, because the drawers
+ * count down from ZSize and stop on zero; a column adding up to anything else takes the counter
+ * past it and the walk runs away through the data. The column table holds 32 bit offsets and a
+ * negative entry means an empty column. Each span ends with a repeat of its length, which the
+ * forward drawers step over and the reverse drawers read first.
+ */
+void Build_Layer(unsigned int seed, int columns, int zsize, bool withnormals)
+{
+ Seed = seed;
+
+ unsigned int * starts = (unsigned int *)StartOffsets;
+ unsigned int * ends = (unsigned int *)EndOffsets;
+
+ int at = 0;
+
+ for (int i = 0; i < columns; i++) {
+
+ if ((Next_Random() % 8) == 0) {
+ starts[i] = UINT_MAX;
+ ends[i] = UINT_MAX;
+ continue;
+ }
+
+ starts[i] = (unsigned int)at;
+
+ int remaining = zsize;
+
+ while (remaining > 0) {
+ int const skip = (int)(Next_Random() % (unsigned int)remaining);
+ remaining -= skip;
+
+ int const run = 1 + (int)(Next_Random() % (unsigned int)remaining);
+ remaining -= run;
+
+ VoxelData[at++] = (unsigned char)skip;
+ VoxelData[at++] = (unsigned char)run;
+
+ /*
+ * A voxel is a colour and a normal for the drawers that shade, and a colour
+ * on its own for the two that do not.
+ */
+ for (int v = 0; v < run; v++) {
+ VoxelData[at++] = (unsigned char)(1 + (Next_Random() % 254));
+
+ if (withnormals) {
+ VoxelData[at++] = (unsigned char)(Next_Random() % 244);
+ }
+ }
+
+ VoxelData[at++] = (unsigned char)run;
+ }
+
+ ends[i] = (unsigned int)(at - 1);
+ }
+
+ for (int i = 0; i < 256 * 3; i++) {
+ ((unsigned char *)VoxelRGBColors)[i] = (unsigned char)(Next_Random() & 0xFF);
+ }
+
+ for (int i = 0; i < MAX_PALETTE_LOOKUP_ENTRIES; i++) {
+ for (int j = 0; j < VOXEL_PALETTE_SIZE; j++) {
+ VoxelPaletteTranslateTable[i][j] = (unsigned char)(Next_Random() & 0xFF);
+ }
+ }
+}
+
+
+void Setup(VoxelFuncArgumentStruct & arg)
+{
+ std::memset(&arg, 0, sizeof(arg));
+
+ arg.StartOffset = StartOffsets;
+ arg.EndOffset = EndOffsets;
+ arg.DataOffset = VoxelData;
+ arg.StartIndex = 24;
+ arg.StrideX = 1;
+ arg.StrideY = 4;
+
+ for (int i = 0; i < 4; i++) {
+ arg.TransformMatrix[i].I = (short)(64 + i * 16);
+ arg.TransformMatrix[i].J = (short)(48 + i * 8);
+ arg.TransformMatrix[i].K = (short)(32 + i * 4);
+ }
+
+ arg.XSize = 4;
+ arg.YSize = 4;
+ arg.ZSize = 8;
+}
+
+} // namespace
+
+
+int main(void)
+{
+ for (int i = 0; i < VoxelGoldenCaseCount; i++) {
+ VoxelGoldenCase const & test = VoxelGoldenCases[i];
+
+ Build_Layer(test.Seed, 64, 8, test.Which < 4);
+
+ VoxelFuncArgumentStruct arg;
+ std::memset(VoxelDrawBuffer, 0, sizeof(VoxelDrawBuffer));
+ Setup(arg);
+
+ Drawers[test.Which](&arg);
+
+ unsigned long long const hash = Hash(VoxelDrawBuffer, sizeof(VoxelDrawBuffer));
+
+ if (hash != test.Hash) {
+ std::printf("FAILED %-38s seed %u: expected %llu, got %llu\n",
+ Names[test.Which], test.Seed, test.Hash, hash);
+ Failures++;
+ }
+
+ Checked++;
+ }
+
+ std::printf("%-52s %s\n", "Voxel drawing matches the recorded assembly", Failures == 0 ? "ok" : "FAILED");
+ std::printf("checked %d cases, %d mismatches\n", Checked, Failures);
+
+ return(Failures == 0 ? 0 : 1);
+}
diff --git a/tests/voxeldraw/voxelgolden.h b/tests/voxeldraw/voxelgolden.h
new file mode 100644
index 00000000..af3f4d9e
--- /dev/null
+++ b/tests/voxeldraw/voxelgolden.h
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * 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 voxel drawers while they were still hand-written assembly, and kept
+// so the C++ that replaced them can be held to the same output. Each row is one drawer
+// run over a generated layer, hashed across the whole draw buffer.
+//
+// Generated file. Do not hand-edit.
+
+#pragma once
+
+struct VoxelGoldenCase {
+ int Which;
+ unsigned int Seed;
+ unsigned long long Hash;
+};
+
+static VoxelGoldenCase const VoxelGoldenCases[] = {
+ {0, 28169u, 13324653092316034450ULL},
+ {0, 36088u, 12351699151280656429ULL},
+ {0, 44007u, 17199592110331691751ULL},
+ {0, 51926u, 15390681673580776202ULL},
+ {0, 59845u, 2825425979693356026ULL},
+ {0, 67764u, 25800052190659043ULL},
+ {0, 75683u, 7325842616049640313ULL},
+ {0, 83602u, 17645968187554184191ULL},
+ {0, 91521u, 9525590033643036072ULL},
+ {0, 99440u, 10585983704101342410ULL},
+ {0, 107359u, 10204120045907133699ULL},
+ {0, 115278u, 11130510175161308529ULL},
+ {0, 123197u, 5767097110549188921ULL},
+ {0, 131116u, 5235687674598385644ULL},
+ {0, 139035u, 9005539365649528394ULL},
+ {0, 146954u, 18425927706755742343ULL},
+ {0, 154873u, 947132574381123500ULL},
+ {0, 162792u, 2943253927102308ULL},
+ {0, 170711u, 11354915360533545630ULL},
+ {0, 178630u, 12938560224086218970ULL},
+ {0, 186549u, 6735834921435141727ULL},
+ {0, 194468u, 4620132221512080041ULL},
+ {0, 202387u, 6805978274876668650ULL},
+ {0, 210306u, 3062081007018294060ULL},
+ {1, 218225u, 5518851115440504590ULL},
+ {1, 226144u, 17766976509397856527ULL},
+ {1, 234063u, 21458341796674991ULL},
+ {1, 241982u, 9668340853698928506ULL},
+ {1, 249901u, 11070411440877969667ULL},
+ {1, 257820u, 3412966419792104896ULL},
+ {1, 265739u, 1644744544794223772ULL},
+ {1, 273658u, 18215157723010317950ULL},
+ {1, 281577u, 13494821044585903190ULL},
+ {1, 289496u, 15635478134736993356ULL},
+ {1, 297415u, 3676630468166872938ULL},
+ {1, 305334u, 1650428375562877262ULL},
+ {1, 313253u, 7635345958887419688ULL},
+ {1, 321172u, 2156384056444245913ULL},
+ {1, 329091u, 16799683983158384103ULL},
+ {1, 337010u, 7022508193269267110ULL},
+ {1, 344929u, 14506774546798531577ULL},
+ {1, 352848u, 18199756956898249519ULL},
+ {1, 360767u, 17470699965221551398ULL},
+ {1, 368686u, 225776899552830475ULL},
+ {1, 376605u, 3449402144847509193ULL},
+ {1, 384524u, 13050037680469517880ULL},
+ {1, 392443u, 9010391954831812739ULL},
+ {1, 400362u, 6942504870830098237ULL},
+ {2, 408281u, 15798523031825813403ULL},
+ {2, 416200u, 4507558737198793848ULL},
+ {2, 424119u, 3851442749804437763ULL},
+ {2, 432038u, 930039072865289532ULL},
+ {2, 439957u, 14918691864484818114ULL},
+ {2, 447876u, 1900814372412917523ULL},
+ {2, 455795u, 9880610814969945598ULL},
+ {2, 463714u, 12235921528745917133ULL},
+ {2, 471633u, 17295491051951213915ULL},
+ {2, 479552u, 8208964221764546070ULL},
+ {2, 487471u, 15498567043124049416ULL},
+ {2, 495390u, 11601304743621742993ULL},
+ {2, 503309u, 13668221661727899355ULL},
+ {2, 511228u, 8056635900584925629ULL},
+ {2, 519147u, 2371813117170145389ULL},
+ {2, 527066u, 11631430866345469306ULL},
+ {2, 534985u, 3391000685292444630ULL},
+ {2, 542904u, 1748974867776887855ULL},
+ {2, 550823u, 12245671744384124113ULL},
+ {2, 558742u, 14093335007620427588ULL},
+ {2, 566661u, 1834971198173119818ULL},
+ {2, 574580u, 11489914551042742038ULL},
+ {2, 582499u, 11144311815646134855ULL},
+ {2, 590418u, 6836879586511554304ULL},
+ {3, 598337u, 1976035810807648333ULL},
+ {3, 606256u, 883352253650328485ULL},
+ {3, 614175u, 15160697399241641046ULL},
+ {3, 622094u, 18205160147392533888ULL},
+ {3, 630013u, 14713795521886969930ULL},
+ {3, 637932u, 11922145548072268503ULL},
+ {3, 645851u, 7792075245259396222ULL},
+ {3, 653770u, 8258093120125759069ULL},
+ {3, 661689u, 18415915043351740624ULL},
+ {3, 669608u, 6976820877669932813ULL},
+ {3, 677527u, 11393741950045336747ULL},
+ {3, 685446u, 7013445700322398ULL},
+ {3, 693365u, 16301890081953396848ULL},
+ {3, 701284u, 2884016264197242965ULL},
+ {3, 709203u, 13109705519595437632ULL},
+ {3, 717122u, 9038234598152107521ULL},
+ {3, 725041u, 18120218201080976346ULL},
+ {3, 732960u, 16154636395797325481ULL},
+ {3, 740879u, 11006938371435845325ULL},
+ {3, 748798u, 5101920956829682532ULL},
+ {3, 756717u, 8748102682002764481ULL},
+ {3, 764636u, 11659063084790268686ULL},
+ {3, 772555u, 2655796341723522167ULL},
+ {3, 780474u, 725836304033682059ULL},
+ {4, 788393u, 17319385156311552112ULL},
+ {4, 796312u, 16114144959221699025ULL},
+ {4, 804231u, 10340858242751730055ULL},
+ {4, 812150u, 16019673527993767970ULL},
+ {4, 820069u, 9428795686763808470ULL},
+ {4, 827988u, 11071396149133517701ULL},
+ {4, 835907u, 3234787090869658245ULL},
+ {4, 843826u, 12935715497379451815ULL},
+ {4, 851745u, 9458909090346731205ULL},
+ {4, 859664u, 13671555177889190665ULL},
+ {4, 867583u, 15378978062566025315ULL},
+ {4, 875502u, 6874713299200778180ULL},
+ {4, 883421u, 2952795751253253804ULL},
+ {4, 891340u, 840002272274625432ULL},
+ {4, 899259u, 2080632909900450398ULL},
+ {4, 907178u, 8985056800710389501ULL},
+ {4, 915097u, 9639344470705128394ULL},
+ {4, 923016u, 16503286310499537632ULL},
+ {4, 930935u, 6516524042821633501ULL},
+ {4, 938854u, 13680118317128312181ULL},
+ {4, 946773u, 3895685521886869962ULL},
+ {4, 954692u, 10075103390259047234ULL},
+ {4, 962611u, 7659016989448857716ULL},
+ {4, 970530u, 16226987279403785379ULL},
+ {5, 978449u, 7288319002546285772ULL},
+ {5, 986368u, 17612033881854792519ULL},
+ {5, 994287u, 3461599239973342401ULL},
+ {5, 1002206u, 15039810666827916584ULL},
+ {5, 1010125u, 18371164988567740942ULL},
+ {5, 1018044u, 12293430003845797862ULL},
+ {5, 1025963u, 8102361577346857935ULL},
+ {5, 1033882u, 2564456440406630395ULL},
+ {5, 1041801u, 3483474835034988953ULL},
+ {5, 1049720u, 2501774471487365128ULL},
+ {5, 1057639u, 16938717331603262696ULL},
+ {5, 1065558u, 6788858469973355994ULL},
+ {5, 1073477u, 4916021252031669732ULL},
+ {5, 1081396u, 3311612869175857256ULL},
+ {5, 1089315u, 1257421795503950132ULL},
+ {5, 1097234u, 13091701898044066741ULL},
+ {5, 1105153u, 658427270734594543ULL},
+ {5, 1113072u, 5468683957858687788ULL},
+ {5, 1120991u, 14975481465617277333ULL},
+ {5, 1128910u, 18275530173698096306ULL},
+ {5, 1136829u, 5749156747542087814ULL},
+ {5, 1144748u, 4516671183284595814ULL},
+ {5, 1152667u, 12988872537847733407ULL},
+ {5, 1160586u, 4971511207443437606ULL},
+};
+
+static int const VoxelGoldenCaseCount = 144;
From f6cb438d4285e5bdc3ee1fa22bf676782ca2f4a8 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Wed, 2 Sep 2026 18:57:31 +0200
Subject: [PATCH 02/14] Resolve the merge conflict left in the unshaded voxel
drawers
---
code/voxlib.cpp | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/code/voxlib.cpp b/code/voxlib.cpp
index 895c50c9..d143ba3b 100644
--- a/code/voxlib.cpp
+++ b/code/voxlib.cpp
@@ -1964,16 +1964,9 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr++;
-<<<<<<< HEAD
- /// Compute buffer index and write color
- unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
- VoxelDrawBuffer[buffer_index] = color_index;
- VoxelDrawBuffer[buffer_index + 1] = color_index;
-=======
/// Compute buffer index and write color. Unlike the shaded
/// drawers, this one covers a single buffer byte per voxel.
VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00)] = color_index;
->>>>>>> 0fef683 (Translate voxel drawing and colour operations to C++)
pixel_x += state->TransformMatrix[3].I;
pixel_y += state->TransformMatrix[3].J;
@@ -2051,16 +2044,9 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr--;
-<<<<<<< HEAD
- /// Compute buffer index and write color
- unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
- VoxelDrawBuffer[buffer_index] = color_index;
- VoxelDrawBuffer[buffer_index + 1] = color_index;
-=======
/// Compute buffer index and write color. Unlike the shaded
/// drawers, this one covers a single buffer byte per voxel.
VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00)] = color_index;
->>>>>>> 0fef683 (Translate voxel drawing and colour operations to C++)
pixel_x += state->TransformMatrix[3].I;
pixel_y += state->TransformMatrix[3].J;
From 710868fe6eace9608936e28430bcf167787e6f11 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Wed, 2 Sep 2026 18:58:00 +0200
Subject: [PATCH 03/14] Remove the assembly superseded by the C++ colour and
voxel ports
---
code/winasm.asm | 2538 -----------------------------------------------
1 file changed, 2538 deletions(-)
delete mode 100644 code/winasm.asm
diff --git a/code/winasm.asm b/code/winasm.asm
deleted file mode 100644
index f02ccaed..00000000
--- a/code/winasm.asm
+++ /dev/null
@@ -1,2538 +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.
-;******************************************************************************
-
-;***************************************************************************
-;** 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 I N C **
-;***************************************************************************
-;* *
-;* Project Name : Command & Conquer *
-;* *
-;* File Name : WINSAM.ASM *
-;* *
-;* Programmer : Steve Tall *
-;* *
-;* Start Date : October 26th, 1995 *
-;* *
-;* Last Update : October 26th, 1995 [ST] *
-;* *
-;*-------------------------------------------------------------------------*
-;* Functions: *
-;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
-
-
-;IDEAL
-;.386P ;P386
-.686P ; Pentium Pro and above enables CMOV
-.mmx
-.model flat, C ;MODEL USE32 FLAT
-
- ; alignment has to be 'page' so that I can use 'align 32' below
- _TEXT$mmx segment page public use32 'CODE';codeseg
-
-
-;
-; externs
-;
-EXTERN C VoxelPixelDeltaTable : PTR WORD ; short [256][2] ; Defined in voxlib.cpp
-EXTERN C VoxelNormalTranslateTable : BYTE ; uchar [256] ; Defined in voxlib.cpp
-EXTERN C VoxelDrawBuffer : BYTE ; uchar [65536] ; Defined in voxdrsys.cpp
-EXTERN C VoxelPaletteTranslateTable : BYTE ; uchar [32][256] ; Defined in voxdrsys.cpp
-EXTERNDEF C UseCMOV : BYTE
-EXTERNDEF C UseMMX : BYTE
-
-
-; no idea how to get this to appear so fake it
-_align MACRO count
- REPT (count / 8)
- ;lea esp, [esp+0] but zero is optimized to a byte..
- db 08Dh, 0A4h, 024h, 00h, 00h, 00h, 00h
- ENDM
-ENDM
-
-_align_ MACRO
- ;lea esp, [esp+0] but zero is optimized to a byte..
- db 08Dh, 064h, 024h, 00h
-ENDM
-
-_alignm MACRO reg
- mov reg,reg
-ENDM
-
-
-;
-; structs
-;
-Vector3i16 STRUCT
- I SWORD ?
- J SWORD ?
- K SWORD ?
-Vector3i16 ENDS
-
-IF SIZEOF Vector3i16 NE 6
- ;.ERR
- ECHO *** Warning: Vector3i16 is not 6 bytes as expected ***
- vecstrucSize DWORD SIZEOF Vector3i16
-ENDIF
-
-
-VoxelFuncArgumentStruct STRUCT ; WARNING: Make sure this struct is updated if the version in voxdrsys.h is modified!
- StartOffset DWORD ? ; unsigned char *
- EndOffset DWORD ? ; unsigned char *
- DataOffset DWORD ? ; unsigned char *
- StartIndex SDWORD ? ; int
- StrideX SDWORD ? ; int
- StrideY SDWORD ? ; int
- TransformMatrix Vector3i16 4 DUP (<>) ; Vector3i16[4]
- XSize BYTE ? ; unsigned char
- YSize BYTE ? ; unsigned char
- ZSize BYTE ? ; unsigned char
- Padding BYTE ? ; pad to make struct size divisible by 4, matching the C++ implementation layout
-VoxelFuncArgumentStruct ENDS
-
-
-IF SIZEOF VoxelFuncArgumentStruct NE 52
- ;.ERR
- ECHO *** Warning: VoxelFuncArgumentStruct is not 48 bytes as expected ***
- voxstrucSize DWORD SIZEOF VoxelFuncArgumentStruct
-ENDIF
-
-TRANSFORM_VECTOR MACRO index:req
- EXITM
-ENDM
-
-TRANSFORM_COMPONENT MACRO index:req, component:req
- LOCAL offset
- IFIDNI ,
- offset = (Vector3i16.I)
- ELSEIFIDNI ,
- offset = (Vector3i16.J)
- ELSEIFIDNI ,
- offset = (Vector3i16.K)
- ELSE
- .ERR
- ENDIF
-
- EXITM
-ENDM
-
-ADJUST_COLOR MACRO procname, mode:req
-
- LOCAL mode
- IFIDNI ,
-
- R_POS = 11
- G_POS = 5
- B_POS = 0
-
- R_MASK = 11111000b
- G_MASK = 11111100b
- B_MASK = 11111000b
-
- R_SHIFT = 8
- G_SHIFT = 3
- B_SHIFT = 3
-
- R_SHIFT_MMX = 8
- G_SHIFT_MMX = 5
- B_SHIFT_MMX = 19
-
- R_SHIFT_CMOV = 8
- G_SHIFT_CMOV = 13
- B_SHIFT_CMOV = 19
-
- ELSEIFIDNI ,
-
- R_POS = 10
- G_POS = 5
- B_POS = 0
-
- R_MASK = 11111000b
- G_MASK = 11111000b
- B_MASK = 11111000b
-
- R_SHIFT = 7
- G_SHIFT = 2
- B_SHIFT = 3
-
- R_SHIFT_MMX = 7
- G_SHIFT_MMX = 6
- B_SHIFT_MMX = 19
-
- R_SHIFT_CMOV = 9
- G_SHIFT_CMOV = 14
- B_SHIFT_CMOV = 19
-
- ELSEIFIDNI ,
-
- R_POS = 11
- G_POS = 6
- B_POS = 0
-
- R_MASK = 11111000b
- G_MASK = 11111000b
- B_MASK = 11111100b
-
- R_SHIFT = 8
- G_SHIFT = 3
- B_SHIFT = 2
-
- R_SHIFT_MMX = 8
- G_SHIFT_MMX = 5
- B_SHIFT_MMX = 18
-
- R_SHIFT_CMOV = 8
- G_SHIFT_CMOV = 13
- B_SHIFT_CMOV = 18
-
- ELSEIFIDNI ,
-
- R_POS = 11
- G_POS = 5
- B_POS = 0
-
- R_MASK = 11111100b
- G_MASK = 11111000b
- B_MASK = 11111000b
-
- R_SHIFT = 8
- G_SHIFT = 2
- B_SHIFT = 3
-
- R_SHIFT_MMX = 8
- G_SHIFT_MMX = 6
- B_SHIFT_MMX = 19
-
- R_SHIFT_CMOV = 8
- G_SHIFT_CMOV = 14
- B_SHIFT_CMOV = 19
-
- ELSE
- .ERR
- ENDIF
-PUBLIC C &procname
-
-&procname proc C uses ebx ecx edx esi edi, \
- srcpal:DWORD, \
- dstpal:DWORD, \
- red:DWORD, \
- green:DWORD, \
- blue:DWORD, \
- intensity:DWORD, \
- _mask:DWORD
-
- LOCAL value:DWORD
- LOCAL counter:DWORD
-
- cmp UseMMX, 0
- jnz ??mmx_path
-
- cmp UseCMOV, 0
- jnz ??cmov_path
-
- mov [counter], 255
- mov esi, [srcpal]
- mov edi, [dstpal]
- mov edx, [_mask]
-
- ; skip first index which is transparent
- add esi, 3
- ; skip first mask index
- inc edx
-
- mov word ptr [edi], 0
- xor ebx, ebx
- jmp ??regular_loop
-
-??cmov_path:
- pushfd
- cld
-
- mov [counter], 255
- mov esi, [srcpal]
- mov [value], 000FF0000h
- mov edi, [dstpal]
- mov edx, [_mask]
-
- ; skip first index which is transparent
- add esi, 3
- ; skip first mask index
- inc edx
-
- mov word ptr [edi], 0
-
- ; advance destination
- add edi, 2
-
- jmp ??cmov_loop
-
-??mmx_path:
- mov [counter], 255
- mov esi, [srcpal]
- mov edi, [dstpal]
- mov edx, [_mask]
-
- ; skip first index which is transparent
- add esi, 3
- ; skip first mask index
- inc edx
-
- sub edi, 2
-
- movq mm1, qword ptr [red]
- movq mm2, qword ptr [blue]
- psrad mm1, 4
- psrad mm2, 4
- packssdw mm1, mm2
- pxor mm0, mm0
- movq mm2, mm1
- punpckhwd mm2, mm1
- punpckhwd mm2, mm2
-
- jmp ??mmx_loop
-
- align 64
-
-??mmx_loop:
- ; advance destination
- add edi, 2
-
- packuswb mm0, mm0
-
- ; check mask, if zero use intensity
- cmp byte ptr [edx], 0
- jz ??mmx_use_intensity
-
- movd eax, mm0
- pxor mm0, mm0
-
- punpcklbw mm0, [esi]
-
- mov ebx, eax
-
- psrlw mm0, 4
-
- ; convert to wanted format
- and eax, R_MASK
- mov ecx, ebx
- shl eax, R_SHIFT_MMX
- and ebx, (G_MASK * 256)
- shr ebx, G_SHIFT_MMX
- and ecx, (B_MASK * 256 * 256)
- shr ecx, B_SHIFT_MMX
- pmulhw mm0, mm1
-
- ; combine red and green
- or eax, ebx
-
- ; advance source
- add esi, 3
-
- or eax, ecx
-
- ; advance mask
- inc edx
-
- ; store color
- mov [edi], ax
-
- dec [counter]
-
- jnz ??mmx_loop
-
-??mmx_exit:
- ; advance destination
- add edi, 2
-
- packuswb mm0, mm0
-
- movd eax, mm0
- mov ebx, eax
-
- ; convert to wanted format
- and eax, R_MASK
- mov ecx, ebx
- shl eax, R_SHIFT_MMX
- and ebx, (G_MASK * 256)
- shr ebx, G_SHIFT_MMX
- and ecx, (B_MASK * 256 * 256)
- shr ecx, B_SHIFT_MMX
-
- ; combine red and green
- or eax, ebx
-
- ; combine blue
- or eax, ecx
-
- ; store color
- mov [edi], ax
-
- emms
- ret
-
-??mmx_use_intensity:
-
- movd eax, mm0
- pxor mm0, mm0
-
- punpcklbw mm0, [esi]
-
- mov ebx, eax
-
- psrlw mm0, 4
-
- ; convert to wanted format
- and eax, R_MASK
- mov ecx, ebx
- shl eax, R_SHIFT_MMX
- and ebx, (G_MASK * 256)
- shr ebx, G_SHIFT_MMX
- and ecx, (B_MASK * 256 * 256)
- shr ecx, B_SHIFT_MMX
-
- ; scale by intensity
- pmulhw mm0, mm2
-
- ; combine red and green
- or eax, ebx
-
- ; advance source
- add esi, 3
-
- ; combine blue
- or eax, ecx
-
- ; advance mask
- inc edx
-
- ; store color
- mov [edi], ax
-
- dec [counter]
-
- jnz ??mmx_loop
-
- jmp ??mmx_exit
-
- align 64
-
-??cmov_loop:
- ; check mask, if zero use intensity
- cmp byte ptr [edx], 0
-
- movzx eax, byte ptr [esi]
- movzx ebx, byte ptr [esi+1]
- movzx ecx, byte ptr [esi+2]
- jz ??cmov_use_intensity
-
- ; scale r g b
- imul eax, [red]
- imul ebx, [green]
- imul ecx, [blue]
-
-??cmov_inner:
- ; advance source
- add esi, 3
-
- ; clamp r g b
- test eax, 0FF000000h
- cmovnz eax, [value]
- test ebx, 0FF000000h
- cmovnz ebx, [value]
- test ecx, 0FF000000h
- cmovnz ecx, [value]
-
- ; convert to wanted format
- and eax, (R_MASK * 256 * 256)
- shr eax, R_SHIFT_CMOV
- and ebx, (G_MASK * 256 * 256)
- shr ebx, G_SHIFT_CMOV
- and ecx, (B_MASK * 256 * 256)
-
- ; combine red and green
- or eax, ebx
-
- shr ecx, B_SHIFT_CMOV
-
- ; advance mask
- inc edx
-
- ; combine blue
- or eax, ecx
-
- ; store color
- stosw
-
- dec [counter]
-
- jnz ??cmov_loop
-
- popfd
-
- ret
-
-??cmov_use_intensity:
- imul eax, [intensity]
- imul ebx, [intensity]
- imul ecx, [intensity]
- jmp ??cmov_inner
-
- align 64
-
-??regular_loop:
- xor eax, eax
- mov bl, [esi+1]
- xor ecx, ecx
- mov al, [esi]
-
- ; check mask, if zero use intensity
- cmp byte ptr [edx], 0
- jz ??regular_use_intensity
-
- mov cl, [esi+2]
- inc edx
- imul eax, [red]
- imul ebx, [green]
- imul ecx, [blue]
-
- shr eax, 16
-
- ; advance source
- add esi, 3
-
- shr ebx, 16
-
- ; clamp r g b
- cmp eax, 255
- setbe ah
- shr ecx, 16
- dec ah
- or al, ah
- cmp ebx, 255
- setbe bh
- dec bh
- cmp ecx, 255
- setbe ch
- or bl, bh
- dec ch
- or cl, ch
-
- ; convert to wanted format
- and eax, R_MASK
- shl eax, R_SHIFT
- and ebx, G_MASK
- shl ebx, G_SHIFT
- and ecx, B_MASK
- shr ecx, B_SHIFT
-
- ; combine red and green
- or eax, ebx
-
- ; advance destination
- add edi, 2
-
- xor ebx, ebx
-
- ; combine blue
- or eax, ecx
-
- dec [counter]
-
- ; store color
- mov [edi], ax
-
- jnz ??regular_loop
-
- ret
-
-??regular_use_intensity:
-
- mov cl, [esi+2]
-
- ; advance mask
- inc edx
-
- ; increase color by intensity
- imul eax, [intensity]
- imul ebx, [intensity]
- imul ecx, [intensity]
-
- ; normalize red
- shr eax, 16
-
- ; advance source
- add esi, 3
-
- ; normalize green
- shr ebx, 16
-
- ; clamp r g b
- cmp eax, 255
- setbe ah
- shr ecx, 16
- dec ah
- or al, ah
- cmp ebx, 255
- setbe bh
- dec bh
- cmp ecx, 255
- setbe ch
- or bl, bh
- dec ch
- or cl, ch
-
- ; convert to wanted format
- and eax, R_MASK
- shl eax, R_SHIFT
- and ebx, G_MASK
- shl ebx, G_SHIFT
- and ecx, B_MASK
- shr ecx, B_SHIFT
-
- ; combine red and green
- or eax, ebx
-
- ; advance destination
- add edi, 2
-
- xor ebx, ebx
-
- ; combine blue
- or eax, ecx
-
- dec [counter]
-
- ; store color
- mov [edi], ax
-
- jnz ??regular_loop
-
- ret
-&procname ENDP
-ENDM
-
-ADJUST_COLOR Adjust_Color_565, rgb565
-ADJUST_COLOR Adjust_Color_555, rgb555
-ADJUST_COLOR Adjust_Color_556, rgb556
-ADJUST_COLOR Adjust_Color_655, rgb655
-
-
-BRIGHTEN_COLOR MACRO procname, mode:req
-
- LOCAL mode
- IFIDNI ,
-
- CONSTANT_0 = 8
- CONSTANT_1 = 3
- CONSTANT_2 = 0F8h
- CONSTANT_3 = 0FCh
- CONSTANT_4 = 8
- CONSTANT_5 = 8
- CONSTANT_6 = 3
- CONSTANT_7 = 2
- CONSTANT_8 = 11
- CONSTANT_9 = 5
- CONSTANT_10 = 3
- CONSTANT_11 = 8
- CONSTANT_12 = 3
-
- ELSEIFIDNI ,
-
- CONSTANT_0 = 8
- CONSTANT_1 = 2
- CONSTANT_2 = 0FCh
- CONSTANT_3 = 0F8h
- CONSTANT_4 = 8
- CONSTANT_5 = 8
- CONSTANT_6 = 2
- CONSTANT_7 = 3
- CONSTANT_8 = 10
- CONSTANT_9 = 5
- CONSTANT_10 = 3
- CONSTANT_11 = 8
- CONSTANT_12 = 3
-
- ELSEIFIDNI ,
-
- CONSTANT_0 = 8
- CONSTANT_1 = 3
- CONSTANT_2 = 0F8h
- CONSTANT_3 = 0F8h
- CONSTANT_4 = 8
- CONSTANT_5 = 8
- CONSTANT_6 = 3
- CONSTANT_7 = 3
- CONSTANT_8 = 11
- CONSTANT_9 = 6
- CONSTANT_10 = 2
- CONSTANT_11 = 8
- CONSTANT_12 = 2
-
- ELSEIFIDNI ,
-
- CONSTANT_0 = 7
- CONSTANT_1 = 2
- CONSTANT_2 = 0F8h
- CONSTANT_3 = 0F8h
- CONSTANT_4 = 8
- CONSTANT_5 = 8
- CONSTANT_6 = 3
- CONSTANT_7 = 3
- CONSTANT_8 = 10
- CONSTANT_9 = 5
- CONSTANT_10 = 3
- CONSTANT_11 = 8
- CONSTANT_12 = 3
-
- ELSE
- .ERR
- ENDIF
-PUBLIC C &procname
-
-&procname proc C uses ebx ecx edx esi edi, \
- mul_buffer:DWORD, \
- color_buffer:DWORD, \
- mulbuff_width:DWORD, \
- color_buff_width:DWORD, \
- dst_width:DWORD, \
- dst_height:DWORD
-
- LOCAL wleft:DWORD
- LOCAL hleft:DWORD
- LOCAL local4:DWORD
- LOCAL local3:DWORD
- LOCAL local2:DWORD
- LOCAL local1:DWORD
-
- xor eax, eax
- mov [local2], eax
- mov eax, [dst_height]
- mov [hleft], eax
- mov [local1], 0
- mov esi, [mul_buffer]
- mov [local4], esi
- mov edi, [color_buffer]
- mov [local3], edi
-
-??loop1:
- mov eax, [dst_width]
- mov [wleft], eax
- xor eax, eax
- xor ebx, ebx
-
-??loop2:
- mov al, [esi]
- test al, al
- jz ??inc
-
- mov bx, [edi]
- mov byte ptr [local1], al
- mov [local2], ebx
- shr ebx, CONSTANT_0
- mov eax, dword ptr [local2]
- shr eax, CONSTANT_1
- and ebx, CONSTANT_2
- and eax, CONSTANT_3
- mov edx, ebx
- mov ecx, eax
- imul ebx, [local1]
- imul eax, [local1]
- shr ebx, CONSTANT_4
- shr eax, CONSTANT_5
- add bl, dl
- setnb dl
- add al, cl
- setnb cl
- dec dl
- dec cl
- or bl, dl
- or al, cl
- shr ebx, CONSTANT_6
- shr eax, CONSTANT_7
- shl ebx, CONSTANT_8
- shl eax, CONSTANT_9
- mov ecx, [local2]
- shl ecx, CONSTANT_10
- or eax, ebx
- and ecx, 0FFh
- mov edx, ecx
- imul ecx, [local1]
- shr ecx, CONSTANT_11
- add cl, dl
- setnb dl
- dec dl
- or cl, dl
- shr ecx, CONSTANT_12
- or eax, ecx
- mov [edi], ax
-
-??inc:
- inc esi
- add edi, 2
- dec [wleft]
- jnz ??loop2
-
- mov esi, [local4]
- add esi, [mulbuff_width]
- mov [local4], esi
- mov edi, [local3]
- add edi, [color_buff_width]
- mov [local3], edi
- dec [hleft]
- jnz ??loop1
-
- ret
-
-&procname ENDP
-ENDM
-
-BRIGHTEN_COLOR Brighten_Color_565, rgb565
-BRIGHTEN_COLOR Brighten_Color_655, rgb655
-
-BRIGHTEN_COLOR Brighten_Color_556, rgb556
-BRIGHTEN_COLOR Brighten_Color_555, rgb555
-
-align 128
-
-MMX_BRIGHTEN_COLOR MACRO procname, mode:req
-
- LOCAL mode
- IFIDNI ,
-
- CONSTANT_2 = 2
- CONSTANT_3 = 1
- CONSTANT_4 = 5
- CONSTANT_5 = 10
- CONSTANT_6 = 0F8h
-
- ELSEIFIDNI ,
-
- CONSTANT_2 = 3
- CONSTANT_3 = 0
- CONSTANT_4 = 5
- CONSTANT_5 = 10
- CONSTANT_6 = 07Ch
-
- ELSEIFIDNI ,
-
- CONSTANT_2 = 2
- CONSTANT_3 = 0
- CONSTANT_4 = 6
- CONSTANT_5 = 10
- CONSTANT_6 = 0F8h
-
- ELSEIFIDNI ,
-
- CONSTANT_2 = 2
- CONSTANT_3 = 1
- CONSTANT_4 = 4
- CONSTANT_5 = 10
- CONSTANT_6 = 423A0A60h
-
- ELSE
- .ERR
- ENDIF
-PUBLIC C &procname
-
-&procname proc C uses ebx ecx edx esi edi, \
- mul_buffer:DWORD, \
- color_buffer:DWORD, \
- mulbuff_width:DWORD, \
- color_buff_width:DWORD, \
- dst_width:DWORD, \
- dst_height:DWORD, \
- mmx_buffer:DWORD
-
- LOCAL local7:DWORD
- LOCAL wleft:DWORD
- LOCAL hleft:DWORD
- LOCAL local4:DWORD
- LOCAL local3:DWORD
- LOCAL local2:QWORD
- LOCAL local1:QWORD
-
- xor eax, eax
- mov [local3], eax
- mov eax, [dst_height]
- mov [wleft], eax
- mov dword ptr [local2], 0
- mov dword ptr [local2+4], 0
- mov dword ptr [local1], 0
- mov dword ptr [local1+4], 0
- mov esi, [mul_buffer]
- mov [hleft], esi
- mov edi, [color_buffer]
- mov [local4], edi
- mov edx, [mmx_buffer]
-
-??loc_6C8BC1:
- mov eax, [dst_width]
- mov [local7], eax
- xor eax, eax
- xor ebx, ebx
- jmp short ??loc_6C8C40
-
- align 64
-
-??loc_6C8C00:
- inc esi
- lea edi, [edi+2]
- dec [local7]
- jnz ??loc_6C8C40
-
- mov esi, [hleft]
- add esi, [mulbuff_width]
- mov [hleft], esi
- mov edi, [local4]
- add edi, [color_buff_width]
- mov [local4], edi
- dec [wleft]
- jnz ??loc_6C8BC1
-
- jmp ??loc_6C8CB7
-
- align 64
-
-??loc_6C8C40:
- mov al, [esi]
- test al, al
- jz ??loc_6C8C00
-
- mov byte ptr [local2], al
- mov bx, [edi]
- mov byte ptr [local2+2], al
- mov byte ptr [local2+4], al
- punpcklbw mm0, [edx+ebx*4]
- psrlw mm0, 8
- movq mm1, mm0
- pmullw mm0, [local2]
- psrlw mm0, 8
- paddusb mm0, mm1
- psrlw mm0, CONSTANT_2
- movq [local1], mm0
-
- xor ebx, ebx
- xor eax, eax
- mov bl, byte ptr [local1]
- mov al, byte ptr [local1+2]
-
-if CONSTANT_3 gt 0
- shr bl, CONSTANT_3
-endif
-
- xor ecx, ecx
- shl eax, CONSTANT_4
- mov cl, byte ptr [local1+4]
- shl ecx, CONSTANT_5
-if CONSTANT_6 eq 0423A0A60h
- and eax, CONSTANT_6
- or ebx, eax
-else
- or ebx, eax
- and ecx, (CONSTANT_6 * 256)
-endif
- inc esi
- or ebx, ecx
- lea edi, [edi+2]
- mov [edi-2], bx
- dec [local7]
- jnz ??loc_6C8C40
-
- mov esi, [hleft]
- add esi, [mulbuff_width]
- mov [hleft], esi
- mov edi, [local4]
- add edi, [color_buff_width]
- mov [local4], edi
- dec [wleft]
- jnz ??loc_6C8BC1
-
-??loc_6C8CB7:
- emms
- ret
-
-&procname ENDP
-ENDM
-
-
-MMX_BRIGHTEN_COLOR MMX_Brighten_Color_565, rgb565
-MMX_BRIGHTEN_COLOR MMX_Brighten_Color_555, rgb555
-MMX_BRIGHTEN_COLOR MMX_Brighten_Color_556, rgb556
-MMX_BRIGHTEN_COLOR MMX_Brighten_Color_655, rgb655
-
-align 8
-
-; VOID cdecl Func(VoxelFuncArgumentStruct * arg1);
-Draw_Voxel_Regular_Normals_ASM proc C uses esi edi ebx ecx edx \
- arg1:DWORD
-
- LOCAL local3:DWORD
- LOCAL local2:DWORD
- LOCAL local1:DWORD
-
- assume esi:ptr VoxelFuncArgumentStruct
-
- mov esi, arg1
- push ebp
- movsx ebp, WORD PTR [esi + TRANSFORM_COMPONENT(3,I)]
- movsx edx, WORD PTR [esi + TRANSFORM_COMPONENT(3,J)]
- xor ecx, ecx
- mov cl, [esi].ZSize
- mov edi, offset VoxelPixelDeltaTable
- xor eax, eax
- xor ebx, ebx
- mov esi, 4
-
-??loc_6C8E6A:
- mov [edi], ax
- add edi, 2
- add eax, ebp
- mov [edi], bx
- add edi, 2
- add ebx, edx
- dec ecx
- jnz ??loc_6C8E6A
-
- pop ebp
- mov esi, arg1
- xor eax, eax
- mov eax, [esi + TRANSFORM_VECTOR(0)]
- mov local1, eax
- mov ch, [esi].YSize
-
-??loc_6C8E8C:
- mov eax, [esi].StartIndex
- mov local3, eax
- mov eax, local1
- mov local2, eax
- mov cl, [esi].XSize
-
-??loc_6C8E9B:
- mov eax, local1
- mov [esi + TRANSFORM_VECTOR(0)], eax
- xor edi, edi
- mov eax, [esi].StartIndex
- mov ebx, [esi].StartOffset
- or edi, [ebx + eax*4]
- jns ??loc_6C8EE0
-
-??loc_6C8EAD:
- mov eax, [esi + TRANSFORM_VECTOR(1)]
- add local1, eax
- mov eax, [esi].StrideX
- add [esi].StartIndex, eax
- dec cl
- jnz ??loc_6C8E9B
-
- mov eax, local2
- add eax, [esi + TRANSFORM_VECTOR(2)]
- mov local1, eax
- mov eax, local3
- add eax, [esi].StrideY
- mov [esi].StartIndex, eax
- dec ch
- jnz ??loc_6C8E8C
-
- ret
-
- align 8
-
-??loc_6C8EE0:
- push esi
- push ecx
- push ebp
- xor ecx, ecx
- add edi, [esi].DataOffset
- mov cl, [esi].ZSize
- mov bx, [esi + TRANSFORM_COMPONENT(0,J)]
- shl ebx, 16
- mov ebp, [esi + TRANSFORM_VECTOR(3)]
- mov bx, [esi + TRANSFORM_COMPONENT(0,I)]
-
-??loc_6C8EF9:
- xor eax, eax
- cmp ecx, 0
- jz ??loc_6C8F36
-
- mov al, [edi]
- inc edi
- sub cl, al
-
- add ebx, [VoxelPixelDeltaTable + eax*4]
- mov ch, [edi]
- inc edi
- test ch, ch
- jz ??loc_6C8F33
-
-??loc_6C8F13:
- mov eax, ebx
- dec cl
- shr eax, 16
- mov dl, [edi]
- mov al, bh
- add edi, 2
- add ebx, ebp
- dec ch
- mov [VoxelDrawBuffer + eax], dl
- mov [VoxelDrawBuffer + eax + 1], dl
- jnz ??loc_6C8F13
-
-??loc_6C8F33:
- inc edi
- jmp ??loc_6C8EF9
-
-??loc_6C8F36:
- pop ebp
- pop ecx
- pop esi
- jmp ??loc_6C8EAD
-
-Draw_Voxel_Regular_Normals_ASM endp
-
-align 8
-
-; VOID cdecl Func(VoxelFuncArgumentStruct * arg1);
-Draw_Voxel_Reverse_Normals_ASM proc C uses esi edi ebx ecx edx \
- arg1:DWORD
-
- LOCAL local3:DWORD
- LOCAL local2:DWORD
- LOCAL local1:DWORD
-
- assume eax:ptr VoxelFuncArgumentStruct
-
- mov esi, arg1
- push ebp
- movsx ebp, WORD PTR [esi + TRANSFORM_COMPONENT(3,I)]
- movsx edx, WORD PTR [esi + TRANSFORM_COMPONENT(3,J)]
- xor ecx, ecx
- mov cl, [esi].ZSize
- mov edi, offset VoxelPixelDeltaTable
- xor eax, eax
- xor ebx, ebx
- mov esi, 4
-
-??loc_6C8F6A:
- mov [edi], ax
- add edi, 2
- add eax, ebp
- mov [edi], bx
- add edi, 2
- add ebx, edx
- dec ecx
- jnz ??loc_6C8F6A
-
- pop ebp
- mov esi, arg1
- xor eax, eax
- mov eax, [esi + TRANSFORM_VECTOR(0)]
- mov local1, eax
- mov ch, [esi].YSize
-
-??loc_6C8F8C:
- mov eax, [esi].StartIndex
- mov local3, eax
- mov eax, local1
- mov local2, eax
- mov cl, [esi].XSize
-
-??loc_6C8F9B:
- mov eax, local1
- mov [esi + TRANSFORM_VECTOR(0)], eax
- xor edi, edi
- mov eax, [esi].StartIndex
- mov ebx, [esi].EndOffset
- or edi, [ebx + eax*4]
- jns ??loc_6C8FE0
-
-??loc_6C8FAE:
- mov eax, [esi + TRANSFORM_VECTOR(1)]
- add local1, eax
- mov eax, [esi].StrideX
- add [esi].StartIndex, eax
- dec cl
- jnz ??loc_6C8F9B
-
- mov eax, local2
- add eax, [esi + TRANSFORM_VECTOR(2)]
- mov local1, eax
- mov eax, local3
- add eax, [esi].StrideY
- mov [esi].StartIndex, eax
- dec ch
- jnz ??loc_6C8F8C
-
- ret
-
- align 8
-
-??loc_6C8FE0:
- push esi
- push ecx
- push ebp
- xor ecx, ecx
- add edi, [esi].DataOffset
- mov cl, [esi].ZSize
- mov bx, [esi + TRANSFORM_COMPONENT(0,J)]
- shl ebx, 16
- mov ebp, [esi + TRANSFORM_VECTOR(3)]
- mov bx, [esi + TRANSFORM_COMPONENT(0,I)]
-
-??loc_6C8FF9:
- cmp ecx, 0
- jz ??loc_6C9035
-
- mov ch, [edi]
- dec edi
- test ch, ch
- jz ??loc_6C9024
-
-??loc_6C9005:
- mov eax, ebx
- dec cl
- dec edi
- shr eax, 16
- mov dl, [edi]
- mov al, bh
- dec edi
- add ebx, ebp
- dec ch
- mov [VoxelDrawBuffer + eax], dl
- mov [VoxelDrawBuffer + eax + 1], dl
- jnz ??loc_6C9005
-
-??loc_6C9024:
- dec edi
- xor eax, eax
- mov al, [edi]
- dec edi
- sub cl, al
-
- add ebx, [VoxelPixelDeltaTable + eax*4]
- jmp ??loc_6C8FF9
-
-??loc_6C9035:
- pop ebp
- pop ecx
- pop esi
- jmp ??loc_6C8FAE
-
-Draw_Voxel_Reverse_Normals_ASM endp
-
-align 8
-
-; VOID cdecl Func(VoxelFuncArgumentStruct * arg1);
-Draw_Voxel_Regular_Lighting_Normals_ASM proc C uses esi edi ebx ecx edx \
- arg1:DWORD
-
- LOCAL local3:DWORD
- LOCAL local2:DWORD
- LOCAL local1:DWORD
-
- assume eax:ptr VoxelFuncArgumentStruct
-
- mov esi, arg1
- push ebp
- movsx ebp, WORD PTR [esi + TRANSFORM_COMPONENT(3,I)]
- movsx edx, WORD PTR [esi + TRANSFORM_COMPONENT(3,J)]
- xor ecx, ecx
- mov cl, [esi].ZSize
- mov edi, offset VoxelPixelDeltaTable
- xor eax, eax
- xor ebx, ebx
- mov esi, 4
-
-??loc_6C906A:
- mov [edi], ax
- add edi, 2
- add eax, ebp
- mov [edi], bx
- add edi, 2
- add ebx, edx
- dec ecx
- jnz ??loc_6C906A
-
- pop ebp
- mov esi, arg1
- xor eax, eax
- mov eax, [esi + TRANSFORM_VECTOR(0)]
- mov local1, eax
- mov ch, [esi].YSize
-
-??loc_6C908C:
- mov eax, [esi].StartIndex
- mov local3, eax
- mov eax, local1
- mov local2, eax
- mov cl, [esi].XSize
-
-??loc_6C909B:
- mov eax, local1
- mov [esi + TRANSFORM_VECTOR(0)], eax
- xor edi, edi
- mov eax, [esi].StartIndex
- mov ebx, [esi].StartOffset
- or edi, [ebx + eax*4]
- jns ??loc_6C90E0
-
-??loc_6C90AD:
- mov eax, [esi + TRANSFORM_VECTOR(1)]
- add local1, eax
- mov eax, [esi].StrideX
- add [esi].StartIndex, eax
- dec cl
- jnz ??loc_6C909B
-
- mov eax, local2
- add eax, [esi + TRANSFORM_VECTOR(2)]
- mov local1, eax
- mov eax, local3
- add eax, [esi].StrideY
- mov [esi].StartIndex, eax
- dec ch
- jnz ??loc_6C908C
-
- ret
-
- align 8
-
-??loc_6C90E0:
- push esi
- push ecx
- push ebp
- xor ecx, ecx
- add edi, [esi].DataOffset
- mov cl, [esi].ZSize
- mov bx, [esi + TRANSFORM_COMPONENT(0,J)]
- shl ebx, 16
- mov ebp, [esi + TRANSFORM_VECTOR(3)]
- mov bx, [esi + TRANSFORM_COMPONENT(0,I)]
-
-??loc_6C90F9:
- xor eax, eax
- cmp ecx, 0
- jz ??loc_6C9147
-
- mov al, [edi]
- inc edi
- sub cl, al
-
- add ebx, [VoxelPixelDeltaTable + eax*4]
- mov ch, [edi]
- inc edi
- test ch, ch
- jz ??loc_6C9144
-
-??loc_6C9113:
- mov eax, ebx
- dec cl
- shr eax, 16
- xor edx, edx
- mov dl, [edi+1]
- mov al, bh
- mov dh, VoxelNormalTranslateTable[edx]
- mov dl, [edi]
- add ebx, ebp
- add edi, 2
- dec ch
- mov dl, VoxelPaletteTranslateTable[edx]
- mov [VoxelDrawBuffer + eax], dl
- mov [VoxelDrawBuffer + eax + 1], dl
- jnz ??loc_6C9113
-
-??loc_6C9144:
- inc edi
- jmp ??loc_6C90F9
-
-??loc_6C9147:
- pop ebp
- pop ecx
- pop esi
- jmp ??loc_6C90AD
-
-Draw_Voxel_Regular_Lighting_Normals_ASM endp
-
-align 8
-
-; VOID cdecl Func(VoxelFuncArgumentStruct * arg1);
-Draw_Voxel_Reverse_Lighting_Normals_ASM proc C uses esi edi ebx ecx edx \
- arg1:DWORD
-
- LOCAL local3:DWORD
- LOCAL local2:DWORD
- LOCAL local1:DWORD
-
- assume eax:ptr VoxelFuncArgumentStruct
-
- mov esi, arg1
- push ebp
- movsx ebp, WORD PTR [esi + TRANSFORM_COMPONENT(3,I)]
- movsx edx, WORD PTR [esi + TRANSFORM_COMPONENT(3,J)]
- xor ecx, ecx
- mov cl, [esi].ZSize
- mov edi, offset VoxelPixelDeltaTable
- xor eax, eax
- xor ebx, ebx
- mov esi, 4
-
-??loc_6C918A:
- mov [edi], ax
- add edi, 2
- add eax, ebp
- mov [edi], bx
- add edi, 2
- add ebx, edx
- dec ecx
- jnz ??loc_6C918A
-
- pop ebp
- mov esi, arg1
- xor eax, eax
- mov eax, [esi + TRANSFORM_VECTOR(0)]
- mov local1, eax
- mov ch, [esi].YSize
-
-??loc_6C91AC:
- mov eax, [esi].StartIndex
- mov local3, eax
- mov eax, local1
- mov local2, eax
- mov cl, [esi].XSize
-
-??loc_6C91BB:
- mov eax, local1
- mov [esi + TRANSFORM_VECTOR(0)], eax
- xor edi, edi
- mov eax, [esi].StartIndex
- mov ebx, [esi].EndOffset
- or edi, [ebx + eax*4]
- jns ??loc_6C9200
-
-??loc_6C91CE:
- mov eax, [esi + TRANSFORM_VECTOR(1)]
- add local1, eax
- mov eax, [esi].StrideX
- add [esi].StartIndex, eax
- dec cl
- jnz ??loc_6C91BB
-
- mov eax, local2
- add eax, [esi + TRANSFORM_VECTOR(2)]
- mov local1, eax
- mov eax, local3
- add eax, [esi].StrideY
- mov [esi].StartIndex, eax
- dec ch
- jnz ??loc_6C91AC
-
- ret
-
- align 8
-
-??loc_6C9200:
- push esi
- push ecx
- push ebp
- xor ecx, ecx
- add edi, [esi].DataOffset
- mov cl, [esi].ZSize
- mov bx, [esi + TRANSFORM_COMPONENT(0,J)]
- shl ebx, 16
- mov ebp, [esi + TRANSFORM_VECTOR(3)]
- mov bx, [esi + TRANSFORM_COMPONENT(0,I)]
-
-??loc_6C9219:
- cmp ecx, 0
- jz ??loc_6C9267
-
- mov ch, [edi]
- dec edi
- test ch, ch
- jz ??loc_6C9256
-
-??loc_6C9225:
- mov eax, ebx
- dec cl
- shr eax, 16
- xor edx, edx
- mov dl, [edi]
- mov al, bh
- mov dh, VoxelNormalTranslateTable[edx]
- mov dl, [edi-1]
- add ebx, ebp
- sub edi, 2
- dec ch
- mov dl, VoxelPaletteTranslateTable[edx]
- mov [VoxelDrawBuffer + eax], dl
- mov [VoxelDrawBuffer + eax + 1], dl
- jnz ??loc_6C9225
-
-??loc_6C9256:
- dec edi
- xor eax, eax
- mov al, [edi]
- dec edi
- sub cl, al
-
- add ebx, [VoxelPixelDeltaTable + eax*4]
- jmp ??loc_6C9219
-
-??loc_6C9267:
- pop ebp
- pop ecx
- pop esi
- jmp ??loc_6C91CE
-
-Draw_Voxel_Reverse_Lighting_Normals_ASM endp
-
-align 8
-
-; VOID cdecl Func(VoxelFuncArgumentStruct * arg1);
-Draw_Voxel_Regular_ASM proc C uses esi edi ebx ecx edx \
- arg1:DWORD
-
- LOCAL local3:DWORD
- LOCAL local2:DWORD
- LOCAL local1:DWORD
-
- assume eax:ptr VoxelFuncArgumentStruct
-
- mov esi, arg1
- push ebp
- movsx ebp, WORD PTR [esi + TRANSFORM_COMPONENT(3,I)]
- movsx edx, WORD PTR [esi + TRANSFORM_COMPONENT(3,J)]
- mov ecx, 0FFh
- sub cl, [esi].ZSize
- mov edi, offset VoxelPixelDeltaTable
- xor eax, eax
- xor ebx, ebx
- mov esi, 4
-
-??loc_6C92AD:
- mov [edi], ax
- add edi, 2
- add eax, ebp
- mov [edi], bx
- add edi, 2
- add ebx, edx
- dec ecx
- jnz ??loc_6C92AD
-
- pop ebp
- mov esi, arg1
- xor eax, eax
- mov eax, [esi + TRANSFORM_VECTOR(0)]
- mov local1, eax
- mov ch, [esi].YSize
-
-??loc_6C92CF:
- mov eax, [esi].StartIndex
- mov local3, eax
- mov eax, local1
- mov local2, eax
- mov cl, [esi].XSize
-
-??loc_6C92DE:
- mov eax, local1
- mov [esi + TRANSFORM_VECTOR(0)], eax
- xor edi, edi
- mov eax, [esi].StartIndex
- mov ebx, [esi].StartOffset
- or edi, [ebx + eax*4]
- jns ??loc_6C9320
-
-??loc_6C92F0:
- mov eax, [esi + TRANSFORM_VECTOR(1)]
- add local1, eax
- mov eax, [esi].StrideX
- add [esi].StartIndex, eax
- dec cl
- jnz ??loc_6C92DE
-
- mov eax, local2
- add eax, [esi + TRANSFORM_VECTOR(2)]
- mov local1, eax
- mov eax, local3
- add eax, [esi].StrideY
- mov [esi].StartIndex, eax
- dec ch
- jnz ??loc_6C92CF
-
- ret
-
- align 8
-
-??loc_6C9320:
- push esi
- push ecx
- push ebp
- xor ecx, ecx
- add edi, [esi].DataOffset
- mov cl, [esi].ZSize
- mov bx, [esi + TRANSFORM_COMPONENT(0,J)]
- shl ebx, 16
- mov ebp, [esi + TRANSFORM_VECTOR(3)]
- mov bx, [esi + TRANSFORM_COMPONENT(0,I)]
-
-??loc_6C9339:
- xor eax, eax
- cmp ecx, 0
- jz ??loc_6C936E
-
- mov al, [edi]
- inc edi
- sub cl, al
-
- add ebx, [VoxelPixelDeltaTable + eax*4]
- mov ch, [edi]
- inc edi
- test ch, ch
- jz ??loc_6C936B
-
-??loc_6C9353:
- mov eax, ebx
- dec cl
- shr eax, 16
- mov dl, [edi]
- mov al, bh
- inc edi
- add ebx, ebp
- dec ch
- mov [VoxelDrawBuffer + eax], dl
- jnz ??loc_6C9353
-
-??loc_6C936B:
- inc edi
- jmp ??loc_6C9339
-
-??loc_6C936E:
- pop ebp
- pop ecx
- pop esi
- jmp ??loc_6C92F0
-
-Draw_Voxel_Regular_ASM endp
-
-align 8
-
-; VOID cdecl Func(VoxelFuncArgumentStruct * arg1);
-Draw_Voxel_Reverse_ASM proc C uses esi edi ebx ecx edx \
- arg1:DWORD
-
- LOCAL local3:DWORD
- LOCAL local2:DWORD
- LOCAL local1:DWORD
-
- assume eax:ptr VoxelFuncArgumentStruct
-
- mov esi, arg1
- push ebp
- movsx ebp, WORD PTR [esi + TRANSFORM_COMPONENT(3,I)]
- movsx edx, WORD PTR [esi + TRANSFORM_COMPONENT(3,J)]
- mov ecx, 0FFh
- sub cl, [esi].ZSize
- mov edi, offset VoxelPixelDeltaTable
- xor eax, eax
- xor ebx, ebx
- mov esi, 4
-
-??loc_6C93AD:
- mov [edi], ax
- add edi, 2
- add eax, ebp
- mov [edi], bx
- add edi, 2
- add ebx, edx
- dec ecx
- jnz ??loc_6C93AD
-
- pop ebp
- mov esi, arg1
- xor eax, eax
- mov eax, [esi + TRANSFORM_VECTOR(0)]
- mov local1, eax
- mov ch, [esi].YSize
-
-??loc_6C93CF:
- mov eax, [esi].StartIndex
- mov local3, eax
- mov eax, local1
- mov local2, eax
- mov cl, [esi].XSize
-
-??loc_6C93DE:
- mov eax, local1
- mov [esi + TRANSFORM_VECTOR(0)], eax
- xor edi, edi
- mov eax, [esi].StartIndex
- mov ebx, [esi].EndOffset
- or edi, [ebx + eax*4]
- jns ??loc_6C9420
-
-??loc_6C93F1:
- mov eax, [esi + TRANSFORM_VECTOR(1)]
- add local1, eax
- mov eax, [esi].StrideX
- add [esi].StartIndex, eax
- dec cl
- jnz ??loc_6C93DE
-
- mov eax, local2
- add eax, [esi + TRANSFORM_VECTOR(2)]
- mov local1, eax
- mov eax, local3
- add eax, [esi].StrideY
- mov [esi].StartIndex, eax
- dec ch
- jnz ??loc_6C93CF
-
- ret
-
- align 8
-
-??loc_6C9420:
- push esi
- push ecx
- push ebp
- xor ecx, ecx
- add edi, [esi].DataOffset
- mov cl, [esi].ZSize
- mov bx, [esi + TRANSFORM_COMPONENT(0,J)]
- shl ebx, 16
- mov ebp, [esi + TRANSFORM_VECTOR(3)]
- mov bx, [esi + TRANSFORM_COMPONENT(0,I)]
-
-??loc_6C9439:
- cmp ecx, 0
- jz ??loc_6C946E
-
- mov ch, [edi]
- dec edi
- test ch, ch
- jz ??loc_6C945D
-
-??loc_6C9445:
- mov eax, ebx
- dec cl
- shr eax, 16
- mov dl, [edi]
- mov al, bh
- dec edi
- add ebx, ebp
- dec ch
- mov [VoxelDrawBuffer + eax], dl
- jnz ??loc_6C9445
-
-??loc_6C945D:
- dec edi
- xor eax, eax
- mov al, [edi]
- dec edi
- sub cl, al
-
- add ebx, [VoxelPixelDeltaTable + eax*4]
- jmp ??loc_6C9439
-
-??loc_6C946E:
- pop ebp
- pop ecx
- pop esi
- jmp ??loc_6C93F1
-
-Draw_Voxel_Reverse_ASM endp
-
-align 8
-
-; VOID cdecl Func(VoxelFuncArgumentStruct * arg1);
-Draw_Voxel_Regular_UNUSED_ASM proc C uses esi edi ebx ecx edx \
- arg1:DWORD
-
- LOCAL local3:DWORD
- LOCAL local2:DWORD
- LOCAL local1:DWORD
-
- assume esi:ptr VoxelFuncArgumentStruct
-
- mov esi, arg1
- push ebp
- movsx ebp, WORD PTR [esi + TRANSFORM_COMPONENT(3,I)]
- movsx edx, WORD PTR [esi + TRANSFORM_COMPONENT(3,J)]
- mov ecx, 0FFh
- sub cl, [esi].ZSize
- mov edi, offset VoxelPixelDeltaTable
- xor eax, eax
- xor ebx, ebx
- mov esi, 4
-
-??loc_6C94AD:
- mov [edi], ax
- add edi, 2
- add eax, ebp
- mov [edi], bx
- add edi, 2
- add ebx, edx
- dec ecx
- jnz ??loc_6C94AD
-
- pop ebp
- mov esi, arg1
- xor eax, eax
- mov eax, [esi + TRANSFORM_VECTOR(0)]
- mov local1, eax
- mov ch, [esi].YSize
-
-??loc_6C94CF:
- mov eax, [esi].StartIndex
- mov local3, eax
- mov eax, local1
- mov local2, eax
- mov cl, [esi].XSize
-
-??loc_6C94DE:
- mov eax, local1
- mov [esi + TRANSFORM_VECTOR(0)], eax
- xor edi, edi
- mov eax, [esi].StartIndex
- mov ebx, [esi].StartOffset
- or edi, [ebx + eax*4]
- jns ??loc_6C9520
-
-??loc_6C94F0:
- mov eax, [esi + TRANSFORM_VECTOR(1)]
- add local1, eax
- mov eax, [esi].StrideX
- add [esi].StartIndex, eax
- dec cl
- jnz ??loc_6C94DE
-
- mov eax, local2
- add eax, [esi + TRANSFORM_VECTOR(2)]
- mov local1, eax
- mov eax, local3
- add eax, [esi].StrideY
- mov [esi].StartIndex, eax
- dec ch
- jnz ??loc_6C94CF
-
- ret
-
- align 8
-
-??loc_6C9520:
- push esi
- push ecx
- push ebp
- xor ecx, ecx
- add edi, [esi].DataOffset
- mov cl, [esi].ZSize
- mov bx, [esi + TRANSFORM_COMPONENT(0,J)]
- shl ebx, 16
- mov ebp, [esi + TRANSFORM_VECTOR(3)]
- mov bx, [esi + TRANSFORM_COMPONENT(0,I)]
-
-??loc_6C9539:
- xor eax, eax
- cmp ecx, 0
- jz ??loc_6C9574
-
- mov al, [edi]
- inc edi
- sub cl, al
-
- add ebx, [VoxelPixelDeltaTable + eax*4]
- mov ch, [edi]
- inc edi
- test ch, ch
- jz ??loc_6C9571
-
-??loc_6C9553:
- mov eax, ebx
- dec cl
- shr eax, 16
- mov dl, [edi]
- mov al, bh
- inc edi
- add ebx, ebp
- dec ch
- mov [VoxelDrawBuffer + eax], dl
- mov [VoxelDrawBuffer + eax + 1], dl
- jnz ??loc_6C9553
-
-??loc_6C9571:
- inc edi
- jmp ??loc_6C9539
-
-??loc_6C9574:
- pop ebp
- pop ecx
- pop esi
- jmp ??loc_6C94F0
-
-Draw_Voxel_Regular_UNUSED_ASM endp
-
-align 8
-
-; VOID cdecl Func(VoxelFuncArgumentStruct * arg1);
-Draw_Voxel_Reverse_UNUSED_ASM proc C uses esi edi ebx ecx edx \
- arg1:DWORD
-
- LOCAL local3:DWORD
- LOCAL local2:DWORD
- LOCAL local1:DWORD
-
- assume esi:ptr VoxelFuncArgumentStruct
-
- mov esi, arg1
- push ebp
- movsx ebp, WORD PTR [esi + TRANSFORM_COMPONENT(3,I)]
- movsx edx, WORD PTR [esi + TRANSFORM_COMPONENT(3,J)]
- mov ecx, 0FFh
- sub cl, [esi].ZSize
- mov edi, offset VoxelPixelDeltaTable
- xor eax, eax
- xor ebx, ebx
- mov esi, 4
-
-??loc_6C95AD:
- mov [edi], ax
- add edi, 2
- add eax, ebp
- mov [edi], bx
- add edi, 2
- add ebx, edx
- dec ecx
- jnz ??loc_6C95AD
-
- pop ebp
- mov esi, arg1
- xor eax, eax
- mov eax, [esi + TRANSFORM_VECTOR(0)]
- mov local1, eax
- mov ch, [esi].YSize
-
-??loc_6C95CF:
- mov eax, [esi].StartIndex
- mov local3, eax
- mov eax, local1
- mov local2, eax
- mov cl, [esi].XSize
-
-??loc_6C95DE:
- mov eax, local1
- mov [esi + TRANSFORM_VECTOR(0)], eax
- xor edi, edi
- mov eax, [esi].StartIndex
- mov ebx, [esi].EndOffset
- or edi, [ebx + eax*4]
- jns ??loc_6C9620
-
-??loc_6C95F1:
- mov eax, [esi + TRANSFORM_VECTOR(1)]
- add local1, eax
- mov eax, [esi].StrideX
- add [esi].StartIndex, eax
- dec cl
- jnz ??loc_6C95DE
-
- mov eax, local2
- add eax, [esi + TRANSFORM_VECTOR(2)]
- mov local1, eax
- mov eax, local3
- add eax, [esi].StrideY
- mov [esi].StartIndex, eax
- dec ch
- jnz ??loc_6C95CF
-
- ret
-
- align 8
-
-??loc_6C9620:
- push esi
- push ecx
- push ebp
- xor ecx, ecx
- add edi, [esi].DataOffset
- mov cl, [esi].ZSize
- mov bx, [esi + TRANSFORM_COMPONENT(0,J)]
- shl ebx, 16
- mov ebp, [esi + TRANSFORM_VECTOR(3)]
- mov bx, [esi + TRANSFORM_COMPONENT(0,I)]
-
-??loc_6C9639:
- cmp ecx, 0
- jz ??loc_6C9674
-
- mov ch, [edi]
- dec edi
- test ch, ch
- jz ??loc_6C9663
-
-??loc_6C9645:
- mov eax, ebx
- dec cl
- shr eax, 16
- mov dl, [edi]
- mov al, bh
- dec edi
- add ebx, ebp
- dec ch
- mov [VoxelDrawBuffer + eax], dl
- mov [VoxelDrawBuffer + eax + 1], dl
- jnz ??loc_6C9645
-
-??loc_6C9663:
- dec edi
- xor eax, eax
- mov al, [edi]
- dec edi
- sub cl, al
-
- add ebx, [VoxelPixelDeltaTable + eax*4]
- jmp ??loc_6C9639
-
-??loc_6C9674:
- pop ebp
- pop ecx
- pop esi
- jmp ??loc_6C95F1
-
-Draw_Voxel_Reverse_UNUSED_ASM endp
-
-
-public _Int3
-_Int3 proc near
- ;int 3
- ret
-_Int3 endp
-
-
-;proc Stop_Execution C near
-;
-; nop
-; ret
-;
-;endp
-
-
- _TEXT$mmx ends
- _TEXT$mycode segment page public use32 'CODE' ; segment mycode page public use32 'code' ; Need stricter segment alignment
-
-public C Asm_Interpolate
-public C Asm_Interpolate_Line_Double
-public C Asm_Interpolate_Line_Interpolate
-extern C PaletteInterpolationTable:byte
-
-
-;*********************************************************************************************
-;* Asm_Interpolate -- interpolate a 320x200 buffer to a 640x400 screen *
-;* *
-;* INPUT: ptr to source buffer (320x200 image) *
-;* ptr to dest buffer (640x400) *
-;* height of source buffer *
-;* width of source buffer *
-;* width of dest buffer *
-;* *
-;* *
-;* OUTPUT: none *
-;* *
-;* Warnings: *
-;* *
-;* HISTORY: *
-;* 12/15/95 ST : Created. *
-;*===========================================================================================*
-
-Asm_Interpolate PROC near USES ebx ecx edi esi \
- \
- , src_ptr:dword \
- , dest_ptr:dword \
- , source_height:dword \
- , source_width:dword \
- , dest_width:dword
-
- LOCAL old_dest:dword
-
- pushad
-
- mov eax,[dest_ptr]
- mov [old_dest],eax
-
- mov esi,[src_ptr]
-
-??each_line_loop:
- mov ecx,[source_width]
- sub ecx,2
- shr ecx,1
- mov edi,[old_dest]
- jmp ??interpolate_loop
-
- _align 32 ;align 32
- _alignm edi
-;
-; convert 2 pixels of source into 4 pixels of destination
-; so we can write to video memory with dwords
-;
-??interpolate_loop:
- mov eax,dword ptr [esi]
- lea esi,[esi+2]
- mov edx,eax
- mov ebx,eax
- and edx,65535
- ror ebx,8
- mov bl,[edx+PaletteInterpolationTable]
- mov bh,ah
- and eax,000ffff00h
- ror ebx,8
-
-;1st 3 pixels now in ebx
-
- shr eax,8
- mov bh,[eax+PaletteInterpolationTable]
- ror ebx,16
- mov [edi],ebx
- add edi,4
-
- dec ecx
- jnz ??interpolate_loop
-
-; do the last three pixels and a blank on the end of a row
- xor eax,eax
- mov ax,word ptr [esi]
- mov [edi],al
- inc edi
- lea esi,[esi+2]
- mov al,[eax+PaletteInterpolationTable]
- mov [edi],al
- inc edi
- mov [edi],ah
- inc edi
- mov byte ptr[edi],0
-
- mov edi,[dest_width]
- add [old_dest],edi
-
- dec [source_height]
- jnz ??each_line_loop
-
- popad
- ret
-
-Asm_Interpolate endp
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Asm_Interpolate_Line_Double PROC near \
- , src_ptr:dword \
- , dest_ptr:dword \
- , source_height:dword \
- , source_width:dword \
- , dest_width:dword \
-
- LOCAL old_dest:dword
- LOCAL width_counter:dword
- LOCAL pixel_count:dword
-
- pushad
-
- mov eax,[dest_ptr]
- mov [old_dest],eax
-
- mov esi,[src_ptr]
- mov edi,[dest_ptr]
-
-??each_line_loop:
- mov [width_counter],0
- mov ecx,[source_width]
- sub ecx,2
- shr ecx,1
- mov [pixel_count],ecx
- mov ecx,offset LineBuffer
- mov edi,[old_dest]
- jmp ??interpolate_loop
- _align 8 ;align 16
- _align_
-
-; convert 2 pixels of source into 4 pixels of destination
-??interpolate_loop:
- mov eax,dword ptr [esi]
- lea esi,[esi+2]
- mov edx,eax
- mov ebx,eax
- and edx,65535
- ror ebx,8
- mov bl,[edx+PaletteInterpolationTable]
- mov bh,ah
- and eax,000ffff00h
- ror ebx,8
-
- ;1st 3 pixels now in ebx
- shr eax,8
- mov bh,[eax+PaletteInterpolationTable]
- ror ebx,16
- mov [edi],ebx
- mov [ecx],ebx
- add edi,4
- add ecx,4
-
- dec [pixel_count]
- jnz ??interpolate_loop
-
-; do the last three pixels and a blank
-
- xor eax,eax
- mov ax,word ptr[esi]
- mov [edi],al
- mov [ecx],al
- inc edi
- inc ecx
- lea esi,[esi+2]
- mov al,[eax+PaletteInterpolationTable]
- mov [edi],al
- mov [ecx],al
- inc edi
- inc ecx
- mov [edi],ah
- mov [ecx],ah
- inc edi
- inc ecx
- mov byte ptr[edi],0
- mov byte ptr[ecx],0
-
- mov edi,[dest_width]
- shr edi,1
- add [old_dest],edi
- push esi
- push edi
- mov esi,offset LineBuffer
- mov edi,[old_dest]
- mov ecx,[source_width]
- shr ecx,1
- rep movsd
- pop edi
- pop esi
- add [old_dest],edi
- mov edi,[old_dest]
-
- dec [source_height]
- jnz ??each_line_loop
-
- popad
- ret
-
-Asm_Interpolate_Line_Double endp
-
-
-
-
-
-
-
-
-
- ;ends
-
- _TEXT$mycode ends
- .data;dataseg
-
-TopLine dd 640 dup (?)
-BottomLine dd 640 dup (?)
-LineBuffer dd 640 dup (?)
-
- _TEXT$mycode segment page public use32 'CODE' ; segment mycode page public use32 'code' ; Need stricter segment alignment
-
-
-Interpolate_Single_Line proc near \
- \
- , source_ptr:dword \
- , dest_ptr:dword \
- , source_width:dword
-
- pushad
-
- mov ecx,[source_width]
- sub ecx,2
- shr ecx,1
-
- mov esi,[source_ptr]
- mov edi,[dest_ptr]
-
-??interpolate_loop:
- mov eax,dword ptr[esi]
- lea esi,[esi+2]
- mov edx,eax
- mov ebx,eax
- and edx,65535
- ror ebx,8
- mov bl,[edx+PaletteInterpolationTable]
- mov bh,ah
- and eax,000ffff00h
- ror ebx,8
-
- ;1st 3 pixels now in ebx
- shr eax,8
- mov bh,[eax+PaletteInterpolationTable]
- ror ebx,16
- mov [edi],ebx
- add edi,4
-
- dec ecx
- jnz ??interpolate_loop
-
-; do the last three pixels and a blank
-
- xor eax,eax
- mov ax,word ptr[esi]
- mov [edi],al
- inc edi
- mov al,[eax+PaletteInterpolationTable]
- mov [edi],al
- inc edi
- mov [edi],ah
- inc edi
- mov byte ptr[edi],0
-
- popad
- ret
-
-
-Interpolate_Single_Line endp
-
-
-Interpolate_Between_Lines proc near \
- \
- , source1:dword \
- , source2:dword \
- , destination:dword \
- , source_width:dword
-
- pushad
- mov esi,[source1]
- mov edi,[destination]
- mov ebx,[source2]
- xor eax,eax
- mov ecx,[source_width]
- add ecx,ecx
-
-??interpolate_each_pixel_loop:
- mov al,byte ptr[esi]
- mov ah,[ebx]
- inc esi
- inc ebx
- mov dl,[eax+PaletteInterpolationTable]
- mov [edi],dl
- inc edi
- dec ecx
- jnz ??interpolate_each_pixel_loop
-
- popad
- ret
-
-Interpolate_Between_Lines endp
-
-
-
-
-Lineswp macro
- push [next_line]
- push [last_line]
- pop [next_line]
- pop [last_line]
-endm
-
-
-Asm_Interpolate_Line_Interpolate PROC near \
- \
- \
- , src_ptr:dword \
- , dest_ptr:dword \
- , source_lines:dword \
- , source_width:dword \
- , dest_width:dword \
-
- LOCAL old_dest:dword
- LOCAL pixel_count:dword
- LOCAL next_line:dword
- LOCAL last_line:dword
-
- pushad
-
- mov eax,[dest_ptr]
- mov [old_dest],eax
-
- mov [next_line],offset TopLine
- mov [last_line],offset BottomLine
- mov ecx,[source_width]
- shr ecx,1
- mov [pixel_count],ecx
- shr [dest_width],1
-
- invoke Interpolate_Single_Line,[src_ptr],[next_line],[source_width]
- mov esi,[source_width]
- Lineswp
- add [src_ptr],esi
- dec [source_lines]
-
-
-??each_line_pair_loop:
- invoke Interpolate_Single_Line,[src_ptr],[next_line],[source_width]
- invoke Interpolate_Between_Lines,[last_line],[next_line],offset LineBuffer,[source_width]
-
- mov esi,[last_line]
- mov edi,[old_dest]
- mov ecx,[pixel_count]
- rep movsd
-
- mov edi,[old_dest]
- mov esi,offset LineBuffer
- add edi,[dest_width]
- mov ecx,[pixel_count]
- mov [old_dest],edi
- rep movsd
-
- mov edi,[old_dest]
- mov esi,[source_width]
- add edi,[dest_width]
- add [src_ptr],esi
- mov [old_dest],edi
-
- Lineswp
- dec [source_lines]
- jnz ??each_line_pair_loop
-
- invoke Interpolate_Single_Line,[src_ptr],[next_line],[source_width]
- mov esi,[next_line]
- mov edi,[old_dest]
- mov ecx,[pixel_count]
- rep movsd
-
- popad
- ret
-
-
-Asm_Interpolate_Line_Interpolate endp
-
- ;ends mycode
-
-
-
-
-public C Asm_Create_Palette_Interpolation_Table
-extern C InterpolationPalette:dword
-
- ;codeseg
-
-
-Asm_Create_Palette_Interpolation_Table proc near
-
- LOCAL palette_counter:dword
- LOCAL first_palette:dword
- LOCAL second_palette:dword
- LOCAL dest_ptr:dword
- LOCAL count:dword
- LOCAL closest_colour:dword
- LOCAL distance_of_closest:dword
-
- pushad
-
- mov [dest_ptr],0
- mov [palette_counter],256
- mov esi,[InterpolationPalette]
-
-??palette_outer_loop:
- mov edi,[InterpolationPalette]
- mov ecx,256
-
-??palette_inner_loop:
- mov bl,byte ptr[esi]
- add bl,[edi]
- shr bl,1
-
- mov bh,byte ptr[esi+1]
- add bh,[edi+1]
- shr bh,1
-
- mov dl,byte ptr[esi+2]
- add dl,[edi+2]
- shr dl,1
-
- mov [closest_colour],0
- mov [distance_of_closest],-1
-
- push edi
- push ecx
- mov edi,[InterpolationPalette]
- mov [count],0
-
-??cmp_pal_lp: xor eax,eax
- xor ecx,ecx
- mov al,[edi]
- sub al,bl
- imul al
- mov ecx,eax
- mov al,[edi+1]
- sub al,bh
- imul al
- add ecx,eax
- mov al,[edi+2]
- sub al,dl
- imul al
- add ecx,eax
-
- cmp ecx,[distance_of_closest]
- ja ??end_cmp_lp
- mov [distance_of_closest],ecx
- mov eax,[count]
- mov [closest_colour],eax
- test ecx,ecx
- jz ??got_perfect
-
-??end_cmp_lp: lea edi,[edi+3]
- inc [count]
- cmp [count],256
- jb ??cmp_pal_lp
-
-
-??got_perfect: mov edi,[dest_ptr]
- mov eax,[closest_colour]
- mov [edi+PaletteInterpolationTable],al
- inc [dest_ptr]
-
- pop ecx
- pop edi
- lea edi,[edi+3]
- dec ecx
- jnz ??palette_inner_loop
-
- lea esi,[esi+3]
- dec [palette_counter]
- jnz ??palette_outer_loop
-
- popad
- ret
-
-Asm_Create_Palette_Interpolation_Table endp
-
-
- _TEXT$mycode ends
-
-end
From 3eb428207d1163bee574fb5536cafcecbfcda154 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Wed, 2 Sep 2026 18:58:06 +0200
Subject: [PATCH 04/14] Use // prose and drop restating comments in voxlib
---
code/voxlib.cpp | 126 ++++++++----------------------------------------
1 file changed, 20 insertions(+), 106 deletions(-)
diff --git a/code/voxlib.cpp b/code/voxlib.cpp
index d143ba3b..f6186c05 100644
--- a/code/voxlib.cpp
+++ b/code/voxlib.cpp
@@ -86,7 +86,7 @@ const Vector3 *VoxelNormalTables[] =
};
-/// warning C4305: 'argument' : truncation from 'const double' to 'float'
+// warning C4305: 'argument' : truncation from 'const double' to 'float'
#pragma warning(disable : 4305)
float VoxelNormals1[][3] = {
@@ -837,17 +837,14 @@ void VoxelLibrary::Render_Object(VoxelRenderStruct & voxel, Vector3 & center)
/// The projection, stride and voxel data setup for this object.
static void __cdecl _voxel_draw_shadow(VoxelFuncArgumentStruct * state)
{
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->EndOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -860,13 +857,11 @@ static void __cdecl _voxel_draw_shadow(VoxelFuncArgumentStruct * state)
VoxelDrawBuffer[buffer_index + 1] = color_index;
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -929,33 +924,24 @@ void VoxelLibrary::Render_Shadow(VoxelShadowRenderStruct & voxel, Vector3 & cent
///
void VoxelLibrary::Compute_Bounding_Box(void)
{
- /// Compute the coordinates of the eight corners of the bounding box.
for (unsigned i = 0; i < LayerInfoCount; i++) {
LayerInfoStruct &layerinfo = LayerInfos[i];
- // +x +y -z
layerinfo.BoxCorner[VOXEL_BOUNDS_BFR] = Vector3(+layerinfo.XSize / 2.0f, +layerinfo.YSize / 2.0f, -layerinfo.ZSize / 2.0f);
- // +x -y -z
layerinfo.BoxCorner[VOXEL_BOUNDS_BBR] = Vector3(+layerinfo.XSize / 2.0f, -layerinfo.YSize / 2.0f, -layerinfo.ZSize / 2.0f);
- // -x -y -z
layerinfo.BoxCorner[VOXEL_BOUNDS_BBL] = Vector3(-layerinfo.XSize / 2.0f, -layerinfo.YSize / 2.0f, -layerinfo.ZSize / 2.0f);
- // -x +y -z
layerinfo.BoxCorner[VOXEL_BOUNDS_BFL] = Vector3(-layerinfo.XSize / 2.0f, +layerinfo.YSize / 2.0f, -layerinfo.ZSize / 2.0f);
- // +x +y +z
layerinfo.BoxCorner[VOXEL_BOUNDS_TFR] = Vector3(+layerinfo.XSize / 2.0f, +layerinfo.YSize / 2.0f, +layerinfo.ZSize / 2.0f);
- // +x -y +z
layerinfo.BoxCorner[VOXEL_BOUNDS_TBR] = Vector3(+layerinfo.XSize / 2.0f, -layerinfo.YSize / 2.0f, +layerinfo.ZSize / 2.0f);
- // -x -y +z
layerinfo.BoxCorner[VOXEL_BOUNDS_TBL] = Vector3(-layerinfo.XSize / 2.0f, -layerinfo.YSize / 2.0f, +layerinfo.ZSize / 2.0f);
- // -x +y +z
layerinfo.BoxCorner[VOXEL_BOUNDS_TFL] = Vector3(-layerinfo.XSize / 2.0f, +layerinfo.YSize / 2.0f, +layerinfo.ZSize / 2.0f);
}
}
-/// The three variants that follow build the same table and differ only in whether each
-/// store goes through the local reference or names VoxelPixelDeltaTable outright. Which
-/// variant a drawer calls is deliberate; do not merge them.
+// The three variants that follow build the same table and differ only in whether each
+// store goes through the local reference or names VoxelPixelDeltaTable outright. Which
+// variant a drawer calls is deliberate; do not merge them.
///
/// Fills in the voxel projection delta table.
@@ -1041,17 +1027,14 @@ void __cdecl Draw_Voxel_Regular_Normals(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table2(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->StartOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1061,7 +1044,7 @@ void __cdecl Draw_Voxel_Regular_Normals(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -1094,8 +1077,7 @@ void __cdecl Draw_Voxel_Regular_Normals(VoxelFuncArgumentStruct * state)
*/
ptr++;
- /// Compute buffer index and write color. A voxel covers two
- /// buffer bytes, so the colour goes down twice.
+ // A voxel covers two buffer bytes, so the colour goes down twice.
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
VoxelDrawBuffer[buffer_index] = color_index;
VoxelDrawBuffer[buffer_index + 1] = color_index;
@@ -1111,13 +1093,11 @@ void __cdecl Draw_Voxel_Regular_Normals(VoxelFuncArgumentStruct * state)
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -1140,17 +1120,14 @@ void __cdecl Draw_Voxel_Reverse_Normals(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table1(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->EndOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1160,7 +1137,7 @@ void __cdecl Draw_Voxel_Reverse_Normals(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -1182,8 +1159,7 @@ void __cdecl Draw_Voxel_Reverse_Normals(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr--;
- /// Compute buffer index and write color. A voxel covers two
- /// buffer bytes, so the colour goes down twice.
+ // A voxel covers two buffer bytes, so the colour goes down twice.
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
VoxelDrawBuffer[buffer_index] = color_index;
VoxelDrawBuffer[buffer_index + 1] = color_index;
@@ -1210,13 +1186,11 @@ void __cdecl Draw_Voxel_Reverse_Normals(VoxelFuncArgumentStruct * state)
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -1239,19 +1213,16 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table3(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -1262,7 +1233,7 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -1297,7 +1268,6 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
*/
ptr++;
- /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
VoxelDrawZBuffer[buffer_index] = (pixel_z >> 8);
@@ -1318,14 +1288,12 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
@@ -1349,19 +1317,16 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table2(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -1372,7 +1337,7 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -1400,7 +1365,6 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
value = *ptr;
ptr--;
- /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
VoxelDrawZBuffer[buffer_index] = (pixel_z >> 8);
@@ -1433,14 +1397,12 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
@@ -1464,17 +1426,14 @@ void __cdecl Draw_Voxel_Regular_Normals_Lighting(VoxelFuncArgumentStruct * state
*/
Fill_Delta_Table1(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->StartOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1484,7 +1443,7 @@ void __cdecl Draw_Voxel_Regular_Normals_Lighting(VoxelFuncArgumentStruct * state
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -1519,7 +1478,6 @@ void __cdecl Draw_Voxel_Regular_Normals_Lighting(VoxelFuncArgumentStruct * state
unsigned char table_index = VoxelNormalTranslateTable[normal_index];
ptr++;
- /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
color_index = VoxelPaletteTranslateTable[table_index][color_index];
@@ -1537,13 +1495,11 @@ void __cdecl Draw_Voxel_Regular_Normals_Lighting(VoxelFuncArgumentStruct * state
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -1566,17 +1522,14 @@ void __cdecl Draw_Voxel_Reverse_Normals_Lighting(VoxelFuncArgumentStruct * state
*/
Fill_Delta_Table2(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->EndOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1586,7 +1539,7 @@ void __cdecl Draw_Voxel_Reverse_Normals_Lighting(VoxelFuncArgumentStruct * state
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -1610,7 +1563,6 @@ void __cdecl Draw_Voxel_Reverse_Normals_Lighting(VoxelFuncArgumentStruct * state
unsigned char color_index = *ptr;
ptr--;
- /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
color_index = VoxelPaletteTranslateTable[table_index][color_index];
@@ -1639,13 +1591,11 @@ void __cdecl Draw_Voxel_Reverse_Normals_Lighting(VoxelFuncArgumentStruct * state
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -1668,19 +1618,16 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
*/
Fill_Delta_Table2(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -1691,7 +1638,7 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -1714,7 +1661,6 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
remaining -= run_length;
while (run_length) {
- /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
@@ -1761,14 +1707,12 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
@@ -1792,19 +1736,16 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
*/
Fill_Delta_Table1(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -1815,7 +1756,7 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -1826,7 +1767,6 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
remaining -= run_length;
while (run_length) {
- /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
@@ -1886,14 +1826,12 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
@@ -1916,17 +1854,14 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table1(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->StartOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1936,7 +1871,7 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -1964,8 +1899,7 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr++;
- /// Compute buffer index and write color. Unlike the shaded
- /// drawers, this one covers a single buffer byte per voxel.
+ // Unlike the shaded drawers, this one covers a single buffer byte per voxel.
VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00)] = color_index;
pixel_x += state->TransformMatrix[3].I;
@@ -1979,13 +1913,11 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -2007,17 +1939,14 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table2(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->EndOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -2027,7 +1956,7 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -2044,8 +1973,7 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr--;
- /// Compute buffer index and write color. Unlike the shaded
- /// drawers, this one covers a single buffer byte per voxel.
+ // Unlike the shaded drawers, this one covers a single buffer byte per voxel.
VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00)] = color_index;
pixel_x += state->TransformMatrix[3].I;
@@ -2070,13 +1998,11 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -2099,19 +2025,16 @@ void __cdecl Draw_Voxel_Regular_ZBuffer(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table2(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -2122,7 +2045,7 @@ void __cdecl Draw_Voxel_Regular_ZBuffer(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -2152,7 +2075,6 @@ void __cdecl Draw_Voxel_Regular_ZBuffer(VoxelFuncArgumentStruct * state)
value = *ptr;
ptr++;
- /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
VoxelDrawZBuffer[buffer_index] = (pixel_z >> 8);
@@ -2173,14 +2095,12 @@ void __cdecl Draw_Voxel_Regular_ZBuffer(VoxelFuncArgumentStruct * state)
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
@@ -2204,19 +2124,16 @@ void __cdecl Draw_Voxel_Reverse_ZBuffer(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table2(state);
- /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
- /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
- /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -2227,7 +2144,7 @@ void __cdecl Draw_Voxel_Reverse_ZBuffer(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- /// Parse voxel run-length encoded data along Z axis
+ // Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -2250,7 +2167,6 @@ void __cdecl Draw_Voxel_Reverse_ZBuffer(VoxelFuncArgumentStruct * state)
value = *ptr;
ptr--;
- /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
VoxelDrawZBuffer[buffer_index] = (pixel_z >> 8);
@@ -2283,14 +2199,12 @@ void __cdecl Draw_Voxel_Reverse_ZBuffer(VoxelFuncArgumentStruct * state)
}
}
- /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
- /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
From 5566540c99bdaa939fdba03c72837922d9e2ac6b Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Wed, 2 Sep 2026 18:59:04 +0200
Subject: [PATCH 05/14] Remove the non-MMX spot light brightening path
---
code/colorops.cpp | 109 --------------------------------
code/ovrlight.cpp | 33 ++--------
tests/colorops/coloropstest.cpp | 22 +++----
3 files changed, 14 insertions(+), 150 deletions(-)
diff --git a/code/colorops.cpp b/code/colorops.cpp
index c1648281..a5c2332d 100644
--- a/code/colorops.cpp
+++ b/code/colorops.cpp
@@ -21,24 +21,6 @@
#include "always.h"
-/*
- * Two families of routine, each replacing four assembly routines of the same names, one per
- * hicolor layout.
- *
- * Adjust_Color_* builds a palette translation table: every colour is scaled and packed into a
- * pixel. A colour whose mask entry is set is scaled by the separate red, green and blue tints;
- * one whose entry is clear is scaled by the single intensity instead.
- *
- * Brighten_Color_* and MMX_Brighten_Color_* lighten a hicolor image through a per-pixel
- * multiplier. The two reach the same shape by different routes -- the first unpacks each pixel
- * with shifts, the second reads the channels out of a caller-supplied 65536 entry table -- and
- * they are kept apart here rather than folded together, because only the caller knows whether
- * the table it built agrees with the shifts.
- *
- * The assembly had three hand-written paths through Adjust_Color, chosen at run time by the
- * MMX and CMOV flags. All three computed the same thing, so one routine replaces them.
- */
-
namespace {
/*
@@ -108,32 +90,6 @@ void Adjust_Color(unsigned char const * palette, unsigned short * translator, in
}
-/*
- * How one layout is taken apart and put back together by the brightening routines. The names
- * follow the order the assembly worked in rather than red, green, blue.
- */
-struct BrightenFormat {
- unsigned int ShiftA;
- unsigned int ShiftB;
- unsigned int MaskA;
- unsigned int MaskB;
- unsigned int ScaleShiftA;
- unsigned int ScaleShiftB;
- unsigned int DownA;
- unsigned int DownB;
- unsigned int UpA;
- unsigned int UpB;
- unsigned int ShiftC;
- unsigned int ScaleShiftC;
- unsigned int DownC;
-};
-
-BrightenFormat const _Brighten565 = {8, 3, 0xF8, 0xFC, 8, 8, 3, 2, 11, 5, 3, 8, 3};
-BrightenFormat const _Brighten655 = {8, 2, 0xFC, 0xF8, 8, 8, 2, 3, 10, 5, 3, 8, 3};
-BrightenFormat const _Brighten556 = {8, 3, 0xF8, 0xF8, 8, 8, 3, 3, 11, 6, 2, 8, 2};
-BrightenFormat const _Brighten555 = {7, 2, 0xF8, 0xF8, 8, 8, 3, 3, 10, 5, 3, 8, 3};
-
-
///
/// Adds two channel values, holding the result at 255 rather than letting it wrap.
///
@@ -147,47 +103,6 @@ inline unsigned int Add_Saturated(unsigned int left, unsigned int right)
}
-void Brighten_Color(unsigned char const * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth,
- int colorbuffwidth, int width, int height, BrightenFormat const & format)
-{
- unsigned char const * mulrow = mulbuffer;
- unsigned char * colorrow = (unsigned char *)colorbuffer;
-
- for (int y = 0; y < height; y++) {
- unsigned char const * mul = mulrow;
- unsigned short * color = (unsigned short *)colorrow;
-
- for (int x = 0; x < width; x++) {
- unsigned int const multiplier = *mul;
-
- if (multiplier != 0) {
- unsigned int const pixel = *color;
-
- unsigned int const a = (pixel >> format.ShiftA) & format.MaskA;
- unsigned int const b = (pixel >> format.ShiftB) & format.MaskB;
- unsigned int const c = (pixel << format.ShiftC) & 0xFF;
-
- unsigned int outa = Add_Saturated((a * multiplier) >> format.ScaleShiftA, a);
- unsigned int outb = Add_Saturated((b * multiplier) >> format.ScaleShiftB, b);
- unsigned int outc = Add_Saturated((c * multiplier) >> format.ScaleShiftC, c);
-
- outa = (outa >> format.DownA) << format.UpA;
- outb = (outb >> format.DownB) << format.UpB;
- outc = outc >> format.DownC;
-
- *color = (unsigned short)(outa | outb | outc);
- }
-
- mul++;
- color++;
- }
-
- mulrow += mulbuffwidth;
- colorrow += colorbuffwidth;
- }
-}
-
-
/*
* How the table-driven brightening puts a pixel back together. The channels arrive already
* separated, so only the reassembly differs between layouts.
@@ -299,30 +214,6 @@ void __cdecl Adjust_Color_655(void * palette, void * translator, int red, int gr
}
-void __cdecl Brighten_Color_565(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height)
-{
- Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, _Brighten565);
-}
-
-
-void __cdecl Brighten_Color_555(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height)
-{
- Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, _Brighten555);
-}
-
-
-void __cdecl Brighten_Color_556(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height)
-{
- Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, _Brighten556);
-}
-
-
-void __cdecl Brighten_Color_655(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height)
-{
- Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, _Brighten655);
-}
-
-
void __cdecl MMX_Brighten_Color_565(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height, int * mmxbuffer)
{
MMX_Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, mmxbuffer, _MmxBrighten565);
diff --git a/code/ovrlight.cpp b/code/ovrlight.cpp
index 13e2b8e8..dbb4a7ae 100644
--- a/code/ovrlight.cpp
+++ b/code/ovrlight.cpp
@@ -36,18 +36,13 @@ BSurface *SpotLightSurfaces[SpotLightClass::SPOTLIGHT_SURFACE_COUNT + SpotLightC
extern "C" {
/*
- * Externs to assembly routines from winasm.asm
+ * Externs to the colour routines in colorops.cpp
*/
void __cdecl Adjust_Color_565(void *pal1, void *pal2, int red, int green, int blue, int intensity, char *arg7);
void __cdecl Adjust_Color_555(void *pal1, void *pal2, int red, int green, int blue, int intensity, char *arg7);
void __cdecl Adjust_Color_556(void *pal1, void *pal2, int red, int green, int blue, int intensity, char *arg7);
void __cdecl Adjust_Color_655(void *pal1, void *pal2, int red, int green, int blue, int intensity, char *arg7);
-void __cdecl Brighten_Color_565(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int width, int height);
-void __cdecl Brighten_Color_555(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int width, int height);
-void __cdecl Brighten_Color_556(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int width, int height);
-void __cdecl Brighten_Color_655(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int width, int height);
-
void __cdecl MMX_Brighten_Color_565(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *mmx_buffer);
void __cdecl MMX_Brighten_Color_555(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *mmx_buffer);
void __cdecl MMX_Brighten_Color_556(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *mmx_buffer);
@@ -240,39 +235,23 @@ void SpotLightClass::Draw_It(void)
unsigned char *sptr_row = sptr;
unsigned short *dptr_row = dptr;
- if (SpotLightDontUseMMX != 1) {
+ if (SpotLightDontUseMMX != 1 && SpotLightMMXBuffer != NULL) {
switch (SpotLightColorMode) {
case COLORMODE_555:
- if (SpotLightMMXBuffer) {
- MMX_Brighten_Color_555(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
- } else {
- Brighten_Color_555(sptr, dptr, 256, stride, srect.Width, srect.Height);
- }
+ MMX_Brighten_Color_555(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
break;
case COLORMODE_556:
- if (SpotLightMMXBuffer) {
- MMX_Brighten_Color_556(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
- } else {
- Brighten_Color_556(sptr, dptr, 256, stride, srect.Width, srect.Height);
- }
+ MMX_Brighten_Color_556(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
break;
case COLORMODE_565:
- if (SpotLightMMXBuffer) {
- MMX_Brighten_Color_565(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
- } else {
- Brighten_Color_565(sptr, dptr, 256, stride, srect.Width, srect.Height);
- }
+ MMX_Brighten_Color_565(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
break;
case COLORMODE_655:
- if (SpotLightMMXBuffer) {
- MMX_Brighten_Color_655(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
- } else {
- Brighten_Color_655(sptr, dptr, 256, stride, srect.Width, srect.Height);
- }
+ MMX_Brighten_Color_655(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
break;
default:
diff --git a/tests/colorops/coloropstest.cpp b/tests/colorops/coloropstest.cpp
index 00d8b941..834de892 100644
--- a/tests/colorops/coloropstest.cpp
+++ b/tests/colorops/coloropstest.cpp
@@ -24,11 +24,6 @@ void __cdecl Adjust_Color_555(void *pal, void *xlat, int r, int g, int b, int i,
void __cdecl Adjust_Color_556(void *pal, void *xlat, int r, int g, int b, int i, void *mask);
void __cdecl Adjust_Color_655(void *pal, void *xlat, int r, int g, int b, int i, void *mask);
-void __cdecl Brighten_Color_565(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h);
-void __cdecl Brighten_Color_555(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h);
-void __cdecl Brighten_Color_556(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h);
-void __cdecl Brighten_Color_655(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h);
-
void __cdecl MMX_Brighten_Color_565(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
void __cdecl MMX_Brighten_Color_555(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
void __cdecl MMX_Brighten_Color_556(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
@@ -71,11 +66,9 @@ unsigned long long Hash(void const * data, int size)
typedef void (__cdecl * AdjustFunc)(void *, void *, int, int, int, int, void *);
-typedef void (__cdecl * BrightenFunc)(unsigned char *, unsigned short *, int, int, int, int);
typedef void (__cdecl * MmxBrightenFunc)(unsigned char *, unsigned short *, int, int, int, int, int *);
AdjustFunc const Adjusts[4] = {Adjust_Color_565, Adjust_Color_555, Adjust_Color_556, Adjust_Color_655};
-BrightenFunc const Brightens[4] = {Brighten_Color_565, Brighten_Color_555, Brighten_Color_556, Brighten_Color_655};
MmxBrightenFunc const MmxBrightens[4] = {MMX_Brighten_Color_565, MMX_Brighten_Color_555, MMX_Brighten_Color_556, MMX_Brighten_Color_655};
char const * const ModeNames[4] = {"565", "555", "556", "655"};
@@ -137,6 +130,11 @@ int main(void)
for (int i = 0; i < BrightenGoldenCaseCount; i++) {
BrightenGoldenCase const & test = BrightenGoldenCases[i];
+ // The non-MMX vectors record a path colorops.cpp no longer has.
+ if (test.Mmx == 0) {
+ continue;
+ }
+
Seed = test.Seed;
for (int j = 0; j < 256 * 256; j++) {
@@ -149,17 +147,13 @@ int main(void)
MmxBuffer[j] = (int)(Next_Random() & 0x00FFFFFF);
}
- if (test.Mmx != 0) {
- MmxBrightens[test.Mode](MulBuffer, ColorBuffer, 256, 512 * 2, test.Width, test.Height, MmxBuffer);
- } else {
- Brightens[test.Mode](MulBuffer, ColorBuffer, 256, 512 * 2, test.Width, test.Height);
- }
+ MmxBrightens[test.Mode](MulBuffer, ColorBuffer, 256, 512 * 2, test.Width, test.Height, MmxBuffer);
unsigned long long const hash = Hash(ColorBuffer, 512 * 512 * 2);
if (hash != test.Hash) {
- std::printf("FAILED %sBrighten_Color_%s %dx%d: expected %llu, got %llu\n",
- test.Mmx ? "MMX_" : "", ModeNames[test.Mode], test.Width, test.Height, test.Hash, hash);
+ std::printf("FAILED MMX_Brighten_Color_%s %dx%d: expected %llu, got %llu\n",
+ ModeNames[test.Mode], test.Width, test.Height, test.Hash, hash);
Failures++;
}
From 93950fc3bdb5742c32a557101647438b84835ddc Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Wed, 2 Sep 2026 18:59:44 +0200
Subject: [PATCH 06/14] Drop the MMX prefix and use sized integer types in
colorops
---
code/colorops.cpp | 161 ++++++++++++++++----------------
code/ovrlight.cpp | 16 ++--
tests/colorops/coloropstest.cpp | 20 ++--
3 files changed, 100 insertions(+), 97 deletions(-)
diff --git a/code/colorops.cpp b/code/colorops.cpp
index a5c2332d..d189646e 100644
--- a/code/colorops.cpp
+++ b/code/colorops.cpp
@@ -21,6 +21,8 @@
#include "always.h"
+#include
+
namespace {
/*
@@ -28,12 +30,12 @@ namespace {
* carry, and the shift moves them into place; red and green shift up, blue shifts down.
*/
struct PackFormat {
- unsigned int RedMask;
- unsigned int RedShift;
- unsigned int GreenMask;
- unsigned int GreenShift;
- unsigned int BlueMask;
- unsigned int BlueShift;
+ std::uint32_t RedMask;
+ std::uint32_t RedShift;
+ std::uint32_t GreenMask;
+ std::uint32_t GreenShift;
+ std::uint32_t BlueMask;
+ std::uint32_t BlueShift;
};
PackFormat const _Format565 = {0xF8, 8, 0xFC, 3, 0xF8, 3};
@@ -48,42 +50,42 @@ PackFormat const _Format655 = {0xFC, 8, 0xF8, 2, 0xF8, 3};
///
/// The channel value, 0 to 255.
/// The 16.16 fixed point factor to scale it by.
-/// unsigned int; The scaled channel, at most 255.
-inline unsigned int Scale_Channel(unsigned int channel, unsigned int scale)
+/// std::uint32_t; The scaled channel, at most 255.
+inline std::uint32_t Scale_Channel(std::uint32_t channel, std::uint32_t scale)
{
- unsigned int const scaled = (unsigned int)(channel * scale) >> 16;
+ std::uint32_t const scaled = (std::uint32_t)(channel * scale) >> 16;
return((scaled > 255) ? 255 : scaled);
}
-void Adjust_Color(unsigned char const * palette, unsigned short * translator, int red, int green, int blue,
- int intensity, unsigned char const * mask, PackFormat const & format)
+void Adjust_Color(std::uint8_t const * palette, std::uint16_t * translator, std::int32_t red, std::int32_t green,
+ std::int32_t blue, std::int32_t intensity, std::uint8_t const * mask, PackFormat const & format)
{
/*
* Index zero is the transparent one and is never scaled.
*/
translator[0] = 0;
- for (int i = 1; i < 256; i++) {
- unsigned int const r = palette[i * 3 + 0];
- unsigned int const g = palette[i * 3 + 1];
- unsigned int const b = palette[i * 3 + 2];
+ for (std::int32_t i = 1; i < 256; i++) {
+ std::uint32_t const r = palette[i * 3 + 0];
+ std::uint32_t const g = palette[i * 3 + 1];
+ std::uint32_t const b = palette[i * 3 + 2];
- unsigned int redscale = (unsigned int)intensity;
- unsigned int greenscale = (unsigned int)intensity;
- unsigned int bluescale = (unsigned int)intensity;
+ std::uint32_t redscale = (std::uint32_t)intensity;
+ std::uint32_t greenscale = (std::uint32_t)intensity;
+ std::uint32_t bluescale = (std::uint32_t)intensity;
if (mask[i] != 0) {
- redscale = (unsigned int)red;
- greenscale = (unsigned int)green;
- bluescale = (unsigned int)blue;
+ redscale = (std::uint32_t)red;
+ greenscale = (std::uint32_t)green;
+ bluescale = (std::uint32_t)blue;
}
- unsigned int const outr = Scale_Channel(r, redscale);
- unsigned int const outg = Scale_Channel(g, greenscale);
- unsigned int const outb = Scale_Channel(b, bluescale);
+ std::uint32_t const outr = Scale_Channel(r, redscale);
+ std::uint32_t const outg = Scale_Channel(g, greenscale);
+ std::uint32_t const outb = Scale_Channel(b, bluescale);
- translator[i] = (unsigned short)(((outr & format.RedMask) << format.RedShift)
+ translator[i] = (std::uint16_t)(((outr & format.RedMask) << format.RedShift)
| ((outg & format.GreenMask) << format.GreenShift)
| ((outb & format.BlueMask) >> format.BlueShift));
}
@@ -95,10 +97,10 @@ void Adjust_Color(unsigned char const * palette, unsigned short * translator, in
///
/// One value.
/// The other.
-/// unsigned int; The sum, at most 255.
-inline unsigned int Add_Saturated(unsigned int left, unsigned int right)
+/// std::uint32_t; The sum, at most 255.
+inline std::uint32_t Add_Saturated(std::uint32_t left, std::uint32_t right)
{
- unsigned int const sum = (left & 0xFF) + (right & 0xFF);
+ std::uint32_t const sum = (left & 0xFF) + (right & 0xFF);
return((sum > 255) ? 255 : sum);
}
@@ -107,12 +109,12 @@ inline unsigned int Add_Saturated(unsigned int left, unsigned int right)
* How the table-driven brightening puts a pixel back together. The channels arrive already
* separated, so only the reassembly differs between layouts.
*/
-struct MmxBrightenFormat {
- unsigned int Down;
- unsigned int BlueDown;
- unsigned int GreenUp;
- unsigned int RedUp;
- unsigned int Mask;
+struct BrightenFormat {
+ std::uint32_t Down;
+ std::uint32_t BlueDown;
+ std::uint32_t GreenUp;
+ std::uint32_t RedUp;
+ std::uint32_t Mask;
};
/*
@@ -121,59 +123,60 @@ struct MmxBrightenFormat {
* well. It is preserved because the recorded output depends on it, not because it reads like a
* mask anyone intended.
*/
-unsigned int const MMX_ALTERNATE_MARKER = 0x423A0A60;
+std::uint32_t const ALTERNATE_MARKER = 0x423A0A60;
-MmxBrightenFormat const _MmxBrighten565 = {2, 1, 5, 10, 0xF8};
-MmxBrightenFormat const _MmxBrighten555 = {3, 0, 5, 10, 0x7C};
-MmxBrightenFormat const _MmxBrighten556 = {2, 0, 6, 10, 0xF8};
-MmxBrightenFormat const _MmxBrighten655 = {2, 1, 4, 10, MMX_ALTERNATE_MARKER};
+BrightenFormat const _Brighten565 = {2, 1, 5, 10, 0xF8};
+BrightenFormat const _Brighten555 = {3, 0, 5, 10, 0x7C};
+BrightenFormat const _Brighten556 = {2, 0, 6, 10, 0xF8};
+BrightenFormat const _Brighten655 = {2, 1, 4, 10, ALTERNATE_MARKER};
-void MMX_Brighten_Color(unsigned char const * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth,
- int colorbuffwidth, int width, int height, int const * mmxbuffer, MmxBrightenFormat const & format)
+void Brighten_Color(std::uint8_t const * mulbuffer, std::uint16_t * colorbuffer, std::int32_t mulbuffwidth,
+ std::int32_t colorbuffwidth, std::int32_t width, std::int32_t height, std::int32_t const * colortable,
+ BrightenFormat const & format)
{
- unsigned char const * mulrow = mulbuffer;
- unsigned char * colorrow = (unsigned char *)colorbuffer;
+ std::uint8_t const * mulrow = mulbuffer;
+ std::uint8_t * colorrow = (std::uint8_t *)colorbuffer;
- for (int y = 0; y < height; y++) {
- unsigned char const * mul = mulrow;
- unsigned short * color = (unsigned short *)colorrow;
+ for (std::int32_t y = 0; y < height; y++) {
+ std::uint8_t const * mul = mulrow;
+ std::uint16_t * color = (std::uint16_t *)colorrow;
- for (int x = 0; x < width; x++) {
- unsigned int const multiplier = *mul;
+ for (std::int32_t x = 0; x < width; x++) {
+ std::uint32_t const multiplier = *mul;
if (multiplier != 0) {
- unsigned int const pixel = *color;
- unsigned int const entry = (unsigned int)mmxbuffer[pixel];
+ std::uint32_t const pixel = *color;
+ std::uint32_t const entry = (std::uint32_t)colortable[pixel];
/*
* The table holds the three channels one per byte, which the assembly
* widened to a word each before scaling them together.
*/
- unsigned int const blue = entry & 0xFF;
- unsigned int const green = (entry >> 8) & 0xFF;
- unsigned int const red = (entry >> 16) & 0xFF;
+ std::uint32_t const blue = entry & 0xFF;
+ std::uint32_t const green = (entry >> 8) & 0xFF;
+ std::uint32_t const red = (entry >> 16) & 0xFF;
- unsigned int const outblue = Add_Saturated((blue * multiplier) >> 8, blue) >> format.Down;
- unsigned int const outgreen = Add_Saturated((green * multiplier) >> 8, green) >> format.Down;
- unsigned int const outred = Add_Saturated((red * multiplier) >> 8, red) >> format.Down;
+ std::uint32_t const outblue = Add_Saturated((blue * multiplier) >> 8, blue) >> format.Down;
+ std::uint32_t const outgreen = Add_Saturated((green * multiplier) >> 8, green) >> format.Down;
+ std::uint32_t const outred = Add_Saturated((red * multiplier) >> 8, red) >> format.Down;
- unsigned int result = outblue >> format.BlueDown;
- unsigned int const greenpart = outgreen << format.GreenUp;
- unsigned int const redpart = outred << format.RedUp;
+ std::uint32_t result = outblue >> format.BlueDown;
+ std::uint32_t const greenpart = outgreen << format.GreenUp;
+ std::uint32_t const redpart = outred << format.RedUp;
- if (format.Mask == MMX_ALTERNATE_MARKER) {
- result |= (greenpart & MMX_ALTERNATE_MARKER);
+ if (format.Mask == ALTERNATE_MARKER) {
+ result |= (greenpart & ALTERNATE_MARKER);
} else {
result |= greenpart;
result |= (redpart & (format.Mask * 256));
}
- if (format.Mask == MMX_ALTERNATE_MARKER) {
+ if (format.Mask == ALTERNATE_MARKER) {
result |= redpart;
}
- *color = (unsigned short)result;
+ *color = (std::uint16_t)result;
}
mul++;
@@ -190,51 +193,51 @@ void MMX_Brighten_Color(unsigned char const * mulbuffer, unsigned short * colorb
extern "C" {
-void __cdecl Adjust_Color_565(void * palette, void * translator, int red, int green, int blue, int intensity, void * mask)
+void __cdecl Adjust_Color_565(void * palette, void * translator, std::int32_t red, std::int32_t green, std::int32_t blue, std::int32_t intensity, void * mask)
{
- Adjust_Color((unsigned char const *)palette, (unsigned short *)translator, red, green, blue, intensity, (unsigned char const *)mask, _Format565);
+ Adjust_Color((std::uint8_t const *)palette, (std::uint16_t *)translator, red, green, blue, intensity, (std::uint8_t const *)mask, _Format565);
}
-void __cdecl Adjust_Color_555(void * palette, void * translator, int red, int green, int blue, int intensity, void * mask)
+void __cdecl Adjust_Color_555(void * palette, void * translator, std::int32_t red, std::int32_t green, std::int32_t blue, std::int32_t intensity, void * mask)
{
- Adjust_Color((unsigned char const *)palette, (unsigned short *)translator, red, green, blue, intensity, (unsigned char const *)mask, _Format555);
+ Adjust_Color((std::uint8_t const *)palette, (std::uint16_t *)translator, red, green, blue, intensity, (std::uint8_t const *)mask, _Format555);
}
-void __cdecl Adjust_Color_556(void * palette, void * translator, int red, int green, int blue, int intensity, void * mask)
+void __cdecl Adjust_Color_556(void * palette, void * translator, std::int32_t red, std::int32_t green, std::int32_t blue, std::int32_t intensity, void * mask)
{
- Adjust_Color((unsigned char const *)palette, (unsigned short *)translator, red, green, blue, intensity, (unsigned char const *)mask, _Format556);
+ Adjust_Color((std::uint8_t const *)palette, (std::uint16_t *)translator, red, green, blue, intensity, (std::uint8_t const *)mask, _Format556);
}
-void __cdecl Adjust_Color_655(void * palette, void * translator, int red, int green, int blue, int intensity, void * mask)
+void __cdecl Adjust_Color_655(void * palette, void * translator, std::int32_t red, std::int32_t green, std::int32_t blue, std::int32_t intensity, void * mask)
{
- Adjust_Color((unsigned char const *)palette, (unsigned short *)translator, red, green, blue, intensity, (unsigned char const *)mask, _Format655);
+ Adjust_Color((std::uint8_t const *)palette, (std::uint16_t *)translator, red, green, blue, intensity, (std::uint8_t const *)mask, _Format655);
}
-void __cdecl MMX_Brighten_Color_565(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height, int * mmxbuffer)
+void __cdecl Brighten_Color_565(std::uint8_t * mulbuffer, std::uint16_t * colorbuffer, std::int32_t mulbuffwidth, std::int32_t colorbuffwidth, std::int32_t width, std::int32_t height, std::int32_t * colortable)
{
- MMX_Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, mmxbuffer, _MmxBrighten565);
+ Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, colortable, _Brighten565);
}
-void __cdecl MMX_Brighten_Color_555(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height, int * mmxbuffer)
+void __cdecl Brighten_Color_555(std::uint8_t * mulbuffer, std::uint16_t * colorbuffer, std::int32_t mulbuffwidth, std::int32_t colorbuffwidth, std::int32_t width, std::int32_t height, std::int32_t * colortable)
{
- MMX_Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, mmxbuffer, _MmxBrighten555);
+ Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, colortable, _Brighten555);
}
-void __cdecl MMX_Brighten_Color_556(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height, int * mmxbuffer)
+void __cdecl Brighten_Color_556(std::uint8_t * mulbuffer, std::uint16_t * colorbuffer, std::int32_t mulbuffwidth, std::int32_t colorbuffwidth, std::int32_t width, std::int32_t height, std::int32_t * colortable)
{
- MMX_Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, mmxbuffer, _MmxBrighten556);
+ Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, colortable, _Brighten556);
}
-void __cdecl MMX_Brighten_Color_655(unsigned char * mulbuffer, unsigned short * colorbuffer, int mulbuffwidth, int colorbuffwidth, int width, int height, int * mmxbuffer)
+void __cdecl Brighten_Color_655(std::uint8_t * mulbuffer, std::uint16_t * colorbuffer, std::int32_t mulbuffwidth, std::int32_t colorbuffwidth, std::int32_t width, std::int32_t height, std::int32_t * colortable)
{
- MMX_Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, mmxbuffer, _MmxBrighten655);
+ Brighten_Color(mulbuffer, colorbuffer, mulbuffwidth, colorbuffwidth, width, height, colortable, _Brighten655);
}
} // extern "C"
diff --git a/code/ovrlight.cpp b/code/ovrlight.cpp
index dbb4a7ae..c7fa5f14 100644
--- a/code/ovrlight.cpp
+++ b/code/ovrlight.cpp
@@ -43,10 +43,10 @@ void __cdecl Adjust_Color_555(void *pal1, void *pal2, int red, int green, int bl
void __cdecl Adjust_Color_556(void *pal1, void *pal2, int red, int green, int blue, int intensity, char *arg7);
void __cdecl Adjust_Color_655(void *pal1, void *pal2, int red, int green, int blue, int intensity, char *arg7);
-void __cdecl MMX_Brighten_Color_565(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *mmx_buffer);
-void __cdecl MMX_Brighten_Color_555(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *mmx_buffer);
-void __cdecl MMX_Brighten_Color_556(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *mmx_buffer);
-void __cdecl MMX_Brighten_Color_655(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *mmx_buffer);
+void __cdecl Brighten_Color_565(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *color_table);
+void __cdecl Brighten_Color_555(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *color_table);
+void __cdecl Brighten_Color_556(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *color_table);
+void __cdecl Brighten_Color_655(unsigned char *mul_buffer, unsigned short *color_buffer, int mulbuff_width, int color_buff_width, int dst_width, int dst_height, int *color_table);
}
@@ -239,19 +239,19 @@ void SpotLightClass::Draw_It(void)
switch (SpotLightColorMode) {
case COLORMODE_555:
- MMX_Brighten_Color_555(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
+ Brighten_Color_555(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
break;
case COLORMODE_556:
- MMX_Brighten_Color_556(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
+ Brighten_Color_556(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
break;
case COLORMODE_565:
- MMX_Brighten_Color_565(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
+ Brighten_Color_565(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
break;
case COLORMODE_655:
- MMX_Brighten_Color_655(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
+ Brighten_Color_655(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
break;
default:
diff --git a/tests/colorops/coloropstest.cpp b/tests/colorops/coloropstest.cpp
index 834de892..c4370411 100644
--- a/tests/colorops/coloropstest.cpp
+++ b/tests/colorops/coloropstest.cpp
@@ -24,10 +24,10 @@ void __cdecl Adjust_Color_555(void *pal, void *xlat, int r, int g, int b, int i,
void __cdecl Adjust_Color_556(void *pal, void *xlat, int r, int g, int b, int i, void *mask);
void __cdecl Adjust_Color_655(void *pal, void *xlat, int r, int g, int b, int i, void *mask);
-void __cdecl MMX_Brighten_Color_565(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
-void __cdecl MMX_Brighten_Color_555(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
-void __cdecl MMX_Brighten_Color_556(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
-void __cdecl MMX_Brighten_Color_655(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *mmx);
+void __cdecl Brighten_Color_565(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *table);
+void __cdecl Brighten_Color_555(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *table);
+void __cdecl Brighten_Color_556(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *table);
+void __cdecl Brighten_Color_655(unsigned char *mul, unsigned short *col, int mw, int cw, int w, int h, int *table);
}
namespace {
@@ -38,7 +38,7 @@ unsigned short Translator[256];
unsigned char MulBuffer[256 * 256];
unsigned short ColorBuffer[512 * 512];
-int MmxBuffer[65536];
+int ColorTable[65536];
unsigned int Seed = 0;
@@ -66,10 +66,10 @@ unsigned long long Hash(void const * data, int size)
typedef void (__cdecl * AdjustFunc)(void *, void *, int, int, int, int, void *);
-typedef void (__cdecl * MmxBrightenFunc)(unsigned char *, unsigned short *, int, int, int, int, int *);
+typedef void (__cdecl * BrightenFunc)(unsigned char *, unsigned short *, int, int, int, int, int *);
AdjustFunc const Adjusts[4] = {Adjust_Color_565, Adjust_Color_555, Adjust_Color_556, Adjust_Color_655};
-MmxBrightenFunc const MmxBrightens[4] = {MMX_Brighten_Color_565, MMX_Brighten_Color_555, MMX_Brighten_Color_556, MMX_Brighten_Color_655};
+BrightenFunc const Brightens[4] = {Brighten_Color_565, Brighten_Color_555, Brighten_Color_556, Brighten_Color_655};
char const * const ModeNames[4] = {"565", "555", "556", "655"};
@@ -144,15 +144,15 @@ int main(void)
ColorBuffer[j] = (unsigned short)(Next_Random() & 0xFFFF);
}
for (int j = 0; j < 65536; j++) {
- MmxBuffer[j] = (int)(Next_Random() & 0x00FFFFFF);
+ ColorTable[j] = (int)(Next_Random() & 0x00FFFFFF);
}
- MmxBrightens[test.Mode](MulBuffer, ColorBuffer, 256, 512 * 2, test.Width, test.Height, MmxBuffer);
+ Brightens[test.Mode](MulBuffer, ColorBuffer, 256, 512 * 2, test.Width, test.Height, ColorTable);
unsigned long long const hash = Hash(ColorBuffer, 512 * 512 * 2);
if (hash != test.Hash) {
- std::printf("FAILED MMX_Brighten_Color_%s %dx%d: expected %llu, got %llu\n",
+ std::printf("FAILED Brighten_Color_%s %dx%d: expected %llu, got %llu\n",
ModeNames[test.Mode], test.Width, test.Height, test.Hash, hash);
Failures++;
}
From 5421a6dd72678097d517debf971d6e60615d4c75 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Wed, 2 Sep 2026 19:04:28 +0200
Subject: [PATCH 07/14] Comment cleanup
---
code/colorops.cpp | 8 ---
code/voxlib.cpp | 126 ++++++++++++++++++++++++++++++++++++++--------
2 files changed, 106 insertions(+), 28 deletions(-)
diff --git a/code/colorops.cpp b/code/colorops.cpp
index d189646e..144c3ed1 100644
--- a/code/colorops.cpp
+++ b/code/colorops.cpp
@@ -11,14 +11,6 @@
* disclaimers apply; see LICENSE.md.
******************************************************************************/
-/****************************************************************************
-*
-* File : winasm.asm
-* Description : Palette tinting and spot light brightening for each of
-* the supported hicolor pixel layouts.
-*
-****************************************************************************/
-
#include "always.h"
#include
diff --git a/code/voxlib.cpp b/code/voxlib.cpp
index f6186c05..d143ba3b 100644
--- a/code/voxlib.cpp
+++ b/code/voxlib.cpp
@@ -86,7 +86,7 @@ const Vector3 *VoxelNormalTables[] =
};
-// warning C4305: 'argument' : truncation from 'const double' to 'float'
+/// warning C4305: 'argument' : truncation from 'const double' to 'float'
#pragma warning(disable : 4305)
float VoxelNormals1[][3] = {
@@ -837,14 +837,17 @@ void VoxelLibrary::Render_Object(VoxelRenderStruct & voxel, Vector3 & center)
/// The projection, stride and voxel data setup for this object.
static void __cdecl _voxel_draw_shadow(VoxelFuncArgumentStruct * state)
{
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->EndOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -857,11 +860,13 @@ static void __cdecl _voxel_draw_shadow(VoxelFuncArgumentStruct * state)
VoxelDrawBuffer[buffer_index + 1] = color_index;
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -924,24 +929,33 @@ void VoxelLibrary::Render_Shadow(VoxelShadowRenderStruct & voxel, Vector3 & cent
///
void VoxelLibrary::Compute_Bounding_Box(void)
{
+ /// Compute the coordinates of the eight corners of the bounding box.
for (unsigned i = 0; i < LayerInfoCount; i++) {
LayerInfoStruct &layerinfo = LayerInfos[i];
+ // +x +y -z
layerinfo.BoxCorner[VOXEL_BOUNDS_BFR] = Vector3(+layerinfo.XSize / 2.0f, +layerinfo.YSize / 2.0f, -layerinfo.ZSize / 2.0f);
+ // +x -y -z
layerinfo.BoxCorner[VOXEL_BOUNDS_BBR] = Vector3(+layerinfo.XSize / 2.0f, -layerinfo.YSize / 2.0f, -layerinfo.ZSize / 2.0f);
+ // -x -y -z
layerinfo.BoxCorner[VOXEL_BOUNDS_BBL] = Vector3(-layerinfo.XSize / 2.0f, -layerinfo.YSize / 2.0f, -layerinfo.ZSize / 2.0f);
+ // -x +y -z
layerinfo.BoxCorner[VOXEL_BOUNDS_BFL] = Vector3(-layerinfo.XSize / 2.0f, +layerinfo.YSize / 2.0f, -layerinfo.ZSize / 2.0f);
+ // +x +y +z
layerinfo.BoxCorner[VOXEL_BOUNDS_TFR] = Vector3(+layerinfo.XSize / 2.0f, +layerinfo.YSize / 2.0f, +layerinfo.ZSize / 2.0f);
+ // +x -y +z
layerinfo.BoxCorner[VOXEL_BOUNDS_TBR] = Vector3(+layerinfo.XSize / 2.0f, -layerinfo.YSize / 2.0f, +layerinfo.ZSize / 2.0f);
+ // -x -y +z
layerinfo.BoxCorner[VOXEL_BOUNDS_TBL] = Vector3(-layerinfo.XSize / 2.0f, -layerinfo.YSize / 2.0f, +layerinfo.ZSize / 2.0f);
+ // -x +y +z
layerinfo.BoxCorner[VOXEL_BOUNDS_TFL] = Vector3(-layerinfo.XSize / 2.0f, +layerinfo.YSize / 2.0f, +layerinfo.ZSize / 2.0f);
}
}
-// The three variants that follow build the same table and differ only in whether each
-// store goes through the local reference or names VoxelPixelDeltaTable outright. Which
-// variant a drawer calls is deliberate; do not merge them.
+/// The three variants that follow build the same table and differ only in whether each
+/// store goes through the local reference or names VoxelPixelDeltaTable outright. Which
+/// variant a drawer calls is deliberate; do not merge them.
///
/// Fills in the voxel projection delta table.
@@ -1027,14 +1041,17 @@ void __cdecl Draw_Voxel_Regular_Normals(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table2(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->StartOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1044,7 +1061,7 @@ void __cdecl Draw_Voxel_Regular_Normals(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -1077,7 +1094,8 @@ void __cdecl Draw_Voxel_Regular_Normals(VoxelFuncArgumentStruct * state)
*/
ptr++;
- // A voxel covers two buffer bytes, so the colour goes down twice.
+ /// Compute buffer index and write color. A voxel covers two
+ /// buffer bytes, so the colour goes down twice.
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
VoxelDrawBuffer[buffer_index] = color_index;
VoxelDrawBuffer[buffer_index + 1] = color_index;
@@ -1093,11 +1111,13 @@ void __cdecl Draw_Voxel_Regular_Normals(VoxelFuncArgumentStruct * state)
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -1120,14 +1140,17 @@ void __cdecl Draw_Voxel_Reverse_Normals(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table1(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->EndOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1137,7 +1160,7 @@ void __cdecl Draw_Voxel_Reverse_Normals(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -1159,7 +1182,8 @@ void __cdecl Draw_Voxel_Reverse_Normals(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr--;
- // A voxel covers two buffer bytes, so the colour goes down twice.
+ /// Compute buffer index and write color. A voxel covers two
+ /// buffer bytes, so the colour goes down twice.
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
VoxelDrawBuffer[buffer_index] = color_index;
VoxelDrawBuffer[buffer_index + 1] = color_index;
@@ -1186,11 +1210,13 @@ void __cdecl Draw_Voxel_Reverse_Normals(VoxelFuncArgumentStruct * state)
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -1213,16 +1239,19 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table3(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -1233,7 +1262,7 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -1268,6 +1297,7 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
*/
ptr++;
+ /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
VoxelDrawZBuffer[buffer_index] = (pixel_z >> 8);
@@ -1288,12 +1318,14 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
@@ -1317,16 +1349,19 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table2(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -1337,7 +1372,7 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -1365,6 +1400,7 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
value = *ptr;
ptr--;
+ /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
VoxelDrawZBuffer[buffer_index] = (pixel_z >> 8);
@@ -1397,12 +1433,14 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer(VoxelFuncArgumentStruct * state)
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
@@ -1426,14 +1464,17 @@ void __cdecl Draw_Voxel_Regular_Normals_Lighting(VoxelFuncArgumentStruct * state
*/
Fill_Delta_Table1(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->StartOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1443,7 +1484,7 @@ void __cdecl Draw_Voxel_Regular_Normals_Lighting(VoxelFuncArgumentStruct * state
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -1478,6 +1519,7 @@ void __cdecl Draw_Voxel_Regular_Normals_Lighting(VoxelFuncArgumentStruct * state
unsigned char table_index = VoxelNormalTranslateTable[normal_index];
ptr++;
+ /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
color_index = VoxelPaletteTranslateTable[table_index][color_index];
@@ -1495,11 +1537,13 @@ void __cdecl Draw_Voxel_Regular_Normals_Lighting(VoxelFuncArgumentStruct * state
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -1522,14 +1566,17 @@ void __cdecl Draw_Voxel_Reverse_Normals_Lighting(VoxelFuncArgumentStruct * state
*/
Fill_Delta_Table2(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->EndOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1539,7 +1586,7 @@ void __cdecl Draw_Voxel_Reverse_Normals_Lighting(VoxelFuncArgumentStruct * state
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -1563,6 +1610,7 @@ void __cdecl Draw_Voxel_Reverse_Normals_Lighting(VoxelFuncArgumentStruct * state
unsigned char color_index = *ptr;
ptr--;
+ /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
color_index = VoxelPaletteTranslateTable[table_index][color_index];
@@ -1591,11 +1639,13 @@ void __cdecl Draw_Voxel_Reverse_Normals_Lighting(VoxelFuncArgumentStruct * state
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -1618,16 +1668,19 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
*/
Fill_Delta_Table2(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -1638,7 +1691,7 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -1661,6 +1714,7 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
remaining -= run_length;
while (run_length) {
+ /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
@@ -1707,12 +1761,14 @@ void __cdecl Draw_Voxel_Regular_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
@@ -1736,16 +1792,19 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
*/
Fill_Delta_Table1(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -1756,7 +1815,7 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -1767,6 +1826,7 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
remaining -= run_length;
while (run_length) {
+ /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
@@ -1826,12 +1886,14 @@ void __cdecl Draw_Voxel_Reverse_Normals_ZBuffer_Lighting(VoxelFuncArgumentStruct
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
@@ -1854,14 +1916,17 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table1(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->StartOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1871,7 +1936,7 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -1899,7 +1964,8 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr++;
- // Unlike the shaded drawers, this one covers a single buffer byte per voxel.
+ /// Compute buffer index and write color. Unlike the shaded
+ /// drawers, this one covers a single buffer byte per voxel.
VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00)] = color_index;
pixel_x += state->TransformMatrix[3].I;
@@ -1913,11 +1979,13 @@ void __cdecl Draw_Voxel_Regular(VoxelFuncArgumentStruct * state)
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -1939,14 +2007,17 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table2(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned int data_offset = ((unsigned int *)state->EndOffset)[state->StartIndex];
unsigned short column_start_x = pixel_x;
@@ -1956,7 +2027,7 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -1973,7 +2044,8 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
unsigned char color_index = *ptr;
ptr--;
- // Unlike the shaded drawers, this one covers a single buffer byte per voxel.
+ /// Compute buffer index and write color. Unlike the shaded
+ /// drawers, this one covers a single buffer byte per voxel.
VoxelDrawBuffer[(pixel_x >> 8) | (pixel_y & 0xFF00)] = color_index;
pixel_x += state->TransformMatrix[3].I;
@@ -1998,11 +2070,13 @@ void __cdecl Draw_Voxel_Reverse(VoxelFuncArgumentStruct * state)
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
state->StartIndex = state->StrideY + base_index;
@@ -2025,16 +2099,19 @@ void __cdecl Draw_Voxel_Regular_ZBuffer(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table2(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -2045,7 +2122,7 @@ void __cdecl Draw_Voxel_Regular_ZBuffer(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
/*
@@ -2075,6 +2152,7 @@ void __cdecl Draw_Voxel_Regular_ZBuffer(VoxelFuncArgumentStruct * state)
value = *ptr;
ptr++;
+ /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
VoxelDrawZBuffer[buffer_index] = (pixel_z >> 8);
@@ -2095,12 +2173,14 @@ void __cdecl Draw_Voxel_Regular_ZBuffer(VoxelFuncArgumentStruct * state)
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
@@ -2124,16 +2204,19 @@ void __cdecl Draw_Voxel_Reverse_ZBuffer(VoxelFuncArgumentStruct * state)
*/
Fill_Delta_Table2(state);
+ /// Set starting 2D projection position
unsigned short pixel_x = state->TransformMatrix[0].I;
unsigned short pixel_y = state->TransformMatrix[0].J;
unsigned short pixel_z = state->TransformMatrix[0].K;
+ /// Iterate over voxel Y slices (rows)
for (unsigned int y = 0; y < state->YSize; y++) {
unsigned int base_index = state->StartIndex;
unsigned short row_start_x = pixel_x;
unsigned short row_start_y = pixel_y;
unsigned short row_start_z = pixel_z;
+ /// Iterate over voxel X columns (within the current Y row)
for (unsigned int x = 0; x < state->XSize; x++) {
unsigned short column_start_x = pixel_x;
unsigned short column_start_y = pixel_y;
@@ -2144,7 +2227,7 @@ void __cdecl Draw_Voxel_Reverse_ZBuffer(VoxelFuncArgumentStruct * state)
unsigned char * ptr = state->DataOffset + data_offset;
unsigned int remaining = state->ZSize;
- // Parse voxel run-length encoded data along Z axis
+ /// Parse voxel run-length encoded data along Z axis
while (remaining) {
// Byte 4 - run length(backward)
@@ -2167,6 +2250,7 @@ void __cdecl Draw_Voxel_Reverse_ZBuffer(VoxelFuncArgumentStruct * state)
value = *ptr;
ptr--;
+ /// Compute buffer index and write color
unsigned int buffer_index = (pixel_x >> 8) | (pixel_y & 0xFF00);
if ((pixel_z >> 8) > VoxelDrawZBuffer[buffer_index]) {
VoxelDrawZBuffer[buffer_index] = (pixel_z >> 8);
@@ -2199,12 +2283,14 @@ void __cdecl Draw_Voxel_Reverse_ZBuffer(VoxelFuncArgumentStruct * state)
}
}
+ /// Advance to next voxel in X direction
pixel_x = column_start_x + state->TransformMatrix[1].I;
pixel_y = column_start_y + state->TransformMatrix[1].J;
pixel_z = column_start_z + state->TransformMatrix[1].K;
state->StartIndex = state->StrideX + state->StartIndex;
}
+ /// Advance to next voxel row (Y direction)
pixel_x = row_start_x + state->TransformMatrix[2].I;
pixel_y = row_start_y + state->TransformMatrix[2].J;
pixel_z = row_start_z + state->TransformMatrix[2].K;
From 7a838559922afdfb6cfc359f212c387a1b677dac Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Thu, 3 Sep 2026 21:04:55 +0200
Subject: [PATCH 08/14] Correct the voxel drawer dispatch table comment
---
code/voxlib.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/code/voxlib.cpp b/code/voxlib.cpp
index d143ba3b..02e5a37a 100644
--- a/code/voxlib.cpp
+++ b/code/voxlib.cpp
@@ -38,8 +38,8 @@ void __cdecl Draw_Voxel_Reverse_ZBuffer(VoxelFuncArgumentStruct * state);
/*
* Indexed by the orientation's direction together with the depth buffer, lighting and normal
- * type switches, which is why the last four entries repeat the four before them: the normal
- * type does not change which drawer is wanted once lighting is off.
+ * type switches, which is why the last four entries repeat the four before them: a layer
+ * without normals has nothing to light, so lighting does not change which drawer is wanted.
*/
VoxelFuncPtr VoxelDrawFunctions[16] = {
&Draw_Voxel_Regular_Normals,
From f45fa044fdddd3974ed0b6535b04488077cb0012 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Thu, 3 Sep 2026 21:04:55 +0200
Subject: [PATCH 09/14] Fold the duplicated 655 brightening branch into one
if/else
---
code/colorops.cpp | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/code/colorops.cpp b/code/colorops.cpp
index 144c3ed1..d3c34766 100644
--- a/code/colorops.cpp
+++ b/code/colorops.cpp
@@ -159,15 +159,12 @@ void Brighten_Color(std::uint8_t const * mulbuffer, std::uint16_t * colorbuffer,
if (format.Mask == ALTERNATE_MARKER) {
result |= (greenpart & ALTERNATE_MARKER);
+ result |= redpart;
} else {
result |= greenpart;
result |= (redpart & (format.Mask * 256));
}
- if (format.Mask == ALTERNATE_MARKER) {
- result |= redpart;
- }
-
*color = (std::uint16_t)result;
}
From ec17648e01c67fd6b950193760f1925cda6e82a6 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Thu, 3 Sep 2026 21:04:56 +0200
Subject: [PATCH 10/14] Fill the normal lookup in the voxel drawing test
---
tests/voxeldraw/voxeldraw.cpp | 9 ++++
tests/voxeldraw/voxelgolden.h | 96 +++++++++++++++++------------------
2 files changed, 57 insertions(+), 48 deletions(-)
diff --git a/tests/voxeldraw/voxeldraw.cpp b/tests/voxeldraw/voxeldraw.cpp
index ea8e99f9..02b4b73e 100644
--- a/tests/voxeldraw/voxeldraw.cpp
+++ b/tests/voxeldraw/voxeldraw.cpp
@@ -173,6 +173,15 @@ void Build_Layer(unsigned int seed, int columns, int zsize, bool withnormals)
VoxelPaletteTranslateTable[i][j] = (unsigned char)(Next_Random() & 0xFF);
}
}
+
+ /*
+ * The shaded drawers pick a palette lookup row through this table, and the engine only
+ * ever puts a row number in it. Left zeroed it holds every voxel to row zero, which is
+ * the one case that would not tell a wrong lookup apart from a right one.
+ */
+ for (int i = 0; i < VOXEL_PALETTE_SIZE; i++) {
+ VoxelNormalTranslateTable[i] = (unsigned char)(Next_Random() % MAX_PALETTE_LOOKUP_ENTRIES);
+ }
}
diff --git a/tests/voxeldraw/voxelgolden.h b/tests/voxeldraw/voxelgolden.h
index af3f4d9e..41a1e1b5 100644
--- a/tests/voxeldraw/voxelgolden.h
+++ b/tests/voxeldraw/voxelgolden.h
@@ -70,54 +70,54 @@ static VoxelGoldenCase const VoxelGoldenCases[] = {
{1, 384524u, 13050037680469517880ULL},
{1, 392443u, 9010391954831812739ULL},
{1, 400362u, 6942504870830098237ULL},
- {2, 408281u, 15798523031825813403ULL},
- {2, 416200u, 4507558737198793848ULL},
- {2, 424119u, 3851442749804437763ULL},
- {2, 432038u, 930039072865289532ULL},
- {2, 439957u, 14918691864484818114ULL},
- {2, 447876u, 1900814372412917523ULL},
- {2, 455795u, 9880610814969945598ULL},
- {2, 463714u, 12235921528745917133ULL},
- {2, 471633u, 17295491051951213915ULL},
- {2, 479552u, 8208964221764546070ULL},
- {2, 487471u, 15498567043124049416ULL},
- {2, 495390u, 11601304743621742993ULL},
- {2, 503309u, 13668221661727899355ULL},
- {2, 511228u, 8056635900584925629ULL},
- {2, 519147u, 2371813117170145389ULL},
- {2, 527066u, 11631430866345469306ULL},
- {2, 534985u, 3391000685292444630ULL},
- {2, 542904u, 1748974867776887855ULL},
- {2, 550823u, 12245671744384124113ULL},
- {2, 558742u, 14093335007620427588ULL},
- {2, 566661u, 1834971198173119818ULL},
- {2, 574580u, 11489914551042742038ULL},
- {2, 582499u, 11144311815646134855ULL},
- {2, 590418u, 6836879586511554304ULL},
- {3, 598337u, 1976035810807648333ULL},
- {3, 606256u, 883352253650328485ULL},
- {3, 614175u, 15160697399241641046ULL},
- {3, 622094u, 18205160147392533888ULL},
- {3, 630013u, 14713795521886969930ULL},
- {3, 637932u, 11922145548072268503ULL},
- {3, 645851u, 7792075245259396222ULL},
- {3, 653770u, 8258093120125759069ULL},
- {3, 661689u, 18415915043351740624ULL},
- {3, 669608u, 6976820877669932813ULL},
- {3, 677527u, 11393741950045336747ULL},
- {3, 685446u, 7013445700322398ULL},
- {3, 693365u, 16301890081953396848ULL},
- {3, 701284u, 2884016264197242965ULL},
- {3, 709203u, 13109705519595437632ULL},
- {3, 717122u, 9038234598152107521ULL},
- {3, 725041u, 18120218201080976346ULL},
- {3, 732960u, 16154636395797325481ULL},
- {3, 740879u, 11006938371435845325ULL},
- {3, 748798u, 5101920956829682532ULL},
- {3, 756717u, 8748102682002764481ULL},
- {3, 764636u, 11659063084790268686ULL},
- {3, 772555u, 2655796341723522167ULL},
- {3, 780474u, 725836304033682059ULL},
+ {2, 408281u, 12117523108316906693ULL},
+ {2, 416200u, 2860773480838482206ULL},
+ {2, 424119u, 16795950920314261845ULL},
+ {2, 432038u, 16269504432944727866ULL},
+ {2, 439957u, 5759255697188250555ULL},
+ {2, 447876u, 3905793808348731109ULL},
+ {2, 455795u, 11958563865995725522ULL},
+ {2, 463714u, 7905260979237486147ULL},
+ {2, 471633u, 6596126725648556101ULL},
+ {2, 479552u, 9396465740447231265ULL},
+ {2, 487471u, 3021707311810065007ULL},
+ {2, 495390u, 12608520186210480583ULL},
+ {2, 503309u, 7168738705722408131ULL},
+ {2, 511228u, 16415847505290227908ULL},
+ {2, 519147u, 14850527117861014473ULL},
+ {2, 527066u, 2224878929674075414ULL},
+ {2, 534985u, 3526068071759325697ULL},
+ {2, 542904u, 7468107996873568077ULL},
+ {2, 550823u, 2552806796036422836ULL},
+ {2, 558742u, 10047178558152115580ULL},
+ {2, 566661u, 15609928606204843882ULL},
+ {2, 574580u, 3130933050453705124ULL},
+ {2, 582499u, 14337216876066503889ULL},
+ {2, 590418u, 10456759002404203783ULL},
+ {3, 598337u, 6351919810774857422ULL},
+ {3, 606256u, 13915808430987595008ULL},
+ {3, 614175u, 17903783046195662788ULL},
+ {3, 622094u, 4914405847178468645ULL},
+ {3, 630013u, 333711237430617735ULL},
+ {3, 637932u, 3463009737098995480ULL},
+ {3, 645851u, 18173791062746827977ULL},
+ {3, 653770u, 11159028218079293990ULL},
+ {3, 661689u, 11850058907912138592ULL},
+ {3, 669608u, 2196087987858281170ULL},
+ {3, 677527u, 17000547845918035067ULL},
+ {3, 685446u, 15682288714728306616ULL},
+ {3, 693365u, 12264100888018795473ULL},
+ {3, 701284u, 11491390033144584866ULL},
+ {3, 709203u, 11496496764390394209ULL},
+ {3, 717122u, 15575541066751950758ULL},
+ {3, 725041u, 2084845422949980028ULL},
+ {3, 732960u, 376904464664531940ULL},
+ {3, 740879u, 11946234243501752857ULL},
+ {3, 748798u, 12248491227993063803ULL},
+ {3, 756717u, 3197674996467238327ULL},
+ {3, 764636u, 6995839700847232548ULL},
+ {3, 772555u, 5309075241543235626ULL},
+ {3, 780474u, 10479909650629901107ULL},
{4, 788393u, 17319385156311552112ULL},
{4, 796312u, 16114144959221699025ULL},
{4, 804231u, 10340858242751730055ULL},
From 07d3f77720e56992ba9d8c38cf0bca80f896f908 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Thu, 3 Sep 2026 21:04:56 +0200
Subject: [PATCH 11/14] Record only the table-driven brightening vectors
---
tests/colorops/colorgolden.h | 99 +++++++++++----------------------
tests/colorops/coloropstest.cpp | 5 --
2 files changed, 33 insertions(+), 71 deletions(-)
diff --git a/tests/colorops/colorgolden.h b/tests/colorops/colorgolden.h
index fdd1a910..3e4d8a34 100644
--- a/tests/colorops/colorgolden.h
+++ b/tests/colorops/colorgolden.h
@@ -49,7 +49,6 @@ static int const AdjustGoldenCaseCount = 20;
struct BrightenGoldenCase {
int Mode;
- int Mmx;
int Width;
int Height;
unsigned int Seed;
@@ -57,70 +56,38 @@ struct BrightenGoldenCase {
};
static BrightenGoldenCase const BrightenGoldenCases[] = {
- {0, 0, 1, 1, 174490u, 9683954061780082186ULL},
- {0, 0, 2, 1, 182409u, 3585589939020540445ULL},
- {0, 0, 7, 3, 190328u, 12646124570177522196ULL},
- {0, 0, 16, 4, 198247u, 8855089449368412364ULL},
- {0, 0, 33, 9, 206166u, 4161396504343120247ULL},
- {0, 0, 64, 16, 214085u, 7491337042742393889ULL},
- {0, 0, 128, 32, 222004u, 1562462105826136594ULL},
- {0, 0, 255, 64, 229923u, 12977303894793765084ULL},
- {0, 1, 1, 1, 237842u, 2534684662198146892ULL},
- {0, 1, 2, 1, 245761u, 9679803194961330382ULL},
- {0, 1, 7, 3, 253680u, 2549577378279256583ULL},
- {0, 1, 16, 4, 261599u, 11676825973235883859ULL},
- {0, 1, 33, 9, 269518u, 13545447451985782494ULL},
- {0, 1, 64, 16, 277437u, 4102005335375077591ULL},
- {0, 1, 128, 32, 285356u, 3889344650472255677ULL},
- {0, 1, 255, 64, 293275u, 3297543697270025883ULL},
- {1, 0, 1, 1, 301194u, 13186354609198225149ULL},
- {1, 0, 2, 1, 309113u, 13814059303084228345ULL},
- {1, 0, 7, 3, 317032u, 10720627840618582556ULL},
- {1, 0, 16, 4, 324951u, 18012041115974557435ULL},
- {1, 0, 33, 9, 332870u, 7090443837710868316ULL},
- {1, 0, 64, 16, 340789u, 7935162482590007511ULL},
- {1, 0, 128, 32, 348708u, 16754602968852868577ULL},
- {1, 0, 255, 64, 356627u, 11578321534074525250ULL},
- {1, 1, 1, 1, 364546u, 10427039056597764142ULL},
- {1, 1, 2, 1, 372465u, 1748292752117078850ULL},
- {1, 1, 7, 3, 380384u, 10317547240677326599ULL},
- {1, 1, 16, 4, 388303u, 16604617947182860757ULL},
- {1, 1, 33, 9, 396222u, 1318537032546736748ULL},
- {1, 1, 64, 16, 404141u, 9229413794311576209ULL},
- {1, 1, 128, 32, 412060u, 7340557553286926667ULL},
- {1, 1, 255, 64, 419979u, 5071078941017253528ULL},
- {2, 0, 1, 1, 427898u, 10459444610915521759ULL},
- {2, 0, 2, 1, 435817u, 9809152111208362860ULL},
- {2, 0, 7, 3, 443736u, 5974842822965084410ULL},
- {2, 0, 16, 4, 451655u, 14016269938534619012ULL},
- {2, 0, 33, 9, 459574u, 11686188751530981124ULL},
- {2, 0, 64, 16, 467493u, 16824327894963774702ULL},
- {2, 0, 128, 32, 475412u, 831560034207278086ULL},
- {2, 0, 255, 64, 483331u, 10597710443419274145ULL},
- {2, 1, 1, 1, 491250u, 8479100877978498426ULL},
- {2, 1, 2, 1, 499169u, 7481949699832809259ULL},
- {2, 1, 7, 3, 507088u, 16607636731006922296ULL},
- {2, 1, 16, 4, 515007u, 6405581235097048851ULL},
- {2, 1, 33, 9, 522926u, 822099569615870640ULL},
- {2, 1, 64, 16, 530845u, 8266273084601642906ULL},
- {2, 1, 128, 32, 538764u, 8535626501608830796ULL},
- {2, 1, 255, 64, 546683u, 3737545516508015044ULL},
- {3, 0, 1, 1, 554602u, 3476118273324028887ULL},
- {3, 0, 2, 1, 562521u, 3460303321212174411ULL},
- {3, 0, 7, 3, 570440u, 5507246755901068217ULL},
- {3, 0, 16, 4, 578359u, 2761380345813287195ULL},
- {3, 0, 33, 9, 586278u, 14881774169913704698ULL},
- {3, 0, 64, 16, 594197u, 13329692175776703259ULL},
- {3, 0, 128, 32, 602116u, 16441757303667149227ULL},
- {3, 0, 255, 64, 610035u, 2060866494282096795ULL},
- {3, 1, 1, 1, 617954u, 11405787290677921704ULL},
- {3, 1, 2, 1, 625873u, 6279770659411831877ULL},
- {3, 1, 7, 3, 633792u, 10521531452208876928ULL},
- {3, 1, 16, 4, 641711u, 14797326666873277565ULL},
- {3, 1, 33, 9, 649630u, 7304885447097531915ULL},
- {3, 1, 64, 16, 657549u, 15330689263602870827ULL},
- {3, 1, 128, 32, 665468u, 10892574876935284254ULL},
- {3, 1, 255, 64, 673387u, 10579957447657776596ULL},
+ {0, 1, 1, 174490u, 8547899790972384037ULL},
+ {0, 2, 1, 182409u, 9033303418023310041ULL},
+ {0, 7, 3, 190328u, 6143991159647516153ULL},
+ {0, 16, 4, 198247u, 6630761853223497632ULL},
+ {0, 33, 9, 206166u, 622415682941848259ULL},
+ {0, 64, 16, 214085u, 14245264095721699130ULL},
+ {0, 128, 32, 222004u, 3535184424732130215ULL},
+ {0, 255, 64, 229923u, 11059887967966512383ULL},
+ {1, 1, 1, 237842u, 8952510067782069416ULL},
+ {1, 2, 1, 245761u, 18341618508397812069ULL},
+ {1, 7, 3, 253680u, 17136944462687638323ULL},
+ {1, 16, 4, 261599u, 1329247239310315574ULL},
+ {1, 33, 9, 269518u, 9097168305540845299ULL},
+ {1, 64, 16, 277437u, 9011678934784903602ULL},
+ {1, 128, 32, 285356u, 516312214522963662ULL},
+ {1, 255, 64, 293275u, 16586913180682861867ULL},
+ {2, 1, 1, 301194u, 1854941125446135212ULL},
+ {2, 2, 1, 309113u, 8166626354983351891ULL},
+ {2, 7, 3, 317032u, 3566864742387281003ULL},
+ {2, 16, 4, 324951u, 13038710579393311255ULL},
+ {2, 33, 9, 332870u, 9886918198976680958ULL},
+ {2, 64, 16, 340789u, 15331910246435108890ULL},
+ {2, 128, 32, 348708u, 9794244924404923692ULL},
+ {2, 255, 64, 356627u, 13922501480171177141ULL},
+ {3, 1, 1, 364546u, 13913672783145744802ULL},
+ {3, 2, 1, 372465u, 14314246977719733954ULL},
+ {3, 7, 3, 380384u, 11543133916950861488ULL},
+ {3, 16, 4, 388303u, 3167944849081864697ULL},
+ {3, 33, 9, 396222u, 6021446366408612999ULL},
+ {3, 64, 16, 404141u, 1062804387441418589ULL},
+ {3, 128, 32, 412060u, 3865748224324302223ULL},
+ {3, 255, 64, 419979u, 5307043396739084831ULL},
};
-static int const BrightenGoldenCaseCount = 64;
+static int const BrightenGoldenCaseCount = 32;
diff --git a/tests/colorops/coloropstest.cpp b/tests/colorops/coloropstest.cpp
index c4370411..dbba0e08 100644
--- a/tests/colorops/coloropstest.cpp
+++ b/tests/colorops/coloropstest.cpp
@@ -130,11 +130,6 @@ int main(void)
for (int i = 0; i < BrightenGoldenCaseCount; i++) {
BrightenGoldenCase const & test = BrightenGoldenCases[i];
- // The non-MMX vectors record a path colorops.cpp no longer has.
- if (test.Mmx == 0) {
- continue;
- }
-
Seed = test.Seed;
for (int j = 0; j < 256 * 256; j++) {
From 00610f2d2d61b7f4582239f1b8a4d8e49a58fba1 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Thu, 3 Sep 2026 21:04:56 +0200
Subject: [PATCH 12/14] Name the spot light colour table for what it holds
---
code/ovrlight.cpp | 33 ++++++++++++++-------------------
1 file changed, 14 insertions(+), 19 deletions(-)
diff --git a/code/ovrlight.cpp b/code/ovrlight.cpp
index c7fa5f14..6e1b6fda 100644
--- a/code/ovrlight.cpp
+++ b/code/ovrlight.cpp
@@ -18,7 +18,6 @@
#include "_tactica.h"
#include "bsurface.h"
#include "dsurface.h"
-#include "getcpu.h"
#include "globals.h"
#include "rules.h"
#include "scenario.h"
@@ -29,9 +28,8 @@
DynamicVectorClass SpotLights;
-int SpotLightDontUseMMX = false;
int SpotLightColorMode = -1;
-int *SpotLightMMXBuffer;
+int *SpotLightColorTable;
BSurface *SpotLightSurfaces[SpotLightClass::SPOTLIGHT_SURFACE_COUNT + SpotLightClass::SPOTLIGHT_EXTRA_SURFACE_COUNT];
extern "C" {
@@ -108,7 +106,7 @@ void SpotLightClass::Update_All(void)
///
/// Performs the one time initialization of the spot light system.
/// This routine builds the brightness ramp surfaces that every spot light is drawn from,
-/// and prepares the hicolor acceleration table when the processor can make use of it.
+/// and the table the brightening routines read a pixel's channels out of.
///
/// It is safe to call this routine again after the video mode changes -- the
/// artwork is built only once, but the color mode is picked up afresh each time.
@@ -155,15 +153,12 @@ void SpotLightClass::One_Time(void)
}
SpotLightColorMode = DSurface::Get_Primary_Color_Mode();
- int cpu_type = PROC_PENTIUM_PRO;
- bool mmx = false;
- Get_CPU_Type(cpu_type, mmx);
- if (mmx && SpotLightMMXBuffer == NULL) {
- SpotLightMMXBuffer = new int[65536];
+ if (SpotLightColorTable == NULL) {
+ SpotLightColorTable = new int[65536];
for (int color = 0; color < 65536; color++) {
RGBClass rgb = DSurface::Deconstruct_Hicolor_Pixel(color);
- SpotLightMMXBuffer[color] = (rgb.Get_Red() << 16) | (rgb.Get_Green() << 8) | (rgb.Get_Blue());
+ SpotLightColorTable[color] = (rgb.Get_Red() << 16) | (rgb.Get_Green() << 8) | (rgb.Get_Blue());
}
}
}
@@ -172,13 +167,13 @@ void SpotLightClass::One_Time(void)
///
/// Frees the artwork the spot lights draw with.
/// This routine is called during shutdown to release the brightness ramp surfaces and the
-/// hicolor acceleration table that One_Time built.
+/// hicolor lookup table that One_Time built.
///
void SpotLightClass::Clear_All(void)
{
- if (SpotLightMMXBuffer != NULL) {
- delete [] SpotLightMMXBuffer;
- SpotLightMMXBuffer = NULL;
+ if (SpotLightColorTable != NULL) {
+ delete [] SpotLightColorTable;
+ SpotLightColorTable = NULL;
}
for (int i = 0; i < SPOTLIGHT_SURFACE_COUNT + SPOTLIGHT_EXTRA_SURFACE_COUNT; i++) {
delete SpotLightSurfaces[i];
@@ -235,23 +230,23 @@ void SpotLightClass::Draw_It(void)
unsigned char *sptr_row = sptr;
unsigned short *dptr_row = dptr;
- if (SpotLightDontUseMMX != 1 && SpotLightMMXBuffer != NULL) {
+ if (SpotLightColorTable != NULL) {
switch (SpotLightColorMode) {
case COLORMODE_555:
- Brighten_Color_555(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
+ Brighten_Color_555(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightColorTable);
break;
case COLORMODE_556:
- Brighten_Color_556(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
+ Brighten_Color_556(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightColorTable);
break;
case COLORMODE_565:
- Brighten_Color_565(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
+ Brighten_Color_565(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightColorTable);
break;
case COLORMODE_655:
- Brighten_Color_655(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightMMXBuffer);
+ Brighten_Color_655(sptr, dptr, 256, stride, srect.Width, srect.Height, SpotLightColorTable);
break;
default:
From ec38053b8f0a72cc24a03909793a116648fb8915 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Thu, 3 Sep 2026 21:04:56 +0200
Subject: [PATCH 13/14] Remove MMX detection
---
code/getcpu.cpp | 28 ++++++-----------------
code/getcpu.h | 12 ++--------
code/init.cpp | 3 +--
code/milsectmr.cpp | 3 +--
code/scenario.cpp | 3 +--
code/syncreport.cpp | 3 +--
manual/changes/cpu-feature-detection.md | 21 ++++++++---------
tests/cpudetect/cpudetect.cpp | 30 +++++--------------------
8 files changed, 29 insertions(+), 74 deletions(-)
diff --git a/code/getcpu.cpp b/code/getcpu.cpp
index 456c1b32..6f9ac4ae 100644
--- a/code/getcpu.cpp
+++ b/code/getcpu.cpp
@@ -51,7 +51,6 @@
* *
* *
* INPUT: int - reference to cpu type *
- * bool - reference to mmx availability flag *
* char* - ptr to buffer to receive chip vendor info *
* int - length of above buffer *
* *
@@ -65,15 +64,12 @@
extern "C" {
-char UseCMOV = 1;
-char HasCMOV = 1;
-char UseMMX = 1;
char CPUType = 0;
/*
- * Filled in by Detect_MMX_Availability from CPUID leaf 0. The buffer holds the twelve
- * vendor characters, the separating space the original wrote after them, and the
- * terminator Get_CPU_Type copies up to.
+ * Filled in by CPU_Id from CPUID leaf 0. The buffer holds the twelve vendor characters,
+ * the separating space the original wrote after them, and the terminator Get_CPU_Type
+ * copies up to.
*/
char VendorID[20] = "Not available";
@@ -81,13 +77,9 @@ char VendorID[20] = "Not available";
///
-/// Records the processor family in CPUType and the vendor in VendorID, and reports MMX
-/// support. The supported minimum hardware (SSE2, so a Pentium 4 or Athlon 64 onward) always
-/// has MMX, so this always sets UseMMX and returns true rather than reading the CPUID
-/// feature bit.
+/// Records the processor family in CPUType and the vendor in VendorID.
///
-/// bool; always true on the supported minimum hardware.
-bool __cdecl Detect_MMX_Availability(void)
+void __cdecl CPU_Id(void)
{
int regs[4];
@@ -108,18 +100,12 @@ bool __cdecl Detect_MMX_Availability(void)
}
CPUType = cputype;
-
- UseMMX = 1;
- return(true);
}
-void Get_CPU_Type(int & cpu_type, bool & mmx, char * vendor_id, int vendor_id_length)
+void Get_CPU_Type(int & cpu_type, char * vendor_id, int vendor_id_length)
{
- /*
- ** Call the asm CPU detection code
- */
- mmx = Detect_MMX_Availability();
+ CPU_Id();
/*
** Return the promised results
diff --git a/code/getcpu.h b/code/getcpu.h
index 6ee8f1a2..286a276a 100644
--- a/code/getcpu.h
+++ b/code/getcpu.h
@@ -13,21 +13,13 @@
#pragma once
-void Get_CPU_Type(int & cpu_type, bool & mmx, char * vendor_id = 0, int vendor_id_length = 0);
+void Get_CPU_Type(int & cpu_type, char * vendor_id = 0, int vendor_id_length = 0);
extern "C" {
- bool __cdecl Detect_MMX_Availability(void);
+ void __cdecl CPU_Id(void);
extern char CPUType;
extern char VendorID[];
-
- /*
- * Fixed true rather than probed: the supported minimum hardware (SSE2, so a Pentium 4 or
- * Athlon 64 onward) always has CMOV and MMX.
- */
- extern char UseCMOV;
- extern char HasCMOV;
- extern char UseMMX;
}
// Processor family constants. Get_CPU_Type reports the CPUID base family through its
diff --git a/code/init.cpp b/code/init.cpp
index 810bf5c0..8ea908fa 100644
--- a/code/init.cpp
+++ b/code/init.cpp
@@ -3023,10 +3023,9 @@ BOOL CALLBACK Version_Dialog_Proc(HWND window, UINT message, WPARAM wparam, LPAR
// The braces keep the 'case' label from jumping over these initializations.
{
int cpu_type = 5;
- bool mmx = false;
char vendor[32];
vendor[0] = '\0';
- Get_CPU_Type(cpu_type, mmx, vendor, sizeof(vendor) - 1);
+ Get_CPU_Type(cpu_type, vendor, sizeof(vendor) - 1);
sprintf(buffer, "CPU vendor: %s", vendor);
ListBox_AddString(handle, buffer);
diff --git a/code/milsectmr.cpp b/code/milsectmr.cpp
index ccc29ab1..f77953f9 100644
--- a/code/milsectmr.cpp
+++ b/code/milsectmr.cpp
@@ -77,10 +77,9 @@ MillisecondTimerClass::~MillisecondTimerClass(void)
MillisecondTimerClass::operator double () const
{
static int cpu_type = -1;
- static bool has_mmx = false;
if (cpu_type == -1) {
- Get_CPU_Type(cpu_type, has_mmx, NULL, 0);
+ Get_CPU_Type(cpu_type, NULL, 0);
}
/// On extremely old CPUs (80486 and older) the TSC and rdtsc instruction don't exist.
if (Frequency != 1.0 && cpu_type > 4) {
diff --git a/code/scenario.cpp b/code/scenario.cpp
index ae7da335..a0fa8e42 100644
--- a/code/scenario.cpp
+++ b/code/scenario.cpp
@@ -3738,11 +3738,10 @@ int Adjust_To_CPU_Timing(int time)
static const double TIME_SCALE = 200;
int cpu_type;
- bool mmx;
int speed = 0;
- Get_CPU_Type(cpu_type, mmx, NULL, 0);
+ Get_CPU_Type(cpu_type, NULL, 0);
if (cpu_type > PROC_PENTIUM_PRO) {
time = (int)(time * P_SIX_TWEAK);
diff --git a/code/syncreport.cpp b/code/syncreport.cpp
index 5835cf79..626ffbf2 100644
--- a/code/syncreport.cpp
+++ b/code/syncreport.cpp
@@ -237,10 +237,9 @@ void Print_CRCs(EventClass const * events, int count, unsigned const * crc_ring,
fprintf(fp, "FPU control word: %x\n", _controlfp(0, 0));
int cpu_type = PROC_PENTIUM_PRO;
- bool mmx = false;
char vendor[32];
vendor[0] = '\0';
- Get_CPU_Type(cpu_type, mmx, vendor, sizeof(vendor) - 1);
+ Get_CPU_Type(cpu_type, vendor, sizeof(vendor) - 1);
fprintf(fp, "CPU vendor: %s\r\n", vendor);
fprintf(fp, "Frames: %d\n", Frame);
diff --git a/manual/changes/cpu-feature-detection.md b/manual/changes/cpu-feature-detection.md
index 1e3dcd5f..0cb7e00d 100644
--- a/manual/changes/cpu-feature-detection.md
+++ b/manual/changes/cpu-feature-detection.md
@@ -1,20 +1,21 @@
---
-title: Assume MMX and CMOV on the supported minimum hardware
+title: Remove MMX and CMOV detection
category: internal
release: 0.2.0
breaking: true
migration:
-- Remove any code that calls `Detect_CMOV_Availability` or `Processor`; both have been removed.
-- Treat `UseMMX`, `UseCMOV`, and `HasCMOV` as fixed-true constants rather than runtime-detected flags.
+- Remove any code that calls `Detect_MMX_Availability`, `Detect_CMOV_Availability`, or `Processor`; all have been removed.
+- Remove any use of `UseMMX`, `UseCMOV`, and `HasCMOV`; the flags have been removed along with the assembly that read them.
+- Drop the MMX flag argument from `Get_CPU_Type` calls; the parameter is gone.
targets: []
credit: [tinix0]
---
-OpenTS no longer asks the processor at startup whether it supports MMX and CMOV, and assumes
-both. This formalizes the minimum hardware OpenTS already requires — SSE2, so a Pentium 4 or
-Athlon 64 onward — which always carries MMX and CMOV.
+OpenTS no longer asks the processor whether it supports MMX or CMOV. This formalizes the
+minimum hardware OpenTS already requires — SSE2, so a Pentium 4 or Athlon 64 onward — which
+always carries both.
-A machine below that minimum was never covered by a build claim. It previously took a slower
-path through the palette-fade routines and now executes an MMX or CMOV instruction the
-processor does not have. The processor family CPUID reports is still read and returned through
-`Get_CPU_Type` and the `CPUType` global.
+A machine below that minimum was never covered by a build claim. The routines the flags
+selected between are C++ now and take one path on every processor, so neither the flags nor the
+detection that set them remain. The processor family and vendor CPUID reports are still read
+and returned through `Get_CPU_Type` and the `CPUType` and `VendorID` globals.
diff --git a/tests/cpudetect/cpudetect.cpp b/tests/cpudetect/cpudetect.cpp
index e0f219fe..c0f06013 100644
--- a/tests/cpudetect/cpudetect.cpp
+++ b/tests/cpudetect/cpudetect.cpp
@@ -9,8 +9,7 @@
// Checks the processor detection in getcpu.cpp against CPUID read directly here. The
// detection used to be hand-written assembly, so the point is to confirm the C++ reports the
-// same family and vendor the instruction does, and that MMX and CMOV are reported available
-// unconditionally, as required by the supported minimum hardware. Needs no game data.
+// same family and vendor the instruction does. Needs no game data.
#include
@@ -48,13 +47,6 @@ int Reference_Family(void)
}
-int Reference_Feature_Edx(void)
-{
- int regs[4];
- __cpuid(regs, 1);
- return(regs[3]);
-}
-
} // namespace
@@ -73,23 +65,21 @@ int main(void)
Check(maxleaf >= 1, "CPUID reports leaf 1");
int const family = Reference_Family();
- int const edx = Reference_Feature_Edx();
- std::printf("Reported vendor '%s', family %d, feature EDX %08X\n\n", vendor, family, (unsigned int)edx);
+ std::printf("Reported vendor '%s', family %d\n\n", vendor, family);
int cpu_type = -1;
- bool mmx = false;
char reported[64];
std::memset(reported, 0, sizeof(reported));
- Get_CPU_Type(cpu_type, mmx, reported, sizeof(reported) - 1);
+ Get_CPU_Type(cpu_type, reported, sizeof(reported) - 1);
Check(cpu_type == family, "Get_CPU_Type family matches CPUID");
Check(CPUType == (char)family, "CPUType global matches CPUID");
/*
- * Detect_MMX_Availability writes the twelve vendor characters and then a space, so the
- * buffer Get_CPU_Type copies out is the vendor followed by that separator.
+ * CPU_Id writes the twelve vendor characters and then a space, so the buffer
+ * Get_CPU_Type copies out is the vendor followed by that separator.
*/
char expected[16];
std::memcpy(expected, vendor, 12);
@@ -97,16 +87,6 @@ int main(void)
expected[13] = '\0';
Check(std::strcmp(reported, expected) == 0, "Vendor string matches CPUID");
- /*
- * The supported minimum hardware (SSE2, so a Pentium 4 or Athlon 64 onward) always carries
- * MMX and CMOV, so detection reports both available unconditionally rather than reading
- * the CPUID feature bits.
- */
- Check(mmx, "Get_CPU_Type reports MMX available");
- Check(UseMMX != 0, "UseMMX global reports available");
- Check(HasCMOV != 0, "HasCMOV global reports available");
- Check(UseCMOV != 0, "UseCMOV global reports available");
-
/*
* The clock accumulator only ever counts up, so a later read cannot be the smaller of
* the two once both halves are put back together.
From 63f778a34e5d8efb12cbb4459ba7bb2870564ed8 Mon Sep 17 00:00:00 2001
From: Jakub Vesely <1251980+tinix0@users.noreply.github.com>
Date: Thu, 3 Sep 2026 21:06:10 +0200
Subject: [PATCH 14/14] Register the syncrec test again
---
tests/CMakeLists.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index d7a35e0d..003214f4 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -5,5 +5,6 @@ add_subdirectory(logstress)
add_subdirectory(netpacket)
add_subdirectory(sosparity)
add_subdirectory(spawner)
+add_subdirectory(syncrec)
add_subdirectory(colorops)
add_subdirectory(voxeldraw)