From 2f01a95d866a4cca2d6a696b43d173855c9692bd Mon Sep 17 00:00:00 2001 From: Jakub Vesely <1251980+tinix0@users.noreply.github.com> Date: Fri, 28 Aug 2026 15:36:02 +0200 Subject: [PATCH 1/4] Translate the SOS ADPCM audio codecs to C++ No documentation update: tests/sosparity checks the C++ codec against golden vectors recorded from the original assembly, so documented audio behavior is unchanged. --- code/difftb.inc | 1443 -------------------------------- code/indextb.inc | 1443 -------------------------------- code/nybbtb.inc | 54 -- code/olsosdec.asm | 652 --------------- code/soscodec.asm | 622 -------------- code/soscodec.cpp | 784 +++++++++++++++++ code/soscomp.h | 1 - code/vqa_sos.asm | 1406 ------------------------------- tests/CMakeLists.txt | 1 + tests/sosparity/CMakeLists.txt | 30 + tests/sosparity/sosgolden.h | 270 ++++++ tests/sosparity/sosparity.cpp | 212 +++++ 12 files changed, 1297 insertions(+), 5621 deletions(-) delete mode 100644 code/difftb.inc delete mode 100644 code/indextb.inc delete mode 100644 code/nybbtb.inc delete mode 100644 code/olsosdec.asm delete mode 100644 code/soscodec.asm create mode 100644 code/soscodec.cpp delete mode 100644 code/vqa_sos.asm create mode 100644 tests/sosparity/CMakeLists.txt create mode 100644 tests/sosparity/sosgolden.h create mode 100644 tests/sosparity/sosparity.cpp diff --git a/code/difftb.inc b/code/difftb.inc deleted file mode 100644 index 76abbf21..00000000 --- a/code/difftb.inc +++ /dev/null @@ -1,1443 +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. -;****************************************************************************** - -;**************************************************************************** -;* dwDiffTable - ADPCM Lookup table for sample differences -;**************************************************************************** - - align 4 - -dwDiffTable DD 0 ; Index = 0 Token = 0 - DD 1 ; Index = 0 Token = 1 - DD 3 ; Index = 0 Token = 2 - DD 4 ; Index = 0 Token = 3 - DD 7 ; Index = 0 Token = 4 - DD 8 ; Index = 0 Token = 5 - DD 10 ; Index = 0 Token = 6 - DD 11 ; Index = 0 Token = 7 - DD 0 ; Index = 0 Token = 8 - DD -1 ; Index = 0 Token = 9 - DD -3 ; Index = 0 Token = 10 - DD -4 ; Index = 0 Token = 11 - DD -7 ; Index = 0 Token = 12 - DD -8 ; Index = 0 Token = 13 - DD -10 ; Index = 0 Token = 14 - DD -11 ; Index = 0 Token = 15 - DD 1 ; Index = 1 Token = 0 - DD 3 ; Index = 1 Token = 1 - DD 5 ; Index = 1 Token = 2 - DD 7 ; Index = 1 Token = 3 - DD 9 ; Index = 1 Token = 4 - DD 11 ; Index = 1 Token = 5 - DD 13 ; Index = 1 Token = 6 - DD 15 ; Index = 1 Token = 7 - DD -1 ; Index = 1 Token = 8 - DD -3 ; Index = 1 Token = 9 - DD -5 ; Index = 1 Token = 10 - DD -7 ; Index = 1 Token = 11 - DD -9 ; Index = 1 Token = 12 - DD -11 ; Index = 1 Token = 13 - DD -13 ; Index = 1 Token = 14 - DD -15 ; Index = 1 Token = 15 - DD 1 ; Index = 2 Token = 0 - DD 3 ; Index = 2 Token = 1 - DD 5 ; Index = 2 Token = 2 - DD 7 ; Index = 2 Token = 3 - DD 10 ; Index = 2 Token = 4 - DD 12 ; Index = 2 Token = 5 - DD 14 ; Index = 2 Token = 6 - DD 16 ; Index = 2 Token = 7 - DD -1 ; Index = 2 Token = 8 - DD -3 ; Index = 2 Token = 9 - DD -5 ; Index = 2 Token = 10 - DD -7 ; Index = 2 Token = 11 - DD -10 ; Index = 2 Token = 12 - DD -12 ; Index = 2 Token = 13 - DD -14 ; Index = 2 Token = 14 - DD -16 ; Index = 2 Token = 15 - DD 1 ; Index = 3 Token = 0 - DD 3 ; Index = 3 Token = 1 - DD 6 ; Index = 3 Token = 2 - DD 8 ; Index = 3 Token = 3 - DD 11 ; Index = 3 Token = 4 - DD 13 ; Index = 3 Token = 5 - DD 16 ; Index = 3 Token = 6 - DD 18 ; Index = 3 Token = 7 - DD -1 ; Index = 3 Token = 8 - DD -3 ; Index = 3 Token = 9 - DD -6 ; Index = 3 Token = 10 - DD -8 ; Index = 3 Token = 11 - DD -11 ; Index = 3 Token = 12 - DD -13 ; Index = 3 Token = 13 - DD -16 ; Index = 3 Token = 14 - DD -18 ; Index = 3 Token = 15 - DD 1 ; Index = 4 Token = 0 - DD 3 ; Index = 4 Token = 1 - DD 6 ; Index = 4 Token = 2 - DD 8 ; Index = 4 Token = 3 - DD 12 ; Index = 4 Token = 4 - DD 14 ; Index = 4 Token = 5 - DD 17 ; Index = 4 Token = 6 - DD 19 ; Index = 4 Token = 7 - DD -1 ; Index = 4 Token = 8 - DD -3 ; Index = 4 Token = 9 - DD -6 ; Index = 4 Token = 10 - DD -8 ; Index = 4 Token = 11 - DD -12 ; Index = 4 Token = 12 - DD -14 ; Index = 4 Token = 13 - DD -17 ; Index = 4 Token = 14 - DD -19 ; Index = 4 Token = 15 - DD 1 ; Index = 5 Token = 0 - DD 4 ; Index = 5 Token = 1 - DD 7 ; Index = 5 Token = 2 - DD 10 ; Index = 5 Token = 3 - DD 13 ; Index = 5 Token = 4 - DD 16 ; Index = 5 Token = 5 - DD 19 ; Index = 5 Token = 6 - DD 22 ; Index = 5 Token = 7 - DD -1 ; Index = 5 Token = 8 - DD -4 ; Index = 5 Token = 9 - DD -7 ; Index = 5 Token = 10 - DD -10 ; Index = 5 Token = 11 - DD -13 ; Index = 5 Token = 12 - DD -16 ; Index = 5 Token = 13 - DD -19 ; Index = 5 Token = 14 - DD -22 ; Index = 5 Token = 15 - DD 1 ; Index = 6 Token = 0 - DD 4 ; Index = 6 Token = 1 - DD 7 ; Index = 6 Token = 2 - DD 10 ; Index = 6 Token = 3 - DD 14 ; Index = 6 Token = 4 - DD 17 ; Index = 6 Token = 5 - DD 20 ; Index = 6 Token = 6 - DD 23 ; Index = 6 Token = 7 - DD -1 ; Index = 6 Token = 8 - DD -4 ; Index = 6 Token = 9 - DD -7 ; Index = 6 Token = 10 - DD -10 ; Index = 6 Token = 11 - DD -14 ; Index = 6 Token = 12 - DD -17 ; Index = 6 Token = 13 - DD -20 ; Index = 6 Token = 14 - DD -23 ; Index = 6 Token = 15 - DD 1 ; Index = 7 Token = 0 - DD 4 ; Index = 7 Token = 1 - DD 8 ; Index = 7 Token = 2 - DD 11 ; Index = 7 Token = 3 - DD 15 ; Index = 7 Token = 4 - DD 18 ; Index = 7 Token = 5 - DD 22 ; Index = 7 Token = 6 - DD 25 ; Index = 7 Token = 7 - DD -1 ; Index = 7 Token = 8 - DD -4 ; Index = 7 Token = 9 - DD -8 ; Index = 7 Token = 10 - DD -11 ; Index = 7 Token = 11 - DD -15 ; Index = 7 Token = 12 - DD -18 ; Index = 7 Token = 13 - DD -22 ; Index = 7 Token = 14 - DD -25 ; Index = 7 Token = 15 - DD 2 ; Index = 8 Token = 0 - DD 6 ; Index = 8 Token = 1 - DD 10 ; Index = 8 Token = 2 - DD 14 ; Index = 8 Token = 3 - DD 18 ; Index = 8 Token = 4 - DD 22 ; Index = 8 Token = 5 - DD 26 ; Index = 8 Token = 6 - DD 30 ; Index = 8 Token = 7 - DD -2 ; Index = 8 Token = 8 - DD -6 ; Index = 8 Token = 9 - DD -10 ; Index = 8 Token = 10 - DD -14 ; Index = 8 Token = 11 - DD -18 ; Index = 8 Token = 12 - DD -22 ; Index = 8 Token = 13 - DD -26 ; Index = 8 Token = 14 - DD -30 ; Index = 8 Token = 15 - DD 2 ; Index = 9 Token = 0 - DD 6 ; Index = 9 Token = 1 - DD 10 ; Index = 9 Token = 2 - DD 14 ; Index = 9 Token = 3 - DD 19 ; Index = 9 Token = 4 - DD 23 ; Index = 9 Token = 5 - DD 27 ; Index = 9 Token = 6 - DD 31 ; Index = 9 Token = 7 - DD -2 ; Index = 9 Token = 8 - DD -6 ; Index = 9 Token = 9 - DD -10 ; Index = 9 Token = 10 - DD -14 ; Index = 9 Token = 11 - DD -19 ; Index = 9 Token = 12 - DD -23 ; Index = 9 Token = 13 - DD -27 ; Index = 9 Token = 14 - DD -31 ; Index = 9 Token = 15 - DD 2 ; Index = 10 Token = 0 - DD 6 ; Index = 10 Token = 1 - DD 11 ; Index = 10 Token = 2 - DD 15 ; Index = 10 Token = 3 - DD 21 ; Index = 10 Token = 4 - DD 25 ; Index = 10 Token = 5 - DD 30 ; Index = 10 Token = 6 - DD 34 ; Index = 10 Token = 7 - DD -2 ; Index = 10 Token = 8 - DD -6 ; Index = 10 Token = 9 - DD -11 ; Index = 10 Token = 10 - DD -15 ; Index = 10 Token = 11 - DD -21 ; Index = 10 Token = 12 - DD -25 ; Index = 10 Token = 13 - DD -30 ; Index = 10 Token = 14 - DD -34 ; Index = 10 Token = 15 - DD 2 ; Index = 11 Token = 0 - DD 7 ; Index = 11 Token = 1 - DD 12 ; Index = 11 Token = 2 - DD 17 ; Index = 11 Token = 3 - DD 23 ; Index = 11 Token = 4 - DD 28 ; Index = 11 Token = 5 - DD 33 ; Index = 11 Token = 6 - DD 38 ; Index = 11 Token = 7 - DD -2 ; Index = 11 Token = 8 - DD -7 ; Index = 11 Token = 9 - DD -12 ; Index = 11 Token = 10 - DD -17 ; Index = 11 Token = 11 - DD -23 ; Index = 11 Token = 12 - DD -28 ; Index = 11 Token = 13 - DD -33 ; Index = 11 Token = 14 - DD -38 ; Index = 11 Token = 15 - DD 2 ; Index = 12 Token = 0 - DD 7 ; Index = 12 Token = 1 - DD 13 ; Index = 12 Token = 2 - DD 18 ; Index = 12 Token = 3 - DD 25 ; Index = 12 Token = 4 - DD 30 ; Index = 12 Token = 5 - DD 36 ; Index = 12 Token = 6 - DD 41 ; Index = 12 Token = 7 - DD -2 ; Index = 12 Token = 8 - DD -7 ; Index = 12 Token = 9 - DD -13 ; Index = 12 Token = 10 - DD -18 ; Index = 12 Token = 11 - DD -25 ; Index = 12 Token = 12 - DD -30 ; Index = 12 Token = 13 - DD -36 ; Index = 12 Token = 14 - DD -41 ; Index = 12 Token = 15 - DD 3 ; Index = 13 Token = 0 - DD 9 ; Index = 13 Token = 1 - DD 15 ; Index = 13 Token = 2 - DD 21 ; Index = 13 Token = 3 - DD 28 ; Index = 13 Token = 4 - DD 34 ; Index = 13 Token = 5 - DD 40 ; Index = 13 Token = 6 - DD 46 ; Index = 13 Token = 7 - DD -3 ; Index = 13 Token = 8 - DD -9 ; Index = 13 Token = 9 - DD -15 ; Index = 13 Token = 10 - DD -21 ; Index = 13 Token = 11 - DD -28 ; Index = 13 Token = 12 - DD -34 ; Index = 13 Token = 13 - DD -40 ; Index = 13 Token = 14 - DD -46 ; Index = 13 Token = 15 - DD 3 ; Index = 14 Token = 0 - DD 10 ; Index = 14 Token = 1 - DD 17 ; Index = 14 Token = 2 - DD 24 ; Index = 14 Token = 3 - DD 31 ; Index = 14 Token = 4 - DD 38 ; Index = 14 Token = 5 - DD 45 ; Index = 14 Token = 6 - DD 52 ; Index = 14 Token = 7 - DD -3 ; Index = 14 Token = 8 - DD -10 ; Index = 14 Token = 9 - DD -17 ; Index = 14 Token = 10 - DD -24 ; Index = 14 Token = 11 - DD -31 ; Index = 14 Token = 12 - DD -38 ; Index = 14 Token = 13 - DD -45 ; Index = 14 Token = 14 - DD -52 ; Index = 14 Token = 15 - DD 3 ; Index = 15 Token = 0 - DD 10 ; Index = 15 Token = 1 - DD 18 ; Index = 15 Token = 2 - DD 25 ; Index = 15 Token = 3 - DD 34 ; Index = 15 Token = 4 - DD 41 ; Index = 15 Token = 5 - DD 49 ; Index = 15 Token = 6 - DD 56 ; Index = 15 Token = 7 - DD -3 ; Index = 15 Token = 8 - DD -10 ; Index = 15 Token = 9 - DD -18 ; Index = 15 Token = 10 - DD -25 ; Index = 15 Token = 11 - DD -34 ; Index = 15 Token = 12 - DD -41 ; Index = 15 Token = 13 - DD -49 ; Index = 15 Token = 14 - DD -56 ; Index = 15 Token = 15 - DD 4 ; Index = 16 Token = 0 - DD 12 ; Index = 16 Token = 1 - DD 21 ; Index = 16 Token = 2 - DD 29 ; Index = 16 Token = 3 - DD 38 ; Index = 16 Token = 4 - DD 46 ; Index = 16 Token = 5 - DD 55 ; Index = 16 Token = 6 - DD 63 ; Index = 16 Token = 7 - DD -4 ; Index = 16 Token = 8 - DD -12 ; Index = 16 Token = 9 - DD -21 ; Index = 16 Token = 10 - DD -29 ; Index = 16 Token = 11 - DD -38 ; Index = 16 Token = 12 - DD -46 ; Index = 16 Token = 13 - DD -55 ; Index = 16 Token = 14 - DD -63 ; Index = 16 Token = 15 - DD 4 ; Index = 17 Token = 0 - DD 13 ; Index = 17 Token = 1 - DD 22 ; Index = 17 Token = 2 - DD 31 ; Index = 17 Token = 3 - DD 41 ; Index = 17 Token = 4 - DD 50 ; Index = 17 Token = 5 - DD 59 ; Index = 17 Token = 6 - DD 68 ; Index = 17 Token = 7 - DD -4 ; Index = 17 Token = 8 - DD -13 ; Index = 17 Token = 9 - DD -22 ; Index = 17 Token = 10 - DD -31 ; Index = 17 Token = 11 - DD -41 ; Index = 17 Token = 12 - DD -50 ; Index = 17 Token = 13 - DD -59 ; Index = 17 Token = 14 - DD -68 ; Index = 17 Token = 15 - DD 5 ; Index = 18 Token = 0 - DD 15 ; Index = 18 Token = 1 - DD 25 ; Index = 18 Token = 2 - DD 35 ; Index = 18 Token = 3 - DD 46 ; Index = 18 Token = 4 - DD 56 ; Index = 18 Token = 5 - DD 66 ; Index = 18 Token = 6 - DD 76 ; Index = 18 Token = 7 - DD -5 ; Index = 18 Token = 8 - DD -15 ; Index = 18 Token = 9 - DD -25 ; Index = 18 Token = 10 - DD -35 ; Index = 18 Token = 11 - DD -46 ; Index = 18 Token = 12 - DD -56 ; Index = 18 Token = 13 - DD -66 ; Index = 18 Token = 14 - DD -76 ; Index = 18 Token = 15 - DD 5 ; Index = 19 Token = 0 - DD 16 ; Index = 19 Token = 1 - DD 27 ; Index = 19 Token = 2 - DD 38 ; Index = 19 Token = 3 - DD 50 ; Index = 19 Token = 4 - DD 61 ; Index = 19 Token = 5 - DD 72 ; Index = 19 Token = 6 - DD 83 ; Index = 19 Token = 7 - DD -5 ; Index = 19 Token = 8 - DD -16 ; Index = 19 Token = 9 - DD -27 ; Index = 19 Token = 10 - DD -38 ; Index = 19 Token = 11 - DD -50 ; Index = 19 Token = 12 - DD -61 ; Index = 19 Token = 13 - DD -72 ; Index = 19 Token = 14 - DD -83 ; Index = 19 Token = 15 - DD 6 ; Index = 20 Token = 0 - DD 18 ; Index = 20 Token = 1 - DD 31 ; Index = 20 Token = 2 - DD 43 ; Index = 20 Token = 3 - DD 56 ; Index = 20 Token = 4 - DD 68 ; Index = 20 Token = 5 - DD 81 ; Index = 20 Token = 6 - DD 93 ; Index = 20 Token = 7 - DD -6 ; Index = 20 Token = 8 - DD -18 ; Index = 20 Token = 9 - DD -31 ; Index = 20 Token = 10 - DD -43 ; Index = 20 Token = 11 - DD -56 ; Index = 20 Token = 12 - DD -68 ; Index = 20 Token = 13 - DD -81 ; Index = 20 Token = 14 - DD -93 ; Index = 20 Token = 15 - DD 6 ; Index = 21 Token = 0 - DD 19 ; Index = 21 Token = 1 - DD 33 ; Index = 21 Token = 2 - DD 46 ; Index = 21 Token = 3 - DD 61 ; Index = 21 Token = 4 - DD 74 ; Index = 21 Token = 5 - DD 88 ; Index = 21 Token = 6 - DD 101 ; Index = 21 Token = 7 - DD -6 ; Index = 21 Token = 8 - DD -19 ; Index = 21 Token = 9 - DD -33 ; Index = 21 Token = 10 - DD -46 ; Index = 21 Token = 11 - DD -61 ; Index = 21 Token = 12 - DD -74 ; Index = 21 Token = 13 - DD -88 ; Index = 21 Token = 14 - DD -101 ; Index = 21 Token = 15 - DD 7 ; Index = 22 Token = 0 - DD 22 ; Index = 22 Token = 1 - DD 37 ; Index = 22 Token = 2 - DD 52 ; Index = 22 Token = 3 - DD 67 ; Index = 22 Token = 4 - DD 82 ; Index = 22 Token = 5 - DD 97 ; Index = 22 Token = 6 - DD 112 ; Index = 22 Token = 7 - DD -7 ; Index = 22 Token = 8 - DD -22 ; Index = 22 Token = 9 - DD -37 ; Index = 22 Token = 10 - DD -52 ; Index = 22 Token = 11 - DD -67 ; Index = 22 Token = 12 - DD -82 ; Index = 22 Token = 13 - DD -97 ; Index = 22 Token = 14 - DD -112 ; Index = 22 Token = 15 - DD 8 ; Index = 23 Token = 0 - DD 24 ; Index = 23 Token = 1 - DD 41 ; Index = 23 Token = 2 - DD 57 ; Index = 23 Token = 3 - DD 74 ; Index = 23 Token = 4 - DD 90 ; Index = 23 Token = 5 - DD 107 ; Index = 23 Token = 6 - DD 123 ; Index = 23 Token = 7 - DD -8 ; Index = 23 Token = 8 - DD -24 ; Index = 23 Token = 9 - DD -41 ; Index = 23 Token = 10 - DD -57 ; Index = 23 Token = 11 - DD -74 ; Index = 23 Token = 12 - DD -90 ; Index = 23 Token = 13 - DD -107 ; Index = 23 Token = 14 - DD -123 ; Index = 23 Token = 15 - DD 9 ; Index = 24 Token = 0 - DD 27 ; Index = 24 Token = 1 - DD 45 ; Index = 24 Token = 2 - DD 63 ; Index = 24 Token = 3 - DD 82 ; Index = 24 Token = 4 - DD 100 ; Index = 24 Token = 5 - DD 118 ; Index = 24 Token = 6 - DD 136 ; Index = 24 Token = 7 - DD -9 ; Index = 24 Token = 8 - DD -27 ; Index = 24 Token = 9 - DD -45 ; Index = 24 Token = 10 - DD -63 ; Index = 24 Token = 11 - DD -82 ; Index = 24 Token = 12 - DD -100 ; Index = 24 Token = 13 - DD -118 ; Index = 24 Token = 14 - DD -136 ; Index = 24 Token = 15 - DD 10 ; Index = 25 Token = 0 - DD 30 ; Index = 25 Token = 1 - DD 50 ; Index = 25 Token = 2 - DD 70 ; Index = 25 Token = 3 - DD 90 ; Index = 25 Token = 4 - DD 110 ; Index = 25 Token = 5 - DD 130 ; Index = 25 Token = 6 - DD 150 ; Index = 25 Token = 7 - DD -10 ; Index = 25 Token = 8 - DD -30 ; Index = 25 Token = 9 - DD -50 ; Index = 25 Token = 10 - DD -70 ; Index = 25 Token = 11 - DD -90 ; Index = 25 Token = 12 - DD -110 ; Index = 25 Token = 13 - DD -130 ; Index = 25 Token = 14 - DD -150 ; Index = 25 Token = 15 - DD 11 ; Index = 26 Token = 0 - DD 33 ; Index = 26 Token = 1 - DD 55 ; Index = 26 Token = 2 - DD 77 ; Index = 26 Token = 3 - DD 99 ; Index = 26 Token = 4 - DD 121 ; Index = 26 Token = 5 - DD 143 ; Index = 26 Token = 6 - DD 165 ; Index = 26 Token = 7 - DD -11 ; Index = 26 Token = 8 - DD -33 ; Index = 26 Token = 9 - DD -55 ; Index = 26 Token = 10 - DD -77 ; Index = 26 Token = 11 - DD -99 ; Index = 26 Token = 12 - DD -121 ; Index = 26 Token = 13 - DD -143 ; Index = 26 Token = 14 - DD -165 ; Index = 26 Token = 15 - DD 12 ; Index = 27 Token = 0 - DD 36 ; Index = 27 Token = 1 - DD 60 ; Index = 27 Token = 2 - DD 84 ; Index = 27 Token = 3 - DD 109 ; Index = 27 Token = 4 - DD 133 ; Index = 27 Token = 5 - DD 157 ; Index = 27 Token = 6 - DD 181 ; Index = 27 Token = 7 - DD -12 ; Index = 27 Token = 8 - DD -36 ; Index = 27 Token = 9 - DD -60 ; Index = 27 Token = 10 - DD -84 ; Index = 27 Token = 11 - DD -109 ; Index = 27 Token = 12 - DD -133 ; Index = 27 Token = 13 - DD -157 ; Index = 27 Token = 14 - DD -181 ; Index = 27 Token = 15 - DD 13 ; Index = 28 Token = 0 - DD 39 ; Index = 28 Token = 1 - DD 66 ; Index = 28 Token = 2 - DD 92 ; Index = 28 Token = 3 - DD 120 ; Index = 28 Token = 4 - DD 146 ; Index = 28 Token = 5 - DD 173 ; Index = 28 Token = 6 - DD 199 ; Index = 28 Token = 7 - DD -13 ; Index = 28 Token = 8 - DD -39 ; Index = 28 Token = 9 - DD -66 ; Index = 28 Token = 10 - DD -92 ; Index = 28 Token = 11 - DD -120 ; Index = 28 Token = 12 - DD -146 ; Index = 28 Token = 13 - DD -173 ; Index = 28 Token = 14 - DD -199 ; Index = 28 Token = 15 - DD 14 ; Index = 29 Token = 0 - DD 43 ; Index = 29 Token = 1 - DD 73 ; Index = 29 Token = 2 - DD 102 ; Index = 29 Token = 3 - DD 132 ; Index = 29 Token = 4 - DD 161 ; Index = 29 Token = 5 - DD 191 ; Index = 29 Token = 6 - DD 220 ; Index = 29 Token = 7 - DD -14 ; Index = 29 Token = 8 - DD -43 ; Index = 29 Token = 9 - DD -73 ; Index = 29 Token = 10 - DD -102 ; Index = 29 Token = 11 - DD -132 ; Index = 29 Token = 12 - DD -161 ; Index = 29 Token = 13 - DD -191 ; Index = 29 Token = 14 - DD -220 ; Index = 29 Token = 15 - DD 16 ; Index = 30 Token = 0 - DD 48 ; Index = 30 Token = 1 - DD 81 ; Index = 30 Token = 2 - DD 113 ; Index = 30 Token = 3 - DD 146 ; Index = 30 Token = 4 - DD 178 ; Index = 30 Token = 5 - DD 211 ; Index = 30 Token = 6 - DD 243 ; Index = 30 Token = 7 - DD -16 ; Index = 30 Token = 8 - DD -48 ; Index = 30 Token = 9 - DD -81 ; Index = 30 Token = 10 - DD -113 ; Index = 30 Token = 11 - DD -146 ; Index = 30 Token = 12 - DD -178 ; Index = 30 Token = 13 - DD -211 ; Index = 30 Token = 14 - DD -243 ; Index = 30 Token = 15 - DD 17 ; Index = 31 Token = 0 - DD 52 ; Index = 31 Token = 1 - DD 88 ; Index = 31 Token = 2 - DD 123 ; Index = 31 Token = 3 - DD 160 ; Index = 31 Token = 4 - DD 195 ; Index = 31 Token = 5 - DD 231 ; Index = 31 Token = 6 - DD 266 ; Index = 31 Token = 7 - DD -17 ; Index = 31 Token = 8 - DD -52 ; Index = 31 Token = 9 - DD -88 ; Index = 31 Token = 10 - DD -123 ; Index = 31 Token = 11 - DD -160 ; Index = 31 Token = 12 - DD -195 ; Index = 31 Token = 13 - DD -231 ; Index = 31 Token = 14 - DD -266 ; Index = 31 Token = 15 - DD 19 ; Index = 32 Token = 0 - DD 58 ; Index = 32 Token = 1 - DD 97 ; Index = 32 Token = 2 - DD 136 ; Index = 32 Token = 3 - DD 176 ; Index = 32 Token = 4 - DD 215 ; Index = 32 Token = 5 - DD 254 ; Index = 32 Token = 6 - DD 293 ; Index = 32 Token = 7 - DD -19 ; Index = 32 Token = 8 - DD -58 ; Index = 32 Token = 9 - DD -97 ; Index = 32 Token = 10 - DD -136 ; Index = 32 Token = 11 - DD -176 ; Index = 32 Token = 12 - DD -215 ; Index = 32 Token = 13 - DD -254 ; Index = 32 Token = 14 - DD -293 ; Index = 32 Token = 15 - DD 21 ; Index = 33 Token = 0 - DD 64 ; Index = 33 Token = 1 - DD 107 ; Index = 33 Token = 2 - DD 150 ; Index = 33 Token = 3 - DD 194 ; Index = 33 Token = 4 - DD 237 ; Index = 33 Token = 5 - DD 280 ; Index = 33 Token = 6 - DD 323 ; Index = 33 Token = 7 - DD -21 ; Index = 33 Token = 8 - DD -64 ; Index = 33 Token = 9 - DD -107 ; Index = 33 Token = 10 - DD -150 ; Index = 33 Token = 11 - DD -194 ; Index = 33 Token = 12 - DD -237 ; Index = 33 Token = 13 - DD -280 ; Index = 33 Token = 14 - DD -323 ; Index = 33 Token = 15 - DD 23 ; Index = 34 Token = 0 - DD 70 ; Index = 34 Token = 1 - DD 118 ; Index = 34 Token = 2 - DD 165 ; Index = 34 Token = 3 - DD 213 ; Index = 34 Token = 4 - DD 260 ; Index = 34 Token = 5 - DD 308 ; Index = 34 Token = 6 - DD 355 ; Index = 34 Token = 7 - DD -23 ; Index = 34 Token = 8 - DD -70 ; Index = 34 Token = 9 - DD -118 ; Index = 34 Token = 10 - DD -165 ; Index = 34 Token = 11 - DD -213 ; Index = 34 Token = 12 - DD -260 ; Index = 34 Token = 13 - DD -308 ; Index = 34 Token = 14 - DD -355 ; Index = 34 Token = 15 - DD 26 ; Index = 35 Token = 0 - DD 78 ; Index = 35 Token = 1 - DD 130 ; Index = 35 Token = 2 - DD 182 ; Index = 35 Token = 3 - DD 235 ; Index = 35 Token = 4 - DD 287 ; Index = 35 Token = 5 - DD 339 ; Index = 35 Token = 6 - DD 391 ; Index = 35 Token = 7 - DD -26 ; Index = 35 Token = 8 - DD -78 ; Index = 35 Token = 9 - DD -130 ; Index = 35 Token = 10 - DD -182 ; Index = 35 Token = 11 - DD -235 ; Index = 35 Token = 12 - DD -287 ; Index = 35 Token = 13 - DD -339 ; Index = 35 Token = 14 - DD -391 ; Index = 35 Token = 15 - DD 28 ; Index = 36 Token = 0 - DD 85 ; Index = 36 Token = 1 - DD 143 ; Index = 36 Token = 2 - DD 200 ; Index = 36 Token = 3 - DD 258 ; Index = 36 Token = 4 - DD 315 ; Index = 36 Token = 5 - DD 373 ; Index = 36 Token = 6 - DD 430 ; Index = 36 Token = 7 - DD -28 ; Index = 36 Token = 8 - DD -85 ; Index = 36 Token = 9 - DD -143 ; Index = 36 Token = 10 - DD -200 ; Index = 36 Token = 11 - DD -258 ; Index = 36 Token = 12 - DD -315 ; Index = 36 Token = 13 - DD -373 ; Index = 36 Token = 14 - DD -430 ; Index = 36 Token = 15 - DD 31 ; Index = 37 Token = 0 - DD 94 ; Index = 37 Token = 1 - DD 157 ; Index = 37 Token = 2 - DD 220 ; Index = 37 Token = 3 - DD 284 ; Index = 37 Token = 4 - DD 347 ; Index = 37 Token = 5 - DD 410 ; Index = 37 Token = 6 - DD 473 ; Index = 37 Token = 7 - DD -31 ; Index = 37 Token = 8 - DD -94 ; Index = 37 Token = 9 - DD -157 ; Index = 37 Token = 10 - DD -220 ; Index = 37 Token = 11 - DD -284 ; Index = 37 Token = 12 - DD -347 ; Index = 37 Token = 13 - DD -410 ; Index = 37 Token = 14 - DD -473 ; Index = 37 Token = 15 - DD 34 ; Index = 38 Token = 0 - DD 103 ; Index = 38 Token = 1 - DD 173 ; Index = 38 Token = 2 - DD 242 ; Index = 38 Token = 3 - DD 313 ; Index = 38 Token = 4 - DD 382 ; Index = 38 Token = 5 - DD 452 ; Index = 38 Token = 6 - DD 521 ; Index = 38 Token = 7 - DD -34 ; Index = 38 Token = 8 - DD -103 ; Index = 38 Token = 9 - DD -173 ; Index = 38 Token = 10 - DD -242 ; Index = 38 Token = 11 - DD -313 ; Index = 38 Token = 12 - DD -382 ; Index = 38 Token = 13 - DD -452 ; Index = 38 Token = 14 - DD -521 ; Index = 38 Token = 15 - DD 38 ; Index = 39 Token = 0 - DD 114 ; Index = 39 Token = 1 - DD 191 ; Index = 39 Token = 2 - DD 267 ; Index = 39 Token = 3 - DD 345 ; Index = 39 Token = 4 - DD 421 ; Index = 39 Token = 5 - DD 498 ; Index = 39 Token = 6 - DD 574 ; Index = 39 Token = 7 - DD -38 ; Index = 39 Token = 8 - DD -114 ; Index = 39 Token = 9 - DD -191 ; Index = 39 Token = 10 - DD -267 ; Index = 39 Token = 11 - DD -345 ; Index = 39 Token = 12 - DD -421 ; Index = 39 Token = 13 - DD -498 ; Index = 39 Token = 14 - DD -574 ; Index = 39 Token = 15 - DD 42 ; Index = 40 Token = 0 - DD 126 ; Index = 40 Token = 1 - DD 210 ; Index = 40 Token = 2 - DD 294 ; Index = 40 Token = 3 - DD 379 ; Index = 40 Token = 4 - DD 463 ; Index = 40 Token = 5 - DD 547 ; Index = 40 Token = 6 - DD 631 ; Index = 40 Token = 7 - DD -42 ; Index = 40 Token = 8 - DD -126 ; Index = 40 Token = 9 - DD -210 ; Index = 40 Token = 10 - DD -294 ; Index = 40 Token = 11 - DD -379 ; Index = 40 Token = 12 - DD -463 ; Index = 40 Token = 13 - DD -547 ; Index = 40 Token = 14 - DD -631 ; Index = 40 Token = 15 - DD 46 ; Index = 41 Token = 0 - DD 138 ; Index = 41 Token = 1 - DD 231 ; Index = 41 Token = 2 - DD 323 ; Index = 41 Token = 3 - DD 417 ; Index = 41 Token = 4 - DD 509 ; Index = 41 Token = 5 - DD 602 ; Index = 41 Token = 6 - DD 694 ; Index = 41 Token = 7 - DD -46 ; Index = 41 Token = 8 - DD -138 ; Index = 41 Token = 9 - DD -231 ; Index = 41 Token = 10 - DD -323 ; Index = 41 Token = 11 - DD -417 ; Index = 41 Token = 12 - DD -509 ; Index = 41 Token = 13 - DD -602 ; Index = 41 Token = 14 - DD -694 ; Index = 41 Token = 15 - DD 51 ; Index = 42 Token = 0 - DD 153 ; Index = 42 Token = 1 - DD 255 ; Index = 42 Token = 2 - DD 357 ; Index = 42 Token = 3 - DD 459 ; Index = 42 Token = 4 - DD 561 ; Index = 42 Token = 5 - DD 663 ; Index = 42 Token = 6 - DD 765 ; Index = 42 Token = 7 - DD -51 ; Index = 42 Token = 8 - DD -153 ; Index = 42 Token = 9 - DD -255 ; Index = 42 Token = 10 - DD -357 ; Index = 42 Token = 11 - DD -459 ; Index = 42 Token = 12 - DD -561 ; Index = 42 Token = 13 - DD -663 ; Index = 42 Token = 14 - DD -765 ; Index = 42 Token = 15 - DD 56 ; Index = 43 Token = 0 - DD 168 ; Index = 43 Token = 1 - DD 280 ; Index = 43 Token = 2 - DD 392 ; Index = 43 Token = 3 - DD 505 ; Index = 43 Token = 4 - DD 617 ; Index = 43 Token = 5 - DD 729 ; Index = 43 Token = 6 - DD 841 ; Index = 43 Token = 7 - DD -56 ; Index = 43 Token = 8 - DD -168 ; Index = 43 Token = 9 - DD -280 ; Index = 43 Token = 10 - DD -392 ; Index = 43 Token = 11 - DD -505 ; Index = 43 Token = 12 - DD -617 ; Index = 43 Token = 13 - DD -729 ; Index = 43 Token = 14 - DD -841 ; Index = 43 Token = 15 - DD 61 ; Index = 44 Token = 0 - DD 184 ; Index = 44 Token = 1 - DD 308 ; Index = 44 Token = 2 - DD 431 ; Index = 44 Token = 3 - DD 555 ; Index = 44 Token = 4 - DD 678 ; Index = 44 Token = 5 - DD 802 ; Index = 44 Token = 6 - DD 925 ; Index = 44 Token = 7 - DD -61 ; Index = 44 Token = 8 - DD -184 ; Index = 44 Token = 9 - DD -308 ; Index = 44 Token = 10 - DD -431 ; Index = 44 Token = 11 - DD -555 ; Index = 44 Token = 12 - DD -678 ; Index = 44 Token = 13 - DD -802 ; Index = 44 Token = 14 - DD -925 ; Index = 44 Token = 15 - DD 68 ; Index = 45 Token = 0 - DD 204 ; Index = 45 Token = 1 - DD 340 ; Index = 45 Token = 2 - DD 476 ; Index = 45 Token = 3 - DD 612 ; Index = 45 Token = 4 - DD 748 ; Index = 45 Token = 5 - DD 884 ; Index = 45 Token = 6 - DD 1020 ; Index = 45 Token = 7 - DD -68 ; Index = 45 Token = 8 - DD -204 ; Index = 45 Token = 9 - DD -340 ; Index = 45 Token = 10 - DD -476 ; Index = 45 Token = 11 - DD -612 ; Index = 45 Token = 12 - DD -748 ; Index = 45 Token = 13 - DD -884 ; Index = 45 Token = 14 - DD -1020 ; Index = 45 Token = 15 - DD 74 ; Index = 46 Token = 0 - DD 223 ; Index = 46 Token = 1 - DD 373 ; Index = 46 Token = 2 - DD 522 ; Index = 46 Token = 3 - DD 672 ; Index = 46 Token = 4 - DD 821 ; Index = 46 Token = 5 - DD 971 ; Index = 46 Token = 6 - DD 1120 ; Index = 46 Token = 7 - DD -74 ; Index = 46 Token = 8 - DD -223 ; Index = 46 Token = 9 - DD -373 ; Index = 46 Token = 10 - DD -522 ; Index = 46 Token = 11 - DD -672 ; Index = 46 Token = 12 - DD -821 ; Index = 46 Token = 13 - DD -971 ; Index = 46 Token = 14 - DD -1120 ; Index = 46 Token = 15 - DD 82 ; Index = 47 Token = 0 - DD 246 ; Index = 47 Token = 1 - DD 411 ; Index = 47 Token = 2 - DD 575 ; Index = 47 Token = 3 - DD 740 ; Index = 47 Token = 4 - DD 904 ; Index = 47 Token = 5 - DD 1069 ; Index = 47 Token = 6 - DD 1233 ; Index = 47 Token = 7 - DD -82 ; Index = 47 Token = 8 - DD -246 ; Index = 47 Token = 9 - DD -411 ; Index = 47 Token = 10 - DD -575 ; Index = 47 Token = 11 - DD -740 ; Index = 47 Token = 12 - DD -904 ; Index = 47 Token = 13 - DD -1069 ; Index = 47 Token = 14 - DD -1233 ; Index = 47 Token = 15 - DD 90 ; Index = 48 Token = 0 - DD 271 ; Index = 48 Token = 1 - DD 452 ; Index = 48 Token = 2 - DD 633 ; Index = 48 Token = 3 - DD 814 ; Index = 48 Token = 4 - DD 995 ; Index = 48 Token = 5 - DD 1176 ; Index = 48 Token = 6 - DD 1357 ; Index = 48 Token = 7 - DD -90 ; Index = 48 Token = 8 - DD -271 ; Index = 48 Token = 9 - DD -452 ; Index = 48 Token = 10 - DD -633 ; Index = 48 Token = 11 - DD -814 ; Index = 48 Token = 12 - DD -995 ; Index = 48 Token = 13 - DD -1176 ; Index = 48 Token = 14 - DD -1357 ; Index = 48 Token = 15 - DD 99 ; Index = 49 Token = 0 - DD 298 ; Index = 49 Token = 1 - DD 497 ; Index = 49 Token = 2 - DD 696 ; Index = 49 Token = 3 - DD 895 ; Index = 49 Token = 4 - DD 1094 ; Index = 49 Token = 5 - DD 1293 ; Index = 49 Token = 6 - DD 1492 ; Index = 49 Token = 7 - DD -99 ; Index = 49 Token = 8 - DD -298 ; Index = 49 Token = 9 - DD -497 ; Index = 49 Token = 10 - DD -696 ; Index = 49 Token = 11 - DD -895 ; Index = 49 Token = 12 - DD -1094 ; Index = 49 Token = 13 - DD -1293 ; Index = 49 Token = 14 - DD -1492 ; Index = 49 Token = 15 - DD 109 ; Index = 50 Token = 0 - DD 328 ; Index = 50 Token = 1 - DD 547 ; Index = 50 Token = 2 - DD 766 ; Index = 50 Token = 3 - DD 985 ; Index = 50 Token = 4 - DD 1204 ; Index = 50 Token = 5 - DD 1423 ; Index = 50 Token = 6 - DD 1642 ; Index = 50 Token = 7 - DD -109 ; Index = 50 Token = 8 - DD -328 ; Index = 50 Token = 9 - DD -547 ; Index = 50 Token = 10 - DD -766 ; Index = 50 Token = 11 - DD -985 ; Index = 50 Token = 12 - DD -1204 ; Index = 50 Token = 13 - DD -1423 ; Index = 50 Token = 14 - DD -1642 ; Index = 50 Token = 15 - DD 120 ; Index = 51 Token = 0 - DD 360 ; Index = 51 Token = 1 - DD 601 ; Index = 51 Token = 2 - DD 841 ; Index = 51 Token = 3 - DD 1083 ; Index = 51 Token = 4 - DD 1323 ; Index = 51 Token = 5 - DD 1564 ; Index = 51 Token = 6 - DD 1804 ; Index = 51 Token = 7 - DD -120 ; Index = 51 Token = 8 - DD -360 ; Index = 51 Token = 9 - DD -601 ; Index = 51 Token = 10 - DD -841 ; Index = 51 Token = 11 - DD -1083 ; Index = 51 Token = 12 - DD -1323 ; Index = 51 Token = 13 - DD -1564 ; Index = 51 Token = 14 - DD -1804 ; Index = 51 Token = 15 - DD 132 ; Index = 52 Token = 0 - DD 397 ; Index = 52 Token = 1 - DD 662 ; Index = 52 Token = 2 - DD 927 ; Index = 52 Token = 3 - DD 1192 ; Index = 52 Token = 4 - DD 1457 ; Index = 52 Token = 5 - DD 1722 ; Index = 52 Token = 6 - DD 1987 ; Index = 52 Token = 7 - DD -132 ; Index = 52 Token = 8 - DD -397 ; Index = 52 Token = 9 - DD -662 ; Index = 52 Token = 10 - DD -927 ; Index = 52 Token = 11 - DD -1192 ; Index = 52 Token = 12 - DD -1457 ; Index = 52 Token = 13 - DD -1722 ; Index = 52 Token = 14 - DD -1987 ; Index = 52 Token = 15 - DD 145 ; Index = 53 Token = 0 - DD 436 ; Index = 53 Token = 1 - DD 728 ; Index = 53 Token = 2 - DD 1019 ; Index = 53 Token = 3 - DD 1311 ; Index = 53 Token = 4 - DD 1602 ; Index = 53 Token = 5 - DD 1894 ; Index = 53 Token = 6 - DD 2185 ; Index = 53 Token = 7 - DD -145 ; Index = 53 Token = 8 - DD -436 ; Index = 53 Token = 9 - DD -728 ; Index = 53 Token = 10 - DD -1019 ; Index = 53 Token = 11 - DD -1311 ; Index = 53 Token = 12 - DD -1602 ; Index = 53 Token = 13 - DD -1894 ; Index = 53 Token = 14 - DD -2185 ; Index = 53 Token = 15 - DD 160 ; Index = 54 Token = 0 - DD 480 ; Index = 54 Token = 1 - DD 801 ; Index = 54 Token = 2 - DD 1121 ; Index = 54 Token = 3 - DD 1442 ; Index = 54 Token = 4 - DD 1762 ; Index = 54 Token = 5 - DD 2083 ; Index = 54 Token = 6 - DD 2403 ; Index = 54 Token = 7 - DD -160 ; Index = 54 Token = 8 - DD -480 ; Index = 54 Token = 9 - DD -801 ; Index = 54 Token = 10 - DD -1121 ; Index = 54 Token = 11 - DD -1442 ; Index = 54 Token = 12 - DD -1762 ; Index = 54 Token = 13 - DD -2083 ; Index = 54 Token = 14 - DD -2403 ; Index = 54 Token = 15 - DD 176 ; Index = 55 Token = 0 - DD 528 ; Index = 55 Token = 1 - DD 881 ; Index = 55 Token = 2 - DD 1233 ; Index = 55 Token = 3 - DD 1587 ; Index = 55 Token = 4 - DD 1939 ; Index = 55 Token = 5 - DD 2292 ; Index = 55 Token = 6 - DD 2644 ; Index = 55 Token = 7 - DD -176 ; Index = 55 Token = 8 - DD -528 ; Index = 55 Token = 9 - DD -881 ; Index = 55 Token = 10 - DD -1233 ; Index = 55 Token = 11 - DD -1587 ; Index = 55 Token = 12 - DD -1939 ; Index = 55 Token = 13 - DD -2292 ; Index = 55 Token = 14 - DD -2644 ; Index = 55 Token = 15 - DD 194 ; Index = 56 Token = 0 - DD 582 ; Index = 56 Token = 1 - DD 970 ; Index = 56 Token = 2 - DD 1358 ; Index = 56 Token = 3 - DD 1746 ; Index = 56 Token = 4 - DD 2134 ; Index = 56 Token = 5 - DD 2522 ; Index = 56 Token = 6 - DD 2910 ; Index = 56 Token = 7 - DD -194 ; Index = 56 Token = 8 - DD -582 ; Index = 56 Token = 9 - DD -970 ; Index = 56 Token = 10 - DD -1358 ; Index = 56 Token = 11 - DD -1746 ; Index = 56 Token = 12 - DD -2134 ; Index = 56 Token = 13 - DD -2522 ; Index = 56 Token = 14 - DD -2910 ; Index = 56 Token = 15 - DD 213 ; Index = 57 Token = 0 - DD 639 ; Index = 57 Token = 1 - DD 1066 ; Index = 57 Token = 2 - DD 1492 ; Index = 57 Token = 3 - DD 1920 ; Index = 57 Token = 4 - DD 2346 ; Index = 57 Token = 5 - DD 2773 ; Index = 57 Token = 6 - DD 3199 ; Index = 57 Token = 7 - DD -213 ; Index = 57 Token = 8 - DD -639 ; Index = 57 Token = 9 - DD -1066 ; Index = 57 Token = 10 - DD -1492 ; Index = 57 Token = 11 - DD -1920 ; Index = 57 Token = 12 - DD -2346 ; Index = 57 Token = 13 - DD -2773 ; Index = 57 Token = 14 - DD -3199 ; Index = 57 Token = 15 - DD 234 ; Index = 58 Token = 0 - DD 703 ; Index = 58 Token = 1 - DD 1173 ; Index = 58 Token = 2 - DD 1642 ; Index = 58 Token = 3 - DD 2112 ; Index = 58 Token = 4 - DD 2581 ; Index = 58 Token = 5 - DD 3051 ; Index = 58 Token = 6 - DD 3520 ; Index = 58 Token = 7 - DD -234 ; Index = 58 Token = 8 - DD -703 ; Index = 58 Token = 9 - DD -1173 ; Index = 58 Token = 10 - DD -1642 ; Index = 58 Token = 11 - DD -2112 ; Index = 58 Token = 12 - DD -2581 ; Index = 58 Token = 13 - DD -3051 ; Index = 58 Token = 14 - DD -3520 ; Index = 58 Token = 15 - DD 258 ; Index = 59 Token = 0 - DD 774 ; Index = 59 Token = 1 - DD 1291 ; Index = 59 Token = 2 - DD 1807 ; Index = 59 Token = 3 - DD 2324 ; Index = 59 Token = 4 - DD 2840 ; Index = 59 Token = 5 - DD 3357 ; Index = 59 Token = 6 - DD 3873 ; Index = 59 Token = 7 - DD -258 ; Index = 59 Token = 8 - DD -774 ; Index = 59 Token = 9 - DD -1291 ; Index = 59 Token = 10 - DD -1807 ; Index = 59 Token = 11 - DD -2324 ; Index = 59 Token = 12 - DD -2840 ; Index = 59 Token = 13 - DD -3357 ; Index = 59 Token = 14 - DD -3873 ; Index = 59 Token = 15 - DD 284 ; Index = 60 Token = 0 - DD 852 ; Index = 60 Token = 1 - DD 1420 ; Index = 60 Token = 2 - DD 1988 ; Index = 60 Token = 3 - DD 2556 ; Index = 60 Token = 4 - DD 3124 ; Index = 60 Token = 5 - DD 3692 ; Index = 60 Token = 6 - DD 4260 ; Index = 60 Token = 7 - DD -284 ; Index = 60 Token = 8 - DD -852 ; Index = 60 Token = 9 - DD -1420 ; Index = 60 Token = 10 - DD -1988 ; Index = 60 Token = 11 - DD -2556 ; Index = 60 Token = 12 - DD -3124 ; Index = 60 Token = 13 - DD -3692 ; Index = 60 Token = 14 - DD -4260 ; Index = 60 Token = 15 - DD 312 ; Index = 61 Token = 0 - DD 936 ; Index = 61 Token = 1 - DD 1561 ; Index = 61 Token = 2 - DD 2185 ; Index = 61 Token = 3 - DD 2811 ; Index = 61 Token = 4 - DD 3435 ; Index = 61 Token = 5 - DD 4060 ; Index = 61 Token = 6 - DD 4684 ; Index = 61 Token = 7 - DD -312 ; Index = 61 Token = 8 - DD -936 ; Index = 61 Token = 9 - DD -1561 ; Index = 61 Token = 10 - DD -2185 ; Index = 61 Token = 11 - DD -2811 ; Index = 61 Token = 12 - DD -3435 ; Index = 61 Token = 13 - DD -4060 ; Index = 61 Token = 14 - DD -4684 ; Index = 61 Token = 15 - DD 343 ; Index = 62 Token = 0 - DD 1030 ; Index = 62 Token = 1 - DD 1717 ; Index = 62 Token = 2 - DD 2404 ; Index = 62 Token = 3 - DD 3092 ; Index = 62 Token = 4 - DD 3779 ; Index = 62 Token = 5 - DD 4466 ; Index = 62 Token = 6 - DD 5153 ; Index = 62 Token = 7 - DD -343 ; Index = 62 Token = 8 - DD -1030 ; Index = 62 Token = 9 - DD -1717 ; Index = 62 Token = 10 - DD -2404 ; Index = 62 Token = 11 - DD -3092 ; Index = 62 Token = 12 - DD -3779 ; Index = 62 Token = 13 - DD -4466 ; Index = 62 Token = 14 - DD -5153 ; Index = 62 Token = 15 - DD 378 ; Index = 63 Token = 0 - DD 1134 ; Index = 63 Token = 1 - DD 1890 ; Index = 63 Token = 2 - DD 2646 ; Index = 63 Token = 3 - DD 3402 ; Index = 63 Token = 4 - DD 4158 ; Index = 63 Token = 5 - DD 4914 ; Index = 63 Token = 6 - DD 5670 ; Index = 63 Token = 7 - DD -378 ; Index = 63 Token = 8 - DD -1134 ; Index = 63 Token = 9 - DD -1890 ; Index = 63 Token = 10 - DD -2646 ; Index = 63 Token = 11 - DD -3402 ; Index = 63 Token = 12 - DD -4158 ; Index = 63 Token = 13 - DD -4914 ; Index = 63 Token = 14 - DD -5670 ; Index = 63 Token = 15 - DD 415 ; Index = 64 Token = 0 - DD 1246 ; Index = 64 Token = 1 - DD 2078 ; Index = 64 Token = 2 - DD 2909 ; Index = 64 Token = 3 - DD 3742 ; Index = 64 Token = 4 - DD 4573 ; Index = 64 Token = 5 - DD 5405 ; Index = 64 Token = 6 - DD 6236 ; Index = 64 Token = 7 - DD -415 ; Index = 64 Token = 8 - DD -1246 ; Index = 64 Token = 9 - DD -2078 ; Index = 64 Token = 10 - DD -2909 ; Index = 64 Token = 11 - DD -3742 ; Index = 64 Token = 12 - DD -4573 ; Index = 64 Token = 13 - DD -5405 ; Index = 64 Token = 14 - DD -6236 ; Index = 64 Token = 15 - DD 457 ; Index = 65 Token = 0 - DD 1372 ; Index = 65 Token = 1 - DD 2287 ; Index = 65 Token = 2 - DD 3202 ; Index = 65 Token = 3 - DD 4117 ; Index = 65 Token = 4 - DD 5032 ; Index = 65 Token = 5 - DD 5947 ; Index = 65 Token = 6 - DD 6862 ; Index = 65 Token = 7 - DD -457 ; Index = 65 Token = 8 - DD -1372 ; Index = 65 Token = 9 - DD -2287 ; Index = 65 Token = 10 - DD -3202 ; Index = 65 Token = 11 - DD -4117 ; Index = 65 Token = 12 - DD -5032 ; Index = 65 Token = 13 - DD -5947 ; Index = 65 Token = 14 - DD -6862 ; Index = 65 Token = 15 - DD 503 ; Index = 66 Token = 0 - DD 1509 ; Index = 66 Token = 1 - DD 2516 ; Index = 66 Token = 2 - DD 3522 ; Index = 66 Token = 3 - DD 4529 ; Index = 66 Token = 4 - DD 5535 ; Index = 66 Token = 5 - DD 6542 ; Index = 66 Token = 6 - DD 7548 ; Index = 66 Token = 7 - DD -503 ; Index = 66 Token = 8 - DD -1509 ; Index = 66 Token = 9 - DD -2516 ; Index = 66 Token = 10 - DD -3522 ; Index = 66 Token = 11 - DD -4529 ; Index = 66 Token = 12 - DD -5535 ; Index = 66 Token = 13 - DD -6542 ; Index = 66 Token = 14 - DD -7548 ; Index = 66 Token = 15 - DD 553 ; Index = 67 Token = 0 - DD 1660 ; Index = 67 Token = 1 - DD 2767 ; Index = 67 Token = 2 - DD 3874 ; Index = 67 Token = 3 - DD 4981 ; Index = 67 Token = 4 - DD 6088 ; Index = 67 Token = 5 - DD 7195 ; Index = 67 Token = 6 - DD 8302 ; Index = 67 Token = 7 - DD -553 ; Index = 67 Token = 8 - DD -1660 ; Index = 67 Token = 9 - DD -2767 ; Index = 67 Token = 10 - DD -3874 ; Index = 67 Token = 11 - DD -4981 ; Index = 67 Token = 12 - DD -6088 ; Index = 67 Token = 13 - DD -7195 ; Index = 67 Token = 14 - DD -8302 ; Index = 67 Token = 15 - DD 608 ; Index = 68 Token = 0 - DD 1825 ; Index = 68 Token = 1 - DD 3043 ; Index = 68 Token = 2 - DD 4260 ; Index = 68 Token = 3 - DD 5479 ; Index = 68 Token = 4 - DD 6696 ; Index = 68 Token = 5 - DD 7914 ; Index = 68 Token = 6 - DD 9131 ; Index = 68 Token = 7 - DD -608 ; Index = 68 Token = 8 - DD -1825 ; Index = 68 Token = 9 - DD -3043 ; Index = 68 Token = 10 - DD -4260 ; Index = 68 Token = 11 - DD -5479 ; Index = 68 Token = 12 - DD -6696 ; Index = 68 Token = 13 - DD -7914 ; Index = 68 Token = 14 - DD -9131 ; Index = 68 Token = 15 - DD 669 ; Index = 69 Token = 0 - DD 2008 ; Index = 69 Token = 1 - DD 3348 ; Index = 69 Token = 2 - DD 4687 ; Index = 69 Token = 3 - DD 6027 ; Index = 69 Token = 4 - DD 7366 ; Index = 69 Token = 5 - DD 8706 ; Index = 69 Token = 6 - DD 10045 ; Index = 69 Token = 7 - DD -669 ; Index = 69 Token = 8 - DD -2008 ; Index = 69 Token = 9 - DD -3348 ; Index = 69 Token = 10 - DD -4687 ; Index = 69 Token = 11 - DD -6027 ; Index = 69 Token = 12 - DD -7366 ; Index = 69 Token = 13 - DD -8706 ; Index = 69 Token = 14 - DD -10045 ; Index = 69 Token = 15 - DD 736 ; Index = 70 Token = 0 - DD 2209 ; Index = 70 Token = 1 - DD 3683 ; Index = 70 Token = 2 - DD 5156 ; Index = 70 Token = 3 - DD 6630 ; Index = 70 Token = 4 - DD 8103 ; Index = 70 Token = 5 - DD 9577 ; Index = 70 Token = 6 - DD 11050 ; Index = 70 Token = 7 - DD -736 ; Index = 70 Token = 8 - DD -2209 ; Index = 70 Token = 9 - DD -3683 ; Index = 70 Token = 10 - DD -5156 ; Index = 70 Token = 11 - DD -6630 ; Index = 70 Token = 12 - DD -8103 ; Index = 70 Token = 13 - DD -9577 ; Index = 70 Token = 14 - DD -11050 ; Index = 70 Token = 15 - DD 810 ; Index = 71 Token = 0 - DD 2431 ; Index = 71 Token = 1 - DD 4052 ; Index = 71 Token = 2 - DD 5673 ; Index = 71 Token = 3 - DD 7294 ; Index = 71 Token = 4 - DD 8915 ; Index = 71 Token = 5 - DD 10536 ; Index = 71 Token = 6 - DD 12157 ; Index = 71 Token = 7 - DD -810 ; Index = 71 Token = 8 - DD -2431 ; Index = 71 Token = 9 - DD -4052 ; Index = 71 Token = 10 - DD -5673 ; Index = 71 Token = 11 - DD -7294 ; Index = 71 Token = 12 - DD -8915 ; Index = 71 Token = 13 - DD -10536 ; Index = 71 Token = 14 - DD -12157 ; Index = 71 Token = 15 - DD 891 ; Index = 72 Token = 0 - DD 2674 ; Index = 72 Token = 1 - DD 4457 ; Index = 72 Token = 2 - DD 6240 ; Index = 72 Token = 3 - DD 8023 ; Index = 72 Token = 4 - DD 9806 ; Index = 72 Token = 5 - DD 11589 ; Index = 72 Token = 6 - DD 13372 ; Index = 72 Token = 7 - DD -891 ; Index = 72 Token = 8 - DD -2674 ; Index = 72 Token = 9 - DD -4457 ; Index = 72 Token = 10 - DD -6240 ; Index = 72 Token = 11 - DD -8023 ; Index = 72 Token = 12 - DD -9806 ; Index = 72 Token = 13 - DD -11589 ; Index = 72 Token = 14 - DD -13372 ; Index = 72 Token = 15 - DD 980 ; Index = 73 Token = 0 - DD 2941 ; Index = 73 Token = 1 - DD 4902 ; Index = 73 Token = 2 - DD 6863 ; Index = 73 Token = 3 - DD 8825 ; Index = 73 Token = 4 - DD 10786 ; Index = 73 Token = 5 - DD 12747 ; Index = 73 Token = 6 - DD 14708 ; Index = 73 Token = 7 - DD -980 ; Index = 73 Token = 8 - DD -2941 ; Index = 73 Token = 9 - DD -4902 ; Index = 73 Token = 10 - DD -6863 ; Index = 73 Token = 11 - DD -8825 ; Index = 73 Token = 12 - DD -10786 ; Index = 73 Token = 13 - DD -12747 ; Index = 73 Token = 14 - DD -14708 ; Index = 73 Token = 15 - DD 1078 ; Index = 74 Token = 0 - DD 3235 ; Index = 74 Token = 1 - DD 5393 ; Index = 74 Token = 2 - DD 7550 ; Index = 74 Token = 3 - DD 9708 ; Index = 74 Token = 4 - DD 11865 ; Index = 74 Token = 5 - DD 14023 ; Index = 74 Token = 6 - DD 16180 ; Index = 74 Token = 7 - DD -1078 ; Index = 74 Token = 8 - DD -3235 ; Index = 74 Token = 9 - DD -5393 ; Index = 74 Token = 10 - DD -7550 ; Index = 74 Token = 11 - DD -9708 ; Index = 74 Token = 12 - DD -11865 ; Index = 74 Token = 13 - DD -14023 ; Index = 74 Token = 14 - DD -16180 ; Index = 74 Token = 15 - DD 1186 ; Index = 75 Token = 0 - DD 3559 ; Index = 75 Token = 1 - DD 5932 ; Index = 75 Token = 2 - DD 8305 ; Index = 75 Token = 3 - DD 10679 ; Index = 75 Token = 4 - DD 13052 ; Index = 75 Token = 5 - DD 15425 ; Index = 75 Token = 6 - DD 17798 ; Index = 75 Token = 7 - DD -1186 ; Index = 75 Token = 8 - DD -3559 ; Index = 75 Token = 9 - DD -5932 ; Index = 75 Token = 10 - DD -8305 ; Index = 75 Token = 11 - DD -10679 ; Index = 75 Token = 12 - DD -13052 ; Index = 75 Token = 13 - DD -15425 ; Index = 75 Token = 14 - DD -17798 ; Index = 75 Token = 15 - DD 1305 ; Index = 76 Token = 0 - DD 3915 ; Index = 76 Token = 1 - DD 6526 ; Index = 76 Token = 2 - DD 9136 ; Index = 76 Token = 3 - DD 11747 ; Index = 76 Token = 4 - DD 14357 ; Index = 76 Token = 5 - DD 16968 ; Index = 76 Token = 6 - DD 19578 ; Index = 76 Token = 7 - DD -1305 ; Index = 76 Token = 8 - DD -3915 ; Index = 76 Token = 9 - DD -6526 ; Index = 76 Token = 10 - DD -9136 ; Index = 76 Token = 11 - DD -11747 ; Index = 76 Token = 12 - DD -14357 ; Index = 76 Token = 13 - DD -16968 ; Index = 76 Token = 14 - DD -19578 ; Index = 76 Token = 15 - DD 1435 ; Index = 77 Token = 0 - DD 4306 ; Index = 77 Token = 1 - DD 7178 ; Index = 77 Token = 2 - DD 10049 ; Index = 77 Token = 3 - DD 12922 ; Index = 77 Token = 4 - DD 15793 ; Index = 77 Token = 5 - DD 18665 ; Index = 77 Token = 6 - DD 21536 ; Index = 77 Token = 7 - DD -1435 ; Index = 77 Token = 8 - DD -4306 ; Index = 77 Token = 9 - DD -7178 ; Index = 77 Token = 10 - DD -10049 ; Index = 77 Token = 11 - DD -12922 ; Index = 77 Token = 12 - DD -15793 ; Index = 77 Token = 13 - DD -18665 ; Index = 77 Token = 14 - DD -21536 ; Index = 77 Token = 15 - DD 1579 ; Index = 78 Token = 0 - DD 4737 ; Index = 78 Token = 1 - DD 7896 ; Index = 78 Token = 2 - DD 11054 ; Index = 78 Token = 3 - DD 14214 ; Index = 78 Token = 4 - DD 17372 ; Index = 78 Token = 5 - DD 20531 ; Index = 78 Token = 6 - DD 23689 ; Index = 78 Token = 7 - DD -1579 ; Index = 78 Token = 8 - DD -4737 ; Index = 78 Token = 9 - DD -7896 ; Index = 78 Token = 10 - DD -11054 ; Index = 78 Token = 11 - DD -14214 ; Index = 78 Token = 12 - DD -17372 ; Index = 78 Token = 13 - DD -20531 ; Index = 78 Token = 14 - DD -23689 ; Index = 78 Token = 15 - DD 1737 ; Index = 79 Token = 0 - DD 5211 ; Index = 79 Token = 1 - DD 8686 ; Index = 79 Token = 2 - DD 12160 ; Index = 79 Token = 3 - DD 15636 ; Index = 79 Token = 4 - DD 19110 ; Index = 79 Token = 5 - DD 22585 ; Index = 79 Token = 6 - DD 26059 ; Index = 79 Token = 7 - DD -1737 ; Index = 79 Token = 8 - DD -5211 ; Index = 79 Token = 9 - DD -8686 ; Index = 79 Token = 10 - DD -12160 ; Index = 79 Token = 11 - DD -15636 ; Index = 79 Token = 12 - DD -19110 ; Index = 79 Token = 13 - DD -22585 ; Index = 79 Token = 14 - DD -26059 ; Index = 79 Token = 15 - DD 1911 ; Index = 80 Token = 0 - DD 5733 ; Index = 80 Token = 1 - DD 9555 ; Index = 80 Token = 2 - DD 13377 ; Index = 80 Token = 3 - DD 17200 ; Index = 80 Token = 4 - DD 21022 ; Index = 80 Token = 5 - DD 24844 ; Index = 80 Token = 6 - DD 28666 ; Index = 80 Token = 7 - DD -1911 ; Index = 80 Token = 8 - DD -5733 ; Index = 80 Token = 9 - DD -9555 ; Index = 80 Token = 10 - DD -13377 ; Index = 80 Token = 11 - DD -17200 ; Index = 80 Token = 12 - DD -21022 ; Index = 80 Token = 13 - DD -24844 ; Index = 80 Token = 14 - DD -28666 ; Index = 80 Token = 15 - DD 2102 ; Index = 81 Token = 0 - DD 6306 ; Index = 81 Token = 1 - DD 10511 ; Index = 81 Token = 2 - DD 14715 ; Index = 81 Token = 3 - DD 18920 ; Index = 81 Token = 4 - DD 23124 ; Index = 81 Token = 5 - DD 27329 ; Index = 81 Token = 6 - DD 31533 ; Index = 81 Token = 7 - DD -2102 ; Index = 81 Token = 8 - DD -6306 ; Index = 81 Token = 9 - DD -10511 ; Index = 81 Token = 10 - DD -14715 ; Index = 81 Token = 11 - DD -18920 ; Index = 81 Token = 12 - DD -23124 ; Index = 81 Token = 13 - DD -27329 ; Index = 81 Token = 14 - DD -31533 ; Index = 81 Token = 15 - DD 2312 ; Index = 82 Token = 0 - DD 6937 ; Index = 82 Token = 1 - DD 11562 ; Index = 82 Token = 2 - DD 16187 ; Index = 82 Token = 3 - DD 20812 ; Index = 82 Token = 4 - DD 25437 ; Index = 82 Token = 5 - DD 30062 ; Index = 82 Token = 6 - DD 34687 ; Index = 82 Token = 7 - DD -2312 ; Index = 82 Token = 8 - DD -6937 ; Index = 82 Token = 9 - DD -11562 ; Index = 82 Token = 10 - DD -16187 ; Index = 82 Token = 11 - DD -20812 ; Index = 82 Token = 12 - DD -25437 ; Index = 82 Token = 13 - DD -30062 ; Index = 82 Token = 14 - DD -34687 ; Index = 82 Token = 15 - DD 2543 ; Index = 83 Token = 0 - DD 7630 ; Index = 83 Token = 1 - DD 12718 ; Index = 83 Token = 2 - DD 17805 ; Index = 83 Token = 3 - DD 22893 ; Index = 83 Token = 4 - DD 27980 ; Index = 83 Token = 5 - DD 33068 ; Index = 83 Token = 6 - DD 38155 ; Index = 83 Token = 7 - DD -2543 ; Index = 83 Token = 8 - DD -7630 ; Index = 83 Token = 9 - DD -12718 ; Index = 83 Token = 10 - DD -17805 ; Index = 83 Token = 11 - DD -22893 ; Index = 83 Token = 12 - DD -27980 ; Index = 83 Token = 13 - DD -33068 ; Index = 83 Token = 14 - DD -38155 ; Index = 83 Token = 15 - DD 2798 ; Index = 84 Token = 0 - DD 8394 ; Index = 84 Token = 1 - DD 13990 ; Index = 84 Token = 2 - DD 19586 ; Index = 84 Token = 3 - DD 25183 ; Index = 84 Token = 4 - DD 30779 ; Index = 84 Token = 5 - DD 36375 ; Index = 84 Token = 6 - DD 41971 ; Index = 84 Token = 7 - DD -2798 ; Index = 84 Token = 8 - DD -8394 ; Index = 84 Token = 9 - DD -13990 ; Index = 84 Token = 10 - DD -19586 ; Index = 84 Token = 11 - DD -25183 ; Index = 84 Token = 12 - DD -30779 ; Index = 84 Token = 13 - DD -36375 ; Index = 84 Token = 14 - DD -41971 ; Index = 84 Token = 15 - DD 3077 ; Index = 85 Token = 0 - DD 9232 ; Index = 85 Token = 1 - DD 15388 ; Index = 85 Token = 2 - DD 21543 ; Index = 85 Token = 3 - DD 27700 ; Index = 85 Token = 4 - DD 33855 ; Index = 85 Token = 5 - DD 40011 ; Index = 85 Token = 6 - DD 46166 ; Index = 85 Token = 7 - DD -3077 ; Index = 85 Token = 8 - DD -9232 ; Index = 85 Token = 9 - DD -15388 ; Index = 85 Token = 10 - DD -21543 ; Index = 85 Token = 11 - DD -27700 ; Index = 85 Token = 12 - DD -33855 ; Index = 85 Token = 13 - DD -40011 ; Index = 85 Token = 14 - DD -46166 ; Index = 85 Token = 15 - DD 3385 ; Index = 86 Token = 0 - DD 10156 ; Index = 86 Token = 1 - DD 16928 ; Index = 86 Token = 2 - DD 23699 ; Index = 86 Token = 3 - DD 30471 ; Index = 86 Token = 4 - DD 37242 ; Index = 86 Token = 5 - DD 44014 ; Index = 86 Token = 6 - DD 50785 ; Index = 86 Token = 7 - DD -3385 ; Index = 86 Token = 8 - DD -10156 ; Index = 86 Token = 9 - DD -16928 ; Index = 86 Token = 10 - DD -23699 ; Index = 86 Token = 11 - DD -30471 ; Index = 86 Token = 12 - DD -37242 ; Index = 86 Token = 13 - DD -44014 ; Index = 86 Token = 14 - DD -50785 ; Index = 86 Token = 15 - DD 3724 ; Index = 87 Token = 0 - DD 11172 ; Index = 87 Token = 1 - DD 18621 ; Index = 87 Token = 2 - DD 26069 ; Index = 87 Token = 3 - DD 33518 ; Index = 87 Token = 4 - DD 40966 ; Index = 87 Token = 5 - DD 48415 ; Index = 87 Token = 6 - DD 55863 ; Index = 87 Token = 7 - DD -3724 ; Index = 87 Token = 8 - DD -11172 ; Index = 87 Token = 9 - DD -18621 ; Index = 87 Token = 10 - DD -26069 ; Index = 87 Token = 11 - DD -33518 ; Index = 87 Token = 12 - DD -40966 ; Index = 87 Token = 13 - DD -48415 ; Index = 87 Token = 14 - DD -55863 ; Index = 87 Token = 15 - DD 4095 ; Index = 88 Token = 0 - DD 12286 ; Index = 88 Token = 1 - DD 20478 ; Index = 88 Token = 2 - DD 28669 ; Index = 88 Token = 3 - DD 36862 ; Index = 88 Token = 4 - DD 45053 ; Index = 88 Token = 5 - DD 53245 ; Index = 88 Token = 6 - DD 61436 ; Index = 88 Token = 7 - DD -4095 ; Index = 88 Token = 8 - DD -12286 ; Index = 88 Token = 9 - DD -20478 ; Index = 88 Token = 10 - DD -28669 ; Index = 88 Token = 11 - DD -36862 ; Index = 88 Token = 12 - DD -45053 ; Index = 88 Token = 13 - DD -53245 ; Index = 88 Token = 14 - DD -61436 ; Index = 88 Token = 15 diff --git a/code/indextb.inc b/code/indextb.inc deleted file mode 100644 index c250ed43..00000000 --- a/code/indextb.inc +++ /dev/null @@ -1,1443 +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. -;****************************************************************************** - -;**************************************************************************** -;* wIndexTable - ADPCM Lookup table for indexes -;**************************************************************************** - - align 4 - -wIndexTable DW 0 * 2 ; Index = 0 Token = 0 - DW 0 * 2 ; Index = 0 Token = 1 - DW 0 * 2 ; Index = 0 Token = 2 - DW 0 * 2 ; Index = 0 Token = 3 - DW 32 * 2 ; Index = 0 Token = 4 - DW 64 * 2 ; Index = 0 Token = 5 - DW 96 * 2 ; Index = 0 Token = 6 - DW 128 * 2 ; Index = 0 Token = 7 - DW 0 * 2 ; Index = 0 Token = 8 - DW 0 * 2 ; Index = 0 Token = 9 - DW 0 * 2 ; Index = 0 Token = 10 - DW 0 * 2 ; Index = 0 Token = 11 - DW 32 * 2 ; Index = 0 Token = 12 - DW 64 * 2 ; Index = 0 Token = 13 - DW 96 * 2 ; Index = 0 Token = 14 - DW 128 * 2 ; Index = 0 Token = 15 - DW 0 * 2 ; Index = 1 Token = 0 - DW 0 * 2 ; Index = 1 Token = 1 - DW 0 * 2 ; Index = 1 Token = 2 - DW 0 * 2 ; Index = 1 Token = 3 - DW 48 * 2 ; Index = 1 Token = 4 - DW 80 * 2 ; Index = 1 Token = 5 - DW 112 * 2 ; Index = 1 Token = 6 - DW 144 * 2 ; Index = 1 Token = 7 - DW 0 * 2 ; Index = 1 Token = 8 - DW 0 * 2 ; Index = 1 Token = 9 - DW 0 * 2 ; Index = 1 Token = 10 - DW 0 * 2 ; Index = 1 Token = 11 - DW 48 * 2 ; Index = 1 Token = 12 - DW 80 * 2 ; Index = 1 Token = 13 - DW 112 * 2 ; Index = 1 Token = 14 - DW 144 * 2 ; Index = 1 Token = 15 - DW 16 * 2 ; Index = 2 Token = 0 - DW 16 * 2 ; Index = 2 Token = 1 - DW 16 * 2 ; Index = 2 Token = 2 - DW 16 * 2 ; Index = 2 Token = 3 - DW 64 * 2 ; Index = 2 Token = 4 - DW 96 * 2 ; Index = 2 Token = 5 - DW 128 * 2 ; Index = 2 Token = 6 - DW 160 * 2 ; Index = 2 Token = 7 - DW 16 * 2 ; Index = 2 Token = 8 - DW 16 * 2 ; Index = 2 Token = 9 - DW 16 * 2 ; Index = 2 Token = 10 - DW 16 * 2 ; Index = 2 Token = 11 - DW 64 * 2 ; Index = 2 Token = 12 - DW 96 * 2 ; Index = 2 Token = 13 - DW 128 * 2 ; Index = 2 Token = 14 - DW 160 * 2 ; Index = 2 Token = 15 - DW 32 * 2 ; Index = 3 Token = 0 - DW 32 * 2 ; Index = 3 Token = 1 - DW 32 * 2 ; Index = 3 Token = 2 - DW 32 * 2 ; Index = 3 Token = 3 - DW 80 * 2 ; Index = 3 Token = 4 - DW 112 * 2 ; Index = 3 Token = 5 - DW 144 * 2 ; Index = 3 Token = 6 - DW 176 * 2 ; Index = 3 Token = 7 - DW 32 * 2 ; Index = 3 Token = 8 - DW 32 * 2 ; Index = 3 Token = 9 - DW 32 * 2 ; Index = 3 Token = 10 - DW 32 * 2 ; Index = 3 Token = 11 - DW 80 * 2 ; Index = 3 Token = 12 - DW 112 * 2 ; Index = 3 Token = 13 - DW 144 * 2 ; Index = 3 Token = 14 - DW 176 * 2 ; Index = 3 Token = 15 - DW 48 * 2 ; Index = 4 Token = 0 - DW 48 * 2 ; Index = 4 Token = 1 - DW 48 * 2 ; Index = 4 Token = 2 - DW 48 * 2 ; Index = 4 Token = 3 - DW 96 * 2 ; Index = 4 Token = 4 - DW 128 * 2 ; Index = 4 Token = 5 - DW 160 * 2 ; Index = 4 Token = 6 - DW 192 * 2 ; Index = 4 Token = 7 - DW 48 * 2 ; Index = 4 Token = 8 - DW 48 * 2 ; Index = 4 Token = 9 - DW 48 * 2 ; Index = 4 Token = 10 - DW 48 * 2 ; Index = 4 Token = 11 - DW 96 * 2 ; Index = 4 Token = 12 - DW 128 * 2 ; Index = 4 Token = 13 - DW 160 * 2 ; Index = 4 Token = 14 - DW 192 * 2 ; Index = 4 Token = 15 - DW 64 * 2 ; Index = 5 Token = 0 - DW 64 * 2 ; Index = 5 Token = 1 - DW 64 * 2 ; Index = 5 Token = 2 - DW 64 * 2 ; Index = 5 Token = 3 - DW 112 * 2 ; Index = 5 Token = 4 - DW 144 * 2 ; Index = 5 Token = 5 - DW 176 * 2 ; Index = 5 Token = 6 - DW 208 * 2 ; Index = 5 Token = 7 - DW 64 * 2 ; Index = 5 Token = 8 - DW 64 * 2 ; Index = 5 Token = 9 - DW 64 * 2 ; Index = 5 Token = 10 - DW 64 * 2 ; Index = 5 Token = 11 - DW 112 * 2 ; Index = 5 Token = 12 - DW 144 * 2 ; Index = 5 Token = 13 - DW 176 * 2 ; Index = 5 Token = 14 - DW 208 * 2 ; Index = 5 Token = 15 - DW 80 * 2 ; Index = 6 Token = 0 - DW 80 * 2 ; Index = 6 Token = 1 - DW 80 * 2 ; Index = 6 Token = 2 - DW 80 * 2 ; Index = 6 Token = 3 - DW 128 * 2 ; Index = 6 Token = 4 - DW 160 * 2 ; Index = 6 Token = 5 - DW 192 * 2 ; Index = 6 Token = 6 - DW 224 * 2 ; Index = 6 Token = 7 - DW 80 * 2 ; Index = 6 Token = 8 - DW 80 * 2 ; Index = 6 Token = 9 - DW 80 * 2 ; Index = 6 Token = 10 - DW 80 * 2 ; Index = 6 Token = 11 - DW 128 * 2 ; Index = 6 Token = 12 - DW 160 * 2 ; Index = 6 Token = 13 - DW 192 * 2 ; Index = 6 Token = 14 - DW 224 * 2 ; Index = 6 Token = 15 - DW 96 * 2 ; Index = 7 Token = 0 - DW 96 * 2 ; Index = 7 Token = 1 - DW 96 * 2 ; Index = 7 Token = 2 - DW 96 * 2 ; Index = 7 Token = 3 - DW 144 * 2 ; Index = 7 Token = 4 - DW 176 * 2 ; Index = 7 Token = 5 - DW 208 * 2 ; Index = 7 Token = 6 - DW 240 * 2 ; Index = 7 Token = 7 - DW 96 * 2 ; Index = 7 Token = 8 - DW 96 * 2 ; Index = 7 Token = 9 - DW 96 * 2 ; Index = 7 Token = 10 - DW 96 * 2 ; Index = 7 Token = 11 - DW 144 * 2 ; Index = 7 Token = 12 - DW 176 * 2 ; Index = 7 Token = 13 - DW 208 * 2 ; Index = 7 Token = 14 - DW 240 * 2 ; Index = 7 Token = 15 - DW 112 * 2 ; Index = 8 Token = 0 - DW 112 * 2 ; Index = 8 Token = 1 - DW 112 * 2 ; Index = 8 Token = 2 - DW 112 * 2 ; Index = 8 Token = 3 - DW 160 * 2 ; Index = 8 Token = 4 - DW 192 * 2 ; Index = 8 Token = 5 - DW 224 * 2 ; Index = 8 Token = 6 - DW 256 * 2 ; Index = 8 Token = 7 - DW 112 * 2 ; Index = 8 Token = 8 - DW 112 * 2 ; Index = 8 Token = 9 - DW 112 * 2 ; Index = 8 Token = 10 - DW 112 * 2 ; Index = 8 Token = 11 - DW 160 * 2 ; Index = 8 Token = 12 - DW 192 * 2 ; Index = 8 Token = 13 - DW 224 * 2 ; Index = 8 Token = 14 - DW 256 * 2 ; Index = 8 Token = 15 - DW 128 * 2 ; Index = 9 Token = 0 - DW 128 * 2 ; Index = 9 Token = 1 - DW 128 * 2 ; Index = 9 Token = 2 - DW 128 * 2 ; Index = 9 Token = 3 - DW 176 * 2 ; Index = 9 Token = 4 - DW 208 * 2 ; Index = 9 Token = 5 - DW 240 * 2 ; Index = 9 Token = 6 - DW 272 * 2 ; Index = 9 Token = 7 - DW 128 * 2 ; Index = 9 Token = 8 - DW 128 * 2 ; Index = 9 Token = 9 - DW 128 * 2 ; Index = 9 Token = 10 - DW 128 * 2 ; Index = 9 Token = 11 - DW 176 * 2 ; Index = 9 Token = 12 - DW 208 * 2 ; Index = 9 Token = 13 - DW 240 * 2 ; Index = 9 Token = 14 - DW 272 * 2 ; Index = 9 Token = 15 - DW 144 * 2 ; Index = 10 Token = 0 - DW 144 * 2 ; Index = 10 Token = 1 - DW 144 * 2 ; Index = 10 Token = 2 - DW 144 * 2 ; Index = 10 Token = 3 - DW 192 * 2 ; Index = 10 Token = 4 - DW 224 * 2 ; Index = 10 Token = 5 - DW 256 * 2 ; Index = 10 Token = 6 - DW 288 * 2 ; Index = 10 Token = 7 - DW 144 * 2 ; Index = 10 Token = 8 - DW 144 * 2 ; Index = 10 Token = 9 - DW 144 * 2 ; Index = 10 Token = 10 - DW 144 * 2 ; Index = 10 Token = 11 - DW 192 * 2 ; Index = 10 Token = 12 - DW 224 * 2 ; Index = 10 Token = 13 - DW 256 * 2 ; Index = 10 Token = 14 - DW 288 * 2 ; Index = 10 Token = 15 - DW 160 * 2 ; Index = 11 Token = 0 - DW 160 * 2 ; Index = 11 Token = 1 - DW 160 * 2 ; Index = 11 Token = 2 - DW 160 * 2 ; Index = 11 Token = 3 - DW 208 * 2 ; Index = 11 Token = 4 - DW 240 * 2 ; Index = 11 Token = 5 - DW 272 * 2 ; Index = 11 Token = 6 - DW 304 * 2 ; Index = 11 Token = 7 - DW 160 * 2 ; Index = 11 Token = 8 - DW 160 * 2 ; Index = 11 Token = 9 - DW 160 * 2 ; Index = 11 Token = 10 - DW 160 * 2 ; Index = 11 Token = 11 - DW 208 * 2 ; Index = 11 Token = 12 - DW 240 * 2 ; Index = 11 Token = 13 - DW 272 * 2 ; Index = 11 Token = 14 - DW 304 * 2 ; Index = 11 Token = 15 - DW 176 * 2 ; Index = 12 Token = 0 - DW 176 * 2 ; Index = 12 Token = 1 - DW 176 * 2 ; Index = 12 Token = 2 - DW 176 * 2 ; Index = 12 Token = 3 - DW 224 * 2 ; Index = 12 Token = 4 - DW 256 * 2 ; Index = 12 Token = 5 - DW 288 * 2 ; Index = 12 Token = 6 - DW 320 * 2 ; Index = 12 Token = 7 - DW 176 * 2 ; Index = 12 Token = 8 - DW 176 * 2 ; Index = 12 Token = 9 - DW 176 * 2 ; Index = 12 Token = 10 - DW 176 * 2 ; Index = 12 Token = 11 - DW 224 * 2 ; Index = 12 Token = 12 - DW 256 * 2 ; Index = 12 Token = 13 - DW 288 * 2 ; Index = 12 Token = 14 - DW 320 * 2 ; Index = 12 Token = 15 - DW 192 * 2 ; Index = 13 Token = 0 - DW 192 * 2 ; Index = 13 Token = 1 - DW 192 * 2 ; Index = 13 Token = 2 - DW 192 * 2 ; Index = 13 Token = 3 - DW 240 * 2 ; Index = 13 Token = 4 - DW 272 * 2 ; Index = 13 Token = 5 - DW 304 * 2 ; Index = 13 Token = 6 - DW 336 * 2 ; Index = 13 Token = 7 - DW 192 * 2 ; Index = 13 Token = 8 - DW 192 * 2 ; Index = 13 Token = 9 - DW 192 * 2 ; Index = 13 Token = 10 - DW 192 * 2 ; Index = 13 Token = 11 - DW 240 * 2 ; Index = 13 Token = 12 - DW 272 * 2 ; Index = 13 Token = 13 - DW 304 * 2 ; Index = 13 Token = 14 - DW 336 * 2 ; Index = 13 Token = 15 - DW 208 * 2 ; Index = 14 Token = 0 - DW 208 * 2 ; Index = 14 Token = 1 - DW 208 * 2 ; Index = 14 Token = 2 - DW 208 * 2 ; Index = 14 Token = 3 - DW 256 * 2 ; Index = 14 Token = 4 - DW 288 * 2 ; Index = 14 Token = 5 - DW 320 * 2 ; Index = 14 Token = 6 - DW 352 * 2 ; Index = 14 Token = 7 - DW 208 * 2 ; Index = 14 Token = 8 - DW 208 * 2 ; Index = 14 Token = 9 - DW 208 * 2 ; Index = 14 Token = 10 - DW 208 * 2 ; Index = 14 Token = 11 - DW 256 * 2 ; Index = 14 Token = 12 - DW 288 * 2 ; Index = 14 Token = 13 - DW 320 * 2 ; Index = 14 Token = 14 - DW 352 * 2 ; Index = 14 Token = 15 - DW 224 * 2 ; Index = 15 Token = 0 - DW 224 * 2 ; Index = 15 Token = 1 - DW 224 * 2 ; Index = 15 Token = 2 - DW 224 * 2 ; Index = 15 Token = 3 - DW 272 * 2 ; Index = 15 Token = 4 - DW 304 * 2 ; Index = 15 Token = 5 - DW 336 * 2 ; Index = 15 Token = 6 - DW 368 * 2 ; Index = 15 Token = 7 - DW 224 * 2 ; Index = 15 Token = 8 - DW 224 * 2 ; Index = 15 Token = 9 - DW 224 * 2 ; Index = 15 Token = 10 - DW 224 * 2 ; Index = 15 Token = 11 - DW 272 * 2 ; Index = 15 Token = 12 - DW 304 * 2 ; Index = 15 Token = 13 - DW 336 * 2 ; Index = 15 Token = 14 - DW 368 * 2 ; Index = 15 Token = 15 - DW 240 * 2 ; Index = 16 Token = 0 - DW 240 * 2 ; Index = 16 Token = 1 - DW 240 * 2 ; Index = 16 Token = 2 - DW 240 * 2 ; Index = 16 Token = 3 - DW 288 * 2 ; Index = 16 Token = 4 - DW 320 * 2 ; Index = 16 Token = 5 - DW 352 * 2 ; Index = 16 Token = 6 - DW 384 * 2 ; Index = 16 Token = 7 - DW 240 * 2 ; Index = 16 Token = 8 - DW 240 * 2 ; Index = 16 Token = 9 - DW 240 * 2 ; Index = 16 Token = 10 - DW 240 * 2 ; Index = 16 Token = 11 - DW 288 * 2 ; Index = 16 Token = 12 - DW 320 * 2 ; Index = 16 Token = 13 - DW 352 * 2 ; Index = 16 Token = 14 - DW 384 * 2 ; Index = 16 Token = 15 - DW 256 * 2 ; Index = 17 Token = 0 - DW 256 * 2 ; Index = 17 Token = 1 - DW 256 * 2 ; Index = 17 Token = 2 - DW 256 * 2 ; Index = 17 Token = 3 - DW 304 * 2 ; Index = 17 Token = 4 - DW 336 * 2 ; Index = 17 Token = 5 - DW 368 * 2 ; Index = 17 Token = 6 - DW 400 * 2 ; Index = 17 Token = 7 - DW 256 * 2 ; Index = 17 Token = 8 - DW 256 * 2 ; Index = 17 Token = 9 - DW 256 * 2 ; Index = 17 Token = 10 - DW 256 * 2 ; Index = 17 Token = 11 - DW 304 * 2 ; Index = 17 Token = 12 - DW 336 * 2 ; Index = 17 Token = 13 - DW 368 * 2 ; Index = 17 Token = 14 - DW 400 * 2 ; Index = 17 Token = 15 - DW 272 * 2 ; Index = 18 Token = 0 - DW 272 * 2 ; Index = 18 Token = 1 - DW 272 * 2 ; Index = 18 Token = 2 - DW 272 * 2 ; Index = 18 Token = 3 - DW 320 * 2 ; Index = 18 Token = 4 - DW 352 * 2 ; Index = 18 Token = 5 - DW 384 * 2 ; Index = 18 Token = 6 - DW 416 * 2 ; Index = 18 Token = 7 - DW 272 * 2 ; Index = 18 Token = 8 - DW 272 * 2 ; Index = 18 Token = 9 - DW 272 * 2 ; Index = 18 Token = 10 - DW 272 * 2 ; Index = 18 Token = 11 - DW 320 * 2 ; Index = 18 Token = 12 - DW 352 * 2 ; Index = 18 Token = 13 - DW 384 * 2 ; Index = 18 Token = 14 - DW 416 * 2 ; Index = 18 Token = 15 - DW 288 * 2 ; Index = 19 Token = 0 - DW 288 * 2 ; Index = 19 Token = 1 - DW 288 * 2 ; Index = 19 Token = 2 - DW 288 * 2 ; Index = 19 Token = 3 - DW 336 * 2 ; Index = 19 Token = 4 - DW 368 * 2 ; Index = 19 Token = 5 - DW 400 * 2 ; Index = 19 Token = 6 - DW 432 * 2 ; Index = 19 Token = 7 - DW 288 * 2 ; Index = 19 Token = 8 - DW 288 * 2 ; Index = 19 Token = 9 - DW 288 * 2 ; Index = 19 Token = 10 - DW 288 * 2 ; Index = 19 Token = 11 - DW 336 * 2 ; Index = 19 Token = 12 - DW 368 * 2 ; Index = 19 Token = 13 - DW 400 * 2 ; Index = 19 Token = 14 - DW 432 * 2 ; Index = 19 Token = 15 - DW 304 * 2 ; Index = 20 Token = 0 - DW 304 * 2 ; Index = 20 Token = 1 - DW 304 * 2 ; Index = 20 Token = 2 - DW 304 * 2 ; Index = 20 Token = 3 - DW 352 * 2 ; Index = 20 Token = 4 - DW 384 * 2 ; Index = 20 Token = 5 - DW 416 * 2 ; Index = 20 Token = 6 - DW 448 * 2 ; Index = 20 Token = 7 - DW 304 * 2 ; Index = 20 Token = 8 - DW 304 * 2 ; Index = 20 Token = 9 - DW 304 * 2 ; Index = 20 Token = 10 - DW 304 * 2 ; Index = 20 Token = 11 - DW 352 * 2 ; Index = 20 Token = 12 - DW 384 * 2 ; Index = 20 Token = 13 - DW 416 * 2 ; Index = 20 Token = 14 - DW 448 * 2 ; Index = 20 Token = 15 - DW 320 * 2 ; Index = 21 Token = 0 - DW 320 * 2 ; Index = 21 Token = 1 - DW 320 * 2 ; Index = 21 Token = 2 - DW 320 * 2 ; Index = 21 Token = 3 - DW 368 * 2 ; Index = 21 Token = 4 - DW 400 * 2 ; Index = 21 Token = 5 - DW 432 * 2 ; Index = 21 Token = 6 - DW 464 * 2 ; Index = 21 Token = 7 - DW 320 * 2 ; Index = 21 Token = 8 - DW 320 * 2 ; Index = 21 Token = 9 - DW 320 * 2 ; Index = 21 Token = 10 - DW 320 * 2 ; Index = 21 Token = 11 - DW 368 * 2 ; Index = 21 Token = 12 - DW 400 * 2 ; Index = 21 Token = 13 - DW 432 * 2 ; Index = 21 Token = 14 - DW 464 * 2 ; Index = 21 Token = 15 - DW 336 * 2 ; Index = 22 Token = 0 - DW 336 * 2 ; Index = 22 Token = 1 - DW 336 * 2 ; Index = 22 Token = 2 - DW 336 * 2 ; Index = 22 Token = 3 - DW 384 * 2 ; Index = 22 Token = 4 - DW 416 * 2 ; Index = 22 Token = 5 - DW 448 * 2 ; Index = 22 Token = 6 - DW 480 * 2 ; Index = 22 Token = 7 - DW 336 * 2 ; Index = 22 Token = 8 - DW 336 * 2 ; Index = 22 Token = 9 - DW 336 * 2 ; Index = 22 Token = 10 - DW 336 * 2 ; Index = 22 Token = 11 - DW 384 * 2 ; Index = 22 Token = 12 - DW 416 * 2 ; Index = 22 Token = 13 - DW 448 * 2 ; Index = 22 Token = 14 - DW 480 * 2 ; Index = 22 Token = 15 - DW 352 * 2 ; Index = 23 Token = 0 - DW 352 * 2 ; Index = 23 Token = 1 - DW 352 * 2 ; Index = 23 Token = 2 - DW 352 * 2 ; Index = 23 Token = 3 - DW 400 * 2 ; Index = 23 Token = 4 - DW 432 * 2 ; Index = 23 Token = 5 - DW 464 * 2 ; Index = 23 Token = 6 - DW 496 * 2 ; Index = 23 Token = 7 - DW 352 * 2 ; Index = 23 Token = 8 - DW 352 * 2 ; Index = 23 Token = 9 - DW 352 * 2 ; Index = 23 Token = 10 - DW 352 * 2 ; Index = 23 Token = 11 - DW 400 * 2 ; Index = 23 Token = 12 - DW 432 * 2 ; Index = 23 Token = 13 - DW 464 * 2 ; Index = 23 Token = 14 - DW 496 * 2 ; Index = 23 Token = 15 - DW 368 * 2 ; Index = 24 Token = 0 - DW 368 * 2 ; Index = 24 Token = 1 - DW 368 * 2 ; Index = 24 Token = 2 - DW 368 * 2 ; Index = 24 Token = 3 - DW 416 * 2 ; Index = 24 Token = 4 - DW 448 * 2 ; Index = 24 Token = 5 - DW 480 * 2 ; Index = 24 Token = 6 - DW 512 * 2 ; Index = 24 Token = 7 - DW 368 * 2 ; Index = 24 Token = 8 - DW 368 * 2 ; Index = 24 Token = 9 - DW 368 * 2 ; Index = 24 Token = 10 - DW 368 * 2 ; Index = 24 Token = 11 - DW 416 * 2 ; Index = 24 Token = 12 - DW 448 * 2 ; Index = 24 Token = 13 - DW 480 * 2 ; Index = 24 Token = 14 - DW 512 * 2 ; Index = 24 Token = 15 - DW 384 * 2 ; Index = 25 Token = 0 - DW 384 * 2 ; Index = 25 Token = 1 - DW 384 * 2 ; Index = 25 Token = 2 - DW 384 * 2 ; Index = 25 Token = 3 - DW 432 * 2 ; Index = 25 Token = 4 - DW 464 * 2 ; Index = 25 Token = 5 - DW 496 * 2 ; Index = 25 Token = 6 - DW 528 * 2 ; Index = 25 Token = 7 - DW 384 * 2 ; Index = 25 Token = 8 - DW 384 * 2 ; Index = 25 Token = 9 - DW 384 * 2 ; Index = 25 Token = 10 - DW 384 * 2 ; Index = 25 Token = 11 - DW 432 * 2 ; Index = 25 Token = 12 - DW 464 * 2 ; Index = 25 Token = 13 - DW 496 * 2 ; Index = 25 Token = 14 - DW 528 * 2 ; Index = 25 Token = 15 - DW 400 * 2 ; Index = 26 Token = 0 - DW 400 * 2 ; Index = 26 Token = 1 - DW 400 * 2 ; Index = 26 Token = 2 - DW 400 * 2 ; Index = 26 Token = 3 - DW 448 * 2 ; Index = 26 Token = 4 - DW 480 * 2 ; Index = 26 Token = 5 - DW 512 * 2 ; Index = 26 Token = 6 - DW 544 * 2 ; Index = 26 Token = 7 - DW 400 * 2 ; Index = 26 Token = 8 - DW 400 * 2 ; Index = 26 Token = 9 - DW 400 * 2 ; Index = 26 Token = 10 - DW 400 * 2 ; Index = 26 Token = 11 - DW 448 * 2 ; Index = 26 Token = 12 - DW 480 * 2 ; Index = 26 Token = 13 - DW 512 * 2 ; Index = 26 Token = 14 - DW 544 * 2 ; Index = 26 Token = 15 - DW 416 * 2 ; Index = 27 Token = 0 - DW 416 * 2 ; Index = 27 Token = 1 - DW 416 * 2 ; Index = 27 Token = 2 - DW 416 * 2 ; Index = 27 Token = 3 - DW 464 * 2 ; Index = 27 Token = 4 - DW 496 * 2 ; Index = 27 Token = 5 - DW 528 * 2 ; Index = 27 Token = 6 - DW 560 * 2 ; Index = 27 Token = 7 - DW 416 * 2 ; Index = 27 Token = 8 - DW 416 * 2 ; Index = 27 Token = 9 - DW 416 * 2 ; Index = 27 Token = 10 - DW 416 * 2 ; Index = 27 Token = 11 - DW 464 * 2 ; Index = 27 Token = 12 - DW 496 * 2 ; Index = 27 Token = 13 - DW 528 * 2 ; Index = 27 Token = 14 - DW 560 * 2 ; Index = 27 Token = 15 - DW 432 * 2 ; Index = 28 Token = 0 - DW 432 * 2 ; Index = 28 Token = 1 - DW 432 * 2 ; Index = 28 Token = 2 - DW 432 * 2 ; Index = 28 Token = 3 - DW 480 * 2 ; Index = 28 Token = 4 - DW 512 * 2 ; Index = 28 Token = 5 - DW 544 * 2 ; Index = 28 Token = 6 - DW 576 * 2 ; Index = 28 Token = 7 - DW 432 * 2 ; Index = 28 Token = 8 - DW 432 * 2 ; Index = 28 Token = 9 - DW 432 * 2 ; Index = 28 Token = 10 - DW 432 * 2 ; Index = 28 Token = 11 - DW 480 * 2 ; Index = 28 Token = 12 - DW 512 * 2 ; Index = 28 Token = 13 - DW 544 * 2 ; Index = 28 Token = 14 - DW 576 * 2 ; Index = 28 Token = 15 - DW 448 * 2 ; Index = 29 Token = 0 - DW 448 * 2 ; Index = 29 Token = 1 - DW 448 * 2 ; Index = 29 Token = 2 - DW 448 * 2 ; Index = 29 Token = 3 - DW 496 * 2 ; Index = 29 Token = 4 - DW 528 * 2 ; Index = 29 Token = 5 - DW 560 * 2 ; Index = 29 Token = 6 - DW 592 * 2 ; Index = 29 Token = 7 - DW 448 * 2 ; Index = 29 Token = 8 - DW 448 * 2 ; Index = 29 Token = 9 - DW 448 * 2 ; Index = 29 Token = 10 - DW 448 * 2 ; Index = 29 Token = 11 - DW 496 * 2 ; Index = 29 Token = 12 - DW 528 * 2 ; Index = 29 Token = 13 - DW 560 * 2 ; Index = 29 Token = 14 - DW 592 * 2 ; Index = 29 Token = 15 - DW 464 * 2 ; Index = 30 Token = 0 - DW 464 * 2 ; Index = 30 Token = 1 - DW 464 * 2 ; Index = 30 Token = 2 - DW 464 * 2 ; Index = 30 Token = 3 - DW 512 * 2 ; Index = 30 Token = 4 - DW 544 * 2 ; Index = 30 Token = 5 - DW 576 * 2 ; Index = 30 Token = 6 - DW 608 * 2 ; Index = 30 Token = 7 - DW 464 * 2 ; Index = 30 Token = 8 - DW 464 * 2 ; Index = 30 Token = 9 - DW 464 * 2 ; Index = 30 Token = 10 - DW 464 * 2 ; Index = 30 Token = 11 - DW 512 * 2 ; Index = 30 Token = 12 - DW 544 * 2 ; Index = 30 Token = 13 - DW 576 * 2 ; Index = 30 Token = 14 - DW 608 * 2 ; Index = 30 Token = 15 - DW 480 * 2 ; Index = 31 Token = 0 - DW 480 * 2 ; Index = 31 Token = 1 - DW 480 * 2 ; Index = 31 Token = 2 - DW 480 * 2 ; Index = 31 Token = 3 - DW 528 * 2 ; Index = 31 Token = 4 - DW 560 * 2 ; Index = 31 Token = 5 - DW 592 * 2 ; Index = 31 Token = 6 - DW 624 * 2 ; Index = 31 Token = 7 - DW 480 * 2 ; Index = 31 Token = 8 - DW 480 * 2 ; Index = 31 Token = 9 - DW 480 * 2 ; Index = 31 Token = 10 - DW 480 * 2 ; Index = 31 Token = 11 - DW 528 * 2 ; Index = 31 Token = 12 - DW 560 * 2 ; Index = 31 Token = 13 - DW 592 * 2 ; Index = 31 Token = 14 - DW 624 * 2 ; Index = 31 Token = 15 - DW 496 * 2 ; Index = 32 Token = 0 - DW 496 * 2 ; Index = 32 Token = 1 - DW 496 * 2 ; Index = 32 Token = 2 - DW 496 * 2 ; Index = 32 Token = 3 - DW 544 * 2 ; Index = 32 Token = 4 - DW 576 * 2 ; Index = 32 Token = 5 - DW 608 * 2 ; Index = 32 Token = 6 - DW 640 * 2 ; Index = 32 Token = 7 - DW 496 * 2 ; Index = 32 Token = 8 - DW 496 * 2 ; Index = 32 Token = 9 - DW 496 * 2 ; Index = 32 Token = 10 - DW 496 * 2 ; Index = 32 Token = 11 - DW 544 * 2 ; Index = 32 Token = 12 - DW 576 * 2 ; Index = 32 Token = 13 - DW 608 * 2 ; Index = 32 Token = 14 - DW 640 * 2 ; Index = 32 Token = 15 - DW 512 * 2 ; Index = 33 Token = 0 - DW 512 * 2 ; Index = 33 Token = 1 - DW 512 * 2 ; Index = 33 Token = 2 - DW 512 * 2 ; Index = 33 Token = 3 - DW 560 * 2 ; Index = 33 Token = 4 - DW 592 * 2 ; Index = 33 Token = 5 - DW 624 * 2 ; Index = 33 Token = 6 - DW 656 * 2 ; Index = 33 Token = 7 - DW 512 * 2 ; Index = 33 Token = 8 - DW 512 * 2 ; Index = 33 Token = 9 - DW 512 * 2 ; Index = 33 Token = 10 - DW 512 * 2 ; Index = 33 Token = 11 - DW 560 * 2 ; Index = 33 Token = 12 - DW 592 * 2 ; Index = 33 Token = 13 - DW 624 * 2 ; Index = 33 Token = 14 - DW 656 * 2 ; Index = 33 Token = 15 - DW 528 * 2 ; Index = 34 Token = 0 - DW 528 * 2 ; Index = 34 Token = 1 - DW 528 * 2 ; Index = 34 Token = 2 - DW 528 * 2 ; Index = 34 Token = 3 - DW 576 * 2 ; Index = 34 Token = 4 - DW 608 * 2 ; Index = 34 Token = 5 - DW 640 * 2 ; Index = 34 Token = 6 - DW 672 * 2 ; Index = 34 Token = 7 - DW 528 * 2 ; Index = 34 Token = 8 - DW 528 * 2 ; Index = 34 Token = 9 - DW 528 * 2 ; Index = 34 Token = 10 - DW 528 * 2 ; Index = 34 Token = 11 - DW 576 * 2 ; Index = 34 Token = 12 - DW 608 * 2 ; Index = 34 Token = 13 - DW 640 * 2 ; Index = 34 Token = 14 - DW 672 * 2 ; Index = 34 Token = 15 - DW 544 * 2 ; Index = 35 Token = 0 - DW 544 * 2 ; Index = 35 Token = 1 - DW 544 * 2 ; Index = 35 Token = 2 - DW 544 * 2 ; Index = 35 Token = 3 - DW 592 * 2 ; Index = 35 Token = 4 - DW 624 * 2 ; Index = 35 Token = 5 - DW 656 * 2 ; Index = 35 Token = 6 - DW 688 * 2 ; Index = 35 Token = 7 - DW 544 * 2 ; Index = 35 Token = 8 - DW 544 * 2 ; Index = 35 Token = 9 - DW 544 * 2 ; Index = 35 Token = 10 - DW 544 * 2 ; Index = 35 Token = 11 - DW 592 * 2 ; Index = 35 Token = 12 - DW 624 * 2 ; Index = 35 Token = 13 - DW 656 * 2 ; Index = 35 Token = 14 - DW 688 * 2 ; Index = 35 Token = 15 - DW 560 * 2 ; Index = 36 Token = 0 - DW 560 * 2 ; Index = 36 Token = 1 - DW 560 * 2 ; Index = 36 Token = 2 - DW 560 * 2 ; Index = 36 Token = 3 - DW 608 * 2 ; Index = 36 Token = 4 - DW 640 * 2 ; Index = 36 Token = 5 - DW 672 * 2 ; Index = 36 Token = 6 - DW 704 * 2 ; Index = 36 Token = 7 - DW 560 * 2 ; Index = 36 Token = 8 - DW 560 * 2 ; Index = 36 Token = 9 - DW 560 * 2 ; Index = 36 Token = 10 - DW 560 * 2 ; Index = 36 Token = 11 - DW 608 * 2 ; Index = 36 Token = 12 - DW 640 * 2 ; Index = 36 Token = 13 - DW 672 * 2 ; Index = 36 Token = 14 - DW 704 * 2 ; Index = 36 Token = 15 - DW 576 * 2 ; Index = 37 Token = 0 - DW 576 * 2 ; Index = 37 Token = 1 - DW 576 * 2 ; Index = 37 Token = 2 - DW 576 * 2 ; Index = 37 Token = 3 - DW 624 * 2 ; Index = 37 Token = 4 - DW 656 * 2 ; Index = 37 Token = 5 - DW 688 * 2 ; Index = 37 Token = 6 - DW 720 * 2 ; Index = 37 Token = 7 - DW 576 * 2 ; Index = 37 Token = 8 - DW 576 * 2 ; Index = 37 Token = 9 - DW 576 * 2 ; Index = 37 Token = 10 - DW 576 * 2 ; Index = 37 Token = 11 - DW 624 * 2 ; Index = 37 Token = 12 - DW 656 * 2 ; Index = 37 Token = 13 - DW 688 * 2 ; Index = 37 Token = 14 - DW 720 * 2 ; Index = 37 Token = 15 - DW 592 * 2 ; Index = 38 Token = 0 - DW 592 * 2 ; Index = 38 Token = 1 - DW 592 * 2 ; Index = 38 Token = 2 - DW 592 * 2 ; Index = 38 Token = 3 - DW 640 * 2 ; Index = 38 Token = 4 - DW 672 * 2 ; Index = 38 Token = 5 - DW 704 * 2 ; Index = 38 Token = 6 - DW 736 * 2 ; Index = 38 Token = 7 - DW 592 * 2 ; Index = 38 Token = 8 - DW 592 * 2 ; Index = 38 Token = 9 - DW 592 * 2 ; Index = 38 Token = 10 - DW 592 * 2 ; Index = 38 Token = 11 - DW 640 * 2 ; Index = 38 Token = 12 - DW 672 * 2 ; Index = 38 Token = 13 - DW 704 * 2 ; Index = 38 Token = 14 - DW 736 * 2 ; Index = 38 Token = 15 - DW 608 * 2 ; Index = 39 Token = 0 - DW 608 * 2 ; Index = 39 Token = 1 - DW 608 * 2 ; Index = 39 Token = 2 - DW 608 * 2 ; Index = 39 Token = 3 - DW 656 * 2 ; Index = 39 Token = 4 - DW 688 * 2 ; Index = 39 Token = 5 - DW 720 * 2 ; Index = 39 Token = 6 - DW 752 * 2 ; Index = 39 Token = 7 - DW 608 * 2 ; Index = 39 Token = 8 - DW 608 * 2 ; Index = 39 Token = 9 - DW 608 * 2 ; Index = 39 Token = 10 - DW 608 * 2 ; Index = 39 Token = 11 - DW 656 * 2 ; Index = 39 Token = 12 - DW 688 * 2 ; Index = 39 Token = 13 - DW 720 * 2 ; Index = 39 Token = 14 - DW 752 * 2 ; Index = 39 Token = 15 - DW 624 * 2 ; Index = 40 Token = 0 - DW 624 * 2 ; Index = 40 Token = 1 - DW 624 * 2 ; Index = 40 Token = 2 - DW 624 * 2 ; Index = 40 Token = 3 - DW 672 * 2 ; Index = 40 Token = 4 - DW 704 * 2 ; Index = 40 Token = 5 - DW 736 * 2 ; Index = 40 Token = 6 - DW 768 * 2 ; Index = 40 Token = 7 - DW 624 * 2 ; Index = 40 Token = 8 - DW 624 * 2 ; Index = 40 Token = 9 - DW 624 * 2 ; Index = 40 Token = 10 - DW 624 * 2 ; Index = 40 Token = 11 - DW 672 * 2 ; Index = 40 Token = 12 - DW 704 * 2 ; Index = 40 Token = 13 - DW 736 * 2 ; Index = 40 Token = 14 - DW 768 * 2 ; Index = 40 Token = 15 - DW 640 * 2 ; Index = 41 Token = 0 - DW 640 * 2 ; Index = 41 Token = 1 - DW 640 * 2 ; Index = 41 Token = 2 - DW 640 * 2 ; Index = 41 Token = 3 - DW 688 * 2 ; Index = 41 Token = 4 - DW 720 * 2 ; Index = 41 Token = 5 - DW 752 * 2 ; Index = 41 Token = 6 - DW 784 * 2 ; Index = 41 Token = 7 - DW 640 * 2 ; Index = 41 Token = 8 - DW 640 * 2 ; Index = 41 Token = 9 - DW 640 * 2 ; Index = 41 Token = 10 - DW 640 * 2 ; Index = 41 Token = 11 - DW 688 * 2 ; Index = 41 Token = 12 - DW 720 * 2 ; Index = 41 Token = 13 - DW 752 * 2 ; Index = 41 Token = 14 - DW 784 * 2 ; Index = 41 Token = 15 - DW 656 * 2 ; Index = 42 Token = 0 - DW 656 * 2 ; Index = 42 Token = 1 - DW 656 * 2 ; Index = 42 Token = 2 - DW 656 * 2 ; Index = 42 Token = 3 - DW 704 * 2 ; Index = 42 Token = 4 - DW 736 * 2 ; Index = 42 Token = 5 - DW 768 * 2 ; Index = 42 Token = 6 - DW 800 * 2 ; Index = 42 Token = 7 - DW 656 * 2 ; Index = 42 Token = 8 - DW 656 * 2 ; Index = 42 Token = 9 - DW 656 * 2 ; Index = 42 Token = 10 - DW 656 * 2 ; Index = 42 Token = 11 - DW 704 * 2 ; Index = 42 Token = 12 - DW 736 * 2 ; Index = 42 Token = 13 - DW 768 * 2 ; Index = 42 Token = 14 - DW 800 * 2 ; Index = 42 Token = 15 - DW 672 * 2 ; Index = 43 Token = 0 - DW 672 * 2 ; Index = 43 Token = 1 - DW 672 * 2 ; Index = 43 Token = 2 - DW 672 * 2 ; Index = 43 Token = 3 - DW 720 * 2 ; Index = 43 Token = 4 - DW 752 * 2 ; Index = 43 Token = 5 - DW 784 * 2 ; Index = 43 Token = 6 - DW 816 * 2 ; Index = 43 Token = 7 - DW 672 * 2 ; Index = 43 Token = 8 - DW 672 * 2 ; Index = 43 Token = 9 - DW 672 * 2 ; Index = 43 Token = 10 - DW 672 * 2 ; Index = 43 Token = 11 - DW 720 * 2 ; Index = 43 Token = 12 - DW 752 * 2 ; Index = 43 Token = 13 - DW 784 * 2 ; Index = 43 Token = 14 - DW 816 * 2 ; Index = 43 Token = 15 - DW 688 * 2 ; Index = 44 Token = 0 - DW 688 * 2 ; Index = 44 Token = 1 - DW 688 * 2 ; Index = 44 Token = 2 - DW 688 * 2 ; Index = 44 Token = 3 - DW 736 * 2 ; Index = 44 Token = 4 - DW 768 * 2 ; Index = 44 Token = 5 - DW 800 * 2 ; Index = 44 Token = 6 - DW 832 * 2 ; Index = 44 Token = 7 - DW 688 * 2 ; Index = 44 Token = 8 - DW 688 * 2 ; Index = 44 Token = 9 - DW 688 * 2 ; Index = 44 Token = 10 - DW 688 * 2 ; Index = 44 Token = 11 - DW 736 * 2 ; Index = 44 Token = 12 - DW 768 * 2 ; Index = 44 Token = 13 - DW 800 * 2 ; Index = 44 Token = 14 - DW 832 * 2 ; Index = 44 Token = 15 - DW 704 * 2 ; Index = 45 Token = 0 - DW 704 * 2 ; Index = 45 Token = 1 - DW 704 * 2 ; Index = 45 Token = 2 - DW 704 * 2 ; Index = 45 Token = 3 - DW 752 * 2 ; Index = 45 Token = 4 - DW 784 * 2 ; Index = 45 Token = 5 - DW 816 * 2 ; Index = 45 Token = 6 - DW 848 * 2 ; Index = 45 Token = 7 - DW 704 * 2 ; Index = 45 Token = 8 - DW 704 * 2 ; Index = 45 Token = 9 - DW 704 * 2 ; Index = 45 Token = 10 - DW 704 * 2 ; Index = 45 Token = 11 - DW 752 * 2 ; Index = 45 Token = 12 - DW 784 * 2 ; Index = 45 Token = 13 - DW 816 * 2 ; Index = 45 Token = 14 - DW 848 * 2 ; Index = 45 Token = 15 - DW 720 * 2 ; Index = 46 Token = 0 - DW 720 * 2 ; Index = 46 Token = 1 - DW 720 * 2 ; Index = 46 Token = 2 - DW 720 * 2 ; Index = 46 Token = 3 - DW 768 * 2 ; Index = 46 Token = 4 - DW 800 * 2 ; Index = 46 Token = 5 - DW 832 * 2 ; Index = 46 Token = 6 - DW 864 * 2 ; Index = 46 Token = 7 - DW 720 * 2 ; Index = 46 Token = 8 - DW 720 * 2 ; Index = 46 Token = 9 - DW 720 * 2 ; Index = 46 Token = 10 - DW 720 * 2 ; Index = 46 Token = 11 - DW 768 * 2 ; Index = 46 Token = 12 - DW 800 * 2 ; Index = 46 Token = 13 - DW 832 * 2 ; Index = 46 Token = 14 - DW 864 * 2 ; Index = 46 Token = 15 - DW 736 * 2 ; Index = 47 Token = 0 - DW 736 * 2 ; Index = 47 Token = 1 - DW 736 * 2 ; Index = 47 Token = 2 - DW 736 * 2 ; Index = 47 Token = 3 - DW 784 * 2 ; Index = 47 Token = 4 - DW 816 * 2 ; Index = 47 Token = 5 - DW 848 * 2 ; Index = 47 Token = 6 - DW 880 * 2 ; Index = 47 Token = 7 - DW 736 * 2 ; Index = 47 Token = 8 - DW 736 * 2 ; Index = 47 Token = 9 - DW 736 * 2 ; Index = 47 Token = 10 - DW 736 * 2 ; Index = 47 Token = 11 - DW 784 * 2 ; Index = 47 Token = 12 - DW 816 * 2 ; Index = 47 Token = 13 - DW 848 * 2 ; Index = 47 Token = 14 - DW 880 * 2 ; Index = 47 Token = 15 - DW 752 * 2 ; Index = 48 Token = 0 - DW 752 * 2 ; Index = 48 Token = 1 - DW 752 * 2 ; Index = 48 Token = 2 - DW 752 * 2 ; Index = 48 Token = 3 - DW 800 * 2 ; Index = 48 Token = 4 - DW 832 * 2 ; Index = 48 Token = 5 - DW 864 * 2 ; Index = 48 Token = 6 - DW 896 * 2 ; Index = 48 Token = 7 - DW 752 * 2 ; Index = 48 Token = 8 - DW 752 * 2 ; Index = 48 Token = 9 - DW 752 * 2 ; Index = 48 Token = 10 - DW 752 * 2 ; Index = 48 Token = 11 - DW 800 * 2 ; Index = 48 Token = 12 - DW 832 * 2 ; Index = 48 Token = 13 - DW 864 * 2 ; Index = 48 Token = 14 - DW 896 * 2 ; Index = 48 Token = 15 - DW 768 * 2 ; Index = 49 Token = 0 - DW 768 * 2 ; Index = 49 Token = 1 - DW 768 * 2 ; Index = 49 Token = 2 - DW 768 * 2 ; Index = 49 Token = 3 - DW 816 * 2 ; Index = 49 Token = 4 - DW 848 * 2 ; Index = 49 Token = 5 - DW 880 * 2 ; Index = 49 Token = 6 - DW 912 * 2 ; Index = 49 Token = 7 - DW 768 * 2 ; Index = 49 Token = 8 - DW 768 * 2 ; Index = 49 Token = 9 - DW 768 * 2 ; Index = 49 Token = 10 - DW 768 * 2 ; Index = 49 Token = 11 - DW 816 * 2 ; Index = 49 Token = 12 - DW 848 * 2 ; Index = 49 Token = 13 - DW 880 * 2 ; Index = 49 Token = 14 - DW 912 * 2 ; Index = 49 Token = 15 - DW 784 * 2 ; Index = 50 Token = 0 - DW 784 * 2 ; Index = 50 Token = 1 - DW 784 * 2 ; Index = 50 Token = 2 - DW 784 * 2 ; Index = 50 Token = 3 - DW 832 * 2 ; Index = 50 Token = 4 - DW 864 * 2 ; Index = 50 Token = 5 - DW 896 * 2 ; Index = 50 Token = 6 - DW 928 * 2 ; Index = 50 Token = 7 - DW 784 * 2 ; Index = 50 Token = 8 - DW 784 * 2 ; Index = 50 Token = 9 - DW 784 * 2 ; Index = 50 Token = 10 - DW 784 * 2 ; Index = 50 Token = 11 - DW 832 * 2 ; Index = 50 Token = 12 - DW 864 * 2 ; Index = 50 Token = 13 - DW 896 * 2 ; Index = 50 Token = 14 - DW 928 * 2 ; Index = 50 Token = 15 - DW 800 * 2 ; Index = 51 Token = 0 - DW 800 * 2 ; Index = 51 Token = 1 - DW 800 * 2 ; Index = 51 Token = 2 - DW 800 * 2 ; Index = 51 Token = 3 - DW 848 * 2 ; Index = 51 Token = 4 - DW 880 * 2 ; Index = 51 Token = 5 - DW 912 * 2 ; Index = 51 Token = 6 - DW 944 * 2 ; Index = 51 Token = 7 - DW 800 * 2 ; Index = 51 Token = 8 - DW 800 * 2 ; Index = 51 Token = 9 - DW 800 * 2 ; Index = 51 Token = 10 - DW 800 * 2 ; Index = 51 Token = 11 - DW 848 * 2 ; Index = 51 Token = 12 - DW 880 * 2 ; Index = 51 Token = 13 - DW 912 * 2 ; Index = 51 Token = 14 - DW 944 * 2 ; Index = 51 Token = 15 - DW 816 * 2 ; Index = 52 Token = 0 - DW 816 * 2 ; Index = 52 Token = 1 - DW 816 * 2 ; Index = 52 Token = 2 - DW 816 * 2 ; Index = 52 Token = 3 - DW 864 * 2 ; Index = 52 Token = 4 - DW 896 * 2 ; Index = 52 Token = 5 - DW 928 * 2 ; Index = 52 Token = 6 - DW 960 * 2 ; Index = 52 Token = 7 - DW 816 * 2 ; Index = 52 Token = 8 - DW 816 * 2 ; Index = 52 Token = 9 - DW 816 * 2 ; Index = 52 Token = 10 - DW 816 * 2 ; Index = 52 Token = 11 - DW 864 * 2 ; Index = 52 Token = 12 - DW 896 * 2 ; Index = 52 Token = 13 - DW 928 * 2 ; Index = 52 Token = 14 - DW 960 * 2 ; Index = 52 Token = 15 - DW 832 * 2 ; Index = 53 Token = 0 - DW 832 * 2 ; Index = 53 Token = 1 - DW 832 * 2 ; Index = 53 Token = 2 - DW 832 * 2 ; Index = 53 Token = 3 - DW 880 * 2 ; Index = 53 Token = 4 - DW 912 * 2 ; Index = 53 Token = 5 - DW 944 * 2 ; Index = 53 Token = 6 - DW 976 * 2 ; Index = 53 Token = 7 - DW 832 * 2 ; Index = 53 Token = 8 - DW 832 * 2 ; Index = 53 Token = 9 - DW 832 * 2 ; Index = 53 Token = 10 - DW 832 * 2 ; Index = 53 Token = 11 - DW 880 * 2 ; Index = 53 Token = 12 - DW 912 * 2 ; Index = 53 Token = 13 - DW 944 * 2 ; Index = 53 Token = 14 - DW 976 * 2 ; Index = 53 Token = 15 - DW 848 * 2 ; Index = 54 Token = 0 - DW 848 * 2 ; Index = 54 Token = 1 - DW 848 * 2 ; Index = 54 Token = 2 - DW 848 * 2 ; Index = 54 Token = 3 - DW 896 * 2 ; Index = 54 Token = 4 - DW 928 * 2 ; Index = 54 Token = 5 - DW 960 * 2 ; Index = 54 Token = 6 - DW 992 * 2 ; Index = 54 Token = 7 - DW 848 * 2 ; Index = 54 Token = 8 - DW 848 * 2 ; Index = 54 Token = 9 - DW 848 * 2 ; Index = 54 Token = 10 - DW 848 * 2 ; Index = 54 Token = 11 - DW 896 * 2 ; Index = 54 Token = 12 - DW 928 * 2 ; Index = 54 Token = 13 - DW 960 * 2 ; Index = 54 Token = 14 - DW 992 * 2 ; Index = 54 Token = 15 - DW 864 * 2 ; Index = 55 Token = 0 - DW 864 * 2 ; Index = 55 Token = 1 - DW 864 * 2 ; Index = 55 Token = 2 - DW 864 * 2 ; Index = 55 Token = 3 - DW 912 * 2 ; Index = 55 Token = 4 - DW 944 * 2 ; Index = 55 Token = 5 - DW 976 * 2 ; Index = 55 Token = 6 - DW 1008 * 2 ; Index = 55 Token = 7 - DW 864 * 2 ; Index = 55 Token = 8 - DW 864 * 2 ; Index = 55 Token = 9 - DW 864 * 2 ; Index = 55 Token = 10 - DW 864 * 2 ; Index = 55 Token = 11 - DW 912 * 2 ; Index = 55 Token = 12 - DW 944 * 2 ; Index = 55 Token = 13 - DW 976 * 2 ; Index = 55 Token = 14 - DW 1008 * 2 ; Index = 55 Token = 15 - DW 880 * 2 ; Index = 56 Token = 0 - DW 880 * 2 ; Index = 56 Token = 1 - DW 880 * 2 ; Index = 56 Token = 2 - DW 880 * 2 ; Index = 56 Token = 3 - DW 928 * 2 ; Index = 56 Token = 4 - DW 960 * 2 ; Index = 56 Token = 5 - DW 992 * 2 ; Index = 56 Token = 6 - DW 1024 * 2 ; Index = 56 Token = 7 - DW 880 * 2 ; Index = 56 Token = 8 - DW 880 * 2 ; Index = 56 Token = 9 - DW 880 * 2 ; Index = 56 Token = 10 - DW 880 * 2 ; Index = 56 Token = 11 - DW 928 * 2 ; Index = 56 Token = 12 - DW 960 * 2 ; Index = 56 Token = 13 - DW 992 * 2 ; Index = 56 Token = 14 - DW 1024 * 2 ; Index = 56 Token = 15 - DW 896 * 2 ; Index = 57 Token = 0 - DW 896 * 2 ; Index = 57 Token = 1 - DW 896 * 2 ; Index = 57 Token = 2 - DW 896 * 2 ; Index = 57 Token = 3 - DW 944 * 2 ; Index = 57 Token = 4 - DW 976 * 2 ; Index = 57 Token = 5 - DW 1008 * 2 ; Index = 57 Token = 6 - DW 1040 * 2 ; Index = 57 Token = 7 - DW 896 * 2 ; Index = 57 Token = 8 - DW 896 * 2 ; Index = 57 Token = 9 - DW 896 * 2 ; Index = 57 Token = 10 - DW 896 * 2 ; Index = 57 Token = 11 - DW 944 * 2 ; Index = 57 Token = 12 - DW 976 * 2 ; Index = 57 Token = 13 - DW 1008 * 2 ; Index = 57 Token = 14 - DW 1040 * 2 ; Index = 57 Token = 15 - DW 912 * 2 ; Index = 58 Token = 0 - DW 912 * 2 ; Index = 58 Token = 1 - DW 912 * 2 ; Index = 58 Token = 2 - DW 912 * 2 ; Index = 58 Token = 3 - DW 960 * 2 ; Index = 58 Token = 4 - DW 992 * 2 ; Index = 58 Token = 5 - DW 1024 * 2 ; Index = 58 Token = 6 - DW 1056 * 2 ; Index = 58 Token = 7 - DW 912 * 2 ; Index = 58 Token = 8 - DW 912 * 2 ; Index = 58 Token = 9 - DW 912 * 2 ; Index = 58 Token = 10 - DW 912 * 2 ; Index = 58 Token = 11 - DW 960 * 2 ; Index = 58 Token = 12 - DW 992 * 2 ; Index = 58 Token = 13 - DW 1024 * 2 ; Index = 58 Token = 14 - DW 1056 * 2 ; Index = 58 Token = 15 - DW 928 * 2 ; Index = 59 Token = 0 - DW 928 * 2 ; Index = 59 Token = 1 - DW 928 * 2 ; Index = 59 Token = 2 - DW 928 * 2 ; Index = 59 Token = 3 - DW 976 * 2 ; Index = 59 Token = 4 - DW 1008 * 2 ; Index = 59 Token = 5 - DW 1040 * 2 ; Index = 59 Token = 6 - DW 1072 * 2 ; Index = 59 Token = 7 - DW 928 * 2 ; Index = 59 Token = 8 - DW 928 * 2 ; Index = 59 Token = 9 - DW 928 * 2 ; Index = 59 Token = 10 - DW 928 * 2 ; Index = 59 Token = 11 - DW 976 * 2 ; Index = 59 Token = 12 - DW 1008 * 2 ; Index = 59 Token = 13 - DW 1040 * 2 ; Index = 59 Token = 14 - DW 1072 * 2 ; Index = 59 Token = 15 - DW 944 * 2 ; Index = 60 Token = 0 - DW 944 * 2 ; Index = 60 Token = 1 - DW 944 * 2 ; Index = 60 Token = 2 - DW 944 * 2 ; Index = 60 Token = 3 - DW 992 * 2 ; Index = 60 Token = 4 - DW 1024 * 2 ; Index = 60 Token = 5 - DW 1056 * 2 ; Index = 60 Token = 6 - DW 1088 * 2 ; Index = 60 Token = 7 - DW 944 * 2 ; Index = 60 Token = 8 - DW 944 * 2 ; Index = 60 Token = 9 - DW 944 * 2 ; Index = 60 Token = 10 - DW 944 * 2 ; Index = 60 Token = 11 - DW 992 * 2 ; Index = 60 Token = 12 - DW 1024 * 2 ; Index = 60 Token = 13 - DW 1056 * 2 ; Index = 60 Token = 14 - DW 1088 * 2 ; Index = 60 Token = 15 - DW 960 * 2 ; Index = 61 Token = 0 - DW 960 * 2 ; Index = 61 Token = 1 - DW 960 * 2 ; Index = 61 Token = 2 - DW 960 * 2 ; Index = 61 Token = 3 - DW 1008 * 2 ; Index = 61 Token = 4 - DW 1040 * 2 ; Index = 61 Token = 5 - DW 1072 * 2 ; Index = 61 Token = 6 - DW 1104 * 2 ; Index = 61 Token = 7 - DW 960 * 2 ; Index = 61 Token = 8 - DW 960 * 2 ; Index = 61 Token = 9 - DW 960 * 2 ; Index = 61 Token = 10 - DW 960 * 2 ; Index = 61 Token = 11 - DW 1008 * 2 ; Index = 61 Token = 12 - DW 1040 * 2 ; Index = 61 Token = 13 - DW 1072 * 2 ; Index = 61 Token = 14 - DW 1104 * 2 ; Index = 61 Token = 15 - DW 976 * 2 ; Index = 62 Token = 0 - DW 976 * 2 ; Index = 62 Token = 1 - DW 976 * 2 ; Index = 62 Token = 2 - DW 976 * 2 ; Index = 62 Token = 3 - DW 1024 * 2 ; Index = 62 Token = 4 - DW 1056 * 2 ; Index = 62 Token = 5 - DW 1088 * 2 ; Index = 62 Token = 6 - DW 1120 * 2 ; Index = 62 Token = 7 - DW 976 * 2 ; Index = 62 Token = 8 - DW 976 * 2 ; Index = 62 Token = 9 - DW 976 * 2 ; Index = 62 Token = 10 - DW 976 * 2 ; Index = 62 Token = 11 - DW 1024 * 2 ; Index = 62 Token = 12 - DW 1056 * 2 ; Index = 62 Token = 13 - DW 1088 * 2 ; Index = 62 Token = 14 - DW 1120 * 2 ; Index = 62 Token = 15 - DW 992 * 2 ; Index = 63 Token = 0 - DW 992 * 2 ; Index = 63 Token = 1 - DW 992 * 2 ; Index = 63 Token = 2 - DW 992 * 2 ; Index = 63 Token = 3 - DW 1040 * 2 ; Index = 63 Token = 4 - DW 1072 * 2 ; Index = 63 Token = 5 - DW 1104 * 2 ; Index = 63 Token = 6 - DW 1136 * 2 ; Index = 63 Token = 7 - DW 992 * 2 ; Index = 63 Token = 8 - DW 992 * 2 ; Index = 63 Token = 9 - DW 992 * 2 ; Index = 63 Token = 10 - DW 992 * 2 ; Index = 63 Token = 11 - DW 1040 * 2 ; Index = 63 Token = 12 - DW 1072 * 2 ; Index = 63 Token = 13 - DW 1104 * 2 ; Index = 63 Token = 14 - DW 1136 * 2 ; Index = 63 Token = 15 - DW 1008 * 2 ; Index = 64 Token = 0 - DW 1008 * 2 ; Index = 64 Token = 1 - DW 1008 * 2 ; Index = 64 Token = 2 - DW 1008 * 2 ; Index = 64 Token = 3 - DW 1056 * 2 ; Index = 64 Token = 4 - DW 1088 * 2 ; Index = 64 Token = 5 - DW 1120 * 2 ; Index = 64 Token = 6 - DW 1152 * 2 ; Index = 64 Token = 7 - DW 1008 * 2 ; Index = 64 Token = 8 - DW 1008 * 2 ; Index = 64 Token = 9 - DW 1008 * 2 ; Index = 64 Token = 10 - DW 1008 * 2 ; Index = 64 Token = 11 - DW 1056 * 2 ; Index = 64 Token = 12 - DW 1088 * 2 ; Index = 64 Token = 13 - DW 1120 * 2 ; Index = 64 Token = 14 - DW 1152 * 2 ; Index = 64 Token = 15 - DW 1024 * 2 ; Index = 65 Token = 0 - DW 1024 * 2 ; Index = 65 Token = 1 - DW 1024 * 2 ; Index = 65 Token = 2 - DW 1024 * 2 ; Index = 65 Token = 3 - DW 1072 * 2 ; Index = 65 Token = 4 - DW 1104 * 2 ; Index = 65 Token = 5 - DW 1136 * 2 ; Index = 65 Token = 6 - DW 1168 * 2 ; Index = 65 Token = 7 - DW 1024 * 2 ; Index = 65 Token = 8 - DW 1024 * 2 ; Index = 65 Token = 9 - DW 1024 * 2 ; Index = 65 Token = 10 - DW 1024 * 2 ; Index = 65 Token = 11 - DW 1072 * 2 ; Index = 65 Token = 12 - DW 1104 * 2 ; Index = 65 Token = 13 - DW 1136 * 2 ; Index = 65 Token = 14 - DW 1168 * 2 ; Index = 65 Token = 15 - DW 1040 * 2 ; Index = 66 Token = 0 - DW 1040 * 2 ; Index = 66 Token = 1 - DW 1040 * 2 ; Index = 66 Token = 2 - DW 1040 * 2 ; Index = 66 Token = 3 - DW 1088 * 2 ; Index = 66 Token = 4 - DW 1120 * 2 ; Index = 66 Token = 5 - DW 1152 * 2 ; Index = 66 Token = 6 - DW 1184 * 2 ; Index = 66 Token = 7 - DW 1040 * 2 ; Index = 66 Token = 8 - DW 1040 * 2 ; Index = 66 Token = 9 - DW 1040 * 2 ; Index = 66 Token = 10 - DW 1040 * 2 ; Index = 66 Token = 11 - DW 1088 * 2 ; Index = 66 Token = 12 - DW 1120 * 2 ; Index = 66 Token = 13 - DW 1152 * 2 ; Index = 66 Token = 14 - DW 1184 * 2 ; Index = 66 Token = 15 - DW 1056 * 2 ; Index = 67 Token = 0 - DW 1056 * 2 ; Index = 67 Token = 1 - DW 1056 * 2 ; Index = 67 Token = 2 - DW 1056 * 2 ; Index = 67 Token = 3 - DW 1104 * 2 ; Index = 67 Token = 4 - DW 1136 * 2 ; Index = 67 Token = 5 - DW 1168 * 2 ; Index = 67 Token = 6 - DW 1200 * 2 ; Index = 67 Token = 7 - DW 1056 * 2 ; Index = 67 Token = 8 - DW 1056 * 2 ; Index = 67 Token = 9 - DW 1056 * 2 ; Index = 67 Token = 10 - DW 1056 * 2 ; Index = 67 Token = 11 - DW 1104 * 2 ; Index = 67 Token = 12 - DW 1136 * 2 ; Index = 67 Token = 13 - DW 1168 * 2 ; Index = 67 Token = 14 - DW 1200 * 2 ; Index = 67 Token = 15 - DW 1072 * 2 ; Index = 68 Token = 0 - DW 1072 * 2 ; Index = 68 Token = 1 - DW 1072 * 2 ; Index = 68 Token = 2 - DW 1072 * 2 ; Index = 68 Token = 3 - DW 1120 * 2 ; Index = 68 Token = 4 - DW 1152 * 2 ; Index = 68 Token = 5 - DW 1184 * 2 ; Index = 68 Token = 6 - DW 1216 * 2 ; Index = 68 Token = 7 - DW 1072 * 2 ; Index = 68 Token = 8 - DW 1072 * 2 ; Index = 68 Token = 9 - DW 1072 * 2 ; Index = 68 Token = 10 - DW 1072 * 2 ; Index = 68 Token = 11 - DW 1120 * 2 ; Index = 68 Token = 12 - DW 1152 * 2 ; Index = 68 Token = 13 - DW 1184 * 2 ; Index = 68 Token = 14 - DW 1216 * 2 ; Index = 68 Token = 15 - DW 1088 * 2 ; Index = 69 Token = 0 - DW 1088 * 2 ; Index = 69 Token = 1 - DW 1088 * 2 ; Index = 69 Token = 2 - DW 1088 * 2 ; Index = 69 Token = 3 - DW 1136 * 2 ; Index = 69 Token = 4 - DW 1168 * 2 ; Index = 69 Token = 5 - DW 1200 * 2 ; Index = 69 Token = 6 - DW 1232 * 2 ; Index = 69 Token = 7 - DW 1088 * 2 ; Index = 69 Token = 8 - DW 1088 * 2 ; Index = 69 Token = 9 - DW 1088 * 2 ; Index = 69 Token = 10 - DW 1088 * 2 ; Index = 69 Token = 11 - DW 1136 * 2 ; Index = 69 Token = 12 - DW 1168 * 2 ; Index = 69 Token = 13 - DW 1200 * 2 ; Index = 69 Token = 14 - DW 1232 * 2 ; Index = 69 Token = 15 - DW 1104 * 2 ; Index = 70 Token = 0 - DW 1104 * 2 ; Index = 70 Token = 1 - DW 1104 * 2 ; Index = 70 Token = 2 - DW 1104 * 2 ; Index = 70 Token = 3 - DW 1152 * 2 ; Index = 70 Token = 4 - DW 1184 * 2 ; Index = 70 Token = 5 - DW 1216 * 2 ; Index = 70 Token = 6 - DW 1248 * 2 ; Index = 70 Token = 7 - DW 1104 * 2 ; Index = 70 Token = 8 - DW 1104 * 2 ; Index = 70 Token = 9 - DW 1104 * 2 ; Index = 70 Token = 10 - DW 1104 * 2 ; Index = 70 Token = 11 - DW 1152 * 2 ; Index = 70 Token = 12 - DW 1184 * 2 ; Index = 70 Token = 13 - DW 1216 * 2 ; Index = 70 Token = 14 - DW 1248 * 2 ; Index = 70 Token = 15 - DW 1120 * 2 ; Index = 71 Token = 0 - DW 1120 * 2 ; Index = 71 Token = 1 - DW 1120 * 2 ; Index = 71 Token = 2 - DW 1120 * 2 ; Index = 71 Token = 3 - DW 1168 * 2 ; Index = 71 Token = 4 - DW 1200 * 2 ; Index = 71 Token = 5 - DW 1232 * 2 ; Index = 71 Token = 6 - DW 1264 * 2 ; Index = 71 Token = 7 - DW 1120 * 2 ; Index = 71 Token = 8 - DW 1120 * 2 ; Index = 71 Token = 9 - DW 1120 * 2 ; Index = 71 Token = 10 - DW 1120 * 2 ; Index = 71 Token = 11 - DW 1168 * 2 ; Index = 71 Token = 12 - DW 1200 * 2 ; Index = 71 Token = 13 - DW 1232 * 2 ; Index = 71 Token = 14 - DW 1264 * 2 ; Index = 71 Token = 15 - DW 1136 * 2 ; Index = 72 Token = 0 - DW 1136 * 2 ; Index = 72 Token = 1 - DW 1136 * 2 ; Index = 72 Token = 2 - DW 1136 * 2 ; Index = 72 Token = 3 - DW 1184 * 2 ; Index = 72 Token = 4 - DW 1216 * 2 ; Index = 72 Token = 5 - DW 1248 * 2 ; Index = 72 Token = 6 - DW 1280 * 2 ; Index = 72 Token = 7 - DW 1136 * 2 ; Index = 72 Token = 8 - DW 1136 * 2 ; Index = 72 Token = 9 - DW 1136 * 2 ; Index = 72 Token = 10 - DW 1136 * 2 ; Index = 72 Token = 11 - DW 1184 * 2 ; Index = 72 Token = 12 - DW 1216 * 2 ; Index = 72 Token = 13 - DW 1248 * 2 ; Index = 72 Token = 14 - DW 1280 * 2 ; Index = 72 Token = 15 - DW 1152 * 2 ; Index = 73 Token = 0 - DW 1152 * 2 ; Index = 73 Token = 1 - DW 1152 * 2 ; Index = 73 Token = 2 - DW 1152 * 2 ; Index = 73 Token = 3 - DW 1200 * 2 ; Index = 73 Token = 4 - DW 1232 * 2 ; Index = 73 Token = 5 - DW 1264 * 2 ; Index = 73 Token = 6 - DW 1296 * 2 ; Index = 73 Token = 7 - DW 1152 * 2 ; Index = 73 Token = 8 - DW 1152 * 2 ; Index = 73 Token = 9 - DW 1152 * 2 ; Index = 73 Token = 10 - DW 1152 * 2 ; Index = 73 Token = 11 - DW 1200 * 2 ; Index = 73 Token = 12 - DW 1232 * 2 ; Index = 73 Token = 13 - DW 1264 * 2 ; Index = 73 Token = 14 - DW 1296 * 2 ; Index = 73 Token = 15 - DW 1168 * 2 ; Index = 74 Token = 0 - DW 1168 * 2 ; Index = 74 Token = 1 - DW 1168 * 2 ; Index = 74 Token = 2 - DW 1168 * 2 ; Index = 74 Token = 3 - DW 1216 * 2 ; Index = 74 Token = 4 - DW 1248 * 2 ; Index = 74 Token = 5 - DW 1280 * 2 ; Index = 74 Token = 6 - DW 1312 * 2 ; Index = 74 Token = 7 - DW 1168 * 2 ; Index = 74 Token = 8 - DW 1168 * 2 ; Index = 74 Token = 9 - DW 1168 * 2 ; Index = 74 Token = 10 - DW 1168 * 2 ; Index = 74 Token = 11 - DW 1216 * 2 ; Index = 74 Token = 12 - DW 1248 * 2 ; Index = 74 Token = 13 - DW 1280 * 2 ; Index = 74 Token = 14 - DW 1312 * 2 ; Index = 74 Token = 15 - DW 1184 * 2 ; Index = 75 Token = 0 - DW 1184 * 2 ; Index = 75 Token = 1 - DW 1184 * 2 ; Index = 75 Token = 2 - DW 1184 * 2 ; Index = 75 Token = 3 - DW 1232 * 2 ; Index = 75 Token = 4 - DW 1264 * 2 ; Index = 75 Token = 5 - DW 1296 * 2 ; Index = 75 Token = 6 - DW 1328 * 2 ; Index = 75 Token = 7 - DW 1184 * 2 ; Index = 75 Token = 8 - DW 1184 * 2 ; Index = 75 Token = 9 - DW 1184 * 2 ; Index = 75 Token = 10 - DW 1184 * 2 ; Index = 75 Token = 11 - DW 1232 * 2 ; Index = 75 Token = 12 - DW 1264 * 2 ; Index = 75 Token = 13 - DW 1296 * 2 ; Index = 75 Token = 14 - DW 1328 * 2 ; Index = 75 Token = 15 - DW 1200 * 2 ; Index = 76 Token = 0 - DW 1200 * 2 ; Index = 76 Token = 1 - DW 1200 * 2 ; Index = 76 Token = 2 - DW 1200 * 2 ; Index = 76 Token = 3 - DW 1248 * 2 ; Index = 76 Token = 4 - DW 1280 * 2 ; Index = 76 Token = 5 - DW 1312 * 2 ; Index = 76 Token = 6 - DW 1344 * 2 ; Index = 76 Token = 7 - DW 1200 * 2 ; Index = 76 Token = 8 - DW 1200 * 2 ; Index = 76 Token = 9 - DW 1200 * 2 ; Index = 76 Token = 10 - DW 1200 * 2 ; Index = 76 Token = 11 - DW 1248 * 2 ; Index = 76 Token = 12 - DW 1280 * 2 ; Index = 76 Token = 13 - DW 1312 * 2 ; Index = 76 Token = 14 - DW 1344 * 2 ; Index = 76 Token = 15 - DW 1216 * 2 ; Index = 77 Token = 0 - DW 1216 * 2 ; Index = 77 Token = 1 - DW 1216 * 2 ; Index = 77 Token = 2 - DW 1216 * 2 ; Index = 77 Token = 3 - DW 1264 * 2 ; Index = 77 Token = 4 - DW 1296 * 2 ; Index = 77 Token = 5 - DW 1328 * 2 ; Index = 77 Token = 6 - DW 1360 * 2 ; Index = 77 Token = 7 - DW 1216 * 2 ; Index = 77 Token = 8 - DW 1216 * 2 ; Index = 77 Token = 9 - DW 1216 * 2 ; Index = 77 Token = 10 - DW 1216 * 2 ; Index = 77 Token = 11 - DW 1264 * 2 ; Index = 77 Token = 12 - DW 1296 * 2 ; Index = 77 Token = 13 - DW 1328 * 2 ; Index = 77 Token = 14 - DW 1360 * 2 ; Index = 77 Token = 15 - DW 1232 * 2 ; Index = 78 Token = 0 - DW 1232 * 2 ; Index = 78 Token = 1 - DW 1232 * 2 ; Index = 78 Token = 2 - DW 1232 * 2 ; Index = 78 Token = 3 - DW 1280 * 2 ; Index = 78 Token = 4 - DW 1312 * 2 ; Index = 78 Token = 5 - DW 1344 * 2 ; Index = 78 Token = 6 - DW 1376 * 2 ; Index = 78 Token = 7 - DW 1232 * 2 ; Index = 78 Token = 8 - DW 1232 * 2 ; Index = 78 Token = 9 - DW 1232 * 2 ; Index = 78 Token = 10 - DW 1232 * 2 ; Index = 78 Token = 11 - DW 1280 * 2 ; Index = 78 Token = 12 - DW 1312 * 2 ; Index = 78 Token = 13 - DW 1344 * 2 ; Index = 78 Token = 14 - DW 1376 * 2 ; Index = 78 Token = 15 - DW 1248 * 2 ; Index = 79 Token = 0 - DW 1248 * 2 ; Index = 79 Token = 1 - DW 1248 * 2 ; Index = 79 Token = 2 - DW 1248 * 2 ; Index = 79 Token = 3 - DW 1296 * 2 ; Index = 79 Token = 4 - DW 1328 * 2 ; Index = 79 Token = 5 - DW 1360 * 2 ; Index = 79 Token = 6 - DW 1392 * 2 ; Index = 79 Token = 7 - DW 1248 * 2 ; Index = 79 Token = 8 - DW 1248 * 2 ; Index = 79 Token = 9 - DW 1248 * 2 ; Index = 79 Token = 10 - DW 1248 * 2 ; Index = 79 Token = 11 - DW 1296 * 2 ; Index = 79 Token = 12 - DW 1328 * 2 ; Index = 79 Token = 13 - DW 1360 * 2 ; Index = 79 Token = 14 - DW 1392 * 2 ; Index = 79 Token = 15 - DW 1264 * 2 ; Index = 80 Token = 0 - DW 1264 * 2 ; Index = 80 Token = 1 - DW 1264 * 2 ; Index = 80 Token = 2 - DW 1264 * 2 ; Index = 80 Token = 3 - DW 1312 * 2 ; Index = 80 Token = 4 - DW 1344 * 2 ; Index = 80 Token = 5 - DW 1376 * 2 ; Index = 80 Token = 6 - DW 1408 * 2 ; Index = 80 Token = 7 - DW 1264 * 2 ; Index = 80 Token = 8 - DW 1264 * 2 ; Index = 80 Token = 9 - DW 1264 * 2 ; Index = 80 Token = 10 - DW 1264 * 2 ; Index = 80 Token = 11 - DW 1312 * 2 ; Index = 80 Token = 12 - DW 1344 * 2 ; Index = 80 Token = 13 - DW 1376 * 2 ; Index = 80 Token = 14 - DW 1408 * 2 ; Index = 80 Token = 15 - DW 1280 * 2 ; Index = 81 Token = 0 - DW 1280 * 2 ; Index = 81 Token = 1 - DW 1280 * 2 ; Index = 81 Token = 2 - DW 1280 * 2 ; Index = 81 Token = 3 - DW 1328 * 2 ; Index = 81 Token = 4 - DW 1360 * 2 ; Index = 81 Token = 5 - DW 1392 * 2 ; Index = 81 Token = 6 - DW 1408 * 2 ; Index = 81 Token = 7 - DW 1280 * 2 ; Index = 81 Token = 8 - DW 1280 * 2 ; Index = 81 Token = 9 - DW 1280 * 2 ; Index = 81 Token = 10 - DW 1280 * 2 ; Index = 81 Token = 11 - DW 1328 * 2 ; Index = 81 Token = 12 - DW 1360 * 2 ; Index = 81 Token = 13 - DW 1392 * 2 ; Index = 81 Token = 14 - DW 1408 * 2 ; Index = 81 Token = 15 - DW 1296 * 2 ; Index = 82 Token = 0 - DW 1296 * 2 ; Index = 82 Token = 1 - DW 1296 * 2 ; Index = 82 Token = 2 - DW 1296 * 2 ; Index = 82 Token = 3 - DW 1344 * 2 ; Index = 82 Token = 4 - DW 1376 * 2 ; Index = 82 Token = 5 - DW 1408 * 2 ; Index = 82 Token = 6 - DW 1408 * 2 ; Index = 82 Token = 7 - DW 1296 * 2 ; Index = 82 Token = 8 - DW 1296 * 2 ; Index = 82 Token = 9 - DW 1296 * 2 ; Index = 82 Token = 10 - DW 1296 * 2 ; Index = 82 Token = 11 - DW 1344 * 2 ; Index = 82 Token = 12 - DW 1376 * 2 ; Index = 82 Token = 13 - DW 1408 * 2 ; Index = 82 Token = 14 - DW 1408 * 2 ; Index = 82 Token = 15 - DW 1312 * 2 ; Index = 83 Token = 0 - DW 1312 * 2 ; Index = 83 Token = 1 - DW 1312 * 2 ; Index = 83 Token = 2 - DW 1312 * 2 ; Index = 83 Token = 3 - DW 1360 * 2 ; Index = 83 Token = 4 - DW 1392 * 2 ; Index = 83 Token = 5 - DW 1408 * 2 ; Index = 83 Token = 6 - DW 1408 * 2 ; Index = 83 Token = 7 - DW 1312 * 2 ; Index = 83 Token = 8 - DW 1312 * 2 ; Index = 83 Token = 9 - DW 1312 * 2 ; Index = 83 Token = 10 - DW 1312 * 2 ; Index = 83 Token = 11 - DW 1360 * 2 ; Index = 83 Token = 12 - DW 1392 * 2 ; Index = 83 Token = 13 - DW 1408 * 2 ; Index = 83 Token = 14 - DW 1408 * 2 ; Index = 83 Token = 15 - DW 1328 * 2 ; Index = 84 Token = 0 - DW 1328 * 2 ; Index = 84 Token = 1 - DW 1328 * 2 ; Index = 84 Token = 2 - DW 1328 * 2 ; Index = 84 Token = 3 - DW 1376 * 2 ; Index = 84 Token = 4 - DW 1408 * 2 ; Index = 84 Token = 5 - DW 1408 * 2 ; Index = 84 Token = 6 - DW 1408 * 2 ; Index = 84 Token = 7 - DW 1328 * 2 ; Index = 84 Token = 8 - DW 1328 * 2 ; Index = 84 Token = 9 - DW 1328 * 2 ; Index = 84 Token = 10 - DW 1328 * 2 ; Index = 84 Token = 11 - DW 1376 * 2 ; Index = 84 Token = 12 - DW 1408 * 2 ; Index = 84 Token = 13 - DW 1408 * 2 ; Index = 84 Token = 14 - DW 1408 * 2 ; Index = 84 Token = 15 - DW 1344 * 2 ; Index = 85 Token = 0 - DW 1344 * 2 ; Index = 85 Token = 1 - DW 1344 * 2 ; Index = 85 Token = 2 - DW 1344 * 2 ; Index = 85 Token = 3 - DW 1392 * 2 ; Index = 85 Token = 4 - DW 1408 * 2 ; Index = 85 Token = 5 - DW 1408 * 2 ; Index = 85 Token = 6 - DW 1408 * 2 ; Index = 85 Token = 7 - DW 1344 * 2 ; Index = 85 Token = 8 - DW 1344 * 2 ; Index = 85 Token = 9 - DW 1344 * 2 ; Index = 85 Token = 10 - DW 1344 * 2 ; Index = 85 Token = 11 - DW 1392 * 2 ; Index = 85 Token = 12 - DW 1408 * 2 ; Index = 85 Token = 13 - DW 1408 * 2 ; Index = 85 Token = 14 - DW 1408 * 2 ; Index = 85 Token = 15 - DW 1360 * 2 ; Index = 86 Token = 0 - DW 1360 * 2 ; Index = 86 Token = 1 - DW 1360 * 2 ; Index = 86 Token = 2 - DW 1360 * 2 ; Index = 86 Token = 3 - DW 1408 * 2 ; Index = 86 Token = 4 - DW 1408 * 2 ; Index = 86 Token = 5 - DW 1408 * 2 ; Index = 86 Token = 6 - DW 1408 * 2 ; Index = 86 Token = 7 - DW 1360 * 2 ; Index = 86 Token = 8 - DW 1360 * 2 ; Index = 86 Token = 9 - DW 1360 * 2 ; Index = 86 Token = 10 - DW 1360 * 2 ; Index = 86 Token = 11 - DW 1408 * 2 ; Index = 86 Token = 12 - DW 1408 * 2 ; Index = 86 Token = 13 - DW 1408 * 2 ; Index = 86 Token = 14 - DW 1408 * 2 ; Index = 86 Token = 15 - DW 1376 * 2 ; Index = 87 Token = 0 - DW 1376 * 2 ; Index = 87 Token = 1 - DW 1376 * 2 ; Index = 87 Token = 2 - DW 1376 * 2 ; Index = 87 Token = 3 - DW 1408 * 2 ; Index = 87 Token = 4 - DW 1408 * 2 ; Index = 87 Token = 5 - DW 1408 * 2 ; Index = 87 Token = 6 - DW 1408 * 2 ; Index = 87 Token = 7 - DW 1376 * 2 ; Index = 87 Token = 8 - DW 1376 * 2 ; Index = 87 Token = 9 - DW 1376 * 2 ; Index = 87 Token = 10 - DW 1376 * 2 ; Index = 87 Token = 11 - DW 1408 * 2 ; Index = 87 Token = 12 - DW 1408 * 2 ; Index = 87 Token = 13 - DW 1408 * 2 ; Index = 87 Token = 14 - DW 1408 * 2 ; Index = 87 Token = 15 - DW 1392 * 2 ; Index = 88 Token = 0 - DW 1392 * 2 ; Index = 88 Token = 1 - DW 1392 * 2 ; Index = 88 Token = 2 - DW 1392 * 2 ; Index = 88 Token = 3 - DW 1408 * 2 ; Index = 88 Token = 4 - DW 1408 * 2 ; Index = 88 Token = 5 - DW 1408 * 2 ; Index = 88 Token = 6 - DW 1408 * 2 ; Index = 88 Token = 7 - DW 1392 * 2 ; Index = 88 Token = 8 - DW 1392 * 2 ; Index = 88 Token = 9 - DW 1392 * 2 ; Index = 88 Token = 10 - DW 1392 * 2 ; Index = 88 Token = 11 - DW 1408 * 2 ; Index = 88 Token = 12 - DW 1408 * 2 ; Index = 88 Token = 13 - DW 1408 * 2 ; Index = 88 Token = 14 - DW 1408 * 2 ; Index = 88 Token = 15 diff --git a/code/nybbtb.inc b/code/nybbtb.inc deleted file mode 100644 index fbb111c8..00000000 --- a/code/nybbtb.inc +++ /dev/null @@ -1,54 +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. -;****************************************************************************** - -;**************************************************************************** -;* bNybbleTablexxxx - ADPCM Lookup table for nybbles -;**************************************************************************** - - align 4 - -bNybbleTableLow DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - DB 00h*2,01h*2,02h*2,03h*2,04h*2,05h*2,06h*2,07h*2,08h*2,09h*2,0Ah*2,0Bh*2,0Ch*2,0Dh*2,0Eh*2,0Fh*2 - - align 4 - -bNybbleTableHigh DB 00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2,00h*2 - DB 01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2,01h*2 - DB 02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2,02h*2 - DB 03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2,03h*2 - DB 04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2,04h*2 - DB 05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2,05h*2 - DB 06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2,06h*2 - DB 07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2,07h*2 - DB 08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2,08h*2 - DB 09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2,09h*2 - DB 0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2,0Ah*2 - DB 0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2,0Bh*2 - DB 0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2,0Ch*2 - DB 0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2,0Dh*2 - DB 0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2,0Eh*2 - DB 0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2,0Fh*2 diff --git a/code/olsosdec.asm b/code/olsosdec.asm deleted file mode 100644 index f2f22860..00000000 --- a/code/olsosdec.asm +++ /dev/null @@ -1,652 +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. -;****************************************************************************** - -;**************************************************************************** -;* -;* Copyright (c) 1994, HMI, INC. All Rights Reserved -;* -;*--------------------------------------------------------------------------- -;* -;* FILE -;* soscodec.asm -;* -;* DESCRIPTION -;* HMI SOS ADPCM compression/decompression. -;* -;* PROGRAMMER -;* Nick Skrepetos -;* Denzil E. Long, Jr. (Fixed bugs, rewrote for watcom) -;* Bill Petro (Added stereo support) -;* DATE -;* Febuary 15, 1995 -;* -;*--------------------------------------------------------------------------- -;* -;* PUBLIC -;* -;**************************************************************************** - - ; IDEAL - .386P ;P386 - .MODEL FLAT, C ;MODEL USE32 FLAT - ;LOCALS ?? - - -DPMI_INTR equ 31h -IF_LOCKED_PM_CODE equ 1h ; Locked PM code for DPMI. -IF_LOCKED_PM_DATA equ 2h ; Locked PM code for DPMI. - - sCompInfo STRUC -lpSource DD ? ;Compressed data pointer -lpDest DD ? ;Uncompressed data pointer -dwCompSize DD ? ;Compressed size -dwUnCompSize DD ? ;Uncompressed size - -dwSampleIndex DD ? ;Index into sample -dwPredicted DD ? ;Next predicted value -dwDifference DD ? ;Difference from last sample -wCodeBuf DW ? ;Holds 2 nibbles for decompression -wCode DW ? ;Current 4 bit code -wStep DW ? ;Step value in table -wIndex DW ? ;Index into step table - -dwSampleIndex2 DD ? ;Index into sample -dwPredicted2 DD ? ;Next predicted value -dwDifference2 DD ? ;Difference from last sample -wCodeBuf2 DW ? ;Holds 2 nibbles for decompression -wCode2 DW ? ;Current 4 bit code -wStep2 DW ? ;Step value in table -wIndex2 DW ? ;Index into step table - -wBitSize DW ? ;Bit size for decompression -wChannels DW ? ;number of channels - sCompInfo ENDS - - .DATA ;DATASEG - - -;InitFlags DD 0 ; Flags to indicate what has been initialized. - - -;LABEL LockedDataStart BYTE - -;* Index table for stepping into step table - -wCODECIndexTab DW -1,-1,-1,-1,2,4,6,8 - DW -1,-1,-1,-1,2,4,6,8 - - -;Lookup table of replacement values -;The actual sound value is replaced with an index to lookup in this table -;The index only takes up a nibble(4bits) and represents an int(16bits) -;Essentially: -;Get a value -;compare it with the value before it -;find closest value in table and store the index into the table -;if i'm going down then negitize it -;go to next byte. - -;Theory for stereo: -;1)handle stereo and mono in two seperate loops. cleaner... -;start at byte 0 and skip every other byte(or word) both write and read -;when we get done -; set start byte to 1 and do it again - - - - -;This table essentialy round off to closes values in 3 distinct bands -; precalculated and optimized(i guess) for human hearing. - -wCODECStepTab DW 7, 8, 9, 10, 11, 12, 13,14 - DW 16, 17, 19, 21, 23, 25, 28, 31 - DW 34, 37, 41, 45, 50, 55, 60, 66 - DW 73, 80, 88, 97, 107, 118, 130, 143 - DW 157, 173, 190, 209, 230, 253, 279, 307 - DW 337, 371, 408, 449, 494, 544, 598, 658 - DW 724, 796, 876, 963, 1060, 1166, 1282, 1411 - DW 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024 - DW 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484 - DW 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899 - DW 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794 - DW 32767 - -;dwCODECByteIndex DD 0 ; this is when to stop compressing -;dwCODECTempStep DD 0 ; tempory storage for step value -;wCODECMask DW 0 ; Current mask - -;LABEL LockedDataEnd BYTE - - - .CODE ;CODESEG - -;LABEL LockedCodeStart BYTE - -;**************************************************************************** -;* -;* NAME -;* sosCODECInitStream - Initialize compression stream. -;* -;* SYNOPSIS -;* sosCODECInitStream(CompInfo) -;* -;* void sosCODECInitStream(_SOS_COMPRESS_INFO *); -;* -;* FUNCTION -;* Initialize compression stream for compression and decompression. -;* -;* INPUTS -;* CompInfo - Compression information structure. -;* -;* RESULT -;* NONE -;* -;**************************************************************************** - - PUBLIC General_sosCODECInitStream - General_sosCODECInitStream PROC NEAR \ - \ - sSOSInfo:DWORD - - assume eax:ptr sCompInfo - - mov eax,[sSOSInfo] - mov [[eax].wIndex],0 ; starting index 0 - mov [[eax].wStep],7 ; start with a step of 7 - mov [[eax].dwPredicted],0 ; no predicted value - mov [[eax].dwSampleIndex],0 ;start at head of index - mov [[eax].wIndex2],0 ; starting index 0 - mov [[eax].wStep2],7 ; start with a step of 7 - mov [[eax].dwPredicted2],0 ; no predicted value - mov [[eax].dwSampleIndex2],0 ;start at head of index - ret - - General_sosCODECInitStream ENDP - - - -;**************************************************************************** -;* -;* NAME -;* sosCODECDecompressData - Decompress audio data. -;* -;* SYNOPSIS -;* Size = sosCODECDecompressData(CompInfo, NumBytes) -;* -;* long sosCODECDecompressData(_SOS_COMPRESS_INFO *, long); -;* -;* FUNCTION -;* Decompress data from a 4:1 ADPCM compressed stream. The number of -;* bytes decompressed is returned. -;* -;* INPUTS -;* CompInfo - Compress information structure. -;* NumBytes - Number of bytes to compress. -;* -;* RESULT -;* Size - Size of decompressed data. -;* -;**************************************************************************** - - PUBLIC General_sosCODECDecompressData - General_sosCODECDecompressData PROC NEAR \ - \ - sSOSInfo:DWORD, \ - wBytes:DWORD - - assume ebx:ptr sCompInfo - - local dwCODECBytesProcessed:dword ;bytes to decompress - local dwCODECByteIndex:dword ;this is when to stop compressing - ; these need to be local if the function is to be reenterant - push esi - push edi - push ebx - push ecx - push edx - -;*--------------------------------------------------------------------------- -;* Initialize -;*--------------------------------------------------------------------------- - - mov ebx,[sSOSInfo] - mov eax,[wBytes] - mov [dwCODECBytesProcessed],eax - mov [[ebx].dwSampleIndex],0 ;start at head of index - mov [[ebx].dwSampleIndex2],0 ;start at head of index - - ;Check for 16 bit decompression - - cmp [[ebx].wBitSize],16 - jne short ??skipByteDivide - - shr eax,1 ;Divide size by two - -??skipByteDivide: - mov [dwCODECByteIndex],eax - mov esi,[[ebx].lpSource] - mov edi,[[ebx].lpDest] - cmp [[ebx].wChannels],2 ;stereo check - je ??mainloopl ;do left side first - -; Determine if sample index is even or odd. This will determine -; if we need to get a new token or not. - -;--------------------------------------------------------------------------- -;Main Mono Loop -;--------------------------------------------------------------------------- - - - -??mainloop: - test [[ebx].dwSampleIndex],1 ;odd ?? - je short ??fetchToken ; if so get new token - xor eax,eax ;else shift int codebuf - mov ax,[[ebx].wCodeBuf] ;ored with Code - shr eax,4 - and eax,000Fh - mov [[ebx].wCode],ax - jmp short ??calcDifference - -??fetchToken: - xor eax,eax ;get a new token - mov al,[esi] ;put in codebuf - mov [[ebx].wCodeBuf],ax - inc esi - and eax,000Fh - mov [[ebx].wCode],ax ;and then code - -??calcDifference: - mov [[ebx].dwDifference],0 ;reset diff - xor ecx,ecx - mov cx,[[ebx].wStep] ;cx is step value - test eax,4 ;Check for wCode & 4 - je short ??no4 - add [[ebx].dwDifference],ecx ;Add wStep - -??no4: - test eax,2 ;Check for wCode & 2 - je short ??no2 - mov edx,ecx ;Add wStep >> 1 - shr edx,1 - add [[ebx].dwDifference],edx - -??no2: - test eax,1 ;Check for wCode & 1 - je short ??no1 - mov edx,ecx ;Add wStep >> 2 - shr edx,2 - add [[ebx].dwDifference],edx - -??no1: - mov edx,ecx ;Add in wStep >> 3 - shr edx,3 - add [[ebx].dwDifference],edx - test eax,8 ;Check for wCode & 8 - je short ??no8 - neg [[ebx].dwDifference] ;Negate diff - -??no8: - ; add difference to predicted value. - - mov eax,[[ebx].dwPredicted] - add eax,[[ebx].dwDifference] - - ; make sure there is no under or overflow. - - cmp eax,7FFFh - jl short ??noOverflow - mov eax,7FFFh - -??noOverflow: - cmp eax,0FFFF8000h - jg short ??noUnderflow - mov eax,0FFFF8000h - -??noUnderflow: - mov [[ebx].dwPredicted],eax - cmp [[ebx].wBitSize],16 - jne short ??output8Bit - mov [edi],ax ;Output 16bit sample - add edi,2 - jmp short ??adjustIndex - -??output8Bit: - ; output 8 bit sample - - xor ah,80h - mov [edi],ah - inc edi - -??adjustIndex: - xor ecx,ecx - mov cx,[[ebx].wCode] - xor eax,eax - shl ecx,1 - mov ax,[wCODECIndexTab + ecx] - add [[ebx].wIndex],ax ;check if wIndex < 0 - cmp [[ebx].wIndex],8000h - jb short ??checkOverflow - mov [[ebx].wIndex],0 ;reset index to zero - jmp short ??adjustStep - -??checkOverflow: - cmp [[ebx].wIndex],88 ;check if wIndex > 88 - jbe short ??adjustStep - mov [[ebx].wIndex],88 ;reset index to 88 - -??adjustStep: - ; fetch wIndex so we can fetch new step value - - xor ecx,ecx - mov cx,[[ebx].wIndex] - xor eax,eax - shl ecx,1 - mov ax,[wCODECStepTab + ecx] - - ; advance index and store step value - - add [[ebx].dwSampleIndex],1 - mov [[ebx].wStep],ax - - ; decrement bytes processed and loop back. - - dec [dwCODECByteIndex] - jne ??mainloop - jmp ??exitout - -;-------------------------------------------------------------------------- -;Left Channel Start -;-------------------------------------------------------------------------- - - -??mainloopl: - test [[ebx].dwSampleIndex],1 - je short ??fetchTokenl - - xor eax,eax - mov ax,[[ebx].wCodeBuf] - shr eax,4 - and eax,000Fh - mov [[ebx].wCode],ax - jmp short ??calcDifferencel - -??fetchTokenl: - xor eax,eax - mov al,[esi] - mov [[ebx].wCodeBuf],ax - add esi,2 ;2 for stereo - and eax,000Fh - mov [[ebx].wCode],ax - -??calcDifferencel: - ; reset difference - - mov [[ebx].dwDifference],0 - xor ecx,ecx - mov cx,[[ebx].wStep] - test eax,4 ;Check for wCode & 4 - je short ??no4l - add [[ebx].dwDifference],ecx ;Add wStep - -??no4l: - test eax,2 ;Check for wCode & 2 - je short ??no2l - mov edx,ecx ;Add wStep >> 1 - shr edx,1 - add [[ebx].dwDifference],edx - -??no2l: - test eax,1 ;Check for wCode & 1 - je short ??no1l - mov edx,ecx ;Add wStep >> 2 - shr edx,2 - add [[ebx].dwDifference],edx - -??no1l: - mov edx,ecx ;Add in wStep >> 3 - shr edx,3 - add [[ebx].dwDifference],edx - test eax,8 ;Check for wCode & 8 - je short ??no8l - neg [[ebx].dwDifference] ;Negate diff - -??no8l: - ; add difference to predicted value. - - mov eax,[[ebx].dwPredicted] - add eax,[[ebx].dwDifference] - - ; make sure there is no under or overflow. - - cmp eax,7FFFh - jl short ??noOverflowl - mov eax,7FFFh - -??noOverflowl: - cmp eax,0FFFF8000h - jg short ??noUnderflowl - mov eax,0FFFF8000h - -??noUnderflowl: - mov [[ebx].dwPredicted],eax - cmp [[ebx].wBitSize],16 - jne short ??output8Bitl - mov [edi],ax ;Output 16bit sample - add edi,4 ;4 for stereo - jmp short ??adjustIndexl - -??output8Bitl: - ; output 8 bit sample - - xor ah,80h - mov [edi],ah - add edi,2 ;2 for stereo - -??adjustIndexl: - xor ecx,ecx - mov cx,[[ebx].wCode] - xor eax,eax - shl ecx,1 - mov ax,[wCODECIndexTab + ecx] - add [[ebx].wIndex],ax - ; check if wIndex < 0 - cmp [[ebx].wIndex],8000h - jb short ??checkOverflowl - mov [[ebx].wIndex],0 - jmp short ??adjustStepl ;reset index to zero - - -??checkOverflowl: - - cmp [[ebx].wIndex],88 ; check if wIndex > 88 - jbe short ??adjustStepl - mov [[ebx].wIndex],88 ; reset index to 88 - -??adjustStepl: - ; fetch wIndex so we can fetch new step value - - xor ecx,ecx - mov cx,[[ebx].wIndex] - xor eax,eax - shl ecx,1 - mov ax,[wCODECStepTab + ecx] - - ; advance index and store step value - - add [[ebx].dwSampleIndex],1 - mov [[ebx].wStep],ax - - ; decrement bytes processed and loop back. - - sub [dwCODECByteIndex],2 - jne ??mainloopl -;---------------------------------------------------------------------------- -; Right Side Setup -;---------------------------------------------------------------------------- - mov eax,[wBytes] - mov [dwCODECBytesProcessed],eax - mov esi,[[ebx].lpSource] - mov edi,[[ebx].lpDest] - inc esi ; skip left channel - inc edi ; skip left channel - cmp [[ebx].wBitSize],16 ;16 bit ?? - je short ??doByteDivide - mov [dwCODECByteIndex],eax - jmp short ??mainloopr - -??doByteDivide: - shr eax,1 ;Divide size by two - inc edi ; 16 bit so skip 1 more - mov [dwCODECByteIndex],eax - - -;-------------------------------------------------------------------------- -;Right Channel Start -;-------------------------------------------------------------------------- - - -??mainloopr: - test [[ebx].dwSampleIndex2],1 - je short ??fetchTokenr - xor eax,eax - mov ax,[[ebx].wCodeBuf2] - shr eax,4 - and eax,000Fh - mov [[ebx].wCode2],ax - jmp short ??calcDifferencer - -??fetchTokenr: - xor eax,eax - mov al,[esi] - mov [[ebx].wCodeBuf2],ax - add esi,2 ;2 for stereo - and eax,000Fh - mov [[ebx].wCode2],ax - -??calcDifferencer: - ; reset difference - - mov [[ebx].dwDifference2],0 - xor ecx,ecx - mov cx,[[ebx].wStep2] - test eax,4 ;Check for wCode & 4 - je short ??no4r - add [[ebx].dwDifference2],ecx ;Add wStep - -??no4r: - test eax,2 ;Check for wCode & 2 - je short ??no2r - mov edx,ecx ;Add wStep >> 1 - shr edx,1 - add [[ebx].dwDifference2],edx - -??no2r: - test eax,1 ;Check for wCode & 1 - je short ??no1r - mov edx,ecx ;Add wStep >> 2 - shr edx,2 - add [[ebx].dwDifference2],edx - -??no1r: - mov edx,ecx ;Add in wStep >> 3 - shr edx,3 - add [[ebx].dwDifference2],edx - test eax,8 ;Check for wCode & 8 - je short ??no8r - neg [[ebx].dwDifference2] ;Negate diff - -??no8r: - ; add difference to predicted value. - mov eax,[[ebx].dwPredicted2] - add eax,[[ebx].dwDifference2] - cmp eax,7FFFh - jl short ??noOverflowr - mov eax,7FFFh - -??noOverflowr: - cmp eax,0FFFF8000h - jg short ??noUnderflowr - mov eax,0FFFF8000h - -??noUnderflowr: - mov [[ebx].dwPredicted2],eax - cmp [[ebx].wBitSize],16 - jne short ??output8Bitr - mov [edi],ax ;Output 16bit sample - add edi,4 ;4 for stereo *** - jmp short ??adjustIndexr - -??output8Bitr: - ; output 8 bit sample - xor ah,80h - mov [edi],ah - add edi,2 ;2 for stereo - -??adjustIndexr: - xor ecx,ecx - mov cx,[[ebx].wCode2] - xor eax,eax - shl ecx,1 - mov ax,[wCODECIndexTab + ecx] - add [[ebx].wIndex2],ax - ; check if wIndex < 0 - cmp [[ebx].wIndex2],8000h - jb short ??checkOverflowr - ; reset index to zero - mov [[ebx].wIndex2],0 - jmp short ??adjustStepr - -??checkOverflowr: - ; check if wIndex > 88 - cmp [[ebx].wIndex2],88 - jbe short ??adjustStepr - mov [[ebx].wIndex2],88 ; reset index to 88 - -??adjustStepr: - ; fetch wIndex so we can fetch new step value - - xor ecx,ecx - mov cx,[[ebx].wIndex2] - xor eax,eax - shl ecx,1 - mov ax,[wCODECStepTab + ecx] - - ; advance index and store step value - - add [[ebx].dwSampleIndex2],1 - mov [[ebx].wStep2],ax - - ; decrement bytes processed and loop back. - - sub [dwCODECByteIndex],2 - jne ??mainloopr - - -??exitout: -; don't think we need this but just in case i'll leave it here!! - -; mov [[ebx].lpSource],esi -; mov [[ebx].lpDest],edi - ; set up return value for number of bytes processed. - mov eax,[dwCODECBytesProcessed] - pop edx - pop ecx - pop ebx - pop edi - pop esi - ret - - General_sosCODECDecompressData ENDP - - END diff --git a/code/soscodec.asm b/code/soscodec.asm deleted file mode 100644 index 59c6e0d5..00000000 --- a/code/soscodec.asm +++ /dev/null @@ -1,622 +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. -;****************************************************************************** - -;**************************************************************************** -;* -;* Copyright (c) 1994, HMI, INC. All Rights Reserved -;* -;*--------------------------------------------------------------------------- -;* -;* FILE -;* soscodec.asm -;* -;* DESCRIPTION -;* HMI SOS ADPCM compression/decompression. -;* -;* PROGRAMMER -;* Nick Skrepetos -;* Denzil E. Long, Jr. (Fixed bugs, rewrote for watcom) -;* Bill Petro (Added stereo support) -;* Jonathan Lanier -;* -;* DATE -;* Febuary 15, 1995 -;* -;* LAST MODIFIED -;* 08/07/95 [jdl] - Rewrote/optimized sosCODECDecompressData -;* -;*--------------------------------------------------------------------------- -;* -;* PUBLIC -;* -;**************************************************************************** - - ;IDEAL - .386P;P386 - .MODEL FLAT, C ;MODEL USE32 FLAT - ;LOCALS ?? - -DPMI_INTR equ 31h -IF_LOCKED_PM_CODE equ 1h ; Locked PM code for DPMI. -IF_LOCKED_PM_DATA equ 2h ; Locked PM code for DPMI. - - sCompInfo STRUC -lpSource DD ? ;Compressed data pointer -lpDest DD ? ;Uncompressed data pointer -dwCompSize DD ? ;Compressed size -dwUnCompSize DD ? ;Uncompressed size - -dwSampleIndex DD ? ;Index into sample -dwPredicted DD ? ;Next predicted value -dwDifference DD ? ;Difference from last sample -wCodeBuf DW ? ;Holds 2 nibbles for decompression -wCode DW ? ;Current 4 bit code -wStep DW ? ;Step value in table -wIndex DW ? ;Index into step table - -dwSampleIndex2 DD ? ;Index into sample -dwPredicted2 DD ? ;Next predicted value -dwDifference2 DD ? ;Difference from last sample -wCodeBuf2 DW ? ;Holds 2 nibbles for decompression -wCode2 DW ? ;Current 4 bit code -wStep2 DW ? ;Step value in table -wIndex2 DW ? ;Index into step table - -wBitSize DW ? ;Bit size for decompression -wChannels DW ? ;number of channels - sCompInfo ENDS - - - .DATA;DATASEG - - -InitFlags DD 0 ; Flags to indicate what has been initialized. - - -;LABEL LockedDataStart BYTE - -;* Index table for stepping into step table - -INCLUDE difftb.inc -INCLUDE indextb.inc -INCLUDE nybbtb.inc - -;LABEL LockedDataEnd BYTE - - .CODE;CODESEG - -;LABEL LockedCodeStart BYTE - -;**************************************************************************** -;* -;* NAME -;* sosCODECInitStream - Initialize compression stream. -;* -;* SYNOPSIS -;* sosCODECInitStream(CompInfo) -;* -;* void sosCODECInitStream(_SOS_COMPRESS_INFO *); -;* -;* FUNCTION -;* Initialize compression stream for compression and decompression. -;* -;* INPUTS -;* CompInfo - Compression information structure. -;* -;* RESULT -;* NONE -;* -;**************************************************************************** - - PUBLIC sosCODECInitStream - sosCODECInitStream PROC NEAR \ - \ - sSOSInfo:DWORD - - assume eax:ptr sCompInfo - - mov eax,[sSOSInfo] - mov [[eax].wIndex],0 ; starting index 0 - mov [[eax].dwPredicted],0 ; no predicted value - mov [[eax].wIndex2],0 ; starting index 0 - mov [[eax].dwPredicted2],0 ; no predicted value - ret - - sosCODECInitStream ENDP - - - -;**************************************************************************** -;* -;* NAME -;* sosCODECDecompressData - Decompress audio data. -;* -;* SYNOPSIS -;* Size = sosCODECDecompressData(CompInfo, NumBytes) -;* -;* long sosCODECDecompressData(_SOS_COMPRESS_INFO *, long); -;* -;* FUNCTION -;* Decompress data from a 4:1 ADPCM compressed stream. The number of -;* bytes decompressed is returned. -;* -;* INPUTS -;* CompInfo - Compress information structure. -;* NumBytes - Number of bytes to decompress. -;* -;* RESULT -;* Size - Size of decompressed data. -;* -;* -;* NOTES -;* This routine has been optimized for pipelining on both -;* 486 and Pentium processors. Changing, inserting, or moving any -;* instructions will most likely slow down the code, in some cases by -;* as much as 20%. It can burst-decompress 16384 samples in about -;* 1940?s on a Pentium 90Mhz, and about 3960?s on a 486 66Mhz. -;* Instruction reordering could bring this down to below 1870?s on -;* the Pentium, but this would cause a great degradation in 486 -;* performance. Since slow 486's are the reason this code was -;* written to be fast, it has been optimized for the Pentium only where -;* it would not degrade 486 performance. So, be careful when changing -;* ANY of this code, because it is very carefully balanced... -;**************************************************************************** - - PUBLIC sosCODECDecompressData - sosCODECDecompressData PROC NEAR \ - \ - sSOSInfo:DWORD, \ - wBytes:DWORD - - assume ebx:ptr sCompInfo - - push esi - push edi - push ebx - push ecx - push edx ;save all the regs - - mov ebx,[sSOSInfo] ;get base of sCompInfo struct - mov cx,[[ebx].wBitSize] ;check the bit size - mov dx,[[ebx].wChannels] ;check the number of channels -; -; -; Determine the correct routine to use for decoding -; (for now only ADPCM 4:1 Mono 16-bit is implemented) - cmp cx,8 - jne ??do16Bits - -??do8Bits: - cmp dx,2 - jne ??not8Stereo -; jmp ??decomp8Stereo - jmp ??byeBye - -??not8Stereo: - cmp dx,1 - jne ??byeBye -; jmp decomp8Mono - jmp ??byeBye - -??do16Bits: - cmp cx,16 - jne ??byeBye - - cmp dx,2 - jne ??not16Stereo -; jmp ??decomp16Stereo - jmp ??byeBye - -??not16Stereo: - cmp dx,1 - jne ??byeBye - - push ebp -; -; -; 16 bit ADPCM 4:1 Mono pre-loop initialization -??decomp16Mono: - push ebx ;save struct base - xor edx,edx ;clear index - mov eax,[[ebx].dwPredicted] ;get last sample - mov dx,[[ebx].wIndex] ;get last index value - mov esi,[[ebx].lpSource] ;get source address - mov edi,[[ebx].lpDest] ;get dest address - - mov ebp,[wBytes] ;get the number of dest. bytes - cmp ebp,16 ;less than 16? (less than 8 samples) - jl ??fixAlign16Mono0 ;if so, don't bother with alignment -; -; -; Check to see if we need to fix an alignment problem on the source buffer -; (non-aligned buffers are MUCH slower; if we're given a non-DWORD aligned -; source address, we do as many samples as needed to get to the nearest -; DWORD boundary, then finish the bulk as a DWORD-aligned decompress). - mov ebx,esi ;get source address - and ebx,03h ;check LSB - jnz ??fixalign16Mono ;if non-zero, need to align for - ;warp speed -??fixAlign16Mono0: - push ebp ;save for later - shr ebp,4 ;divide by 16 for 16-bit, - ;because we do 8 nybbles per loop, - ;and there are two samples per - ;byte, so there are n/16 iterations - ;required - xor ebx,ebx ;clear our nybble index - or ebp,ebp ;set flags for EBP - jmp ??start16Mono ;start with test... don't go if - ;we have zero bytes to do -??fixalign16Mono: - jmp [DWORD PTR dwMono16AlignJmpTable+ebx*4] ;do non-aligned first - - align 4 -??fixAlign16Mono1: - sub ebp,12 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Mono6 ;borrow exit code to go through a - ;piece of a loop - align 4 -??fixAlign16Mono2: - sub ebp,8 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Mono4 ;borrow exit code to go through a - ;piece of a loop - align 4 -??fixAlign16Mono3: - sub ebp,4 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Mono2 ;borrow exit code to go through a - ;piece of a loop -; "The Loop" -; -; Process 1st nybble - align 4 -??loop16Mono: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix1Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix1Smp16MonoU -??fixed1Smp16Mono: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi],ax ;save the sample -; -; -; Process 2nd nybble -??finish7Smp16Mono: - mov bl,ch ;get next 2 nybbles in ebx - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix2Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix2Smp16MonoU -??fixed2Smp16Mono: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+02h],ax ;save the sample - shr ecx,16 ;move top four nybbles into bottom -; -; -; Process 3rd nybble -??finish6Smp16Mono: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix3Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix3Smp16MonoU -??fixed3Smp16Mono: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+04h],ax ;save the sample -; -; -; Process 4th nybble -??finish5Smp16Mono: - mov bl,cl - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix4Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix4Smp16MonoU -??fixed4Smp16Mono: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+06h],ax ;save the sample -; -; -; Process 5th nybble -??finish4Smp16Mono: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix5Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix5Smp16MonoU -??fixed5Smp16Mono: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+08h],ax ;save the sample -; -; -; Process 6th nybble -??finish3Smp16Mono: - mov bl,ch - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix6Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix6Smp16MonoU -??fixed6Smp16Mono: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+0Ah],ax ;save the sample -; -; -; Process 7th nybble -??finish2Smp16Mono: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix7Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix7Smp16MonoU -??fixed7Smp16Mono: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+0Ch],ax ;save the sample -; -; -; Process 8th nybble -??finish1Smp16Mono: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix8Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix8Smp16MonoU -; -; -; Loop cleanup for next pass -??fixed8Smp16Mono: - mov [edi+0Eh],ax ;save the sample - add esi,04h ;bump esi to point to next longword - add edi,10h ;incr. the destination buffer ptr - dec ebp ;count down the number of samples/8 -??start16Mono: - jng ??cleanup16Mono ;if done, clean up - mov ecx,[esi] ;get 4 nybbles in one whack (whee!) - mov bl,cl ;get next 2 nybbles in ebx - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??loop16Mono ;loop until done - -??cleanup16Mono: - jnz ??done16Mono ;if ebp is non-zero, we're DONE - ;if exactly zero, finish the tail-end - ;of the conversion (may be a non- - ;multiple of 8 nybbles) -; -; -; Loop cleanup for last (incomplete) pass - pop ecx ;restore # of words - shr ecx,1 ;divide by two to get samples - and ecx,07h ;get # of samples we missed - jmp [DWORD PTR dwMono16JmpTable+ecx*4] ;go finish the job... -; -; -; Structure cleanup -??done16Mono: - pop ebx ;restore struct base - pop ebp ;restore stack frame pointer - mov [[ebx].dwPredicted],eax ;save last sample - mov [[ebx].wIndex],dx ;save last index value - mov eax,[wBytes] ;get # of bytes we did -??byeBye: - pop edx ;restore all the regs - pop ecx - pop ebx - pop edi - pop esi - ret -; -; -; Jumps for -32768/+32767 bounds check go to these vvvv - align 4 -??fix1Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed1Smp16Mono ;go back - - align 4 -??fix1Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed1Smp16Mono ;go back - - align 4 -??fix2Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed2Smp16Mono ;go back - - align 4 -??fix2Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed2Smp16Mono ;go back - - align 4 -??fix3Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed3Smp16Mono ;go back - - align 4 -??fix3Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed3Smp16Mono ;go back - - align 4 -??fix4Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed4Smp16Mono ;go back - - align 4 -??fix4Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed4Smp16Mono ;go back - - align 4 -??fix5Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed5Smp16Mono ;go back - - align 4 -??fix5Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed5Smp16Mono ;go back - - align 4 -??fix6Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed6Smp16Mono ;go back - - align 4 -??fix6Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed6Smp16Mono ;go back - - align 4 -??fix7Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed7Smp16Mono ;go back - - align 4 -??fix7Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed7Smp16Mono ;go back - - align 4 -??fix8Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed8Smp16Mono ;go back - - align 4 -??fix8Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed8Smp16Mono ;go back -; -; -; Jump tables for cleanup after loop unroll point to these vvvv - align 4 -??finish16Mono1: - xor ecx,ecx ;clear nybble bucket - mov ch,[esi] ;get 1 nybble (1 byte) - shl ch,4 ;move it over - mov bl,ch ;get nybble in ebx - sub edi,0Eh ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish1Smp16Mono ;go finish it - - align 4 -??finish16Mono2: - xor ecx,ecx ;clear nybble bucket - mov ch,[esi] ;get 2 nybbles (1 byte) - mov bl,ch ;get nybbles in ebx - sub edi,0Ch ;back edi up - sub esi,3 ;adjust esi (used for dword aligning) - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish2Smp16Mono ;go finish it - - align 4 -??finish16Mono3: - xor ecx,ecx ;clear nybble bucket - mov cx,[esi] ;get 3 nybbles (2 bytes) - shl cx,4 ;move it over - mov bl,cl ;get nybbles in ebx - sub edi,0Ah ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish3Smp16Mono ;go finish it - - align 4 -??finish16Mono4: - xor ecx,ecx ;clear nybble bucket - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - sub edi,08h ;back edi up - sub esi,2 ;adjust esi (used for dword aligning) - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish4Smp16Mono ;go finish it - - align 4 -??finish16Mono5: - xor ecx,ecx ;clear nybble bucket - mov cl,[esi+2] ;get 1 nybble (1 byte) - shl ecx,16 ;shift it over - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - shr ecx,4 ;move it over - shl bl,4 ;move it over - sub edi,06h ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish5Smp16Mono ;go finish it - - align 4 -??finish16Mono6: - xor ecx,ecx ;clear nybble bucket - mov cl,[esi+2] ;get 2 nybbles (1 byte) - shl ecx,16 ;move it over - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - shr ecx,8 ;move it over - sub esi,1 ;adjust esi (used for dword aligning) - sub edi,04h ;back edi up - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish6Smp16Mono ;go finish it - - align 4 -??finish16Mono7: - xor ecx,ecx ;clear nybble bucket - mov ecx,[esi] ;get 7 nybbles (4 bytes) - shl ecx,4 ;move it over - mov bl,cl ;get nybbles in ebx - sub edi,02h ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish7Smp16Mono ;go finish it -; -; -; Jump Tables - align 4 - -dwMono16JmpTable DD ??done16Mono - DD ??finish16Mono1 - DD ??finish16Mono2 - DD ??finish16Mono3 - DD ??finish16Mono4 - DD ??finish16Mono5 - DD ??finish16Mono6 - DD ??finish16Mono7 - - align 4 -dwMono16AlignJmpTable DD ??fixAlign16Mono0 - DD ??fixAlign16Mono1 - DD ??fixAlign16Mono2 - DD ??fixAlign16Mono3 - - sosCODECDecompressData ENDP - - END - diff --git a/code/soscodec.cpp b/code/soscodec.cpp new file mode 100644 index 00000000..2e94ade3 --- /dev/null +++ b/code/soscodec.cpp @@ -0,0 +1,784 @@ +/******************************************************************************* + * 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 : soscodec.asm +* Date Created : 6/1/94 +* Description : ADPCM decompression for the SOS audio streams. +* +* Programmer(s) : Nick Skrepetos +* Last Modification : 10/1/94 - 11:37:9 AM +* Additional Notes : Modified by Denzil E. Long, Jr. +* +***************************************************************************** +* Copyright (c) 1994, HMI, Inc. All Rights Reserved * +****************************************************************************/ + +#include "always.h" + +#include "soscomp.h" +#include "vqalib/cmp.h" + +/* + * Three decoders share this file, each replacing an assembly routine of the same name. + * + * sosCODECDecompressData is the fast path for 16 bit mono. It walks a difference table + * indexed by the step index and the token together, and its stream state is that combined + * index rather than a plain step index: wIndex holds the step index times 32, which is the + * form the table wants and the form the assembly persisted between calls. + * + * General_sosCODECDecompressData handles every other shape. It computes the difference + * arithmetically from the current step instead of reading a table, which is the same + * arithmetic the table was built from. + * + * VQA_sosCODECDecompressData is the VQA flavour. It takes its shape through arguments, + * carries only four values of state, and implements 16 bit only; anything else returns + * having done nothing, exactly as the assembly did. + */ + +namespace { + +/* + * Step index adjustment per token, and the step size per index. These belong to the general + * decoder; the other two reach the same numbers through the difference table below. + */ +short const _SosIndexAdjust[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 +}; + +unsigned short const _SosStepTable[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, + 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, + 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, + 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, + 32767 +}; + +/* + * Difference to add to the running sample, and the next step index scaled by 32, both keyed + * on the step index and token together. Transcribed from the tables the assembly carried. + */ +int const _SosDiffTable[89 * 16] = { + 0, 1, 3, 4, 7, 8, 10, 11, + 0, -1, -3, -4, -7, -8, -10, -11, + 1, 3, 5, 7, 9, 11, 13, 15, + -1, -3, -5, -7, -9, -11, -13, -15, + 1, 3, 5, 7, 10, 12, 14, 16, + -1, -3, -5, -7, -10, -12, -14, -16, + 1, 3, 6, 8, 11, 13, 16, 18, + -1, -3, -6, -8, -11, -13, -16, -18, + 1, 3, 6, 8, 12, 14, 17, 19, + -1, -3, -6, -8, -12, -14, -17, -19, + 1, 4, 7, 10, 13, 16, 19, 22, + -1, -4, -7, -10, -13, -16, -19, -22, + 1, 4, 7, 10, 14, 17, 20, 23, + -1, -4, -7, -10, -14, -17, -20, -23, + 1, 4, 8, 11, 15, 18, 22, 25, + -1, -4, -8, -11, -15, -18, -22, -25, + 2, 6, 10, 14, 18, 22, 26, 30, + -2, -6, -10, -14, -18, -22, -26, -30, + 2, 6, 10, 14, 19, 23, 27, 31, + -2, -6, -10, -14, -19, -23, -27, -31, + 2, 6, 11, 15, 21, 25, 30, 34, + -2, -6, -11, -15, -21, -25, -30, -34, + 2, 7, 12, 17, 23, 28, 33, 38, + -2, -7, -12, -17, -23, -28, -33, -38, + 2, 7, 13, 18, 25, 30, 36, 41, + -2, -7, -13, -18, -25, -30, -36, -41, + 3, 9, 15, 21, 28, 34, 40, 46, + -3, -9, -15, -21, -28, -34, -40, -46, + 3, 10, 17, 24, 31, 38, 45, 52, + -3, -10, -17, -24, -31, -38, -45, -52, + 3, 10, 18, 25, 34, 41, 49, 56, + -3, -10, -18, -25, -34, -41, -49, -56, + 4, 12, 21, 29, 38, 46, 55, 63, + -4, -12, -21, -29, -38, -46, -55, -63, + 4, 13, 22, 31, 41, 50, 59, 68, + -4, -13, -22, -31, -41, -50, -59, -68, + 5, 15, 25, 35, 46, 56, 66, 76, + -5, -15, -25, -35, -46, -56, -66, -76, + 5, 16, 27, 38, 50, 61, 72, 83, + -5, -16, -27, -38, -50, -61, -72, -83, + 6, 18, 31, 43, 56, 68, 81, 93, + -6, -18, -31, -43, -56, -68, -81, -93, + 6, 19, 33, 46, 61, 74, 88, 101, + -6, -19, -33, -46, -61, -74, -88, -101, + 7, 22, 37, 52, 67, 82, 97, 112, + -7, -22, -37, -52, -67, -82, -97, -112, + 8, 24, 41, 57, 74, 90, 107, 123, + -8, -24, -41, -57, -74, -90, -107, -123, + 9, 27, 45, 63, 82, 100, 118, 136, + -9, -27, -45, -63, -82, -100, -118, -136, + 10, 30, 50, 70, 90, 110, 130, 150, + -10, -30, -50, -70, -90, -110, -130, -150, + 11, 33, 55, 77, 99, 121, 143, 165, + -11, -33, -55, -77, -99, -121, -143, -165, + 12, 36, 60, 84, 109, 133, 157, 181, + -12, -36, -60, -84, -109, -133, -157, -181, + 13, 39, 66, 92, 120, 146, 173, 199, + -13, -39, -66, -92, -120, -146, -173, -199, + 14, 43, 73, 102, 132, 161, 191, 220, + -14, -43, -73, -102, -132, -161, -191, -220, + 16, 48, 81, 113, 146, 178, 211, 243, + -16, -48, -81, -113, -146, -178, -211, -243, + 17, 52, 88, 123, 160, 195, 231, 266, + -17, -52, -88, -123, -160, -195, -231, -266, + 19, 58, 97, 136, 176, 215, 254, 293, + -19, -58, -97, -136, -176, -215, -254, -293, + 21, 64, 107, 150, 194, 237, 280, 323, + -21, -64, -107, -150, -194, -237, -280, -323, + 23, 70, 118, 165, 213, 260, 308, 355, + -23, -70, -118, -165, -213, -260, -308, -355, + 26, 78, 130, 182, 235, 287, 339, 391, + -26, -78, -130, -182, -235, -287, -339, -391, + 28, 85, 143, 200, 258, 315, 373, 430, + -28, -85, -143, -200, -258, -315, -373, -430, + 31, 94, 157, 220, 284, 347, 410, 473, + -31, -94, -157, -220, -284, -347, -410, -473, + 34, 103, 173, 242, 313, 382, 452, 521, + -34, -103, -173, -242, -313, -382, -452, -521, + 38, 114, 191, 267, 345, 421, 498, 574, + -38, -114, -191, -267, -345, -421, -498, -574, + 42, 126, 210, 294, 379, 463, 547, 631, + -42, -126, -210, -294, -379, -463, -547, -631, + 46, 138, 231, 323, 417, 509, 602, 694, + -46, -138, -231, -323, -417, -509, -602, -694, + 51, 153, 255, 357, 459, 561, 663, 765, + -51, -153, -255, -357, -459, -561, -663, -765, + 56, 168, 280, 392, 505, 617, 729, 841, + -56, -168, -280, -392, -505, -617, -729, -841, + 61, 184, 308, 431, 555, 678, 802, 925, + -61, -184, -308, -431, -555, -678, -802, -925, + 68, 204, 340, 476, 612, 748, 884, 1020, + -68, -204, -340, -476, -612, -748, -884, -1020, + 74, 223, 373, 522, 672, 821, 971, 1120, + -74, -223, -373, -522, -672, -821, -971, -1120, + 82, 246, 411, 575, 740, 904, 1069, 1233, + -82, -246, -411, -575, -740, -904, -1069, -1233, + 90, 271, 452, 633, 814, 995, 1176, 1357, + -90, -271, -452, -633, -814, -995, -1176, -1357, + 99, 298, 497, 696, 895, 1094, 1293, 1492, + -99, -298, -497, -696, -895, -1094, -1293, -1492, + 109, 328, 547, 766, 985, 1204, 1423, 1642, + -109, -328, -547, -766, -985, -1204, -1423, -1642, + 120, 360, 601, 841, 1083, 1323, 1564, 1804, + -120, -360, -601, -841, -1083, -1323, -1564, -1804, + 132, 397, 662, 927, 1192, 1457, 1722, 1987, + -132, -397, -662, -927, -1192, -1457, -1722, -1987, + 145, 436, 728, 1019, 1311, 1602, 1894, 2185, + -145, -436, -728, -1019, -1311, -1602, -1894, -2185, + 160, 480, 801, 1121, 1442, 1762, 2083, 2403, + -160, -480, -801, -1121, -1442, -1762, -2083, -2403, + 176, 528, 881, 1233, 1587, 1939, 2292, 2644, + -176, -528, -881, -1233, -1587, -1939, -2292, -2644, + 194, 582, 970, 1358, 1746, 2134, 2522, 2910, + -194, -582, -970, -1358, -1746, -2134, -2522, -2910, + 213, 639, 1066, 1492, 1920, 2346, 2773, 3199, + -213, -639, -1066, -1492, -1920, -2346, -2773, -3199, + 234, 703, 1173, 1642, 2112, 2581, 3051, 3520, + -234, -703, -1173, -1642, -2112, -2581, -3051, -3520, + 258, 774, 1291, 1807, 2324, 2840, 3357, 3873, + -258, -774, -1291, -1807, -2324, -2840, -3357, -3873, + 284, 852, 1420, 1988, 2556, 3124, 3692, 4260, + -284, -852, -1420, -1988, -2556, -3124, -3692, -4260, + 312, 936, 1561, 2185, 2811, 3435, 4060, 4684, + -312, -936, -1561, -2185, -2811, -3435, -4060, -4684, + 343, 1030, 1717, 2404, 3092, 3779, 4466, 5153, + -343, -1030, -1717, -2404, -3092, -3779, -4466, -5153, + 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670, + -378, -1134, -1890, -2646, -3402, -4158, -4914, -5670, + 415, 1246, 2078, 2909, 3742, 4573, 5405, 6236, + -415, -1246, -2078, -2909, -3742, -4573, -5405, -6236, + 457, 1372, 2287, 3202, 4117, 5032, 5947, 6862, + -457, -1372, -2287, -3202, -4117, -5032, -5947, -6862, + 503, 1509, 2516, 3522, 4529, 5535, 6542, 7548, + -503, -1509, -2516, -3522, -4529, -5535, -6542, -7548, + 553, 1660, 2767, 3874, 4981, 6088, 7195, 8302, + -553, -1660, -2767, -3874, -4981, -6088, -7195, -8302, + 608, 1825, 3043, 4260, 5479, 6696, 7914, 9131, + -608, -1825, -3043, -4260, -5479, -6696, -7914, -9131, + 669, 2008, 3348, 4687, 6027, 7366, 8706, 10045, + -669, -2008, -3348, -4687, -6027, -7366, -8706, -10045, + 736, 2209, 3683, 5156, 6630, 8103, 9577, 11050, + -736, -2209, -3683, -5156, -6630, -8103, -9577, -11050, + 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157, + -810, -2431, -4052, -5673, -7294, -8915, -10536, -12157, + 891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, + -891, -2674, -4457, -6240, -8023, -9806, -11589, -13372, + 980, 2941, 4902, 6863, 8825, 10786, 12747, 14708, + -980, -2941, -4902, -6863, -8825, -10786, -12747, -14708, + 1078, 3235, 5393, 7550, 9708, 11865, 14023, 16180, + -1078, -3235, -5393, -7550, -9708, -11865, -14023, -16180, + 1186, 3559, 5932, 8305, 10679, 13052, 15425, 17798, + -1186, -3559, -5932, -8305, -10679, -13052, -15425, -17798, + 1305, 3915, 6526, 9136, 11747, 14357, 16968, 19578, + -1305, -3915, -6526, -9136, -11747, -14357, -16968, -19578, + 1435, 4306, 7178, 10049, 12922, 15793, 18665, 21536, + -1435, -4306, -7178, -10049, -12922, -15793, -18665, -21536, + 1579, 4737, 7896, 11054, 14214, 17372, 20531, 23689, + -1579, -4737, -7896, -11054, -14214, -17372, -20531, -23689, + 1737, 5211, 8686, 12160, 15636, 19110, 22585, 26059, + -1737, -5211, -8686, -12160, -15636, -19110, -22585, -26059, + 1911, 5733, 9555, 13377, 17200, 21022, 24844, 28666, + -1911, -5733, -9555, -13377, -17200, -21022, -24844, -28666, + 2102, 6306, 10511, 14715, 18920, 23124, 27329, 31533, + -2102, -6306, -10511, -14715, -18920, -23124, -27329, -31533, + 2312, 6937, 11562, 16187, 20812, 25437, 30062, 34687, + -2312, -6937, -11562, -16187, -20812, -25437, -30062, -34687, + 2543, 7630, 12718, 17805, 22893, 27980, 33068, 38155, + -2543, -7630, -12718, -17805, -22893, -27980, -33068, -38155, + 2798, 8394, 13990, 19586, 25183, 30779, 36375, 41971, + -2798, -8394, -13990, -19586, -25183, -30779, -36375, -41971, + 3077, 9232, 15388, 21543, 27700, 33855, 40011, 46166, + -3077, -9232, -15388, -21543, -27700, -33855, -40011, -46166, + 3385, 10156, 16928, 23699, 30471, 37242, 44014, 50785, + -3385, -10156, -16928, -23699, -30471, -37242, -44014, -50785, + 3724, 11172, 18621, 26069, 33518, 40966, 48415, 55863, + -3724, -11172, -18621, -26069, -33518, -40966, -48415, -55863, + 4095, 12286, 20478, 28669, 36862, 45053, 53245, 61436, + -4095, -12286, -20478, -28669, -36862, -45053, -53245, -61436 + +}; + +unsigned short const _SosIndexTable[89 * 16] = { + 0, 0, 0, 0, 64, 128, 192, 256, + 0, 0, 0, 0, 64, 128, 192, 256, + 0, 0, 0, 0, 96, 160, 224, 288, + 0, 0, 0, 0, 96, 160, 224, 288, + 32, 32, 32, 32, 128, 192, 256, 320, + 32, 32, 32, 32, 128, 192, 256, 320, + 64, 64, 64, 64, 160, 224, 288, 352, + 64, 64, 64, 64, 160, 224, 288, 352, + 96, 96, 96, 96, 192, 256, 320, 384, + 96, 96, 96, 96, 192, 256, 320, 384, + 128, 128, 128, 128, 224, 288, 352, 416, + 128, 128, 128, 128, 224, 288, 352, 416, + 160, 160, 160, 160, 256, 320, 384, 448, + 160, 160, 160, 160, 256, 320, 384, 448, + 192, 192, 192, 192, 288, 352, 416, 480, + 192, 192, 192, 192, 288, 352, 416, 480, + 224, 224, 224, 224, 320, 384, 448, 512, + 224, 224, 224, 224, 320, 384, 448, 512, + 256, 256, 256, 256, 352, 416, 480, 544, + 256, 256, 256, 256, 352, 416, 480, 544, + 288, 288, 288, 288, 384, 448, 512, 576, + 288, 288, 288, 288, 384, 448, 512, 576, + 320, 320, 320, 320, 416, 480, 544, 608, + 320, 320, 320, 320, 416, 480, 544, 608, + 352, 352, 352, 352, 448, 512, 576, 640, + 352, 352, 352, 352, 448, 512, 576, 640, + 384, 384, 384, 384, 480, 544, 608, 672, + 384, 384, 384, 384, 480, 544, 608, 672, + 416, 416, 416, 416, 512, 576, 640, 704, + 416, 416, 416, 416, 512, 576, 640, 704, + 448, 448, 448, 448, 544, 608, 672, 736, + 448, 448, 448, 448, 544, 608, 672, 736, + 480, 480, 480, 480, 576, 640, 704, 768, + 480, 480, 480, 480, 576, 640, 704, 768, + 512, 512, 512, 512, 608, 672, 736, 800, + 512, 512, 512, 512, 608, 672, 736, 800, + 544, 544, 544, 544, 640, 704, 768, 832, + 544, 544, 544, 544, 640, 704, 768, 832, + 576, 576, 576, 576, 672, 736, 800, 864, + 576, 576, 576, 576, 672, 736, 800, 864, + 608, 608, 608, 608, 704, 768, 832, 896, + 608, 608, 608, 608, 704, 768, 832, 896, + 640, 640, 640, 640, 736, 800, 864, 928, + 640, 640, 640, 640, 736, 800, 864, 928, + 672, 672, 672, 672, 768, 832, 896, 960, + 672, 672, 672, 672, 768, 832, 896, 960, + 704, 704, 704, 704, 800, 864, 928, 992, + 704, 704, 704, 704, 800, 864, 928, 992, + 736, 736, 736, 736, 832, 896, 960, 1024, + 736, 736, 736, 736, 832, 896, 960, 1024, + 768, 768, 768, 768, 864, 928, 992, 1056, + 768, 768, 768, 768, 864, 928, 992, 1056, + 800, 800, 800, 800, 896, 960, 1024, 1088, + 800, 800, 800, 800, 896, 960, 1024, 1088, + 832, 832, 832, 832, 928, 992, 1056, 1120, + 832, 832, 832, 832, 928, 992, 1056, 1120, + 864, 864, 864, 864, 960, 1024, 1088, 1152, + 864, 864, 864, 864, 960, 1024, 1088, 1152, + 896, 896, 896, 896, 992, 1056, 1120, 1184, + 896, 896, 896, 896, 992, 1056, 1120, 1184, + 928, 928, 928, 928, 1024, 1088, 1152, 1216, + 928, 928, 928, 928, 1024, 1088, 1152, 1216, + 960, 960, 960, 960, 1056, 1120, 1184, 1248, + 960, 960, 960, 960, 1056, 1120, 1184, 1248, + 992, 992, 992, 992, 1088, 1152, 1216, 1280, + 992, 992, 992, 992, 1088, 1152, 1216, 1280, + 1024, 1024, 1024, 1024, 1120, 1184, 1248, 1312, + 1024, 1024, 1024, 1024, 1120, 1184, 1248, 1312, + 1056, 1056, 1056, 1056, 1152, 1216, 1280, 1344, + 1056, 1056, 1056, 1056, 1152, 1216, 1280, 1344, + 1088, 1088, 1088, 1088, 1184, 1248, 1312, 1376, + 1088, 1088, 1088, 1088, 1184, 1248, 1312, 1376, + 1120, 1120, 1120, 1120, 1216, 1280, 1344, 1408, + 1120, 1120, 1120, 1120, 1216, 1280, 1344, 1408, + 1152, 1152, 1152, 1152, 1248, 1312, 1376, 1440, + 1152, 1152, 1152, 1152, 1248, 1312, 1376, 1440, + 1184, 1184, 1184, 1184, 1280, 1344, 1408, 1472, + 1184, 1184, 1184, 1184, 1280, 1344, 1408, 1472, + 1216, 1216, 1216, 1216, 1312, 1376, 1440, 1504, + 1216, 1216, 1216, 1216, 1312, 1376, 1440, 1504, + 1248, 1248, 1248, 1248, 1344, 1408, 1472, 1536, + 1248, 1248, 1248, 1248, 1344, 1408, 1472, 1536, + 1280, 1280, 1280, 1280, 1376, 1440, 1504, 1568, + 1280, 1280, 1280, 1280, 1376, 1440, 1504, 1568, + 1312, 1312, 1312, 1312, 1408, 1472, 1536, 1600, + 1312, 1312, 1312, 1312, 1408, 1472, 1536, 1600, + 1344, 1344, 1344, 1344, 1440, 1504, 1568, 1632, + 1344, 1344, 1344, 1344, 1440, 1504, 1568, 1632, + 1376, 1376, 1376, 1376, 1472, 1536, 1600, 1664, + 1376, 1376, 1376, 1376, 1472, 1536, 1600, 1664, + 1408, 1408, 1408, 1408, 1504, 1568, 1632, 1696, + 1408, 1408, 1408, 1408, 1504, 1568, 1632, 1696, + 1440, 1440, 1440, 1440, 1536, 1600, 1664, 1728, + 1440, 1440, 1440, 1440, 1536, 1600, 1664, 1728, + 1472, 1472, 1472, 1472, 1568, 1632, 1696, 1760, + 1472, 1472, 1472, 1472, 1568, 1632, 1696, 1760, + 1504, 1504, 1504, 1504, 1600, 1664, 1728, 1792, + 1504, 1504, 1504, 1504, 1600, 1664, 1728, 1792, + 1536, 1536, 1536, 1536, 1632, 1696, 1760, 1824, + 1536, 1536, 1536, 1536, 1632, 1696, 1760, 1824, + 1568, 1568, 1568, 1568, 1664, 1728, 1792, 1856, + 1568, 1568, 1568, 1568, 1664, 1728, 1792, 1856, + 1600, 1600, 1600, 1600, 1696, 1760, 1824, 1888, + 1600, 1600, 1600, 1600, 1696, 1760, 1824, 1888, + 1632, 1632, 1632, 1632, 1728, 1792, 1856, 1920, + 1632, 1632, 1632, 1632, 1728, 1792, 1856, 1920, + 1664, 1664, 1664, 1664, 1760, 1824, 1888, 1952, + 1664, 1664, 1664, 1664, 1760, 1824, 1888, 1952, + 1696, 1696, 1696, 1696, 1792, 1856, 1920, 1984, + 1696, 1696, 1696, 1696, 1792, 1856, 1920, 1984, + 1728, 1728, 1728, 1728, 1824, 1888, 1952, 2016, + 1728, 1728, 1728, 1728, 1824, 1888, 1952, 2016, + 1760, 1760, 1760, 1760, 1856, 1920, 1984, 2048, + 1760, 1760, 1760, 1760, 1856, 1920, 1984, 2048, + 1792, 1792, 1792, 1792, 1888, 1952, 2016, 2080, + 1792, 1792, 1792, 1792, 1888, 1952, 2016, 2080, + 1824, 1824, 1824, 1824, 1920, 1984, 2048, 2112, + 1824, 1824, 1824, 1824, 1920, 1984, 2048, 2112, + 1856, 1856, 1856, 1856, 1952, 2016, 2080, 2144, + 1856, 1856, 1856, 1856, 1952, 2016, 2080, 2144, + 1888, 1888, 1888, 1888, 1984, 2048, 2112, 2176, + 1888, 1888, 1888, 1888, 1984, 2048, 2112, 2176, + 1920, 1920, 1920, 1920, 2016, 2080, 2144, 2208, + 1920, 1920, 1920, 1920, 2016, 2080, 2144, 2208, + 1952, 1952, 1952, 1952, 2048, 2112, 2176, 2240, + 1952, 1952, 1952, 1952, 2048, 2112, 2176, 2240, + 1984, 1984, 1984, 1984, 2080, 2144, 2208, 2272, + 1984, 1984, 1984, 1984, 2080, 2144, 2208, 2272, + 2016, 2016, 2016, 2016, 2112, 2176, 2240, 2304, + 2016, 2016, 2016, 2016, 2112, 2176, 2240, 2304, + 2048, 2048, 2048, 2048, 2144, 2208, 2272, 2336, + 2048, 2048, 2048, 2048, 2144, 2208, 2272, 2336, + 2080, 2080, 2080, 2080, 2176, 2240, 2304, 2368, + 2080, 2080, 2080, 2080, 2176, 2240, 2304, 2368, + 2112, 2112, 2112, 2112, 2208, 2272, 2336, 2400, + 2112, 2112, 2112, 2112, 2208, 2272, 2336, 2400, + 2144, 2144, 2144, 2144, 2240, 2304, 2368, 2432, + 2144, 2144, 2144, 2144, 2240, 2304, 2368, 2432, + 2176, 2176, 2176, 2176, 2272, 2336, 2400, 2464, + 2176, 2176, 2176, 2176, 2272, 2336, 2400, 2464, + 2208, 2208, 2208, 2208, 2304, 2368, 2432, 2496, + 2208, 2208, 2208, 2208, 2304, 2368, 2432, 2496, + 2240, 2240, 2240, 2240, 2336, 2400, 2464, 2528, + 2240, 2240, 2240, 2240, 2336, 2400, 2464, 2528, + 2272, 2272, 2272, 2272, 2368, 2432, 2496, 2560, + 2272, 2272, 2272, 2272, 2368, 2432, 2496, 2560, + 2304, 2304, 2304, 2304, 2400, 2464, 2528, 2592, + 2304, 2304, 2304, 2304, 2400, 2464, 2528, 2592, + 2336, 2336, 2336, 2336, 2432, 2496, 2560, 2624, + 2336, 2336, 2336, 2336, 2432, 2496, 2560, 2624, + 2368, 2368, 2368, 2368, 2464, 2528, 2592, 2656, + 2368, 2368, 2368, 2368, 2464, 2528, 2592, 2656, + 2400, 2400, 2400, 2400, 2496, 2560, 2624, 2688, + 2400, 2400, 2400, 2400, 2496, 2560, 2624, 2688, + 2432, 2432, 2432, 2432, 2528, 2592, 2656, 2720, + 2432, 2432, 2432, 2432, 2528, 2592, 2656, 2720, + 2464, 2464, 2464, 2464, 2560, 2624, 2688, 2752, + 2464, 2464, 2464, 2464, 2560, 2624, 2688, 2752, + 2496, 2496, 2496, 2496, 2592, 2656, 2720, 2784, + 2496, 2496, 2496, 2496, 2592, 2656, 2720, 2784, + 2528, 2528, 2528, 2528, 2624, 2688, 2752, 2816, + 2528, 2528, 2528, 2528, 2624, 2688, 2752, 2816, + 2560, 2560, 2560, 2560, 2656, 2720, 2784, 2816, + 2560, 2560, 2560, 2560, 2656, 2720, 2784, 2816, + 2592, 2592, 2592, 2592, 2688, 2752, 2816, 2816, + 2592, 2592, 2592, 2592, 2688, 2752, 2816, 2816, + 2624, 2624, 2624, 2624, 2720, 2784, 2816, 2816, + 2624, 2624, 2624, 2624, 2720, 2784, 2816, 2816, + 2656, 2656, 2656, 2656, 2752, 2816, 2816, 2816, + 2656, 2656, 2656, 2656, 2752, 2816, 2816, 2816, + 2688, 2688, 2688, 2688, 2784, 2816, 2816, 2816, + 2688, 2688, 2688, 2688, 2784, 2816, 2816, 2816, + 2720, 2720, 2720, 2720, 2816, 2816, 2816, 2816, + 2720, 2720, 2720, 2720, 2816, 2816, 2816, 2816, + 2752, 2752, 2752, 2752, 2816, 2816, 2816, 2816, + 2752, 2752, 2752, 2752, 2816, 2816, 2816, 2816, + 2784, 2784, 2784, 2784, 2816, 2816, 2816, 2816, + 2784, 2784, 2784, 2784, 2816, 2816, 2816, 2816 + +}; + + +/// +/// Holds a running sample inside the range a 16 bit sample can carry. +/// +/// The sample to bring back into range. +/// long; The sample, clamped. +inline long Clamp_Sample(long sample) +{ + if (sample > 32767) { + return(32767); + } + + if (sample < -32768) { + return(-32768); + } + + return(sample); +} + + +/// +/// Decodes 16 bit samples through the difference table, the form both the SOS fast path and +/// the VQA decoder use. Tokens come out of each source byte low half first. +/// +/// Compressed nybbles. +/// Where the samples go. +/// How many samples to produce. +/// Distance in shorts between one sample and the next. +/// Running sample, carried in and out. +/// Step index times 32, carried in and out. +void Decode_Table_16(unsigned char const * source, short * dest, int samples, int deststride, long & predicted, unsigned short & index) +{ + long sample = predicted; + unsigned int slotbase = index; + + for (int i = 0; i < samples; i++) { + unsigned int const byte = source[i >> 1]; + unsigned int const token = ((i & 1) == 0) ? (byte & 0x0F) : ((byte >> 4) & 0x0F); + + /* + * The index is a multiple of 32 and the token contributes at most 30, so the + * assembly's OR into the low byte is an addition that cannot carry. + */ + unsigned int const slot = (slotbase | (token * 2)) >> 1; + + sample += _SosDiffTable[slot]; + slotbase = _SosIndexTable[slot]; + sample = Clamp_Sample(sample); + + dest[i * deststride] = (short)sample; + } + + predicted = sample; + index = (unsigned short)slotbase; +} + + +/* + * The general decoder keeps a separate copy of this state per channel, so the loop below + * reaches it through pointers rather than naming the structure's fields twice. + */ +struct SosChannel { + unsigned long * SampleIndex; + short * CodeBuf; + short * Code; + long * Predicted; + long * Difference; + short * Index; + short * Step; +}; + + +/// +/// Decodes one channel the general way, computing each difference from the current step. +/// +/// The stream state for this channel. +/// Compressed nybbles. +/// Where the samples go. +/// How many samples to produce. +/// Distance in bytes between one source byte and the next. +/// Distance in bytes between one sample and the next. +/// 8 or 16, the width of a written sample. +void Decode_General(SosChannel const & channel, unsigned char const * source, unsigned char * dest, int samples, int sourcestride, int deststride, int bits) +{ + for (int i = 0; i < samples; i++) { + + /* + * A byte carries two tokens. Odd samples take the half already fetched, which is + * why the sample counter and the code buffer are stream state rather than locals. + */ + if ((*channel.SampleIndex & 1) != 0) { + *channel.Code = (short)(((unsigned short)*channel.CodeBuf >> 4) & 0x0F); + } else { + *channel.CodeBuf = (short)(unsigned short)*source; + source += sourcestride; + *channel.Code = (short)(*channel.CodeBuf & 0x0F); + } + + int const code = *channel.Code; + long const step = (long)(unsigned short)*channel.Step; + + long difference = 0; + + if ((code & 4) != 0) { + difference += step; + } + + if ((code & 2) != 0) { + difference += step >> 1; + } + + if ((code & 1) != 0) { + difference += step >> 2; + } + + difference += step >> 3; + + if ((code & 8) != 0) { + difference = -difference; + } + + *channel.Difference = difference; + + long const sample = Clamp_Sample(*channel.Predicted + difference); + *channel.Predicted = sample; + + if (bits == 16) { + *(short *)dest = (short)sample; + } else { + + /* + * An 8 bit stream carries the top half of the sample, biased to unsigned. + */ + *dest = (unsigned char)((((unsigned long)sample >> 8) & 0xFF) ^ 0x80); + } + + dest += deststride; + + /* + * The assembly tests the index as unsigned, so an adjustment that takes it below + * zero shows up as a very large value and folds back to zero. + */ + unsigned short next = (unsigned short)((unsigned short)*channel.Index + (unsigned short)_SosIndexAdjust[code]); + + if (next >= 0x8000) { + next = 0; + } else if (next > 88) { + next = 88; + } + + *channel.Index = (short)next; + *channel.Step = (short)_SosStepTable[next]; + + (*channel.SampleIndex)++; + } +} + + +SosChannel Left_Channel(_SOS_COMPRESS_INFO * info) +{ + SosChannel channel; + channel.SampleIndex = &info->dwSampleIndex; + channel.CodeBuf = &info->wCodeBuf; + channel.Code = &info->wCode; + channel.Predicted = &info->dwPredicted; + channel.Difference = &info->dwDifference; + channel.Index = &info->wIndex; + channel.Step = &info->wStep; + return(channel); +} + + +SosChannel Right_Channel(_SOS_COMPRESS_INFO * info) +{ + SosChannel channel; + channel.SampleIndex = &info->dwSampleIndex2; + channel.CodeBuf = &info->wCodeBuf2; + channel.Code = &info->wCode2; + channel.Predicted = &info->dwPredicted2; + channel.Difference = &info->dwDifference2; + channel.Index = &info->wIndex2; + channel.Step = &info->wStep2; + return(channel); +} + +} // namespace + + +/// +/// Starts a compression stream, clearing the running sample and step index for both channels. +/// +/// The stream to initialize. +void __cdecl sosCODECInitStream(_SOS_COMPRESS_INFO * info) +{ + info->wIndex = 0; + info->dwPredicted = 0; + info->wIndex2 = 0; + info->dwPredicted2 = 0; +} + + +/// +/// Decompresses 4:1 ADPCM, the specialized path for 16 bit mono. Anything else is left alone, +/// as it was in the assembly, where only this one shape was ever implemented. +/// +/// Stream state, source and destination. +/// How many bytes of samples to produce. +/// unsigned long; The byte count asked for, or zero if the shape is not handled. +unsigned long __cdecl sosCODECDecompressData(_SOS_COMPRESS_INFO * info, unsigned long bytes) +{ + if (info->wBitSize != 16 || info->wChannels != 1) { + return(0); + } + + unsigned short index = (unsigned short)info->wIndex; + + Decode_Table_16((unsigned char const *)info->lpSource, (short *)info->lpDest, (int)(bytes / 2), 1, info->dwPredicted, index); + + info->wIndex = (short)index; + return(bytes); +} + + +/// +/// Starts a compression stream for the general decoder. +/// +/// The stream to initialize. +void __cdecl General_sosCODECInitStream(_SOS_COMPRESS_INFO * info) +{ + info->wIndex = 0; + info->wStep = (short)_SosStepTable[0]; + info->dwPredicted = 0; + info->dwSampleIndex = 0; + info->wIndex2 = 0; + info->wStep2 = (short)_SosStepTable[0]; + info->dwPredicted2 = 0; + info->dwSampleIndex2 = 0; +} + + +/// +/// Decompresses 4:1 ADPCM for any bit size and channel count. +/// +/// The assembly counted down and only then tested for zero, so a request for nothing, or an +/// odd number of samples on the stereo path, never reached the test and ran away through both +/// buffers. Those requests now decode nothing instead. +/// +/// Stream state, source and destination. +/// How many bytes of samples to produce. +/// unsigned long; The byte count asked for. +unsigned long __cdecl General_sosCODECDecompressData(_SOS_COMPRESS_INFO * info, unsigned long bytes) +{ + info->dwSampleIndex = 0; + info->dwSampleIndex2 = 0; + + int const bits = info->wBitSize; + int const samples = (bits == 16) ? (int)(bytes / 2) : (int)bytes; + + if (samples <= 0) { + return(bytes); + } + + unsigned char const * source = (unsigned char const *)info->lpSource; + unsigned char * dest = (unsigned char *)info->lpDest; + + if (info->wChannels == 2) { + if ((samples % 2) != 0) { + return(bytes); + } + + int const perchannel = samples / 2; + int const sampled = (bits == 16) ? 4 : 2; + + Decode_General(Left_Channel(info), source, dest, perchannel, 2, sampled, bits); + Decode_General(Right_Channel(info), source + 1, dest + (bits == 16 ? 2 : 1), perchannel, 2, sampled, bits); + } else { + Decode_General(Left_Channel(info), source, dest, samples, 1, (bits == 16) ? 2 : 1, bits); + } + + return(bytes); +} + + +/// +/// Starts a VQA compression stream. +/// +/// The stream to initialize. +void __cdecl VQA_sosCODECInitStream(_VQA_SOS_COMPRESS_INFO * info) +{ + info->wIndex = 0; + info->dwPredicted = 0; + info->wIndex2 = 0; + info->dwPredicted2 = 0; +} + + +/// +/// Decompresses 4:1 ADPCM for VQA audio. Only 16 bit is implemented, mono and stereo; an 8 bit +/// request does nothing, which is what the assembly did. +/// +/// A stereo stream carries its two channels as consecutive halves of the source rather than +/// interleaved, and writes them interleaved into the destination. +/// +/// Compressed nybbles. +/// Where the samples go. +/// Sample width; only 16 is handled. +/// 1 or 2. +/// How many bytes of samples to produce. +/// Stream state carried between calls. +void __cdecl VQA_sosCODECDecompressData(void * src, void * dst, unsigned short bits, unsigned short channels, unsigned long bytes, _VQA_SOS_COMPRESS_INFO * info) +{ + if (bits != 16) { + return; + } + + unsigned char const * source = (unsigned char const *)src; + short * dest = (short *)dst; + + if (channels == 2) { + int const perchannel = (int)(bytes / 4); + unsigned short index = (unsigned short)info->wIndex; + unsigned short index2 = (unsigned short)info->wIndex2; + + Decode_Table_16(source, dest, perchannel, 2, info->dwPredicted, index); + Decode_Table_16(source + (bytes >> 3), dest + 1, perchannel, 2, info->dwPredicted2, index2); + + info->wIndex = (short)index; + info->wIndex2 = (short)index2; + return; + } + + if (channels != 1) { + return; + } + + unsigned short index = (unsigned short)info->wIndex; + + Decode_Table_16(source, dest, (int)(bytes / 2), 1, info->dwPredicted, index); + + info->wIndex = (short)index; +} diff --git a/code/soscomp.h b/code/soscomp.h index 5dc6fd5d..4fc8eb0f 100644 --- a/code/soscomp.h +++ b/code/soscomp.h @@ -69,7 +69,6 @@ struct _SOS_COMPRESS_HEADER { extern "C" { void __cdecl sosCODECInitStream(_SOS_COMPRESS_INFO *); void __cdecl General_sosCODECInitStream(_SOS_COMPRESS_INFO *); - unsigned long __cdecl sosCODECCompressData(_SOS_COMPRESS_INFO *, unsigned long); unsigned long __cdecl sosCODECDecompressData(_SOS_COMPRESS_INFO *, unsigned long); unsigned long __cdecl General_sosCODECDecompressData(_SOS_COMPRESS_INFO *, unsigned long); } diff --git a/code/vqa_sos.asm b/code/vqa_sos.asm deleted file mode 100644 index 3ccc0fb1..00000000 --- a/code/vqa_sos.asm +++ /dev/null @@ -1,1406 +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. -;****************************************************************************** - -;**************************************************************************** -;* -;* Copyright (c) 1994, HMI, INC. All Rights Reserved -;* -;*--------------------------------------------------------------------------- -;* -;* FILE -;* soscodec.asm -;* -;* DESCRIPTION -;* HMI SOS ADPCM compression/decompression. -;* -;* PROGRAMMER -;* Nick Skrepetos -;* Denzil E. Long, Jr. (Fixed bugs, rewrote for watcom) -;* Bill Petro (Added stereo support) -;* Jonathan Lanier -;* -;* DATE -;* Febuary 15, 1995 -;* -;* LAST MODIFIED -;* 08/07/95 [jdl] - Rewrote/optimized sosCODECDecompressData -;* -;*--------------------------------------------------------------------------- -;* -;* PUBLIC -;* -;**************************************************************************** - - ;IDEAL - .386P;P386 - .MODEL FLAT, C ;MODEL USE32 FLAT - ;LOCALS ?? - -; avoids symbol conflicts with regular SOS -dwDiffTable equ VQA_dwDiffTable -wIndexTable equ VQA_wIndexTable -bNybbleTableLow equ VQA_bNybbleTableLow -bNybbleTableHigh equ VQA_bNybbleTableHigh - - -DPMI_INTR equ 31h -IF_LOCKED_PM_CODE equ 1h ; Locked PM code for DPMI. -IF_LOCKED_PM_DATA equ 2h ; Locked PM code for DPMI. - - sCompInfo STRUC -dwPredicted DD ? ;Next predicted value -wIndex DW ? ;Index into step table - -dwPredicted2 DD ? ;Next predicted value -wIndex2 DW ? ;Index into step table - sCompInfo ENDS - - - .DATA;DATASEG - - -;InitFlags DD 0 ; Flags to indicate what has been initialized. - - -;LABEL LockedDataStart BYTE - -;* Index table for stepping into step table - -INCLUDE difftb.inc -INCLUDE indextb.inc -INCLUDE nybbtb.inc - -;LABEL LockedDataEnd BYTE - - .CODE;CODESEG - -;LABEL LockedCodeStart BYTE - -;**************************************************************************** -;* -;* NAME -;* sosCODECInitStream - Initialize compression stream. -;* -;* SYNOPSIS -;* sosCODECInitStream(CompInfo) -;* -;* void sosCODECInitStream(_SOS_COMPRESS_INFO *); -;* -;* FUNCTION -;* Initialize compression stream for compression and decompression. -;* -;* INPUTS -;* CompInfo - Compression information structure. -;* -;* RESULT -;* NONE -;* -;**************************************************************************** - - PUBLIC VQA_sosCODECInitStream - VQA_sosCODECInitStream PROC NEAR \ - \ - sSOSInfo:DWORD - - assume eax:ptr sCompInfo - - mov eax,[sSOSInfo] - mov [[eax].wIndex],0 ; starting index 0 - mov [[eax].dwPredicted],0 ; no predicted value - mov [[eax].wIndex2],0 ; starting index 0 - mov [[eax].dwPredicted2],0 ; no predicted value - ret - - VQA_sosCODECInitStream ENDP - - - -;**************************************************************************** -;* -;* NAME -;* sosCODECDecompressData - Decompress audio data. -;* -;* SYNOPSIS -;* Size = sosCODECDecompressData(CompInfo, NumBytes) -;* -;* long sosCODECDecompressData(_SOS_COMPRESS_INFO *, long); -;* -;* FUNCTION -;* Decompress data from a 4:1 ADPCM compressed stream. The number of -;* bytes decompressed is returned. -;* -;* INPUTS -;* CompInfo - Compress information structure. -;* NumBytes - Number of bytes to decompress. -;* -;* RESULT -;* Size - Size of decompressed data. -;* -;* -;* NOTES -;* This routine has been optimized for pipelining on both -;* 486 and Pentium processors. Changing, inserting, or moving any -;* instructions will most likely slow down the code, in some cases by -;* as much as 20%. It can burst-decompress 16384 samples in about -;* 1940?s on a Pentium 90Mhz, and about 3960?s on a 486 66Mhz. -;* Instruction reordering could bring this down to below 1870?s on -;* the Pentium, but this would cause a great degradation in 486 -;* performance. Since slow 486's are the reason this code was -;* written to be fast, it has been optimized for the Pentium only where -;* it would not degrade 486 performance. So, be careful when changing -;* ANY of this code, because it is very carefully balanced... -;**************************************************************************** - - PUBLIC VQA_sosCODECDecompressData - VQA_sosCODECDecompressData PROC NEAR \ - \ - lpSource:DWORD, \ - lpDest:DWORD, \ - wBitSize:WORD, \ - wChannels:WORD, \ - wBytes:DWORD, \ - sSOSInfo:DWORD - - assume ebx:ptr sCompInfo - - push esi - push edi - push ebx - push ecx - push edx ;save all the regs - - mov ebx,[sSOSInfo] ;get base of sCompInfo struct - mov cx,[wBitSize] ;check the bit size - mov dx,[wChannels] ;check the number of channels -; -; -; Determine the correct routine to use for decoding -; (for now only ADPCM 4:1 Mono 16-bit is implemented) - cmp cx,8 - jne ??do16Bits - -??do8Bits: - cmp dx,2 - jne ??not8Stereo -; jmp ??decomp8Stereo - jmp ??byeBye - -??not8Stereo: - cmp dx,1 - jne ??byeBye -; jmp decomp8Mono - jmp ??byeBye - -??do16Bits: - cmp cx,16 - jne ??byeBye - - cmp dx,2 - jne ??not16Stereo - jmp ??decomp16Stereo -; jmp ??byeBye - -??not16Stereo: - cmp dx,1 - jne ??byeBye - - push ebp -; -; -; 16 bit ADPCM 4:1 Mono pre-loop initialization -??decomp16Mono: - push ebx ;save struct base - xor edx,edx ;clear index - mov eax,[[ebx].dwPredicted] ;get last sample - mov dx,[[ebx].wIndex] ;get last index value - mov esi,[lpSource] ;get source address - mov edi,[lpDest] ;get dest address - - mov ebp,[wBytes] ;get the number of dest. bytes - cmp ebp,16 ;less than 16? (less than 8 samples) - jl ??fixAlign16Mono0 ;if so, don't bother with alignment -; -; -; Check to see if we need to fix an alignment problem on the source buffer -; (non-aligned buffers are MUCH slower; if we're given a non-DWORD aligned -; source address, we do as many samples as needed to get to the nearest -; DWORD boundary, then finish the bulk as a DWORD-aligned decompress). - mov ebx,esi ;get source address - and ebx,03h ;check LSB - jnz ??fixalign16Mono ;if non-zero, need to align for - ;warp speed -??fixAlign16Mono0: - push ebp ;save for later - shr ebp,4 ;divide by 16 for 16-bit, - ;because we do 8 nybbles per loop, - ;and there are two samples per - ;byte, so there are n/16 iterations - ;required - xor ebx,ebx ;clear our nybble index - or ebp,ebp ;set flags for EBP - jmp ??start16Mono ;start with test... don't go if - ;we have zero bytes to do -??fixalign16Mono: - jmp [DWORD PTR dwMono16AlignJmpTable+ebx*4] ;do non-aligned first - - align 4 -??fixAlign16Mono1: - sub ebp,12 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Mono6 ;borrow exit code to go through a - ;piece of a loop - align 4 -??fixAlign16Mono2: - sub ebp,8 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Mono4 ;borrow exit code to go through a - ;piece of a loop - align 4 -??fixAlign16Mono3: - sub ebp,4 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Mono2 ;borrow exit code to go through a - ;piece of a loop -; "The Loop" -; -; Process 1st nybble - align 4 -??loop16Mono: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix1Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix1Smp16MonoU -??fixed1Smp16Mono: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi],ax ;save the sample -; -; -; Process 2nd nybble -??finish7Smp16Mono: - mov bl,ch ;get next 2 nybbles in ebx - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix2Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix2Smp16MonoU -??fixed2Smp16Mono: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+02h],ax ;save the sample - shr ecx,16 ;move top four nybbles into bottom -; -; -; Process 3rd nybble -??finish6Smp16Mono: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix3Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix3Smp16MonoU -??fixed3Smp16Mono: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+04h],ax ;save the sample -; -; -; Process 4th nybble -??finish5Smp16Mono: - mov bl,cl - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix4Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix4Smp16MonoU -??fixed4Smp16Mono: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+06h],ax ;save the sample -; -; -; Process 5th nybble -??finish4Smp16Mono: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix5Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix5Smp16MonoU -??fixed5Smp16Mono: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+08h],ax ;save the sample -; -; -; Process 6th nybble -??finish3Smp16Mono: - mov bl,ch - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix6Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix6Smp16MonoU -??fixed6Smp16Mono: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+0Ah],ax ;save the sample -; -; -; Process 7th nybble -??finish2Smp16Mono: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix7Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix7Smp16MonoU -??fixed7Smp16Mono: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+0Ch],ax ;save the sample -; -; -; Process 8th nybble -??finish1Smp16Mono: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix8Smp16MonoO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix8Smp16MonoU -; -; -; Loop cleanup for next pass -??fixed8Smp16Mono: - mov [edi+0Eh],ax ;save the sample - add esi,04h ;bump esi to point to next longword - add edi,10h ;incr. the destination buffer ptr - dec ebp ;count down the number of samples/8 -??start16Mono: - jng ??cleanup16Mono ;if done, clean up - mov ecx,[esi] ;get 4 nybbles in one whack (whee!) - mov bl,cl ;get next 2 nybbles in ebx - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??loop16Mono ;loop until done - -??cleanup16Mono: - jnz ??done16Mono ;if ebp is non-zero, we're DONE - ;if exactly zero, finish the tail-end - ;of the conversion (may be a non- - ;multiple of 8 nybbles) -; -; -; Loop cleanup for last (incomplete) pass - pop ecx ;restore # of words - shr ecx,1 ;divide by two to get samples - and ecx,07h ;get # of samples we missed - jmp [DWORD PTR dwMono16JmpTable+ecx*4] ;go finish the job... -; -; -; Structure cleanup -??done16Mono: - pop ebx ;restore struct base - pop ebp ;restore stack frame pointer - mov [[ebx].dwPredicted],eax ;save last sample - mov [[ebx].wIndex],dx ;save last index value - mov eax,[wBytes] ;get # of bytes we did -??byeBye: - pop edx ;restore all the regs - pop ecx - pop ebx - pop edi - pop esi - ret -; -; -; Jumps for -32768/+32767 bounds check go to these vvvv - align 4 -??fix1Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed1Smp16Mono ;go back - - align 4 -??fix1Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed1Smp16Mono ;go back - - align 4 -??fix2Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed2Smp16Mono ;go back - - align 4 -??fix2Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed2Smp16Mono ;go back - - align 4 -??fix3Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed3Smp16Mono ;go back - - align 4 -??fix3Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed3Smp16Mono ;go back - - align 4 -??fix4Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed4Smp16Mono ;go back - - align 4 -??fix4Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed4Smp16Mono ;go back - - align 4 -??fix5Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed5Smp16Mono ;go back - - align 4 -??fix5Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed5Smp16Mono ;go back - - align 4 -??fix6Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed6Smp16Mono ;go back - - align 4 -??fix6Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed6Smp16Mono ;go back - - align 4 -??fix7Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed7Smp16Mono ;go back - - align 4 -??fix7Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed7Smp16Mono ;go back - - align 4 -??fix8Smp16MonoO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed8Smp16Mono ;go back - - align 4 -??fix8Smp16MonoU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed8Smp16Mono ;go back -; -; -; Jump tables for cleanup after loop unroll point to these vvvv - align 4 -??finish16Mono1: - xor ecx,ecx ;clear nybble bucket - mov ch,[esi] ;get 1 nybble (1 byte) - shl ch,4 ;move it over - mov bl,ch ;get nybble in ebx - sub edi,0Eh ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish1Smp16Mono ;go finish it - - align 4 -??finish16Mono2: - xor ecx,ecx ;clear nybble bucket - mov ch,[esi] ;get 2 nybbles (1 byte) - mov bl,ch ;get nybbles in ebx - sub edi,0Ch ;back edi up - sub esi,3 ;adjust esi (used for dword aligning) - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish2Smp16Mono ;go finish it - - align 4 -??finish16Mono3: - xor ecx,ecx ;clear nybble bucket - mov cx,[esi] ;get 3 nybbles (2 bytes) - shl cx,4 ;move it over - mov bl,cl ;get nybbles in ebx - sub edi,0Ah ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish3Smp16Mono ;go finish it - - align 4 -??finish16Mono4: - xor ecx,ecx ;clear nybble bucket - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - sub edi,08h ;back edi up - sub esi,2 ;adjust esi (used for dword aligning) - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish4Smp16Mono ;go finish it - - align 4 -??finish16Mono5: - xor ecx,ecx ;clear nybble bucket - mov cl,[esi+2] ;get 1 nybble (1 byte) - shl ecx,16 ;shift it over - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - shr ecx,4 ;move it over - shl bl,4 ;move it over - sub edi,06h ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish5Smp16Mono ;go finish it - - align 4 -??finish16Mono6: - xor ecx,ecx ;clear nybble bucket - mov cl,[esi+2] ;get 2 nybbles (1 byte) - shl ecx,16 ;move it over - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - shr ecx,8 ;move it over - sub esi,1 ;adjust esi (used for dword aligning) - sub edi,04h ;back edi up - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish6Smp16Mono ;go finish it - - align 4 -??finish16Mono7: - xor ecx,ecx ;clear nybble bucket - mov ecx,[esi] ;get 7 nybbles (4 bytes) - shl ecx,4 ;move it over - mov bl,cl ;get nybbles in ebx - sub edi,02h ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish7Smp16Mono ;go finish it -; -; -; Jump Tables - align 4 - -dwMono16JmpTable DD ??done16Mono - DD ??finish16Mono1 - DD ??finish16Mono2 - DD ??finish16Mono3 - DD ??finish16Mono4 - DD ??finish16Mono5 - DD ??finish16Mono6 - DD ??finish16Mono7 - - align 4 -dwMono16AlignJmpTable DD ??fixAlign16Mono0 - DD ??fixAlign16Mono1 - DD ??fixAlign16Mono2 - DD ??fixAlign16Mono3 - -??decomp16Stereo: - -??decomp16StereoLeft: - push ebp -; -; -; 16 bit ADPCM 4:1 Left pre-loop initialization -??decomp16Left: - push ebx ;save struct base - xor edx,edx ;clear index - mov eax,[[ebx].dwPredicted] ;get last sample - mov dx,[[ebx].wIndex] ;get last index value - mov esi,[lpSource] ;get source address - mov edi,[lpDest] ;get dest address - - mov ebp,[wBytes] ;get the number of dest. bytes - shr ebp,1 - cmp ebp,16 ;less than 16? (less than 8 samples) - jl ??fixAlign16Left0 ;if so, don't bother with alignment -; -; -; Check to see if we need to fix an alignment problem on the source buffer -; (non-aligned buffers are MUCH slower; if we're given a non-DWORD aligned -; source address, we do as many samples as needed to get to the nearest -; DWORD boundary, then finish the bulk as a DWORD-aligned decompress). - mov ebx,esi ;get source address - and ebx,03h ;check LSB - jnz ??fixalign16Left ;if non-zero, need to align for - ;warp speed -??fixAlign16Left0: - push ebp ;save for later - shr ebp,4 ;divide by 16 for 16-bit, - ;because we do 8 nybbles per loop, - ;and there are two samples per - ;byte, so there are n/16 iterations - ;required - xor ebx,ebx ;clear our nybble index - or ebp,ebp ;set flags for EBP - jmp ??start16Left ;start with test... don't go if - ;we have zero bytes to do -??fixalign16Left: - jmp [DWORD PTR dwLeft16AlignJmpTable+ebx*4] ;do non-aligned first - - align 4 -??fixAlign16Left1: - sub ebp,12 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Left6 ;borrow exit code to go through a - ;piece of a loop - align 4 -??fixAlign16Left2: - sub ebp,8 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Left4 ;borrow exit code to go through a - ;piece of a loop - align 4 -??fixAlign16Left3: - sub ebp,4 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Left2 ;borrow exit code to go through a - ;piece of a loop -; "The Loop" -; -; Process 1st nybble - align 4 -??loop16Left: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix1Smp16LeftO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix1Smp16LeftU -??fixed1Smp16Left: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi],ax ;save the sample -; -; -; Process 2nd nybble -??finish7Smp16Left: - mov bl,ch ;get next 2 nybbles in ebx - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix2Smp16LeftO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix2Smp16LeftU -??fixed2Smp16Left: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+2*02h],ax ;save the sample - shr ecx,16 ;move top four nybbles into bottom -; -; -; Process 3rd nybble -??finish6Smp16Left: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix3Smp16LeftO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix3Smp16LeftU -??fixed3Smp16Left: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+2*04h],ax ;save the sample -; -; -; Process 4th nybble -??finish5Smp16Left: - mov bl,cl - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix4Smp16LeftO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix4Smp16LeftU -??fixed4Smp16Left: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+2*06h],ax ;save the sample -; -; -; Process 5th nybble -??finish4Smp16Left: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix5Smp16LeftO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix5Smp16LeftU -??fixed5Smp16Left: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+2*08h],ax ;save the sample -; -; -; Process 6th nybble -??finish3Smp16Left: - mov bl,ch - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix6Smp16LeftO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix6Smp16LeftU -??fixed6Smp16Left: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+2*0Ah],ax ;save the sample -; -; -; Process 7th nybble -??finish2Smp16Left: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix7Smp16LeftO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix7Smp16LeftU -??fixed7Smp16Left: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+2*0Ch],ax ;save the sample -; -; -; Process 8th nybble -??finish1Smp16Left: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix8Smp16LeftO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix8Smp16LeftU -; -; -; Loop cleanup for next pass -??fixed8Smp16Left: - mov [edi+2*0Eh],ax ;save the sample - add esi,04h ;bump esi to point to next longword - add edi,2*10h ;incr. the destination buffer ptr - dec ebp ;count down the number of samples/8 -??start16Left: - jng ??cleanup16Left ;if done, clean up - mov ecx,[esi] ;get 4 nybbles in one whack (whee!) - mov bl,cl ;get next 2 nybbles in ebx - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??loop16Left ;loop until done - -??cleanup16Left: - jnz ??done16Left ;if ebp is non-zero, we're DONE - ;if exactly zero, finish the tail-end - ;of the conversion (may be a non- - ;multiple of 8 nybbles) -; -; -; Loop cleanup for last (incomplete) pass - pop ecx ;restore # of words - shr ecx,1 ;divide by two to get samples - and ecx,07h ;get # of samples we missed - jmp [DWORD PTR dwLeft16JmpTable+ecx*4] ;go finish the job... -; -; -; Structure cleanup -??done16Left: - pop ebx ;restore struct base - pop ebp ;restore stack frame pointer - mov [[ebx].dwPredicted],eax ;save last sample - mov [[ebx].wIndex],dx ;save last index value -; mov eax,[wBytes] ;get # of bytes we did - jmp ??decomp16StereoRight -; -; -; Jumps for -32768/+32767 bounds check go to these vvvv - align 4 -??fix1Smp16LeftO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed1Smp16Left ;go back - - align 4 -??fix1Smp16LeftU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed1Smp16Left ;go back - - align 4 -??fix2Smp16LeftO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed2Smp16Left ;go back - - align 4 -??fix2Smp16LeftU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed2Smp16Left ;go back - - align 4 -??fix3Smp16LeftO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed3Smp16Left ;go back - - align 4 -??fix3Smp16LeftU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed3Smp16Left ;go back - - align 4 -??fix4Smp16LeftO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed4Smp16Left ;go back - - align 4 -??fix4Smp16LeftU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed4Smp16Left ;go back - - align 4 -??fix5Smp16LeftO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed5Smp16Left ;go back - - align 4 -??fix5Smp16LeftU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed5Smp16Left ;go back - - align 4 -??fix6Smp16LeftO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed6Smp16Left ;go back - - align 4 -??fix6Smp16LeftU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed6Smp16Left ;go back - - align 4 -??fix7Smp16LeftO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed7Smp16Left ;go back - - align 4 -??fix7Smp16LeftU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed7Smp16Left ;go back - - align 4 -??fix8Smp16LeftO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed8Smp16Left ;go back - - align 4 -??fix8Smp16LeftU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed8Smp16Left ;go back -; -; -; Jump tables for cleanup after loop unroll point to these vvvv - align 4 -??finish16Left1: - xor ecx,ecx ;clear nybble bucket - mov ch,[esi] ;get 1 nybble (1 byte) - shl ch,4 ;move it over - mov bl,ch ;get nybble in ebx - sub edi,2*0Eh ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish1Smp16Left ;go finish it - - align 4 -??finish16Left2: - xor ecx,ecx ;clear nybble bucket - mov ch,[esi] ;get 2 nybbles (1 byte) - mov bl,ch ;get nybbles in ebx - sub edi,2*0Ch ;back edi up - sub esi,3 ;adjust esi (used for dword aligning) - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish2Smp16Left ;go finish it - - align 4 -??finish16Left3: - xor ecx,ecx ;clear nybble bucket - mov cx,[esi] ;get 3 nybbles (2 bytes) - shl cx,4 ;move it over - mov bl,cl ;get nybbles in ebx - sub edi,2*0Ah ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish3Smp16Left ;go finish it - - align 4 -??finish16Left4: - xor ecx,ecx ;clear nybble bucket - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - sub edi,2*08h ;back edi up - sub esi,2 ;adjust esi (used for dword aligning) - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish4Smp16Left ;go finish it - - align 4 -??finish16Left5: - xor ecx,ecx ;clear nybble bucket - mov cl,[esi+2] ;get 1 nybble (1 byte) - shl ecx,16 ;shift it over - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - shr ecx,4 ;move it over - shl bl,4 ;move it over - sub edi,2*06h ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish5Smp16Left ;go finish it - - align 4 -??finish16Left6: - xor ecx,ecx ;clear nybble bucket - mov cl,[esi+2] ;get 2 nybbles (1 byte) - shl ecx,16 ;move it over - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - shr ecx,8 ;move it over - sub esi,1 ;adjust esi (used for dword aligning) - sub edi,2*04h ;back edi up - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish6Smp16Left ;go finish it - - align 4 -??finish16Left7: - xor ecx,ecx ;clear nybble bucket - mov ecx,[esi] ;get 7 nybbles (4 bytes) - shl ecx,4 ;move it over - mov bl,cl ;get nybbles in ebx - sub edi,2*02h ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish7Smp16Left ;go finish it -; -; -; Jump Tables - align 4 - -dwLeft16JmpTable DD ??done16Left - DD ??finish16Left1 - DD ??finish16Left2 - DD ??finish16Left3 - DD ??finish16Left4 - DD ??finish16Left5 - DD ??finish16Left6 - DD ??finish16Left7 - - align 4 -dwLeft16AlignJmpTable DD ??fixAlign16Left0 - DD ??fixAlign16Left1 - DD ??fixAlign16Left2 - DD ??fixAlign16Left3 - -??decomp16StereoRight: - push ebp -; -; -; 16 bit ADPCM 4:1 Right pre-loop initialization -??decomp16Right: - push ebx ;save struct base - mov esi,[lpSource] ;get source address - mov edi,[lpDest] ;get dest address - - add edi,2 - mov edx,[wBytes] - shr edx,3 - add esi,edx - - xor edx,edx ;clear index - mov eax,[[ebx].dwPredicted2] ;get last sample - mov dx,[[ebx].wIndex2] ;get last index value - - mov ebp,[wBytes] ;get the number of dest. bytes - shr ebp,1 - cmp ebp,16 ;less than 16? (less than 8 samples) - jl ??fixAlign16Right0 ;if so, don't bother with alignment -; -; -; Check to see if we need to fix an alignment problem on the source buffer -; (non-aligned buffers are MUCH slower; if we're given a non-DWORD aligned -; source address, we do as many samples as needed to get to the nearest -; DWORD boundary, then finish the bulk as a DWORD-aligned decompress). - mov ebx,esi ;get source address - and ebx,03h ;check LSB - jnz ??fixalign16Right ;if non-zero, need to align for - ;warp speed -??fixAlign16Right0: - push ebp ;save for later - shr ebp,4 ;divide by 16 for 16-bit, - ;because we do 8 nybbles per loop, - ;and there are two samples per - ;byte, so there are n/16 iterations - ;required - xor ebx,ebx ;clear our nybble index - or ebp,ebp ;set flags for EBP - jmp ??start16Right ;start with test... don't go if - ;we have zero bytes to do -??fixalign16Right: - jmp [DWORD PTR dwRight16AlignJmpTable+ebx*4] ;do non-aligned first - - align 4 -??fixAlign16Right1: - sub ebp,12 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Right6 ;borrow exit code to go through a - ;piece of a loop - align 4 -??fixAlign16Right2: - sub ebp,8 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Right4 ;borrow exit code to go through a - ;piece of a loop - align 4 -??fixAlign16Right3: - sub ebp,4 ;adjust # of dest. bytes - push ebp ;save it - shr ebp,4 ;divide by 16 to get samples/8 - xor ebx,ebx ;clear our nybble index - inc ebp ;adjust ebp for loop - jmp ??finish16Right2 ;borrow exit code to go through a - ;piece of a loop -; "The Loop" -; -; Process 1st nybble - align 4 -??loop16Right: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix1Smp16RightO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix1Smp16RightU -??fixed1Smp16Right: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi],ax ;save the sample -; -; -; Process 2nd nybble -??finish7Smp16Right: - mov bl,ch ;get next 2 nybbles in ebx - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix2Smp16RightO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix2Smp16RightU -??fixed2Smp16Right: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+2*02h],ax ;save the sample - shr ecx,16 ;move top four nybbles into bottom -; -; -; Process 3rd nybble -??finish6Smp16Right: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix3Smp16RightO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix3Smp16RightU -??fixed3Smp16Right: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+2*04h],ax ;save the sample -; -; -; Process 4th nybble -??finish5Smp16Right: - mov bl,cl - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix4Smp16RightO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix4Smp16RightU -??fixed4Smp16Right: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+2*06h],ax ;save the sample -; -; -; Process 5th nybble -??finish4Smp16Right: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix5Smp16RightO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix5Smp16RightU -??fixed5Smp16Right: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+2*08h],ax ;save the sample -; -; -; Process 6th nybble -??finish3Smp16Right: - mov bl,ch - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix6Smp16RightO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix6Smp16RightU -??fixed6Smp16Right: - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - mov [edi+2*0Ah],ax ;save the sample -; -; -; Process 7th nybble -??finish2Smp16Right: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix7Smp16RightO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix7Smp16RightU -??fixed7Smp16Right: - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - mov [edi+2*0Ch],ax ;save the sample -; -; -; Process 8th nybble -??finish1Smp16Right: - add eax,[dwDiffTable+edx*2] ;add difference to prev. sample - mov dx,[wIndexTable+edx] ;adjust dx to next index base - cmp eax,00007FFFh ;check for overflow - jg ??fix8Smp16RightO - cmp eax,0FFFF8000h ;check for underflow - jl ??fix8Smp16RightU -; -; -; Loop cleanup for next pass -??fixed8Smp16Right: - mov [edi+2*0Eh],ax ;save the sample - add esi,04h ;bump esi to point to next longword - add edi,2*10h ;incr. the destination buffer ptr - dec ebp ;count down the number of samples/8 -??start16Right: - jng ??cleanup16Right ;if done, clean up - mov ecx,[esi] ;get 4 nybbles in one whack (whee!) - mov bl,cl ;get next 2 nybbles in ebx - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??loop16Right ;loop until done - -??cleanup16Right: - jnz ??done16Right ;if ebp is non-zero, we're DONE - ;if exactly zero, finish the tail-end - ;of the conversion (may be a non- - ;multiple of 8 nybbles) -; -; -; Loop cleanup for last (incomplete) pass - pop ecx ;restore # of words - shr ecx,1 ;divide by two to get samples - and ecx,07h ;get # of samples we missed - jmp [DWORD PTR dwRight16JmpTable+ecx*4] ;go finish the job... -; -; -; Structure cleanup -??done16Right: - pop ebx ;restore struct base - pop ebp ;restore stack frame pointer - mov [[ebx].dwPredicted2],eax ;save last sample - mov [[ebx].wIndex2],dx ;save last index value - mov eax,[wBytes] ;get # of bytes we did - jmp ??byeBye -; -; -; Jumps for -32768/+32767 bounds check go to these vvvv - align 4 -??fix1Smp16RightO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed1Smp16Right ;go back - - align 4 -??fix1Smp16RightU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed1Smp16Right ;go back - - align 4 -??fix2Smp16RightO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed2Smp16Right ;go back - - align 4 -??fix2Smp16RightU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed2Smp16Right ;go back - - align 4 -??fix3Smp16RightO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed3Smp16Right ;go back - - align 4 -??fix3Smp16RightU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed3Smp16Right ;go back - - align 4 -??fix4Smp16RightO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed4Smp16Right ;go back - - align 4 -??fix4Smp16RightU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed4Smp16Right ;go back - - align 4 -??fix5Smp16RightO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed5Smp16Right ;go back - - align 4 -??fix5Smp16RightU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed5Smp16Right ;go back - - align 4 -??fix6Smp16RightO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed6Smp16Right ;go back - - align 4 -??fix6Smp16RightU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed6Smp16Right ;go back - - align 4 -??fix7Smp16RightO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed7Smp16Right ;go back - - align 4 -??fix7Smp16RightU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed7Smp16Right ;go back - - align 4 -??fix8Smp16RightO: - mov eax,00007FFFh ;Overflow - truncate to +32767 - jmp ??fixed8Smp16Right ;go back - - align 4 -??fix8Smp16RightU: - mov eax,0FFFF8000h ;Underflow - truncate to -32768 - jmp ??fixed8Smp16Right ;go back -; -; -; Jump tables for cleanup after loop unroll point to these vvvv - align 4 -??finish16Right1: - xor ecx,ecx ;clear nybble bucket - mov ch,[esi] ;get 1 nybble (1 byte) - shl ch,4 ;move it over - mov bl,ch ;get nybble in ebx - sub edi,2*0Eh ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish1Smp16Right ;go finish it - - align 4 -??finish16Right2: - xor ecx,ecx ;clear nybble bucket - mov ch,[esi] ;get 2 nybbles (1 byte) - mov bl,ch ;get nybbles in ebx - sub edi,2*0Ch ;back edi up - sub esi,3 ;adjust esi (used for dword aligning) - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish2Smp16Right ;go finish it - - align 4 -??finish16Right3: - xor ecx,ecx ;clear nybble bucket - mov cx,[esi] ;get 3 nybbles (2 bytes) - shl cx,4 ;move it over - mov bl,cl ;get nybbles in ebx - sub edi,2*0Ah ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish3Smp16Right ;go finish it - - align 4 -??finish16Right4: - xor ecx,ecx ;clear nybble bucket - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - sub edi,2*08h ;back edi up - sub esi,2 ;adjust esi (used for dword aligning) - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish4Smp16Right ;go finish it - - align 4 -??finish16Right5: - xor ecx,ecx ;clear nybble bucket - mov cl,[esi+2] ;get 1 nybble (1 byte) - shl ecx,16 ;shift it over - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - shr ecx,4 ;move it over - shl bl,4 ;move it over - sub edi,2*06h ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish5Smp16Right ;go finish it - - align 4 -??finish16Right6: - xor ecx,ecx ;clear nybble bucket - mov cl,[esi+2] ;get 2 nybbles (1 byte) - shl ecx,16 ;move it over - mov cx,[esi] ;get 4 nybbles (2 bytes) - mov bl,cl ;get nybbles in ebx - shr ecx,8 ;move it over - sub esi,1 ;adjust esi (used for dword aligning) - sub edi,2*04h ;back edi up - or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble - jmp ??finish6Smp16Right ;go finish it - - align 4 -??finish16Right7: - xor ecx,ecx ;clear nybble bucket - mov ecx,[esi] ;get 7 nybbles (4 bytes) - shl ecx,4 ;move it over - mov bl,cl ;get nybbles in ebx - sub edi,2*02h ;back edi up - or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble - jmp ??finish7Smp16Right ;go finish it -; -; -; Jump Tables - align 4 - -dwRight16JmpTable DD ??done16Right - DD ??finish16Right1 - DD ??finish16Right2 - DD ??finish16Right3 - DD ??finish16Right4 - DD ??finish16Right5 - DD ??finish16Right6 - DD ??finish16Right7 - - align 4 -dwRight16AlignJmpTable DD ??fixAlign16Right0 - DD ??fixAlign16Right1 - DD ??fixAlign16Right2 - DD ??fixAlign16Right3 - - VQA_sosCODECDecompressData ENDP - - END - - diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5de329d7..7807b09b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(gamedirs) add_subdirectory(logstress) add_subdirectory(cpudetect) +add_subdirectory(sosparity) diff --git a/tests/sosparity/CMakeLists.txt b/tests/sosparity/CMakeLists.txt new file mode 100644 index 00000000..60f2d36b --- /dev/null +++ b/tests/sosparity/CMakeLists.txt @@ -0,0 +1,30 @@ +# The decoder 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(SosParity + "${CMAKE_CURRENT_SOURCE_DIR}/sosparity.cpp" + "${CMAKE_SOURCE_DIR}/code/soscodec.cpp" +) + +target_compile_features(SosParity PRIVATE cxx_std_20) + +target_include_directories(SosParity PRIVATE + "${CMAKE_SOURCE_DIR}/code" + "${CMAKE_CURRENT_SOURCE_DIR}" +) + +target_compile_definitions(SosParity 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(SosParity PRIVATE + $<$:/MTd /EHsc /Zc:__cplusplus /arch:SSE2 /fp:precise> + $<$:/MT /EHsc /Zc:__cplusplus /arch:SSE2 /fp:precise> +) + +target_link_libraries(SosParity PRIVATE kernel32 user32 shell32) + +set_target_properties(SosParity PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" +) + +add_test(NAME sosparity COMMAND SosParity) diff --git a/tests/sosparity/sosgolden.h b/tests/sosparity/sosgolden.h new file mode 100644 index 00000000..52c6e09c --- /dev/null +++ b/tests/sosparity/sosgolden.h @@ -0,0 +1,270 @@ +/******************************************************************************* + * 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 SOS ADPCM decoders 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 +// decode: the inputs, a hash of the destination buffer together with the bytes just past +// it, the count the decoder reported, and the stream state it left behind. +// +// Zero-length decodes and odd sample counts on the stereo path are absent on purpose: the +// assembly ran off both buffers on those, so it had no behaviour worth preserving. +// +// Generated file. Do not hand-edit. + +#pragma once + +struct SosGoldenCase { + int Codec; // 0 sosCODEC, 1 General_sosCODEC, 2 VQA_sosCODEC + int BitSize; + int Channels; + int Bytes; + int SourceAlign; + unsigned int Seed; + unsigned long long Hash; + unsigned long Returned; + long Predicted; + short Index; + long Predicted2; + short Index2; +}; + +static SosGoldenCase const SosGoldenCases[] = { + {0, 16, 1, 0, 0, 20264u, 5274368763727098819ULL, 0ul, 0, 0, 0, 0}, + {0, 16, 1, 0, 1, 28183u, 5274368763727098819ULL, 0ul, 0, 0, 0, 0}, + {0, 16, 1, 0, 2, 36102u, 5274368763727098819ULL, 0ul, 0, 0, 0, 0}, + {0, 16, 1, 0, 3, 44021u, 5274368763727098819ULL, 0ul, 0, 0, 0, 0}, + {0, 16, 1, 2, 0, 51940u, 13610437612761655990ULL, 2ul, -4, 0, 0, 0}, + {0, 16, 1, 2, 1, 59859u, 5496546865811898883ULL, 2ul, -7, 64, 0, 0}, + {0, 16, 1, 2, 2, 67778u, 12978567897254605458ULL, 2ul, 1, 0, 0, 0}, + {0, 16, 1, 2, 3, 75697u, 14060187829091914074ULL, 2ul, -8, 128, 0, 0}, + {0, 16, 1, 4, 0, 83616u, 15354726053559268155ULL, 4ul, 3, 0, 0, 0}, + {0, 16, 1, 4, 1, 91535u, 17758497508840661836ULL, 4ul, -3, 128, 0, 0}, + {0, 16, 1, 4, 2, 99454u, 18203407314218912118ULL, 4ul, 5, 192, 0, 0}, + {0, 16, 1, 4, 3, 107373u, 4150528965588047567ULL, 4ul, -1, 0, 0, 0}, + {0, 16, 1, 6, 0, 115292u, 9185414312197800190ULL, 6ul, 14, 448, 0, 0}, + {0, 16, 1, 6, 1, 123211u, 5830957061080840889ULL, 6ul, 1, 160, 0, 0}, + {0, 16, 1, 6, 2, 131130u, 15366521363562229954ULL, 6ul, 10, 384, 0, 0}, + {0, 16, 1, 6, 3, 139049u, 15128245409544142712ULL, 6ul, -1, 0, 0, 0}, + {0, 16, 1, 8, 0, 146968u, 14853089910075337439ULL, 8ul, -89, 704, 0, 0}, + {0, 16, 1, 8, 1, 154887u, 11337909234844552333ULL, 8ul, 35, 256, 0, 0}, + {0, 16, 1, 8, 2, 162806u, 5422447752634895630ULL, 8ul, 56, 480, 0, 0}, + {0, 16, 1, 8, 3, 170725u, 10252521348640859036ULL, 8ul, -15, 448, 0, 0}, + {0, 16, 1, 14, 0, 178644u, 14311769202811283897ULL, 14ul, -138, 960, 0, 0}, + {0, 16, 1, 14, 1, 186563u, 12712365809389159377ULL, 14ul, 12, 512, 0, 0}, + {0, 16, 1, 14, 2, 194482u, 7335098160264680671ULL, 14ul, -21, 416, 0, 0}, + {0, 16, 1, 14, 3, 202401u, 13676435463270447144ULL, 14ul, 105, 864, 0, 0}, + {0, 16, 1, 16, 0, 210320u, 1170345982649159698ULL, 16ul, -109, 672, 0, 0}, + {0, 16, 1, 16, 1, 218239u, 15441938223519084474ULL, 16ul, 19, 256, 0, 0}, + {0, 16, 1, 16, 2, 226158u, 10818996547221589014ULL, 16ul, -3, 192, 0, 0}, + {0, 16, 1, 16, 3, 234077u, 12221386661659597313ULL, 16ul, 174, 992, 0, 0}, + {0, 16, 1, 18, 0, 241996u, 15172564049796488522ULL, 18ul, 183, 864, 0, 0}, + {0, 16, 1, 18, 1, 249915u, 17935465075700011238ULL, 18ul, -22, 672, 0, 0}, + {0, 16, 1, 18, 2, 257834u, 10454247689239487127ULL, 18ul, 18, 288, 0, 0}, + {0, 16, 1, 18, 3, 265753u, 13546386653128937974ULL, 18ul, 129, 960, 0, 0}, + {0, 16, 1, 20, 0, 273672u, 7980149223572879927ULL, 20ul, -68, 640, 0, 0}, + {0, 16, 1, 20, 1, 281591u, 15408555689786398761ULL, 20ul, -7, 320, 0, 0}, + {0, 16, 1, 20, 2, 289510u, 13922476269201059982ULL, 20ul, -57, 544, 0, 0}, + {0, 16, 1, 20, 3, 297429u, 3606780486007698744ULL, 20ul, 9, 1024, 0, 0}, + {0, 16, 1, 30, 0, 305348u, 280245331949694907ULL, 30ul, -689, 1184, 0, 0}, + {0, 16, 1, 30, 1, 313267u, 7260216457094815919ULL, 30ul, -60, 960, 0, 0}, + {0, 16, 1, 30, 2, 321186u, 1198320268398845736ULL, 30ul, -31, 960, 0, 0}, + {0, 16, 1, 30, 3, 329105u, 10536187224048579643ULL, 30ul, -306, 1024, 0, 0}, + {0, 16, 1, 32, 0, 337024u, 7906698980633337235ULL, 32ul, -38, 544, 0, 0}, + {0, 16, 1, 32, 1, 344943u, 16519268349226066435ULL, 32ul, 0, 640, 0, 0}, + {0, 16, 1, 32, 2, 352862u, 15453207641938544575ULL, 32ul, -1126, 1536, 0, 0}, + {0, 16, 1, 32, 3, 360781u, 16100470903260047865ULL, 32ul, -567, 1088, 0, 0}, + {0, 16, 1, 34, 0, 368700u, 15713220814635393788ULL, 34ul, -74, 832, 0, 0}, + {0, 16, 1, 34, 1, 376619u, 13415305621050540748ULL, 34ul, -992, 1568, 0, 0}, + {0, 16, 1, 34, 2, 384538u, 4900783230497662646ULL, 34ul, -1308, 1600, 0, 0}, + {0, 16, 1, 34, 3, 392457u, 167305038471962918ULL, 34ul, 618, 1120, 0, 0}, + {0, 16, 1, 48, 0, 400376u, 7107284848441028346ULL, 48ul, -6073, 2080, 0, 0}, + {0, 16, 1, 48, 1, 408295u, 7107605843355047459ULL, 48ul, 10543, 2336, 0, 0}, + {0, 16, 1, 48, 2, 416214u, 3595676925368089172ULL, 48ul, 1258, 1824, 0, 0}, + {0, 16, 1, 48, 3, 424133u, 12948323636491828016ULL, 48ul, -352, 1600, 0, 0}, + {0, 16, 1, 64, 0, 432052u, 9899388477687943425ULL, 64ul, 4688, 2432, 0, 0}, + {0, 16, 1, 64, 1, 439971u, 13496053586220789409ULL, 64ul, -17844, 2304, 0, 0}, + {0, 16, 1, 64, 2, 447890u, 3641777821233128891ULL, 64ul, 2718, 1792, 0, 0}, + {0, 16, 1, 64, 3, 455809u, 8971773695870401005ULL, 64ul, -5650, 2176, 0, 0}, + {0, 16, 1, 100, 0, 463728u, 7498684829627092833ULL, 100ul, -32768, 2816, 0, 0}, + {0, 16, 1, 100, 1, 471647u, 13915309717216931807ULL, 100ul, -20482, 2784, 0, 0}, + {0, 16, 1, 100, 2, 479566u, 4095091591695163725ULL, 100ul, -24002, 2720, 0, 0}, + {0, 16, 1, 100, 3, 487485u, 3944738899366765040ULL, 100ul, 20481, 2784, 0, 0}, + {0, 16, 1, 128, 0, 495404u, 14520230991988790869ULL, 128ul, 11840, 2752, 0, 0}, + {0, 16, 1, 128, 1, 503323u, 8811338111480428814ULL, 128ul, 32767, 2816, 0, 0}, + {0, 16, 1, 128, 2, 511242u, 3945370601803369913ULL, 128ul, 32767, 2816, 0, 0}, + {0, 16, 1, 128, 3, 519161u, 16277102790415663415ULL, 128ul, 0, 2784, 0, 0}, + {0, 16, 1, 254, 0, 527080u, 5809103180587516122ULL, 254ul, -32768, 2816, 0, 0}, + {0, 16, 1, 254, 1, 534999u, 16157155190227307417ULL, 254ul, 32767, 2752, 0, 0}, + {0, 16, 1, 254, 2, 542918u, 1271540802129353514ULL, 254ul, -32768, 2816, 0, 0}, + {0, 16, 1, 254, 3, 550837u, 15859176993912080614ULL, 254ul, -32768, 2784, 0, 0}, + {0, 16, 1, 256, 0, 558756u, 9315686927156167034ULL, 256ul, 32767, 2816, 0, 0}, + {0, 16, 1, 256, 1, 566675u, 13593097283900326641ULL, 256ul, 32767, 2816, 0, 0}, + {0, 16, 1, 256, 2, 574594u, 2122553823323561861ULL, 256ul, -23843, 2816, 0, 0}, + {0, 16, 1, 256, 3, 582513u, 16810863911402418160ULL, 256ul, 32767, 2720, 0, 0}, + {0, 16, 1, 512, 0, 590432u, 16594943730014962698ULL, 512ul, -30544, 2816, 0, 0}, + {0, 16, 1, 512, 1, 598351u, 4449042173754640539ULL, 512ul, 32767, 2656, 0, 0}, + {0, 16, 1, 512, 2, 606270u, 8473865152050145026ULL, 512ul, 20477, 2816, 0, 0}, + {0, 16, 1, 512, 3, 614189u, 15768703443741671865ULL, 512ul, -32768, 2816, 0, 0}, + {0, 16, 1, 1000, 0, 622108u, 7370634040902866110ULL, 1000ul, -15648, 2816, 0, 0}, + {0, 16, 1, 1000, 1, 630027u, 2133928206205019992ULL, 1000ul, -28669, 2816, 0, 0}, + {0, 16, 1, 1000, 2, 637946u, 6352677713832042436ULL, 1000ul, 18935, 2816, 0, 0}, + {0, 16, 1, 1000, 3, 645865u, 5781932327977088053ULL, 1000ul, -23096, 2816, 0, 0}, + {0, 16, 1, 2048, 0, 653784u, 15076251625756695583ULL, 2048ul, -20482, 2784, 0, 0}, + {0, 16, 1, 2048, 1, 661703u, 5531132392870705495ULL, 2048ul, 32767, 2816, 0, 0}, + {0, 16, 1, 2048, 2, 669622u, 12858793891892160924ULL, 2048ul, -32768, 2816, 0, 0}, + {0, 16, 1, 2048, 3, 677541u, 8002383651492373634ULL, 2048ul, 30965, 2784, 0, 0}, + {1, 8, 1, 2, 0, 685460u, 8457806783455251515ULL, 2ul, 8, 4, 0, 0}, + {1, 8, 1, 4, 0, 693379u, 6126395978435784425ULL, 4ul, -41, 18, 0, 0}, + {1, 8, 1, 6, 0, 701298u, 17087678584412589026ULL, 6ul, -21, 15, 0, 0}, + {1, 8, 1, 8, 0, 709217u, 336745316543356026ULL, 8ul, 13, 0, 0, 0}, + {1, 8, 1, 14, 0, 717136u, 7276360942363792860ULL, 14ul, 101, 17, 0, 0}, + {1, 8, 1, 16, 0, 725055u, 2620817727586339935ULL, 16ul, 180, 28, 0, 0}, + {1, 8, 1, 18, 0, 732974u, 17830020442838479152ULL, 18ul, -16, 20, 0, 0}, + {1, 8, 1, 20, 0, 740893u, 15981588836978027159ULL, 20ul, -1, 40, 0, 0}, + {1, 8, 1, 30, 0, 748812u, 2870519093256118180ULL, 30ul, 1341, 46, 0, 0}, + {1, 8, 1, 32, 0, 756731u, 3120133209687698849ULL, 32ul, 32767, 88, 0, 0}, + {1, 8, 1, 34, 0, 764650u, 15399835199742063086ULL, 34ul, 10099, 75, 0, 0}, + {1, 8, 1, 48, 0, 772569u, 1156678309786002258ULL, 48ul, -6332, 86, 0, 0}, + {1, 8, 1, 64, 0, 780488u, 12949629040562794301ULL, 64ul, 30234, 88, 0, 0}, + {1, 8, 1, 100, 0, 788407u, 1805979449264766850ULL, 100ul, -32768, 87, 0, 0}, + {1, 8, 1, 128, 0, 796326u, 5626654143510041055ULL, 128ul, -32768, 88, 0, 0}, + {1, 8, 1, 254, 0, 804245u, 15133604307217352496ULL, 254ul, 32767, 88, 0, 0}, + {1, 8, 1, 256, 0, 812164u, 3325957635046854994ULL, 256ul, -4095, 88, 0, 0}, + {1, 8, 1, 512, 0, 820083u, 12114861683264565056ULL, 512ul, 32767, 88, 0, 0}, + {1, 8, 1, 1000, 0, 828002u, 5847497246247626793ULL, 1000ul, 32767, 88, 0, 0}, + {1, 8, 1, 2048, 0, 835921u, 3521157266034709340ULL, 2048ul, -7373, 87, 0, 0}, + {1, 8, 2, 2, 0, 843840u, 11734316019872117916ULL, 2ul, -4, 0, 0, 0}, + {1, 8, 2, 4, 0, 851759u, 10828610133427013116ULL, 4ul, 2, 0, 11, 5}, + {1, 8, 2, 6, 0, 859678u, 6934923240258354971ULL, 6ul, 7, 4, -21, 16}, + {1, 8, 2, 8, 0, 867597u, 3190393389586662870ULL, 8ul, -19, 11, -37, 11}, + {1, 8, 2, 14, 0, 875516u, 10422428658551767243ULL, 14ul, 40, 6, 3, 8}, + {1, 8, 2, 16, 0, 883435u, 15027536316257617508ULL, 16ul, -42, 15, -55, 17}, + {1, 8, 2, 18, 0, 891354u, 9782993574160807193ULL, 18ul, 45, 16, -74, 22}, + {1, 8, 2, 20, 0, 899273u, 8767844308865394856ULL, 20ul, 29, 19, 7, 3}, + {1, 8, 2, 30, 0, 907192u, 17526530167203445855ULL, 30ul, -13, 20, -347, 54}, + {1, 8, 2, 32, 0, 915111u, 14939172501825435793ULL, 32ul, -214, 44, 17, 31}, + {1, 8, 2, 34, 0, 923030u, 10190260692350967381ULL, 34ul, 134, 19, 192, 26}, + {1, 8, 2, 48, 0, 930949u, 13316181661150893650ULL, 48ul, -159, 35, 4139, 58}, + {1, 8, 2, 64, 0, 938868u, 7131332940394329912ULL, 64ul, -1643, 47, 1096, 39}, + {1, 8, 2, 100, 0, 946787u, 1795297238688675538ULL, 100ul, 32767, 88, -32768, 88}, + {1, 8, 2, 128, 0, 954706u, 3991742729995597528ULL, 128ul, 18039, 82, 14102, 83}, + {1, 8, 2, 254, 0, 962625u, 4925783379165475326ULL, 254ul, 32767, 88, 4098, 87}, + {1, 8, 2, 256, 0, 970544u, 2544282549193640795ULL, 256ul, -7244, 88, 32767, 88}, + {1, 8, 2, 512, 0, 978463u, 10466679902044322924ULL, 512ul, -32768, 88, -32768, 88}, + {1, 8, 2, 1000, 0, 986382u, 14858065648303542796ULL, 1000ul, -32768, 87, -32768, 88}, + {1, 8, 2, 2048, 0, 994301u, 12222826251282894865ULL, 2048ul, 4094, 88, 32767, 88}, + {1, 16, 1, 2, 0, 1002220u, 14756051507102498384ULL, 2ul, -10, 6, 0, 0}, + {1, 16, 1, 4, 0, 1010139u, 2453697702370540243ULL, 4ul, -23, 10, 0, 0}, + {1, 16, 1, 6, 0, 1018058u, 1147563972556738192ULL, 6ul, 8, 12, 0, 0}, + {1, 16, 1, 8, 0, 1025977u, 9008945703190859318ULL, 8ul, -30, 14, 0, 0}, + {1, 16, 1, 14, 0, 1033896u, 12747799131272319141ULL, 14ul, -10, 24, 0, 0}, + {1, 16, 1, 16, 0, 1041815u, 18236492726405716031ULL, 16ul, 310, 31, 0, 0}, + {1, 16, 1, 18, 0, 1049734u, 7274631452226086236ULL, 18ul, -80, 16, 0, 0}, + {1, 16, 1, 20, 0, 1057653u, 347087483952965207ULL, 20ul, 16, 20, 0, 0}, + {1, 16, 1, 30, 0, 1065572u, 9395317121611137970ULL, 30ul, -28, 4, 0, 0}, + {1, 16, 1, 32, 0, 1073491u, 8032276571079152817ULL, 32ul, -339, 51, 0, 0}, + {1, 16, 1, 34, 0, 1081410u, 12282895018286288542ULL, 34ul, -1152, 55, 0, 0}, + {1, 16, 1, 48, 0, 1089329u, 4373911869350240575ULL, 48ul, -43, 48, 0, 0}, + {1, 16, 1, 64, 0, 1097248u, 18075392506829567980ULL, 64ul, 353, 56, 0, 0}, + {1, 16, 1, 100, 0, 1105167u, 15561700175432311330ULL, 100ul, 12289, 87, 0, 0}, + {1, 16, 1, 128, 0, 1113086u, 12182154675260358670ULL, 128ul, 32767, 88, 0, 0}, + {1, 16, 1, 254, 0, 1121005u, 10031882507292802669ULL, 254ul, -751, 88, 0, 0}, + {1, 16, 1, 256, 0, 1128924u, 15243152442876284955ULL, 256ul, 9873, 80, 0, 0}, + {1, 16, 1, 512, 0, 1136843u, 1935936819891746919ULL, 512ul, -27191, 88, 0, 0}, + {1, 16, 1, 1000, 0, 1144762u, 3843388292666852233ULL, 1000ul, -23936, 88, 0, 0}, + {1, 16, 1, 2048, 0, 1152681u, 17032068187087902488ULL, 2048ul, 28672, 87, 0, 0}, + {1, 16, 2, 4, 0, 1160600u, 12485480762551179531ULL, 4ul, 1, 0, 1, 0}, + {1, 16, 2, 8, 0, 1168519u, 3200699482275911687ULL, 8ul, -29, 10, 41, 16}, + {1, 16, 2, 16, 0, 1176438u, 8192550340054956277ULL, 16ul, -35, 13, -42, 13}, + {1, 16, 2, 20, 0, 1184357u, 13315265890779850150ULL, 20ul, 24, 9, 79, 19}, + {1, 16, 2, 32, 0, 1192276u, 18003480170076876689ULL, 32ul, -6, 19, 36, 17}, + {1, 16, 2, 48, 0, 1200195u, 9236954837538779649ULL, 48ul, -43, 23, 42, 22}, + {1, 16, 2, 64, 0, 1208114u, 17197740730176029996ULL, 64ul, -330, 34, 7, 25}, + {1, 16, 2, 100, 0, 1216033u, 17748861698220807440ULL, 100ul, -6435, 59, 74, 13}, + {1, 16, 2, 128, 0, 1223952u, 16160103284895095124ULL, 128ul, 124, 42, 4395, 63}, + {1, 16, 2, 256, 0, 1231871u, 15127361913922791055ULL, 256ul, 32767, 85, -28673, 87}, + {1, 16, 2, 512, 0, 1239790u, 6699821538034233569ULL, 512ul, -8561, 86, 32767, 88}, + {1, 16, 2, 1000, 0, 1247709u, 11894715843638544548ULL, 1000ul, -32768, 88, -2656, 84}, + {1, 16, 2, 2048, 0, 1255628u, 6426509828928289771ULL, 2048ul, -10052, 86, -32768, 88}, + {2, 8, 1, 2, 0, 1263547u, 15184995244074288565ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 4, 0, 1271466u, 10714933761686629167ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 6, 0, 1279385u, 1149076099741300001ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 8, 0, 1287304u, 6250629193073305835ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 14, 0, 1295223u, 6178921175022514505ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 16, 0, 1303142u, 13360723517247081875ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 18, 0, 1311061u, 7517444103758849285ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 20, 0, 1318980u, 1620605505821761343ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 30, 0, 1326899u, 4886561000908439961ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 32, 0, 1334818u, 9014609365494796707ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 34, 0, 1342737u, 6772423796913715093ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 48, 0, 1350656u, 12973240445765916531ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 64, 0, 1358575u, 9753575262271803651ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 100, 0, 1366494u, 14363263618461700687ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 128, 0, 1374413u, 480751472056897347ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 254, 0, 1382332u, 3161599458952835385ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 256, 0, 1390251u, 13360375778243743939ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 512, 0, 1398170u, 8465094464321121731ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 1000, 0, 1406089u, 18230885618526639115ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 1, 2048, 0, 1414008u, 17955963017492798403ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 2, 0, 1421927u, 15184995244074288565ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 4, 0, 1429846u, 10714933761686629167ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 6, 0, 1437765u, 1149076099741300001ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 8, 0, 1445684u, 6250629193073305835ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 14, 0, 1453603u, 6178921175022514505ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 16, 0, 1461522u, 13360723517247081875ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 18, 0, 1469441u, 7517444103758849285ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 20, 0, 1477360u, 1620605505821761343ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 30, 0, 1485279u, 4886561000908439961ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 32, 0, 1493198u, 9014609365494796707ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 34, 0, 1501117u, 6772423796913715093ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 48, 0, 1509036u, 12973240445765916531ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 64, 0, 1516955u, 9753575262271803651ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 100, 0, 1524874u, 14363263618461700687ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 128, 0, 1532793u, 480751472056897347ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 254, 0, 1540712u, 3161599458952835385ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 256, 0, 1548631u, 13360375778243743939ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 512, 0, 1556550u, 8465094464321121731ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 1000, 0, 1564469u, 18230885618526639115ULL, 0ul, 0, 0, 0, 0}, + {2, 8, 2, 2048, 0, 1572388u, 17955963017492798403ULL, 0ul, 0, 0, 0, 0}, + {2, 16, 1, 2, 0, 1580307u, 13610437612761655990ULL, 0ul, -4, 0, 0, 0}, + {2, 16, 1, 4, 0, 1588226u, 1810731647628669094ULL, 0ul, 7, 128, 0, 0}, + {2, 16, 1, 6, 0, 1596145u, 6770358138352074232ULL, 0ul, 2, 448, 0, 0}, + {2, 16, 1, 8, 0, 1604064u, 12580881364436446023ULL, 0ul, 13, 288, 0, 0}, + {2, 16, 1, 14, 0, 1611983u, 11217443675920369267ULL, 0ul, 66, 288, 0, 0}, + {2, 16, 1, 16, 0, 1619902u, 4715406761644250681ULL, 0ul, -42, 224, 0, 0}, + {2, 16, 1, 18, 0, 1627821u, 15498989996244813584ULL, 0ul, 78, 736, 0, 0}, + {2, 16, 1, 20, 0, 1635740u, 2162189087590789159ULL, 0ul, -342, 1088, 0, 0}, + {2, 16, 1, 30, 0, 1643659u, 3283742485932472352ULL, 0ul, -21, 736, 0, 0}, + {2, 16, 1, 32, 0, 1651578u, 9697185004225865703ULL, 0ul, 8, 1152, 0, 0}, + {2, 16, 1, 34, 0, 1659497u, 9490636130463788437ULL, 0ul, -26, 672, 0, 0}, + {2, 16, 1, 48, 0, 1667416u, 14432387161153805128ULL, 0ul, 144, 1440, 0, 0}, + {2, 16, 1, 64, 0, 1675335u, 11980743695349239125ULL, 0ul, -918, 1664, 0, 0}, + {2, 16, 1, 100, 0, 1683254u, 7331447801406977309ULL, 0ul, 32767, 2816, 0, 0}, + {2, 16, 1, 128, 0, 1691173u, 1297283808354321843ULL, 0ul, 23772, 2816, 0, 0}, + {2, 16, 1, 254, 0, 1699092u, 17439416550492295440ULL, 0ul, -12286, 2816, 0, 0}, + {2, 16, 1, 256, 0, 1707011u, 1168575646441781828ULL, 0ul, -32768, 2816, 0, 0}, + {2, 16, 1, 512, 0, 1714930u, 1329624559029150574ULL, 0ul, -9680, 2816, 0, 0}, + {2, 16, 1, 1000, 0, 1722849u, 6284855679889550234ULL, 0ul, -23096, 2816, 0, 0}, + {2, 16, 1, 2048, 0, 1730768u, 4064289893190706ULL, 0ul, 4094, 2816, 0, 0}, + {2, 16, 2, 4, 0, 1738687u, 18425378682733712439ULL, 0ul, -10, 192, -10, 192}, + {2, 16, 2, 8, 0, 1746606u, 14598362780268279422ULL, 0ul, -2, 32, -5, 224}, + {2, 16, 2, 16, 0, 1754525u, 10506767197297975497ULL, 0ul, 5, 96, -7, 160}, + {2, 16, 2, 20, 0, 1762444u, 17855437077999936616ULL, 0ul, -8, 352, -59, 320}, + {2, 16, 2, 32, 0, 1770363u, 13127012318976177492ULL, 0ul, 15, 448, 145, 768}, + {2, 16, 2, 48, 0, 1778282u, 13263434783396403780ULL, 0ul, -300, 800, -153, 672}, + {2, 16, 2, 64, 0, 1786201u, 16835112328200048782ULL, 0ul, -24, 640, 17, 416}, + {2, 16, 2, 100, 0, 1794120u, 16769304379864097132ULL, 0ul, -307, 864, 1479, 1408}, + {2, 16, 2, 128, 0, 1802039u, 4633952329909610040ULL, 0ul, 24146, 2368, 2509, 2176}, + {2, 16, 2, 256, 0, 1809958u, 17864068044738663900ULL, 0ul, 32767, 2784, -31623, 2752}, + {2, 16, 2, 512, 0, 1817877u, 5612315858536515013ULL, 0ul, 24572, 2784, -11924, 2752}, + {2, 16, 2, 1000, 0, 1825796u, 17690577286636386809ULL, 0ul, 651, 2752, -32768, 2816}, + {2, 16, 2, 2048, 0, 1833715u, 13614952584274715092ULL, 0ul, -32768, 2816, -32768, 2720}, +}; + +static int const SosGoldenCaseCount = 230; diff --git a/tests/sosparity/sosparity.cpp b/tests/sosparity/sosparity.cpp new file mode 100644 index 00000000..ebca8891 --- /dev/null +++ b/tests/sosparity/sosparity.cpp @@ -0,0 +1,212 @@ +/******************************************************************************* + * 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 SOS ADPCM decoders in soscodec.cpp to the output the assembly they replaced +// produced. The vectors in sosgolden.h were recorded from that assembly before it was +// removed; this replays each one and compares the decoded bytes and the stream state left +// behind. Needs no game data. + +#include +#include + +#include "soscomp.h" +#include "vqalib/cmp.h" + +#include "sosgolden.h" + +namespace { + +int const SRCMAX = 8192; +int const DSTMAX = 65536; +unsigned char const GUARD = 0xA5; + +unsigned char SourceStore[SRCMAX + 16]; +unsigned char DestStore[DSTMAX]; + +unsigned int Seed = 0; + +int Failures = 0; +int Checked = 0; + + +unsigned int Next_Random(void) +{ + Seed = Seed * 1103515245u + 12345u; + return(Seed >> 8); +} + + +// Must reproduce the generator's pattern exactly or every vector misses. +void Fill_Source(unsigned int seed) +{ + Seed = seed; + for (int i = 0; i < SRCMAX + 16; i++) { + SourceStore[i] = (unsigned char)(Next_Random() & 0xFF); + } +} + + +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); +} + + +unsigned long long Dest_Hash(int bytes) +{ + return(Hash(DestStore, bytes + 64)); +} + + +void Report(SosGoldenCase const & test, char const * what, long long expected, long long got) +{ + char const * name = "sosCODEC"; + + if (test.Codec == 1) { + name = "General_sosCODEC"; + } else if (test.Codec == 2) { + name = "VQA_sosCODEC"; + } + + std::printf("FAILED %s %d bit %d channel %d bytes align %d: %s expected %lld, got %lld\n", + name, test.BitSize, test.Channels, test.Bytes, test.SourceAlign, what, expected, got); + Failures++; +} + + +void Check(SosGoldenCase const & test, char const * what, long long expected, long long got) +{ + if (expected != got) { + Report(test, what, expected, got); + } +} + + +void Run_Case(SosGoldenCase const & test) +{ + Fill_Source(test.Seed); + std::memset(DestStore, GUARD, sizeof(DestStore)); + + if (test.Codec == 2) { + _VQA_SOS_COMPRESS_INFO info; + std::memset(&info, 0, sizeof(info)); + VQA_sosCODECInitStream(&info); + + VQA_sosCODECDecompressData(SourceStore, DestStore, (unsigned short)test.BitSize, (unsigned short)test.Channels, (unsigned long)test.Bytes, &info); + + Check(test, "hash", (long long)test.Hash, (long long)Dest_Hash(test.Bytes)); + Check(test, "predicted", test.Predicted, info.dwPredicted); + Check(test, "index", test.Index, info.wIndex); + Check(test, "predicted2", test.Predicted2, info.dwPredicted2); + Check(test, "index2", test.Index2, info.wIndex2); + Checked++; + return; + } + + _SOS_COMPRESS_INFO info; + std::memset(&info, 0, sizeof(info)); + info.wBitSize = (short)test.BitSize; + info.wChannels = (short)test.Channels; + + if (test.Codec == 0) { + sosCODECInitStream(&info); + } else { + General_sosCODECInitStream(&info); + } + + info.wBitSize = (short)test.BitSize; + info.wChannels = (short)test.Channels; + info.lpSource = (char *)(SourceStore + test.SourceAlign); + info.lpDest = (char *)DestStore; + + unsigned long returned = 0; + + if (test.Codec == 0) { + returned = sosCODECDecompressData(&info, (unsigned long)test.Bytes); + } else { + returned = General_sosCODECDecompressData(&info, (unsigned long)test.Bytes); + } + + Check(test, "hash", (long long)test.Hash, (long long)Dest_Hash(test.Bytes)); + Check(test, "return", (long long)test.Returned, (long long)returned); + Check(test, "predicted", test.Predicted, info.dwPredicted); + Check(test, "index", test.Index, info.wIndex); + Check(test, "predicted2", test.Predicted2, info.dwPredicted2); + Check(test, "index2", test.Index2, info.wIndex2); + Checked++; +} + +} // namespace + + +namespace { + +// The assembly's countdown was tested only after being decremented, so these requests never +// reached zero and ran away through both buffers. They must now decode nothing and return. +void Check_Runaway_Inputs(void) +{ + int const bits[] = {8, 8, 16, 16, 8, 16}; + int const channels[] = {1, 2, 1, 2, 2, 2}; + int const bytes[] = {0, 0, 0, 0, 3, 2}; + + for (int i = 0; i < 6; i++) { + Fill_Source(999u); + std::memset(DestStore, GUARD, sizeof(DestStore)); + + _SOS_COMPRESS_INFO info; + std::memset(&info, 0, sizeof(info)); + info.wBitSize = (short)bits[i]; + info.wChannels = (short)channels[i]; + General_sosCODECInitStream(&info); + info.wBitSize = (short)bits[i]; + info.wChannels = (short)channels[i]; + info.lpSource = (char *)SourceStore; + info.lpDest = (char *)DestStore; + + General_sosCODECDecompressData(&info, (unsigned long)bytes[i]); + + bool untouched = true; + for (int b = 0; b < 256; b++) { + if (DestStore[b] != GUARD) { + untouched = false; + break; + } + } + + if (!untouched) { + std::printf("FAILED General_sosCODEC %d bit %d channel %d bytes wrote to the destination\n", + bits[i], channels[i], bytes[i]); + Failures++; + } + + Checked++; + } +} + +} // namespace + + +int main(void) +{ + for (int i = 0; i < SosGoldenCaseCount; i++) { + Run_Case(SosGoldenCases[i]); + } + + Check_Runaway_Inputs(); + + std::printf("%-52s %s\n", "SOS ADPCM decode matches the recorded assembly", Failures == 0 ? "ok" : "FAILED"); + std::printf("checked %d cases, %d mismatches\n", Checked, Failures); + + return(Failures == 0 ? 0 : 1); +} From 63c736f7abd8dacae13fe7c228a90aac459753f6 Mon Sep 17 00:00:00 2001 From: Jakub Vesely <1251980+tinix0@users.noreply.github.com> Date: Sun, 30 Aug 2026 21:13:48 +0200 Subject: [PATCH 2/4] Use fixed-width integers in the SOS ADPCM codec --- code/soscodec.cpp | 34 ++++++++++++++++++---------------- code/soscomp.h | 30 ++++++++++++++++-------------- code/vqalib/cmp.h | 8 +++++--- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/code/soscodec.cpp b/code/soscodec.cpp index 2e94ade3..8e6d6361 100644 --- a/code/soscodec.cpp +++ b/code/soscodec.cpp @@ -27,6 +27,8 @@ #include "always.h" +#include + #include "soscomp.h" #include "vqalib/cmp.h" @@ -446,8 +448,8 @@ unsigned short const _SosIndexTable[89 * 16] = { /// Holds a running sample inside the range a 16 bit sample can carry. /// /// The sample to bring back into range. -/// long; The sample, clamped. -inline long Clamp_Sample(long sample) +/// int32_t; The sample, clamped. +inline int32_t Clamp_Sample(int32_t sample) { if (sample > 32767) { return(32767); @@ -471,9 +473,9 @@ inline long Clamp_Sample(long sample) /// Distance in shorts between one sample and the next. /// Running sample, carried in and out. /// Step index times 32, carried in and out. -void Decode_Table_16(unsigned char const * source, short * dest, int samples, int deststride, long & predicted, unsigned short & index) +void Decode_Table_16(unsigned char const * source, short * dest, int samples, int deststride, int32_t & predicted, unsigned short & index) { - long sample = predicted; + int32_t sample = predicted; unsigned int slotbase = index; for (int i = 0; i < samples; i++) { @@ -503,11 +505,11 @@ void Decode_Table_16(unsigned char const * source, short * dest, int samples, in * reaches it through pointers rather than naming the structure's fields twice. */ struct SosChannel { - unsigned long * SampleIndex; + uint32_t * SampleIndex; short * CodeBuf; short * Code; - long * Predicted; - long * Difference; + int32_t * Predicted; + int32_t * Difference; short * Index; short * Step; }; @@ -540,9 +542,9 @@ void Decode_General(SosChannel const & channel, unsigned char const * source, un } int const code = *channel.Code; - long const step = (long)(unsigned short)*channel.Step; + int32_t const step = (int32_t)(unsigned short)*channel.Step; - long difference = 0; + int32_t difference = 0; if ((code & 4) != 0) { difference += step; @@ -564,7 +566,7 @@ void Decode_General(SosChannel const & channel, unsigned char const * source, un *channel.Difference = difference; - long const sample = Clamp_Sample(*channel.Predicted + difference); + int32_t const sample = Clamp_Sample(*channel.Predicted + difference); *channel.Predicted = sample; if (bits == 16) { @@ -574,7 +576,7 @@ void Decode_General(SosChannel const & channel, unsigned char const * source, un /* * An 8 bit stream carries the top half of the sample, biased to unsigned. */ - *dest = (unsigned char)((((unsigned long)sample >> 8) & 0xFF) ^ 0x80); + *dest = (unsigned char)((((uint32_t)sample >> 8) & 0xFF) ^ 0x80); } dest += deststride; @@ -648,8 +650,8 @@ void __cdecl sosCODECInitStream(_SOS_COMPRESS_INFO * info) /// /// Stream state, source and destination. /// How many bytes of samples to produce. -/// unsigned long; The byte count asked for, or zero if the shape is not handled. -unsigned long __cdecl sosCODECDecompressData(_SOS_COMPRESS_INFO * info, unsigned long bytes) +/// uint32_t; The byte count asked for, or zero if the shape is not handled. +uint32_t __cdecl sosCODECDecompressData(_SOS_COMPRESS_INFO * info, uint32_t bytes) { if (info->wBitSize != 16 || info->wChannels != 1) { return(0); @@ -690,8 +692,8 @@ void __cdecl General_sosCODECInitStream(_SOS_COMPRESS_INFO * info) /// /// Stream state, source and destination. /// How many bytes of samples to produce. -/// unsigned long; The byte count asked for. -unsigned long __cdecl General_sosCODECDecompressData(_SOS_COMPRESS_INFO * info, unsigned long bytes) +/// uint32_t; The byte count asked for. +uint32_t __cdecl General_sosCODECDecompressData(_SOS_COMPRESS_INFO * info, uint32_t bytes) { info->dwSampleIndex = 0; info->dwSampleIndex2 = 0; @@ -750,7 +752,7 @@ void __cdecl VQA_sosCODECInitStream(_VQA_SOS_COMPRESS_INFO * info) /// 1 or 2. /// How many bytes of samples to produce. /// Stream state carried between calls. -void __cdecl VQA_sosCODECDecompressData(void * src, void * dst, unsigned short bits, unsigned short channels, unsigned long bytes, _VQA_SOS_COMPRESS_INFO * info) +void __cdecl VQA_sosCODECDecompressData(void * src, void * dst, unsigned short bits, unsigned short channels, uint32_t bytes, _VQA_SOS_COMPRESS_INFO * info) { if (bits != 16) { return; diff --git a/code/soscomp.h b/code/soscomp.h index 4fc8eb0f..66169030 100644 --- a/code/soscomp.h +++ b/code/soscomp.h @@ -26,6 +26,8 @@ ****************************************************************************/ #pragma once +#include + /* compression types */ enum { _ADPCM_TYPE_1, @@ -35,19 +37,19 @@ enum { struct _SOS_COMPRESS_INFO { char *lpSource; char *lpDest; - unsigned long dwCompSize; - unsigned long dwUnCompSize; - unsigned long dwSampleIndex; - long dwPredicted; - long dwDifference; + uint32_t dwCompSize; + uint32_t dwUnCompSize; + uint32_t dwSampleIndex; + int32_t dwPredicted; + int32_t dwDifference; short wCodeBuf; short wCode; short wStep; short wIndex; - unsigned long dwSampleIndex2; //added BP for channel 2 - long dwPredicted2; //added BP for channel 2 - long dwDifference2; //added BP for channel 2 + uint32_t dwSampleIndex2; //added BP for channel 2 + int32_t dwPredicted2; //added BP for channel 2 + int32_t dwDifference2; //added BP for channel 2 short wCodeBuf2; //added BP for channel 2 short wCode2; //added BP for channel 2 short wStep2; //added BP for channel 2 @@ -58,10 +60,10 @@ struct _SOS_COMPRESS_INFO { /* compressed file type header */ struct _SOS_COMPRESS_HEADER { - unsigned long dwType; // type of compression - unsigned long dwCompressedSize; // compressed file size - unsigned long dwUnCompressedSize; // uncompressed file size - unsigned long dwSourceBitSize; // original bit size + uint32_t dwType; // type of compression + uint32_t dwCompressedSize; // compressed file size + uint32_t dwUnCompressedSize; // uncompressed file size + uint32_t dwSourceBitSize; // original bit size char szName[16]; // file type, for error checking }; @@ -69,6 +71,6 @@ struct _SOS_COMPRESS_HEADER { extern "C" { void __cdecl sosCODECInitStream(_SOS_COMPRESS_INFO *); void __cdecl General_sosCODECInitStream(_SOS_COMPRESS_INFO *); - unsigned long __cdecl sosCODECDecompressData(_SOS_COMPRESS_INFO *, unsigned long); - unsigned long __cdecl General_sosCODECDecompressData(_SOS_COMPRESS_INFO *, unsigned long); + uint32_t __cdecl sosCODECDecompressData(_SOS_COMPRESS_INFO *, uint32_t); + uint32_t __cdecl General_sosCODECDecompressData(_SOS_COMPRESS_INFO *, uint32_t); } diff --git a/code/vqalib/cmp.h b/code/vqalib/cmp.h index 69838687..b8e0cb77 100644 --- a/code/vqalib/cmp.h +++ b/code/vqalib/cmp.h @@ -16,6 +16,8 @@ #pragma once +#include + #if defined(__WATCOMC__) || defined(_MSC_VER) #pragma pack(push,1) #endif @@ -23,9 +25,9 @@ struct _VQA_SOS_COMPRESS_INFO { - long dwPredicted; + int32_t dwPredicted; short wIndex; - long dwPredicted2; + int32_t dwPredicted2; short wIndex2; }; @@ -44,7 +46,7 @@ long __cdecl AudioUnzap(void *source, void *dest, long); extern "C" { void __cdecl VQA_sosCODECInitStream(_VQA_SOS_COMPRESS_INFO *); -void __cdecl VQA_sosCODECDecompressData(void *src, void *dst, unsigned short wBitSize, unsigned short wChannels, unsigned long dwUnCompSize, _VQA_SOS_COMPRESS_INFO *sosinfo); +void __cdecl VQA_sosCODECDecompressData(void *src, void *dst, unsigned short wBitSize, unsigned short wChannels, uint32_t dwUnCompSize, _VQA_SOS_COMPRESS_INFO *sosinfo); } //#define VQA_sosCODECDecompressData sosCODECDecompressData From fee2615d09ff6f9a68988ae4dd148bdab576e23a Mon Sep 17 00:00:00 2001 From: Jakub Vesely <1251980+tinix0@users.noreply.github.com> Date: Sun, 30 Aug 2026 21:15:16 +0200 Subject: [PATCH 3/4] Move SOS ADPCM tables into their own header --- code/soscodec.cpp | 394 +-------------------------------------- code/soscodec_tables.h | 414 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 415 insertions(+), 393 deletions(-) create mode 100644 code/soscodec_tables.h diff --git a/code/soscodec.cpp b/code/soscodec.cpp index 8e6d6361..c62b76d3 100644 --- a/code/soscodec.cpp +++ b/code/soscodec.cpp @@ -30,6 +30,7 @@ #include #include "soscomp.h" +#include "soscodec_tables.h" #include "vqalib/cmp.h" /* @@ -51,399 +52,6 @@ namespace { -/* - * Step index adjustment per token, and the step size per index. These belong to the general - * decoder; the other two reach the same numbers through the difference table below. - */ -short const _SosIndexAdjust[16] = { - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8 -}; - -unsigned short const _SosStepTable[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, - 16, 17, 19, 21, 23, 25, 28, 31, - 34, 37, 41, 45, 50, 55, 60, 66, - 73, 80, 88, 97, 107, 118, 130, 143, - 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, - 724, 796, 876, 963, 1060, 1166, 1282, 1411, - 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, - 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, - 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, - 32767 -}; - -/* - * Difference to add to the running sample, and the next step index scaled by 32, both keyed - * on the step index and token together. Transcribed from the tables the assembly carried. - */ -int const _SosDiffTable[89 * 16] = { - 0, 1, 3, 4, 7, 8, 10, 11, - 0, -1, -3, -4, -7, -8, -10, -11, - 1, 3, 5, 7, 9, 11, 13, 15, - -1, -3, -5, -7, -9, -11, -13, -15, - 1, 3, 5, 7, 10, 12, 14, 16, - -1, -3, -5, -7, -10, -12, -14, -16, - 1, 3, 6, 8, 11, 13, 16, 18, - -1, -3, -6, -8, -11, -13, -16, -18, - 1, 3, 6, 8, 12, 14, 17, 19, - -1, -3, -6, -8, -12, -14, -17, -19, - 1, 4, 7, 10, 13, 16, 19, 22, - -1, -4, -7, -10, -13, -16, -19, -22, - 1, 4, 7, 10, 14, 17, 20, 23, - -1, -4, -7, -10, -14, -17, -20, -23, - 1, 4, 8, 11, 15, 18, 22, 25, - -1, -4, -8, -11, -15, -18, -22, -25, - 2, 6, 10, 14, 18, 22, 26, 30, - -2, -6, -10, -14, -18, -22, -26, -30, - 2, 6, 10, 14, 19, 23, 27, 31, - -2, -6, -10, -14, -19, -23, -27, -31, - 2, 6, 11, 15, 21, 25, 30, 34, - -2, -6, -11, -15, -21, -25, -30, -34, - 2, 7, 12, 17, 23, 28, 33, 38, - -2, -7, -12, -17, -23, -28, -33, -38, - 2, 7, 13, 18, 25, 30, 36, 41, - -2, -7, -13, -18, -25, -30, -36, -41, - 3, 9, 15, 21, 28, 34, 40, 46, - -3, -9, -15, -21, -28, -34, -40, -46, - 3, 10, 17, 24, 31, 38, 45, 52, - -3, -10, -17, -24, -31, -38, -45, -52, - 3, 10, 18, 25, 34, 41, 49, 56, - -3, -10, -18, -25, -34, -41, -49, -56, - 4, 12, 21, 29, 38, 46, 55, 63, - -4, -12, -21, -29, -38, -46, -55, -63, - 4, 13, 22, 31, 41, 50, 59, 68, - -4, -13, -22, -31, -41, -50, -59, -68, - 5, 15, 25, 35, 46, 56, 66, 76, - -5, -15, -25, -35, -46, -56, -66, -76, - 5, 16, 27, 38, 50, 61, 72, 83, - -5, -16, -27, -38, -50, -61, -72, -83, - 6, 18, 31, 43, 56, 68, 81, 93, - -6, -18, -31, -43, -56, -68, -81, -93, - 6, 19, 33, 46, 61, 74, 88, 101, - -6, -19, -33, -46, -61, -74, -88, -101, - 7, 22, 37, 52, 67, 82, 97, 112, - -7, -22, -37, -52, -67, -82, -97, -112, - 8, 24, 41, 57, 74, 90, 107, 123, - -8, -24, -41, -57, -74, -90, -107, -123, - 9, 27, 45, 63, 82, 100, 118, 136, - -9, -27, -45, -63, -82, -100, -118, -136, - 10, 30, 50, 70, 90, 110, 130, 150, - -10, -30, -50, -70, -90, -110, -130, -150, - 11, 33, 55, 77, 99, 121, 143, 165, - -11, -33, -55, -77, -99, -121, -143, -165, - 12, 36, 60, 84, 109, 133, 157, 181, - -12, -36, -60, -84, -109, -133, -157, -181, - 13, 39, 66, 92, 120, 146, 173, 199, - -13, -39, -66, -92, -120, -146, -173, -199, - 14, 43, 73, 102, 132, 161, 191, 220, - -14, -43, -73, -102, -132, -161, -191, -220, - 16, 48, 81, 113, 146, 178, 211, 243, - -16, -48, -81, -113, -146, -178, -211, -243, - 17, 52, 88, 123, 160, 195, 231, 266, - -17, -52, -88, -123, -160, -195, -231, -266, - 19, 58, 97, 136, 176, 215, 254, 293, - -19, -58, -97, -136, -176, -215, -254, -293, - 21, 64, 107, 150, 194, 237, 280, 323, - -21, -64, -107, -150, -194, -237, -280, -323, - 23, 70, 118, 165, 213, 260, 308, 355, - -23, -70, -118, -165, -213, -260, -308, -355, - 26, 78, 130, 182, 235, 287, 339, 391, - -26, -78, -130, -182, -235, -287, -339, -391, - 28, 85, 143, 200, 258, 315, 373, 430, - -28, -85, -143, -200, -258, -315, -373, -430, - 31, 94, 157, 220, 284, 347, 410, 473, - -31, -94, -157, -220, -284, -347, -410, -473, - 34, 103, 173, 242, 313, 382, 452, 521, - -34, -103, -173, -242, -313, -382, -452, -521, - 38, 114, 191, 267, 345, 421, 498, 574, - -38, -114, -191, -267, -345, -421, -498, -574, - 42, 126, 210, 294, 379, 463, 547, 631, - -42, -126, -210, -294, -379, -463, -547, -631, - 46, 138, 231, 323, 417, 509, 602, 694, - -46, -138, -231, -323, -417, -509, -602, -694, - 51, 153, 255, 357, 459, 561, 663, 765, - -51, -153, -255, -357, -459, -561, -663, -765, - 56, 168, 280, 392, 505, 617, 729, 841, - -56, -168, -280, -392, -505, -617, -729, -841, - 61, 184, 308, 431, 555, 678, 802, 925, - -61, -184, -308, -431, -555, -678, -802, -925, - 68, 204, 340, 476, 612, 748, 884, 1020, - -68, -204, -340, -476, -612, -748, -884, -1020, - 74, 223, 373, 522, 672, 821, 971, 1120, - -74, -223, -373, -522, -672, -821, -971, -1120, - 82, 246, 411, 575, 740, 904, 1069, 1233, - -82, -246, -411, -575, -740, -904, -1069, -1233, - 90, 271, 452, 633, 814, 995, 1176, 1357, - -90, -271, -452, -633, -814, -995, -1176, -1357, - 99, 298, 497, 696, 895, 1094, 1293, 1492, - -99, -298, -497, -696, -895, -1094, -1293, -1492, - 109, 328, 547, 766, 985, 1204, 1423, 1642, - -109, -328, -547, -766, -985, -1204, -1423, -1642, - 120, 360, 601, 841, 1083, 1323, 1564, 1804, - -120, -360, -601, -841, -1083, -1323, -1564, -1804, - 132, 397, 662, 927, 1192, 1457, 1722, 1987, - -132, -397, -662, -927, -1192, -1457, -1722, -1987, - 145, 436, 728, 1019, 1311, 1602, 1894, 2185, - -145, -436, -728, -1019, -1311, -1602, -1894, -2185, - 160, 480, 801, 1121, 1442, 1762, 2083, 2403, - -160, -480, -801, -1121, -1442, -1762, -2083, -2403, - 176, 528, 881, 1233, 1587, 1939, 2292, 2644, - -176, -528, -881, -1233, -1587, -1939, -2292, -2644, - 194, 582, 970, 1358, 1746, 2134, 2522, 2910, - -194, -582, -970, -1358, -1746, -2134, -2522, -2910, - 213, 639, 1066, 1492, 1920, 2346, 2773, 3199, - -213, -639, -1066, -1492, -1920, -2346, -2773, -3199, - 234, 703, 1173, 1642, 2112, 2581, 3051, 3520, - -234, -703, -1173, -1642, -2112, -2581, -3051, -3520, - 258, 774, 1291, 1807, 2324, 2840, 3357, 3873, - -258, -774, -1291, -1807, -2324, -2840, -3357, -3873, - 284, 852, 1420, 1988, 2556, 3124, 3692, 4260, - -284, -852, -1420, -1988, -2556, -3124, -3692, -4260, - 312, 936, 1561, 2185, 2811, 3435, 4060, 4684, - -312, -936, -1561, -2185, -2811, -3435, -4060, -4684, - 343, 1030, 1717, 2404, 3092, 3779, 4466, 5153, - -343, -1030, -1717, -2404, -3092, -3779, -4466, -5153, - 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670, - -378, -1134, -1890, -2646, -3402, -4158, -4914, -5670, - 415, 1246, 2078, 2909, 3742, 4573, 5405, 6236, - -415, -1246, -2078, -2909, -3742, -4573, -5405, -6236, - 457, 1372, 2287, 3202, 4117, 5032, 5947, 6862, - -457, -1372, -2287, -3202, -4117, -5032, -5947, -6862, - 503, 1509, 2516, 3522, 4529, 5535, 6542, 7548, - -503, -1509, -2516, -3522, -4529, -5535, -6542, -7548, - 553, 1660, 2767, 3874, 4981, 6088, 7195, 8302, - -553, -1660, -2767, -3874, -4981, -6088, -7195, -8302, - 608, 1825, 3043, 4260, 5479, 6696, 7914, 9131, - -608, -1825, -3043, -4260, -5479, -6696, -7914, -9131, - 669, 2008, 3348, 4687, 6027, 7366, 8706, 10045, - -669, -2008, -3348, -4687, -6027, -7366, -8706, -10045, - 736, 2209, 3683, 5156, 6630, 8103, 9577, 11050, - -736, -2209, -3683, -5156, -6630, -8103, -9577, -11050, - 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157, - -810, -2431, -4052, -5673, -7294, -8915, -10536, -12157, - 891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, - -891, -2674, -4457, -6240, -8023, -9806, -11589, -13372, - 980, 2941, 4902, 6863, 8825, 10786, 12747, 14708, - -980, -2941, -4902, -6863, -8825, -10786, -12747, -14708, - 1078, 3235, 5393, 7550, 9708, 11865, 14023, 16180, - -1078, -3235, -5393, -7550, -9708, -11865, -14023, -16180, - 1186, 3559, 5932, 8305, 10679, 13052, 15425, 17798, - -1186, -3559, -5932, -8305, -10679, -13052, -15425, -17798, - 1305, 3915, 6526, 9136, 11747, 14357, 16968, 19578, - -1305, -3915, -6526, -9136, -11747, -14357, -16968, -19578, - 1435, 4306, 7178, 10049, 12922, 15793, 18665, 21536, - -1435, -4306, -7178, -10049, -12922, -15793, -18665, -21536, - 1579, 4737, 7896, 11054, 14214, 17372, 20531, 23689, - -1579, -4737, -7896, -11054, -14214, -17372, -20531, -23689, - 1737, 5211, 8686, 12160, 15636, 19110, 22585, 26059, - -1737, -5211, -8686, -12160, -15636, -19110, -22585, -26059, - 1911, 5733, 9555, 13377, 17200, 21022, 24844, 28666, - -1911, -5733, -9555, -13377, -17200, -21022, -24844, -28666, - 2102, 6306, 10511, 14715, 18920, 23124, 27329, 31533, - -2102, -6306, -10511, -14715, -18920, -23124, -27329, -31533, - 2312, 6937, 11562, 16187, 20812, 25437, 30062, 34687, - -2312, -6937, -11562, -16187, -20812, -25437, -30062, -34687, - 2543, 7630, 12718, 17805, 22893, 27980, 33068, 38155, - -2543, -7630, -12718, -17805, -22893, -27980, -33068, -38155, - 2798, 8394, 13990, 19586, 25183, 30779, 36375, 41971, - -2798, -8394, -13990, -19586, -25183, -30779, -36375, -41971, - 3077, 9232, 15388, 21543, 27700, 33855, 40011, 46166, - -3077, -9232, -15388, -21543, -27700, -33855, -40011, -46166, - 3385, 10156, 16928, 23699, 30471, 37242, 44014, 50785, - -3385, -10156, -16928, -23699, -30471, -37242, -44014, -50785, - 3724, 11172, 18621, 26069, 33518, 40966, 48415, 55863, - -3724, -11172, -18621, -26069, -33518, -40966, -48415, -55863, - 4095, 12286, 20478, 28669, 36862, 45053, 53245, 61436, - -4095, -12286, -20478, -28669, -36862, -45053, -53245, -61436 - -}; - -unsigned short const _SosIndexTable[89 * 16] = { - 0, 0, 0, 0, 64, 128, 192, 256, - 0, 0, 0, 0, 64, 128, 192, 256, - 0, 0, 0, 0, 96, 160, 224, 288, - 0, 0, 0, 0, 96, 160, 224, 288, - 32, 32, 32, 32, 128, 192, 256, 320, - 32, 32, 32, 32, 128, 192, 256, 320, - 64, 64, 64, 64, 160, 224, 288, 352, - 64, 64, 64, 64, 160, 224, 288, 352, - 96, 96, 96, 96, 192, 256, 320, 384, - 96, 96, 96, 96, 192, 256, 320, 384, - 128, 128, 128, 128, 224, 288, 352, 416, - 128, 128, 128, 128, 224, 288, 352, 416, - 160, 160, 160, 160, 256, 320, 384, 448, - 160, 160, 160, 160, 256, 320, 384, 448, - 192, 192, 192, 192, 288, 352, 416, 480, - 192, 192, 192, 192, 288, 352, 416, 480, - 224, 224, 224, 224, 320, 384, 448, 512, - 224, 224, 224, 224, 320, 384, 448, 512, - 256, 256, 256, 256, 352, 416, 480, 544, - 256, 256, 256, 256, 352, 416, 480, 544, - 288, 288, 288, 288, 384, 448, 512, 576, - 288, 288, 288, 288, 384, 448, 512, 576, - 320, 320, 320, 320, 416, 480, 544, 608, - 320, 320, 320, 320, 416, 480, 544, 608, - 352, 352, 352, 352, 448, 512, 576, 640, - 352, 352, 352, 352, 448, 512, 576, 640, - 384, 384, 384, 384, 480, 544, 608, 672, - 384, 384, 384, 384, 480, 544, 608, 672, - 416, 416, 416, 416, 512, 576, 640, 704, - 416, 416, 416, 416, 512, 576, 640, 704, - 448, 448, 448, 448, 544, 608, 672, 736, - 448, 448, 448, 448, 544, 608, 672, 736, - 480, 480, 480, 480, 576, 640, 704, 768, - 480, 480, 480, 480, 576, 640, 704, 768, - 512, 512, 512, 512, 608, 672, 736, 800, - 512, 512, 512, 512, 608, 672, 736, 800, - 544, 544, 544, 544, 640, 704, 768, 832, - 544, 544, 544, 544, 640, 704, 768, 832, - 576, 576, 576, 576, 672, 736, 800, 864, - 576, 576, 576, 576, 672, 736, 800, 864, - 608, 608, 608, 608, 704, 768, 832, 896, - 608, 608, 608, 608, 704, 768, 832, 896, - 640, 640, 640, 640, 736, 800, 864, 928, - 640, 640, 640, 640, 736, 800, 864, 928, - 672, 672, 672, 672, 768, 832, 896, 960, - 672, 672, 672, 672, 768, 832, 896, 960, - 704, 704, 704, 704, 800, 864, 928, 992, - 704, 704, 704, 704, 800, 864, 928, 992, - 736, 736, 736, 736, 832, 896, 960, 1024, - 736, 736, 736, 736, 832, 896, 960, 1024, - 768, 768, 768, 768, 864, 928, 992, 1056, - 768, 768, 768, 768, 864, 928, 992, 1056, - 800, 800, 800, 800, 896, 960, 1024, 1088, - 800, 800, 800, 800, 896, 960, 1024, 1088, - 832, 832, 832, 832, 928, 992, 1056, 1120, - 832, 832, 832, 832, 928, 992, 1056, 1120, - 864, 864, 864, 864, 960, 1024, 1088, 1152, - 864, 864, 864, 864, 960, 1024, 1088, 1152, - 896, 896, 896, 896, 992, 1056, 1120, 1184, - 896, 896, 896, 896, 992, 1056, 1120, 1184, - 928, 928, 928, 928, 1024, 1088, 1152, 1216, - 928, 928, 928, 928, 1024, 1088, 1152, 1216, - 960, 960, 960, 960, 1056, 1120, 1184, 1248, - 960, 960, 960, 960, 1056, 1120, 1184, 1248, - 992, 992, 992, 992, 1088, 1152, 1216, 1280, - 992, 992, 992, 992, 1088, 1152, 1216, 1280, - 1024, 1024, 1024, 1024, 1120, 1184, 1248, 1312, - 1024, 1024, 1024, 1024, 1120, 1184, 1248, 1312, - 1056, 1056, 1056, 1056, 1152, 1216, 1280, 1344, - 1056, 1056, 1056, 1056, 1152, 1216, 1280, 1344, - 1088, 1088, 1088, 1088, 1184, 1248, 1312, 1376, - 1088, 1088, 1088, 1088, 1184, 1248, 1312, 1376, - 1120, 1120, 1120, 1120, 1216, 1280, 1344, 1408, - 1120, 1120, 1120, 1120, 1216, 1280, 1344, 1408, - 1152, 1152, 1152, 1152, 1248, 1312, 1376, 1440, - 1152, 1152, 1152, 1152, 1248, 1312, 1376, 1440, - 1184, 1184, 1184, 1184, 1280, 1344, 1408, 1472, - 1184, 1184, 1184, 1184, 1280, 1344, 1408, 1472, - 1216, 1216, 1216, 1216, 1312, 1376, 1440, 1504, - 1216, 1216, 1216, 1216, 1312, 1376, 1440, 1504, - 1248, 1248, 1248, 1248, 1344, 1408, 1472, 1536, - 1248, 1248, 1248, 1248, 1344, 1408, 1472, 1536, - 1280, 1280, 1280, 1280, 1376, 1440, 1504, 1568, - 1280, 1280, 1280, 1280, 1376, 1440, 1504, 1568, - 1312, 1312, 1312, 1312, 1408, 1472, 1536, 1600, - 1312, 1312, 1312, 1312, 1408, 1472, 1536, 1600, - 1344, 1344, 1344, 1344, 1440, 1504, 1568, 1632, - 1344, 1344, 1344, 1344, 1440, 1504, 1568, 1632, - 1376, 1376, 1376, 1376, 1472, 1536, 1600, 1664, - 1376, 1376, 1376, 1376, 1472, 1536, 1600, 1664, - 1408, 1408, 1408, 1408, 1504, 1568, 1632, 1696, - 1408, 1408, 1408, 1408, 1504, 1568, 1632, 1696, - 1440, 1440, 1440, 1440, 1536, 1600, 1664, 1728, - 1440, 1440, 1440, 1440, 1536, 1600, 1664, 1728, - 1472, 1472, 1472, 1472, 1568, 1632, 1696, 1760, - 1472, 1472, 1472, 1472, 1568, 1632, 1696, 1760, - 1504, 1504, 1504, 1504, 1600, 1664, 1728, 1792, - 1504, 1504, 1504, 1504, 1600, 1664, 1728, 1792, - 1536, 1536, 1536, 1536, 1632, 1696, 1760, 1824, - 1536, 1536, 1536, 1536, 1632, 1696, 1760, 1824, - 1568, 1568, 1568, 1568, 1664, 1728, 1792, 1856, - 1568, 1568, 1568, 1568, 1664, 1728, 1792, 1856, - 1600, 1600, 1600, 1600, 1696, 1760, 1824, 1888, - 1600, 1600, 1600, 1600, 1696, 1760, 1824, 1888, - 1632, 1632, 1632, 1632, 1728, 1792, 1856, 1920, - 1632, 1632, 1632, 1632, 1728, 1792, 1856, 1920, - 1664, 1664, 1664, 1664, 1760, 1824, 1888, 1952, - 1664, 1664, 1664, 1664, 1760, 1824, 1888, 1952, - 1696, 1696, 1696, 1696, 1792, 1856, 1920, 1984, - 1696, 1696, 1696, 1696, 1792, 1856, 1920, 1984, - 1728, 1728, 1728, 1728, 1824, 1888, 1952, 2016, - 1728, 1728, 1728, 1728, 1824, 1888, 1952, 2016, - 1760, 1760, 1760, 1760, 1856, 1920, 1984, 2048, - 1760, 1760, 1760, 1760, 1856, 1920, 1984, 2048, - 1792, 1792, 1792, 1792, 1888, 1952, 2016, 2080, - 1792, 1792, 1792, 1792, 1888, 1952, 2016, 2080, - 1824, 1824, 1824, 1824, 1920, 1984, 2048, 2112, - 1824, 1824, 1824, 1824, 1920, 1984, 2048, 2112, - 1856, 1856, 1856, 1856, 1952, 2016, 2080, 2144, - 1856, 1856, 1856, 1856, 1952, 2016, 2080, 2144, - 1888, 1888, 1888, 1888, 1984, 2048, 2112, 2176, - 1888, 1888, 1888, 1888, 1984, 2048, 2112, 2176, - 1920, 1920, 1920, 1920, 2016, 2080, 2144, 2208, - 1920, 1920, 1920, 1920, 2016, 2080, 2144, 2208, - 1952, 1952, 1952, 1952, 2048, 2112, 2176, 2240, - 1952, 1952, 1952, 1952, 2048, 2112, 2176, 2240, - 1984, 1984, 1984, 1984, 2080, 2144, 2208, 2272, - 1984, 1984, 1984, 1984, 2080, 2144, 2208, 2272, - 2016, 2016, 2016, 2016, 2112, 2176, 2240, 2304, - 2016, 2016, 2016, 2016, 2112, 2176, 2240, 2304, - 2048, 2048, 2048, 2048, 2144, 2208, 2272, 2336, - 2048, 2048, 2048, 2048, 2144, 2208, 2272, 2336, - 2080, 2080, 2080, 2080, 2176, 2240, 2304, 2368, - 2080, 2080, 2080, 2080, 2176, 2240, 2304, 2368, - 2112, 2112, 2112, 2112, 2208, 2272, 2336, 2400, - 2112, 2112, 2112, 2112, 2208, 2272, 2336, 2400, - 2144, 2144, 2144, 2144, 2240, 2304, 2368, 2432, - 2144, 2144, 2144, 2144, 2240, 2304, 2368, 2432, - 2176, 2176, 2176, 2176, 2272, 2336, 2400, 2464, - 2176, 2176, 2176, 2176, 2272, 2336, 2400, 2464, - 2208, 2208, 2208, 2208, 2304, 2368, 2432, 2496, - 2208, 2208, 2208, 2208, 2304, 2368, 2432, 2496, - 2240, 2240, 2240, 2240, 2336, 2400, 2464, 2528, - 2240, 2240, 2240, 2240, 2336, 2400, 2464, 2528, - 2272, 2272, 2272, 2272, 2368, 2432, 2496, 2560, - 2272, 2272, 2272, 2272, 2368, 2432, 2496, 2560, - 2304, 2304, 2304, 2304, 2400, 2464, 2528, 2592, - 2304, 2304, 2304, 2304, 2400, 2464, 2528, 2592, - 2336, 2336, 2336, 2336, 2432, 2496, 2560, 2624, - 2336, 2336, 2336, 2336, 2432, 2496, 2560, 2624, - 2368, 2368, 2368, 2368, 2464, 2528, 2592, 2656, - 2368, 2368, 2368, 2368, 2464, 2528, 2592, 2656, - 2400, 2400, 2400, 2400, 2496, 2560, 2624, 2688, - 2400, 2400, 2400, 2400, 2496, 2560, 2624, 2688, - 2432, 2432, 2432, 2432, 2528, 2592, 2656, 2720, - 2432, 2432, 2432, 2432, 2528, 2592, 2656, 2720, - 2464, 2464, 2464, 2464, 2560, 2624, 2688, 2752, - 2464, 2464, 2464, 2464, 2560, 2624, 2688, 2752, - 2496, 2496, 2496, 2496, 2592, 2656, 2720, 2784, - 2496, 2496, 2496, 2496, 2592, 2656, 2720, 2784, - 2528, 2528, 2528, 2528, 2624, 2688, 2752, 2816, - 2528, 2528, 2528, 2528, 2624, 2688, 2752, 2816, - 2560, 2560, 2560, 2560, 2656, 2720, 2784, 2816, - 2560, 2560, 2560, 2560, 2656, 2720, 2784, 2816, - 2592, 2592, 2592, 2592, 2688, 2752, 2816, 2816, - 2592, 2592, 2592, 2592, 2688, 2752, 2816, 2816, - 2624, 2624, 2624, 2624, 2720, 2784, 2816, 2816, - 2624, 2624, 2624, 2624, 2720, 2784, 2816, 2816, - 2656, 2656, 2656, 2656, 2752, 2816, 2816, 2816, - 2656, 2656, 2656, 2656, 2752, 2816, 2816, 2816, - 2688, 2688, 2688, 2688, 2784, 2816, 2816, 2816, - 2688, 2688, 2688, 2688, 2784, 2816, 2816, 2816, - 2720, 2720, 2720, 2720, 2816, 2816, 2816, 2816, - 2720, 2720, 2720, 2720, 2816, 2816, 2816, 2816, - 2752, 2752, 2752, 2752, 2816, 2816, 2816, 2816, - 2752, 2752, 2752, 2752, 2816, 2816, 2816, 2816, - 2784, 2784, 2784, 2784, 2816, 2816, 2816, 2816, - 2784, 2784, 2784, 2784, 2816, 2816, 2816, 2816 - -}; - - /// /// Holds a running sample inside the range a 16 bit sample can carry. /// diff --git a/code/soscodec_tables.h b/code/soscodec_tables.h new file mode 100644 index 00000000..fd54f19d --- /dev/null +++ b/code/soscodec_tables.h @@ -0,0 +1,414 @@ +/******************************************************************************* + * 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 + +/* + * Step index and difference tables for the SOS ADPCM decoders in soscodec.cpp. + */ + +namespace { + +/* + * Step index adjustment per token, and the step size per index. These belong to the general + * decoder; the other two reach the same numbers through the difference table below. + */ +short const _SosIndexAdjust[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 +}; + +unsigned short const _SosStepTable[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, + 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, + 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, + 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, + 32767 +}; + +/* + * Difference to add to the running sample, and the next step index scaled by 32, both keyed + * on the step index and token together. Transcribed from the tables the assembly carried. + */ +int const _SosDiffTable[89 * 16] = { + 0, 1, 3, 4, 7, 8, 10, 11, + 0, -1, -3, -4, -7, -8, -10, -11, + 1, 3, 5, 7, 9, 11, 13, 15, + -1, -3, -5, -7, -9, -11, -13, -15, + 1, 3, 5, 7, 10, 12, 14, 16, + -1, -3, -5, -7, -10, -12, -14, -16, + 1, 3, 6, 8, 11, 13, 16, 18, + -1, -3, -6, -8, -11, -13, -16, -18, + 1, 3, 6, 8, 12, 14, 17, 19, + -1, -3, -6, -8, -12, -14, -17, -19, + 1, 4, 7, 10, 13, 16, 19, 22, + -1, -4, -7, -10, -13, -16, -19, -22, + 1, 4, 7, 10, 14, 17, 20, 23, + -1, -4, -7, -10, -14, -17, -20, -23, + 1, 4, 8, 11, 15, 18, 22, 25, + -1, -4, -8, -11, -15, -18, -22, -25, + 2, 6, 10, 14, 18, 22, 26, 30, + -2, -6, -10, -14, -18, -22, -26, -30, + 2, 6, 10, 14, 19, 23, 27, 31, + -2, -6, -10, -14, -19, -23, -27, -31, + 2, 6, 11, 15, 21, 25, 30, 34, + -2, -6, -11, -15, -21, -25, -30, -34, + 2, 7, 12, 17, 23, 28, 33, 38, + -2, -7, -12, -17, -23, -28, -33, -38, + 2, 7, 13, 18, 25, 30, 36, 41, + -2, -7, -13, -18, -25, -30, -36, -41, + 3, 9, 15, 21, 28, 34, 40, 46, + -3, -9, -15, -21, -28, -34, -40, -46, + 3, 10, 17, 24, 31, 38, 45, 52, + -3, -10, -17, -24, -31, -38, -45, -52, + 3, 10, 18, 25, 34, 41, 49, 56, + -3, -10, -18, -25, -34, -41, -49, -56, + 4, 12, 21, 29, 38, 46, 55, 63, + -4, -12, -21, -29, -38, -46, -55, -63, + 4, 13, 22, 31, 41, 50, 59, 68, + -4, -13, -22, -31, -41, -50, -59, -68, + 5, 15, 25, 35, 46, 56, 66, 76, + -5, -15, -25, -35, -46, -56, -66, -76, + 5, 16, 27, 38, 50, 61, 72, 83, + -5, -16, -27, -38, -50, -61, -72, -83, + 6, 18, 31, 43, 56, 68, 81, 93, + -6, -18, -31, -43, -56, -68, -81, -93, + 6, 19, 33, 46, 61, 74, 88, 101, + -6, -19, -33, -46, -61, -74, -88, -101, + 7, 22, 37, 52, 67, 82, 97, 112, + -7, -22, -37, -52, -67, -82, -97, -112, + 8, 24, 41, 57, 74, 90, 107, 123, + -8, -24, -41, -57, -74, -90, -107, -123, + 9, 27, 45, 63, 82, 100, 118, 136, + -9, -27, -45, -63, -82, -100, -118, -136, + 10, 30, 50, 70, 90, 110, 130, 150, + -10, -30, -50, -70, -90, -110, -130, -150, + 11, 33, 55, 77, 99, 121, 143, 165, + -11, -33, -55, -77, -99, -121, -143, -165, + 12, 36, 60, 84, 109, 133, 157, 181, + -12, -36, -60, -84, -109, -133, -157, -181, + 13, 39, 66, 92, 120, 146, 173, 199, + -13, -39, -66, -92, -120, -146, -173, -199, + 14, 43, 73, 102, 132, 161, 191, 220, + -14, -43, -73, -102, -132, -161, -191, -220, + 16, 48, 81, 113, 146, 178, 211, 243, + -16, -48, -81, -113, -146, -178, -211, -243, + 17, 52, 88, 123, 160, 195, 231, 266, + -17, -52, -88, -123, -160, -195, -231, -266, + 19, 58, 97, 136, 176, 215, 254, 293, + -19, -58, -97, -136, -176, -215, -254, -293, + 21, 64, 107, 150, 194, 237, 280, 323, + -21, -64, -107, -150, -194, -237, -280, -323, + 23, 70, 118, 165, 213, 260, 308, 355, + -23, -70, -118, -165, -213, -260, -308, -355, + 26, 78, 130, 182, 235, 287, 339, 391, + -26, -78, -130, -182, -235, -287, -339, -391, + 28, 85, 143, 200, 258, 315, 373, 430, + -28, -85, -143, -200, -258, -315, -373, -430, + 31, 94, 157, 220, 284, 347, 410, 473, + -31, -94, -157, -220, -284, -347, -410, -473, + 34, 103, 173, 242, 313, 382, 452, 521, + -34, -103, -173, -242, -313, -382, -452, -521, + 38, 114, 191, 267, 345, 421, 498, 574, + -38, -114, -191, -267, -345, -421, -498, -574, + 42, 126, 210, 294, 379, 463, 547, 631, + -42, -126, -210, -294, -379, -463, -547, -631, + 46, 138, 231, 323, 417, 509, 602, 694, + -46, -138, -231, -323, -417, -509, -602, -694, + 51, 153, 255, 357, 459, 561, 663, 765, + -51, -153, -255, -357, -459, -561, -663, -765, + 56, 168, 280, 392, 505, 617, 729, 841, + -56, -168, -280, -392, -505, -617, -729, -841, + 61, 184, 308, 431, 555, 678, 802, 925, + -61, -184, -308, -431, -555, -678, -802, -925, + 68, 204, 340, 476, 612, 748, 884, 1020, + -68, -204, -340, -476, -612, -748, -884, -1020, + 74, 223, 373, 522, 672, 821, 971, 1120, + -74, -223, -373, -522, -672, -821, -971, -1120, + 82, 246, 411, 575, 740, 904, 1069, 1233, + -82, -246, -411, -575, -740, -904, -1069, -1233, + 90, 271, 452, 633, 814, 995, 1176, 1357, + -90, -271, -452, -633, -814, -995, -1176, -1357, + 99, 298, 497, 696, 895, 1094, 1293, 1492, + -99, -298, -497, -696, -895, -1094, -1293, -1492, + 109, 328, 547, 766, 985, 1204, 1423, 1642, + -109, -328, -547, -766, -985, -1204, -1423, -1642, + 120, 360, 601, 841, 1083, 1323, 1564, 1804, + -120, -360, -601, -841, -1083, -1323, -1564, -1804, + 132, 397, 662, 927, 1192, 1457, 1722, 1987, + -132, -397, -662, -927, -1192, -1457, -1722, -1987, + 145, 436, 728, 1019, 1311, 1602, 1894, 2185, + -145, -436, -728, -1019, -1311, -1602, -1894, -2185, + 160, 480, 801, 1121, 1442, 1762, 2083, 2403, + -160, -480, -801, -1121, -1442, -1762, -2083, -2403, + 176, 528, 881, 1233, 1587, 1939, 2292, 2644, + -176, -528, -881, -1233, -1587, -1939, -2292, -2644, + 194, 582, 970, 1358, 1746, 2134, 2522, 2910, + -194, -582, -970, -1358, -1746, -2134, -2522, -2910, + 213, 639, 1066, 1492, 1920, 2346, 2773, 3199, + -213, -639, -1066, -1492, -1920, -2346, -2773, -3199, + 234, 703, 1173, 1642, 2112, 2581, 3051, 3520, + -234, -703, -1173, -1642, -2112, -2581, -3051, -3520, + 258, 774, 1291, 1807, 2324, 2840, 3357, 3873, + -258, -774, -1291, -1807, -2324, -2840, -3357, -3873, + 284, 852, 1420, 1988, 2556, 3124, 3692, 4260, + -284, -852, -1420, -1988, -2556, -3124, -3692, -4260, + 312, 936, 1561, 2185, 2811, 3435, 4060, 4684, + -312, -936, -1561, -2185, -2811, -3435, -4060, -4684, + 343, 1030, 1717, 2404, 3092, 3779, 4466, 5153, + -343, -1030, -1717, -2404, -3092, -3779, -4466, -5153, + 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670, + -378, -1134, -1890, -2646, -3402, -4158, -4914, -5670, + 415, 1246, 2078, 2909, 3742, 4573, 5405, 6236, + -415, -1246, -2078, -2909, -3742, -4573, -5405, -6236, + 457, 1372, 2287, 3202, 4117, 5032, 5947, 6862, + -457, -1372, -2287, -3202, -4117, -5032, -5947, -6862, + 503, 1509, 2516, 3522, 4529, 5535, 6542, 7548, + -503, -1509, -2516, -3522, -4529, -5535, -6542, -7548, + 553, 1660, 2767, 3874, 4981, 6088, 7195, 8302, + -553, -1660, -2767, -3874, -4981, -6088, -7195, -8302, + 608, 1825, 3043, 4260, 5479, 6696, 7914, 9131, + -608, -1825, -3043, -4260, -5479, -6696, -7914, -9131, + 669, 2008, 3348, 4687, 6027, 7366, 8706, 10045, + -669, -2008, -3348, -4687, -6027, -7366, -8706, -10045, + 736, 2209, 3683, 5156, 6630, 8103, 9577, 11050, + -736, -2209, -3683, -5156, -6630, -8103, -9577, -11050, + 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157, + -810, -2431, -4052, -5673, -7294, -8915, -10536, -12157, + 891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, + -891, -2674, -4457, -6240, -8023, -9806, -11589, -13372, + 980, 2941, 4902, 6863, 8825, 10786, 12747, 14708, + -980, -2941, -4902, -6863, -8825, -10786, -12747, -14708, + 1078, 3235, 5393, 7550, 9708, 11865, 14023, 16180, + -1078, -3235, -5393, -7550, -9708, -11865, -14023, -16180, + 1186, 3559, 5932, 8305, 10679, 13052, 15425, 17798, + -1186, -3559, -5932, -8305, -10679, -13052, -15425, -17798, + 1305, 3915, 6526, 9136, 11747, 14357, 16968, 19578, + -1305, -3915, -6526, -9136, -11747, -14357, -16968, -19578, + 1435, 4306, 7178, 10049, 12922, 15793, 18665, 21536, + -1435, -4306, -7178, -10049, -12922, -15793, -18665, -21536, + 1579, 4737, 7896, 11054, 14214, 17372, 20531, 23689, + -1579, -4737, -7896, -11054, -14214, -17372, -20531, -23689, + 1737, 5211, 8686, 12160, 15636, 19110, 22585, 26059, + -1737, -5211, -8686, -12160, -15636, -19110, -22585, -26059, + 1911, 5733, 9555, 13377, 17200, 21022, 24844, 28666, + -1911, -5733, -9555, -13377, -17200, -21022, -24844, -28666, + 2102, 6306, 10511, 14715, 18920, 23124, 27329, 31533, + -2102, -6306, -10511, -14715, -18920, -23124, -27329, -31533, + 2312, 6937, 11562, 16187, 20812, 25437, 30062, 34687, + -2312, -6937, -11562, -16187, -20812, -25437, -30062, -34687, + 2543, 7630, 12718, 17805, 22893, 27980, 33068, 38155, + -2543, -7630, -12718, -17805, -22893, -27980, -33068, -38155, + 2798, 8394, 13990, 19586, 25183, 30779, 36375, 41971, + -2798, -8394, -13990, -19586, -25183, -30779, -36375, -41971, + 3077, 9232, 15388, 21543, 27700, 33855, 40011, 46166, + -3077, -9232, -15388, -21543, -27700, -33855, -40011, -46166, + 3385, 10156, 16928, 23699, 30471, 37242, 44014, 50785, + -3385, -10156, -16928, -23699, -30471, -37242, -44014, -50785, + 3724, 11172, 18621, 26069, 33518, 40966, 48415, 55863, + -3724, -11172, -18621, -26069, -33518, -40966, -48415, -55863, + 4095, 12286, 20478, 28669, 36862, 45053, 53245, 61436, + -4095, -12286, -20478, -28669, -36862, -45053, -53245, -61436 + +}; + +unsigned short const _SosIndexTable[89 * 16] = { + 0, 0, 0, 0, 64, 128, 192, 256, + 0, 0, 0, 0, 64, 128, 192, 256, + 0, 0, 0, 0, 96, 160, 224, 288, + 0, 0, 0, 0, 96, 160, 224, 288, + 32, 32, 32, 32, 128, 192, 256, 320, + 32, 32, 32, 32, 128, 192, 256, 320, + 64, 64, 64, 64, 160, 224, 288, 352, + 64, 64, 64, 64, 160, 224, 288, 352, + 96, 96, 96, 96, 192, 256, 320, 384, + 96, 96, 96, 96, 192, 256, 320, 384, + 128, 128, 128, 128, 224, 288, 352, 416, + 128, 128, 128, 128, 224, 288, 352, 416, + 160, 160, 160, 160, 256, 320, 384, 448, + 160, 160, 160, 160, 256, 320, 384, 448, + 192, 192, 192, 192, 288, 352, 416, 480, + 192, 192, 192, 192, 288, 352, 416, 480, + 224, 224, 224, 224, 320, 384, 448, 512, + 224, 224, 224, 224, 320, 384, 448, 512, + 256, 256, 256, 256, 352, 416, 480, 544, + 256, 256, 256, 256, 352, 416, 480, 544, + 288, 288, 288, 288, 384, 448, 512, 576, + 288, 288, 288, 288, 384, 448, 512, 576, + 320, 320, 320, 320, 416, 480, 544, 608, + 320, 320, 320, 320, 416, 480, 544, 608, + 352, 352, 352, 352, 448, 512, 576, 640, + 352, 352, 352, 352, 448, 512, 576, 640, + 384, 384, 384, 384, 480, 544, 608, 672, + 384, 384, 384, 384, 480, 544, 608, 672, + 416, 416, 416, 416, 512, 576, 640, 704, + 416, 416, 416, 416, 512, 576, 640, 704, + 448, 448, 448, 448, 544, 608, 672, 736, + 448, 448, 448, 448, 544, 608, 672, 736, + 480, 480, 480, 480, 576, 640, 704, 768, + 480, 480, 480, 480, 576, 640, 704, 768, + 512, 512, 512, 512, 608, 672, 736, 800, + 512, 512, 512, 512, 608, 672, 736, 800, + 544, 544, 544, 544, 640, 704, 768, 832, + 544, 544, 544, 544, 640, 704, 768, 832, + 576, 576, 576, 576, 672, 736, 800, 864, + 576, 576, 576, 576, 672, 736, 800, 864, + 608, 608, 608, 608, 704, 768, 832, 896, + 608, 608, 608, 608, 704, 768, 832, 896, + 640, 640, 640, 640, 736, 800, 864, 928, + 640, 640, 640, 640, 736, 800, 864, 928, + 672, 672, 672, 672, 768, 832, 896, 960, + 672, 672, 672, 672, 768, 832, 896, 960, + 704, 704, 704, 704, 800, 864, 928, 992, + 704, 704, 704, 704, 800, 864, 928, 992, + 736, 736, 736, 736, 832, 896, 960, 1024, + 736, 736, 736, 736, 832, 896, 960, 1024, + 768, 768, 768, 768, 864, 928, 992, 1056, + 768, 768, 768, 768, 864, 928, 992, 1056, + 800, 800, 800, 800, 896, 960, 1024, 1088, + 800, 800, 800, 800, 896, 960, 1024, 1088, + 832, 832, 832, 832, 928, 992, 1056, 1120, + 832, 832, 832, 832, 928, 992, 1056, 1120, + 864, 864, 864, 864, 960, 1024, 1088, 1152, + 864, 864, 864, 864, 960, 1024, 1088, 1152, + 896, 896, 896, 896, 992, 1056, 1120, 1184, + 896, 896, 896, 896, 992, 1056, 1120, 1184, + 928, 928, 928, 928, 1024, 1088, 1152, 1216, + 928, 928, 928, 928, 1024, 1088, 1152, 1216, + 960, 960, 960, 960, 1056, 1120, 1184, 1248, + 960, 960, 960, 960, 1056, 1120, 1184, 1248, + 992, 992, 992, 992, 1088, 1152, 1216, 1280, + 992, 992, 992, 992, 1088, 1152, 1216, 1280, + 1024, 1024, 1024, 1024, 1120, 1184, 1248, 1312, + 1024, 1024, 1024, 1024, 1120, 1184, 1248, 1312, + 1056, 1056, 1056, 1056, 1152, 1216, 1280, 1344, + 1056, 1056, 1056, 1056, 1152, 1216, 1280, 1344, + 1088, 1088, 1088, 1088, 1184, 1248, 1312, 1376, + 1088, 1088, 1088, 1088, 1184, 1248, 1312, 1376, + 1120, 1120, 1120, 1120, 1216, 1280, 1344, 1408, + 1120, 1120, 1120, 1120, 1216, 1280, 1344, 1408, + 1152, 1152, 1152, 1152, 1248, 1312, 1376, 1440, + 1152, 1152, 1152, 1152, 1248, 1312, 1376, 1440, + 1184, 1184, 1184, 1184, 1280, 1344, 1408, 1472, + 1184, 1184, 1184, 1184, 1280, 1344, 1408, 1472, + 1216, 1216, 1216, 1216, 1312, 1376, 1440, 1504, + 1216, 1216, 1216, 1216, 1312, 1376, 1440, 1504, + 1248, 1248, 1248, 1248, 1344, 1408, 1472, 1536, + 1248, 1248, 1248, 1248, 1344, 1408, 1472, 1536, + 1280, 1280, 1280, 1280, 1376, 1440, 1504, 1568, + 1280, 1280, 1280, 1280, 1376, 1440, 1504, 1568, + 1312, 1312, 1312, 1312, 1408, 1472, 1536, 1600, + 1312, 1312, 1312, 1312, 1408, 1472, 1536, 1600, + 1344, 1344, 1344, 1344, 1440, 1504, 1568, 1632, + 1344, 1344, 1344, 1344, 1440, 1504, 1568, 1632, + 1376, 1376, 1376, 1376, 1472, 1536, 1600, 1664, + 1376, 1376, 1376, 1376, 1472, 1536, 1600, 1664, + 1408, 1408, 1408, 1408, 1504, 1568, 1632, 1696, + 1408, 1408, 1408, 1408, 1504, 1568, 1632, 1696, + 1440, 1440, 1440, 1440, 1536, 1600, 1664, 1728, + 1440, 1440, 1440, 1440, 1536, 1600, 1664, 1728, + 1472, 1472, 1472, 1472, 1568, 1632, 1696, 1760, + 1472, 1472, 1472, 1472, 1568, 1632, 1696, 1760, + 1504, 1504, 1504, 1504, 1600, 1664, 1728, 1792, + 1504, 1504, 1504, 1504, 1600, 1664, 1728, 1792, + 1536, 1536, 1536, 1536, 1632, 1696, 1760, 1824, + 1536, 1536, 1536, 1536, 1632, 1696, 1760, 1824, + 1568, 1568, 1568, 1568, 1664, 1728, 1792, 1856, + 1568, 1568, 1568, 1568, 1664, 1728, 1792, 1856, + 1600, 1600, 1600, 1600, 1696, 1760, 1824, 1888, + 1600, 1600, 1600, 1600, 1696, 1760, 1824, 1888, + 1632, 1632, 1632, 1632, 1728, 1792, 1856, 1920, + 1632, 1632, 1632, 1632, 1728, 1792, 1856, 1920, + 1664, 1664, 1664, 1664, 1760, 1824, 1888, 1952, + 1664, 1664, 1664, 1664, 1760, 1824, 1888, 1952, + 1696, 1696, 1696, 1696, 1792, 1856, 1920, 1984, + 1696, 1696, 1696, 1696, 1792, 1856, 1920, 1984, + 1728, 1728, 1728, 1728, 1824, 1888, 1952, 2016, + 1728, 1728, 1728, 1728, 1824, 1888, 1952, 2016, + 1760, 1760, 1760, 1760, 1856, 1920, 1984, 2048, + 1760, 1760, 1760, 1760, 1856, 1920, 1984, 2048, + 1792, 1792, 1792, 1792, 1888, 1952, 2016, 2080, + 1792, 1792, 1792, 1792, 1888, 1952, 2016, 2080, + 1824, 1824, 1824, 1824, 1920, 1984, 2048, 2112, + 1824, 1824, 1824, 1824, 1920, 1984, 2048, 2112, + 1856, 1856, 1856, 1856, 1952, 2016, 2080, 2144, + 1856, 1856, 1856, 1856, 1952, 2016, 2080, 2144, + 1888, 1888, 1888, 1888, 1984, 2048, 2112, 2176, + 1888, 1888, 1888, 1888, 1984, 2048, 2112, 2176, + 1920, 1920, 1920, 1920, 2016, 2080, 2144, 2208, + 1920, 1920, 1920, 1920, 2016, 2080, 2144, 2208, + 1952, 1952, 1952, 1952, 2048, 2112, 2176, 2240, + 1952, 1952, 1952, 1952, 2048, 2112, 2176, 2240, + 1984, 1984, 1984, 1984, 2080, 2144, 2208, 2272, + 1984, 1984, 1984, 1984, 2080, 2144, 2208, 2272, + 2016, 2016, 2016, 2016, 2112, 2176, 2240, 2304, + 2016, 2016, 2016, 2016, 2112, 2176, 2240, 2304, + 2048, 2048, 2048, 2048, 2144, 2208, 2272, 2336, + 2048, 2048, 2048, 2048, 2144, 2208, 2272, 2336, + 2080, 2080, 2080, 2080, 2176, 2240, 2304, 2368, + 2080, 2080, 2080, 2080, 2176, 2240, 2304, 2368, + 2112, 2112, 2112, 2112, 2208, 2272, 2336, 2400, + 2112, 2112, 2112, 2112, 2208, 2272, 2336, 2400, + 2144, 2144, 2144, 2144, 2240, 2304, 2368, 2432, + 2144, 2144, 2144, 2144, 2240, 2304, 2368, 2432, + 2176, 2176, 2176, 2176, 2272, 2336, 2400, 2464, + 2176, 2176, 2176, 2176, 2272, 2336, 2400, 2464, + 2208, 2208, 2208, 2208, 2304, 2368, 2432, 2496, + 2208, 2208, 2208, 2208, 2304, 2368, 2432, 2496, + 2240, 2240, 2240, 2240, 2336, 2400, 2464, 2528, + 2240, 2240, 2240, 2240, 2336, 2400, 2464, 2528, + 2272, 2272, 2272, 2272, 2368, 2432, 2496, 2560, + 2272, 2272, 2272, 2272, 2368, 2432, 2496, 2560, + 2304, 2304, 2304, 2304, 2400, 2464, 2528, 2592, + 2304, 2304, 2304, 2304, 2400, 2464, 2528, 2592, + 2336, 2336, 2336, 2336, 2432, 2496, 2560, 2624, + 2336, 2336, 2336, 2336, 2432, 2496, 2560, 2624, + 2368, 2368, 2368, 2368, 2464, 2528, 2592, 2656, + 2368, 2368, 2368, 2368, 2464, 2528, 2592, 2656, + 2400, 2400, 2400, 2400, 2496, 2560, 2624, 2688, + 2400, 2400, 2400, 2400, 2496, 2560, 2624, 2688, + 2432, 2432, 2432, 2432, 2528, 2592, 2656, 2720, + 2432, 2432, 2432, 2432, 2528, 2592, 2656, 2720, + 2464, 2464, 2464, 2464, 2560, 2624, 2688, 2752, + 2464, 2464, 2464, 2464, 2560, 2624, 2688, 2752, + 2496, 2496, 2496, 2496, 2592, 2656, 2720, 2784, + 2496, 2496, 2496, 2496, 2592, 2656, 2720, 2784, + 2528, 2528, 2528, 2528, 2624, 2688, 2752, 2816, + 2528, 2528, 2528, 2528, 2624, 2688, 2752, 2816, + 2560, 2560, 2560, 2560, 2656, 2720, 2784, 2816, + 2560, 2560, 2560, 2560, 2656, 2720, 2784, 2816, + 2592, 2592, 2592, 2592, 2688, 2752, 2816, 2816, + 2592, 2592, 2592, 2592, 2688, 2752, 2816, 2816, + 2624, 2624, 2624, 2624, 2720, 2784, 2816, 2816, + 2624, 2624, 2624, 2624, 2720, 2784, 2816, 2816, + 2656, 2656, 2656, 2656, 2752, 2816, 2816, 2816, + 2656, 2656, 2656, 2656, 2752, 2816, 2816, 2816, + 2688, 2688, 2688, 2688, 2784, 2816, 2816, 2816, + 2688, 2688, 2688, 2688, 2784, 2816, 2816, 2816, + 2720, 2720, 2720, 2720, 2816, 2816, 2816, 2816, + 2720, 2720, 2720, 2720, 2816, 2816, 2816, 2816, + 2752, 2752, 2752, 2752, 2816, 2816, 2816, 2816, + 2752, 2752, 2752, 2752, 2816, 2816, 2816, 2816, + 2784, 2784, 2784, 2784, 2816, 2816, 2816, 2816, + 2784, 2784, 2784, 2784, 2816, 2816, 2816, 2816 + +}; + +} // namespace From f0a23bdc366eec17368f80609b77d8122a81cdca Mon Sep 17 00:00:00 2001 From: Jakub Vesely <1251980+tinix0@users.noreply.github.com> Date: Sun, 30 Aug 2026 21:19:02 +0200 Subject: [PATCH 4/4] Comment cleanup --- code/soscodec.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/code/soscodec.cpp b/code/soscodec.cpp index c62b76d3..78539738 100644 --- a/code/soscodec.cpp +++ b/code/soscodec.cpp @@ -11,20 +11,6 @@ * disclaimers apply; see LICENSE.md. ******************************************************************************/ -/**************************************************************************** -* -* File : soscodec.asm -* Date Created : 6/1/94 -* Description : ADPCM decompression for the SOS audio streams. -* -* Programmer(s) : Nick Skrepetos -* Last Modification : 10/1/94 - 11:37:9 AM -* Additional Notes : Modified by Denzil E. Long, Jr. -* -***************************************************************************** -* Copyright (c) 1994, HMI, Inc. All Rights Reserved * -****************************************************************************/ - #include "always.h" #include