ft2-clone

Fasttracker 2 clone
Log | Files | Refs | README | LICENSE

commit d8fb82193aca3a04f7d9e21a8029eae997fc3856
parent 92209522e99043d9ebb480aa117ea76574acd705
Author: Olav Sørensen <olav.sorensen@live.no>
Date:   Tue,  3 Mar 2020 15:03:33 +0100

Pushed v1.10 code

- Bugfix: Channels were internally muted when the tracker was first started.
  You'd get no sound when trying to load samples and entering them in the
  pattern data. You had to load a song for them to properly unmute...
  This has been a bug since v1.04, yikes!
- The audio mixer's resampling interpolation was upgraded from 3-tap cubic to
  4-tap cubic, without affecting the performance of the mixer.
- Fixed some bugs in the .PAT (Gravis Utrasound patch) instrument loader
- Fixed several bugs with the "Echo" toolbox (Sampler screen)
- Bugfix: The "relative tone" section of the Instr. Ed. screen would get messed
  up if loading a WAV/AIFF sample whose playback frequency is immensely large.
- Code cleanup

Diffstat:
MLICENSE | 2+-
Mrelease/LICENSES.txt | 2+-
Msrc/ft2_about.c | 89++-----------------------------------------------------------------------------
Msrc/ft2_audio.c | 26+-------------------------
Msrc/ft2_audio.h | 13+++++++------
Msrc/ft2_config.c | 96+------------------------------------------------------------------------------
Msrc/ft2_edit.c | 25+------------------------
Msrc/ft2_gui.c | 1+
Msrc/ft2_header.h | 14+++++++++-----
Msrc/ft2_inst_ed.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/ft2_main.c | 3++-
Msrc/ft2_mix.c | 66++++++++++++++++++++++++++++++++++++------------------------------
Msrc/ft2_mix_macros.h | 70+++++++++++++++++++++++++++++++---------------------------------------
Msrc/ft2_module_loader.c | 142++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/ft2_module_saver.c | 10+++++++++-
Msrc/ft2_palette.c | 100++++++++++++++-----------------------------------------------------------------
Msrc/ft2_palette.h | 1-
Msrc/ft2_pattern_draw.c | 207+------------------------------------------------------------------------------
Msrc/ft2_pattern_ed.c | 59++++++++---------------------------------------------------
Msrc/ft2_replayer.c | 238+++++++++++++++++++------------------------------------------------------------
Msrc/ft2_replayer.h | 11++++++-----
Msrc/ft2_sample_ed.c | 631+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/ft2_sample_ed.h | 2+-
Msrc/ft2_sample_ed_features.c | 178+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/ft2_sample_loader.c | 117++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/ft2_sampling.c | 33++++++++++++++++++++++-----------
Msrc/ft2_scopedraw.c | 1+
Msrc/ft2_scopes.c | 45+--------------------------------------------
Asrc/ft2_tables.c | 1121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ft2_tables.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/ft2_trim.c | 51++++++++++++++++++++++++++++++++-------------------
Msrc/helpdata/FT2.HLP | 6+++---
Msrc/helpdata/ft2_help_data.h | 1113++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/helpdata/ft2hlp_to_h.exe | 0
Mvs2019_project/ft2-clone/ft2-clone.vcxproj | 2++
Mvs2019_project/ft2-clone/ft2-clone.vcxproj.filters | 4++++
36 files changed, 2688 insertions(+), 1930 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2019, Olav Sørensen +Copyright (c) 2019-2020, Olav Sørensen All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/release/LICENSES.txt b/release/LICENSES.txt @@ -2,7 +2,7 @@ ---------------------- Source code (BSD 3-clause license) ---------------------- -------------------------------------------------------------------------------- -Copyright (c) 2016-2019, Olav Sørensen +Copyright (c) 2016-2020, Olav Sørensen All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/ft2_about.c b/src/ft2_about.c @@ -5,6 +5,7 @@ #include "ft2_pattern_ed.h" #include "ft2_gfxdata.h" #include "ft2_video.h" +#include "ft2_tables.h" // ported from original FT2 code @@ -31,10 +32,8 @@ typedef struct vector_t x, y, z; } matrix_t; -extern const uint16_t sinusTables[256 * 5]; // defined at the bottom of this file - static const uint8_t starColConv[24] = { 2,2,2,2,2,2,2,2, 2,2,2,1,1,1,3,3, 3,3,3,3,3,3,3,3 }; -static const int16_t *sin32767 = (const int16_t *)sinusTables, *cos32767 = (const int16_t *)&sinusTables[256]; +static const int16_t *sin32767 = sinusTables, *cos32767 = &sinusTables[256]; static int16_t hastighet; static int32_t lastStarScreenPos[NUM_STARS]; static uint32_t randSeed; @@ -278,87 +277,3 @@ void exitAboutScreen(void) hideAboutScreen(); showTopScreen(true); } - -const uint16_t sinusTables[256 * 5] = -{ - 0x0000,0x00C9,0x0192,0x025B,0x0324,0x03ED,0x04B6,0x057F,0x0648,0x0711,0x07D9,0x08A2,0x096A,0x0A33,0x0AFB,0x0BC3, - 0x0C8C,0x0D54,0x0E1C,0x0EE3,0x0FAB,0x1072,0x113A,0x1201,0x12C8,0x138F,0x1455,0x151C,0x15E2,0x16A8,0x176D,0x1833, - 0x18F8,0x19BD,0x1A82,0x1B47,0x1C0B,0x1CCF,0x1D93,0x1E56,0x1F19,0x1FDC,0x209F,0x2161,0x2223,0x22E5,0x23A6,0x2467, - 0x2527,0x25E8,0x26A8,0x2767,0x2826,0x28E5,0x29A3,0x2A61,0x2B1F,0x2BDC,0x2C98,0x2D55,0x2E10,0x2ECC,0x2F87,0x3041, - 0x30FB,0x31B5,0x326E,0x3326,0x33DE,0x3496,0x354D,0x3603,0x36B9,0x376F,0x3824,0x38D8,0x398C,0x3A3F,0x3AF2,0x3BA4, - 0x3C56,0x3D07,0x3DB7,0x3E67,0x3F16,0x3FC5,0x4073,0x4120,0x41CD,0x4279,0x4325,0x43D0,0x447A,0x4523,0x45CC,0x4674, - 0x471C,0x47C3,0x4869,0x490E,0x49B3,0x4A57,0x4AFA,0x4B9D,0x4C3F,0x4CE0,0x4D80,0x4E20,0x4EBF,0x4F5D,0x4FFA,0x5097, - 0x5133,0x51CE,0x5268,0x5301,0x539A,0x5432,0x54C9,0x555F,0x55F4,0x5689,0x571D,0x57AF,0x5841,0x58D3,0x5963,0x59F2, - 0x5A81,0x5B0F,0x5B9C,0x5C28,0x5CB3,0x5D3D,0x5DC6,0x5E4F,0x5ED6,0x5F5D,0x5FE2,0x6067,0x60EB,0x616E,0x61EF,0x6270, - 0x62F0,0x6370,0x63EE,0x646B,0x64E7,0x6562,0x65DC,0x6656,0x66CE,0x6745,0x67BB,0x6831,0x68A5,0x6918,0x698A,0x69FC, - 0x6A6C,0x6ADB,0x6B49,0x6BB6,0x6C22,0x6C8E,0x6CF8,0x6D60,0x6DC8,0x6E2F,0x6E95,0x6EFA,0x6F5D,0x6FC0,0x7021,0x7082, - 0x70E1,0x713F,0x719C,0x71F8,0x7253,0x72AD,0x7306,0x735E,0x73B4,0x740A,0x745E,0x74B1,0x7503,0x7554,0x75A4,0x75F2, - 0x7640,0x768C,0x76D7,0x7722,0x776A,0x77B2,0x77F9,0x783E,0x7883,0x78C6,0x7908,0x7949,0x7988,0x79C7,0x7A04,0x7A40, - 0x7A7B,0x7AB5,0x7AED,0x7B25,0x7B5B,0x7B90,0x7BC4,0x7BF7,0x7C28,0x7C58,0x7C87,0x7CB5,0x7CE2,0x7D0D,0x7D38,0x7D61, - 0x7D88,0x7DAF,0x7DD4,0x7DF9,0x7E1C,0x7E3D,0x7E5E,0x7E7D,0x7E9B,0x7EB8,0x7ED4,0x7EEE,0x7F08,0x7F20,0x7F36,0x7F4C, - 0x7F60,0x7F73,0x7F85,0x7F96,0x7FA5,0x7FB3,0x7FC0,0x7FCC,0x7FD7,0x7FE0,0x7FE8,0x7FEF,0x7FF4,0x7FF8,0x7FFC,0x7FFD, - 0x7FFE,0x7FFD,0x7FFC,0x7FF8,0x7FF4,0x7FEF,0x7FE8,0x7FE0,0x7FD7,0x7FCC,0x7FC0,0x7FB3,0x7FA5,0x7F96,0x7F85,0x7F73, - 0x7F60,0x7F4C,0x7F36,0x7F20,0x7F08,0x7EEE,0x7ED4,0x7EB8,0x7E9B,0x7E7D,0x7E5E,0x7E3D,0x7E1C,0x7DF9,0x7DD4,0x7DAF, - 0x7D88,0x7D61,0x7D38,0x7D0D,0x7CE2,0x7CB5,0x7C87,0x7C58,0x7C28,0x7BF7,0x7BC4,0x7B90,0x7B5B,0x7B25,0x7AED,0x7AB5, - 0x7A7B,0x7A40,0x7A04,0x79C7,0x7988,0x7949,0x7908,0x78C6,0x7883,0x783E,0x77F9,0x77B2,0x776A,0x7722,0x76D7,0x768C, - 0x7640,0x75F2,0x75A4,0x7554,0x7503,0x74B1,0x745E,0x740A,0x73B4,0x735E,0x7306,0x72AD,0x7253,0x71F8,0x719C,0x713F, - 0x70E1,0x7082,0x7021,0x6FC0,0x6F5D,0x6EFA,0x6E95,0x6E2F,0x6DC8,0x6D60,0x6CF8,0x6C8E,0x6C22,0x6BB6,0x6B49,0x6ADB, - 0x6A6C,0x69FC,0x698A,0x6918,0x68A5,0x6831,0x67BB,0x6745,0x66CE,0x6656,0x65DC,0x6562,0x64E7,0x646B,0x63EE,0x6370, - 0x62F0,0x6270,0x61EF,0x616E,0x60EB,0x6067,0x5FE2,0x5F5D,0x5ED6,0x5E4F,0x5DC6,0x5D3D,0x5CB3,0x5C28,0x5B9C,0x5B0F, - 0x5A81,0x59F2,0x5963,0x58D3,0x5841,0x57AF,0x571D,0x5689,0x55F4,0x555F,0x54C9,0x5432,0x539A,0x5301,0x5268,0x51CE, - 0x5133,0x5097,0x4FFA,0x4F5D,0x4EBF,0x4E20,0x4D80,0x4CE0,0x4C3F,0x4B9D,0x4AFA,0x4A57,0x49B3,0x490E,0x4869,0x47C3, - 0x471C,0x4674,0x45CC,0x4523,0x447A,0x43D0,0x4325,0x4279,0x41CD,0x4120,0x4073,0x3FC5,0x3F16,0x3E67,0x3DB7,0x3D07, - 0x3C56,0x3BA4,0x3AF2,0x3A3F,0x398C,0x38D8,0x3824,0x376F,0x36B9,0x3603,0x354D,0x3496,0x33DE,0x3326,0x326E,0x31B5, - 0x30FB,0x3041,0x2F87,0x2ECC,0x2E10,0x2D55,0x2C98,0x2BDC,0x2B1F,0x2A61,0x29A3,0x28E5,0x2826,0x2767,0x26A8,0x25E8, - 0x2527,0x2467,0x23A6,0x22E5,0x2223,0x2161,0x209F,0x1FDC,0x1F19,0x1E56,0x1D93,0x1CCF,0x1C0B,0x1B47,0x1A82,0x19BD, - 0x18F8,0x1833,0x176D,0x16A8,0x15E2,0x151C,0x1455,0x138F,0x12C8,0x1201,0x113A,0x1072,0x0FAB,0x0EE3,0x0E1C,0x0D54, - 0x0C8C,0x0BC3,0x0AFB,0x0A33,0x096A,0x08A2,0x07D9,0x0711,0x0648,0x057F,0x04B6,0x03ED,0x0324,0x025B,0x0192,0x00C9, - 0x0000,0xFF37,0xFE6E,0xFDA5,0xFCDC,0xFC13,0xFB4A,0xFA81,0xF9B8,0xF8EF,0xF827,0xF75E,0xF696,0xF5CD,0xF505,0xF43D, - 0xF374,0xF2AC,0xF1E4,0xF11D,0xF055,0xEF8E,0xEEC6,0xEDFF,0xED38,0xEC71,0xEBAB,0xEAE4,0xEA1E,0xE958,0xE893,0xE7CD, - 0xE708,0xE643,0xE57E,0xE4B9,0xE3F5,0xE331,0xE26D,0xE1AA,0xE0E7,0xE024,0xDF61,0xDE9F,0xDDDD,0xDD1B,0xDC5A,0xDB99, - 0xDAD9,0xDA18,0xD958,0xD899,0xD7DA,0xD71B,0xD65D,0xD59F,0xD4E1,0xD424,0xD368,0xD2AB,0xD1F0,0xD134,0xD079,0xCFBF, - 0xCF05,0xCE4B,0xCD92,0xCCDA,0xCC22,0xCB6A,0xCAB3,0xC9FD,0xC947,0xC891,0xC7DC,0xC728,0xC674,0xC5C1,0xC50E,0xC45C, - 0xC3AA,0xC2F9,0xC249,0xC199,0xC0EA,0xC03B,0xBF8D,0xBEE0,0xBE33,0xBD87,0xBCDB,0xBC30,0xBB86,0xBADD,0xBA34,0xB98C, - 0xB8E4,0xB83D,0xB797,0xB6F2,0xB64D,0xB5A9,0xB506,0xB463,0xB3C1,0xB320,0xB280,0xB1E0,0xB141,0xB0A3,0xB006,0xAF69, - 0xAECD,0xAE32,0xAD98,0xACFF,0xAC66,0xABCE,0xAB37,0xAAA1,0xAA0C,0xA977,0xA8E3,0xA851,0xA7BF,0xA72D,0xA69D,0xA60E, - 0xA57F,0xA4F1,0xA464,0xA3D8,0xA34D,0xA2C3,0xA23A,0xA1B1,0xA12A,0xA0A3,0xA01E,0x9F99,0x9F15,0x9E92,0x9E11,0x9D90, - 0x9D10,0x9C90,0x9C12,0x9B95,0x9B19,0x9A9E,0x9A24,0x99AA,0x9932,0x98BB,0x9845,0x97CF,0x975B,0x96E8,0x9676,0x9604, - 0x9594,0x9525,0x94B7,0x944A,0x93DE,0x9372,0x9308,0x92A0,0x9238,0x91D1,0x916B,0x9106,0x90A3,0x9040,0x8FDF,0x8F7E, - 0x8F1F,0x8EC1,0x8E64,0x8E08,0x8DAD,0x8D53,0x8CFA,0x8CA2,0x8C4C,0x8BF6,0x8BA2,0x8B4F,0x8AFD,0x8AAC,0x8A5C,0x8A0E, - 0x89C0,0x8974,0x8929,0x88DE,0x8896,0x884E,0x8807,0x87C2,0x877D,0x873A,0x86F8,0x86B7,0x8678,0x8639,0x85FC,0x85C0, - 0x8585,0x854B,0x8513,0x84DB,0x84A5,0x8470,0x843C,0x8409,0x83D8,0x83A8,0x8379,0x834B,0x831E,0x82F3,0x82C8,0x829F, - 0x8278,0x8251,0x822C,0x8207,0x81E4,0x81C3,0x81A2,0x8183,0x8165,0x8148,0x812C,0x8112,0x80F8,0x80E0,0x80CA,0x80B4, - 0x80A0,0x808D,0x807B,0x806A,0x805B,0x804D,0x8040,0x8034,0x8029,0x8020,0x8018,0x8011,0x800C,0x8008,0x8004,0x8003, - 0x8002,0x8003,0x8004,0x8008,0x800C,0x8011,0x8018,0x8020,0x8029,0x8034,0x8040,0x804D,0x805B,0x806A,0x807B,0x808D, - 0x80A0,0x80B4,0x80CA,0x80E0,0x80F8,0x8112,0x812C,0x8148,0x8165,0x8183,0x81A2,0x81C3,0x81E4,0x8207,0x822C,0x8251, - 0x8278,0x829F,0x82C8,0x82F3,0x831E,0x834B,0x8379,0x83A8,0x83D8,0x8409,0x843C,0x8470,0x84A5,0x84DB,0x8513,0x854B, - 0x8585,0x85C0,0x85FC,0x8639,0x8678,0x86B7,0x86F8,0x873A,0x877D,0x87C2,0x8807,0x884E,0x8896,0x88DE,0x8929,0x8974, - 0x89C0,0x8A0E,0x8A5C,0x8AAC,0x8AFD,0x8B4F,0x8BA2,0x8BF6,0x8C4C,0x8CA2,0x8CFA,0x8D53,0x8DAD,0x8E08,0x8E64,0x8EC1, - 0x8F1F,0x8F7E,0x8FDF,0x9040,0x90A3,0x9106,0x916B,0x91D1,0x9238,0x92A0,0x9308,0x9372,0x93DE,0x944A,0x94B7,0x9525, - 0x9594,0x9604,0x9676,0x96E8,0x975B,0x97CF,0x9845,0x98BB,0x9932,0x99AA,0x9A24,0x9A9E,0x9B19,0x9B95,0x9C12,0x9C90, - 0x9D10,0x9D90,0x9E11,0x9E92,0x9F15,0x9F99,0xA01E,0xA0A3,0xA12A,0xA1B1,0xA23A,0xA2C3,0xA34D,0xA3D8,0xA464,0xA4F1, - 0xA57F,0xA60E,0xA69D,0xA72D,0xA7BF,0xA851,0xA8E3,0xA977,0xAA0C,0xAAA1,0xAB37,0xABCE,0xAC66,0xACFF,0xAD98,0xAE32, - 0xAECD,0xAF69,0xB006,0xB0A3,0xB141,0xB1E0,0xB280,0xB320,0xB3C1,0xB463,0xB506,0xB5A9,0xB64D,0xB6F2,0xB797,0xB83D, - 0xB8E4,0xB98C,0xBA34,0xBADD,0xBB86,0xBC30,0xBCDB,0xBD87,0xBE33,0xBEE0,0xBF8D,0xC03B,0xC0EA,0xC199,0xC249,0xC2F9, - 0xC3AA,0xC45C,0xC50E,0xC5C1,0xC674,0xC728,0xC7DC,0xC891,0xC947,0xC9FD,0xCAB3,0xCB6A,0xCC22,0xCCDA,0xCD92,0xCE4B, - 0xCF05,0xCFBF,0xD079,0xD134,0xD1F0,0xD2AB,0xD368,0xD424,0xD4E1,0xD59F,0xD65D,0xD71B,0xD7DA,0xD899,0xD958,0xDA18, - 0xDAD9,0xDB99,0xDC5A,0xDD1B,0xDDDD,0xDE9F,0xDF61,0xE024,0xE0E7,0xE1AA,0xE26D,0xE331,0xE3F5,0xE4B9,0xE57E,0xE643, - 0xE708,0xE7CD,0xE893,0xE958,0xEA1E,0xEAE4,0xEBAB,0xEC71,0xED38,0xEDFF,0xEEC6,0xEF8E,0xF055,0xF11D,0xF1E4,0xF2AC, - 0xF374,0xF43D,0xF505,0xF5CD,0xF696,0xF75E,0xF827,0xF8EF,0xF9B8,0xFA81,0xFB4A,0xFC13,0xFCDC,0xFDA5,0xFE6E,0xFF37, - 0x0000,0x00C9,0x0192,0x025B,0x0324,0x03ED,0x04B6,0x057F,0x0648,0x0711,0x07D9,0x08A2,0x096A,0x0A33,0x0AFB,0x0BC3, - 0x0C8C,0x0D54,0x0E1C,0x0EE3,0x0FAB,0x1072,0x113A,0x1201,0x12C8,0x138F,0x1455,0x151C,0x15E2,0x16A8,0x176D,0x1833, - 0x18F8,0x19BD,0x1A82,0x1B47,0x1C0B,0x1CCF,0x1D93,0x1E56,0x1F19,0x1FDC,0x209F,0x2161,0x2223,0x22E5,0x23A6,0x2467, - 0x2527,0x25E8,0x26A8,0x2767,0x2826,0x28E5,0x29A3,0x2A61,0x2B1F,0x2BDC,0x2C98,0x2D55,0x2E10,0x2ECC,0x2F87,0x3041, - 0x30FB,0x31B5,0x326E,0x3326,0x33DE,0x3496,0x354D,0x3603,0x36B9,0x376F,0x3824,0x38D8,0x398C,0x3A3F,0x3AF2,0x3BA4, - 0x3C56,0x3D07,0x3DB7,0x3E67,0x3F16,0x3FC5,0x4073,0x4120,0x41CD,0x4279,0x4325,0x43D0,0x447A,0x4523,0x45CC,0x4674, - 0x471C,0x47C3,0x4869,0x490E,0x49B3,0x4A57,0x4AFA,0x4B9D,0x4C3F,0x4CE0,0x4D80,0x4E20,0x4EBF,0x4F5D,0x4FFA,0x5097, - 0x5133,0x51CE,0x5268,0x5301,0x539A,0x5432,0x54C9,0x555F,0x55F4,0x5689,0x571D,0x57AF,0x5841,0x58D3,0x5963,0x59F2, - 0x5A81,0x5B0F,0x5B9C,0x5C28,0x5CB3,0x5D3D,0x5DC6,0x5E4F,0x5ED6,0x5F5D,0x5FE2,0x6067,0x60EB,0x616E,0x61EF,0x6270, - 0x62F0,0x6370,0x63EE,0x646B,0x64E7,0x6562,0x65DC,0x6656,0x66CE,0x6745,0x67BB,0x6831,0x68A5,0x6918,0x698A,0x69FC, - 0x6A6C,0x6ADB,0x6B49,0x6BB6,0x6C22,0x6C8E,0x6CF8,0x6D60,0x6DC8,0x6E2F,0x6E95,0x6EFA,0x6F5D,0x6FC0,0x7021,0x7082, - 0x70E1,0x713F,0x719C,0x71F8,0x7253,0x72AD,0x7306,0x735E,0x73B4,0x740A,0x745E,0x74B1,0x7503,0x7554,0x75A4,0x75F2, - 0x7640,0x768C,0x76D7,0x7722,0x776A,0x77B2,0x77F9,0x783E,0x7883,0x78C6,0x7908,0x7949,0x7988,0x79C7,0x7A04,0x7A40, - 0x7A7B,0x7AB5,0x7AED,0x7B25,0x7B5B,0x7B90,0x7BC4,0x7BF7,0x7C28,0x7C58,0x7C87,0x7CB5,0x7CE2,0x7D0D,0x7D38,0x7D61, - 0x7D88,0x7DAF,0x7DD4,0x7DF9,0x7E1C,0x7E3D,0x7E5E,0x7E7D,0x7E9B,0x7EB8,0x7ED4,0x7EEE,0x7F08,0x7F20,0x7F36,0x7F4C, - 0x7F60,0x7F73,0x7F85,0x7F96,0x7FA5,0x7FB3,0x7FC0,0x7FCC,0x7FD7,0x7FE0,0x7FE8,0x7FEF,0x7FF4,0x7FF8,0x7FFC,0x7FFD -}; diff --git a/src/ft2_audio.c b/src/ft2_audio.c @@ -12,9 +12,8 @@ #include "ft2_gui.h" #include "ft2_midi.h" #include "ft2_wav_renderer.h" -#include "ft2_module_loader.h" #include "ft2_mix.h" -#include "ft2_audio.h" +#include "ft2_tables.h" #define INITIAL_DITHER_SEED 0x12345000 @@ -32,8 +31,6 @@ chSyncData_t *chSyncEntry; volatile bool pattQueueReading, pattQueueClearing, chQueueReading, chQueueClearing; -extern const uint32_t panningTab[257]; // defined at the bottom of this file - void resetOldRevFreqs(void) { oldSFrq = 0; @@ -1226,24 +1223,3 @@ void closeAudio(void) freeAudioBuffers(); } - -const uint32_t panningTab[257] = // panning table from FT2 code -{ - 0, 4096, 5793, 7094, 8192, 9159,10033,10837,11585,12288,12953,13585,14189,14768,15326,15864, - 16384,16888,17378,17854,18318,18770,19212,19644,20066,20480,20886,21283,21674,22058,22435,22806, - 23170,23530,23884,24232,24576,24915,25249,25580,25905,26227,26545,26859,27170,27477,27780,28081, - 28378,28672,28963,29251,29537,29819,30099,30377,30652,30924,31194,31462,31727,31991,32252,32511, - 32768,33023,33276,33527,33776,34024,34270,34514,34756,34996,35235,35472,35708,35942,36175,36406, - 36636,36864,37091,37316,37540,37763,37985,38205,38424,38642,38858,39073,39287,39500,39712,39923, - 40132,40341,40548,40755,40960,41164,41368,41570,41771,41972,42171,42369,42567,42763,42959,43154, - 43348,43541,43733,43925,44115,44305,44494,44682,44869,45056,45242,45427,45611,45795,45977,46160, - 46341,46522,46702,46881,47059,47237,47415,47591,47767,47942,48117,48291,48465,48637,48809,48981, - 49152,49322,49492,49661,49830,49998,50166,50332,50499,50665,50830,50995,51159,51323,51486,51649, - 51811,51972,52134,52294,52454,52614,52773,52932,53090,53248,53405,53562,53719,53874,54030,54185, - 54340,54494,54647,54801,54954,55106,55258,55410,55561,55712,55862,56012,56162,56311,56459,56608, - 56756,56903,57051,57198,57344,57490,57636,57781,57926,58071,58215,58359,58503,58646,58789,58931, - 59073,59215,59357,59498,59639,59779,59919,60059,60199,60338,60477,60615,60753,60891,61029,61166, - 61303,61440,61576,61712,61848,61984,62119,62254,62388,62523,62657,62790,62924,63057,63190,63323, - 63455,63587,63719,63850,63982,64113,64243,64374,64504,64634,64763,64893,65022,65151,65279,65408, - 65536 -}; diff --git a/src/ft2_audio.h b/src/ft2_audio.h @@ -19,6 +19,8 @@ enum #define MIN_AUDIO_FREQ 44100 #define MAX_AUDIO_FREQ 96000 +#define CUBIC_TABLE_LEN (8192+1) + struct audio_t { char *currInputDevice, *currOutputDevice, *lastWorkingAudioDeviceName; @@ -32,7 +34,6 @@ struct audio_t uint64_t tickTime64, tickTime64Frac; double dAudioLatencyMs, dSpeedValMul, dScopeFreqMul; SDL_AudioDeviceID dev; - uint32_t wantFreq, haveFreq, wantSamples, haveSamples, wantChannels, haveChannels; } audio; @@ -72,6 +73,11 @@ struct chSync chSyncData_t data[SYNC_QUEUE_LEN + 1]; } chSync; +extern pattSyncData_t *pattSyncEntry; +extern chSyncData_t *chSyncEntry; + +extern volatile bool pattQueueReading, pattQueueClearing, chQueueReading, chQueueClearing; + void resetOldRevFreqs(void); int32_t pattQueueReadSize(void); int32_t pattQueueWriteSize(void); @@ -106,8 +112,3 @@ void updateSendAudSamplesRoutine(bool lockMixer); void mix_SaveIPVolumes(void); void mix_UpdateChannelVolPanFrq(void); uint32_t mixReplayerTickToBuffer(uint8_t *stream, uint8_t bitDepth); - -extern pattSyncData_t *pattSyncEntry; -extern chSyncData_t *chSyncEntry; - -extern volatile bool pattQueueReading, pattQueueClearing, chQueueReading, chQueueClearing; diff --git a/src/ft2_config.c b/src/ft2_config.c @@ -30,9 +30,7 @@ #include "ft2_gfxdata.h" #include "ft2_palette.h" #include "ft2_pattern_draw.h" - -// defined at the bottom of this file -extern const uint8_t defConfigData[CONFIG_FILE_SIZE]; +#include "ft2_tables.h" // globals config_t config; @@ -2222,95 +2220,3 @@ void configMasterVolUp(void) { scrollBarScrollRight(SB_MASTERVOL_SCROLL, 1); } - -// default FT2 clone FT2.CFG (unencrypted) -const uint8_t defConfigData[CONFIG_FILE_SIZE] = -{ - 0x46,0x61,0x73,0x74,0x54,0x72,0x61,0x63,0x6B,0x65,0x72,0x20,0x32,0x2E,0x30,0x20,0x63,0x6F,0x6E,0x66, - 0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,0x69,0x6C,0x65,0x1A,0x01,0x01,0x80,0xBB,0x00, - 0x00,0xFF,0x00,0x00,0x01,0xDC,0x00,0x00,0x00,0x01,0x01,0x00,0x03,0x00,0xFF,0x00,0x20,0x02,0x01,0x00, - 0x05,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x01,0x01,0x04,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x24,0x2F,0x3F,0x09,0x09,0x10,0x3F,0x3F,0x3F,0x13,0x18,0x26,0x3F,0x3F,0x3F,0x27,0x27, - 0x27,0x00,0x00,0x00,0x08,0x0A,0x0F,0x20,0x29,0x3F,0x0F,0x0F,0x0F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, - 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x01,0x0A,0x10,0x0A,0xE0,0x08,0xC0,0x08,0x40,0x08,0x20,0x08, - 0xF1,0x04,0xF2,0x04,0x81,0x04,0x82,0x04,0x20,0x30,0x40,0x50,0x61,0x62,0x71,0x72,0x91,0x92,0xF8,0x03, - 0x2D,0x88,0x18,0x00,0x66,0x88,0x18,0x00,0x00,0x01,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x01,0x01,0x10,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x64,0x00,0x01,0x01, - 0x01,0x01,0x12,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x01,0x60,0x00,0x05,0x56,0x6F,0x67, - 0x75,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x02,0x16,0x05,0x4D,0x72,0x2E,0x20,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x04,0x4C,0x6F,0x6F,0x74,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x07, - 0x0A,0x4C,0x69,0x7A,0x61,0x72,0x64,0x6B,0x69,0x6E,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x06,0x03,0x41,0x6C,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x05,0x03,0x55,0x62,0x65, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x04,0x00,0x04,0x06,0x4E,0x69,0x6B,0x6C,0x61,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x05,0x4A,0x65,0x6E,0x73,0x61,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02, - 0x05,0x54,0x6F,0x62,0x62,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x01,0x08,0x4B,0x61,0x72,0x6F,0x6C,0x69,0x6E,0x61,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x02,0x00, - 0x00,0x00,0x00,0x99,0xE2,0x27,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x30, - 0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x2C,0x00,0x0E,0x00,0x08,0x00,0x18,0x00,0x16,0x00,0x20,0x00,0x08, - 0x00,0x3C,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x5A,0x00,0x00,0x00,0x64,0x00,0x00, - 0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x0A,0x00,0x28,0x00,0x1E,0x00,0x18,0x00,0x32,0x00,0x20, - 0x00,0x3C,0x00,0x20,0x00,0x46,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x5A,0x00,0x20,0x00,0x64,0x00,0x20, - 0x00,0x6E,0x00,0x20,0x00,0x78,0x00,0x20,0x00,0x82,0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x04,0x00,0x40, - 0x00,0x08,0x00,0x2C,0x00,0x0E,0x00,0x08,0x00,0x18,0x00,0x16,0x00,0x20,0x00,0x08,0x00,0x3C,0x00,0x00, - 0x00,0x46,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x5A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x6E,0x00,0x00, - 0x00,0x00,0x00,0x20,0x00,0x0A,0x00,0x28,0x00,0x1E,0x00,0x18,0x00,0x32,0x00,0x20,0x00,0x3C,0x00,0x20, - 0x00,0x46,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x5A,0x00,0x20,0x00,0x64,0x00,0x20,0x00,0x6E,0x00,0x20, - 0x00,0x78,0x00,0x20,0x00,0x82,0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x2C, - 0x00,0x0E,0x00,0x08,0x00,0x18,0x00,0x16,0x00,0x20,0x00,0x08,0x00,0x3C,0x00,0x00,0x00,0x46,0x00,0x00, - 0x00,0x50,0x00,0x00,0x00,0x5A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x20, - 0x00,0x0A,0x00,0x28,0x00,0x1E,0x00,0x18,0x00,0x32,0x00,0x20,0x00,0x3C,0x00,0x20,0x00,0x46,0x00,0x20, - 0x00,0x50,0x00,0x20,0x00,0x5A,0x00,0x20,0x00,0x64,0x00,0x20,0x00,0x6E,0x00,0x20,0x00,0x78,0x00,0x20, - 0x00,0x82,0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x2C,0x00,0x0E,0x00,0x08, - 0x00,0x18,0x00,0x16,0x00,0x20,0x00,0x08,0x00,0x3C,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x50,0x00,0x00, - 0x00,0x5A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x0A,0x00,0x28, - 0x00,0x1E,0x00,0x18,0x00,0x32,0x00,0x20,0x00,0x3C,0x00,0x20,0x00,0x46,0x00,0x20,0x00,0x50,0x00,0x20, - 0x00,0x5A,0x00,0x20,0x00,0x64,0x00,0x20,0x00,0x6E,0x00,0x20,0x00,0x78,0x00,0x20,0x00,0x82,0x00,0x20, - 0x00,0x00,0x00,0x30,0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x2C,0x00,0x0E,0x00,0x08,0x00,0x18,0x00,0x16, - 0x00,0x20,0x00,0x08,0x00,0x3C,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x5A,0x00,0x00, - 0x00,0x64,0x00,0x00,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x0A,0x00,0x28,0x00,0x1E,0x00,0x18, - 0x00,0x32,0x00,0x20,0x00,0x3C,0x00,0x20,0x00,0x46,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x5A,0x00,0x20, - 0x00,0x64,0x00,0x20,0x00,0x6E,0x00,0x20,0x00,0x78,0x00,0x20,0x00,0x82,0x00,0x20,0x00,0x00,0x00,0x30, - 0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x2C,0x00,0x0E,0x00,0x08,0x00,0x18,0x00,0x16,0x00,0x20,0x00,0x08, - 0x00,0x3C,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x5A,0x00,0x00,0x00,0x64,0x00,0x00, - 0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x0A,0x00,0x28,0x00,0x1E,0x00,0x18,0x00,0x32,0x00,0x20, - 0x00,0x3C,0x00,0x20,0x00,0x46,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x5A,0x00,0x20,0x00,0x64,0x00,0x20, - 0x00,0x6E,0x00,0x20,0x00,0x78,0x00,0x20,0x00,0x82,0x00,0x20,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06, - 0x00,0x06,0x00,0x06,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03, - 0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05, - 0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02, - 0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x05,0x00,0x05, - 0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC8,0x00,0x03,0x00,0x40,0x1F,0x40, - 0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40, - 0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x01,0x00,0x00,0x08,0x00,0x00,0x00 -}; diff --git a/src/ft2_edit.c b/src/ft2_edit.c @@ -13,6 +13,7 @@ #include "ft2_pattern_ed.h" #include "ft2_sysreqs.h" #include "ft2_textboxes.h" +#include "ft2_tables.h" enum { @@ -39,30 +40,6 @@ static tonTyp trackCopyBuff[MAX_PATT_LEN]; static const int8_t tickArr[16] = { 16, 8, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1 }; -static const SDL_Keycode key2VolTab[] = -{ - SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_MINUS, SDLK_PLUS, SDLK_d, - SDLK_u, SDLK_s, SDLK_v, SDLK_p, SDLK_l, SDLK_r, SDLK_m -}; -#define KEY2VOL_ENTRIES (signed)(sizeof (key2VolTab) / sizeof (SDL_Keycode)) - -static const SDL_Keycode key2EfxTab[] = -{ - SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, - SDLK_8, SDLK_9, SDLK_a, SDLK_b, SDLK_c, SDLK_d, SDLK_e, SDLK_f, - SDLK_g, SDLK_h, SDLK_i, SDLK_j, SDLK_k, SDLK_l, SDLK_m, SDLK_n, - SDLK_o, SDLK_p, SDLK_q, SDLK_r, SDLK_s, SDLK_t, SDLK_u, SDLK_v, - SDLK_w, SDLK_x, SDLK_y, SDLK_z -}; -#define KEY2EFX_ENTRIES (signed)(sizeof (key2EfxTab) / sizeof (SDL_Keycode)) - -static const SDL_Keycode key2HexTab[] = -{ - SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, - SDLK_8, SDLK_9, SDLK_a, SDLK_b, SDLK_c, SDLK_d, SDLK_e, SDLK_f -}; -#define KEY2HEX_ENTRIES (signed)(sizeof (key2HexTab) / sizeof (SDL_Keycode)) - void recordNote(uint8_t note, int8_t vol); // when the cursor is at the note slot diff --git a/src/ft2_gui.c b/src/ft2_gui.c @@ -21,6 +21,7 @@ #include "ft2_wav_renderer.h" #include "ft2_trim.h" #include "ft2_video.h" +#include "ft2_tables.h" static void releaseMouseStates(void) { diff --git a/src/ft2_header.h b/src/ft2_header.h @@ -12,16 +12,18 @@ #endif #include "ft2_replayer.h" -#define PROG_VER_STR "1.09" +#define PROG_VER_STR "1.10" // do NOT change these! It will only mess things up... /* "60Hz" ranges everywhere from 59..61Hz depending on the monitor, so with -** no vsync we will get stuttering because the rate is not perfect... */ +** no vsync we will get stuttering because the rate is not perfect... +*/ #define VBLANK_HZ 60 /* Scopes are clocked at 64Hz instead of 60Hz to prevent possible stutters -** from monitors not being exactly 60Hz (and unstable non-vsync mode). */ +** from monitors not being exactly 60Hz (and unstable non-vsync mode). +*/ #define SCOPE_HZ 64 #define FT2_VBLANK_HZ 70 @@ -31,8 +33,10 @@ /* Amount of extra bytes to allocate for every instrument sample, ** this is used for a hack for resampling interpolation to be ** branchless in the inner channel mixer loop. -** Warning: Do not change this! */ -#define LOOP_FIX_LEN 4 +** Warning: Do not change this! +*/ +#define LOOP_FIX_LEN 8 +#define SMP_DAT_OFFSET 4 #ifndef _WIN32 #define _stricmp strcasecmp diff --git a/src/ft2_inst_ed.c b/src/ft2_inst_ed.c @@ -108,7 +108,7 @@ static int32_t lastMouseX, lastMouseY, saveMouseX, saveMouseY; static uint16_t saveInstrNr; static SDL_Thread *thread; -extern int16_t *note2Period; // ft2_replayer.c +extern const int16_t *note2Period; // ft2_replayer.c void updateInstEditor(void); void updateNewInstrument(void); @@ -126,7 +126,7 @@ static int32_t SDLCALL copyInstrThread(void *ptr) bool error; int8_t *p; int16_t destIns, sourceIns; - + sampleTyp *src, *dst; (void)ptr; error = false; @@ -143,16 +143,24 @@ static int32_t SDLCALL copyInstrThread(void *ptr) if (allocateInstr(destIns)) { memcpy(instr[destIns], instr[sourceIns], sizeof (instrTyp)); + for (int16_t i = 0; i < MAX_SMP_PER_INST; i++) { - instr[destIns]->samp[i].pek = NULL; - if (instr[sourceIns]->samp[i].pek != NULL) + src = &instr[sourceIns]->samp[i]; + dst = &instr[destIns]->samp[i]; + + dst->origPek = NULL; + dst->pek = NULL; + + if (src->origPek != NULL) { - p = (int8_t *)malloc(instr[sourceIns]->samp[i].len + LOOP_FIX_LEN); + p = (int8_t *)malloc(src->len + LOOP_FIX_LEN); if (p != NULL) { - memcpy(p, instr[sourceIns]->samp[i].pek, instr[sourceIns]->samp[i].len + LOOP_FIX_LEN); - instr[destIns]->samp[i].pek = p; + dst->origPek = p; + dst->pek = dst->origPek + SMP_DAT_OFFSET; + + memcpy(dst->origPek, src->origPek, src->len + LOOP_FIX_LEN); } else error = true; } @@ -3085,7 +3093,10 @@ void saveInstr(UNICHAR *filenameU, int16_t nr) static int16_t getPATNote(int32_t freq) { - return (int16_t)round(((log(freq / (440.0 * 1000.0)) / M_LN2) * 12.0) + 48.0 + 9.0); + double dNote = (log2(freq * (1.0 / 440000.0)) * 12.0) + 57.0; + int32_t note = (int32_t)(dNote + 0.5); + + return (int16_t)note; } static int32_t SDLCALL loadInstrThread(void *ptr) @@ -3280,8 +3291,9 @@ static int32_t SDLCALL loadInstrThread(void *ptr) if (s->len > 0) { - s->pek = (int8_t *)malloc(s->len + LOOP_FIX_LEN); - if (s->pek == NULL) + s->pek = NULL; + s->origPek = (int8_t *)malloc(s->len + LOOP_FIX_LEN); + if (s->origPek == NULL) { freeInstr(editor.curInstr); resumeAudio(); @@ -3289,6 +3301,8 @@ static int32_t SDLCALL loadInstrThread(void *ptr) goto loadDone; } + s->pek = s->origPek + SMP_DAT_OFFSET; + if (fread(s->pek, s->len, 1, f) != 1) { freeInstr(editor.curInstr); @@ -3308,9 +3322,12 @@ static int32_t SDLCALL loadInstrThread(void *ptr) s->repL /= 2; s->repS /= 2; - newPtr = (int8_t *)realloc(s->pek, s->len + LOOP_FIX_LEN); + newPtr = (int8_t *)realloc(s->origPek, s->len + LOOP_FIX_LEN); if (newPtr != NULL) - s->pek = newPtr; + { + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; + } stereoWarning = true; } @@ -3331,7 +3348,10 @@ static int32_t SDLCALL loadInstrThread(void *ptr) { // PAT - Gravis Ultrasound GF1 patch - if (ih_PAT.layers > 1 || ih_PAT.antSamp > 16 || ih_PAT.antSamp == 0) + if (ih_PAT.antSamp == 0) + ih_PAT.antSamp = 1; // to some patch makers, 0 means 1 + + if (ih_PAT.layers > 1 || ih_PAT.antSamp > MAX_SMP_PER_INST) { okBoxThreadSafe(0, "System message", "Incompatible instrument!"); goto loadDone; @@ -3362,8 +3382,9 @@ static int32_t SDLCALL loadInstrThread(void *ptr) goto loadDone; } - s->pek = (int8_t *)malloc(ih_PATWave.waveSize + LOOP_FIX_LEN); - if (s->pek == NULL) + s->pek = NULL; + s->origPek = (int8_t *)malloc(ih_PATWave.waveSize + LOOP_FIX_LEN); + if (s->origPek == NULL) { freeInstr(editor.curInstr); resumeAudio(); @@ -3371,15 +3392,17 @@ static int32_t SDLCALL loadInstrThread(void *ptr) goto loadDone; } + s->pek = s->origPek + SMP_DAT_OFFSET; + if (i == 0) { ins->vibSweep = ih_PATWave.vibSweep; - ins->vibRate = ih_PATWave.vibRate / 2; + ins->vibRate = (ih_PATWave.vibRate + 2) / 4; if (ins->vibRate > 0x3F) ins->vibRate = 0x3F; - ins->vibDepth = ih_PATWave.vibDepth / 2; + ins->vibDepth = (ih_PATWave.vibDepth + 1) / 2; if (ins->vibDepth > 0x0F) ins->vibDepth = 0x0F; } @@ -3397,38 +3420,41 @@ static int32_t SDLCALL loadInstrThread(void *ptr) s->typ |= 1; // forward loop } - s->pan = ih_PATWave.pan << 4; + s->pan = ((ih_PATWave.pan << 4) & 0xF0) | (ih_PATWave.pan & 0xF); + + if (s->typ & 16) + { + ih_PATWave.waveSize &= 0xFFFFFFFE; + ih_PATWave.repS &= 0xFFFFFFFE; + ih_PATWave.repE &= 0xFFFFFFFE; + } + s->len = ih_PATWave.waveSize; + if (s->len > MAX_SAMPLE_LEN) + s->len = MAX_SAMPLE_LEN; s->repS = ih_PATWave.repS; if (s->repS > s->len) s->repS = 0; s->repL = ih_PATWave.repE - ih_PATWave.repS; - - if (s->typ & 16) - { - s->len &= 0xFFFFFFFE; - s->repS &= 0xFFFFFFFE; - s->repL &= 0xFFFFFFFE; - } - if (s->repL < 0) s->repL = 0; if (s->repS+s->repL > s->len) s->repL = s->len - s->repS; - dFreq = round((1.0 + ih_PATWave.fineTune / 512.0) * ih_PATWave.sampleRate); - tuneSample(s, (int32_t)dFreq); + dFreq = (1.0 + (ih_PATWave.fineTune / 512.0)) * ih_PATWave.sampleRate; + int32_t freq = (int32_t)(dFreq + 0.5); + tuneSample(s, freq); - s->relTon -= (int8_t)(getPATNote(ih_PATWave.rootFrq) - (12*3)); - s->relTon = CLAMP(s->relTon, -48, 71); + a = s->relTon - (getPATNote(ih_PATWave.rootFrq) - (12 * 3)); + s->relTon = (uint8_t)CLAMP(a, -48, 71); a = getPATNote(ih_PATWave.lowFrq); - a = CLAMP(a, 0, 95); - b = getPATNote(ih_PATWave.highFreq); + + a = CLAMP(a, 0, 95); b = CLAMP(b, 0, 95); for (j = a; j <= b; j++) diff --git a/src/ft2_main.c b/src/ft2_main.c @@ -218,8 +218,9 @@ int main(int argc, char *argv[]) SDL_DetachThread(initMidiThread); // don't wait for this thread, let it clean up when done #endif - setupWaitVBL(); + setupWaitVBL(); // this is needed for potential okBox() calls in handleModuleLoadFromArg() handleModuleLoadFromArg(argc, argv); + setupWaitVBL(); // yes, this is needed again for main loop editor.mainLoopOngoing = true; while (editor.programRunning) diff --git a/src/ft2_mix.c b/src/ft2_mix.c @@ -1,27 +1,33 @@ #include <stdint.h> #include <stdbool.h> -#include "ft2_header.h" #include "ft2_mix.h" #include "ft2_mix_macros.h" +#include "ft2_tables.h" /* - --------------------- fixed-point audio channel mixer --------------------- - - This file has separate routines for EVERY possible sampling variation: - Interpolation, volume ramping, 8-bit, 16-bit, no loop, loop, bidi loop. - 24 mixing routines in total. - - Every voice has a function pointer set to the according mixing routine on - sample trigger (from replayer, but set in audio thread), using a function - pointer look-up table. - All voices are always cleared (thread safe) when changing any of the above - states from the GUI, so no problem there with deprecated cached function - pointers. - - Mixing macros can be found in ft2_mix_macros.h. - - Yes, this is a HUGE mess, and I hope you don't need to modify it. - If it's not broken, don't try to fix it! +** --------------------- 32-bit fixed-point audio channel mixer --------------------- +** (Note: Mixing macros can be found in ft2_mix_macros.h) +** +** 8bitbubsy: This is mostly ported from the i386-asm 32-bit mixer that was introduced in +** FT2.08 (MS-DOS). It has been changed and improved quite a bit, though... +** +** This file has separate routines for EVERY possible sampling variation: +** Interpolation on/off, volume ramping on/off, 8-bit, 16-bit, no loop, loop, pingpong. +** (24 mixing routines in total) +** +** Every voice has a function pointer set to the according mixing routine on sample +** trigger (from replayer, but set in audio thread), using a function pointer look-up +** table. All voices & pointers are always thread-safely cleared when changing any +** of the above attributes from the GUI, to prevent possible thread-related issues. +** +** There's one problem with the 4-tap cubic spline resampling interpolation... +** On looped samples where loopStart>0, the splines are not correct when reading +** from the loopStart (or +1?) sample point. The difference in audio is very minor, +** so it's not a big problem. It just has to stay like this the way the mixer works. +** In cases where loopStart=0, the sample before index 0 (yes, we allocate enough +** data and pre-increment main pointer to support negative look-up), is already +** pre-fixed so that the splines will be correct. +** ---------------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */ @@ -239,7 +245,7 @@ static void mix8bNoLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos, delta; uint32_t i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif GET_VOL @@ -309,7 +315,7 @@ static void mix8bLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos, delta; uint32_t i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif GET_VOL @@ -379,7 +385,7 @@ static void mix8bBidiLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos; uint32_t delta, i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif GET_VOL @@ -673,7 +679,7 @@ static void mix8bRampNoLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos, delta; uint32_t i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0) @@ -750,7 +756,7 @@ static void mix8bRampLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos, delta; uint32_t i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0) @@ -827,7 +833,7 @@ static void mix8bRampBidiLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos; uint32_t delta, i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0) @@ -1112,7 +1118,7 @@ static void mix16bNoLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos, delta; uint32_t i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif GET_VOL @@ -1182,7 +1188,7 @@ static void mix16bLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos, delta; uint32_t i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif GET_VOL @@ -1252,7 +1258,7 @@ static void mix16bBidiLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos; uint32_t delta, i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif GET_VOL @@ -1546,7 +1552,7 @@ static void mix16bRampNoLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos, delta; uint32_t i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0) @@ -1623,7 +1629,7 @@ static void mix16bRampLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos, delta; uint32_t i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0) @@ -1700,7 +1706,7 @@ static void mix16bRampBidiLoopIntrp(voice_t *v, uint32_t numSamples) register uint32_t pos; uint32_t delta, i, samplesToMix; #ifndef LERPMIX - int32_t sample3; + int32_t sample3, sample4; #endif if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0) diff --git a/src/ft2_mix_macros.h b/src/ft2_mix_macros.h @@ -101,50 +101,40 @@ #ifndef LERPMIX -// 3-tap quadratic interpolation (default - slower, but better quality) +// 4-tap cubic spline interpolation (default - slower than linear, but better quality) -// in: int32_t s1,s2,s3 = -128..127 | f = 0..65535 (frac) | out: s1 (will exceed 16-bits because of overshoot) -#define INTERPOLATE8(s1, s2, s3, f) \ +// in: int32_t s0,s1,s2,s3 = -128..127 | f = 0..65535 (frac) | out: 16-bit s0 (will exceed 16-bits because of overshoot) +#define INTERPOLATE8(s0, s1, s2, s3, f) \ { \ - int32_t s4, frac = f >> 1; \ - \ - s2 <<= 8; \ - s4 = ((s1 + s3) << (8 - 1)) - s2; \ - s4 = ((s4 * frac) >> 16) + s2; \ - s3 = (s1 + s3) << (8 - 1); \ - s1 <<= 8; \ - s3 = (s1 + s3) >> 1; \ - s1 += ((s4 - s3) * frac) >> 14; \ + const int16_t *t = fastSincTable + ((f >> 6) & 0x3FC); \ + s0 = ((s0 * t[0]) + (s1 * t[1]) + (s2 * t[2]) + (s3 * t[3])) >> (FAST_SINC_TABLE_BITS - 8); \ } \ -// in: int32_t s1,s2,s3 = -32768..32767 | f = 0..65535 (frac) | out: s1 (will exceed 16-bits because of overshoot) -#define INTERPOLATE16(s1, s2, s3, f) \ +// in: int32_t s0,s1,s2,s3 = -32768..32767 | f = 0..65535 (frac) | out: 16-bit s0 (will exceed 16-bits because of overshoot) +#define INTERPOLATE16(s0, s1, s2, s3, f) \ { \ - int32_t s4, frac = f >> 1; \ - \ - s4 = ((s1 + s3) >> 1) - s2; \ - s4 = ((s4 * frac) >> 16) + s2; \ - s3 = (s1 + s3) >> 1; \ - s3 = (s1 + s3) >> 1; \ - s1 += ((s4 - s3) * frac) >> 14; \ + const int16_t *t = fastSincTable + ((f >> 6) & 0x3FC); \ + s0 = ((s0 * t[0]) + (s1 * t[1]) + (s2 * t[2]) + (s3 * t[3])) >> FAST_SINC_TABLE_BITS; \ } \ #define RENDER_8BIT_SMP_INTRP \ assert(smpPtr >= CDA_LinearAdr && smpPtr < CDA_LinearAdr+v->SLen); \ - sample = smpPtr[0]; \ - sample2 = smpPtr[1]; \ - sample3 = smpPtr[2]; \ - INTERPOLATE8(sample, sample2, sample3, pos) \ + sample = smpPtr[-1]; \ + sample2 = smpPtr[0]; \ + sample3 = smpPtr[1]; \ + sample4 = smpPtr[2]; \ + INTERPOLATE8(sample, sample2, sample3, sample4, pos) \ sample <<= 12; \ *audioMixL++ += ((int64_t)sample * CDA_LVol) >> 32; \ *audioMixR++ += ((int64_t)sample * CDA_RVol) >> 32; \ #define RENDER_8BIT_SMP_MONO_INTRP \ assert(smpPtr >= CDA_LinearAdr && smpPtr < CDA_LinearAdr+v->SLen); \ - sample = smpPtr[0]; \ - sample2 = smpPtr[1]; \ - sample3 = smpPtr[2]; \ - INTERPOLATE8(sample, sample2, sample3, pos) \ + sample = smpPtr[-1]; \ + sample2 = smpPtr[0]; \ + sample3 = smpPtr[1]; \ + sample4 = smpPtr[2]; \ + INTERPOLATE8(sample, sample2, sample3, sample4, pos) \ sample <<= 12; \ sample = ((int64_t)sample * CDA_LVol) >> 32; \ *audioMixL++ += sample; \ @@ -152,20 +142,22 @@ #define RENDER_16BIT_SMP_INTRP \ assert(smpPtr >= CDA_LinearAdr && smpPtr < CDA_LinearAdr+v->SLen); \ - sample = smpPtr[0]; \ - sample2 = smpPtr[1]; \ - sample3 = smpPtr[2]; \ - INTERPOLATE16(sample, sample2, sample3, pos) \ + sample = smpPtr[-1]; \ + sample2 = smpPtr[0]; \ + sample3 = smpPtr[1]; \ + sample4 = smpPtr[2]; \ + INTERPOLATE16(sample, sample2, sample3, sample4, pos) \ sample <<= 12; \ *audioMixL++ += ((int64_t)sample * CDA_LVol) >> 32; \ *audioMixR++ += ((int64_t)sample * CDA_RVol) >> 32; \ #define RENDER_16BIT_SMP_MONO_INTRP \ assert(smpPtr >= CDA_LinearAdr && smpPtr < CDA_LinearAdr+v->SLen); \ - sample = smpPtr[0]; \ - sample2 = smpPtr[1]; \ - sample3 = smpPtr[2]; \ - INTERPOLATE16(sample, sample2, sample3, pos) \ + sample = smpPtr[-1]; \ + sample2 = smpPtr[0]; \ + sample3 = smpPtr[1]; \ + sample4 = smpPtr[2]; \ + INTERPOLATE16(sample, sample2, sample3, sample4, pos) \ sample <<= 12; \ sample = ((int64_t)sample * CDA_LVol) >> 32; \ *audioMixL++ += sample; \ @@ -178,14 +170,14 @@ // in: int32_t s1,s2 = -128..127 | f = 0..65535 (frac) | out: s1 = -32768..32767 #define INTERPOLATE8(s1, s2, f) \ s2 -= s1; \ - s2 = (s2 * (int32_t)f) >> 8; \ + s2 = (s2 * (int32_t)f) >> (16 - 8); \ s1 <<= 8; \ s1 += s2; \ // in: int32_t s1,s2 = -32768..32767 | f = 0..65535 (frac) | out: s1 = -32768..32767 #define INTERPOLATE16(s1, s2, f) \ s2 = (s2 - s1) >> 1; \ - s2 = (s2 * (int32_t)f) >> 15; \ + s2 = (s2 * (int32_t)f) >> (16 - 1); \ s1 += s2; \ #define RENDER_8BIT_SMP_INTRP \ diff --git a/src/ft2_module_loader.c b/src/ft2_module_loader.c @@ -24,6 +24,7 @@ #include "ft2_midi.h" #include "ft2_events.h" #include "ft2_video.h" +#include "ft2_tables.h" /* This is a *HUGE* mess! ** I hope you never have to modify it, and you probably shouldn't either. @@ -150,7 +151,6 @@ void checkSampleRepeat(sampleTyp *s); // ft2_replayer.c extern const char modSig[32][5]; -extern const uint16_t amigaPeriod[12*8]; static bool allocateTmpInstr(int16_t nr) { @@ -627,14 +627,17 @@ static bool loadMusicMOD(FILE *f, uint32_t fileLength, bool fromExternalThread) s = &instrTmp[1+a]->samp[0]; s->len = 2 * SWAP16(h_MOD31.instr[a].len); - - s->pek = (int8_t *)malloc(s->len + LOOP_FIX_LEN); - if (s->pek == NULL) + + s->pek = NULL; + s->origPek = (int8_t *)malloc(s->len + LOOP_FIX_LEN); + if (s->origPek == NULL) { showMsg(0, "System message", "Not enough memory!"); goto modLoadError; } + s->pek = s->origPek + SMP_DAT_OFFSET; + if (modFormat != FORMAT_HMNT) // most of "His Master's Noisetracker" songs have junk sample names, so let's not load them memcpy(s->name, songTmp.instrName[1+a], 22); @@ -726,7 +729,7 @@ static uint8_t stmTempoToBPM(uint8_t tempo) // ported from original ST2.3 replay hz -= ((slowdowns[tempo >> 4] * (tempo & 15)) >> 4); // can and will underflow - bpm = (uint32_t)round(hz * 2.5); + bpm = (int32_t)((hz * 2.5) + 0.5); return (uint8_t)CLAMP(bpm, 32, 255); // result can be slightly off, but close enough... } @@ -879,7 +882,8 @@ static bool loadMusicSTM(FILE *f, uint32_t fileLength, bool fromExternalThread) /* Remove any EDx with no note. ** SDx with no note in ST3 = does nothing - ** EDx with no note in FT2 = still retriggers */ + ** EDx with no note in FT2 = still retriggers + */ if (ton->effTyp == 0xE && (ton->eff & 0xF0) == 0xD0) { if (ton->ton == 0 || ton->ton == 97) @@ -931,13 +935,16 @@ static bool loadMusicSTM(FILE *f, uint32_t fileLength, bool fromExternalThread) s = &instrTmp[1+i]->samp[0]; - s->pek = (int8_t *)malloc(h_STM.instr[i].len + LOOP_FIX_LEN); - if (s->pek == NULL) + s->pek = NULL; + s->origPek = (int8_t *)malloc(h_STM.instr[i].len + LOOP_FIX_LEN); + if (s->origPek == NULL) { showMsg(0, "System message", "Not enough memory!"); goto stmLoadError; } + s->pek = s->origPek + SMP_DAT_OFFSET; + s->len = h_STM.instr[i].len; tuneSample(s, h_STM.instr[i].rate); s->vol = h_STM.instr[i].vol; @@ -956,7 +963,7 @@ static bool loadMusicSTM(FILE *f, uint32_t fileLength, bool fromExternalThread) { s->repS = 0; s->repL = 0; - s->typ = 0; + s->typ = 0; } if (s->vol > 64) @@ -1090,9 +1097,9 @@ static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool fromExternalThread) uint8_t ha[2048]; uint8_t s3mLastDEff[32], s3mLastEEff[32], s3mLastFEff[32]; uint8_t s3mLastSEff[32], s3mLastJEff[32], s3mLastGInstr[32], typ; - int16_t i, j, k, ai, ap, ver, ii, kk, tmp; + int16_t ai, ap, ver, ii, kk, tmp; uint16_t ptnOfs[256]; - int32_t len; + int32_t i, j, k, len; tonTyp ton, *pattTon; sampleTyp *s; songS3MHeaderTyp h_S3M; @@ -1149,7 +1156,7 @@ static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool fromExternalThread) } if (k <= songTmp.len) - songTmp.len -= k; + songTmp.len -= (uint16_t)k; else songTmp.len = 0; @@ -1530,7 +1537,7 @@ static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool fromExternalThread) } } - if (tmpPatternEmpty(i)) + if (tmpPatternEmpty((uint16_t)i)) { if (pattTmp[i] != NULL) { @@ -1580,7 +1587,7 @@ static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool fromExternalThread) } else if (h_S3MInstr.memSeg > 0 && h_S3MInstr.len > 0) { - if (!allocateTmpInstr(1 + i)) + if (!allocateTmpInstr((int16_t)(1 + i))) { showMsg(0, "System message", "Not enough memory!"); goto s3mLoadError; @@ -1590,16 +1597,20 @@ static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool fromExternalThread) s = &instrTmp[1+i]->samp[0]; len = h_S3MInstr.len; + + bool hasLoop = h_S3MInstr.flags & 1; + bool stereoSample = (h_S3MInstr.flags >> 1) & 1; + bool is16Bit = (h_S3MInstr.flags >> 2) & 1; + + if (is16Bit) // 16-bit + len *= 2; - if ((h_S3MInstr.flags & 2) != 0) // stereo + if (stereoSample) // stereo { - stereoSamplesWarn = false; + stereoSamplesWarn = true; len *= 2; } - if ((h_S3MInstr.flags & 4) != 0) // 16-bit - len *= 2; - tmpSmp = (int8_t *)malloc(len + LOOP_FIX_LEN); if (tmpSmp == NULL) { @@ -1607,15 +1618,17 @@ static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool fromExternalThread) goto s3mLoadError; } + int8_t *newPtr = tmpSmp + SMP_DAT_OFFSET; + memcpy(s->name, h_S3MInstr.name, 21); - if (h_S3MInstr.c2Spd > 65535) + if (h_S3MInstr.c2Spd > 65535) // ST3 (and OpenMPT) does this h_S3MInstr.c2Spd = 65535; tuneSample(s, h_S3MInstr.c2Spd); - s->len = h_S3MInstr.len; - s->vol = h_S3MInstr.vol; + s->len = h_S3MInstr.len; + s->vol = h_S3MInstr.vol; s->repS = h_S3MInstr.repS; s->repL = h_S3MInstr.repE - h_S3MInstr.repS; @@ -1627,12 +1640,13 @@ static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool fromExternalThread) { s->repS = 0; s->repL = 0; + hasLoop = false; } - s->typ = (h_S3MInstr.flags & 1) + ((h_S3MInstr.flags & 4) << 2); - if (s->repL == 0) - s->typ &= 16; // turn off loop, keep 16-bit flag only + hasLoop = false; + + s->typ = hasLoop + (is16Bit << 4); if (s->vol > 64) s->vol = 64; @@ -1645,28 +1659,25 @@ static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool fromExternalThread) if ((h_S3MInstr.memSeg<<4)+len > (int32_t)dataLength) len = dataLength - (h_S3MInstr.memSeg << 4); - if (fread(tmpSmp, len, 1, f) != 1) + if (ver == 1) { - free(tmpSmp); - showMsg(0, "System message", "General I/O error during loading! Is the file in use?"); - goto s3mLoadError; + fseek(f, len, SEEK_CUR); // sample not supported } - - if (ver != 1) + else { - if ((h_S3MInstr.flags & 4) != 0) + if (fread(newPtr, len, 1, f) != 1) { - conv16BitSample(tmpSmp, len, h_S3MInstr.flags & 2); + free(tmpSmp); + showMsg(0, "System message", "General I/O error during loading! Is the file in use?"); + goto s3mLoadError; + } - s->pek = (int8_t *)malloc((h_S3MInstr.len * 2) + LOOP_FIX_LEN); - if (s->pek == NULL) - { - free(tmpSmp); - showMsg(0, "System message", "Not enough memory!"); - goto s3mLoadError; - } + if (is16Bit) + { + conv16BitSample(newPtr, len, stereoSample); - memcpy(s->pek, tmpSmp, h_S3MInstr.len * 2); + s->origPek = tmpSmp; + s->pek = s->origPek + SMP_DAT_OFFSET; s->len *= 2; s->repS *= 2; @@ -1674,23 +1685,25 @@ static bool loadMusicS3M(FILE *f, uint32_t dataLength, bool fromExternalThread) } else { - conv8BitSample(tmpSmp, len, h_S3MInstr.flags & 2); + conv8BitSample(newPtr, len, stereoSample); + + s->origPek = tmpSmp; + s->pek = s->origPek + SMP_DAT_OFFSET; + } - s->pek = (int8_t *)malloc(h_S3MInstr.len + LOOP_FIX_LEN); - if (s->pek == NULL) + // if stereo sample: reduce memory footprint after sample was downmixed to mono + if (stereoSample) + { + newPtr = (int8_t *)realloc(s->origPek, s->len + LOOP_FIX_LEN); + if (newPtr != NULL) { - free(tmpSmp); - showMsg(0, "System message", "Not enough memory!"); - goto s3mLoadError; + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; } - - memcpy(s->pek, tmpSmp, h_S3MInstr.len); } fixSample(s); } - - free(tmpSmp); } } } @@ -2276,10 +2289,13 @@ static bool loadInstrSample(FILE *f, uint16_t i) l = MAX_SAMPLE_LEN; } - s->pek = (int8_t *)malloc(l + LOOP_FIX_LEN); - if (s->pek == NULL) + s->pek = NULL; + s->origPek = (int8_t *)malloc(l + LOOP_FIX_LEN); + if (s->origPek == NULL) return false; + s->pek = s->origPek + SMP_DAT_OFFSET; + int32_t bytesRead = (int32_t)fread(s->pek, 1, l, f); if (bytesRead < l) { @@ -2300,9 +2316,12 @@ static bool loadInstrSample(FILE *f, uint16_t i) s->repL /= 2; s->repS /= 2; - newPtr = (int8_t *)realloc(s->pek, s->len + LOOP_FIX_LEN); + newPtr = (int8_t *)realloc(s->origPek, s->len + LOOP_FIX_LEN); if (newPtr != NULL) - s->pek = newPtr; + { + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; + } stereoSamplesWarn = true; } @@ -2519,9 +2538,6 @@ static void setupLoadedModule(void) playMode = PLAYMODE_IDLE; songPlaying = false; - editor.currVolEnvPoint = 0; - editor.currPanEnvPoint = 0; - #ifdef HAS_MIDI midi.currMIDIVibDepth = 0; midi.currMIDIPitch = 0; @@ -2566,7 +2582,6 @@ static void setupLoadedModule(void) setScrollBarPos(SB_POS_ED, 0, false); resetChannels(); - refreshScopes(); setPos(0, 0, false); setSpeed(song.speed); @@ -2579,6 +2594,10 @@ static void setupLoadedModule(void) setFrqTab((loadedFormat == FORMAT_XM) ? linearFreqTable : false); unlockMixerCallback(); + editor.currVolEnvPoint = 0; + editor.currPanEnvPoint = 0; + + refreshScopes(); exitTextEditing(); updateTextBoxPointers(); resetChannelOffset(); @@ -2593,9 +2612,8 @@ static void setupLoadedModule(void) // redraw top part of screen if (editor.ui.extended) { - // first exit extended mode, then re-enter - togglePatternEditorExtended(); - togglePatternEditorExtended(); + togglePatternEditorExtended(); // exit + togglePatternEditorExtended(); // re-enter (force redrawing) } else { diff --git a/src/ft2_module_saver.c b/src/ft2_module_saver.c @@ -11,6 +11,7 @@ #include "ft2_mouse.h" #include "ft2_sample_ed.h" #include "ft2_module_loader.h" +#include "ft2_tables.h" /* These savers are directly ported, so they should act identical to FT2 ** except for some very minor changes. @@ -20,8 +21,15 @@ static SDL_Thread *thread; static uint16_t packPatt(uint8_t *pattPtr, uint16_t numRows); +static const char modSig[32][5] = +{ + "1CHN", "2CHN", "3CHN", "4CHN", "5CHN", "6CHN", "7CHN", "8CHN", + "9CHN", "10CH", "11CH", "12CH", "13CH", "14CH", "15CH", "16CH", + "17CH", "18CH", "19CH", "20CH", "21CH", "22CH", "23CH", "24CH", + "25CH", "26CH", "27CH", "28CH", "29CH", "30CH", "31CH", "32CH" +}; + // ft2_replayer.c -extern const char modSig[32][5]; extern const uint16_t amigaPeriod[12*8]; bool saveXM(UNICHAR *filenameU) diff --git a/src/ft2_palette.c b/src/ft2_palette.c @@ -4,6 +4,8 @@ #include "ft2_gui.h" #include "ft2_config.h" #include "ft2_video.h" +#include "ft2_palette.h" +#include "ft2_tables.h" uint8_t cfg_ColorNr = 0; // globalized @@ -124,7 +126,7 @@ static void updatePaletteEditor(void) static void paletteDragMoved(void) { - uint8_t nr, p, contrast; + uint8_t nr, p; int16_t i, k; if (config.cfg_StdPalNr != PAL_USER_DEFINED) @@ -150,17 +152,25 @@ static void paletteDragMoved(void) if (cfg_ColorNr == 4 || cfg_ColorNr == 5) { + double dRed = cfg_Red; + double dGreen = cfg_Green; + double dBlue = cfg_Blue; + + int32_t contrast = cfg_Contrast; + if (contrast < 1) + contrast = 1; + + double dContrast = contrast * (1.0 / 40.0); + for (i = 0; i < 3; i++) { k = scaleOrder[i] + (cfg_ColorNr - 4) * 2; - contrast = cfg_Contrast; - if (contrast < 1) // no idea why FT2 limits contrast to 1 - contrast = 1; + double dMul = palPow((i + 1) * (1.0 / 2.0), dContrast); - palTable[p][k].r = palMax((int32_t)round(cfg_Red * palPow((i + 1) / 2.0, contrast / 40.0))); - palTable[p][k].g = palMax((int32_t)round(cfg_Green * palPow((i + 1) / 2.0, contrast / 40.0))); - palTable[p][k].b = palMax((int32_t)round(cfg_Blue * palPow((i + 1) / 2.0, contrast / 40.0))); + palTable[p][k].r = palMax((int32_t)((dRed * dMul) + 0.5)); + palTable[p][k].g = palMax((int32_t)((dGreen * dMul) + 0.5)); + palTable[p][k].b = palMax((int32_t)((dBlue * dMul) + 0.5)); } palContrast[p][cfg_ColorNr-4] = cfg_Contrast; @@ -443,79 +453,3 @@ void rbConfigPalUserDefined(void) setPal16(palTable[config.cfg_StdPalNr], true); checkRadioButton(RB_CONFIG_PAL_USER_DEFINED); } - -pal16 palTable[12][16] = // FT2 palettes (18-bit VGA RGB, 16 color palette) -{ - { - {0, 0, 0},{30, 38, 63},{0, 0, 17},{63, 63, 63}, - {27, 36, 40},{63, 63, 63},{40, 40, 40},{0, 0, 0}, - {10, 13, 14},{49, 63, 63},{15, 15, 15},{63, 63, 63}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - }, - { - {0, 0, 0},{21, 40, 63},{0, 0, 17},{63, 63, 63}, - {6, 39, 35},{63, 63, 63},{40, 40, 40},{0, 0, 0}, - {2, 14, 13},{11, 63, 63},{16, 16, 16},{63, 63, 63}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - }, - { - {0, 0, 0},{39, 52, 63},{8, 8, 13},{57, 57, 63}, - {10, 21, 33},{63, 63, 63},{37, 37, 45},{0, 0, 0}, - {4, 8, 13},{18, 37, 58},{13, 13, 16},{63, 63, 63}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - }, - { - {0, 0, 0},{47, 47, 47},{9, 9, 9},{63, 63, 63}, - {37, 29, 7},{63, 63, 63},{40, 40, 40},{0, 0, 0}, - {11, 9, 2},{63, 58, 14},{15, 15, 15},{63, 63, 63}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - }, - { - {0, 0, 0},{46, 45, 46},{13, 9, 9},{63, 63, 63}, - {22, 19, 22},{63, 63, 63},{36, 32, 34},{0, 0, 0}, - {8, 7, 8},{39, 34, 39},{13, 12, 12},{63, 58, 62}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - }, - { - {0, 0, 0},{19, 49, 54},{0, 11, 7},{52, 63, 61}, - {9, 31, 21},{63, 63, 63},{40, 40, 40},{0, 0, 0}, - {4, 13, 9},{15, 50, 34},{15, 15, 15},{63, 63, 63}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - }, - { - {0, 0, 0},{27, 37, 53},{0, 0, 20},{63, 63, 63}, - {7, 12, 21},{63, 63, 63},{38, 39, 39},{0, 0, 0}, - {2, 4, 7},{14, 23, 41},{13, 13, 13},{63, 63, 63}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - }, - { - {0, 0, 0},{63, 54, 62},{18, 3, 3},{63, 63, 63}, - {36, 19, 25},{63, 63, 63},{40, 40, 40},{0, 0, 0}, - {11, 6, 8},{63, 38, 50},{15, 15, 15},{63, 63, 63}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - }, - { - {0, 0, 0},{63, 0, 63},{0, 21, 0},{63, 44, 0}, - {0, 63, 0},{63, 63, 63},{63, 0, 0},{0, 0, 0}, - {0, 28, 0},{0, 63, 0},{23, 0, 0},{63, 0, 0}, - {0, 63, 63},{0, 63, 63},{0, 63, 63},{0, 63, 63} - }, - { - {0, 0, 0},{50, 46, 63},{15, 0, 16},{59, 58, 63}, - {34, 21, 41},{63, 63, 63},{40, 40, 40},{0, 0, 0}, - {13, 8, 15},{61, 37, 63},{15, 15, 15},{63, 63, 63}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - }, - { - {0, 0, 0},{63, 63, 32},{10, 10, 10},{63, 63, 63}, - {18, 29, 32},{63, 63, 63},{39, 39, 39},{0, 0, 0}, - {6, 10, 11},{34, 54, 60},{15, 15, 15},{63, 63, 63}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - }, - { - {0, 0, 0},{36, 47, 63},{9, 9, 16},{63, 63, 63}, - {19, 24, 38},{63, 63, 63},{39, 39, 39},{0, 0, 0}, - {8, 10, 15},{32, 41, 63},{15, 15, 15},{63, 63, 63}, - {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} - } -}; diff --git a/src/ft2_palette.h b/src/ft2_palette.h @@ -50,7 +50,6 @@ typedef struct pal16_t } pal16; extern uint8_t cfg_ColorNr; -extern pal16 palTable[12][16]; void setCustomPalColor(uint32_t color); diff --git a/src/ft2_pattern_draw.c b/src/ft2_pattern_draw.c @@ -11,6 +11,7 @@ #include "ft2_config.h" #include "ft2_gui.h" #include "ft2_video.h" +#include "ft2_tables.h" static tonTyp emptyPattern[MAX_VOICES * MAX_PATT_LEN]; @@ -31,212 +32,6 @@ static const uint16_t sharpNote2Char_big[12] = { 36*16, 37*16, 36*16, 37*16, 36* static const uint16_t flatNote1Char_big[12] = { 12*16, 13*16, 13*16, 14*16, 14*16, 15*16, 16*16, 16*16, 10*16, 10*16, 11*16, 11*16 }; static const uint16_t flatNote2Char_big[12] = { 36*16, 38*16, 36*16, 38*16, 36*16, 36*16, 38*16, 36*16, 38*16, 36*16, 38*16, 36*16 }; -static const uint8_t noteTab1[96] = -{ - 0,1,2,3,4,5,6,7,8,9,10,11, - 0,1,2,3,4,5,6,7,8,9,10,11, - 0,1,2,3,4,5,6,7,8,9,10,11, - 0,1,2,3,4,5,6,7,8,9,10,11, - 0,1,2,3,4,5,6,7,8,9,10,11, - 0,1,2,3,4,5,6,7,8,9,10,11, - 0,1,2,3,4,5,6,7,8,9,10,11, - 0,1,2,3,4,5,6,7,8,9,10,11 -}; - -static const uint8_t noteTab2[96] = -{ - 0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3,3,3,3,3, - 4,4,4,4,4,4,4,4,4,4,4,4, - 5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7 -}; - -static const uint8_t hex2Dec[256] = -{ - 0,1,2,3,4,5,6,7,8,9, - 16,17,18,19,20,21,22,23,24,25, - 32,33,34,35,36,37,38,39,40,41, - 48,49,50,51,52,53,54,55,56,57, - 64,65,66,67,68,69,70,71,72,73, - 80,81,82,83,84,85,86,87,88,89, - 96,97,98,99,100,101,102,103,104,105, - 112,113,114,115,116,117,118,119,120,121, - 128,129,130,131,132,133,134,135,136,137, - 144,145,146,147,148,149,150,151,152,153, - - 0,1,2,3,4,5,6,7,8,9, - 16,17,18,19,20,21,22,23,24,25, - 32,33,34,35,36,37,38,39,40,41, - 48,49,50,51,52,53,54,55,56,57, - 64,65,66,67,68,69,70,71,72,73, - 80,81,82,83,84,85,86,87,88,89, - 96,97,98,99,100,101,102,103,104,105, - 112,113,114,115,116,117,118,119,120,121, - 128,129,130,131,132,133,134,135,136,137, - 144,145,146,147,148,149,150,151,152,153, - - 0,1,2,3,4,5,6,7,8,9, - 16,17,18,19,20,21,22,23,24,25, - 32,33,34,35,36,37,38,39,40,41, - 48,49,50,51,52,53,54,55,56,57, - 64,65,66,67,68,69,70,71,72,73, - 80,81,82,83,84,85 -}; - -static const pattCoord_t pattCoordTable[2][2][2] = -{ - // no pattern stretch - { - // no pattern channel scroll - { - { 176, 292, 177, 283, 293, 13, 13 }, // normal pattern editor - { 56, 228, 57, 219, 229, 20, 21 }, // extended pattern editor - }, - - // pattern channel scroll - { - { 176, 285, 177, 276, 286, 12, 12 }, // normal pattern editor - { 56, 221, 57, 212, 222, 19, 20 }, // extended pattern editor - } - }, - - // pattern stretch - { - // no pattern channel scroll - { - { 177, 286, 178, 277, 288, 9, 10 }, // normal pattern editor - { 56, 232, 58, 223, 234, 15, 15 }, // extended pattern editor - }, - - // pattern channel scroll - { - { 176, 285, 177, 276, 286, 9, 9 }, // normal pattern editor - { 56, 220, 57, 211, 221, 14, 15 }, // extended pattern editor - }, - } -}; - -static const pattCoord2_t pattCoord2Table[2][2][2] = -{ - // no pattern stretch - { - // no pattern channel scroll - { - { 175, 291, 107, 107 }, // normal pattern editor - { 55, 227, 163, 171 }, // extended pattern editor - }, - - // pattern channel scroll - { - { 175, 284, 100, 100 }, // normal pattern editor - { 55, 220, 156, 164 }, // extended pattern editor - } - }, - - // pattern stretch - { - // no pattern channel scroll - { - { 175, 285, 101, 113 }, // normal pattern editor - { 55, 231, 167, 167 }, // extended pattern editor - }, - - // pattern channel scroll - { - { 175, 284, 100, 100 }, // normal pattern editor - { 55, 219, 155, 165 }, // extended pattern editor - }, - } -}; - -static const markCoord_t markCoordTable[2][2][2] = -{ - // no pattern stretch - { - // no pattern channel scroll - { - { 177, 281, 293 }, // normal pattern editor - { 57, 217, 229 }, // extended pattern editor - }, - - // pattern channel scroll - { - { 177, 274, 286 }, // normal pattern editor - { 57, 210, 222 }, // extended pattern editor - } - }, - - // pattern stretch - { - // no pattern channel scroll - { - { 176, 275, 286 }, // normal pattern editor - { 56, 221, 232 }, // extended pattern editor - }, - - // pattern channel scroll - { - { 175, 274, 284 }, // normal pattern editor - { 55, 209, 219 }, // extended pattern editor - }, - } -}; - -static const uint8_t pattCursorXTab[2 * 4 * 8] = -{ - // no volume column shown - 32, 88, 104, 0, 0, 120, 136, 152, // 4 columns visible - 32, 80, 88, 0, 0, 96, 104, 112, // 6 columns visible - 32, 56, 64, 0, 0, 72, 80, 88, // 8 columns visible - 32, 52, 56, 0, 0, 60, 64, 68, // 12 columns visible - - // volume column shown - 32, 96, 104, 120, 128, 144, 152, 160, // 4 columns visible - 32, 56, 64, 80, 88, 96, 104, 112, // 6 columns visible - 32, 60, 64, 72, 76, 84, 88, 92, // 8 columns visible - 32, 60, 64, 72, 76, 84, 88, 92, // 12 columns visible -}; - -static const uint8_t pattCursorWTab[2 * 4 * 8] = -{ - // no volume column shown - 48, 16, 16, 0, 0, 16, 16, 16, // 4 columns visible - 48, 8, 8, 0, 0, 8, 8, 8, // 6 columns visible - 24, 8, 8, 0, 0, 8, 8, 8, // 8 columns visible - 16, 4, 4, 0, 0, 4, 4, 4, // 12 columns visible - - // volume column shown - 48, 8, 8, 8, 8, 8, 8, 8, // 4 columns visible - 24, 8, 8, 8, 8, 8, 8, 8, // 6 columns visible - 24, 4, 4, 4, 4, 4, 4, 4, // 8 columns visible - 24, 4, 4, 4, 4, 4, 4, 4 // 12 columns visible -}; - -// global tables - -const char chDecTab1[MAX_VOICES+1] = -{ - '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', - '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', - '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', - '3', '3', '3' -}; - -const char chDecTab2[MAX_VOICES+1] = -{ - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2' -}; - -// ft2_pattern_ed.c -extern const uint16_t chanWidths[6]; - static void pattCharOut(uint32_t xPos, uint32_t yPos, uint8_t chr, uint8_t fontType, uint32_t color); static void drawEmptyNoteSmall(uint32_t xPos, uint32_t yPos, uint32_t color); static void drawKeyOffSmall(uint32_t xPos, uint32_t yPos, uint32_t color); diff --git a/src/ft2_pattern_ed.c b/src/ft2_pattern_ed.c @@ -20,6 +20,7 @@ #include "ft2_wav_renderer.h" #include "ft2_mouse.h" #include "ft2_video.h" +#include "ft2_tables.h" // for pattern marking w/ keyboard static int8_t lastChMark; @@ -37,12 +38,6 @@ static const uint16_t iSwitchExtX[4] = { 221, 262, 303, 344 }; static int32_t lastMouseX, lastMouseY; -// defined at the bottom of this file -extern const pattCoordsMouse_t pattCoordMouseTable[2][2][2]; - -// globalized -const uint16_t chanWidths[6] = { 141, 141, 93, 69, 45, 45 }; - bool allocatePattern(uint16_t nr) // for tracker use only, not in loader! { bool audioWasntLocked; @@ -54,11 +49,11 @@ bool allocatePattern(uint16_t nr) // for tracker use only, not in loader! lockAudio(); /* Original FT2 allocates only the amount of rows needed, but we don't - * do that to avoid out of bondary row look-up between out-of-sync replayer - * state and tracker state (yes it used to happen, rarely). We're not wasting - * too much RAM for a modern computer anyway. Worst case: 256 allocated - * patterns would be ~10MB. - */ + ** do that to avoid out of bondary row look-up between out-of-sync replayer + ** state and tracker state (yes it used to happen, rarely). We're not wasting + ** too much RAM for a modern computer anyway. Worst case: 256 allocated + ** patterns would be ~10MB. + **/ patt[nr] = (tonTyp *)calloc((MAX_PATT_LEN * TRACK_WIDTH) + 16, 1); if (patt[nr] == NULL) @@ -2695,7 +2690,7 @@ static void zapSong(void) lockMixerCallback(); song.len = 1; - song.repS = 0; // FT2 doesn't do this... + song.repS = 0; // Silly: FT2 doesn't do this! song.speed = 125; song.tempo = 6; song.songPos = 0; @@ -2744,7 +2739,7 @@ static void zapInstrs(void) for (int16_t i = 1; i <= MAX_INST; i++) { freeInstr(i); - memset(song.instrName[i], 0, 23); + memset(song.instrName[i], 0, 22 + 1); } updateNewInstrument(); @@ -2922,41 +2917,3 @@ void expandPattern(void) setSongModifiedFlag(); } } - -const pattCoordsMouse_t pattCoordMouseTable[2][2][2] = -{ - /* - uint16_t upperRowsY, midRowY, lowerRowsY; - uint16_t numUpperRows; - */ - - // no pattern stretch - { - // no pattern channel scroll - { - { 177, 281, 293, 13 }, // normal pattern editor - { 57, 217, 229, 20 }, // extended pattern editor - }, - - // pattern channel scroll - { - { 177, 274, 286, 12 }, // normal pattern editor - { 57, 210, 222, 19 }, // extended pattern editor - } - }, - - // pattern stretch - { - // no pattern channel scroll - { - { 176, 275, 286, 9 }, // normal pattern editor - { 56, 221, 232, 15 }, // extended pattern editor - }, - - // pattern channel scroll - { - { 175, 274, 284, 9 }, // normal pattern editor - { 55, 209, 219, 14 }, // extended pattern editor - }, - } -}; diff --git a/src/ft2_replayer.c b/src/ft2_replayer.c @@ -6,7 +6,6 @@ #include <stdint.h> #include <stdio.h> #include <math.h> -#include "ft2_audio.h" #include "ft2_header.h" #include "ft2_config.h" #include "ft2_gui.h" @@ -19,23 +18,16 @@ #include "ft2_scopes.h" #include "ft2_mouse.h" #include "ft2_sample_loader.h" +#include "ft2_tables.h" /* This is a *huge* mess, directly ported from the original FT2 code (and modified). ** You will experience a lot of headaches if you dig into it... -** If something looks to be wrong, it's probably right! */ - -// TABLES AND VARIABLES - -// defined at the bottom of this file -extern const int8_t vibSineTab[256]; -extern const uint8_t vibTab[32]; -extern const uint16_t amigaFinePeriod[12 * 8]; -extern const uint16_t amigaPeriod[12 * 8]; +** If something looks to be off, it's probably not! +*/ static bool bxxOverflow; -static int16_t *linearPeriods, *amigaPeriods, oldPeriod; -static uint32_t *logTab, oldRate; -static uint32_t frequenceDivFactor, frequenceMulFactor; +static int32_t oldPeriod; +static uint32_t oldRate, frequenceDivFactor, frequenceMulFactor; static tonTyp nilPatternLine; // globally accessed @@ -43,7 +35,8 @@ static tonTyp nilPatternLine; int8_t playMode = 0; bool linearFrqTab = false, songPlaying = false, audioPaused = false, musicPaused = false; volatile bool replayerBusy = false; -int16_t *note2Period = NULL, pattLens[MAX_PATTERNS]; +const int16_t *note2Period = NULL; +int16_t pattLens[MAX_PATTERNS]; stmTyp stm[MAX_VOICES]; songTyp song; instrTyp *instr[132]; @@ -131,23 +124,21 @@ void removeSongModifiedFlag(void) editor.updateWindowTitle = true; } -void tuneSample(sampleTyp *s, uint32_t midCFreq) +void tuneSample(sampleTyp *s, int32_t midCFreq) { - int32_t linearFreq, relativeNote; - - if (midCFreq == 0) + if (midCFreq <= 0) { s->fine = 0; s->relTon = 0; + return; } - else - { - linearFreq = (int32_t)round(log(midCFreq / 8363.0) * ((12.0 * 128.0) / M_LN2)); - s->fine = ((linearFreq + 128) & 255) - 128; - relativeNote = (int32_t)round((linearFreq - s->fine) / 128.0); - s->relTon = (int8_t)relativeNote; - } + double dFreq = log2(midCFreq * (1.0 / 8363.0)) * (12.0 * 128.0); + int32_t linearFreq = (int32_t)(dFreq + 0.5); + s->fine = ((linearFreq + 128) & 255) - 128; + + int32_t relTon = (linearFreq - s->fine) >> 7; + s->relTon = (int8_t)CLAMP(relTon, -48, 71); } void setPatternLen(uint16_t nr, int16_t len) @@ -199,7 +190,8 @@ int16_t getUsedSamples(int16_t nr) i--; /* Yes, 'i' can be -1 here, and will be set to at least 0 - ** because of ins->ta values. Possibly an FT2 bug... */ + ** because of ins->ta values. Possibly an FT2 bug... + */ for (j = 0; j < 96; j++) { if (ins->ta[j] > i) @@ -238,7 +230,7 @@ void setFrqTab(bool linear) note2Period = amigaPeriods; } - // update frequency type radiobutton if it's shown + // update "frequency table" radiobutton, if it's shown if (editor.ui.configScreenShown && editor.currConfigScreen == CONFIG_SCREEN_IO_DEVICES) setConfigIORadioButtonStates(); } @@ -255,7 +247,7 @@ static void retrigEnvelopeVibrato(stmTyp *ch) { instrTyp *ins; - if (!(ch->waveCtrl & 0x04)) ch->vibPos = 0; + if (!(ch->waveCtrl & 0x04)) ch->vibPos = 0; if (!(ch->waveCtrl & 0x40)) ch->tremPos = 0; ch->retrigCnt = 0; @@ -307,7 +299,7 @@ void keyOff(stmTyp *ch) ins = ch->instrSeg; assert(ins != NULL); - if (!(ins->envPTyp & 1)) // yes, FT2 does this (!) + if (!(ins->envPTyp & 1)) // yes, FT2 does this (!). Most likely a bug? { if (ch->envPCnt >= ins->envPP[ch->envPPos][0]) ch->envPCnt = ins->envPP[ch->envPPos][0] - 1; @@ -326,16 +318,22 @@ void keyOff(stmTyp *ch) } } -// 100% FT2-accurate routine, do not touch! -void calcReplayRate(uint32_t rate) +void calcReplayRate(int32_t rate) // 100% FT2-accurate routine, do not touch! { if (rate == 0) return; // for voice delta calculation - frequenceDivFactor = (uint32_t)round(65536.0 * 1712.0 / rate * 8363.0); - frequenceMulFactor = (uint32_t)round(256.0 * 65536.0 / rate * 8363.0); - audio.dScopeFreqMul = rate / (double)SCOPE_HZ; + + double dVal, dMul = 1.0 / rate; + + dVal = dMul * (65536.0 * 1712.0 * 8363.0); + frequenceDivFactor = (int32_t)(dVal + 0.5); + + dVal = dMul * (256.0 * 65536.0 * 8363.0); + frequenceMulFactor = (int32_t)(dVal + 0.5); + + audio.dScopeFreqMul = rate * (1.0 / SCOPE_HZ); // for volume ramping (FT2 doesn't round here) audio.quickVolSizeVal = rate / 200; @@ -345,10 +343,10 @@ void calcReplayRate(uint32_t rate) } // 100% FT2-accurate routine, do not touch! -uint32_t getFrequenceValue(uint16_t period) +uint32_t getFrequenceValue(int32_t period) { uint8_t shift; - uint16_t index; + int32_t index, indexQuotient, indexRemainder; uint32_t rate; if (period == 0) @@ -360,11 +358,13 @@ uint32_t getFrequenceValue(uint16_t period) if (linearFrqTab) { index = (12 * 192 * 4) - period; - shift = (14 - (index / 768)) & 0x1F; + indexQuotient = index / 768; + indexRemainder = index % 768; - // this converts to fast code even on x86 (imul + shrd) - rate = ((uint64_t)logTab[index % 768] * frequenceMulFactor) >> 24; - if (shift > 0) + rate = ((uint64_t)logTab[indexRemainder] * frequenceMulFactor) >> LOG_TABLE_BITS; + + shift = (14 - indexQuotient) & 0x1F; + if (shift != 0) rate >>= shift; } else @@ -1327,7 +1327,7 @@ static void fixaEnvelopeVibrato(stmTyp *ch) } else { - // calculate with four times more precision (finalVol = 0..2048) + // calculate with four times more precision (finalVol = 0..65535) vol = (song.globVol * ch->outVol * ch->fadeOutAmp) >> 11; // 0..64 * 0..64 * 0..32768 = 0..65536 } @@ -2368,8 +2368,10 @@ void freeInstr(int16_t nr) for (int8_t i = 0; i < 16; i++) // free sample data { - if (instr[nr]->samp[i].pek != NULL) - free(instr[nr]->samp[i].pek); + sampleTyp *s = &instr[nr]->samp[i]; + + if (s->origPek != NULL) + free(s->origPek); } free(instr[nr]); @@ -2387,8 +2389,10 @@ void freeAllInstr(void) { for (int8_t j = 0; j < MAX_SMP_PER_INST; j++) // free sample data { - if (instr[i]->samp[j].pek != NULL) - free(instr[i]->samp[j].pek); + sampleTyp *s = &instr[i]->samp[j]; + + if (s->origPek != NULL) + free(s->origPek); } free(instr[i]); @@ -2408,8 +2412,8 @@ void freeSample(int16_t nr, int16_t nr2) pauseAudio(); // voice sample pointers are now cleared s = &instr[nr]->samp[nr2]; - if (s->pek != NULL) - free(s->pek); + if (s->origPek != NULL) + free(s->origPek); memset(s, 0, sizeof (sampleTyp)); @@ -2672,24 +2676,6 @@ void closeReplayer(void) freeAllInstr(); freeAllPatterns(); - if (logTab != NULL) - { - free(logTab); - logTab = NULL; - } - - if (amigaPeriods != NULL) - { - free(amigaPeriods); - amigaPeriods = NULL; - } - - if (linearPeriods != NULL) - { - free(linearPeriods); - linearPeriods = NULL; - } - if (instr[0] != NULL) { free(instr[0]); @@ -2711,67 +2697,18 @@ void closeReplayer(void) bool setupReplayer(void) { - uint16_t i, k; - int16_t noteVal; - - // allocate memory for pointers + int32_t i; for (i = 0; i < MAX_PATTERNS; i++) pattLens[i] = 64; - if (linearPeriods == NULL) - linearPeriods = (int16_t *)malloc(sizeof (int16_t) * ((12 * 10 * 16) + 16)); - - if (amigaPeriods == NULL) - amigaPeriods = (int16_t *)malloc(sizeof (int16_t) * ((12 * 10 * 16) + 16)); - - if (logTab == NULL) - logTab = (uint32_t *)malloc(sizeof (int32_t) * 768); - - if (linearPeriods == NULL || amigaPeriods == NULL || logTab == NULL) - { - showErrorMsgBox("Not enough memory!"); - return false; - } - - // generate tables, bit-exact to original FT2 - - // log table - for (i = 0; i < 768; i++) - logTab[i] = (uint32_t)round(16777216.0 * exp((i / 768.0) * M_LN2)); - - // linear table - for (i = 0; i < (12*10*16)+16; i++) - linearPeriods[i] = (((12 * 10 * 16) + 16) * 4) - (i * 4); - - /* Amiga period table - ** This has a LUT read overflow in real FT2 making the last 17 values trash. We patch those later. */ - k = 0; - for (i = 0; i < 10; i++) - { - for (uint16_t j = 0; j < 96; j++) - { - noteVal = ((amigaFinePeriod[j] * 64) + (-1 + (1 << i))) >> (i + 1); - - amigaPeriods[k++] = noteVal; - amigaPeriods[k++] = noteVal; // copy for interpolation applied later - } - } - - // interpolate between points - for (i = 0; i < (12*10*8)+7; i++) - amigaPeriods[(i * 2) + 1] = (amigaPeriods[i * 2] + amigaPeriods[(i * 2) + 2]) / 2; - - // the following 17 values are confirmed to be the correct table LUT overflow values in real FT2 - amigaPeriods[1919] = 22; amigaPeriods[1920] = 16; amigaPeriods[1921] = 8; amigaPeriods[1922] = 0; - amigaPeriods[1923] = 16; amigaPeriods[1924] = 32; amigaPeriods[1925] = 24; amigaPeriods[1926] = 16; - amigaPeriods[1927] = 8; amigaPeriods[1928] = 0; amigaPeriods[1929] = 16; amigaPeriods[1930] = 32; - amigaPeriods[1931] = 24; amigaPeriods[1932] = 16; amigaPeriods[1933] = 8; amigaPeriods[1934] = 0; - amigaPeriods[1935] = 0; - playMode = PLAYMODE_IDLE; songPlaying = false; + // unmute all channels (must be done before resetChannels() call) + for (i = 0; i < MAX_VOICES; i++) + editor.chnMode[i] = 1; + resetChannels(); song.len = 1; @@ -2808,10 +2745,6 @@ bool setupReplayer(void) for (i = 0; i < 16; i++) instr[131]->samp[i].pan = 128; - // unmute all channels - for (i = 0; i < MAX_VOICES; i++) - editor.chnMode[i] = true; - editor.tmpPattern = 65535; // pattern editor update/redraw kludge return true; } @@ -3359,62 +3292,3 @@ void setSyncedReplayerVars(void) editor.ui.updatePatternEditor = true; } } - -// TABLES - -const char modSig[32][5] = -{ - "1CHN", "2CHN", "3CHN", "4CHN", "5CHN", "6CHN", "7CHN", "8CHN", - "9CHN", "10CH", "11CH", "12CH", "13CH", "14CH", "15CH", "16CH", - "17CH", "18CH", "19CH", "20CH", "21CH", "22CH", "23CH", "24CH", - "25CH", "26CH", "27CH", "28CH", "29CH", "30CH", "31CH", "32CH" -}; - -const int8_t vibSineTab[256] = -{ - 0,-2,-3,-5,-6,-8,-9,-11,-12,-14,-16,-17,-19,-20,-22,-23,-24,-26,-27, - -29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44,-45,-46,-47,-48, - -49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59,-59,-60,-60,-61,-61, - -62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64, - -63,-63,-63,-62,-62,-62,-61,-61,-60,-60,-59,-59,-58,-57,-56,-56,-55, - -54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-39,-38,-37, - -36,-34,-33,-32,-30,-29,-27,-26,-24,-23,-22,-20,-19,-17,-16,-14,-12, - -11,-9,-8,-6,-5,-3,-2,0,2,3,5,6,8,9,11,12,14,16,17,19,20,22,23,24,26, - 27,29,30,32,33,34,36,37,38,39,41,42,43,44,45,46,47,48,49,50,51,52,53, - 54,55,56,56,57,58,59,59,60,60,61,61,62,62,62,63,63,63,64,64,64,64,64, - 64,64,64,64,64,64,63,63,63,62,62,62,61,61,60,60,59,59,58,57,56,56,55, - 54,53,52,51,50,49,48,47,46,45,44,43,42,41,39,38,37,36,34,33,32,30,29, - 27,26,24,23,22,20,19,17,16,14,12,11,9,8,6,5,3,2 -}; - -const uint8_t vibTab[32] = -{ - 0, 24, 49, 74, 97,120,141,161, - 180,197,212,224,235,244,250,253, - 255,253,250,244,235,224,212,197, - 180,161,141,120, 97, 74, 49, 24 -}; - -const uint16_t amigaPeriod[12 * 8] = -{ - 4*1712,4*1616,4*1524,4*1440,4*1356,4*1280,4*1208,4*1140,4*1076,4*1016,4*960,4*906, - 2*1712,2*1616,2*1524,2*1440,2*1356,2*1280,2*1208,2*1140,2*1076,2*1016,2*960,2*906, - 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906, - 856,808,762,720,678,640,604,570,538,508,480,453, - 428,404,381,360,339,320,302,285,269,254,240,226, - 214,202,190,180,170,160,151,143,135,127,120,113, - 107,101,95,90,85,80,75,71,67,63,60,56, - 53,50,47,45,42,40,37,35,33,31,30,28 -}; - -const uint16_t amigaFinePeriod[12 * 8] = -{ - 907,900,894,887,881,875,868,862,856,850,844,838, - 832,826,820,814,808,802,796,791,785,779,774,768, - 762,757,752,746,741,736,730,725,720,715,709,704, - 699,694,689,684,678,675,670,665,660,655,651,646, - 640,636,632,628,623,619,614,610,604,601,597,592, - 588,584,580,575,570,567,563,559,555,551,547,543, - 538,535,532,528,524,520,516,513,508,505,502,498, - 494,491,487,484,480,477,474,470,467,463,460,457 -}; diff --git a/src/ft2_replayer.h b/src/ft2_replayer.h @@ -164,7 +164,7 @@ typedef struct sampleTyp_t { char name[22+1]; bool fixed; - int8_t fine, relTon, *pek; + int8_t fine, relTon, *pek, *origPek; uint8_t vol, typ, pan; int16_t fixedSmp1; #ifndef LERPMIX @@ -240,10 +240,10 @@ typedef struct syncedChannel_t // used for audio/video sync queue void fixSongName(void); // removes spaces from right side of song name void fixSampleName(int16_t nr); // removes spaces from right side of ins/smp names -void calcReplayRate(uint32_t rate); +void calcReplayRate(int32_t rate); void resetOldRates(void); -void tuneSample(sampleTyp *s, uint32_t midCFreq); -uint32_t getFrequenceValue(uint16_t period); +void tuneSample(sampleTyp *s, int32_t midCFreq); +uint32_t getFrequenceValue(int32_t period); int16_t relocateTon(int16_t period, int8_t relativeNote, stmTyp *ch); bool allocateInstr(int16_t nr); @@ -297,7 +297,8 @@ void pbRecPtn(void); extern int8_t playMode; extern bool linearFrqTab, songPlaying, audioPaused, musicPaused; extern volatile bool replayerBusy; -extern int16_t *note2Period, pattLens[MAX_PATTERNS]; +extern const int16_t *note2Period; +extern int16_t pattLens[MAX_PATTERNS]; extern stmTyp stm[MAX_VOICES]; extern songTyp song; extern instrTyp *instr[132]; diff --git a/src/ft2_sample_ed.c b/src/ft2_sample_ed.c @@ -58,9 +58,11 @@ void fixSample(sampleTyp *s) int32_t loopStart, loopLen, loopEnd, len; assert(s != NULL); - if (s->pek == NULL) + if (s->origPek == NULL) return; // empty sample + assert(s->pek != NULL); + loopType = s->typ & 3; if (loopType == 0) { @@ -77,6 +79,7 @@ void fixSample(sampleTyp *s) ptr16 = (int16_t *)s->pek; // write new values + ptr16[-1] = 0; ptr16[len+0] = 0; #ifndef LERPMIX ptr16[len+1] = 0; @@ -88,6 +91,7 @@ void fixSample(sampleTyp *s) return; // write new values + s->pek[-1] = 0; s->pek[len+0] = 0; #ifndef LERPMIX s->pek[len+1] = 0; @@ -116,15 +120,18 @@ void fixSample(sampleTyp *s) ptr16 = (int16_t *)s->pek; - // store old values and old fix position - s->fixedSmp1 = ptr16[loopEnd]; + // store old fix position and old values s->fixedPos = s->repS + s->repL; + s->fixedSmp1 = ptr16[loopEnd+0]; #ifndef LERPMIX s->fixedSmp2 = ptr16[loopEnd+1]; #endif // write new values ptr16[loopEnd+0] = ptr16[loopStart+0]; #ifndef LERPMIX + if (loopStart == 0 && loopEnd > 0) + ptr16[-1] = ptr16[loopEnd-1]; + ptr16[loopEnd+1] = ptr16[loopStart+1]; #endif } @@ -138,15 +145,18 @@ void fixSample(sampleTyp *s) loopStart = s->repS; loopEnd = s->repS + s->repL; - // store old values and old fix position - s->fixedSmp1 = s->pek[loopEnd]; + // store old fix position and old values s->fixedPos = loopEnd; + s->fixedSmp1 = s->pek[loopEnd+0]; #ifndef LERPMIX s->fixedSmp2 = s->pek[loopEnd+1]; #endif // write new values s->pek[loopEnd+0] = s->pek[loopStart+0]; #ifndef LERPMIX + if (loopStart == 0 && loopEnd > 0) + s->pek[-1] = s->pek[loopEnd-1]; + s->pek[loopEnd+1] = s->pek[loopStart+1]; #endif } @@ -168,19 +178,22 @@ void fixSample(sampleTyp *s) loopEnd = loopStart + loopLen; ptr16 = (int16_t *)s->pek; - // store old values and old fix position - s->fixedSmp1 = ptr16[loopEnd]; + // store old fix position and old values s->fixedPos = s->repS + s->repL; + s->fixedSmp1 = ptr16[loopEnd+0]; #ifndef LERPMIX s->fixedSmp2 = ptr16[loopEnd+1]; #endif // write new values ptr16[loopEnd+0] = ptr16[loopEnd-1]; #ifndef LERPMIX + if (loopStart == 0) + ptr16[-1] = ptr16[0]; + if (loopLen >= 2) ptr16[loopEnd+1] = ptr16[loopEnd-2]; else - ptr16[loopEnd+1] = ptr16[loopStart]; + ptr16[loopEnd+1] = ptr16[loopStart+0]; #endif } else @@ -195,19 +208,22 @@ void fixSample(sampleTyp *s) loopEnd = loopStart + loopLen; - // store old values and old fix position - s->fixedSmp1 = s->pek[loopEnd]; + // store old fix position and old values s->fixedPos = loopEnd; + s->fixedSmp1 = s->pek[loopEnd+0]; #ifndef LERPMIX s->fixedSmp2 = s->pek[loopEnd+1]; #endif // write new values s->pek[loopEnd+0] = s->pek[loopEnd-1]; #ifndef LERPMIX + if (loopStart == 0) + s->pek[-1] = s->pek[0]; + if (loopLen >= 2) s->pek[loopEnd+1] = s->pek[loopEnd-2]; else - s->pek[loopEnd+1] = s->pek[loopStart]; + s->pek[loopEnd+1] = s->pek[loopStart+0]; #endif } } @@ -219,28 +235,38 @@ void fixSample(sampleTyp *s) void restoreSample(sampleTyp *s) { int16_t *ptr16; + int32_t fixedPos16; assert(s != NULL); - if (s->pek == NULL || s->len == 0 || (s->typ & 3) == 0 || !s->fixed) + if (s->origPek == NULL || s->len == 0 || (s->typ & 3) == 0 || !s->fixed) return; // empty sample, no loop or not fixed + assert(s->pek != NULL); s->fixed = false; + // clear pre-start bytes + s->pek[-4] = 0; + s->pek[-3] = 0; + s->pek[-2] = 0; + s->pek[-1] = 0; + if (s->typ & 16) { // 16-bit sample ptr16 = (int16_t *)s->pek; - ptr16[s->fixedPos / 2] = s->fixedSmp1; + fixedPos16 = s->fixedPos >> 1; + + ptr16[fixedPos16+0] = s->fixedSmp1; #ifndef LERPMIX - ptr16[(s->fixedPos + 2) / 2] = s->fixedSmp2; + ptr16[fixedPos16+1] = s->fixedSmp2; #endif } else { // 8-bit sample - s->pek[s->fixedPos] = (int8_t)s->fixedSmp1; + s->pek[s->fixedPos+0] = (int8_t)s->fixedSmp1; #ifndef LERPMIX s->pek[s->fixedPos+1] = (int8_t)s->fixedSmp2; #endif @@ -293,14 +319,13 @@ void clearCopyBuffer(void) smpCopyBits = 8; } -uint32_t getSampleMiddleCRate(sampleTyp *s) +int32_t getSampleMiddleCRate(sampleTyp *s) { - double dFTune; - - // replayer is shifting the finetune to the right by 3 - dFTune = (s->fine >> 3) / (128.0 / (double)(1 << 3)); + int32_t realFineTune = (int32_t)s->fine >> 3; // the FT2 replayer is ASR'ing the finetune to the right by 3 + double dFTune = realFineTune * (1.0 / 16.0); // new range is -16..15 - return (uint32_t)round(8363.0 * exp2((s->relTon + dFTune) / 12.0)); + double dFreq = 8363.0 * exp2((s->relTon + dFTune) * (1.0 / 12.0)); + return (int32_t)(dFreq + 0.5); } int32_t getSampleRangeStart(void) @@ -350,7 +375,8 @@ static int32_t smpPos2Scr(int32_t pos) if (pos > s->len) pos = s->len; - dPos = round(pos * dPos2ScrMul) - dScrPosScaled; // rounding is needed here + dPos = (pos * dPos2ScrMul) + 0.5; // rounding is needed here (+ 0.5) + dPos -= dScrPosScaled; // this is important, or else the result can mess up in some cases dPos = CLAMP(dPos, INT32_MIN, INT32_MAX); @@ -477,6 +503,7 @@ static int32_t SDLCALL copySampleThread(void *ptr) bool error; int8_t *p; int16_t destIns, destSmp, sourceIns, sourceSmp; + sampleTyp *src, *dst; (void)ptr; @@ -495,14 +522,19 @@ static int32_t SDLCALL copySampleThread(void *ptr) if (!error) { freeSample(destIns, destSmp); - if (instr[sourceIns] != NULL && instr[sourceIns]->samp[sourceSmp].pek != NULL) + + src = &instr[sourceIns]->samp[sourceSmp]; + dst = &instr[destIns]->samp[destSmp]; + + if (instr[sourceIns] != NULL && src->origPek != NULL) { - p = (int8_t *)malloc(instr[sourceIns]->samp[sourceSmp].len + LOOP_FIX_LEN); + p = (int8_t *)malloc(src->len + LOOP_FIX_LEN); if (p != NULL) { - memcpy(&instr[destIns]->samp[destSmp], &instr[sourceIns]->samp[sourceSmp], sizeof (sampleTyp)); - memcpy(p, instr[sourceIns]->samp[sourceSmp].pek, instr[sourceIns]->samp[sourceSmp].len + LOOP_FIX_LEN); - instr[destIns]->samp[destSmp].pek = p; + memcpy(dst, src, sizeof (sampleTyp)); + memcpy(p, src->origPek, src->len + LOOP_FIX_LEN); + dst->origPek = p; + dst->pek = dst->origPek + SMP_DAT_OFFSET; } else error = true; } @@ -1448,7 +1480,10 @@ static void zoomSampleDataIn(int32_t step, int16_t x) updateViewSize(); tmp32 = (x - (SAMPLE_AREA_WIDTH / 2)) * step; - step += (int32_t)round(tmp32 / (double)(SAMPLE_AREA_WIDTH / 2)); + tmp32 += SAMPLE_AREA_WIDTH/4; // rounding bias + tmp32 /= SAMPLE_AREA_WIDTH/2; + + step += tmp32; newScrPos64 = old_SmpScrPos + step; if (newScrPos64+smpEd_ViewSize > s->len) @@ -1488,7 +1523,10 @@ static void zoomSampleDataOut(int32_t step, int16_t x) else { tmp32 = (x - (SAMPLE_AREA_WIDTH / 2)) * step; - step += (int32_t)round(tmp32 / (double)(SAMPLE_AREA_WIDTH / 2)); + tmp32 += SAMPLE_AREA_WIDTH/4; // rounding bias + tmp32 /= SAMPLE_AREA_WIDTH/2; + + step += tmp32; smpEd_ViewSize = newViewSize64 & 0xFFFFFFFF; @@ -1506,8 +1544,6 @@ static void zoomSampleDataOut(int32_t step, int16_t x) void mouseZoomSampleDataIn(void) { - int32_t step; - if (editor.curInstr == 0 || instr[editor.curInstr] == NULL || instr[editor.curInstr]->samp[editor.curSmp].pek == NULL) @@ -1515,14 +1551,11 @@ void mouseZoomSampleDataIn(void) return; } - step = (int32_t)round(old_ViewSize / 10.0); - zoomSampleDataIn(step, mouse.x); + zoomSampleDataIn((old_ViewSize + 5) / 10, mouse.x); } void mouseZoomSampleDataOut(void) { - int32_t step; - if (editor.curInstr == 0 || instr[editor.curInstr] == NULL || instr[editor.curInstr]->samp[editor.curSmp].pek == NULL) @@ -1530,8 +1563,7 @@ void mouseZoomSampleDataOut(void) return; } - step = (int32_t)round(old_ViewSize / 10.0); - zoomSampleDataOut(step, mouse.x); + zoomSampleDataOut((old_ViewSize + 5) / 10, mouse.x); } void zoomOut(void) @@ -1550,7 +1582,11 @@ void zoomOut(void) if (old_ViewSize == s->len) return; - smpEd_ScrPos = (int32_t)round(old_SmpScrPos - (old_ViewSize / 2.0)); + int32_t tmp32 = old_ViewSize; + tmp32++; // rounding bias + tmp32 >>= 1; + + smpEd_ScrPos = old_SmpScrPos - tmp32; if (smpEd_ScrPos < 0) smpEd_ScrPos = 0; @@ -1665,11 +1701,8 @@ static bool cutRange(bool cropMode, int32_t r1, int32_t r2) { if (!getCopyBuffer(r2 - r1)) { - if (!cropMode) - { - fixSample(s); - resumeAudio(); - } + fixSample(s); + resumeAudio(); okBoxThreadSafe(0, "System message", "Not enough memory!"); return false; @@ -1685,7 +1718,7 @@ static bool cutRange(bool cropMode, int32_t r1, int32_t r2) len = s->len - r2 + r1; if (len > 0) { - newPtr = (int8_t *)realloc(s->pek, len + LOOP_FIX_LEN); + newPtr = (int8_t *)realloc(s->origPek, len + LOOP_FIX_LEN); if (newPtr == NULL) { freeSample(editor.curInstr, editor.curSmp); @@ -1698,7 +1731,9 @@ static bool cutRange(bool cropMode, int32_t r1, int32_t r2) return false; } - s->pek = newPtr; + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; + s->len = len; repE = s->repS + s->repL; @@ -1791,7 +1826,6 @@ void sampCut(void) static int32_t SDLCALL sampCopyThread(void *ptr) { - bool smpMustBeFixed; sampleTyp *s = getCurSample(); (void)ptr; @@ -1804,16 +1838,9 @@ static int32_t SDLCALL sampCopyThread(void *ptr) return true; } - // if smp loop fix is within marked range, we need to restore and fix the sample before copy - smpMustBeFixed = (smpEd_Rx1 >= s->fixedPos) || (smpEd_Rx2 >= s->fixedPos); - - if (smpMustBeFixed) - restoreSample(s); - + restoreSample(s); memcpy(smpCopyBuff, &s->pek[smpEd_Rx1], smpEd_Rx2 - smpEd_Rx1); - - if (smpMustBeFixed) - fixSample(s); + fixSample(s); smpCopyBits = (s->typ & 16) ? 16 : 8; setMouseBusy(false); @@ -1825,7 +1852,7 @@ void sampCopy(void) { sampleTyp *s = getCurSample(); - if (s == NULL || s->pek == NULL || s->len <= 0 || smpEd_Rx2 == 0 || smpEd_Rx2 < smpEd_Rx1) + if (s == NULL || s->origPek == NULL || s->len <= 0 || smpEd_Rx2 == 0 || smpEd_Rx2 < smpEd_Rx1) return; mouseAnimOn(); @@ -1839,57 +1866,107 @@ void sampCopy(void) SDL_DetachThread(thread); } -static int32_t SDLCALL sampPasteThread(void *ptr) +static void pasteOverwrite(sampleTyp *s) { - int8_t *p, *ptr8; - int16_t *ptr16; - int32_t i, l, d, realCopyLen, len32; - sampleTyp *s; - - (void)ptr; - - if (instr[editor.curInstr] == NULL && !allocateInstr(editor.curInstr)) + int8_t *p = (int8_t *)malloc(smpCopySize + LOOP_FIX_LEN); + if (p == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); - return true; + return; } - s = getCurSample(); + pauseAudio(); + + if (s->origPek != NULL) + free(s->origPek); + + memset(s, 0, sizeof (sampleTyp)); + + s->origPek = p; + s->pek = p + SMP_DAT_OFFSET; + + memcpy(s->pek, smpCopyBuff, smpCopySize); + + s->len = smpCopySize; + s->vol = 64; + s->pan = 128; + s->typ = (smpCopyBits == 16) ? 16 : 0; - if (smpEd_Rx2 == 0) // paste without selecting where (overwrite) + fixSample(s); + resumeAudio(); + + editor.updateCurSmp = true; + setSongModifiedFlag(); + setMouseBusy(false); +} + +static void pasteCopiedData(int8_t *pek, int32_t offset, int32_t length, bool smpIs16Bit) +{ + if (smpIs16Bit) { - p = (int8_t *)malloc(smpCopySize + LOOP_FIX_LEN); - if (p == NULL) + // destination sample = 16-bit + + if (smpCopyBits == 16) { - okBoxThreadSafe(0, "System message", "Not enough memory!"); - return true; + // src/dst = equal bits, copy directly + memcpy(&pek[offset], smpCopyBuff, length); } + else + { + // convert copy data to 16-bit then paste + int16_t *ptr16 = (int16_t *)&pek[offset]; + int32_t len32 = length >> 1; - pauseAudio(); + for (int32_t i = 0; i < len32; i++) + ptr16[i] = smpCopyBuff[i] << 8; + } + } + else + { + // destination sample = 8-bit - if (s->pek != NULL) - free(s->pek); + if (smpCopyBits == 8) + { + // src/dst = equal bits, copy directly + memcpy(&pek[offset], smpCopyBuff, length); + } + else + { + // convert copy data to 8-bit then paste + int8_t *ptr8 = (int8_t *)&pek[offset]; + int16_t *ptr16 = (int16_t *)smpCopyBuff; - memset(s, 0, sizeof (sampleTyp)); - memcpy(p, smpCopyBuff, smpCopySize); + for (int32_t i = 0; i < length; i++) + ptr8[i] = ptr16[i] >> 8; + } + } +} - s->pek = p; - s->len = smpCopySize; - s->vol = 64; - s->pan = 128; - s->typ = (smpCopyBits == 16) ? 16 : 0; +static int32_t SDLCALL sampPasteThread(void *ptr) +{ + int8_t *p; + int32_t newLength, realCopyLen; + sampleTyp *s; - fixSample(s); - resumeAudio(); + (void)ptr; - editor.updateCurSmp = true; - setSongModifiedFlag(); - setMouseBusy(false); + if (instr[editor.curInstr] == NULL && !allocateInstr(editor.curInstr)) + { + okBoxThreadSafe(0, "System message", "Not enough memory!"); + return true; + } + + s = getCurSample(); + if (smpEd_Rx2 == 0 || s == NULL || s->pek == NULL) + { + pasteOverwrite(s); return true; } - assert(!(s->typ & 16) || (!(smpEd_Rx1 & 1) && !(smpEd_Rx2 & 1) && !(s->len & 1))); + bool smpIs16Bit = (s->typ >> 4) & 1; + + assert(!smpIs16Bit || (!(smpEd_Rx1 & 1) && !(smpEd_Rx2 & 1) && !(s->len & 1))); if (s->len+smpCopySize > MAX_SAMPLE_LEN) { @@ -1898,144 +1975,91 @@ static int32_t SDLCALL sampPasteThread(void *ptr) } realCopyLen = smpCopySize; - if (s->pek != NULL) - { - if (!(s->typ & 16)) - { - // destination sample is 8-bit - - // copy buffer is 16-bit, divide by 2 - if (smpCopyBits == 16) - { - realCopyLen &= 0xFFFFFFFE; - realCopyLen /= 2; - } - } - else - { - // destination sample is 16-bit - // copy buffer is 8-bit, multiply by 2 - if (smpCopyBits == 8) - realCopyLen *= 2; - } + if (smpIs16Bit) + { + // destination sample is 16-bit - d = realCopyLen - (smpEd_Rx1 - smpEd_Rx2); - l = s->len + realCopyLen - (smpEd_Rx2 - smpEd_Rx1); + if (smpCopyBits == 8) // copy buffer is 8-bit, multiply length by 2 + realCopyLen <<= 1; } else { - // destination sample is empty - d = 0; - l = smpCopySize; + // destination sample is 8-bit + + if (smpCopyBits == 16) // copy buffer is 16-bit, divide length by 2 + realCopyLen >>= 1; } - p = (int8_t *)malloc(l + LOOP_FIX_LEN); + newLength = s->len + realCopyLen - (smpEd_Rx2 - smpEd_Rx1); + if (newLength <= 0) + return true; + + if (newLength > MAX_SAMPLE_LEN) + { + okBoxThreadSafe(0, "System message", "Not enough room in sample!"); + return true; + } + + p = (int8_t *)malloc(newLength + LOOP_FIX_LEN); if (p == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); return true; } + int8_t *newPek = p + SMP_DAT_OFFSET; + pauseAudio(); restoreSample(s); - if (s->pek != NULL) - { - // copy first part of sample (left side before copy part) - memcpy(p, s->pek, smpEd_Rx1); + // paste left part of original sample + if (smpEd_Rx1 > 0) + memcpy(newPek, s->pek, smpEd_Rx1); - if (s->typ & 16) - { - // destination sample = 16-bit + // paste copied data + pasteCopiedData(newPek, smpEd_Rx1, realCopyLen, smpIs16Bit); - if (smpCopyBits == 16) - { - // src/dst = equal bits, copy directly - memcpy(&p[smpEd_Rx1], smpCopyBuff, realCopyLen); - } - else - { - // convert copy data to 16-bit then paste - ptr16 = (int16_t *)&p[smpEd_Rx1]; - len32 = realCopyLen / 2; + // paste right part of original sample + if (smpEd_Rx2 < s->len) + memmove(&newPek[smpEd_Rx1+realCopyLen], &s->pek[smpEd_Rx2], s->len - smpEd_Rx2); - for (i = 0; i < len32; i++) - ptr16[i] = smpCopyBuff[i] << 8; - } - } - else - { - // destination sample = 8-bit + free(s->origPek); - if (smpCopyBits == 8) - { - // src/dst = equal bits, copy directly - memcpy(&p[smpEd_Rx1], smpCopyBuff, realCopyLen); - } - else - { - // convert copy data to 8-bit then paste - ptr8 = (int8_t *)&p[smpEd_Rx1]; - ptr16 = (int16_t *)smpCopyBuff; + // adjust loop points if necessary + if (smpEd_Rx2-smpEd_Rx1 != realCopyLen) + { + int32_t loopAdjust = realCopyLen - (smpEd_Rx1 - smpEd_Rx2); - for (i = 0; i < realCopyLen; i++) - ptr8[i] = ptr16[i] >> 8; - } + if (s->repS > smpEd_Rx2) + { + s->repS += loopAdjust; + s->repL -= loopAdjust; } - // copy remaining data from original sample - memmove(&p[smpEd_Rx1+realCopyLen], &s->pek[smpEd_Rx2], s->len - smpEd_Rx2); - free(s->pek); + if (s->repS+s->repL > smpEd_Rx2) + s->repL += loopAdjust; - // adjust loop points if necessary - if (smpEd_Rx2-smpEd_Rx1 != realCopyLen) + if (s->repS > newLength) { - if (s->repS > smpEd_Rx2) - { - s->repS += d; - s->repL -= d; - } - - if (s->repS+s->repL > smpEd_Rx2) - s->repL += d; - - if (s->repS > l) - { - s->repS = 0; - s->repL = 0; - } - - if (s->repS+s->repL > l) - s->repL = l - s->repS; - - // 2-byte align loop points if smaple is 16-bit - if (s->typ & 16) - { - s->repL &= 0xFFFFFFFE; - s->repS &= 0xFFFFFFFE; - } + s->repS = 0; + s->repL = 0; } - } - else - { - // we pasted to an empty sample - - // copy over copy buffer data - memcpy(p, smpCopyBuff, smpCopySize); - // set new sample bit depth - if (smpCopyBits == 16) - s->typ |= 16; - else - s->typ &= ~16; + if (s->repS+s->repL > newLength) + s->repL = newLength - s->repS; - smpEd_ViewSize = l; - updateViewSize(); + // align loop points if sample is 16-bit + if (smpIs16Bit) + { + s->repL &= 0xFFFFFFFE; + s->repS &= 0xFFFFFFFE; + } } - s->len = l; - s->pek = p; + s->len = newLength; + s->origPek = p; + s->pek = s->origPek + SMP_DAT_OFFSET; fixSample(s); resumeAudio(); @@ -2046,7 +2070,8 @@ static int32_t SDLCALL sampPasteThread(void *ptr) // set new range smpEd_Rx2 = smpEd_Rx1 + realCopyLen; - if (s->typ & 16) + // align sample marking points if sample is 16-bit + if (smpIs16Bit) { smpEd_Rx1 &= 0xFFFFFFFE; smpEd_Rx2 &= 0xFFFFFFFE; @@ -2061,6 +2086,16 @@ void sampPaste(void) if (editor.curInstr == 0 || smpEd_Rx2 < smpEd_Rx1 || smpCopyBuff == NULL || smpCopySize == 0) return; + if (smpEd_Rx2 == 0) // no sample data marked, overwrite sample with copy buffer + { + sampleTyp *s = getCurSample(); + if (s != NULL && s->pek != NULL) + { + if (okBox(2, "System request", "The current sample is not empty. Do you really want to overwrite it?") != 1) + return; + } + } + mouseAnimOn(); thread = SDL_CreateThread(sampPasteThread, NULL, NULL); if (thread == NULL) @@ -2120,7 +2155,7 @@ void sampCrop(void) if (s == NULL || s->pek == NULL || s->len <= 0 || smpEd_Rx1 >= smpEd_Rx2) return; - if (smpEd_Rx1 == 0 && smpEd_Rx2 == s->len) + if (smpEd_Rx1 == 0 && smpEd_Rx2 >= s->len) return; // no need to crop (the whole sample is marked) mouseAnimOn(); @@ -2139,7 +2174,7 @@ void sampXFade(void) bool is16Bit; uint8_t t; int16_t c ,d; - int32_t i, x1, x2, y1, y2, a, b, d1, d2, d3, dist; + int32_t tmp32, i, x1, x2, y1, y2, a, b, d1, d2, d3, dist; double dR, dS1, dS2, dS3, dS4; sampleTyp *s = getCurSample(); @@ -2226,8 +2261,11 @@ void sampXFade(void) dS1 = 1.0 - i / (double)d2; dS2 = 2.0 - dS1; dS3 = 1.0 - i / (double)d3; dS4 = 2.0 - dS3; - c = (int16_t)round((a * dS2 + b * dS1) / (dS1 + dS2)); - d = (int16_t)round((b * dS4 + a * dS3) / (dS3 + dS4)); + tmp32 = (int32_t)round((a * dS2 + b * dS1) / (dS1 + dS2)); + c = (int16_t)tmp32; + + tmp32 = (int32_t)round((b * dS4 + a * dS3) / (dS3 + dS4)); + d = (int16_t)tmp32; if (i < d2) putSampleValueNr(s->pek, t, y1 + dist * (-i - 1), c); if (i < d3) putSampleValueNr(s->pek, t, y1 + dist * i, d); @@ -2282,8 +2320,11 @@ void sampXFade(void) dS1 = 1.0 - i / (double)d2; dS2 = 2.0 - dS1; dS3 = 1.0 - i / (double)d3; dS4 = 2.0 - dS3; - c = (int16_t)round((a * dS2 + b * dS1) / (dS1 + dS2)); - d = (int16_t)round((b * dS4 + a * dS3) / (dS3 + dS4)); + tmp32 = (int32_t)round((a * dS2 + b * dS1) / (dS1 + dS2)); + c = (int16_t)tmp32; + + tmp32 = (int32_t)round((b * dS4 + a * dS3) / (dS3 + dS4)); + d = (int16_t)tmp32; if (i < d2) putSampleValueNr(s->pek, t, y1 - i - dist, c); if (i < d3) putSampleValueNr(s->pek, t, y1 + i, d); @@ -2357,16 +2398,22 @@ void sampXFade(void) dS3 = 1.0 - (1.0 - dR) * i / d2; dS4 = dR * i / d2; - c = (int16_t)round((a * dS3 + b * dS4) / (dS3 + dS4)); - d = (int16_t)round((a * dS2 + b * dS1) / (dS1 + dS2)); + tmp32 = (int32_t)round((a * dS3 + b * dS4) / (dS3 + dS4)); + c = (int16_t)tmp32; + + tmp32 = (int32_t)round((a * dS2 + b * dS1) / (dS1 + dS2)); + d = (int16_t)tmp32; } else { dS3 = 1.0 - (1.0 - dR) * (d1 - i) / d3; dS4 = dR * (d1 - i) / d3; - c = (int16_t)round((a * dS2 + b * dS1) / (dS1 + dS2)); - d = (int16_t)round((a * dS4 + b * dS3) / (dS3 + dS4)); + tmp32 = (int32_t)round((a * dS2 + b * dS1) / (dS1 + dS2)); + c = (int16_t)tmp32; + + tmp32 = (int32_t)round((a * dS4 + b * dS3) / (dS3 + dS4)); + d = (int16_t)tmp32; } putSampleValueNr(s->pek, t, y1 + i, c); @@ -2470,17 +2517,22 @@ static int32_t SDLCALL convSmp8Bit(void *ptr) src16 = (int16_t *)s->pek; dst8 = s->pek; - newLen = s->len / 2; + newLen = s->len >> 1; for (i = 0; i < newLen; i++) dst8[i] = src16[i] >> 8; - newPtr = (int8_t *)realloc(s->pek, newLen + LOOP_FIX_LEN); + assert(s->origPek != NULL); + + newPtr = (int8_t *)realloc(s->origPek, newLen + LOOP_FIX_LEN); if (newPtr != NULL) - s->pek = newPtr; + { + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; + } - s->repL /= 2; - s->repS /= 2; - s->len /= 2; + s->repL >>= 1; + s->repS >>= 1; + s->len >>= 1; s->typ &= ~16; // remove 16-bit flag fixSample(s); @@ -2525,7 +2577,6 @@ void rbSample8bit(void) updateSampleEditorSample(); updateSampleEditor(); - writeSample(true); setSongModifiedFlag(); } } @@ -2542,7 +2593,9 @@ static int32_t SDLCALL convSmp16Bit(void *ptr) pauseAudio(); restoreSample(s); - newPtr = (int8_t *)realloc(s->pek, (s->len * 2) + LOOP_FIX_LEN); + assert(s->origPek != NULL); + + newPtr = (int8_t *)realloc(s->origPek, (s->len * 2) + LOOP_FIX_LEN); if (newPtr == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); @@ -2550,7 +2603,8 @@ static int32_t SDLCALL convSmp16Bit(void *ptr) } else { - s->pek = newPtr; + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; } src8 = s->pek; @@ -2562,9 +2616,9 @@ static int32_t SDLCALL convSmp16Bit(void *ptr) dst16[i] = smp16; } - s->len *= 2; - s->repL *= 2; - s->repS *= 2; + s->len <<= 1; + s->repL <<= 1; + s->repS <<= 1; s->typ |= 16; // add 16-bit flag fixSample(s); @@ -2614,7 +2668,6 @@ void rbSample16bit(void) updateSampleEditorSample(); updateSampleEditor(); - writeSample(true); setSongModifiedFlag(); } } @@ -2642,7 +2695,10 @@ void sampMin(void) if (s == NULL || s->pek == NULL || s->len <= 0) return; - if (!(s->typ & 3) || (s->repS+s->repL >= s->len || s->repS+s->repL <= 0)) + bool hasLoop = s->typ & 3; + int32_t loopEnd = s->repS + s->repL; + + if (!hasLoop || (loopEnd >= s->len || loopEnd == 0)) { okBox(0, "System message", "Sample is already minimized."); } @@ -2650,11 +2706,14 @@ void sampMin(void) { lockMixerCallback(); - s->len = s->repS + s->repL; + s->len = loopEnd; - newPtr = (int8_t *)realloc(s->pek, s->len + LOOP_FIX_LEN); + newPtr = (int8_t *)realloc(s->origPek, s->len + LOOP_FIX_LEN); if (newPtr != NULL) - s->pek = newPtr; + { + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; + } unlockMixerCallback(); @@ -3052,7 +3111,8 @@ static void editSampleData(bool mouseButtonHeld) { int8_t *ptr8; int16_t *ptr16; - int32_t mx, my, tmp32, p, vl, tvl, r, rl, rvl; + int32_t mx, my, tmp32, p, vl, tvl, r, rl, rvl, start, end; + double dVal; sampleTyp *s = getCurSample(); if (s == NULL || s->pek == NULL || s->len <= 0) @@ -3071,7 +3131,7 @@ static void editSampleData(bool mouseButtonHeld) lastDrawX = scr2SmpPos(mx); if (s->typ & 16) - lastDrawX /= 2; + lastDrawX >>= 1; if (my == 250) // center { @@ -3079,8 +3139,10 @@ static void editSampleData(bool mouseButtonHeld) } else { - lastDrawY = (int32_t)round((my - 174) * (256.0 / SAMPLE_AREA_HEIGHT)); - lastDrawY = 255 - CLAMP(lastDrawY, 0, 255); + dVal = (my - 174) * (256.0 / SAMPLE_AREA_HEIGHT); + lastDrawY = (int32_t)(dVal + 0.5); + lastDrawY = CLAMP(lastDrawY, 0, 255); + lastDrawY ^= 0xFF; } lastMouseX = mx; @@ -3099,7 +3161,7 @@ static void editSampleData(bool mouseButtonHeld) { p = scr2SmpPos(mx); if (s->typ & 16) - p /= 2; + p >>= 1; } else { @@ -3114,8 +3176,10 @@ static void editSampleData(bool mouseButtonHeld) } else { - vl = (int32_t)round((my - 174) * (256.0 / SAMPLE_AREA_HEIGHT)); - vl = 255 - CLAMP(vl, 0, 255); + dVal = (my - 174) * (256.0 / SAMPLE_AREA_HEIGHT); + vl = (int32_t)(dVal + 0.5); + vl = CLAMP(vl, 0, 255); + vl ^= 0xFF; } } else @@ -3146,35 +3210,87 @@ static void editSampleData(bool mouseButtonHeld) if (s->typ & 16) { // 16-bit + ptr16 = (int16_t *)s->pek; - for (rl = p; rl <= lastDrawX; rl++) + + start = p; + end = lastDrawX+1; + + if (start < 0) + start = 0; + + tmp32 = s->len >> 1; + if (end > tmp32) + end = tmp32; + + if (p == lastDrawX) { - if (rl >= 0 && rl*2 < s->len) - { - if (p != lastDrawX) - tvl = (vl - lastDrawY) * (rl - p) / (p - lastDrawX) + vl; - else - tvl = vl; + int16_t smpVal = (int16_t)((vl << 8) ^ 0x8000); + for (rl = start; rl < end; rl++) + ptr16[rl] = smpVal; + } + else + { + int32_t y = lastDrawY - vl; + uint32_t x = lastDrawX - p; + + uint32_t xMul = 0xFFFFFFFF; + if (x != 0) + xMul /= x; + int32_t i = 0; + for (rl = start; rl < end; rl++) + { + tvl = y * i; + tvl = ((int64_t)tvl * xMul) >> 32; // tvl /= x; + tvl += vl; tvl <<= 8; - ptr16[rl] = (int16_t)tvl ^ 0x8000; + tvl ^= 0x8000; + + ptr16[rl] = (int16_t)tvl; + i++; } } } else { // 8-bit + ptr8 = s->pek; - for (rl = p; rl <= lastDrawX; rl++) + + start = p; + if (start < 0) + start = 0; + + end = lastDrawX+1; + if (end > s->len) + end = s->len; + + if (p == lastDrawX) + { + int8_t smpVal = (int8_t)(vl ^ 0x80); + for (rl = start; rl < end; rl++) + ptr8[rl] = smpVal; + } + else { - if (rl >= 0 && rl < s->len) + int32_t y = lastDrawY - vl; + uint32_t x = lastDrawX - p; + + uint32_t xMul = 0xFFFFFFFF; + if (x != 0) + xMul /= x; + + int32_t i = 0; + for (rl = start; rl < end; rl++) { - if (p != lastDrawX) - tvl = (vl - lastDrawY) * (rl - p) / (p - lastDrawX) + vl; - else - tvl = vl; + tvl = y * i; + tvl = ((int64_t)tvl * xMul) >> 32; // tvl /= x; + tvl += vl; + tvl ^= 0x80; - ptr8[rl] = (int8_t)tvl ^ 0x80; + ptr8[rl] = (int8_t)tvl; + i++; } } } @@ -3581,12 +3697,13 @@ static int32_t SDLCALL fixDCThread(void *ptr) int8_t *ptr8; int16_t *ptr16; int32_t i, len, smpSub, smp32; - int64_t offset; + int64_t averageDC; sampleTyp *s = getCurSample(); (void)ptr; - offset = 0; + averageDC = 0; + if (s->typ & 16) { if (smpEd_Rx1 >= smpEd_Rx2) @@ -3594,7 +3711,7 @@ static int32_t SDLCALL fixDCThread(void *ptr) assert(!(s->len & 1)); ptr16 = (int16_t *)s->pek; - len = s->len / 2; + len = s->len >> 1; } else { @@ -3602,10 +3719,10 @@ static int32_t SDLCALL fixDCThread(void *ptr) assert(!(smpEd_Rx2 & 1)); ptr16 = (int16_t *)&s->pek[smpEd_Rx1]; - len = (smpEd_Rx2 - smpEd_Rx1) / 2; + len = (smpEd_Rx2 - smpEd_Rx1) >> 1; } - if (len < 0 || len > s->len/2) + if (len < 0 || len > s->len>>1) { setMouseBusy(false); return true; @@ -3615,10 +3732,10 @@ static int32_t SDLCALL fixDCThread(void *ptr) restoreSample(s); for (i = 0; i < len; i++) - offset += ptr16[i]; - offset /= len; + averageDC += ptr16[i]; + averageDC /= len; - smpSub = (int32_t)offset; + smpSub = (int32_t)averageDC; for (i = 0; i < len; i++) { smp32 = ptr16[i] - smpSub; @@ -3652,10 +3769,10 @@ static int32_t SDLCALL fixDCThread(void *ptr) restoreSample(s); for (i = 0; i < len; i++) - offset += ptr8[i]; - offset /= len; + averageDC += ptr8[i]; + averageDC /= len; - smpSub = (int32_t)offset; + smpSub = (int32_t)averageDC; for (i = 0; i < len; i++) { smp32 = ptr8[i] - smpSub; diff --git a/src/ft2_sample_ed.h b/src/ft2_sample_ed.h @@ -12,7 +12,7 @@ void fixSample(sampleTyp *s); // adds wrapped sample after loop/end (for branchl void restoreSample(sampleTyp *s); // reverts wrapped sample after loop/end (for branchless mixer interpolation) void clearSample(void); void clearCopyBuffer(void); -uint32_t getSampleMiddleCRate(sampleTyp *s); +int32_t getSampleMiddleCRate(sampleTyp *s); int32_t getSampleRangeStart(void); int32_t getSampleRangeEnd(void); int32_t getSampleRangeLength(void); diff --git a/src/ft2_sample_ed_features.c b/src/ft2_sample_ed_features.c @@ -1,9 +1,9 @@ /* This file contains the routines for the following sample editor functions: - * - Resampler - * - Echo - * - Mix - * - Volume - */ +** - Resampler +** - Echo +** - Mix +** - Volume +**/ // for finding memory leaks in debug mode with Visual Studio #if defined _DEBUG && defined _MSC_VER @@ -24,8 +24,10 @@ #include "ft2_sample_ed.h" #include "ft2_keyboard.h" +static volatile bool stopThread; + static int8_t smpEd_RelReSmp, mix_Balance = 50; -static bool stopThread, echo_AddMemory, exitFlag, outOfMemory; +static bool echo_AddMemory, exitFlag, outOfMemory; static int16_t vol_StartVol = 100, vol_EndVol = 100, echo_nEcho = 1, echo_VolChange = 30; static int32_t echo_Distance = 0x100; static SDL_Thread *thread; @@ -97,7 +99,7 @@ static int32_t SDLCALL resampleThread(void *ptr) s = &instr[editor.curInstr]->samp[editor.curSmp]; mask = (s->typ & 16) ? 0xFFFFFFFE : 0xFFFFFFFF; - dLenMul = exp2(smpEd_RelReSmp / 12.0); + dLenMul = exp2(smpEd_RelReSmp * (1.0 / 12.0)); dNewLen = s->len * dLenMul; if (dNewLen > (double)MAX_SAMPLE_LEN) @@ -114,6 +116,8 @@ static int32_t SDLCALL resampleThread(void *ptr) return true; } + int8_t *newPtr = p2 + SMP_DAT_OFFSET; + p1 = s->pek; // don't use the potentially clamped newLen value here @@ -129,9 +133,9 @@ static int32_t SDLCALL resampleThread(void *ptr) if (s->typ & 16) { src16 = (int16_t *)p1; - dst16 = (int16_t *)p2; + dst16 = (int16_t *)newPtr; - resampleLen = newLen / 2; + resampleLen = newLen >> 1; for (uint32_t i = 0; i < resampleLen; i++) { dst16[i] = src16[posFrac64 >> 32]; @@ -141,7 +145,7 @@ static int32_t SDLCALL resampleThread(void *ptr) else { src8 = p1; - dst8 = p2; + dst8 = newPtr; for (uint32_t i = 0; i < newLen; i++) { @@ -151,24 +155,30 @@ static int32_t SDLCALL resampleThread(void *ptr) } } - free(p1); + free(s->origPek); s->relTon = CLAMP(s->relTon + smpEd_RelReSmp, -48, 71); - s->len = newLen; - s->pek = p2; - s->repS = (int32_t)(s->repS * dLenMul) & mask; - s->repL = (int32_t)(s->repL * dLenMul) & mask; + s->len = newLen & mask; + + s->origPek = p2; + s->pek = s->origPek + SMP_DAT_OFFSET; + + s->repS = (int32_t)(s->repS * dLenMul); + s->repL = (int32_t)(s->repL * dLenMul); + + s->repS &= mask; + s->repL &= mask; if (s->repS >= s->len) - s->repS = s->len - 1; + s->repS = s->len-1; if (s->repS+s->repL > s->len) s->repL = s->len - s->repS; if (s->typ & 16) { - s->len &= 0xFFFFFFFE; + s->len &= 0xFFFFFFFE; s->repS &= 0xFFFFFFFE; s->repL &= 0xFFFFFFFE; } @@ -229,7 +239,7 @@ static void drawResampleBox(void) s = &instr[editor.curInstr]->samp[editor.curSmp]; mask = (s->typ & 16) ? 0xFFFFFFFE : 0xFFFFFFFF; - dLenMul = exp2(smpEd_RelReSmp / 12.0); + dLenMul = exp2(smpEd_RelReSmp * (1.0 / 12.0)); dNewLen = s->len * dLenMul; if (dNewLen > (double)MAX_SAMPLE_LEN) @@ -428,7 +438,7 @@ static void pbEchoFadeoutUp(void) static int32_t SDLCALL createEchoThread(void *ptr) { - int8_t *readPtr, *writePtr, *newPtr; + int8_t *readPtr, *writePtr, *writePtr8, *newPtr; bool is16Bit; int16_t *readPtr16, *writePtr16; int32_t nEchoes, distance, readLen, writeLen, i, j; @@ -445,24 +455,44 @@ static int32_t SDLCALL createEchoThread(void *ptr) is16Bit = (s->typ & 16) ? true : false; distance = echo_Distance * 16; + // scale value for faster math and suitable rounding for PCM waveforms (DIV -> arithmetic bitshift right) + volChange = (echo_VolChange * 256) / 100; // 0..100 -> 0..256 + + if (echo_nEcho < 1) + { + editor.ui.sysReqShown = false; + return true; + } + // calculate real number of echoes - j = is16Bit ? 32768 : 128; i = 0; + j = 32768; + i = 0; while (i < echo_nEcho && j > 0) { - j = (j * echo_VolChange) / 100; + j = (j * volChange) >> 8; i++; } nEchoes = i + 1; + if (nEchoes < 1) + { + editor.ui.sysReqShown = false; + return true; + } + // set write length (either original length or full echo length) writeLen = readLen; if (echo_AddMemory) { - tmp64 = writeLen + ((int64_t)distance * (nEchoes - 1)); + tmp64 = (int64_t)distance * (nEchoes - 1); + if (is16Bit) + tmp64 <<= 1; + + tmp64 += writeLen; if (tmp64 > MAX_SAMPLE_LEN) - writeLen = MAX_SAMPLE_LEN; - else - writeLen += distance * (nEchoes - 1); + tmp64 = MAX_SAMPLE_LEN; + + writeLen = (int32_t)tmp64; if (is16Bit) writeLen &= 0xFFFFFFFE; @@ -482,18 +512,15 @@ static int32_t SDLCALL createEchoThread(void *ptr) writeIdx = 0; - // scale value for faster math and suitable rounding for PCM waveforms (DIV -> arithmetic bitshift right) - volChange = (int32_t)round((echo_VolChange * 256) / 100.0); - if (volChange > 256) - volChange = 256; - if (is16Bit) { readPtr16 = (int16_t *)readPtr; - writePtr16 = (int16_t *)writePtr; + writePtr16 = (int16_t *)&writePtr[SMP_DAT_OFFSET]; writeLen >>= 1; - while (!stopThread && writeIdx < writeLen) + readLen >>= 1; + + while (writeIdx < writeLen) { smpOut = 0; smpMul = 32768; @@ -501,45 +528,57 @@ static int32_t SDLCALL createEchoThread(void *ptr) echoRead = writeIdx; echoCycle = nEchoes; - while (!stopThread && echoRead > 0 && echoCycle-- > 0) + while (!stopThread) { if (echoRead < readLen) - smpOut += (readPtr16[echoRead] * smpMul) >> (16-1); + smpOut += (readPtr16[echoRead] * smpMul) >> 15; smpMul = (smpMul * volChange) >> 8; + echoRead -= distance; + echoCycle--; + + if (echoRead <= 0 || echoCycle <= 0) + break; } CLAMP16(smpOut); writePtr16[writeIdx++] = (int16_t)smpOut; } + writeLen <<= 1; } else { - while (!stopThread && writeIdx < writeLen) + writePtr8 = writePtr + SMP_DAT_OFFSET; + while (writeIdx < writeLen) { smpOut = 0; - smpMul = 65536; + smpMul = 32768; echoRead = writeIdx; echoCycle = nEchoes; - while (!stopThread && echoRead > 0 && echoCycle-- > 0) + while (!stopThread) { if (echoRead < readLen) - smpOut += (readPtr[echoRead] * smpMul) >> (16-8); + smpOut += (readPtr[echoRead] * smpMul) >> (15-8); smpMul = (smpMul * volChange) >> 8; + echoRead -= distance; + echoCycle--; + + if (echoRead <= 0 || echoCycle <= 0) + break; } CLAMP16(smpOut); - writePtr[writeIdx++] = (int8_t)(smpOut >> 8); + writePtr8[writeIdx++] = (int8_t)(smpOut >> 8); } } - free(readPtr); + free(s->origPek); if (stopThread) { @@ -547,13 +586,25 @@ static int32_t SDLCALL createEchoThread(void *ptr) newPtr = (int8_t *)realloc(writePtr, writeIdx + LOOP_FIX_LEN); if (newPtr != NULL) - s->pek = newPtr; + { + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; + } + else + { + if (writePtr != NULL) + free(writePtr); + + s->origPek = s->pek = NULL; + writeLen = 0; + } editor.updateCurSmp = true; } else { - s->pek = writePtr; + s->origPek = writePtr; + s->pek = s->origPek + SMP_DAT_OFFSET; } if (is16Bit) @@ -893,10 +944,13 @@ static int32_t SDLCALL mixThread(void *ptr) } } - mix8Size = (mixTyp & 16) ? (mixLen / 2) : mixLen; - dest8Size = (destTyp & 16) ? (destLen / 2) : destLen; + bool src16Bits = (mixTyp >> 4) & 1; + bool dst16Bits = (destTyp >> 4) & 1; + + mix8Size = src16Bits ? (mixLen >> 1) : mixLen; + dest8Size = dst16Bits ? (destLen >> 1) : destLen; max8Size = (dest8Size > mix8Size) ? dest8Size : mix8Size; - maxLen = (destTyp & 16) ? (max8Size * 2) : max8Size; + maxLen = dst16Bits ? (max8Size << 1) : max8Size; if (maxLen <= 0) { @@ -925,43 +979,49 @@ static int32_t SDLCALL mixThread(void *ptr) pauseAudio(); restoreSample(&instr[destIns]->samp[destSmp]); + + // restore source sample if (instr[mixIns] != NULL) restoreSample(&instr[mixIns]->samp[mixSmp]); // scale value for faster math and suitable rounding for PCM waveforms (DIV -> arithmetic bitshift right) - mixMul1 = (int32_t)round((mix_Balance * 256) / 100.0); - if (mixMul1 > 256) - mixMul1 = 256; + mixMul1 = (mix_Balance * 256) / 100; mixMul2 = 256 - mixMul1; + int8_t *destPek = p + SMP_DAT_OFFSET; for (i = 0; i < max8Size; i++) { - x1 = (i >= mix8Size) ? 0 : getSampleValueNr(mixPtr, mixTyp, (mixTyp & 16) ? (i << 1) : i); - x2 = (i >= dest8Size) ? 0 : getSampleValueNr(destPtr, destTyp, (destTyp & 16) ? (i << 1) : i); + int32_t index16 = i << 1; - if (!(mixTyp & 16)) x1 <<= 8; - if (!(destTyp & 16)) x2 <<= 8; + x1 = (i >= mix8Size) ? 0 : getSampleValueNr(mixPtr, mixTyp, src16Bits ? index16 : i); + x2 = (i >= dest8Size) ? 0 : getSampleValueNr(destPtr, destTyp, dst16Bits ? index16 : i); - smp32 = (int32_t)((((int64_t)x1 * mixMul1) + ((int64_t)x2 * mixMul2)) >> 8); + if (!src16Bits) x1 <<= 8; + if (!dst16Bits) x2 <<= 8; + + smp32 = ((x1 * mixMul1) >> 8) + ((x2 * mixMul2) >> 8); CLAMP16(smp32); - if (!(destTyp & 16)) + if (!dst16Bits) smp32 >>= 8; - putSampleValueNr(p, destTyp, (destTyp & 16) ? (i << 1) : i, (int16_t)smp32); + putSampleValueNr(destPek, destTyp, dst16Bits ? index16 : i, (int16_t)smp32); } - if (instr[destIns]->samp[destSmp].pek != NULL) - free(instr[destIns]->samp[destSmp].pek); + if (instr[destIns]->samp[destSmp].origPek != NULL) + free(instr[destIns]->samp[destSmp].origPek); - instr[destIns]->samp[destSmp].pek = p; + instr[destIns]->samp[destSmp].origPek = p; + instr[destIns]->samp[destSmp].pek = instr[destIns]->samp[destSmp].origPek + SMP_DAT_OFFSET; instr[destIns]->samp[destSmp].len = maxLen; instr[destIns]->samp[destSmp].typ = destTyp; - if (destTyp & 16) // bugfix + if (dst16Bits) instr[destIns]->samp[destSmp].len &= 0xFFFFFFFE; fixSample(&instr[destIns]->samp[destSmp]); + + // fix source sample if (instr[mixIns] != NULL) fixSample(&instr[mixIns]->samp[mixSmp]); diff --git a/src/ft2_sample_loader.c b/src/ft2_sample_loader.c @@ -16,7 +16,8 @@ #include "ft2_diskop.h" /* All of these routines were written from scratch and were not present -** in original FT2. */ +** in original FT2. +*/ enum { @@ -40,9 +41,10 @@ static void normalize64bitDoubleSigned(double *dSampleData, uint32_t sampleLengt void freeTmpSample(sampleTyp *s) { - if (s->pek != NULL) + if (s->origPek != NULL) { - free(s->pek); + free(s->origPek); + s->origPek = NULL; s->pek = NULL; } @@ -70,7 +72,7 @@ static int32_t getAIFFRate(uint8_t *in) exp -= 16383; dOut = ldexp(lo, -31 + exp) + ldexp(hi, -63 + exp); - return (int32_t)round(dOut); + return (int32_t)(dOut + 0.5); } static bool aiffIsStereo(FILE *f) // only ran on files that are confirmed to be AIFFs @@ -98,7 +100,7 @@ static bool aiffIsStereo(FILE *f) // only ran on files that are confirmed to be bytesRead = 0; while (!feof(f) && bytesRead < filesize-12) { - fread(&chunkID, 4, 1, f); chunkID = SWAP32(chunkID); if (feof(f)) break; + fread(&chunkID, 4, 1, f); chunkID = SWAP32(chunkID); if (feof(f)) break; fread(&chunkSize, 4, 1, f); chunkSize = SWAP32(chunkSize); if (feof(f)) break; endOfChunk = (ftell(f) + chunkSize) + (chunkSize & 1); @@ -341,13 +343,15 @@ static int32_t SDLCALL loadAIFFSample(void *ptr) { // 8-BIT SIGNED PCM - tmpSmp.pek = (int8_t *)malloc(sampleLength); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc(sampleLength + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto aiffLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(tmpSmp.pek, sampleLength, 1, f) != 1) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -402,13 +406,15 @@ static int32_t SDLCALL loadAIFFSample(void *ptr) sampleLength /= 2; - tmpSmp.pek = (int8_t *)malloc(sampleLength * 2); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc((sampleLength * 2) + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto aiffLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(tmpSmp.pek, sampleLength, 2, f) != 2) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -469,13 +475,15 @@ static int32_t SDLCALL loadAIFFSample(void *ptr) sampleLength /= 3; - tmpSmp.pek = (int8_t *)malloc((sampleLength * 4) * 2); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc(((sampleLength * 4) * 2) + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto aiffLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(&tmpSmp.pek[sampleLength], sampleLength, 3, f) != 3) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -557,13 +565,15 @@ static int32_t SDLCALL loadAIFFSample(void *ptr) sampleLength /= 4; - tmpSmp.pek = (int8_t *)malloc(sampleLength * 4); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc((sampleLength * 4) + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto aiffLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(tmpSmp.pek, sampleLength, 4, f) != 4) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -636,9 +646,12 @@ static int32_t SDLCALL loadAIFFSample(void *ptr) } // adjust memory needed - newPtr = (int8_t *)realloc(tmpSmp.pek, sampleLength + LOOP_FIX_LEN); + newPtr = (int8_t *)realloc(tmpSmp.origPek, sampleLength + LOOP_FIX_LEN); if (newPtr != NULL) - tmpSmp.pek = newPtr; + { + tmpSmp.origPek = newPtr; + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + } // set sample attributes tmpSmp.len = sampleLength; @@ -714,7 +727,7 @@ static int32_t SDLCALL loadAIFFSample(void *ptr) aiffLoadError: if (f != NULL) fclose(f); - if (tmpSmp.pek != NULL) free(tmpSmp.pek); + if (tmpSmp.origPek != NULL) free(tmpSmp.origPek); stereoSampleLoadMode = -1; sampleIsLoading = false; @@ -741,7 +754,6 @@ static int32_t SDLCALL loadIFFSample(void *ptr) f = NULL; memset(&tmpSmp, 0, sizeof (tmpSmp)); - if (editor.tmpFilenameU == NULL) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -848,7 +860,7 @@ static int32_t SDLCALL loadIFFSample(void *ptr) if (sampleVol > 65535) sampleVol = 65535; - sampleVol = (uint32_t)round(sampleVol / 1024.0); + sampleVol = (int32_t)((sampleVol / 1024.0) + 0.5); if (sampleVol > 64) sampleVol = 64; @@ -870,20 +882,22 @@ static int32_t SDLCALL loadIFFSample(void *ptr) if (sampleLoopStart > sampleLength-2) { - sampleLoopStart = 0; + sampleLoopStart = 0; sampleLoopLength = 0; } tmpSmp.pan = 128; tmpSmp.vol = 64; - tmpSmp.pek = (int8_t *)malloc(sampleLength + LOOP_FIX_LEN); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc(sampleLength + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto iffLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + fseek(f, bodyPtr, SEEK_SET); if (fread(tmpSmp.pek, sampleLength, 1, f) != 1) { @@ -999,7 +1013,7 @@ static int32_t SDLCALL loadIFFSample(void *ptr) iffLoadError: if (f != NULL) fclose(f); - if (tmpSmp.pek != NULL) free(tmpSmp.pek); + if (tmpSmp.origPek != NULL) free(tmpSmp.origPek); stereoSampleLoadMode = -1; sampleIsLoading = false; @@ -1053,13 +1067,15 @@ static int32_t SDLCALL loadRawSample(void *ptr) tmpSmp.pan = 128; tmpSmp.vol = 64; - tmpSmp.pek = (int8_t *)malloc(filesize + LOOP_FIX_LEN); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc(filesize + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto rawLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(tmpSmp.pek, filesize, 1, f) != 1) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -1136,7 +1152,7 @@ static int32_t SDLCALL loadRawSample(void *ptr) rawLoadError: if (f != NULL) fclose(f); - if (tmpSmp.pek != NULL) free(tmpSmp.pek); + if (tmpSmp.origPek != NULL) free(tmpSmp.origPek); stereoSampleLoadMode = -1; sampleIsLoading = false; @@ -1169,7 +1185,7 @@ static int32_t SDLCALL loadWAVSample(void *ptr) memset(&tmpSmp, 0, sizeof (tmpSmp)); // zero out chunk pointers and lengths - fmtPtr = 0; fmtLen = 0; + fmtPtr = 0; fmtLen = 0; dataPtr = 0; dataLen = 0; inamPtr = 0; inamLen = 0; xtraPtr = 0; xtraLen = 0; @@ -1339,13 +1355,15 @@ static int32_t SDLCALL loadWAVSample(void *ptr) if (bitsPerSample == 8) // 8-BIT INTEGER SAMPLE { - tmpSmp.pek = (int8_t *)malloc(sampleLength); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc(sampleLength + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto wavLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(tmpSmp.pek, sampleLength, 1, f) != 1) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -1403,13 +1421,15 @@ static int32_t SDLCALL loadWAVSample(void *ptr) { sampleLength /= 2; - tmpSmp.pek = (int8_t *)malloc(sampleLength * 2); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc((sampleLength * 2) + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto wavLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(tmpSmp.pek, sampleLength, 2, f) != 2) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -1468,13 +1488,15 @@ static int32_t SDLCALL loadWAVSample(void *ptr) { sampleLength /= 3; - tmpSmp.pek = (int8_t *)malloc((sampleLength * 4) * 2); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc(((sampleLength * 4) * 2) + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto wavLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(&tmpSmp.pek[sampleLength], sampleLength, 3, f) != 3) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -1556,13 +1578,15 @@ static int32_t SDLCALL loadWAVSample(void *ptr) { sampleLength /= 4; - tmpSmp.pek = (int8_t *)malloc((sampleLength * 4) + LOOP_FIX_LEN); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc((sampleLength * 4) + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto wavLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(tmpSmp.pek, sampleLength, 4, f) != 4) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -1636,13 +1660,15 @@ static int32_t SDLCALL loadWAVSample(void *ptr) { sampleLength /= 4; - tmpSmp.pek = (int8_t *)malloc((sampleLength * 4) + LOOP_FIX_LEN); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc((sampleLength * 4) + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto wavLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(tmpSmp.pek, sampleLength, 4, f) != 4) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -1703,13 +1729,15 @@ static int32_t SDLCALL loadWAVSample(void *ptr) { sampleLength /= 8; - tmpSmp.pek = (int8_t *)malloc((sampleLength * 8) + LOOP_FIX_LEN); - if (tmpSmp.pek == NULL) + tmpSmp.origPek = (int8_t *)malloc((sampleLength * 8) + LOOP_FIX_LEN); + if (tmpSmp.origPek == NULL) { okBoxThreadSafe(0, "System message", "Not enough memory!"); goto wavLoadError; } + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + if (fread(tmpSmp.pek, sampleLength, 8, f) != 8) { okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?"); @@ -1768,9 +1796,12 @@ static int32_t SDLCALL loadWAVSample(void *ptr) } // adjust memory needed - newPtr = (int8_t *)realloc(tmpSmp.pek, sampleLength + LOOP_FIX_LEN); + newPtr = (int8_t *)realloc(tmpSmp.origPek, sampleLength + LOOP_FIX_LEN); if (newPtr != NULL) - tmpSmp.pek = newPtr; + { + tmpSmp.origPek = newPtr; + tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET; + } tuneSample(&tmpSmp, sampleRate); @@ -1788,9 +1819,9 @@ static int32_t SDLCALL loadWAVSample(void *ptr) { fseek(f, 4 + 4, SEEK_CUR); // skip "samplerData" and "identifier" - fread(&loopType, 4, 1, f); + fread(&loopType, 4, 1, f); fread(&loopStart, 4, 1, f); - fread(&loopEnd, 4, 1, f); + fread(&loopEnd, 4, 1, f); loopEnd++; @@ -1929,7 +1960,7 @@ static int32_t SDLCALL loadWAVSample(void *ptr) wavLoadError: if (f != NULL) fclose(f); - if (tmpSmp.pek != NULL) free(tmpSmp.pek); + if (tmpSmp.origPek != NULL) free(tmpSmp.origPek); stereoSampleLoadMode = -1; sampleIsLoading = false; diff --git a/src/ft2_sampling.c b/src/ft2_sampling.c @@ -37,7 +37,7 @@ static void SDLCALL samplingCallback(void *userdata, Uint8 *stream, int len) s = &instr[editor.curInstr]->samp[editor.curSmp]; - newPtr = (int8_t *)realloc(s->pek, s->len + len); + newPtr = (int8_t *)realloc(s->origPek, (s->len + len) + LOOP_FIX_LEN); if (newPtr == NULL) { drawSamplingBufferFlag = false; @@ -45,7 +45,9 @@ static void SDLCALL samplingCallback(void *userdata, Uint8 *stream, int len) return; } - s->pek = newPtr; + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; + memcpy(&s->pek[s->len], stream, len); s->len += len; @@ -103,15 +105,16 @@ void stopSampling(void) { nextSmp = &instr[editor.curInstr]->samp[rightChSmpSlot]; - nextSmp->pek = (int8_t *)malloc((currSmp->len / 2) + LOOP_FIX_LEN); - if (nextSmp->pek != NULL) + nextSmp->origPek = (int8_t *)malloc((currSmp->len >> 1) + LOOP_FIX_LEN); + if (nextSmp->origPek != NULL) { - nextSmp->len = currSmp->len / 2; + nextSmp->pek = nextSmp->origPek + SMP_DAT_OFFSET; + nextSmp->len = currSmp->len >> 1; src16 = (int16_t *)currSmp->pek; dst16 = (int16_t *)nextSmp->pek; - len = nextSmp->len / 2; + len = nextSmp->len >> 1; for (i = 0; i < len; i++) dst16[i] = src16[(i << 1) + 1]; } @@ -120,29 +123,37 @@ void stopSampling(void) freeSample(editor.curInstr, rightChSmpSlot); } - currSmp->len /= 2; + currSmp->len >>= 1; // read left channel data by skipping every other sample dst16 = (int16_t *)currSmp->pek; - len = currSmp->len / 2; + len = currSmp->len >> 1; for (i = 0; i < len; i++) dst16[i] = dst16[i << 1]; } } - if (currSmp->pek != NULL) + if (currSmp->origPek != NULL) { - newPtr = (int8_t *)realloc(currSmp->pek, currSmp->len + LOOP_FIX_LEN); + newPtr = (int8_t *)realloc(currSmp->origPek, currSmp->len + LOOP_FIX_LEN); if (newPtr != NULL) - currSmp->pek = newPtr; + { + currSmp->origPek = newPtr; + currSmp->pek = currSmp->origPek + SMP_DAT_OFFSET; + } + + fixSample(currSmp); } else { freeSample(editor.curInstr, editor.curSmp); } + if (nextSmp != NULL && nextSmp->origPek != NULL) + fixSample(nextSmp); + updateSampleEditorSample(); editor.updateCurInstr = true; } diff --git a/src/ft2_scopedraw.c b/src/ft2_scopedraw.c @@ -1,6 +1,7 @@ #include "ft2_scopes.h" #include "ft2_scopedraw.h" #include "ft2_video.h" +#include "ft2_palette.h" /* ----------------------------------------------------------------------- */ /* SCOPE DRAWING MACROS */ diff --git a/src/ft2_scopes.c b/src/ft2_scopes.c @@ -20,6 +20,7 @@ #include "ft2_mouse.h" #include "ft2_video.h" #include "ft2_scopedraw.h" +#include "ft2_tables.h" enum { @@ -46,50 +47,6 @@ static SDL_Thread *scopeThread; lastChInstr_t lastChInstr[MAX_VOICES]; // global -static const uint8_t scopeMuteBMPWidths[16] = -{ - 162,111, 76, 56, 42, 35, 28, 24, - 21, 21, 17, 17, 12, 12, 9, 9 -}; - -static const uint8_t scopeMuteBMPHeights[16] = -{ - 27, 27, 26, 25, 25, 25, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24 -}; - -static const uint8_t *scopeMuteBMPPointers[16] = -{ - scopeMuteBMP1, scopeMuteBMP2, scopeMuteBMP3, scopeMuteBMP4, - scopeMuteBMP5, scopeMuteBMP6, scopeMuteBMP7, scopeMuteBMP8, - scopeMuteBMP9, scopeMuteBMP9, scopeMuteBMP10,scopeMuteBMP10, - scopeMuteBMP11,scopeMuteBMP11,scopeMuteBMP12,scopeMuteBMP12 -}; - -static const uint16_t scopeLenTab[16][32] = -{ - /* 2 ch */ {285,285}, - /* 4 ch */ {141,141,141,141}, - /* 6 ch */ {93,93,93,93,93,93}, - /* 8 ch */ {69,69,69,69,69,69,69,69}, - /* 10 ch */ {55,55,55,54,54,55,55,55,54,54}, - /* 12 ch */ {45,45,45,45,45,45,45,45,45,45,45,45}, - /* 14 ch */ {39,38,38,38,38,38,38,39,38,38,38,38,38,38}, - /* 16 ch */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33}, - /* 18 ch */ {29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29}, - /* 20 ch */ {26,26,26,26,26,26,26,26,25,25,26,26,26,26,26,26,26,26,25,25}, - /* 22 ch */ {24,24,23,23,23,23,23,23,23,23,23,24,24,23,23,23,23,23,23,23,23,23}, - /* 24 ch */ {21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21}, - /* 26 ch */ {20,20,19,19,19,19,19,19,19,19,19,19,19,20,20,19,19,19,19,19,19,19,19,19,19,19}, - /* 28 ch */ {18,18,18,18,18,18,18,18,17,17,17,17,17,17,18,18,18,18,18,18,18,18,17,17,17,17,17,17}, - /* 30 ch */ {17,17,17,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,16,16,16,16,16,16,16,16,16,16,16,16}, - /* 32 ch */ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15} -}; - -// ft2_pattern_draw.c -extern const char chDecTab1[MAX_VOICES+1]; -extern char chDecTab2[MAX_VOICES+1]; - void resetOldScopeRates(void) { oldVoiceDelta = 0; diff --git a/src/ft2_tables.c b/src/ft2_tables.c @@ -0,0 +1,1121 @@ +#include <stdint.h> +#include <stdbool.h> +#include "ft2_palette.h" // pal16 typedef +#include "ft2_pattern_ed.h" // pattCoord_t/pattCoord2_t/pattCoordsMouse_t/markCoord_t typedef +#include "ft2_header.h" // MAX_VOICES +#include "ft2_config.h" // CONFIG_FILE_SIZE +#include "ft2_gfxdata.h" + +/* ----------------------------------------------------------------------- */ +/* REPLAYER TABLES */ +/* ----------------------------------------------------------------------- */ + +const int8_t vibSineTab[256] = // for auto-vibrato +{ + 0, -2, -3, -5, -6, -8, -9, -11, -12, -14, -16, -17, -19, -20, -22, -23, + -24, -26, -27, -29, -30, -32, -33, -34, -36, -37, -38, -39, -41, -42, -43, -44, + -45, -46, -47, -48, -49, -50, -51, -52, -53, -54, -55, -56, -56, -57, -58, -59, + -59, -60, -60, -61, -61, -62, -62, -62, -63, -63, -63, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -63, -63, -63, -62, -62, -62, -61, -61, -60, -60, + -59, -59, -58, -57, -56, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, + -45, -44, -43, -42, -41, -39, -38, -37, -36, -34, -33, -32, -30, -29, -27, -26, + -24, -23, -22, -20, -19, -17, -16, -14, -12, -11, -9, -8, -6, -5, -3, -2, + 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23, + 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, + 59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60, + 59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26, + 24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2 +}; + +const uint8_t vibTab[32] = +{ + 0, 24, 49, 74, 97,120,141,161,180,197,212,224,235,244,250,253, + 255,253,250,244,235,224,212,197,180,161,141,120, 97, 74, 49, 24 +}; + +const uint16_t amigaPeriod[12 * 8] = +{ + 6848, 6464, 6096, 5760, 5424, 5120, 4832, 4560, 4304, 4064, 3840, 3624, + 3424, 3232, 3048, 2880, 2712, 2560, 2416, 2280, 2152, 2032, 1920, 1812, + 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 906, + 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453, + 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226, + 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113, + 107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56, + 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28 +}; + +const uint16_t amigaFinePeriod[12 * 8] = +{ + 907, 900, 894, 887, 881, 875, 868, 862, 856, 850, 844, 838, + 832, 826, 820, 814, 808, 802, 796, 791, 785, 779, 774, 768, + 762, 757, 752, 746, 741, 736, 730, 725, 720, 715, 709, 704, + 699, 694, 689, 684, 678, 675, 670, 665, 660, 655, 651, 646, + 640, 636, 632, 628, 623, 619, 614, 610, 604, 601, 597, 592, + 588, 584, 580, 575, 570, 567, 563, 559, 555, 551, 547, 543, + 538, 535, 532, 528, 524, 520, 516, 513, 508, 505, 502, 498, + 494, 491, 487, 484, 480, 477, 474, 470, 467, 463, 460, 457 +}; + +const int16_t linearPeriods[1936] = // bit-exact to FT2 table +{ + 7744, 7740, 7736, 7732, 7728, 7724, 7720, 7716, 7712, 7708, 7704, 7700, 7696, 7692, 7688, 7684, + 7680, 7676, 7672, 7668, 7664, 7660, 7656, 7652, 7648, 7644, 7640, 7636, 7632, 7628, 7624, 7620, + 7616, 7612, 7608, 7604, 7600, 7596, 7592, 7588, 7584, 7580, 7576, 7572, 7568, 7564, 7560, 7556, + 7552, 7548, 7544, 7540, 7536, 7532, 7528, 7524, 7520, 7516, 7512, 7508, 7504, 7500, 7496, 7492, + 7488, 7484, 7480, 7476, 7472, 7468, 7464, 7460, 7456, 7452, 7448, 7444, 7440, 7436, 7432, 7428, + 7424, 7420, 7416, 7412, 7408, 7404, 7400, 7396, 7392, 7388, 7384, 7380, 7376, 7372, 7368, 7364, + 7360, 7356, 7352, 7348, 7344, 7340, 7336, 7332, 7328, 7324, 7320, 7316, 7312, 7308, 7304, 7300, + 7296, 7292, 7288, 7284, 7280, 7276, 7272, 7268, 7264, 7260, 7256, 7252, 7248, 7244, 7240, 7236, + 7232, 7228, 7224, 7220, 7216, 7212, 7208, 7204, 7200, 7196, 7192, 7188, 7184, 7180, 7176, 7172, + 7168, 7164, 7160, 7156, 7152, 7148, 7144, 7140, 7136, 7132, 7128, 7124, 7120, 7116, 7112, 7108, + 7104, 7100, 7096, 7092, 7088, 7084, 7080, 7076, 7072, 7068, 7064, 7060, 7056, 7052, 7048, 7044, + 7040, 7036, 7032, 7028, 7024, 7020, 7016, 7012, 7008, 7004, 7000, 6996, 6992, 6988, 6984, 6980, + 6976, 6972, 6968, 6964, 6960, 6956, 6952, 6948, 6944, 6940, 6936, 6932, 6928, 6924, 6920, 6916, + 6912, 6908, 6904, 6900, 6896, 6892, 6888, 6884, 6880, 6876, 6872, 6868, 6864, 6860, 6856, 6852, + 6848, 6844, 6840, 6836, 6832, 6828, 6824, 6820, 6816, 6812, 6808, 6804, 6800, 6796, 6792, 6788, + 6784, 6780, 6776, 6772, 6768, 6764, 6760, 6756, 6752, 6748, 6744, 6740, 6736, 6732, 6728, 6724, + 6720, 6716, 6712, 6708, 6704, 6700, 6696, 6692, 6688, 6684, 6680, 6676, 6672, 6668, 6664, 6660, + 6656, 6652, 6648, 6644, 6640, 6636, 6632, 6628, 6624, 6620, 6616, 6612, 6608, 6604, 6600, 6596, + 6592, 6588, 6584, 6580, 6576, 6572, 6568, 6564, 6560, 6556, 6552, 6548, 6544, 6540, 6536, 6532, + 6528, 6524, 6520, 6516, 6512, 6508, 6504, 6500, 6496, 6492, 6488, 6484, 6480, 6476, 6472, 6468, + 6464, 6460, 6456, 6452, 6448, 6444, 6440, 6436, 6432, 6428, 6424, 6420, 6416, 6412, 6408, 6404, + 6400, 6396, 6392, 6388, 6384, 6380, 6376, 6372, 6368, 6364, 6360, 6356, 6352, 6348, 6344, 6340, + 6336, 6332, 6328, 6324, 6320, 6316, 6312, 6308, 6304, 6300, 6296, 6292, 6288, 6284, 6280, 6276, + 6272, 6268, 6264, 6260, 6256, 6252, 6248, 6244, 6240, 6236, 6232, 6228, 6224, 6220, 6216, 6212, + 6208, 6204, 6200, 6196, 6192, 6188, 6184, 6180, 6176, 6172, 6168, 6164, 6160, 6156, 6152, 6148, + 6144, 6140, 6136, 6132, 6128, 6124, 6120, 6116, 6112, 6108, 6104, 6100, 6096, 6092, 6088, 6084, + 6080, 6076, 6072, 6068, 6064, 6060, 6056, 6052, 6048, 6044, 6040, 6036, 6032, 6028, 6024, 6020, + 6016, 6012, 6008, 6004, 6000, 5996, 5992, 5988, 5984, 5980, 5976, 5972, 5968, 5964, 5960, 5956, + 5952, 5948, 5944, 5940, 5936, 5932, 5928, 5924, 5920, 5916, 5912, 5908, 5904, 5900, 5896, 5892, + 5888, 5884, 5880, 5876, 5872, 5868, 5864, 5860, 5856, 5852, 5848, 5844, 5840, 5836, 5832, 5828, + 5824, 5820, 5816, 5812, 5808, 5804, 5800, 5796, 5792, 5788, 5784, 5780, 5776, 5772, 5768, 5764, + 5760, 5756, 5752, 5748, 5744, 5740, 5736, 5732, 5728, 5724, 5720, 5716, 5712, 5708, 5704, 5700, + 5696, 5692, 5688, 5684, 5680, 5676, 5672, 5668, 5664, 5660, 5656, 5652, 5648, 5644, 5640, 5636, + 5632, 5628, 5624, 5620, 5616, 5612, 5608, 5604, 5600, 5596, 5592, 5588, 5584, 5580, 5576, 5572, + 5568, 5564, 5560, 5556, 5552, 5548, 5544, 5540, 5536, 5532, 5528, 5524, 5520, 5516, 5512, 5508, + 5504, 5500, 5496, 5492, 5488, 5484, 5480, 5476, 5472, 5468, 5464, 5460, 5456, 5452, 5448, 5444, + 5440, 5436, 5432, 5428, 5424, 5420, 5416, 5412, 5408, 5404, 5400, 5396, 5392, 5388, 5384, 5380, + 5376, 5372, 5368, 5364, 5360, 5356, 5352, 5348, 5344, 5340, 5336, 5332, 5328, 5324, 5320, 5316, + 5312, 5308, 5304, 5300, 5296, 5292, 5288, 5284, 5280, 5276, 5272, 5268, 5264, 5260, 5256, 5252, + 5248, 5244, 5240, 5236, 5232, 5228, 5224, 5220, 5216, 5212, 5208, 5204, 5200, 5196, 5192, 5188, + 5184, 5180, 5176, 5172, 5168, 5164, 5160, 5156, 5152, 5148, 5144, 5140, 5136, 5132, 5128, 5124, + 5120, 5116, 5112, 5108, 5104, 5100, 5096, 5092, 5088, 5084, 5080, 5076, 5072, 5068, 5064, 5060, + 5056, 5052, 5048, 5044, 5040, 5036, 5032, 5028, 5024, 5020, 5016, 5012, 5008, 5004, 5000, 4996, + 4992, 4988, 4984, 4980, 4976, 4972, 4968, 4964, 4960, 4956, 4952, 4948, 4944, 4940, 4936, 4932, + 4928, 4924, 4920, 4916, 4912, 4908, 4904, 4900, 4896, 4892, 4888, 4884, 4880, 4876, 4872, 4868, + 4864, 4860, 4856, 4852, 4848, 4844, 4840, 4836, 4832, 4828, 4824, 4820, 4816, 4812, 4808, 4804, + 4800, 4796, 4792, 4788, 4784, 4780, 4776, 4772, 4768, 4764, 4760, 4756, 4752, 4748, 4744, 4740, + 4736, 4732, 4728, 4724, 4720, 4716, 4712, 4708, 4704, 4700, 4696, 4692, 4688, 4684, 4680, 4676, + 4672, 4668, 4664, 4660, 4656, 4652, 4648, 4644, 4640, 4636, 4632, 4628, 4624, 4620, 4616, 4612, + 4608, 4604, 4600, 4596, 4592, 4588, 4584, 4580, 4576, 4572, 4568, 4564, 4560, 4556, 4552, 4548, + 4544, 4540, 4536, 4532, 4528, 4524, 4520, 4516, 4512, 4508, 4504, 4500, 4496, 4492, 4488, 4484, + 4480, 4476, 4472, 4468, 4464, 4460, 4456, 4452, 4448, 4444, 4440, 4436, 4432, 4428, 4424, 4420, + 4416, 4412, 4408, 4404, 4400, 4396, 4392, 4388, 4384, 4380, 4376, 4372, 4368, 4364, 4360, 4356, + 4352, 4348, 4344, 4340, 4336, 4332, 4328, 4324, 4320, 4316, 4312, 4308, 4304, 4300, 4296, 4292, + 4288, 4284, 4280, 4276, 4272, 4268, 4264, 4260, 4256, 4252, 4248, 4244, 4240, 4236, 4232, 4228, + 4224, 4220, 4216, 4212, 4208, 4204, 4200, 4196, 4192, 4188, 4184, 4180, 4176, 4172, 4168, 4164, + 4160, 4156, 4152, 4148, 4144, 4140, 4136, 4132, 4128, 4124, 4120, 4116, 4112, 4108, 4104, 4100, + 4096, 4092, 4088, 4084, 4080, 4076, 4072, 4068, 4064, 4060, 4056, 4052, 4048, 4044, 4040, 4036, + 4032, 4028, 4024, 4020, 4016, 4012, 4008, 4004, 4000, 3996, 3992, 3988, 3984, 3980, 3976, 3972, + 3968, 3964, 3960, 3956, 3952, 3948, 3944, 3940, 3936, 3932, 3928, 3924, 3920, 3916, 3912, 3908, + 3904, 3900, 3896, 3892, 3888, 3884, 3880, 3876, 3872, 3868, 3864, 3860, 3856, 3852, 3848, 3844, + 3840, 3836, 3832, 3828, 3824, 3820, 3816, 3812, 3808, 3804, 3800, 3796, 3792, 3788, 3784, 3780, + 3776, 3772, 3768, 3764, 3760, 3756, 3752, 3748, 3744, 3740, 3736, 3732, 3728, 3724, 3720, 3716, + 3712, 3708, 3704, 3700, 3696, 3692, 3688, 3684, 3680, 3676, 3672, 3668, 3664, 3660, 3656, 3652, + 3648, 3644, 3640, 3636, 3632, 3628, 3624, 3620, 3616, 3612, 3608, 3604, 3600, 3596, 3592, 3588, + 3584, 3580, 3576, 3572, 3568, 3564, 3560, 3556, 3552, 3548, 3544, 3540, 3536, 3532, 3528, 3524, + 3520, 3516, 3512, 3508, 3504, 3500, 3496, 3492, 3488, 3484, 3480, 3476, 3472, 3468, 3464, 3460, + 3456, 3452, 3448, 3444, 3440, 3436, 3432, 3428, 3424, 3420, 3416, 3412, 3408, 3404, 3400, 3396, + 3392, 3388, 3384, 3380, 3376, 3372, 3368, 3364, 3360, 3356, 3352, 3348, 3344, 3340, 3336, 3332, + 3328, 3324, 3320, 3316, 3312, 3308, 3304, 3300, 3296, 3292, 3288, 3284, 3280, 3276, 3272, 3268, + 3264, 3260, 3256, 3252, 3248, 3244, 3240, 3236, 3232, 3228, 3224, 3220, 3216, 3212, 3208, 3204, + 3200, 3196, 3192, 3188, 3184, 3180, 3176, 3172, 3168, 3164, 3160, 3156, 3152, 3148, 3144, 3140, + 3136, 3132, 3128, 3124, 3120, 3116, 3112, 3108, 3104, 3100, 3096, 3092, 3088, 3084, 3080, 3076, + 3072, 3068, 3064, 3060, 3056, 3052, 3048, 3044, 3040, 3036, 3032, 3028, 3024, 3020, 3016, 3012, + 3008, 3004, 3000, 2996, 2992, 2988, 2984, 2980, 2976, 2972, 2968, 2964, 2960, 2956, 2952, 2948, + 2944, 2940, 2936, 2932, 2928, 2924, 2920, 2916, 2912, 2908, 2904, 2900, 2896, 2892, 2888, 2884, + 2880, 2876, 2872, 2868, 2864, 2860, 2856, 2852, 2848, 2844, 2840, 2836, 2832, 2828, 2824, 2820, + 2816, 2812, 2808, 2804, 2800, 2796, 2792, 2788, 2784, 2780, 2776, 2772, 2768, 2764, 2760, 2756, + 2752, 2748, 2744, 2740, 2736, 2732, 2728, 2724, 2720, 2716, 2712, 2708, 2704, 2700, 2696, 2692, + 2688, 2684, 2680, 2676, 2672, 2668, 2664, 2660, 2656, 2652, 2648, 2644, 2640, 2636, 2632, 2628, + 2624, 2620, 2616, 2612, 2608, 2604, 2600, 2596, 2592, 2588, 2584, 2580, 2576, 2572, 2568, 2564, + 2560, 2556, 2552, 2548, 2544, 2540, 2536, 2532, 2528, 2524, 2520, 2516, 2512, 2508, 2504, 2500, + 2496, 2492, 2488, 2484, 2480, 2476, 2472, 2468, 2464, 2460, 2456, 2452, 2448, 2444, 2440, 2436, + 2432, 2428, 2424, 2420, 2416, 2412, 2408, 2404, 2400, 2396, 2392, 2388, 2384, 2380, 2376, 2372, + 2368, 2364, 2360, 2356, 2352, 2348, 2344, 2340, 2336, 2332, 2328, 2324, 2320, 2316, 2312, 2308, + 2304, 2300, 2296, 2292, 2288, 2284, 2280, 2276, 2272, 2268, 2264, 2260, 2256, 2252, 2248, 2244, + 2240, 2236, 2232, 2228, 2224, 2220, 2216, 2212, 2208, 2204, 2200, 2196, 2192, 2188, 2184, 2180, + 2176, 2172, 2168, 2164, 2160, 2156, 2152, 2148, 2144, 2140, 2136, 2132, 2128, 2124, 2120, 2116, + 2112, 2108, 2104, 2100, 2096, 2092, 2088, 2084, 2080, 2076, 2072, 2068, 2064, 2060, 2056, 2052, + 2048, 2044, 2040, 2036, 2032, 2028, 2024, 2020, 2016, 2012, 2008, 2004, 2000, 1996, 1992, 1988, + 1984, 1980, 1976, 1972, 1968, 1964, 1960, 1956, 1952, 1948, 1944, 1940, 1936, 1932, 1928, 1924, + 1920, 1916, 1912, 1908, 1904, 1900, 1896, 1892, 1888, 1884, 1880, 1876, 1872, 1868, 1864, 1860, + 1856, 1852, 1848, 1844, 1840, 1836, 1832, 1828, 1824, 1820, 1816, 1812, 1808, 1804, 1800, 1796, + 1792, 1788, 1784, 1780, 1776, 1772, 1768, 1764, 1760, 1756, 1752, 1748, 1744, 1740, 1736, 1732, + 1728, 1724, 1720, 1716, 1712, 1708, 1704, 1700, 1696, 1692, 1688, 1684, 1680, 1676, 1672, 1668, + 1664, 1660, 1656, 1652, 1648, 1644, 1640, 1636, 1632, 1628, 1624, 1620, 1616, 1612, 1608, 1604, + 1600, 1596, 1592, 1588, 1584, 1580, 1576, 1572, 1568, 1564, 1560, 1556, 1552, 1548, 1544, 1540, + 1536, 1532, 1528, 1524, 1520, 1516, 1512, 1508, 1504, 1500, 1496, 1492, 1488, 1484, 1480, 1476, + 1472, 1468, 1464, 1460, 1456, 1452, 1448, 1444, 1440, 1436, 1432, 1428, 1424, 1420, 1416, 1412, + 1408, 1404, 1400, 1396, 1392, 1388, 1384, 1380, 1376, 1372, 1368, 1364, 1360, 1356, 1352, 1348, + 1344, 1340, 1336, 1332, 1328, 1324, 1320, 1316, 1312, 1308, 1304, 1300, 1296, 1292, 1288, 1284, + 1280, 1276, 1272, 1268, 1264, 1260, 1256, 1252, 1248, 1244, 1240, 1236, 1232, 1228, 1224, 1220, + 1216, 1212, 1208, 1204, 1200, 1196, 1192, 1188, 1184, 1180, 1176, 1172, 1168, 1164, 1160, 1156, + 1152, 1148, 1144, 1140, 1136, 1132, 1128, 1124, 1120, 1116, 1112, 1108, 1104, 1100, 1096, 1092, + 1088, 1084, 1080, 1076, 1072, 1068, 1064, 1060, 1056, 1052, 1048, 1044, 1040, 1036, 1032, 1028, + 1024, 1020, 1016, 1012, 1008, 1004, 1000, 996, 992, 988, 984, 980, 976, 972, 968, 964, + 960, 956, 952, 948, 944, 940, 936, 932, 928, 924, 920, 916, 912, 908, 904, 900, + 896, 892, 888, 884, 880, 876, 872, 868, 864, 860, 856, 852, 848, 844, 840, 836, + 832, 828, 824, 820, 816, 812, 808, 804, 800, 796, 792, 788, 784, 780, 776, 772, + 768, 764, 760, 756, 752, 748, 744, 740, 736, 732, 728, 724, 720, 716, 712, 708, + 704, 700, 696, 692, 688, 684, 680, 676, 672, 668, 664, 660, 656, 652, 648, 644, + 640, 636, 632, 628, 624, 620, 616, 612, 608, 604, 600, 596, 592, 588, 584, 580, + 576, 572, 568, 564, 560, 556, 552, 548, 544, 540, 536, 532, 528, 524, 520, 516, + 512, 508, 504, 500, 496, 492, 488, 484, 480, 476, 472, 468, 464, 460, 456, 452, + 448, 444, 440, 436, 432, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, + 384, 380, 376, 372, 368, 364, 360, 356, 352, 348, 344, 340, 336, 332, 328, 324, + 320, 316, 312, 308, 304, 300, 296, 292, 288, 284, 280, 276, 272, 268, 264, 260, + 256, 252, 248, 244, 240, 236, 232, 228, 224, 220, 216, 212, 208, 204, 200, 196, + 192, 188, 184, 180, 176, 172, 168, 164, 160, 156, 152, 148, 144, 140, 136, 132, + 128, 124, 120, 116, 112, 108, 104, 100, 96, 92, 88, 84, 80, 76, 72, 68, + 64, 60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4 +}; + +const int16_t amigaPeriods[1936] = // bit-exact to FT2 table +{ + 29024, 28912, 28800, 28704, 28608, 28496, 28384, 28288, 28192, 28096, 28000, 27888, 27776, 27680, 27584, 27488, + 27392, 27296, 27200, 27104, 27008, 26912, 26816, 26720, 26624, 26528, 26432, 26336, 26240, 26144, 26048, 25952, + 25856, 25760, 25664, 25568, 25472, 25392, 25312, 25216, 25120, 25024, 24928, 24848, 24768, 24672, 24576, 24480, + 24384, 24304, 24224, 24144, 24064, 23968, 23872, 23792, 23712, 23632, 23552, 23456, 23360, 23280, 23200, 23120, + 23040, 22960, 22880, 22784, 22688, 22608, 22528, 22448, 22368, 22288, 22208, 22128, 22048, 21968, 21888, 21792, + 21696, 21648, 21600, 21520, 21440, 21360, 21280, 21200, 21120, 21040, 20960, 20896, 20832, 20752, 20672, 20576, + 20480, 20416, 20352, 20288, 20224, 20160, 20096, 20016, 19936, 19872, 19808, 19728, 19648, 19584, 19520, 19424, + 19328, 19280, 19232, 19168, 19104, 19024, 18944, 18880, 18816, 18752, 18688, 18624, 18560, 18480, 18400, 18320, + 18240, 18192, 18144, 18080, 18016, 17952, 17888, 17824, 17760, 17696, 17632, 17568, 17504, 17440, 17376, 17296, + 17216, 17168, 17120, 17072, 17024, 16960, 16896, 16832, 16768, 16704, 16640, 16576, 16512, 16464, 16416, 16336, + 16256, 16208, 16160, 16112, 16064, 16000, 15936, 15872, 15808, 15760, 15712, 15648, 15584, 15536, 15488, 15424, + 15360, 15312, 15264, 15216, 15168, 15104, 15040, 14992, 14944, 14880, 14816, 14768, 14720, 14672, 14624, 14568, + 14512, 14456, 14400, 14352, 14304, 14248, 14192, 14144, 14096, 14048, 14000, 13944, 13888, 13840, 13792, 13744, + 13696, 13648, 13600, 13552, 13504, 13456, 13408, 13360, 13312, 13264, 13216, 13168, 13120, 13072, 13024, 12976, + 12928, 12880, 12832, 12784, 12736, 12696, 12656, 12608, 12560, 12512, 12464, 12424, 12384, 12336, 12288, 12240, + 12192, 12152, 12112, 12072, 12032, 11984, 11936, 11896, 11856, 11816, 11776, 11728, 11680, 11640, 11600, 11560, + 11520, 11480, 11440, 11392, 11344, 11304, 11264, 11224, 11184, 11144, 11104, 11064, 11024, 10984, 10944, 10896, + 10848, 10824, 10800, 10760, 10720, 10680, 10640, 10600, 10560, 10520, 10480, 10448, 10416, 10376, 10336, 10288, + 10240, 10208, 10176, 10144, 10112, 10080, 10048, 10008, 9968, 9936, 9904, 9864, 9824, 9792, 9760, 9712, + 9664, 9640, 9616, 9584, 9552, 9512, 9472, 9440, 9408, 9376, 9344, 9312, 9280, 9240, 9200, 9160, + 9120, 9096, 9072, 9040, 9008, 8976, 8944, 8912, 8880, 8848, 8816, 8784, 8752, 8720, 8688, 8648, + 8608, 8584, 8560, 8536, 8512, 8480, 8448, 8416, 8384, 8352, 8320, 8288, 8256, 8232, 8208, 8168, + 8128, 8104, 8080, 8056, 8032, 8000, 7968, 7936, 7904, 7880, 7856, 7824, 7792, 7768, 7744, 7712, + 7680, 7656, 7632, 7608, 7584, 7552, 7520, 7496, 7472, 7440, 7408, 7384, 7360, 7336, 7312, 7284, + 7256, 7228, 7200, 7176, 7152, 7124, 7096, 7072, 7048, 7024, 7000, 6972, 6944, 6920, 6896, 6872, + 6848, 6824, 6800, 6776, 6752, 6728, 6704, 6680, 6656, 6632, 6608, 6584, 6560, 6536, 6512, 6488, + 6464, 6440, 6416, 6392, 6368, 6348, 6328, 6304, 6280, 6256, 6232, 6212, 6192, 6168, 6144, 6120, + 6096, 6076, 6056, 6036, 6016, 5992, 5968, 5948, 5928, 5908, 5888, 5864, 5840, 5820, 5800, 5780, + 5760, 5740, 5720, 5696, 5672, 5652, 5632, 5612, 5592, 5572, 5552, 5532, 5512, 5492, 5472, 5448, + 5424, 5412, 5400, 5380, 5360, 5340, 5320, 5300, 5280, 5260, 5240, 5224, 5208, 5188, 5168, 5144, + 5120, 5104, 5088, 5072, 5056, 5040, 5024, 5004, 4984, 4968, 4952, 4932, 4912, 4896, 4880, 4856, + 4832, 4820, 4808, 4792, 4776, 4756, 4736, 4720, 4704, 4688, 4672, 4656, 4640, 4620, 4600, 4580, + 4560, 4548, 4536, 4520, 4504, 4488, 4472, 4456, 4440, 4424, 4408, 4392, 4376, 4360, 4344, 4324, + 4304, 4292, 4280, 4268, 4256, 4240, 4224, 4208, 4192, 4176, 4160, 4144, 4128, 4116, 4104, 4084, + 4064, 4052, 4040, 4028, 4016, 4000, 3984, 3968, 3952, 3940, 3928, 3912, 3896, 3884, 3872, 3856, + 3840, 3828, 3816, 3804, 3792, 3776, 3760, 3748, 3736, 3720, 3704, 3692, 3680, 3668, 3656, 3642, + 3628, 3614, 3600, 3588, 3576, 3562, 3548, 3536, 3524, 3512, 3500, 3486, 3472, 3460, 3448, 3436, + 3424, 3412, 3400, 3388, 3376, 3364, 3352, 3340, 3328, 3316, 3304, 3292, 3280, 3268, 3256, 3244, + 3232, 3220, 3208, 3196, 3184, 3174, 3164, 3152, 3140, 3128, 3116, 3106, 3096, 3084, 3072, 3060, + 3048, 3038, 3028, 3018, 3008, 2996, 2984, 2974, 2964, 2954, 2944, 2932, 2920, 2910, 2900, 2890, + 2880, 2870, 2860, 2848, 2836, 2826, 2816, 2806, 2796, 2786, 2776, 2766, 2756, 2746, 2736, 2724, + 2712, 2706, 2700, 2690, 2680, 2670, 2660, 2650, 2640, 2630, 2620, 2612, 2604, 2594, 2584, 2572, + 2560, 2552, 2544, 2536, 2528, 2520, 2512, 2502, 2492, 2484, 2476, 2466, 2456, 2448, 2440, 2428, + 2416, 2410, 2404, 2396, 2388, 2378, 2368, 2360, 2352, 2344, 2336, 2328, 2320, 2310, 2300, 2290, + 2280, 2274, 2268, 2260, 2252, 2244, 2236, 2228, 2220, 2212, 2204, 2196, 2188, 2180, 2172, 2162, + 2152, 2146, 2140, 2134, 2128, 2120, 2112, 2104, 2096, 2088, 2080, 2072, 2064, 2058, 2052, 2042, + 2032, 2026, 2020, 2014, 2008, 2000, 1992, 1984, 1976, 1970, 1964, 1956, 1948, 1942, 1936, 1928, + 1920, 1914, 1908, 1902, 1896, 1888, 1880, 1874, 1868, 1860, 1852, 1846, 1840, 1834, 1828, 1821, + 1814, 1807, 1800, 1794, 1788, 1781, 1774, 1768, 1762, 1756, 1750, 1743, 1736, 1730, 1724, 1718, + 1712, 1706, 1700, 1694, 1688, 1682, 1676, 1670, 1664, 1658, 1652, 1646, 1640, 1634, 1628, 1622, + 1616, 1610, 1604, 1598, 1592, 1587, 1582, 1576, 1570, 1564, 1558, 1553, 1548, 1542, 1536, 1530, + 1524, 1519, 1514, 1509, 1504, 1498, 1492, 1487, 1482, 1477, 1472, 1466, 1460, 1455, 1450, 1445, + 1440, 1435, 1430, 1424, 1418, 1413, 1408, 1403, 1398, 1393, 1388, 1383, 1378, 1373, 1368, 1362, + 1356, 1353, 1350, 1345, 1340, 1335, 1330, 1325, 1320, 1315, 1310, 1306, 1302, 1297, 1292, 1286, + 1280, 1276, 1272, 1268, 1264, 1260, 1256, 1251, 1246, 1242, 1238, 1233, 1228, 1224, 1220, 1214, + 1208, 1205, 1202, 1198, 1194, 1189, 1184, 1180, 1176, 1172, 1168, 1164, 1160, 1155, 1150, 1145, + 1140, 1137, 1134, 1130, 1126, 1122, 1118, 1114, 1110, 1106, 1102, 1098, 1094, 1090, 1086, 1081, + 1076, 1073, 1070, 1067, 1064, 1060, 1056, 1052, 1048, 1044, 1040, 1036, 1032, 1029, 1026, 1021, + 1016, 1013, 1010, 1007, 1004, 1000, 996, 992, 988, 985, 982, 978, 974, 971, 968, 964, + 960, 957, 954, 951, 948, 944, 940, 937, 934, 930, 926, 923, 920, 917, 914, 910, + 907, 903, 900, 897, 894, 890, 887, 884, 881, 878, 875, 871, 868, 865, 862, 859, + 856, 853, 850, 847, 844, 841, 838, 835, 832, 829, 826, 823, 820, 817, 814, 811, + 808, 805, 802, 799, 796, 793, 791, 788, 785, 782, 779, 776, 774, 771, 768, 765, + 762, 759, 757, 754, 752, 749, 746, 743, 741, 738, 736, 733, 730, 727, 725, 722, + 720, 717, 715, 712, 709, 706, 704, 701, 699, 696, 694, 691, 689, 686, 684, 681, + 678, 676, 675, 672, 670, 667, 665, 662, 660, 657, 655, 653, 651, 648, 646, 643, + 640, 638, 636, 634, 632, 630, 628, 625, 623, 621, 619, 616, 614, 612, 610, 607, + 604, 602, 601, 599, 597, 594, 592, 590, 588, 586, 584, 582, 580, 577, 575, 572, + 570, 568, 567, 565, 563, 561, 559, 557, 555, 553, 551, 549, 547, 545, 543, 540, + 538, 536, 535, 533, 532, 530, 528, 526, 524, 522, 520, 518, 516, 514, 513, 510, + 508, 506, 505, 503, 502, 500, 498, 496, 494, 492, 491, 489, 487, 485, 484, 482, + 480, 478, 477, 475, 474, 472, 470, 468, 467, 465, 463, 461, 460, 458, 457, 455, + 453, 451, 450, 448, 447, 445, 443, 441, 440, 438, 437, 435, 434, 432, 431, 429, + 428, 426, 425, 423, 422, 420, 419, 417, 416, 414, 413, 411, 410, 408, 407, 405, + 404, 402, 401, 399, 398, 396, 395, 393, 392, 390, 389, 388, 387, 385, 384, 382, + 381, 379, 378, 377, 376, 374, 373, 371, 370, 369, 368, 366, 365, 363, 362, 361, + 360, 358, 357, 355, 354, 353, 352, 350, 349, 348, 347, 345, 344, 343, 342, 340, + 339, 338, 337, 336, 335, 333, 332, 331, 330, 328, 327, 326, 325, 324, 323, 321, + 320, 319, 318, 317, 316, 315, 314, 312, 311, 310, 309, 308, 307, 306, 305, 303, + 302, 301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, 288, 287, 286, + 285, 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, 274, 273, 272, 271, 270, + 269, 268, 267, 266, 266, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, + 254, 253, 252, 251, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 242, 241, + 240, 239, 238, 237, 237, 236, 235, 234, 233, 232, 231, 230, 230, 229, 228, 227, + 227, 226, 225, 224, 223, 222, 222, 221, 220, 219, 219, 218, 217, 216, 215, 214, + 214, 213, 212, 211, 211, 210, 209, 208, 208, 207, 206, 205, 205, 204, 203, 202, + 202, 201, 200, 199, 199, 198, 198, 197, 196, 195, 195, 194, 193, 192, 192, 191, + 190, 189, 189, 188, 188, 187, 186, 185, 185, 184, 184, 183, 182, 181, 181, 180, + 180, 179, 179, 178, 177, 176, 176, 175, 175, 174, 173, 172, 172, 171, 171, 170, + 169, 169, 169, 168, 167, 166, 166, 165, 165, 164, 164, 163, 163, 162, 161, 160, + 160, 159, 159, 158, 158, 157, 157, 156, 156, 155, 155, 154, 153, 152, 152, 151, + 151, 150, 150, 149, 149, 148, 148, 147, 147, 146, 146, 145, 145, 144, 144, 143, + 142, 142, 142, 141, 141, 140, 140, 139, 139, 138, 138, 137, 137, 136, 136, 135, + 134, 134, 134, 133, 133, 132, 132, 131, 131, 130, 130, 129, 129, 128, 128, 127, + 127, 126, 126, 125, 125, 124, 124, 123, 123, 123, 123, 122, 122, 121, 121, 120, + 120, 119, 119, 118, 118, 117, 117, 117, 117, 116, 116, 115, 115, 114, 114, 113, + 113, 112, 112, 112, 112, 111, 111, 110, 110, 109, 109, 108, 108, 108, 108, 107, + 107, 106, 106, 105, 105, 105, 105, 104, 104, 103, 103, 102, 102, 102, 102, 101, + 101, 100, 100, 99, 99, 99, 99, 98, 98, 97, 97, 97, 97, 96, 96, 95, + 95, 95, 95, 94, 94, 93, 93, 93, 93, 92, 92, 91, 91, 91, 91, 90, + 90, 89, 89, 89, 89, 88, 88, 87, 87, 87, 87, 86, 86, 85, 85, 85, + 85, 84, 84, 84, 84, 83, 83, 82, 82, 82, 82, 81, 81, 81, 81, 80, + 80, 79, 79, 79, 79, 78, 78, 78, 78, 77, 77, 77, 77, 76, 76, 75, + 75, 75, 75, 75, 75, 74, 74, 73, 73, 73, 73, 72, 72, 72, 72, 71, + 71, 71, 71, 70, 70, 70, 70, 69, 69, 69, 69, 68, 68, 68, 68, 67, + 67, 67, 67, 66, 66, 66, 66, 65, 65, 65, 65, 64, 64, 64, 64, 63, + 63, 63, 63, 63, 63, 62, 62, 62, 62, 61, 61, 61, 61, 60, 60, 60, + 60, 60, 60, 59, 59, 59, 59, 58, 58, 58, 58, 57, 57, 57, 57, 57, + 57, 56, 56, 56, 56, 55, 55, 55, 55, 55, 55, 54, 54, 54, 54, 53, + 53, 53, 53, 53, 53, 52, 52, 52, 52, 52, 52, 51, 51, 51, 51, 50, + 50, 50, 50, 50, 50, 49, 49, 49, 49, 49, 49, 48, 48, 48, 48, 48, + 48, 47, 47, 47, 47, 47, 47, 46, 46, 46, 46, 46, 46, 45, 45, 45, + 45, 45, 45, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 42, + 42, 42, 42, 42, 42, 42, 42, 41, 41, 41, 41, 41, 41, 40, 40, 40, + 40, 40, 40, 39, 39, 39, 39, 39, 39, 39, 39, 38, 38, 38, 38, 38, + 38, 38, 38, 37, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 36, + 36, 35, 35, 35, 35, 35, 35, 35, 35, 34, 34, 34, 34, 34, 34, 34, + 34, 33, 33, 33, 33, 33, 33, 33, 33, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 22, + 16, 8, 0, 16, 32, 24, 16, 8, 0, 16, 32, 24, 16, 8, 0, 0 + // the last 17 values are off (but identical to FT2) because of a bug in how FT2 calculates this table +}; + +const uint32_t logTab[768] = // bit-exact to FT2 table +{ + 16777216, 16792365, 16807527, 16822704, 16837894, 16853097, 16868315, 16883546, + 16898791, 16914049, 16929322, 16944608, 16959908, 16975222, 16990549, 17005891, + 17021246, 17036615, 17051999, 17067396, 17082806, 17098231, 17113670, 17129123, + 17144589, 17160070, 17175564, 17191073, 17206595, 17222132, 17237683, 17253247, + 17268826, 17284419, 17300026, 17315646, 17331282, 17346931, 17362594, 17378271, + 17393963, 17409669, 17425389, 17441123, 17456871, 17472634, 17488410, 17504202, + 17520007, 17535826, 17551660, 17567508, 17583371, 17599248, 17615139, 17631044, + 17646964, 17662898, 17678847, 17694810, 17710787, 17726779, 17742785, 17758806, + 17774841, 17790891, 17806955, 17823034, 17839127, 17855235, 17871357, 17887494, + 17903645, 17919811, 17935992, 17952187, 17968397, 17984621, 18000860, 18017114, + 18033382, 18049665, 18065963, 18082276, 18098603, 18114945, 18131302, 18147673, + 18164060, 18180461, 18196877, 18213307, 18229753, 18246213, 18262689, 18279179, + 18295684, 18312204, 18328739, 18345288, 18361853, 18378433, 18395028, 18411637, + 18428262, 18444902, 18461556, 18478226, 18494911, 18511611, 18528325, 18545056, + 18561801, 18578561, 18595336, 18612127, 18628932, 18645753, 18662589, 18679441, + 18696307, 18713189, 18730086, 18746998, 18763925, 18780868, 18797826, 18814800, + 18831788, 18848792, 18865812, 18882846, 18899897, 18916962, 18934043, 18951139, + 18968251, 18985378, 19002521, 19019679, 19036853, 19054042, 19071247, 19088467, + 19105703, 19122954, 19140221, 19157504, 19174802, 19192116, 19209445, 19226790, + 19244151, 19261527, 19278919, 19296327, 19313750, 19331190, 19348645, 19366115, + 19383602, 19401104, 19418622, 19436156, 19453706, 19471271, 19488853, 19506450, + 19524063, 19541692, 19559337, 19576998, 19594675, 19612368, 19630077, 19647802, + 19665543, 19683300, 19701072, 19718861, 19736666, 19754488, 19772325, 19790178, + 19808047, 19825933, 19843835, 19861752, 19879686, 19897637, 19915603, 19933586, + 19951585, 19969600, 19987631, 20005679, 20023743, 20041823, 20059920, 20078033, + 20096162, 20114308, 20132470, 20150648, 20168843, 20187054, 20205282, 20223526, + 20241787, 20260064, 20278358, 20296668, 20314995, 20333338, 20351698, 20370074, + 20388467, 20406877, 20425303, 20443746, 20462206, 20480682, 20499175, 20517684, + 20536211, 20554754, 20573313, 20591890, 20610483, 20629093, 20647720, 20666364, + 20685025, 20703702, 20722396, 20741107, 20759835, 20778580, 20797342, 20816121, + 20834917, 20853729, 20872559, 20891406, 20910270, 20929150, 20948048, 20966963, + 20985895, 21004844, 21023810, 21042794, 21061794, 21080812, 21099846, 21118898, + 21137968, 21157054, 21176158, 21195278, 21214417, 21233572, 21252745, 21271935, + 21291142, 21310367, 21329609, 21348868, 21368145, 21387439, 21406751, 21426080, + 21445426, 21464790, 21484172, 21503571, 21522987, 21542421, 21561873, 21581342, + 21600829, 21620333, 21639855, 21659395, 21678952, 21698527, 21718119, 21737729, + 21757357, 21777003, 21796666, 21816348, 21836046, 21855763, 21875498, 21895250, + 21915020, 21934808, 21954614, 21974438, 21994279, 22014139, 22034016, 22053912, + 22073825, 22093757, 22113706, 22133674, 22153659, 22173663, 22193684, 22213724, + 22233781, 22253857, 22273951, 22294063, 22314194, 22334342, 22354509, 22374693, + 22394897, 22415118, 22435357, 22455615, 22475891, 22496186, 22516499, 22536830, + 22557179, 22577547, 22597933, 22618338, 22638761, 22659202, 22679662, 22700141, + 22720638, 22741153, 22761687, 22782240, 22802811, 22823400, 22844009, 22864635, + 22885281, 22905945, 22926628, 22947329, 22968049, 22988788, 23009546, 23030322, + 23051117, 23071931, 23092764, 23113615, 23134485, 23155374, 23176282, 23197209, + 23218155, 23239120, 23260103, 23281106, 23302127, 23323168, 23344227, 23365306, + 23386403, 23407520, 23428656, 23449810, 23470984, 23492177, 23513389, 23534620, + 23555871, 23577140, 23598429, 23619737, 23641065, 23662411, 23683777, 23705162, + 23726566, 23747990, 23769433, 23790896, 23812377, 23833879, 23855399, 23876939, + 23898499, 23920078, 23941676, 23963294, 23984932, 24006589, 24028265, 24049962, + 24071677, 24093413, 24115168, 24136942, 24158736, 24180550, 24202384, 24224237, + 24246111, 24268003, 24289916, 24311848, 24333801, 24355773, 24377765, 24399776, + 24421808, 24443859, 24465931, 24488022, 24510133, 24532265, 24554416, 24576587, + 24598778, 24620990, 24643221, 24665472, 24687744, 24710036, 24732347, 24754679, + 24777031, 24799403, 24821796, 24844209, 24866641, 24889095, 24911568, 24934062, + 24956576, 24979110, 25001665, 25024240, 25046835, 25069451, 25092088, 25114744, + 25137421, 25160119, 25182837, 25205576, 25228335, 25251115, 25273915, 25296736, + 25319578, 25342440, 25365322, 25388226, 25411150, 25434095, 25457060, 25480047, + 25503054, 25526081, 25549130, 25572199, 25595290, 25618401, 25641533, 25664686, + 25687859, 25711054, 25734270, 25757506, 25780764, 25804042, 25827342, 25850662, + 25874004, 25897367, 25920751, 25944156, 25967582, 25991029, 26014497, 26037987, + 26061498, 26085030, 26108583, 26132158, 26155754, 26179371, 26203009, 26226669, + 26250350, 26274053, 26297777, 26321522, 26345289, 26369077, 26392887, 26416718, + 26440571, 26464445, 26488341, 26512259, 26536198, 26560158, 26584141, 26608145, + 26632170, 26656218, 26680287, 26704377, 26728490, 26752624, 26776780, 26800958, + 26825158, 26849380, 26873623, 26897888, 26922176, 26946485, 26970816, 26995169, + 27019544, 27043941, 27068360, 27092802, 27117265, 27141750, 27166258, 27190787, + 27215339, 27239913, 27264509, 27289127, 27313768, 27338430, 27363116, 27387823, + 27412552, 27437304, 27462079, 27486875, 27511695, 27536536, 27561400, 27586286, + 27611195, 27636126, 27661080, 27686057, 27711056, 27736077, 27761121, 27786188, + 27811277, 27836389, 27861524, 27886681, 27911861, 27937064, 27962290, 27987538, + 28012809, 28038103, 28063420, 28088760, 28114122, 28139508, 28164916, 28190347, + 28215802, 28241279, 28266779, 28292302, 28317849, 28343418, 28369011, 28394626, + 28420265, 28445927, 28471612, 28497320, 28523052, 28548806, 28574584, 28600385, + 28626210, 28652058, 28677929, 28703823, 28729741, 28755683, 28781647, 28807636, + 28833647, 28859682, 28885741, 28911823, 28937929, 28964058, 28990211, 29016388, + 29042588, 29068811, 29095059, 29121330, 29147625, 29173944, 29200286, 29226652, + 29253042, 29279456, 29305894, 29332355, 29358841, 29385350, 29411883, 29438441, + 29465022, 29491627, 29518256, 29544910, 29571587, 29598288, 29625014, 29651764, + 29678538, 29705336, 29732158, 29759004, 29785875, 29812770, 29839689, 29866633, + 29893600, 29920593, 29947609, 29974650, 30001716, 30028805, 30055920, 30083059, + 30110222, 30137410, 30164622, 30191859, 30219120, 30246407, 30273717, 30301053, + 30328413, 30355798, 30383207, 30410642, 30438101, 30465584, 30493093, 30520627, + 30548185, 30575768, 30603377, 30631010, 30658668, 30686351, 30714059, 30741792, + 30769550, 30797333, 30825141, 30852975, 30880833, 30908717, 30936625, 30964559, + 30992519, 31020503, 31048513, 31076548, 31104608, 31132694, 31160805, 31188941, + 31217103, 31245290, 31273503, 31301741, 31330005, 31358294, 31386609, 31414949, + 31443315, 31471707, 31500124, 31528567, 31557035, 31585529, 31614049, 31642595, + 31671166, 31699764, 31728387, 31757036, 31785710, 31814411, 31843138, 31871890, + 31900669, 31929473, 31958304, 31987160, 32016043, 32044951, 32073886, 32102847, + 32131834, 32160847, 32189887, 32218952, 32248044, 32277162, 32306307, 32335478, + 32364675, 32393898, 32423148, 32452424, 32481727, 32511056, 32540412, 32569794, + 32599202, 32628638, 32658099, 32687588, 32717103, 32746645, 32776213, 32805808, + 32835430, 32865078, 32894754, 32924456, 32954184, 32983940, 33013723, 33043532, + 33073369, 33103232, 33133122, 33163040, 33192984, 33222955, 33252954, 33282979, + 33313032, 33343112, 33373219, 33403353, 33433514, 33463703, 33493919, 33524162 +}; + +/* ----------------------------------------------------------------------- */ +/* AUDIO MIXER TABLES */ +/* ----------------------------------------------------------------------- */ + +const uint32_t panningTab[257] = // bit-exact to FT2 table +{ + 0, 4096, 5793, 7094, 8192, 9159,10033,10837,11585,12288,12953,13585,14189,14768,15326,15864, + 16384,16888,17378,17854,18318,18770,19212,19644,20066,20480,20886,21283,21674,22058,22435,22806, + 23170,23530,23884,24232,24576,24915,25249,25580,25905,26227,26545,26859,27170,27477,27780,28081, + 28378,28672,28963,29251,29537,29819,30099,30377,30652,30924,31194,31462,31727,31991,32252,32511, + 32768,33023,33276,33527,33776,34024,34270,34514,34756,34996,35235,35472,35708,35942,36175,36406, + 36636,36864,37091,37316,37540,37763,37985,38205,38424,38642,38858,39073,39287,39500,39712,39923, + 40132,40341,40548,40755,40960,41164,41368,41570,41771,41972,42171,42369,42567,42763,42959,43154, + 43348,43541,43733,43925,44115,44305,44494,44682,44869,45056,45242,45427,45611,45795,45977,46160, + 46341,46522,46702,46881,47059,47237,47415,47591,47767,47942,48117,48291,48465,48637,48809,48981, + 49152,49322,49492,49661,49830,49998,50166,50332,50499,50665,50830,50995,51159,51323,51486,51649, + 51811,51972,52134,52294,52454,52614,52773,52932,53090,53248,53405,53562,53719,53874,54030,54185, + 54340,54494,54647,54801,54954,55106,55258,55410,55561,55712,55862,56012,56162,56311,56459,56608, + 56756,56903,57051,57198,57344,57490,57636,57781,57926,58071,58215,58359,58503,58646,58789,58931, + 59073,59215,59357,59498,59639,59779,59919,60059,60199,60338,60477,60615,60753,60891,61029,61166, + 61303,61440,61576,61712,61848,61984,62119,62254,62388,62523,62657,62790,62924,63057,63190,63323, + 63455,63587,63719,63850,63982,64113,64243,64374,64504,64634,64763,64893,65022,65151,65279,65408, + 65536 +}; + +/* 8bitbubsy: This table was taken from Tables.cpp (the OpenMPT project) +** +** Comment from Tables.cpp: +** "Reversed sinc coefficients for 4x256 taps polyphase FIR resampling filter (SchismTracker's lutgen.c +** should generate a very similar table, but it's more precise)" +*/ +const int16_t fastSincTable[256 * 4] = +{ // Cubic Spline + 0, 16384, 0, 0, -31, 16383, 32, 0, -63, 16381, 65, 0, -93, 16378, 100, -1, + -124, 16374, 135, -1, -153, 16368, 172, -3, -183, 16361, 209, -4, -211, 16353, 247, -5, + -240, 16344, 287, -7, -268, 16334, 327, -9, -295, 16322, 368, -12, -322, 16310, 410, -14, + -348, 16296, 453, -17, -374, 16281, 497, -20, -400, 16265, 541, -23, -425, 16248, 587, -26, + -450, 16230, 634, -30, -474, 16210, 681, -33, -497, 16190, 729, -37, -521, 16168, 778, -41, + -543, 16145, 828, -46, -566, 16121, 878, -50, -588, 16097, 930, -55, -609, 16071, 982, -60, + -630, 16044, 1035, -65, -651, 16016, 1089, -70, -671, 15987, 1144, -75, -691, 15957, 1199, -81, + -710, 15926, 1255, -87, -729, 15894, 1312, -93, -748, 15861, 1370, -99, -766, 15827, 1428, -105, + -784, 15792, 1488, -112, -801, 15756, 1547, -118, -818, 15719, 1608, -125, -834, 15681, 1669, -132, + -850, 15642, 1731, -139, -866, 15602, 1794, -146, -881, 15561, 1857, -153, -896, 15520, 1921, -161, + -911, 15477, 1986, -168, -925, 15434, 2051, -176, -939, 15390, 2117, -184, -952, 15344, 2184, -192, + -965, 15298, 2251, -200, -978, 15251, 2319, -208, -990, 15204, 2387, -216, -1002, 15155, 2456, -225, + -1014, 15106, 2526, -234, -1025, 15055, 2596, -242, -1036, 15004, 2666, -251, -1046, 14952, 2738, -260, + -1056, 14899, 2810, -269, -1066, 14846, 2882, -278, -1075, 14792, 2955, -287, -1084, 14737, 3028, -296, + -1093, 14681, 3102, -306, -1102, 14624, 3177, -315, -1110, 14567, 3252, -325, -1118, 14509, 3327, -334, + -1125, 14450, 3403, -344, -1132, 14390, 3480, -354, -1139, 14330, 3556, -364, -1145, 14269, 3634, -374, + -1152, 14208, 3712, -384, -1157, 14145, 3790, -394, -1163, 14082, 3868, -404, -1168, 14018, 3947, -414, + -1173, 13954, 4027, -424, -1178, 13889, 4107, -434, -1182, 13823, 4187, -445, -1186, 13757, 4268, -455, + -1190, 13690, 4349, -465, -1193, 13623, 4430, -476, -1196, 13555, 4512, -486, -1199, 13486, 4594, -497, + -1202, 13417, 4676, -507, -1204, 13347, 4759, -518, -1206, 13276, 4842, -528, -1208, 13205, 4926, -539, + -1210, 13134, 5010, -550, -1211, 13061, 5094, -560, -1212, 12989, 5178, -571, -1212, 12915, 5262, -581, + -1213, 12842, 5347, -592, -1213, 12767, 5432, -603, -1213, 12693, 5518, -613, -1213, 12617, 5603, -624, + -1212, 12542, 5689, -635, -1211, 12466, 5775, -645, -1210, 12389, 5862, -656, -1209, 12312, 5948, -667, + -1208, 12234, 6035, -677, -1206, 12156, 6122, -688, -1204, 12078, 6209, -698, -1202, 11999, 6296, -709, + -1200, 11920, 6384, -720, -1197, 11840, 6471, -730, -1194, 11760, 6559, -740, -1191, 11679, 6647, -751, + -1188, 11598, 6735, -761, -1184, 11517, 6823, -772, -1181, 11436, 6911, -782, -1177, 11354, 6999, -792, + -1173, 11271, 7088, -802, -1168, 11189, 7176, -812, -1164, 11106, 7265, -822, -1159, 11022, 7354, -832, + -1155, 10939, 7442, -842, -1150, 10855, 7531, -852, -1144, 10771, 7620, -862, -1139, 10686, 7709, -872, + -1134, 10602, 7798, -882, -1128, 10516, 7886, -891, -1122, 10431, 7975, -901, -1116, 10346, 8064, -910, + -1110, 10260, 8153, -919, -1103, 10174, 8242, -929, -1097, 10088, 8331, -938, -1090, 10001, 8420, -947, + -1083, 9915, 8508, -956, -1076, 9828, 8597, -965, -1069, 9741, 8686, -973, -1062, 9654, 8774, -982, + -1054, 9566, 8863, -991, -1047, 9479, 8951, -999, -1039, 9391, 9039, -1007, -1031, 9303, 9127, -1015, + -1024, 9216, 9216, -1024, -1015, 9127, 9303, -1031, -1007, 9039, 9391, -1039, -999, 8951, 9479, -1047, + -991, 8863, 9566, -1054, -982, 8774, 9654, -1062, -973, 8686, 9741, -1069, -965, 8597, 9828, -1076, + -956, 8508, 9915, -1083, -947, 8420, 10001, -1090, -938, 8331, 10088, -1097, -929, 8242, 10174, -1103, + -919, 8153, 10260, -1110, -910, 8064, 10346, -1116, -901, 7975, 10431, -1122, -891, 7886, 10516, -1128, + -882, 7798, 10602, -1134, -872, 7709, 10686, -1139, -862, 7620, 10771, -1144, -852, 7531, 10855, -1150, + -842, 7442, 10939, -1155, -832, 7354, 11022, -1159, -822, 7265, 11106, -1164, -812, 7176, 11189, -1168, + -802, 7088, 11271, -1173, -792, 6999, 11354, -1177, -782, 6911, 11436, -1181, -772, 6823, 11517, -1184, + -761, 6735, 11598, -1188, -751, 6647, 11679, -1191, -740, 6559, 11760, -1194, -730, 6471, 11840, -1197, + -720, 6384, 11920, -1200, -709, 6296, 11999, -1202, -698, 6209, 12078, -1204, -688, 6122, 12156, -1206, + -677, 6035, 12234, -1208, -667, 5948, 12312, -1209, -656, 5862, 12389, -1210, -645, 5775, 12466, -1211, + -635, 5689, 12542, -1212, -624, 5603, 12617, -1213, -613, 5518, 12693, -1213, -603, 5432, 12767, -1213, + -592, 5347, 12842, -1213, -581, 5262, 12915, -1212, -571, 5178, 12989, -1212, -560, 5094, 13061, -1211, + -550, 5010, 13134, -1210, -539, 4926, 13205, -1208, -528, 4842, 13276, -1206, -518, 4759, 13347, -1204, + -507, 4676, 13417, -1202, -497, 4594, 13486, -1199, -486, 4512, 13555, -1196, -476, 4430, 13623, -1193, + -465, 4349, 13690, -1190, -455, 4268, 13757, -1186, -445, 4187, 13823, -1182, -434, 4107, 13889, -1178, + -424, 4027, 13954, -1173, -414, 3947, 14018, -1168, -404, 3868, 14082, -1163, -394, 3790, 14145, -1157, + -384, 3712, 14208, -1152, -374, 3634, 14269, -1145, -364, 3556, 14330, -1139, -354, 3480, 14390, -1132, + -344, 3403, 14450, -1125, -334, 3327, 14509, -1118, -325, 3252, 14567, -1110, -315, 3177, 14624, -1102, + -306, 3102, 14681, -1093, -296, 3028, 14737, -1084, -287, 2955, 14792, -1075, -278, 2882, 14846, -1066, + -269, 2810, 14899, -1056, -260, 2738, 14952, -1046, -251, 2666, 15004, -1036, -242, 2596, 15055, -1025, + -234, 2526, 15106, -1014, -225, 2456, 15155, -1002, -216, 2387, 15204, -990, -208, 2319, 15251, -978, + -200, 2251, 15298, -965, -192, 2184, 15344, -952, -184, 2117, 15390, -939, -176, 2051, 15434, -925, + -168, 1986, 15477, -911, -161, 1921, 15520, -896, -153, 1857, 15561, -881, -146, 1794, 15602, -866, + -139, 1731, 15642, -850, -132, 1669, 15681, -834, -125, 1608, 15719, -818, -118, 1547, 15756, -801, + -112, 1488, 15792, -784, -105, 1428, 15827, -766, -99, 1370, 15861, -748, -93, 1312, 15894, -729, + -87, 1255, 15926, -710, -81, 1199, 15957, -691, -75, 1144, 15987, -671, -70, 1089, 16016, -651, + -65, 1035, 16044, -630, -60, 982, 16071, -609, -55, 930, 16097, -588, -50, 878, 16121, -566, + -46, 828, 16145, -543, -41, 778, 16168, -521, -37, 729, 16190, -497, -33, 681, 16210, -474, + -30, 634, 16230, -450, -26, 587, 16248, -425, -23, 541, 16265, -400, -20, 497, 16281, -374, + -17, 453, 16296, -348, -14, 410, 16310, -322, -12, 368, 16322, -295, -9, 327, 16334, -268, + -7, 287, 16344, -240, -5, 247, 16353, -211, -4, 209, 16361, -183, -3, 172, 16368, -153, + -1, 135, 16374, -124, -1, 100, 16378, -93, 0, 65, 16381, -63, 0, 32, 16383, -31 +}; + +/* ----------------------------------------------------------------------- */ +/* GUI TABLES */ +/* ----------------------------------------------------------------------- */ + +pal16 palTable[12][16] = // FT2 palettes (18-bit VGA RGB, 16 color palette) +{ + { + {0, 0, 0},{30, 38, 63},{0, 0, 17},{63, 63, 63}, + {27, 36, 40},{63, 63, 63},{40, 40, 40},{0, 0, 0}, + {10, 13, 14},{49, 63, 63},{15, 15, 15},{63, 63, 63}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + }, + { + {0, 0, 0},{21, 40, 63},{0, 0, 17},{63, 63, 63}, + {6, 39, 35},{63, 63, 63},{40, 40, 40},{0, 0, 0}, + {2, 14, 13},{11, 63, 63},{16, 16, 16},{63, 63, 63}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + }, + { + {0, 0, 0},{39, 52, 63},{8, 8, 13},{57, 57, 63}, + {10, 21, 33},{63, 63, 63},{37, 37, 45},{0, 0, 0}, + {4, 8, 13},{18, 37, 58},{13, 13, 16},{63, 63, 63}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + }, + { + {0, 0, 0},{47, 47, 47},{9, 9, 9},{63, 63, 63}, + {37, 29, 7},{63, 63, 63},{40, 40, 40},{0, 0, 0}, + {11, 9, 2},{63, 58, 14},{15, 15, 15},{63, 63, 63}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + }, + { + {0, 0, 0},{46, 45, 46},{13, 9, 9},{63, 63, 63}, + {22, 19, 22},{63, 63, 63},{36, 32, 34},{0, 0, 0}, + {8, 7, 8},{39, 34, 39},{13, 12, 12},{63, 58, 62}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + }, + { + {0, 0, 0},{19, 49, 54},{0, 11, 7},{52, 63, 61}, + {9, 31, 21},{63, 63, 63},{40, 40, 40},{0, 0, 0}, + {4, 13, 9},{15, 50, 34},{15, 15, 15},{63, 63, 63}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + }, + { + {0, 0, 0},{27, 37, 53},{0, 0, 20},{63, 63, 63}, + {7, 12, 21},{63, 63, 63},{38, 39, 39},{0, 0, 0}, + {2, 4, 7},{14, 23, 41},{13, 13, 13},{63, 63, 63}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + }, + { + {0, 0, 0},{63, 54, 62},{18, 3, 3},{63, 63, 63}, + {36, 19, 25},{63, 63, 63},{40, 40, 40},{0, 0, 0}, + {11, 6, 8},{63, 38, 50},{15, 15, 15},{63, 63, 63}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + }, + { + {0, 0, 0},{63, 0, 63},{0, 21, 0},{63, 44, 0}, + {0, 63, 0},{63, 63, 63},{63, 0, 0},{0, 0, 0}, + {0, 28, 0},{0, 63, 0},{23, 0, 0},{63, 0, 0}, + {0, 63, 63},{0, 63, 63},{0, 63, 63},{0, 63, 63} + }, + { + {0, 0, 0},{50, 46, 63},{15, 0, 16},{59, 58, 63}, + {34, 21, 41},{63, 63, 63},{40, 40, 40},{0, 0, 0}, + {13, 8, 15},{61, 37, 63},{15, 15, 15},{63, 63, 63}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + }, + { + {0, 0, 0},{63, 63, 32},{10, 10, 10},{63, 63, 63}, + {18, 29, 32},{63, 63, 63},{39, 39, 39},{0, 0, 0}, + {6, 10, 11},{34, 54, 60},{15, 15, 15},{63, 63, 63}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + }, + { + {0, 0, 0},{36, 47, 63},{9, 9, 16},{63, 63, 63}, + {19, 24, 38},{63, 63, 63},{39, 39, 39},{0, 0, 0}, + {8, 10, 15},{32, 41, 63},{15, 15, 15},{63, 63, 63}, + {63, 63, 63},{63, 63, 63},{63, 63, 63},{63, 63, 63} + } +}; + +const uint16_t chanWidths[6] = { 141, 141, 93, 69, 45, 45 }; + +const pattCoordsMouse_t pattCoordMouseTable[2][2][2] = +{ + /* + uint16_t upperRowsY, midRowY, lowerRowsY; + uint16_t numUpperRows; + */ + + // no pattern stretch + { + // no pattern channel scroll + { + { 177, 281, 293, 13 }, // normal pattern editor + { 57, 217, 229, 20 }, // extended pattern editor + }, + + // pattern channel scroll + { + { 177, 274, 286, 12 }, // normal pattern editor + { 57, 210, 222, 19 }, // extended pattern editor + } + }, + + // pattern stretch + { + // no pattern channel scroll + { + { 176, 275, 286, 9 }, // normal pattern editor + { 56, 221, 232, 15 }, // extended pattern editor + }, + + // pattern channel scroll + { + { 175, 274, 284, 9 }, // normal pattern editor + { 55, 209, 219, 14 }, // extended pattern editor + }, + } +}; + +const uint8_t noteTab1[96] = +{ + 0,1,2,3,4,5,6,7,8,9,10,11, + 0,1,2,3,4,5,6,7,8,9,10,11, + 0,1,2,3,4,5,6,7,8,9,10,11, + 0,1,2,3,4,5,6,7,8,9,10,11, + 0,1,2,3,4,5,6,7,8,9,10,11, + 0,1,2,3,4,5,6,7,8,9,10,11, + 0,1,2,3,4,5,6,7,8,9,10,11, + 0,1,2,3,4,5,6,7,8,9,10,11 +}; + +const uint8_t noteTab2[96] = +{ + 0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7 +}; + +const uint8_t hex2Dec[256] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 96, 97, 98, 99,100,101,102,103,104,105, + 112,113,114,115,116,117,118,119,120,121, + 128,129,130,131,132,133,134,135,136,137, + 144,145,146,147,148,149,150,151,152,153, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 96, 97, 98, 99,100,101,102,103,104,105, + 112,113,114,115,116,117,118,119,120,121, + 128,129,130,131,132,133,134,135,136,137, + 144,145,146,147,148,149,150,151,152,153, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 16,17,18,19,20,21,22,23,24,25, + 32,33,34,35,36,37,38,39,40,41, + 48,49,50,51,52,53,54,55,56,57, + 64,65,66,67,68,69,70,71,72,73, + 80,81,82,83,84,85 +}; + +const pattCoord_t pattCoordTable[2][2][2] = +{ + // no pattern stretch + { + // no pattern channel scroll + { + { 176, 292, 177, 283, 293, 13, 13 }, // normal pattern editor + { 56, 228, 57, 219, 229, 20, 21 }, // extended pattern editor + }, + + // pattern channel scroll + { + { 176, 285, 177, 276, 286, 12, 12 }, // normal pattern editor + { 56, 221, 57, 212, 222, 19, 20 }, // extended pattern editor + } + }, + + // pattern stretch + { + // no pattern channel scroll + { + { 177, 286, 178, 277, 288, 9, 10 }, // normal pattern editor + { 56, 232, 58, 223, 234, 15, 15 }, // extended pattern editor + }, + + // pattern channel scroll + { + { 176, 285, 177, 276, 286, 9, 9 }, // normal pattern editor + { 56, 220, 57, 211, 221, 14, 15 }, // extended pattern editor + }, + } +}; + +const pattCoord2_t pattCoord2Table[2][2][2] = +{ + // no pattern stretch + { + // no pattern channel scroll + { + { 175, 291, 107, 107 }, // normal pattern editor + { 55, 227, 163, 171 }, // extended pattern editor + }, + + // pattern channel scroll + { + { 175, 284, 100, 100 }, // normal pattern editor + { 55, 220, 156, 164 }, // extended pattern editor + } + }, + + // pattern stretch + { + // no pattern channel scroll + { + { 175, 285, 101, 113 }, // normal pattern editor + { 55, 231, 167, 167 }, // extended pattern editor + }, + + // pattern channel scroll + { + { 175, 284, 100, 100 }, // normal pattern editor + { 55, 219, 155, 165 }, // extended pattern editor + }, + } +}; + +const markCoord_t markCoordTable[2][2][2] = +{ + // no pattern stretch + { + // no pattern channel scroll + { + { 177, 281, 293 }, // normal pattern editor + { 57, 217, 229 }, // extended pattern editor + }, + + // pattern channel scroll + { + { 177, 274, 286 }, // normal pattern editor + { 57, 210, 222 }, // extended pattern editor + } + }, + + // pattern stretch + { + // no pattern channel scroll + { + { 176, 275, 286 }, // normal pattern editor + { 56, 221, 232 }, // extended pattern editor + }, + + // pattern channel scroll + { + { 175, 274, 284 }, // normal pattern editor + { 55, 209, 219 }, // extended pattern editor + }, + } +}; + +const uint8_t pattCursorXTab[2 * 4 * 8] = +{ + // no volume column shown + 32, 88, 104, 0, 0, 120, 136, 152, // 4 columns visible + 32, 80, 88, 0, 0, 96, 104, 112, // 6 columns visible + 32, 56, 64, 0, 0, 72, 80, 88, // 8 columns visible + 32, 52, 56, 0, 0, 60, 64, 68, // 12 columns visible + + // volume column shown + 32, 96, 104, 120, 128, 144, 152, 160, // 4 columns visible + 32, 56, 64, 80, 88, 96, 104, 112, // 6 columns visible + 32, 60, 64, 72, 76, 84, 88, 92, // 8 columns visible + 32, 60, 64, 72, 76, 84, 88, 92, // 12 columns visible +}; + +const uint8_t pattCursorWTab[2 * 4 * 8] = +{ + // no volume column shown + 48, 16, 16, 0, 0, 16, 16, 16, // 4 columns visible + 48, 8, 8, 0, 0, 8, 8, 8, // 6 columns visible + 24, 8, 8, 0, 0, 8, 8, 8, // 8 columns visible + 16, 4, 4, 0, 0, 4, 4, 4, // 12 columns visible + + // volume column shown + 48, 8, 8, 8, 8, 8, 8, 8, // 4 columns visible + 24, 8, 8, 8, 8, 8, 8, 8, // 6 columns visible + 24, 4, 4, 4, 4, 4, 4, 4, // 8 columns visible + 24, 4, 4, 4, 4, 4, 4, 4 // 12 columns visible +}; + +const char chDecTab1[MAX_VOICES+1] = +{ + '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', + '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', + '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', + '3', '3', '3' +}; + +const char chDecTab2[MAX_VOICES+1] = +{ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2' +}; + +const int16_t sinusTables[256 * 5] = +{ + 0, 201, 402, 603, 804, 1005, 1206, 1407, 1608, 1809, + 2009, 2210, 2410, 2611, 2811, 3011, 3212, 3412, 3612, 3811, + 4011, 4210, 4410, 4609, 4808, 5007, 5205, 5404, 5602, 5800, + 5997, 6195, 6392, 6589, 6786, 6983, 7179, 7375, 7571, 7766, + 7961, 8156, 8351, 8545, 8739, 8933, 9126, 9319, 9511, 9704, + 9896, 10087, 10278, 10469, 10659, 10849, 11039, 11228, 11416, 11605, + 11792, 11980, 12167, 12353, 12539, 12725, 12910, 13094, 13278, 13462, + 13645, 13827, 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, + 15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672, 16845, 17017, + 17189, 17360, 17530, 17699, 17868, 18036, 18204, 18371, 18537, 18702, + 18867, 19031, 19194, 19357, 19519, 19680, 19840, 20000, 20159, 20317, + 20474, 20631, 20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855, + 22004, 22153, 22301, 22447, 22593, 22739, 22883, 23026, 23169, 23311, + 23452, 23592, 23731, 23869, 24006, 24143, 24278, 24413, 24546, 24679, + 24811, 24942, 25071, 25200, 25328, 25456, 25582, 25707, 25831, 25954, + 26076, 26198, 26318, 26437, 26555, 26673, 26789, 26904, 27018, 27132, + 27244, 27355, 27465, 27574, 27682, 27790, 27896, 28000, 28104, 28207, + 28309, 28410, 28509, 28608, 28705, 28802, 28897, 28991, 29084, 29176, + 29267, 29357, 29446, 29534, 29620, 29706, 29790, 29873, 29955, 30036, + 30116, 30194, 30272, 30348, 30423, 30498, 30570, 30642, 30713, 30782, + 30851, 30918, 30984, 31049, 31112, 31175, 31236, 31296, 31355, 31413, + 31469, 31525, 31579, 31632, 31684, 31735, 31784, 31832, 31879, 31925, + 31970, 32013, 32056, 32097, 32136, 32175, 32212, 32249, 32284, 32317, + 32350, 32381, 32411, 32440, 32468, 32494, 32520, 32544, 32566, 32588, + 32608, 32627, 32645, 32662, 32677, 32691, 32704, 32716, 32727, 32736, + 32744, 32751, 32756, 32760, 32764, 32765, 32766, 32765, 32764, 32760, + 32756, 32751, 32744, 32736, 32727, 32716, 32704, 32691, 32677, 32662, + 32645, 32627, 32608, 32588, 32566, 32544, 32520, 32494, 32468, 32440, + 32411, 32381, 32350, 32317, 32284, 32249, 32212, 32175, 32136, 32097, + 32056, 32013, 31970, 31925, 31879, 31832, 31784, 31735, 31684, 31632, + 31579, 31525, 31469, 31413, 31355, 31296, 31236, 31175, 31112, 31049, + 30984, 30918, 30851, 30782, 30713, 30642, 30570, 30498, 30423, 30348, + 30272, 30194, 30116, 30036, 29955, 29873, 29790, 29706, 29620, 29534, + 29446, 29357, 29267, 29176, 29084, 28991, 28897, 28802, 28705, 28608, + 28509, 28410, 28309, 28207, 28104, 28000, 27896, 27790, 27682, 27574, + 27465, 27355, 27244, 27132, 27018, 26904, 26789, 26673, 26555, 26437, + 26318, 26198, 26076, 25954, 25831, 25707, 25582, 25456, 25328, 25200, + 25071, 24942, 24811, 24679, 24546, 24413, 24278, 24143, 24006, 23869, + 23731, 23592, 23452, 23311, 23169, 23026, 22883, 22739, 22593, 22447, + 22301, 22153, 22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942, + 20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680, 19519, 19357, + 19194, 19031, 18867, 18702, 18537, 18371, 18204, 18036, 17868, 17699, + 17530, 17360, 17189, 17017, 16845, 16672, 16499, 16325, 16150, 15975, + 15799, 15623, 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, + 14009, 13827, 13645, 13462, 13278, 13094, 12910, 12725, 12539, 12353, + 12167, 11980, 11792, 11605, 11416, 11228, 11039, 10849, 10659, 10469, + 10278, 10087, 9896, 9704, 9511, 9319, 9126, 8933, 8739, 8545, + 8351, 8156, 7961, 7766, 7571, 7375, 7179, 6983, 6786, 6589, + 6392, 6195, 5997, 5800, 5602, 5404, 5205, 5007, 4808, 4609, + 4410, 4210, 4011, 3811, 3612, 3412, 3212, 3011, 2811, 2611, + 2410, 2210, 2009, 1809, 1608, 1407, 1206, 1005, 804, 603, + 402, 201, 0, -201, -402, -603, -804, -1005, -1206, -1407, + -1608, -1809, -2009, -2210, -2410, -2611, -2811, -3011, -3212, -3412, + -3612, -3811, -4011, -4210, -4410, -4609, -4808, -5007, -5205, -5404, + -5602, -5800, -5997, -6195, -6392, -6589, -6786, -6983, -7179, -7375, + -7571, -7766, -7961, -8156, -8351, -8545, -8739, -8933, -9126, -9319, + -9511, -9704, -9896, -10087, -10278, -10469, -10659, -10849, -11039, -11228, + -11416, -11605, -11792, -11980, -12167, -12353, -12539, -12725, -12910, -13094, + -13278, -13462, -13645, -13827, -14009, -14191, -14372, -14552, -14732, -14911, + -15090, -15268, -15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672, + -16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036, -18204, -18371, + -18537, -18702, -18867, -19031, -19194, -19357, -19519, -19680, -19840, -20000, + -20159, -20317, -20474, -20631, -20787, -20942, -21096, -21249, -21402, -21554, + -21705, -21855, -22004, -22153, -22301, -22447, -22593, -22739, -22883, -23026, + -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143, -24278, -24413, + -24546, -24679, -24811, -24942, -25071, -25200, -25328, -25456, -25582, -25707, + -25831, -25954, -26076, -26198, -26318, -26437, -26555, -26673, -26789, -26904, + -27018, -27132, -27244, -27355, -27465, -27574, -27682, -27790, -27896, -28000, + -28104, -28207, -28309, -28410, -28509, -28608, -28705, -28802, -28897, -28991, + -29084, -29176, -29267, -29357, -29446, -29534, -29620, -29706, -29790, -29873, + -29955, -30036, -30116, -30194, -30272, -30348, -30423, -30498, -30570, -30642, + -30713, -30782, -30851, -30918, -30984, -31049, -31112, -31175, -31236, -31296, + -31355, -31413, -31469, -31525, -31579, -31632, -31684, -31735, -31784, -31832, + -31879, -31925, -31970, -32013, -32056, -32097, -32136, -32175, -32212, -32249, + -32284, -32317, -32350, -32381, -32411, -32440, -32468, -32494, -32520, -32544, + -32566, -32588, -32608, -32627, -32645, -32662, -32677, -32691, -32704, -32716, + -32727, -32736, -32744, -32751, -32756, -32760, -32764, -32765, -32766, -32765, + -32764, -32760, -32756, -32751, -32744, -32736, -32727, -32716, -32704, -32691, + -32677, -32662, -32645, -32627, -32608, -32588, -32566, -32544, -32520, -32494, + -32468, -32440, -32411, -32381, -32350, -32317, -32284, -32249, -32212, -32175, + -32136, -32097, -32056, -32013, -31970, -31925, -31879, -31832, -31784, -31735, + -31684, -31632, -31579, -31525, -31469, -31413, -31355, -31296, -31236, -31175, + -31112, -31049, -30984, -30918, -30851, -30782, -30713, -30642, -30570, -30498, + -30423, -30348, -30272, -30194, -30116, -30036, -29955, -29873, -29790, -29706, + -29620, -29534, -29446, -29357, -29267, -29176, -29084, -28991, -28897, -28802, + -28705, -28608, -28509, -28410, -28309, -28207, -28104, -28000, -27896, -27790, + -27682, -27574, -27465, -27355, -27244, -27132, -27018, -26904, -26789, -26673, + -26555, -26437, -26318, -26198, -26076, -25954, -25831, -25707, -25582, -25456, + -25328, -25200, -25071, -24942, -24811, -24679, -24546, -24413, -24278, -24143, + -24006, -23869, -23731, -23592, -23452, -23311, -23169, -23026, -22883, -22739, + -22593, -22447, -22301, -22153, -22004, -21855, -21705, -21554, -21402, -21249, + -21096, -20942, -20787, -20631, -20474, -20317, -20159, -20000, -19840, -19680, + -19519, -19357, -19194, -19031, -18867, -18702, -18537, -18371, -18204, -18036, + -17868, -17699, -17530, -17360, -17189, -17017, -16845, -16672, -16499, -16325, + -16150, -15975, -15799, -15623, -15446, -15268, -15090, -14911, -14732, -14552, + -14372, -14191, -14009, -13827, -13645, -13462, -13278, -13094, -12910, -12725, + -12539, -12353, -12167, -11980, -11792, -11605, -11416, -11228, -11039, -10849, + -10659, -10469, -10278, -10087, -9896, -9704, -9511, -9319, -9126, -8933, + -8739, -8545, -8351, -8156, -7961, -7766, -7571, -7375, -7179, -6983, + -6786, -6589, -6392, -6195, -5997, -5800, -5602, -5404, -5205, -5007, + -4808, -4609, -4410, -4210, -4011, -3811, -3612, -3412, -3212, -3011, + -2811, -2611, -2410, -2210, -2009, -1809, -1608, -1407, -1206, -1005, + -804, -603, -402, -201, 0, 201, 402, 603, 804, 1005, + 1206, 1407, 1608, 1809, 2009, 2210, 2410, 2611, 2811, 3011, + 3212, 3412, 3612, 3811, 4011, 4210, 4410, 4609, 4808, 5007, + 5205, 5404, 5602, 5800, 5997, 6195, 6392, 6589, 6786, 6983, + 7179, 7375, 7571, 7766, 7961, 8156, 8351, 8545, 8739, 8933, + 9126, 9319, 9511, 9704, 9896, 10087, 10278, 10469, 10659, 10849, + 11039, 11228, 11416, 11605, 11792, 11980, 12167, 12353, 12539, 12725, + 12910, 13094, 13278, 13462, 13645, 13827, 14009, 14191, 14372, 14552, + 14732, 14911, 15090, 15268, 15446, 15623, 15799, 15975, 16150, 16325, + 16499, 16672, 16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036, + 18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357, 19519, 19680, + 19840, 20000, 20159, 20317, 20474, 20631, 20787, 20942, 21096, 21249, + 21402, 21554, 21705, 21855, 22004, 22153, 22301, 22447, 22593, 22739, + 22883, 23026, 23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143, + 24278, 24413, 24546, 24679, 24811, 24942, 25071, 25200, 25328, 25456, + 25582, 25707, 25831, 25954, 26076, 26198, 26318, 26437, 26555, 26673, + 26789, 26904, 27018, 27132, 27244, 27355, 27465, 27574, 27682, 27790, + 27896, 28000, 28104, 28207, 28309, 28410, 28509, 28608, 28705, 28802, + 28897, 28991, 29084, 29176, 29267, 29357, 29446, 29534, 29620, 29706, + 29790, 29873, 29955, 30036, 30116, 30194, 30272, 30348, 30423, 30498, + 30570, 30642, 30713, 30782, 30851, 30918, 30984, 31049, 31112, 31175, + 31236, 31296, 31355, 31413, 31469, 31525, 31579, 31632, 31684, 31735, + 31784, 31832, 31879, 31925, 31970, 32013, 32056, 32097, 32136, 32175, + 32212, 32249, 32284, 32317, 32350, 32381, 32411, 32440, 32468, 32494, + 32520, 32544, 32566, 32588, 32608, 32627, 32645, 32662, 32677, 32691, + 32704, 32716, 32727, 32736, 32744, 32751, 32756, 32760, 32764, 32765 +}; + +const SDL_Keycode key2VolTab[16] = +{ + SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_MINUS, SDLK_PLUS, SDLK_d, + SDLK_u, SDLK_s, SDLK_v, SDLK_p, SDLK_l, SDLK_r, SDLK_m +}; + +const SDL_Keycode key2EfxTab[36] = +{ + SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, + SDLK_8, SDLK_9, SDLK_a, SDLK_b, SDLK_c, SDLK_d, SDLK_e, SDLK_f, + SDLK_g, SDLK_h, SDLK_i, SDLK_j, SDLK_k, SDLK_l, SDLK_m, SDLK_n, + SDLK_o, SDLK_p, SDLK_q, SDLK_r, SDLK_s, SDLK_t, SDLK_u, SDLK_v, + SDLK_w, SDLK_x, SDLK_y, SDLK_z +}; + +const SDL_Keycode key2HexTab[16] = +{ + SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, + SDLK_8, SDLK_9, SDLK_a, SDLK_b, SDLK_c, SDLK_d, SDLK_e, SDLK_f +}; + +const uint8_t scopeMuteBMPWidths[16] = +{ + 162,111, 76, 56, 42, 35, 28, 24, + 21, 21, 17, 17, 12, 12, 9, 9 +}; + +const uint8_t scopeMuteBMPHeights[16] = +{ + 27, 27, 26, 25, 25, 25, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24 +}; + +const uint8_t *scopeMuteBMPPointers[16] = +{ + scopeMuteBMP1, scopeMuteBMP2, scopeMuteBMP3, scopeMuteBMP4, + scopeMuteBMP5, scopeMuteBMP6, scopeMuteBMP7, scopeMuteBMP8, + scopeMuteBMP9, scopeMuteBMP9, scopeMuteBMP10,scopeMuteBMP10, + scopeMuteBMP11,scopeMuteBMP11,scopeMuteBMP12,scopeMuteBMP12 +}; + +const uint16_t scopeLenTab[16][32] = +{ + /* 2 ch */ {285,285}, + /* 4 ch */ {141,141,141,141}, + /* 6 ch */ {93,93,93,93,93,93}, + /* 8 ch */ {69,69,69,69,69,69,69,69}, + /* 10 ch */ {55,55,55,54,54,55,55,55,54,54}, + /* 12 ch */ {45,45,45,45,45,45,45,45,45,45,45,45}, + /* 14 ch */ {39,38,38,38,38,38,38,39,38,38,38,38,38,38}, + /* 16 ch */ {33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33}, + /* 18 ch */ {29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29}, + /* 20 ch */ {26,26,26,26,26,26,26,26,25,25,26,26,26,26,26,26,26,26,25,25}, + /* 22 ch */ {24,24,23,23,23,23,23,23,23,23,23,24,24,23,23,23,23,23,23,23,23,23}, + /* 24 ch */ {21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21}, + /* 26 ch */ {20,20,19,19,19,19,19,19,19,19,19,19,19,20,20,19,19,19,19,19,19,19,19,19,19,19}, + /* 28 ch */ {18,18,18,18,18,18,18,18,17,17,17,17,17,17,18,18,18,18,18,18,18,18,17,17,17,17,17,17}, + /* 30 ch */ {17,17,17,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,16,16,16,16,16,16,16,16,16,16,16,16}, + /* 32 ch */ {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15} +}; + +/* ----------------------------------------------------------------------- */ +/* CONFIG TABLE */ +/* ----------------------------------------------------------------------- */ + +// default FT2 clone FT2.CFG (unencrypted) +const uint8_t defConfigData[CONFIG_FILE_SIZE] = +{ + 0x46,0x61,0x73,0x74,0x54,0x72,0x61,0x63,0x6B,0x65,0x72,0x20,0x32,0x2E,0x30,0x20,0x63,0x6F,0x6E,0x66, + 0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,0x69,0x6C,0x65,0x1A,0x01,0x01,0x80,0xBB,0x00, + 0x00,0xFF,0x00,0x00,0x01,0xDC,0x00,0x00,0x00,0x01,0x01,0x00,0x03,0x00,0xFF,0x00,0x20,0x02,0x01,0x00, + 0x05,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x01,0x01,0x04,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x24,0x2F,0x3F,0x09,0x09,0x10,0x3F,0x3F,0x3F,0x13,0x18,0x26,0x3F,0x3F,0x3F,0x27,0x27, + 0x27,0x00,0x00,0x00,0x08,0x0A,0x0F,0x20,0x29,0x3F,0x0F,0x0F,0x0F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x01,0x0A,0x10,0x0A,0xE0,0x08,0xC0,0x08,0x40,0x08,0x20,0x08, + 0xF1,0x04,0xF2,0x04,0x81,0x04,0x82,0x04,0x20,0x30,0x40,0x50,0x61,0x62,0x71,0x72,0x91,0x92,0xF8,0x03, + 0x2D,0x88,0x18,0x00,0x66,0x88,0x18,0x00,0x00,0x01,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x01,0x01,0x10,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x64,0x00,0x01,0x01, + 0x01,0x01,0x12,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x01,0x60,0x00,0x05,0x56,0x6F,0x67, + 0x75,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x02,0x16,0x05,0x4D,0x72,0x2E,0x20,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x04,0x4C,0x6F,0x6F,0x74,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x07, + 0x0A,0x4C,0x69,0x7A,0x61,0x72,0x64,0x6B,0x69,0x6E,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x06,0x03,0x41,0x6C,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x05,0x03,0x55,0x62,0x65, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x04,0x00,0x04,0x06,0x4E,0x69,0x6B,0x6C,0x61,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x05,0x4A,0x65,0x6E,0x73,0x61,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02, + 0x05,0x54,0x6F,0x62,0x62,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x01,0x08,0x4B,0x61,0x72,0x6F,0x6C,0x69,0x6E,0x61,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x02,0x00, + 0x00,0x00,0x00,0x99,0xE2,0x27,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x30, + 0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x2C,0x00,0x0E,0x00,0x08,0x00,0x18,0x00,0x16,0x00,0x20,0x00,0x08, + 0x00,0x3C,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x5A,0x00,0x00,0x00,0x64,0x00,0x00, + 0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x0A,0x00,0x28,0x00,0x1E,0x00,0x18,0x00,0x32,0x00,0x20, + 0x00,0x3C,0x00,0x20,0x00,0x46,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x5A,0x00,0x20,0x00,0x64,0x00,0x20, + 0x00,0x6E,0x00,0x20,0x00,0x78,0x00,0x20,0x00,0x82,0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x04,0x00,0x40, + 0x00,0x08,0x00,0x2C,0x00,0x0E,0x00,0x08,0x00,0x18,0x00,0x16,0x00,0x20,0x00,0x08,0x00,0x3C,0x00,0x00, + 0x00,0x46,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x5A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x6E,0x00,0x00, + 0x00,0x00,0x00,0x20,0x00,0x0A,0x00,0x28,0x00,0x1E,0x00,0x18,0x00,0x32,0x00,0x20,0x00,0x3C,0x00,0x20, + 0x00,0x46,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x5A,0x00,0x20,0x00,0x64,0x00,0x20,0x00,0x6E,0x00,0x20, + 0x00,0x78,0x00,0x20,0x00,0x82,0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x2C, + 0x00,0x0E,0x00,0x08,0x00,0x18,0x00,0x16,0x00,0x20,0x00,0x08,0x00,0x3C,0x00,0x00,0x00,0x46,0x00,0x00, + 0x00,0x50,0x00,0x00,0x00,0x5A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x20, + 0x00,0x0A,0x00,0x28,0x00,0x1E,0x00,0x18,0x00,0x32,0x00,0x20,0x00,0x3C,0x00,0x20,0x00,0x46,0x00,0x20, + 0x00,0x50,0x00,0x20,0x00,0x5A,0x00,0x20,0x00,0x64,0x00,0x20,0x00,0x6E,0x00,0x20,0x00,0x78,0x00,0x20, + 0x00,0x82,0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x2C,0x00,0x0E,0x00,0x08, + 0x00,0x18,0x00,0x16,0x00,0x20,0x00,0x08,0x00,0x3C,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x50,0x00,0x00, + 0x00,0x5A,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x0A,0x00,0x28, + 0x00,0x1E,0x00,0x18,0x00,0x32,0x00,0x20,0x00,0x3C,0x00,0x20,0x00,0x46,0x00,0x20,0x00,0x50,0x00,0x20, + 0x00,0x5A,0x00,0x20,0x00,0x64,0x00,0x20,0x00,0x6E,0x00,0x20,0x00,0x78,0x00,0x20,0x00,0x82,0x00,0x20, + 0x00,0x00,0x00,0x30,0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x2C,0x00,0x0E,0x00,0x08,0x00,0x18,0x00,0x16, + 0x00,0x20,0x00,0x08,0x00,0x3C,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x5A,0x00,0x00, + 0x00,0x64,0x00,0x00,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x0A,0x00,0x28,0x00,0x1E,0x00,0x18, + 0x00,0x32,0x00,0x20,0x00,0x3C,0x00,0x20,0x00,0x46,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x5A,0x00,0x20, + 0x00,0x64,0x00,0x20,0x00,0x6E,0x00,0x20,0x00,0x78,0x00,0x20,0x00,0x82,0x00,0x20,0x00,0x00,0x00,0x30, + 0x00,0x04,0x00,0x40,0x00,0x08,0x00,0x2C,0x00,0x0E,0x00,0x08,0x00,0x18,0x00,0x16,0x00,0x20,0x00,0x08, + 0x00,0x3C,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x5A,0x00,0x00,0x00,0x64,0x00,0x00, + 0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x0A,0x00,0x28,0x00,0x1E,0x00,0x18,0x00,0x32,0x00,0x20, + 0x00,0x3C,0x00,0x20,0x00,0x46,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x5A,0x00,0x20,0x00,0x64,0x00,0x20, + 0x00,0x6E,0x00,0x20,0x00,0x78,0x00,0x20,0x00,0x82,0x00,0x20,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06, + 0x00,0x06,0x00,0x06,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03, + 0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05, + 0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02, + 0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x05,0x00,0x05, + 0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC8,0x00,0x03,0x00,0x40,0x1F,0x40, + 0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40, + 0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x40,0x1F,0x01,0x00,0x00,0x08,0x00,0x00,0x00 +}; diff --git a/src/ft2_tables.h b/src/ft2_tables.h @@ -0,0 +1,49 @@ +#pragma once + +#include <stdint.h> +#include "ft2_palette.h" // pal16 typedef +#include "ft2_pattern_ed.h" // pattCoord_t/pattCoord2_t/pattCoordsMouse_t/markCoord_t typedef +#include "ft2_header.h" // MAX_VOICES +#include "ft2_config.h" // CONFIG_FILE_SIZE + +#define LOG_TABLE_BITS 24 +#define FAST_SINC_TABLE_BITS 14 + +#define KEY2VOL_ENTRIES (signed)(sizeof (key2VolTab) / sizeof (SDL_Keycode)) +#define KEY2EFX_ENTRIES (signed)(sizeof (key2EfxTab) / sizeof (SDL_Keycode)) +#define KEY2HEX_ENTRIES (signed)(sizeof (key2HexTab) / sizeof (SDL_Keycode)) + +extern const int8_t vibSineTab[256]; // for auto-vibrato +extern const uint8_t vibTab[32]; +extern const uint16_t amigaPeriod[12 * 8]; +extern const uint16_t amigaFinePeriod[12 * 8]; +extern const int16_t linearPeriods[1936]; +extern const int16_t amigaPeriods[1936]; +extern const uint32_t logTab[768]; + +extern const uint32_t panningTab[257]; +extern const int16_t fastSincTable[256 * 4]; + +extern pal16 palTable[12][16]; +extern const uint16_t chanWidths[6]; +extern const pattCoordsMouse_t pattCoordMouseTable[2][2][2]; +extern const int16_t sinusTables[256 * 5]; +extern const uint8_t noteTab1[96]; +extern const uint8_t noteTab2[96]; +extern const uint8_t hex2Dec[256]; +extern const pattCoord_t pattCoordTable[2][2][2]; +extern const pattCoord2_t pattCoord2Table[2][2][2]; +extern const markCoord_t markCoordTable[2][2][2]; +extern const uint8_t pattCursorXTab[2 * 4 * 8]; +extern const uint8_t pattCursorWTab[2 * 4 * 8]; +extern const char chDecTab1[MAX_VOICES+1]; +extern const char chDecTab2[MAX_VOICES+1]; +extern const SDL_Keycode key2VolTab[16]; +extern const SDL_Keycode key2EfxTab[36]; +extern const SDL_Keycode key2HexTab[16]; +extern const uint8_t scopeMuteBMPWidths[16]; +extern const uint8_t scopeMuteBMPHeights[16]; +extern const uint8_t *scopeMuteBMPPointers[16]; +extern const uint16_t scopeLenTab[16][32]; + +extern const uint8_t defConfigData[CONFIG_FILE_SIZE]; diff --git a/src/ft2_trim.c b/src/ft2_trim.c @@ -16,7 +16,7 @@ #include "ft2_audio.h" #include "ft2_mouse.h" -// Messy But Works™ +// this is truly a mess, but it works... static char byteFormatBuffer[64], tmpInstrName[1 + MAX_INST][22 + 1], tmpInstName[MAX_INST][22 + 1]; static bool removePatt, removeInst, removeSamp, removeChans, removeSmpDataAfterLoop, convSmpsTo8Bit; @@ -35,6 +35,8 @@ static void freeTmpInstruments(void) { if (tmpInstr[i] != NULL) { + // don't free samples, as the pointers are shared with main instruments... + free(tmpInstr[i]); tmpInstr[i] = NULL; } @@ -56,7 +58,7 @@ static bool setTmpInstruments(void) return false; } - memcpy(tmpInstr[i], instr[i], sizeof (instrTyp)); + tmpInstr[i] = instr[i]; } } @@ -99,7 +101,8 @@ static int16_t getUsedTempSamples(uint16_t nr) i--; /* Yes, 'i' can be -1 here, and will be set to at least 0 - * because of ins->ta values. Possibly an FT2 bug... */ + ** because of ins->ta values. Possibly an FT2 bug... + **/ for (j = 0; j < 96; j++) { if (ins->ta[j] > i) @@ -410,10 +413,11 @@ static void wipeSamplesUnused(bool testWipeSize, int16_t ai) { // sample is unused - if (s->pek != NULL && !testWipeSize) - free(s->pek); + if (s->origPek != NULL && !testWipeSize) + free(s->origPek); memset(s, 0, sizeof (sampleTyp)); + s->origPek = NULL; s->pek = NULL; } } @@ -484,7 +488,7 @@ static void wipeSmpDataAfterLoop(bool testWipeSize, int16_t ai) for (int16_t j = 0; j < l; j++) { s = &ins->samp[j]; - if (s->pek != NULL && s->typ & 3 && s->len > 0 && s->len > s->repS+s->repL) + if (s->origPek != NULL && s->typ & 3 && s->len > 0 && s->len > s->repS+s->repL) { if (!testWipeSize) restoreSample(s); @@ -495,14 +499,19 @@ static void wipeSmpDataAfterLoop(bool testWipeSize, int16_t ai) if (s->len <= 0) { s->len = 0; - free(s->pek); + + free(s->origPek); + s->origPek = NULL; s->pek = NULL; } else { - newPtr = (int8_t *)realloc(s->pek, s->len + LOOP_FIX_LEN); + newPtr = (int8_t *)realloc(s->origPek, s->len + LOOP_FIX_LEN); if (newPtr != NULL) - s->pek = newPtr; + { + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; + } } } @@ -547,37 +556,41 @@ static void convertSamplesTo8bit(bool testWipeSize, int16_t ai) for (int16_t j = 0; j < k; j++) { s = &ins->samp[j]; - if (s->pek != NULL && (s->typ & 16) && s->len > 0) + if (s->origPek != NULL && (s->typ & 16) && s->len > 0) { if (testWipeSize) { s->typ &= ~16; - s->len /= 2; - s->repL /= 2; - s->repS /= 2; + s->len >>= 1; + s->repL >>= 1; + s->repS >>= 1; } else { restoreSample(s); + assert(s->pek != NULL); src16 = (int16_t *)s->pek; dst8 = s->pek; - newLen = s->len / 2; + newLen = s->len >> 1; for (int32_t a = 0; a < newLen; a++) { smp8 = src16[a] >> 8; dst8[a] = smp8; } - s->repL /= 2; - s->repS /= 2; - s->len /= 2; + s->repL >>= 1; + s->repS >>= 1; + s->len >>= 1; s->typ &= ~16; - newPtr = (int8_t *)realloc(s->pek, s->len + LOOP_FIX_LEN); + newPtr = (int8_t *)realloc(s->origPek, s->len + LOOP_FIX_LEN); if (newPtr != NULL) - s->pek = newPtr; + { + s->origPek = newPtr; + s->pek = s->origPek + SMP_DAT_OFFSET; + } fixSample(s); } diff --git a/src/helpdata/FT2.HLP b/src/helpdata/FT2.HLP @@ -771,9 +771,9 @@ you exit the program. >@X060@C002 The mixing routine interpolates the sample value between the sample points to remove unwanted noise in the sound. Real FT2 uses -2-tap linear interpolation, while this clone uses 3-tap quadratic interpolation for -improved high frequencies. Turning it off will make the audio sharper, -but it will also be noisier. +2-tap linear interpolation, while this clone uses 4-tap cubic spline +interpolation for improved high frequencies. Turning it off will make +the audio sharper, but it will also be noisier. >@X040@C001Volume ramping: >@X060@C002 diff --git a/src/helpdata/ft2_help_data.h b/src/helpdata/ft2_help_data.h @@ -3,9 +3,9 @@ #include <stdint.h> -#define HELP_DATA_LEN 27912 +#define HELP_DATA_LEN 27916 -const uint8_t helpData[27912] = +const uint8_t helpData[27916] = { 0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, @@ -1754,585 +1754,586 @@ const uint8_t helpData[27912] = 0x61,0x6E,0x74,0x65,0x64,0x20,0x6E,0x6F,0x69,0x73,0x65,0x20, 0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x73,0x6F,0x75,0x6E,0x64, 0x2E,0x20,0x52,0x65,0x61,0x6C,0x20,0x46,0x54,0x32,0x20,0x75, - 0x73,0x65,0x73,0x53,0x32,0x2D,0x74,0x61,0x70,0x20,0x6C,0x69, + 0x73,0x65,0x73,0x45,0x32,0x2D,0x74,0x61,0x70,0x20,0x6C,0x69, 0x6E,0x65,0x61,0x72,0x20,0x69,0x6E,0x74,0x65,0x72,0x70,0x6F, 0x6C,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x20,0x77,0x68,0x69,0x6C, 0x65,0x20,0x74,0x68,0x69,0x73,0x20,0x63,0x6C,0x6F,0x6E,0x65, - 0x20,0x75,0x73,0x65,0x73,0x20,0x33,0x2D,0x74,0x61,0x70,0x20, - 0x71,0x75,0x61,0x64,0x72,0x61,0x74,0x69,0x63,0x20,0x69,0x6E, - 0x74,0x65,0x72,0x70,0x6F,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x20, - 0x66,0x6F,0x72,0x46,0x69,0x6D,0x70,0x72,0x6F,0x76,0x65,0x64, - 0x20,0x68,0x69,0x67,0x68,0x20,0x66,0x72,0x65,0x71,0x75,0x65, - 0x6E,0x63,0x69,0x65,0x73,0x2E,0x20,0x54,0x75,0x72,0x6E,0x69, - 0x6E,0x67,0x20,0x69,0x74,0x20,0x6F,0x66,0x66,0x20,0x77,0x69, - 0x6C,0x6C,0x20,0x6D,0x61,0x6B,0x65,0x20,0x74,0x68,0x65,0x20, - 0x61,0x75,0x64,0x69,0x6F,0x20,0x73,0x68,0x61,0x72,0x70,0x65, - 0x72,0x2C,0x1C,0x62,0x75,0x74,0x20,0x69,0x74,0x20,0x77,0x69, - 0x6C,0x6C,0x20,0x61,0x6C,0x73,0x6F,0x20,0x62,0x65,0x20,0x6E, - 0x6F,0x69,0x73,0x69,0x65,0x72,0x2E,0x00,0x1A,0x3E,0x40,0x58, - 0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x56,0x6F,0x6C,0x75, - 0x6D,0x65,0x20,0x72,0x61,0x6D,0x70,0x69,0x6E,0x67,0x3A,0x0B, - 0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x3B, - 0x45,0x6E,0x61,0x62,0x6C,0x65,0x73,0x20,0x74,0x68,0x65,0x20, - 0x61,0x6E,0x74,0x69,0x2D,0x63,0x6C,0x69,0x63,0x6B,0x20,0x73, - 0x79,0x73,0x74,0x65,0x6D,0x20,0x69,0x6E,0x20,0x74,0x68,0x65, - 0x20,0x61,0x75,0x64,0x69,0x6F,0x20,0x6D,0x69,0x78,0x65,0x72, - 0x20,0x28,0x46,0x54,0x32,0x2E,0x30,0x38,0x2B,0x29,0x2E,0x3B, - 0x50,0x6C,0x65,0x61,0x73,0x65,0x20,0x6E,0x6F,0x74,0x65,0x20, - 0x74,0x68,0x61,0x74,0x20,0x6F,0x72,0x69,0x67,0x69,0x6E,0x61, - 0x6C,0x20,0x46,0x54,0x32,0x20,0x63,0x61,0x6E,0x27,0x74,0x20, - 0x6C,0x6F,0x61,0x64,0x20,0x74,0x68,0x69,0x73,0x20,0x63,0x6F, - 0x6E,0x66,0x69,0x67,0x20,0x65,0x6E,0x74,0x72,0x79,0x2C,0x0B, - 0x63,0x6C,0x6F,0x6E,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x2E,0x00, - 0x18,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31, - 0x31,0x2D,0x62,0x69,0x74,0x20,0x64,0x69,0x74,0x68,0x65,0x72, + 0x20,0x75,0x73,0x65,0x73,0x20,0x34,0x2D,0x74,0x61,0x70,0x20, + 0x63,0x75,0x62,0x69,0x63,0x20,0x73,0x70,0x6C,0x69,0x6E,0x65, + 0x20,0x45,0x69,0x6E,0x74,0x65,0x72,0x70,0x6F,0x6C,0x61,0x74, + 0x69,0x6F,0x6E,0x20,0x66,0x6F,0x72,0x20,0x69,0x6D,0x70,0x72, + 0x6F,0x76,0x65,0x64,0x20,0x68,0x69,0x67,0x68,0x20,0x66,0x72, + 0x65,0x71,0x75,0x65,0x6E,0x63,0x69,0x65,0x73,0x2E,0x20,0x54, + 0x75,0x72,0x6E,0x69,0x6E,0x67,0x20,0x69,0x74,0x20,0x6F,0x66, + 0x66,0x20,0x77,0x69,0x6C,0x6C,0x20,0x6D,0x61,0x6B,0x65,0x2F, + 0x74,0x68,0x65,0x20,0x61,0x75,0x64,0x69,0x6F,0x20,0x73,0x68, + 0x61,0x72,0x70,0x65,0x72,0x2C,0x20,0x62,0x75,0x74,0x20,0x69, + 0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,0x61,0x6C,0x73,0x6F,0x20, + 0x62,0x65,0x20,0x6E,0x6F,0x69,0x73,0x69,0x65,0x72,0x2E,0x00, + 0x1A,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31, + 0x56,0x6F,0x6C,0x75,0x6D,0x65,0x20,0x72,0x61,0x6D,0x70,0x69, + 0x6E,0x67,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43, + 0x30,0x30,0x32,0x3B,0x45,0x6E,0x61,0x62,0x6C,0x65,0x73,0x20, + 0x74,0x68,0x65,0x20,0x61,0x6E,0x74,0x69,0x2D,0x63,0x6C,0x69, + 0x63,0x6B,0x20,0x73,0x79,0x73,0x74,0x65,0x6D,0x20,0x69,0x6E, + 0x20,0x74,0x68,0x65,0x20,0x61,0x75,0x64,0x69,0x6F,0x20,0x6D, + 0x69,0x78,0x65,0x72,0x20,0x28,0x46,0x54,0x32,0x2E,0x30,0x38, + 0x2B,0x29,0x2E,0x3B,0x50,0x6C,0x65,0x61,0x73,0x65,0x20,0x6E, + 0x6F,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x6F,0x72,0x69, + 0x67,0x69,0x6E,0x61,0x6C,0x20,0x46,0x54,0x32,0x20,0x63,0x61, + 0x6E,0x27,0x74,0x20,0x6C,0x6F,0x61,0x64,0x20,0x74,0x68,0x69, + 0x73,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,0x20,0x65,0x6E,0x74, + 0x72,0x79,0x2C,0x0B,0x63,0x6C,0x6F,0x6E,0x65,0x20,0x6F,0x6E, + 0x6C,0x79,0x2E,0x00,0x18,0x3E,0x40,0x58,0x30,0x34,0x30,0x40, + 0x43,0x30,0x30,0x31,0x31,0x2D,0x62,0x69,0x74,0x20,0x64,0x69, + 0x74,0x68,0x65,0x72,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30, + 0x40,0x43,0x30,0x30,0x32,0x21,0x57,0x6F,0x72,0x6B,0x73,0x20, + 0x66,0x6F,0x72,0x20,0x31,0x36,0x2D,0x62,0x69,0x74,0x20,0x61, + 0x75,0x64,0x69,0x6F,0x20,0x6D,0x6F,0x64,0x65,0x20,0x6F,0x6E, + 0x6C,0x79,0x2E,0x4E,0x41,0x70,0x70,0x6C,0x69,0x65,0x73,0x20, + 0x72,0x61,0x6E,0x64,0x6F,0x6D,0x20,0x73,0x63,0x61,0x6C,0x65, + 0x64,0x20,0x76,0x61,0x6C,0x75,0x65,0x73,0x20,0x74,0x6F,0x20, + 0x74,0x68,0x65,0x20,0x6D,0x69,0x78,0x65,0x64,0x20,0x73,0x61, + 0x6D,0x70,0x6C,0x65,0x73,0x20,0x62,0x65,0x66,0x6F,0x72,0x65, + 0x20,0x74,0x72,0x75,0x6E,0x63,0x61,0x74,0x69,0x6E,0x67,0x20, + 0x74,0x6F,0x20,0x31,0x36,0x2D,0x62,0x69,0x74,0x2E,0x46,0x54, + 0x68,0x69,0x73,0x20,0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x69, + 0x6E,0x20,0x74,0x68,0x65,0x6F,0x72,0x79,0x20,0x6C,0x6F,0x77, + 0x65,0x72,0x20,0x74,0x68,0x65,0x20,0x71,0x75,0x61,0x6E,0x74, + 0x69,0x7A,0x61,0x74,0x69,0x6F,0x6E,0x20,0x6E,0x6F,0x69,0x73, + 0x65,0x2E,0x20,0x31,0x36,0x2D,0x62,0x69,0x74,0x20,0x61,0x6C, + 0x72,0x65,0x61,0x64,0x79,0x20,0x68,0x61,0x73,0x46,0x61,0x20, + 0x70,0x72,0x65,0x74,0x74,0x79,0x20,0x6C,0x6F,0x77,0x20,0x6E, + 0x6F,0x69,0x73,0x65,0x20,0x66,0x6C,0x6F,0x6F,0x72,0x2C,0x20, + 0x73,0x6F,0x20,0x64,0x6F,0x6E,0x27,0x74,0x20,0x65,0x78,0x70, + 0x65,0x63,0x74,0x20,0x61,0x6E,0x79,0x20,0x61,0x75,0x64,0x69, + 0x62,0x6C,0x65,0x20,0x64,0x69,0x66,0x66,0x65,0x72,0x65,0x6E, + 0x63,0x65,0x20,0x68,0x65,0x72,0x65,0x2E,0x1F,0x41,0x6C,0x73, + 0x6F,0x20,0x61,0x70,0x70,0x6C,0x69,0x65,0x73,0x20,0x66,0x6F, + 0x72,0x20,0x57,0x41,0x56,0x20,0x72,0x65,0x6E,0x64,0x65,0x72, + 0x69,0x6E,0x67,0x2E,0x00,0x19,0x3E,0x40,0x58,0x30,0x34,0x30, + 0x40,0x43,0x30,0x30,0x31,0x41,0x6D,0x70,0x6C,0x69,0x66,0x69, + 0x63,0x61,0x74,0x69,0x6F,0x6E,0x3A,0x0B,0x3E,0x40,0x58,0x30, + 0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x46,0x41,0x6D,0x70,0x6C, + 0x69,0x66,0x69,0x65,0x73,0x20,0x74,0x68,0x65,0x20,0x76,0x6F, + 0x6C,0x75,0x6D,0x65,0x20,0x77,0x68,0x65,0x6E,0x20,0x6D,0x69, + 0x78,0x69,0x6E,0x67,0x2E,0x20,0x49,0x66,0x20,0x79,0x6F,0x75, + 0x20,0x73,0x65,0x74,0x20,0x74,0x68,0x69,0x73,0x20,0x6F,0x6E, + 0x65,0x20,0x74,0x6F,0x6F,0x20,0x68,0x69,0x67,0x68,0x2C,0x20, + 0x79,0x6F,0x75,0x27,0x6C,0x6C,0x3A,0x67,0x65,0x74,0x20,0x64, + 0x69,0x73,0x74,0x6F,0x72,0x74,0x69,0x6F,0x6E,0x2E,0x20,0x33, + 0x32,0x58,0x20,0x65,0x71,0x75,0x61,0x6C,0x73,0x20,0x66,0x75, + 0x6C,0x6C,0x20,0x61,0x6D,0x70,0x6C,0x69,0x74,0x75,0x64,0x65, + 0x20,0x66,0x6F,0x72,0x20,0x6F,0x6E,0x65,0x20,0x63,0x68,0x61, + 0x6E,0x6E,0x65,0x6C,0x2E,0x00,0x1B,0x3E,0x40,0x58,0x30,0x34, + 0x30,0x40,0x43,0x30,0x30,0x31,0x46,0x72,0x65,0x71,0x75,0x65, + 0x6E,0x63,0x79,0x20,0x74,0x61,0x62,0x6C,0x65,0x3A,0x0B,0x3E, + 0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x40,0x54, + 0x68,0x65,0x20,0x6C,0x69,0x6E,0x65,0x61,0x72,0x20,0x66,0x72, + 0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x20,0x74,0x61,0x62,0x6C, + 0x65,0x20,0x6D,0x61,0x6B,0x65,0x73,0x20,0x61,0x6C,0x6C,0x20, + 0x70,0x69,0x74,0x63,0x68,0x20,0x62,0x65,0x6E,0x64,0x73,0x20, + 0x72,0x75,0x6E,0x20,0x69,0x6E,0x20,0x63,0x6F,0x6E,0x73,0x74, + 0x61,0x6E,0x74,0x3F,0x73,0x70,0x65,0x65,0x64,0x2C,0x20,0x69, + 0x6E,0x64,0x65,0x70,0x65,0x6E,0x64,0x65,0x6E,0x74,0x20,0x6F, + 0x66,0x20,0x74,0x68,0x65,0x20,0x63,0x75,0x72,0x72,0x65,0x6E, + 0x74,0x20,0x66,0x72,0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x2E, + 0x20,0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x73,0x77,0x69,0x74, + 0x63,0x68,0x20,0x74,0x68,0x69,0x73,0x41,0x6F,0x6E,0x65,0x2C, + 0x20,0x6F,0x6E,0x20,0x61,0x20,0x66,0x69,0x6E,0x69,0x73,0x68, + 0x65,0x64,0x20,0x73,0x6F,0x6E,0x67,0x2C,0x20,0x69,0x74,0x20, + 0x6D,0x69,0x67,0x68,0x74,0x20,0x73,0x6F,0x75,0x6E,0x64,0x20, + 0x73,0x74,0x72,0x61,0x6E,0x67,0x65,0x20,0x69,0x66,0x20,0x74, + 0x68,0x65,0x20,0x73,0x6F,0x75,0x6E,0x64,0x20,0x75,0x73,0x65, + 0x73,0x0D,0x70,0x6F,0x72,0x74,0x61,0x6D,0x65,0x6E,0x74,0x6F, + 0x65,0x73,0x2E,0x00,0x20,0x40,0x58,0x30,0x32,0x30,0x40,0x43, + 0x30,0x30,0x31,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61, + 0x74,0x69,0x6F,0x6E,0x2C,0x20,0x4C,0x61,0x79,0x6F,0x75,0x74, + 0x3A,0x01,0x3E,0x29,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43, + 0x30,0x30,0x31,0x50,0x61,0x74,0x74,0x65,0x72,0x6E,0x20,0x6C, + 0x61,0x79,0x6F,0x75,0x74,0x2C,0x20,0x68,0x65,0x78,0x20,0x6E, + 0x75,0x6D,0x62,0x65,0x72,0x69,0x6E,0x67,0x3A,0x0B,0x3E,0x40, + 0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x41,0x49,0x66, + 0x20,0x79,0x6F,0x75,0x20,0x75,0x73,0x65,0x20,0x70,0x61,0x74, + 0x74,0x65,0x72,0x6E,0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x61, + 0x72,0x65,0x20,0x6C,0x6F,0x6E,0x67,0x65,0x72,0x20,0x74,0x68, + 0x61,0x6E,0x20,0x39,0x39,0x20,0x6C,0x69,0x6E,0x65,0x73,0x2C, + 0x20,0x79,0x6F,0x75,0x20,0x73,0x68,0x6F,0x75,0x6C,0x64,0x20, + 0x75,0x73,0x65,0x45,0x68,0x65,0x78,0x20,0x63,0x6F,0x75,0x6E, + 0x74,0x69,0x6E,0x67,0x20,0x73,0x69,0x6E,0x63,0x65,0x20,0x74, + 0x68,0x65,0x72,0x65,0x20,0x61,0x72,0x65,0x20,0x6F,0x6E,0x6C, + 0x79,0x20,0x32,0x20,0x64,0x69,0x67,0x69,0x74,0x73,0x20,0x69, + 0x6E,0x20,0x74,0x68,0x65,0x20,0x6C,0x69,0x6E,0x65,0x20,0x6E, + 0x75,0x6D,0x62,0x65,0x72,0x20,0x63,0x6F,0x6C,0x75,0x6D,0x6E, + 0x2E,0x00,0x17,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30, + 0x30,0x31,0x53,0x63,0x6F,0x70,0x65,0x20,0x73,0x74,0x79,0x6C, + 0x65,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30, + 0x30,0x32,0x43,0x22,0x4F,0x72,0x69,0x67,0x69,0x6E,0x61,0x6C, + 0x22,0x20,0x77,0x69,0x6C,0x6C,0x20,0x73,0x68,0x6F,0x77,0x20, + 0x74,0x68,0x65,0x20,0x70,0x6F,0x69,0x6E,0x74,0x73,0x20,0x69, + 0x6E,0x20,0x74,0x68,0x65,0x20,0x73,0x63,0x6F,0x70,0x65,0x73, + 0x20,0x61,0x73,0x20,0x70,0x69,0x78,0x65,0x6C,0x73,0x20,0x28, + 0x6C,0x69,0x6B,0x65,0x20,0x46,0x54,0x32,0x29,0x2E,0x41,0x22, + 0x4C,0x69,0x6E,0x65,0x64,0x22,0x20,0x77,0x69,0x6C,0x6C,0x20, + 0x64,0x72,0x61,0x77,0x20,0x6C,0x69,0x6E,0x65,0x73,0x20,0x62, + 0x65,0x74,0x77,0x65,0x65,0x6E,0x20,0x74,0x68,0x65,0x20,0x70, + 0x6F,0x69,0x6E,0x74,0x73,0x2C,0x20,0x6C,0x69,0x6B,0x65,0x20, + 0x61,0x6E,0x20,0x6F,0x73,0x63,0x69,0x6C,0x6C,0x6F,0x73,0x63, + 0x6F,0x70,0x65,0x2E,0x00,0x27,0x40,0x58,0x30,0x32,0x30,0x40, + 0x43,0x30,0x30,0x31,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72, + 0x61,0x74,0x69,0x6F,0x6E,0x2C,0x20,0x4D,0x69,0x73,0x63,0x65, + 0x6C,0x6C,0x61,0x6E,0x65,0x6F,0x75,0x73,0x3A,0x01,0x3E,0x15, + 0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x56, + 0x53,0x79,0x6E,0x63,0x20,0x6F,0x66,0x66,0x3A,0x0B,0x3E,0x40, + 0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x3F,0x54,0x65, + 0x6C,0x6C,0x73,0x20,0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67, + 0x72,0x61,0x6D,0x20,0x74,0x6F,0x20,0x6E,0x6F,0x74,0x20,0x75, + 0x73,0x65,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,0x66,0x6F,0x72, + 0x20,0x76,0x69,0x64,0x65,0x6F,0x2E,0x20,0x49,0x66,0x20,0x79, + 0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27, + 0x73,0x40,0x72,0x65,0x66,0x72,0x65,0x73,0x68,0x20,0x72,0x61, + 0x74,0x65,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x36,0x30, + 0x48,0x7A,0x20,0x28,0x6F,0x72,0x20,0x35,0x39,0x48,0x7A,0x29, + 0x2C,0x20,0x74,0x68,0x65,0x6E,0x20,0x56,0x53,0x79,0x6E,0x63, + 0x20,0x69,0x73,0x20,0x61,0x6C,0x77,0x61,0x79,0x73,0x20,0x6F, + 0x66,0x66,0x20,0x66,0x6F,0x72,0x45,0x74,0x68,0x69,0x73,0x20, + 0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x2E,0x20,0x4E,0x6F,0x74, + 0x20,0x68,0x61,0x76,0x69,0x6E,0x67,0x20,0x56,0x53,0x79,0x6E, + 0x63,0x20,0x77,0x69,0x6C,0x6C,0x20,0x72,0x65,0x73,0x75,0x6C, + 0x74,0x20,0x69,0x6E,0x20,0x6C,0x65,0x73,0x73,0x20,0x69,0x6E, + 0x70,0x75,0x74,0x2F,0x76,0x69,0x64,0x65,0x6F,0x20,0x64,0x65, + 0x6C,0x61,0x79,0x2C,0x1E,0x62,0x75,0x74,0x20,0x61,0x6C,0x73, + 0x6F,0x20,0x70,0x6F,0x74,0x65,0x6E,0x74,0x69,0x61,0x6C,0x20, + 0x73,0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x2E,0x01, + 0x20,0x18,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30, + 0x31,0x50,0x69,0x78,0x65,0x6C,0x20,0x66,0x69,0x6C,0x74,0x65, + 0x72,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30, + 0x30,0x32,0x43,0x41,0x70,0x70,0x6C,0x69,0x65,0x73,0x20,0x61, + 0x20,0x73,0x75,0x62,0x70,0x69,0x78,0x65,0x6C,0x20,0x66,0x69, + 0x6C,0x74,0x65,0x72,0x20,0x74,0x68,0x61,0x74,0x20,0x69,0x73, + 0x20,0x75,0x73,0x65,0x64,0x20,0x77,0x68,0x65,0x6E,0x20,0x74, + 0x68,0x65,0x20,0x77,0x69,0x6E,0x64,0x6F,0x77,0x20,0x69,0x73, + 0x20,0x75,0x70,0x73,0x63,0x61,0x6C,0x65,0x64,0x2E,0x43,0x54, + 0x68,0x69,0x73,0x20,0x61,0x6C,0x73,0x6F,0x20,0x6D,0x61,0x6B, + 0x65,0x73,0x20,0x66,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,0x65, + 0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,0x63,0x6F,0x6D,0x70,0x6C, + 0x65,0x74,0x65,0x6C,0x79,0x20,0x73,0x74,0x72,0x65,0x74,0x63, + 0x68,0x20,0x6F,0x75,0x74,0x20,0x69,0x66,0x20,0x69,0x74,0x20, + 0x64,0x69,0x64,0x6E,0x27,0x74,0x44,0x61,0x6C,0x72,0x65,0x61, + 0x64,0x79,0x2E,0x20,0x50,0x6C,0x65,0x61,0x73,0x65,0x20,0x6B, + 0x65,0x65,0x70,0x20,0x69,0x6E,0x20,0x6D,0x69,0x6E,0x64,0x20, + 0x74,0x68,0x61,0x74,0x20,0x74,0x68,0x69,0x73,0x20,0x77,0x69, + 0x6C,0x6C,0x20,0x6D,0x61,0x6B,0x65,0x20,0x70,0x69,0x78,0x65, + 0x6C,0x73,0x20,0x6C,0x6F,0x6F,0x6B,0x20,0x62,0x6C,0x75,0x72, + 0x72,0x79,0x2E,0x00,0x23,0x40,0x58,0x30,0x32,0x30,0x40,0x43, + 0x30,0x30,0x31,0x41,0x64,0x76,0x61,0x6E,0x63,0x65,0x64,0x20, + 0x65,0x64,0x69,0x74,0x20,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F, + 0x6E,0x73,0x3A,0x20,0x01,0x3E,0x1E,0x3E,0x40,0x58,0x30,0x34, + 0x30,0x40,0x43,0x30,0x30,0x31,0x43,0x6F,0x70,0x79,0x2F,0x50, + 0x61,0x73,0x74,0x65,0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E,0x67, 0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30, - 0x32,0x21,0x57,0x6F,0x72,0x6B,0x73,0x20,0x66,0x6F,0x72,0x20, - 0x31,0x36,0x2D,0x62,0x69,0x74,0x20,0x61,0x75,0x64,0x69,0x6F, - 0x20,0x6D,0x6F,0x64,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x2E,0x4E, - 0x41,0x70,0x70,0x6C,0x69,0x65,0x73,0x20,0x72,0x61,0x6E,0x64, - 0x6F,0x6D,0x20,0x73,0x63,0x61,0x6C,0x65,0x64,0x20,0x76,0x61, - 0x6C,0x75,0x65,0x73,0x20,0x74,0x6F,0x20,0x74,0x68,0x65,0x20, - 0x6D,0x69,0x78,0x65,0x64,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65, - 0x73,0x20,0x62,0x65,0x66,0x6F,0x72,0x65,0x20,0x74,0x72,0x75, - 0x6E,0x63,0x61,0x74,0x69,0x6E,0x67,0x20,0x74,0x6F,0x20,0x31, - 0x36,0x2D,0x62,0x69,0x74,0x2E,0x46,0x54,0x68,0x69,0x73,0x20, - 0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x69,0x6E,0x20,0x74,0x68, - 0x65,0x6F,0x72,0x79,0x20,0x6C,0x6F,0x77,0x65,0x72,0x20,0x74, - 0x68,0x65,0x20,0x71,0x75,0x61,0x6E,0x74,0x69,0x7A,0x61,0x74, - 0x69,0x6F,0x6E,0x20,0x6E,0x6F,0x69,0x73,0x65,0x2E,0x20,0x31, - 0x36,0x2D,0x62,0x69,0x74,0x20,0x61,0x6C,0x72,0x65,0x61,0x64, - 0x79,0x20,0x68,0x61,0x73,0x46,0x61,0x20,0x70,0x72,0x65,0x74, - 0x74,0x79,0x20,0x6C,0x6F,0x77,0x20,0x6E,0x6F,0x69,0x73,0x65, - 0x20,0x66,0x6C,0x6F,0x6F,0x72,0x2C,0x20,0x73,0x6F,0x20,0x64, - 0x6F,0x6E,0x27,0x74,0x20,0x65,0x78,0x70,0x65,0x63,0x74,0x20, - 0x61,0x6E,0x79,0x20,0x61,0x75,0x64,0x69,0x62,0x6C,0x65,0x20, - 0x64,0x69,0x66,0x66,0x65,0x72,0x65,0x6E,0x63,0x65,0x20,0x68, - 0x65,0x72,0x65,0x2E,0x1F,0x41,0x6C,0x73,0x6F,0x20,0x61,0x70, - 0x70,0x6C,0x69,0x65,0x73,0x20,0x66,0x6F,0x72,0x20,0x57,0x41, - 0x56,0x20,0x72,0x65,0x6E,0x64,0x65,0x72,0x69,0x6E,0x67,0x2E, - 0x00,0x19,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30, - 0x31,0x41,0x6D,0x70,0x6C,0x69,0x66,0x69,0x63,0x61,0x74,0x69, - 0x6F,0x6E,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43, - 0x30,0x30,0x32,0x46,0x41,0x6D,0x70,0x6C,0x69,0x66,0x69,0x65, - 0x73,0x20,0x74,0x68,0x65,0x20,0x76,0x6F,0x6C,0x75,0x6D,0x65, - 0x20,0x77,0x68,0x65,0x6E,0x20,0x6D,0x69,0x78,0x69,0x6E,0x67, - 0x2E,0x20,0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x73,0x65,0x74, - 0x20,0x74,0x68,0x69,0x73,0x20,0x6F,0x6E,0x65,0x20,0x74,0x6F, - 0x6F,0x20,0x68,0x69,0x67,0x68,0x2C,0x20,0x79,0x6F,0x75,0x27, - 0x6C,0x6C,0x3A,0x67,0x65,0x74,0x20,0x64,0x69,0x73,0x74,0x6F, - 0x72,0x74,0x69,0x6F,0x6E,0x2E,0x20,0x33,0x32,0x58,0x20,0x65, - 0x71,0x75,0x61,0x6C,0x73,0x20,0x66,0x75,0x6C,0x6C,0x20,0x61, - 0x6D,0x70,0x6C,0x69,0x74,0x75,0x64,0x65,0x20,0x66,0x6F,0x72, - 0x20,0x6F,0x6E,0x65,0x20,0x63,0x68,0x61,0x6E,0x6E,0x65,0x6C, - 0x2E,0x00,0x1B,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30, - 0x30,0x31,0x46,0x72,0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x20, - 0x74,0x61,0x62,0x6C,0x65,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36, - 0x30,0x40,0x43,0x30,0x30,0x32,0x40,0x54,0x68,0x65,0x20,0x6C, - 0x69,0x6E,0x65,0x61,0x72,0x20,0x66,0x72,0x65,0x71,0x75,0x65, - 0x6E,0x63,0x79,0x20,0x74,0x61,0x62,0x6C,0x65,0x20,0x6D,0x61, - 0x6B,0x65,0x73,0x20,0x61,0x6C,0x6C,0x20,0x70,0x69,0x74,0x63, - 0x68,0x20,0x62,0x65,0x6E,0x64,0x73,0x20,0x72,0x75,0x6E,0x20, - 0x69,0x6E,0x20,0x63,0x6F,0x6E,0x73,0x74,0x61,0x6E,0x74,0x3F, - 0x73,0x70,0x65,0x65,0x64,0x2C,0x20,0x69,0x6E,0x64,0x65,0x70, - 0x65,0x6E,0x64,0x65,0x6E,0x74,0x20,0x6F,0x66,0x20,0x74,0x68, - 0x65,0x20,0x63,0x75,0x72,0x72,0x65,0x6E,0x74,0x20,0x66,0x72, - 0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x2E,0x20,0x49,0x66,0x20, - 0x79,0x6F,0x75,0x20,0x73,0x77,0x69,0x74,0x63,0x68,0x20,0x74, - 0x68,0x69,0x73,0x41,0x6F,0x6E,0x65,0x2C,0x20,0x6F,0x6E,0x20, - 0x61,0x20,0x66,0x69,0x6E,0x69,0x73,0x68,0x65,0x64,0x20,0x73, - 0x6F,0x6E,0x67,0x2C,0x20,0x69,0x74,0x20,0x6D,0x69,0x67,0x68, - 0x74,0x20,0x73,0x6F,0x75,0x6E,0x64,0x20,0x73,0x74,0x72,0x61, - 0x6E,0x67,0x65,0x20,0x69,0x66,0x20,0x74,0x68,0x65,0x20,0x73, - 0x6F,0x75,0x6E,0x64,0x20,0x75,0x73,0x65,0x73,0x0D,0x70,0x6F, - 0x72,0x74,0x61,0x6D,0x65,0x6E,0x74,0x6F,0x65,0x73,0x2E,0x00, - 0x20,0x40,0x58,0x30,0x32,0x30,0x40,0x43,0x30,0x30,0x31,0x43, - 0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E, - 0x2C,0x20,0x4C,0x61,0x79,0x6F,0x75,0x74,0x3A,0x01,0x3E,0x29, - 0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x50, - 0x61,0x74,0x74,0x65,0x72,0x6E,0x20,0x6C,0x61,0x79,0x6F,0x75, - 0x74,0x2C,0x20,0x68,0x65,0x78,0x20,0x6E,0x75,0x6D,0x62,0x65, - 0x72,0x69,0x6E,0x67,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30, - 0x40,0x43,0x30,0x30,0x32,0x41,0x49,0x66,0x20,0x79,0x6F,0x75, - 0x20,0x75,0x73,0x65,0x20,0x70,0x61,0x74,0x74,0x65,0x72,0x6E, - 0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x61,0x72,0x65,0x20,0x6C, - 0x6F,0x6E,0x67,0x65,0x72,0x20,0x74,0x68,0x61,0x6E,0x20,0x39, - 0x39,0x20,0x6C,0x69,0x6E,0x65,0x73,0x2C,0x20,0x79,0x6F,0x75, - 0x20,0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x75,0x73,0x65,0x45, - 0x68,0x65,0x78,0x20,0x63,0x6F,0x75,0x6E,0x74,0x69,0x6E,0x67, - 0x20,0x73,0x69,0x6E,0x63,0x65,0x20,0x74,0x68,0x65,0x72,0x65, - 0x20,0x61,0x72,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x32,0x20, - 0x64,0x69,0x67,0x69,0x74,0x73,0x20,0x69,0x6E,0x20,0x74,0x68, - 0x65,0x20,0x6C,0x69,0x6E,0x65,0x20,0x6E,0x75,0x6D,0x62,0x65, - 0x72,0x20,0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x2E,0x00,0x17,0x3E, - 0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x53,0x63, - 0x6F,0x70,0x65,0x20,0x73,0x74,0x79,0x6C,0x65,0x3A,0x0B,0x3E, - 0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x43,0x22, - 0x4F,0x72,0x69,0x67,0x69,0x6E,0x61,0x6C,0x22,0x20,0x77,0x69, - 0x6C,0x6C,0x20,0x73,0x68,0x6F,0x77,0x20,0x74,0x68,0x65,0x20, - 0x70,0x6F,0x69,0x6E,0x74,0x73,0x20,0x69,0x6E,0x20,0x74,0x68, - 0x65,0x20,0x73,0x63,0x6F,0x70,0x65,0x73,0x20,0x61,0x73,0x20, - 0x70,0x69,0x78,0x65,0x6C,0x73,0x20,0x28,0x6C,0x69,0x6B,0x65, - 0x20,0x46,0x54,0x32,0x29,0x2E,0x41,0x22,0x4C,0x69,0x6E,0x65, - 0x64,0x22,0x20,0x77,0x69,0x6C,0x6C,0x20,0x64,0x72,0x61,0x77, - 0x20,0x6C,0x69,0x6E,0x65,0x73,0x20,0x62,0x65,0x74,0x77,0x65, - 0x65,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,0x6F,0x69,0x6E,0x74, - 0x73,0x2C,0x20,0x6C,0x69,0x6B,0x65,0x20,0x61,0x6E,0x20,0x6F, - 0x73,0x63,0x69,0x6C,0x6C,0x6F,0x73,0x63,0x6F,0x70,0x65,0x2E, - 0x00,0x27,0x40,0x58,0x30,0x32,0x30,0x40,0x43,0x30,0x30,0x31, - 0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F, - 0x6E,0x2C,0x20,0x4D,0x69,0x73,0x63,0x65,0x6C,0x6C,0x61,0x6E, - 0x65,0x6F,0x75,0x73,0x3A,0x01,0x3E,0x15,0x3E,0x40,0x58,0x30, - 0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x56,0x53,0x79,0x6E,0x63, - 0x20,0x6F,0x66,0x66,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30, - 0x40,0x43,0x30,0x30,0x32,0x3F,0x54,0x65,0x6C,0x6C,0x73,0x20, - 0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20, - 0x74,0x6F,0x20,0x6E,0x6F,0x74,0x20,0x75,0x73,0x65,0x20,0x56, - 0x53,0x79,0x6E,0x63,0x20,0x66,0x6F,0x72,0x20,0x76,0x69,0x64, - 0x65,0x6F,0x2E,0x20,0x49,0x66,0x20,0x79,0x6F,0x75,0x72,0x20, - 0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,0x40,0x72,0x65, - 0x66,0x72,0x65,0x73,0x68,0x20,0x72,0x61,0x74,0x65,0x20,0x69, - 0x73,0x20,0x6E,0x6F,0x74,0x20,0x36,0x30,0x48,0x7A,0x20,0x28, - 0x6F,0x72,0x20,0x35,0x39,0x48,0x7A,0x29,0x2C,0x20,0x74,0x68, - 0x65,0x6E,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,0x69,0x73,0x20, - 0x61,0x6C,0x77,0x61,0x79,0x73,0x20,0x6F,0x66,0x66,0x20,0x66, - 0x6F,0x72,0x45,0x74,0x68,0x69,0x73,0x20,0x70,0x72,0x6F,0x67, - 0x72,0x61,0x6D,0x2E,0x20,0x4E,0x6F,0x74,0x20,0x68,0x61,0x76, - 0x69,0x6E,0x67,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,0x77,0x69, - 0x6C,0x6C,0x20,0x72,0x65,0x73,0x75,0x6C,0x74,0x20,0x69,0x6E, - 0x20,0x6C,0x65,0x73,0x73,0x20,0x69,0x6E,0x70,0x75,0x74,0x2F, - 0x76,0x69,0x64,0x65,0x6F,0x20,0x64,0x65,0x6C,0x61,0x79,0x2C, - 0x1E,0x62,0x75,0x74,0x20,0x61,0x6C,0x73,0x6F,0x20,0x70,0x6F, - 0x74,0x65,0x6E,0x74,0x69,0x61,0x6C,0x20,0x73,0x74,0x75,0x74, - 0x74,0x65,0x72,0x69,0x6E,0x67,0x2E,0x01,0x20,0x18,0x3E,0x40, - 0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x50,0x69,0x78, - 0x65,0x6C,0x20,0x66,0x69,0x6C,0x74,0x65,0x72,0x3A,0x0B,0x3E, - 0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x43,0x41, - 0x70,0x70,0x6C,0x69,0x65,0x73,0x20,0x61,0x20,0x73,0x75,0x62, - 0x70,0x69,0x78,0x65,0x6C,0x20,0x66,0x69,0x6C,0x74,0x65,0x72, - 0x20,0x74,0x68,0x61,0x74,0x20,0x69,0x73,0x20,0x75,0x73,0x65, - 0x64,0x20,0x77,0x68,0x65,0x6E,0x20,0x74,0x68,0x65,0x20,0x77, - 0x69,0x6E,0x64,0x6F,0x77,0x20,0x69,0x73,0x20,0x75,0x70,0x73, - 0x63,0x61,0x6C,0x65,0x64,0x2E,0x43,0x54,0x68,0x69,0x73,0x20, - 0x61,0x6C,0x73,0x6F,0x20,0x6D,0x61,0x6B,0x65,0x73,0x20,0x66, - 0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F, - 0x64,0x65,0x20,0x63,0x6F,0x6D,0x70,0x6C,0x65,0x74,0x65,0x6C, - 0x79,0x20,0x73,0x74,0x72,0x65,0x74,0x63,0x68,0x20,0x6F,0x75, - 0x74,0x20,0x69,0x66,0x20,0x69,0x74,0x20,0x64,0x69,0x64,0x6E, - 0x27,0x74,0x44,0x61,0x6C,0x72,0x65,0x61,0x64,0x79,0x2E,0x20, - 0x50,0x6C,0x65,0x61,0x73,0x65,0x20,0x6B,0x65,0x65,0x70,0x20, - 0x69,0x6E,0x20,0x6D,0x69,0x6E,0x64,0x20,0x74,0x68,0x61,0x74, - 0x20,0x74,0x68,0x69,0x73,0x20,0x77,0x69,0x6C,0x6C,0x20,0x6D, - 0x61,0x6B,0x65,0x20,0x70,0x69,0x78,0x65,0x6C,0x73,0x20,0x6C, - 0x6F,0x6F,0x6B,0x20,0x62,0x6C,0x75,0x72,0x72,0x79,0x2E,0x00, - 0x23,0x40,0x58,0x30,0x32,0x30,0x40,0x43,0x30,0x30,0x31,0x41, - 0x64,0x76,0x61,0x6E,0x63,0x65,0x64,0x20,0x65,0x64,0x69,0x74, - 0x20,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x73,0x3A,0x20, - 0x01,0x3E,0x1E,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30, - 0x30,0x31,0x43,0x6F,0x70,0x79,0x2F,0x50,0x61,0x73,0x74,0x65, - 0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E,0x67,0x3A,0x0B,0x3E,0x40, - 0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x37,0x54,0x68, - 0x65,0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E,0x67,0x20,0x69,0x73, - 0x20,0x75,0x73,0x65,0x64,0x20,0x66,0x6F,0x72,0x20,0x63,0x6F, - 0x70,0x79,0x69,0x6E,0x67,0x2F,0x70,0x61,0x73,0x74,0x69,0x6E, - 0x67,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x70,0x61,0x72,0x74,0x73, - 0x20,0x6F,0x66,0x20,0x61,0x46,0x22,0x6E,0x6F,0x74,0x65,0x2D, - 0x63,0x65,0x6C,0x6C,0x22,0x2E,0x20,0x54,0x68,0x65,0x20,0x64, - 0x69,0x66,0x66,0x65,0x72,0x65,0x6E,0x74,0x20,0x70,0x61,0x72, - 0x74,0x73,0x20,0x6F,0x66,0x20,0x61,0x20,0x22,0x6E,0x6F,0x74, - 0x65,0x2D,0x63,0x65,0x6C,0x6C,0x22,0x20,0x69,0x73,0x20,0x4E, - 0x6F,0x74,0x65,0x2C,0x20,0x49,0x6E,0x73,0x74,0x72,0x2E,0x20, - 0x6E,0x72,0x2E,0x2C,0x20,0x56,0x6F,0x6C,0x75,0x6D,0x65,0x2C, - 0x20,0x45,0x66,0x66,0x65,0x63,0x74,0x20,0x6E,0x72,0x20,0x26, - 0x20,0x45,0x66,0x66,0x65,0x63,0x74,0x20,0x64,0x61,0x74,0x61, - 0x2E,0x34,0x3E,0x41,0x73,0x20,0x79,0x6F,0x75,0x20,0x63,0x61, - 0x6E,0x20,0x73,0x65,0x65,0x20,0x69,0x6E,0x20,0x74,0x68,0x65, - 0x20,0x77,0x69,0x6E,0x64,0x6F,0x77,0x20,0x74,0x68,0x65,0x72, - 0x65,0x20,0x61,0x72,0x65,0x20,0x33,0x20,0x63,0x6F,0x6C,0x75, - 0x6D,0x6E,0x73,0x20,0x6F,0x66,0x3D,0x22,0x65,0x6E,0x61,0x62, - 0x6C,0x65,0x2F,0x64,0x69,0x73,0x61,0x62,0x6C,0x65,0x20,0x62, - 0x75,0x74,0x74,0x6F,0x6E,0x73,0x22,0x20,0x77,0x68,0x69,0x63, - 0x68,0x20,0x68,0x61,0x73,0x20,0x74,0x68,0x65,0x20,0x6C,0x65, - 0x74,0x74,0x65,0x72,0x73,0x20,0x43,0x2C,0x50,0x20,0x26,0x20, - 0x54,0x20,0x61,0x62,0x6F,0x76,0x65,0x2E,0x45,0x3E,0x43,0x20, - 0x6D,0x65,0x61,0x6E,0x73,0x20,0x63,0x6F,0x70,0x79,0x2C,0x20, - 0x69,0x74,0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x73,0x20, - 0x77,0x68,0x69,0x63,0x68,0x20,0x70,0x61,0x72,0x74,0x73,0x20, - 0x74,0x68,0x61,0x74,0x20,0x67,0x6F,0x65,0x73,0x20,0x69,0x6E, - 0x74,0x6F,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x70,0x79,0x62, - 0x75,0x66,0x66,0x65,0x72,0x2E,0x3E,0x3E,0x50,0x20,0x6D,0x65, - 0x61,0x6E,0x73,0x20,0x70,0x61,0x73,0x74,0x65,0x20,0x61,0x6E, - 0x64,0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x73,0x20,0x77, - 0x68,0x69,0x63,0x68,0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x74, - 0x68,0x61,0x74,0x20,0x67,0x6F,0x65,0x73,0x20,0x6F,0x75,0x74, - 0x20,0x66,0x72,0x6F,0x6D,0x20,0x74,0x68,0x65,0x0B,0x63,0x6F, - 0x70,0x79,0x62,0x75,0x66,0x66,0x65,0x72,0x2E,0x45,0x3E,0x54, - 0x20,0x6D,0x65,0x61,0x6E,0x73,0x20,0x74,0x72,0x61,0x6E,0x73, - 0x70,0x61,0x72,0x65,0x6E,0x63,0x79,0x2E,0x20,0x49,0x66,0x20, - 0x69,0x74,0x27,0x73,0x20,0x65,0x6E,0x61,0x62,0x6C,0x65,0x64, - 0x2C,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x73,0x74,0x69,0x6E, - 0x67,0x20,0x64,0x6F,0x65,0x73,0x6E,0x27,0x74,0x20,0x6F,0x76, - 0x65,0x72,0x77,0x72,0x69,0x74,0x65,0x3D,0x64,0x61,0x74,0x61, - 0x20,0x77,0x69,0x74,0x68,0x20,0x6E,0x69,0x6C,0x2D,0x69,0x6E, - 0x66,0x6F,0x72,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x20,0x6F, - 0x6E,0x6C,0x79,0x20,0x77,0x69,0x74,0x68,0x20,0x61,0x20,0x6E, - 0x6F,0x74,0x65,0x20,0x6F,0x72,0x20,0x61,0x20,0x6E,0x75,0x6D, - 0x62,0x65,0x72,0x20,0x3C,0x3E,0x20,0x30,0x2E,0x01,0x3E,0x40, - 0x3E,0x54,0x68,0x65,0x20,0x63,0x75,0x74,0x20,0x66,0x75,0x6E, - 0x63,0x74,0x69,0x6F,0x6E,0x73,0x20,0x77,0x6F,0x72,0x6B,0x73, - 0x20,0x6C,0x69,0x6B,0x65,0x20,0x70,0x61,0x73,0x74,0x69,0x6E, - 0x67,0x20,0x77,0x69,0x74,0x68,0x20,0x7A,0x65,0x72,0x6F,0x2D, - 0x64,0x61,0x74,0x61,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x6D, - 0x65,0x61,0x6E,0x73,0x3B,0x74,0x68,0x61,0x74,0x20,0x74,0x68, - 0x65,0x20,0x63,0x75,0x74,0x74,0x69,0x6E,0x67,0x20,0x69,0x73, - 0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x6C,0x65,0x64,0x20, - 0x77,0x69,0x74,0x68,0x20,0x50,0x2D,0x63,0x6F,0x6C,0x75,0x6D, - 0x6E,0x20,0x28,0x6F,0x72,0x20,0x54,0x2D,0x63,0x6F,0x6C,0x75, - 0x6D,0x6E,0x29,0x2E,0x3C,0x3E,0x57,0x68,0x65,0x6E,0x20,0x79, - 0x6F,0x75,0x20,0x63,0x6F,0x70,0x79,0x20,0x64,0x61,0x74,0x61, - 0x20,0x77,0x69,0x74,0x68,0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E, - 0x67,0x2C,0x20,0x74,0x68,0x65,0x20,0x64,0x69,0x73,0x61,0x62, - 0x6C,0x65,0x64,0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x61,0x72, - 0x65,0x20,0x6E,0x6F,0x74,0x43,0x63,0x6C,0x65,0x61,0x72,0x65, - 0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x70, - 0x79,0x62,0x75,0x66,0x66,0x65,0x72,0x2E,0x20,0x28,0x4D,0x61, - 0x6B,0x69,0x6E,0x67,0x20,0x69,0x74,0x20,0x70,0x6F,0x73,0x73, - 0x69,0x62,0x6C,0x65,0x20,0x74,0x6F,0x20,0x63,0x6F,0x6C,0x6C, - 0x65,0x63,0x74,0x20,0x64,0x61,0x74,0x61,0x20,0x66,0x72,0x6F, - 0x6D,0x27,0x73,0x65,0x76,0x65,0x72,0x61,0x6C,0x20,0x6C,0x6F, - 0x63,0x61,0x74,0x69,0x6F,0x6E,0x73,0x20,0x69,0x6E,0x74,0x6F, - 0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x70,0x79,0x62,0x75,0x66, - 0x66,0x65,0x72,0x2E,0x29,0x00,0x03,0x45,0x4E,0x44,0x4C,0x3B, - 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, + 0x32,0x37,0x54,0x68,0x65,0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E, + 0x67,0x20,0x69,0x73,0x20,0x75,0x73,0x65,0x64,0x20,0x66,0x6F, + 0x72,0x20,0x63,0x6F,0x70,0x79,0x69,0x6E,0x67,0x2F,0x70,0x61, + 0x73,0x74,0x69,0x6E,0x67,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x70, + 0x61,0x72,0x74,0x73,0x20,0x6F,0x66,0x20,0x61,0x46,0x22,0x6E, + 0x6F,0x74,0x65,0x2D,0x63,0x65,0x6C,0x6C,0x22,0x2E,0x20,0x54, + 0x68,0x65,0x20,0x64,0x69,0x66,0x66,0x65,0x72,0x65,0x6E,0x74, + 0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x6F,0x66,0x20,0x61,0x20, + 0x22,0x6E,0x6F,0x74,0x65,0x2D,0x63,0x65,0x6C,0x6C,0x22,0x20, + 0x69,0x73,0x20,0x4E,0x6F,0x74,0x65,0x2C,0x20,0x49,0x6E,0x73, + 0x74,0x72,0x2E,0x20,0x6E,0x72,0x2E,0x2C,0x20,0x56,0x6F,0x6C, + 0x75,0x6D,0x65,0x2C,0x20,0x45,0x66,0x66,0x65,0x63,0x74,0x20, + 0x6E,0x72,0x20,0x26,0x20,0x45,0x66,0x66,0x65,0x63,0x74,0x20, + 0x64,0x61,0x74,0x61,0x2E,0x34,0x3E,0x41,0x73,0x20,0x79,0x6F, + 0x75,0x20,0x63,0x61,0x6E,0x20,0x73,0x65,0x65,0x20,0x69,0x6E, + 0x20,0x74,0x68,0x65,0x20,0x77,0x69,0x6E,0x64,0x6F,0x77,0x20, + 0x74,0x68,0x65,0x72,0x65,0x20,0x61,0x72,0x65,0x20,0x33,0x20, + 0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x73,0x20,0x6F,0x66,0x3D,0x22, + 0x65,0x6E,0x61,0x62,0x6C,0x65,0x2F,0x64,0x69,0x73,0x61,0x62, + 0x6C,0x65,0x20,0x62,0x75,0x74,0x74,0x6F,0x6E,0x73,0x22,0x20, + 0x77,0x68,0x69,0x63,0x68,0x20,0x68,0x61,0x73,0x20,0x74,0x68, + 0x65,0x20,0x6C,0x65,0x74,0x74,0x65,0x72,0x73,0x20,0x43,0x2C, + 0x50,0x20,0x26,0x20,0x54,0x20,0x61,0x62,0x6F,0x76,0x65,0x2E, + 0x45,0x3E,0x43,0x20,0x6D,0x65,0x61,0x6E,0x73,0x20,0x63,0x6F, + 0x70,0x79,0x2C,0x20,0x69,0x74,0x20,0x63,0x6F,0x6E,0x74,0x72, + 0x6F,0x6C,0x73,0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x70,0x61, + 0x72,0x74,0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x67,0x6F,0x65, + 0x73,0x20,0x69,0x6E,0x74,0x6F,0x20,0x74,0x68,0x65,0x20,0x63, + 0x6F,0x70,0x79,0x62,0x75,0x66,0x66,0x65,0x72,0x2E,0x3E,0x3E, + 0x50,0x20,0x6D,0x65,0x61,0x6E,0x73,0x20,0x70,0x61,0x73,0x74, + 0x65,0x20,0x61,0x6E,0x64,0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F, + 0x6C,0x73,0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x70,0x61,0x72, + 0x74,0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x67,0x6F,0x65,0x73, + 0x20,0x6F,0x75,0x74,0x20,0x66,0x72,0x6F,0x6D,0x20,0x74,0x68, + 0x65,0x0B,0x63,0x6F,0x70,0x79,0x62,0x75,0x66,0x66,0x65,0x72, + 0x2E,0x45,0x3E,0x54,0x20,0x6D,0x65,0x61,0x6E,0x73,0x20,0x74, + 0x72,0x61,0x6E,0x73,0x70,0x61,0x72,0x65,0x6E,0x63,0x79,0x2E, + 0x20,0x49,0x66,0x20,0x69,0x74,0x27,0x73,0x20,0x65,0x6E,0x61, + 0x62,0x6C,0x65,0x64,0x2C,0x20,0x74,0x68,0x65,0x20,0x70,0x61, + 0x73,0x74,0x69,0x6E,0x67,0x20,0x64,0x6F,0x65,0x73,0x6E,0x27, + 0x74,0x20,0x6F,0x76,0x65,0x72,0x77,0x72,0x69,0x74,0x65,0x3D, + 0x64,0x61,0x74,0x61,0x20,0x77,0x69,0x74,0x68,0x20,0x6E,0x69, + 0x6C,0x2D,0x69,0x6E,0x66,0x6F,0x72,0x6D,0x61,0x74,0x69,0x6F, + 0x6E,0x2C,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x77,0x69,0x74,0x68, + 0x20,0x61,0x20,0x6E,0x6F,0x74,0x65,0x20,0x6F,0x72,0x20,0x61, + 0x20,0x6E,0x75,0x6D,0x62,0x65,0x72,0x20,0x3C,0x3E,0x20,0x30, + 0x2E,0x01,0x3E,0x40,0x3E,0x54,0x68,0x65,0x20,0x63,0x75,0x74, + 0x20,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x73,0x20,0x77, + 0x6F,0x72,0x6B,0x73,0x20,0x6C,0x69,0x6B,0x65,0x20,0x70,0x61, + 0x73,0x74,0x69,0x6E,0x67,0x20,0x77,0x69,0x74,0x68,0x20,0x7A, + 0x65,0x72,0x6F,0x2D,0x64,0x61,0x74,0x61,0x2E,0x20,0x54,0x68, + 0x69,0x73,0x20,0x6D,0x65,0x61,0x6E,0x73,0x3B,0x74,0x68,0x61, + 0x74,0x20,0x74,0x68,0x65,0x20,0x63,0x75,0x74,0x74,0x69,0x6E, + 0x67,0x20,0x69,0x73,0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C, + 0x6C,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x50,0x2D,0x63, + 0x6F,0x6C,0x75,0x6D,0x6E,0x20,0x28,0x6F,0x72,0x20,0x54,0x2D, + 0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x29,0x2E,0x3C,0x3E,0x57,0x68, + 0x65,0x6E,0x20,0x79,0x6F,0x75,0x20,0x63,0x6F,0x70,0x79,0x20, + 0x64,0x61,0x74,0x61,0x20,0x77,0x69,0x74,0x68,0x20,0x6D,0x61, + 0x73,0x6B,0x69,0x6E,0x67,0x2C,0x20,0x74,0x68,0x65,0x20,0x64, + 0x69,0x73,0x61,0x62,0x6C,0x65,0x64,0x20,0x70,0x61,0x72,0x74, + 0x73,0x20,0x61,0x72,0x65,0x20,0x6E,0x6F,0x74,0x43,0x63,0x6C, + 0x65,0x61,0x72,0x65,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65, + 0x20,0x63,0x6F,0x70,0x79,0x62,0x75,0x66,0x66,0x65,0x72,0x2E, + 0x20,0x28,0x4D,0x61,0x6B,0x69,0x6E,0x67,0x20,0x69,0x74,0x20, + 0x70,0x6F,0x73,0x73,0x69,0x62,0x6C,0x65,0x20,0x74,0x6F,0x20, + 0x63,0x6F,0x6C,0x6C,0x65,0x63,0x74,0x20,0x64,0x61,0x74,0x61, + 0x20,0x66,0x72,0x6F,0x6D,0x27,0x73,0x65,0x76,0x65,0x72,0x61, + 0x6C,0x20,0x6C,0x6F,0x63,0x61,0x74,0x69,0x6F,0x6E,0x73,0x20, + 0x69,0x6E,0x74,0x6F,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x70, + 0x79,0x62,0x75,0x66,0x66,0x65,0x72,0x2E,0x29,0x00,0x03,0x45, + 0x4E,0x44,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, - 0x2A,0x2A,0x2A,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, + 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x4C,0x3B,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, - 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x0E,0x40,0x4C,0x50, - 0x72,0x6F,0x62,0x6C,0x65,0x6D,0x73,0x2F,0x46,0x41,0x51,0x06, - 0x3E,0x40,0x58,0x30,0x32,0x30,0x41,0x3E,0x40,0x43,0x30,0x30, - 0x31,0x51,0x3A,0x20,0x43,0x61,0x6E,0x20,0x49,0x20,0x6D,0x61, - 0x6B,0x65,0x20,0x66,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,0x65, - 0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,0x73,0x74,0x72,0x65,0x74, - 0x63,0x68,0x20,0x6F,0x75,0x74,0x20,0x74,0x68,0x65,0x20,0x77, - 0x68,0x6F,0x6C,0x65,0x20,0x73,0x63,0x72,0x65,0x65,0x6E,0x3F, - 0x3A,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x45,0x6E, - 0x61,0x62,0x6C,0x65,0x20,0x22,0x50,0x69,0x78,0x65,0x6C,0x20, - 0x66,0x69,0x6C,0x74,0x65,0x72,0x22,0x20,0x69,0x6E,0x20,0x43, - 0x6F,0x6E,0x66,0x69,0x67,0x20,0x2D,0x3E,0x20,0x4D,0x69,0x73, - 0x63,0x65,0x6C,0x6C,0x61,0x6E,0x65,0x6F,0x75,0x73,0x2E,0x4D, - 0x3E,0x40,0x58,0x30,0x33,0x35,0x49,0x74,0x20,0x77,0x6F,0x6E, - 0x27,0x74,0x20,0x6C,0x6F,0x6F,0x6B,0x20,0x70,0x72,0x65,0x74, - 0x74,0x79,0x2C,0x20,0x62,0x75,0x74,0x20,0x74,0x6F,0x20,0x73, - 0x6F,0x6D,0x65,0x20,0x70,0x65,0x6F,0x70,0x6C,0x65,0x20,0x69, - 0x74,0x27,0x73,0x20,0x6D,0x75,0x63,0x68,0x20,0x62,0x65,0x74, - 0x74,0x65,0x72,0x20,0x74,0x68,0x61,0x6E,0x20,0x6E,0x6F,0x74, - 0x68,0x69,0x6E,0x67,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30, - 0x27,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x49,0x20, - 0x63,0x61,0x6E,0x27,0x74,0x20,0x75,0x73,0x65,0x20,0x41,0x4C, - 0x54,0x2B,0x46,0x34,0x20,0x61,0x6E,0x64,0x20,0x41,0x4C,0x54, - 0x2B,0x46,0x35,0x21,0x4E,0x3E,0x40,0x43,0x30,0x30,0x32,0x41, - 0x3A,0x20,0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,0x3A,0x20,0x49, - 0x66,0x20,0x79,0x6F,0x75,0x20,0x68,0x61,0x76,0x65,0x20,0x47, - 0x65,0x46,0x6F,0x72,0x63,0x65,0x20,0x45,0x78,0x70,0x65,0x72, - 0x69,0x65,0x6E,0x63,0x65,0x20,0x69,0x6E,0x73,0x74,0x61,0x6C, - 0x6C,0x65,0x64,0x2C,0x20,0x79,0x6F,0x75,0x20,0x6E,0x65,0x65, - 0x64,0x20,0x74,0x6F,0x20,0x63,0x68,0x61,0x6E,0x67,0x65,0x2B, - 0x3E,0x40,0x58,0x30,0x33,0x35,0x74,0x68,0x65,0x20,0x6B,0x65, - 0x79,0x62,0x69,0x6E,0x64,0x69,0x6E,0x67,0x73,0x20,0x69,0x6E, - 0x20,0x69,0x74,0x73,0x20,0x73,0x65,0x74,0x74,0x69,0x6E,0x67, - 0x73,0x20,0x70,0x61,0x67,0x65,0x2E,0x56,0x6D,0x61,0x63,0x4F, - 0x53,0x2F,0x4F,0x53,0x20,0x58,0x3A,0x20,0x43,0x68,0x61,0x6E, - 0x67,0x65,0x20,0x41,0x4C,0x54,0x2B,0x46,0x34,0x2F,0x41,0x4C, - 0x54,0x2B,0x46,0x35,0x20,0x6B,0x65,0x79,0x73,0x20,0x69,0x6E, - 0x20,0x74,0x68,0x65,0x20,0x4F,0x53,0x20,0x74,0x6F,0x20,0x73, - 0x6F,0x6D,0x65,0x74,0x68,0x69,0x6E,0x67,0x20,0x65,0x6C,0x73, - 0x65,0x2E,0x20,0x41,0x6C,0x73,0x6F,0x20,0x66,0x6F,0x72,0x20, - 0x47,0x4E,0x55,0x2F,0x4C,0x69,0x6E,0x75,0x78,0x2E,0x06,0x3E, - 0x40,0x58,0x30,0x32,0x30,0x2B,0x3E,0x40,0x43,0x30,0x30,0x31, - 0x51,0x3A,0x20,0x54,0x68,0x65,0x20,0x6D,0x6F,0x75,0x73,0x65, - 0x20,0x63,0x75,0x72,0x73,0x6F,0x72,0x20,0x69,0x73,0x20,0x64, - 0x65,0x6C,0x61,0x79,0x65,0x64,0x2F,0x6C,0x61,0x67,0x67,0x79, - 0x21,0x44,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x4D, - 0x61,0x6B,0x65,0x20,0x73,0x75,0x72,0x65,0x20,0x22,0x53,0x6F, - 0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x6D,0x6F,0x75,0x73,0x65, - 0x22,0x20,0x69,0x73,0x20,0x64,0x69,0x73,0x61,0x62,0x6C,0x65, - 0x64,0x20,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x66,0x69,0x67,0x20, - 0x2D,0x3E,0x20,0x4C,0x61,0x79,0x6F,0x75,0x74,0x2E,0x4B,0x3E, - 0x40,0x58,0x30,0x33,0x35,0x41,0x6C,0x74,0x65,0x72,0x6E,0x61, - 0x74,0x69,0x76,0x65,0x6C,0x79,0x2C,0x20,0x79,0x6F,0x75,0x20, - 0x63,0x61,0x6E,0x20,0x65,0x6E,0x61,0x62,0x6C,0x65,0x20,0x22, - 0x56,0x53,0x79,0x6E,0x63,0x20,0x6F,0x66,0x66,0x22,0x20,0x69, - 0x6E,0x20,0x43,0x6F,0x6E,0x66,0x69,0x67,0x20,0x2D,0x3E,0x20, - 0x4D,0x69,0x73,0x63,0x65,0x6C,0x6C,0x61,0x6E,0x65,0x6F,0x75, - 0x73,0x2E,0x46,0x3E,0x54,0x68,0x69,0x73,0x20,0x68,0x6F,0x77, - 0x65,0x76,0x65,0x72,0x2C,0x20,0x77,0x69,0x6C,0x6C,0x20,0x69, - 0x6E,0x74,0x72,0x6F,0x64,0x75,0x63,0x65,0x20,0x73,0x74,0x75, - 0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x20,0x62,0x65,0x63,0x61, - 0x75,0x73,0x65,0x20,0x74,0x68,0x65,0x20,0x72,0x65,0x6E,0x64, - 0x65,0x72,0x69,0x6E,0x67,0x20,0x72,0x61,0x74,0x65,0x20,0x69, - 0x73,0x22,0x3E,0x6E,0x6F,0x74,0x20,0x65,0x78,0x61,0x63,0x74, - 0x20,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E, - 0x69,0x74,0x6F,0x72,0x27,0x73,0x20,0x72,0x61,0x74,0x65,0x2E, - 0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x33,0x3E,0x40,0x43,0x30, - 0x30,0x31,0x51,0x3A,0x20,0x57,0x69,0x6C,0x6C,0x20,0x79,0x6F, - 0x75,0x20,0x69,0x6D,0x70,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x20, - 0x4D,0x49,0x44,0x49,0x20,0x6F,0x75,0x74,0x20,0x66,0x75,0x6E, - 0x63,0x74,0x69,0x6F,0x6E,0x61,0x6C,0x69,0x74,0x79,0x3F,0x4D, - 0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x4E,0x6F,0x2C, - 0x20,0x73,0x6F,0x72,0x72,0x79,0x2E,0x20,0x54,0x68,0x69,0x73, - 0x20,0x69,0x73,0x20,0x76,0x65,0x72,0x79,0x20,0x64,0x69,0x66, - 0x66,0x69,0x63,0x75,0x6C,0x74,0x20,0x74,0x6F,0x20,0x69,0x6D, - 0x70,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x20,0x63,0x6F,0x72,0x72, - 0x65,0x63,0x74,0x6C,0x79,0x20,0x77,0x68,0x65,0x6E,0x20,0x68, - 0x61,0x76,0x69,0x6E,0x67,0x3C,0x3E,0x40,0x58,0x30,0x33,0x35, - 0x68,0x69,0x67,0x68,0x65,0x72,0x20,0x61,0x75,0x64,0x69,0x6F, - 0x20,0x62,0x75,0x66,0x66,0x65,0x72,0x20,0x73,0x69,0x7A,0x65, - 0x73,0x20,0x28,0x62,0x75,0x66,0x66,0x65,0x72,0x65,0x64,0x20, - 0x72,0x65,0x70,0x6C,0x61,0x79,0x65,0x72,0x20,0x74,0x69,0x63, - 0x6B,0x73,0x29,0x2E,0x2E,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32, - 0x30,0x30,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x57, - 0x68,0x65,0x72,0x65,0x20,0x69,0x73,0x20,0x74,0x68,0x65,0x20, - 0x63,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F, - 0x6E,0x20,0x66,0x69,0x6C,0x65,0x20,0x73,0x74,0x6F,0x72,0x65, - 0x64,0x3F,0x3F,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20, - 0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,0x3A,0x20,0x5C,0x55,0x73, - 0x65,0x72,0x73,0x5C,0x55,0x53,0x45,0x52,0x5C,0x41,0x70,0x70, - 0x44,0x61,0x74,0x61,0x5C,0x52,0x6F,0x61,0x6D,0x69,0x6E,0x67, - 0x5C,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,0x5C,0x46, - 0x54,0x32,0x2E,0x43,0x46,0x47,0x45,0x3E,0x40,0x58,0x30,0x33, - 0x35,0x4F,0x53,0x20,0x58,0x3A,0x20,0x2F,0x55,0x73,0x65,0x72, - 0x73,0x2F,0x55,0x53,0x45,0x52,0x2F,0x4C,0x69,0x62,0x72,0x61, - 0x72,0x79,0x2F,0x41,0x70,0x70,0x6C,0x69,0x63,0x61,0x74,0x69, - 0x6F,0x6E,0x20,0x53,0x75,0x70,0x70,0x6F,0x72,0x74,0x2F,0x46, - 0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,0x2F,0x46,0x54,0x32, - 0x2E,0x43,0x46,0x47,0x2F,0x47,0x4E,0x55,0x2F,0x4C,0x69,0x6E, - 0x75,0x78,0x3A,0x20,0x2F,0x68,0x6F,0x6D,0x65,0x2F,0x55,0x53, - 0x45,0x52,0x2F,0x2E,0x63,0x6F,0x6E,0x66,0x69,0x67,0x2F,0x46, - 0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,0x2F,0x46,0x54,0x32, - 0x2E,0x43,0x46,0x47,0x01,0x3E,0x48,0x49,0x74,0x20,0x77,0x69, - 0x6C,0x6C,0x20,0x62,0x65,0x20,0x73,0x74,0x6F,0x72,0x65,0x64, - 0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67, - 0x72,0x61,0x6D,0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72, - 0x79,0x20,0x69,0x66,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x74, - 0x68,0x20,0x63,0x6F,0x75,0x6C,0x64,0x6E,0x27,0x74,0x20,0x62, - 0x65,0x20,0x75,0x73,0x65,0x64,0x2E,0x4D,0x49,0x66,0x20,0x79, - 0x6F,0x75,0x20,0x70,0x75,0x74,0x20,0x74,0x68,0x65,0x20,0x63, - 0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E, - 0x20,0x66,0x69,0x6C,0x65,0x20,0x69,0x6E,0x20,0x74,0x68,0x65, - 0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x64,0x69,0x72, - 0x65,0x63,0x74,0x6F,0x72,0x79,0x2C,0x20,0x69,0x74,0x20,0x77, - 0x69,0x6C,0x6C,0x20,0x72,0x65,0x61,0x64,0x20,0x74,0x68,0x61, - 0x74,0x4A,0x6F,0x6E,0x65,0x20,0x61,0x6E,0x64,0x20,0x6E,0x6F, - 0x74,0x20,0x61,0x74,0x74,0x65,0x6D,0x70,0x74,0x20,0x74,0x6F, - 0x20,0x63,0x72,0x65,0x61,0x74,0x65,0x20,0x63,0x6F,0x6E,0x66, - 0x69,0x67,0x20,0x64,0x69,0x72,0x73,0x20,0x66,0x6F,0x72,0x20, - 0x74,0x68,0x65,0x20,0x4F,0x53,0x20,0x75,0x73,0x65,0x72,0x2E, - 0x20,0x28,0x70,0x6F,0x72,0x74,0x61,0x62,0x6C,0x65,0x20,0x6D, - 0x6F,0x64,0x65,0x29,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x42, - 0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x43,0x61,0x6E, - 0x20,0x74,0x68,0x65,0x20,0x63,0x6C,0x6F,0x6E,0x65,0x20,0x72, - 0x65,0x61,0x64,0x20,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x20, - 0x66,0x72,0x6F,0x6D,0x20,0x72,0x65,0x61,0x6C,0x20,0x46,0x54, - 0x32,0x2C,0x20,0x61,0x6E,0x64,0x20,0x76,0x69,0x63,0x65,0x20, - 0x76,0x65,0x72,0x73,0x61,0x3F,0x4C,0x3E,0x40,0x43,0x30,0x30, - 0x32,0x41,0x3A,0x20,0x59,0x65,0x73,0x2C,0x20,0x69,0x74,0x20, - 0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x77,0x6F,0x72,0x6B,0x20, - 0x6A,0x75,0x73,0x74,0x20,0x66,0x69,0x6E,0x65,0x2E,0x20,0x50, - 0x75,0x74,0x20,0x69,0x74,0x20,0x69,0x6E,0x20,0x74,0x68,0x65, - 0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72,0x79,0x20,0x73, - 0x68,0x6F,0x77,0x6E,0x20,0x61,0x62,0x6F,0x76,0x65,0x2E,0x06, - 0x3E,0x40,0x58,0x30,0x32,0x30,0x52,0x3E,0x40,0x43,0x30,0x30, - 0x31,0x51,0x3A,0x20,0x53,0x6D,0x70,0x2E,0x20,0x45,0x64,0x2E, - 0x3A,0x20,0x57,0x68,0x69,0x6C,0x65,0x20,0x7A,0x6F,0x6F,0x6D, - 0x69,0x6E,0x67,0x20,0x69,0x6E,0x2C,0x20,0x49,0x20,0x73,0x6F, - 0x6D,0x65,0x74,0x69,0x6D,0x65,0x73,0x20,0x63,0x61,0x6E,0x27, - 0x74,0x20,0x6D,0x61,0x72,0x6B,0x20,0x74,0x68,0x65,0x20,0x6C, - 0x61,0x73,0x74,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x70, - 0x6F,0x69,0x6E,0x74,0x21,0x47,0x3E,0x40,0x43,0x30,0x30,0x32, - 0x41,0x3A,0x20,0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x6E, - 0x6F,0x72,0x6D,0x61,0x6C,0x2E,0x20,0x54,0x68,0x69,0x73,0x20, - 0x69,0x73,0x20,0x61,0x20,0x6C,0x69,0x6D,0x69,0x74,0x61,0x74, - 0x69,0x6F,0x6E,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x6E, - 0x61,0x74,0x75,0x72,0x65,0x20,0x6F,0x66,0x20,0x73,0x63,0x61, - 0x6C,0x69,0x6E,0x67,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30, - 0x17,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x49,0x20, - 0x66,0x6F,0x75,0x6E,0x64,0x20,0x61,0x20,0x62,0x75,0x67,0x21, - 0x4B,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x50,0x6C, - 0x65,0x61,0x73,0x65,0x20,0x73,0x65,0x6E,0x64,0x20,0x61,0x20, - 0x6D,0x61,0x69,0x6C,0x20,0x74,0x6F,0x20,0x6F,0x6C,0x61,0x76, - 0x2E,0x73,0x6F,0x72,0x65,0x6E,0x73,0x65,0x6E,0x40,0x6C,0x69, - 0x76,0x65,0x2E,0x6E,0x6F,0x20,0x61,0x6E,0x64,0x20,0x74,0x72, - 0x79,0x20,0x74,0x6F,0x20,0x65,0x78,0x70,0x6C,0x61,0x69,0x6E, - 0x20,0x69,0x74,0x2E,0x00,0x03,0x45,0x4E,0x44,0x4C,0x3B,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, + 0x0E,0x40,0x4C,0x50,0x72,0x6F,0x62,0x6C,0x65,0x6D,0x73,0x2F, + 0x46,0x41,0x51,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x41,0x3E, + 0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x43,0x61,0x6E,0x20, + 0x49,0x20,0x6D,0x61,0x6B,0x65,0x20,0x66,0x75,0x6C,0x6C,0x73, + 0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,0x73, + 0x74,0x72,0x65,0x74,0x63,0x68,0x20,0x6F,0x75,0x74,0x20,0x74, + 0x68,0x65,0x20,0x77,0x68,0x6F,0x6C,0x65,0x20,0x73,0x63,0x72, + 0x65,0x65,0x6E,0x3F,0x3A,0x3E,0x40,0x43,0x30,0x30,0x32,0x41, + 0x3A,0x20,0x45,0x6E,0x61,0x62,0x6C,0x65,0x20,0x22,0x50,0x69, + 0x78,0x65,0x6C,0x20,0x66,0x69,0x6C,0x74,0x65,0x72,0x22,0x20, + 0x69,0x6E,0x20,0x43,0x6F,0x6E,0x66,0x69,0x67,0x20,0x2D,0x3E, + 0x20,0x4D,0x69,0x73,0x63,0x65,0x6C,0x6C,0x61,0x6E,0x65,0x6F, + 0x75,0x73,0x2E,0x4D,0x3E,0x40,0x58,0x30,0x33,0x35,0x49,0x74, + 0x20,0x77,0x6F,0x6E,0x27,0x74,0x20,0x6C,0x6F,0x6F,0x6B,0x20, + 0x70,0x72,0x65,0x74,0x74,0x79,0x2C,0x20,0x62,0x75,0x74,0x20, + 0x74,0x6F,0x20,0x73,0x6F,0x6D,0x65,0x20,0x70,0x65,0x6F,0x70, + 0x6C,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x6D,0x75,0x63,0x68, + 0x20,0x62,0x65,0x74,0x74,0x65,0x72,0x20,0x74,0x68,0x61,0x6E, + 0x20,0x6E,0x6F,0x74,0x68,0x69,0x6E,0x67,0x2E,0x06,0x3E,0x40, + 0x58,0x30,0x32,0x30,0x27,0x3E,0x40,0x43,0x30,0x30,0x31,0x51, + 0x3A,0x20,0x49,0x20,0x63,0x61,0x6E,0x27,0x74,0x20,0x75,0x73, + 0x65,0x20,0x41,0x4C,0x54,0x2B,0x46,0x34,0x20,0x61,0x6E,0x64, + 0x20,0x41,0x4C,0x54,0x2B,0x46,0x35,0x21,0x4E,0x3E,0x40,0x43, + 0x30,0x30,0x32,0x41,0x3A,0x20,0x57,0x69,0x6E,0x64,0x6F,0x77, + 0x73,0x3A,0x20,0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x68,0x61, + 0x76,0x65,0x20,0x47,0x65,0x46,0x6F,0x72,0x63,0x65,0x20,0x45, + 0x78,0x70,0x65,0x72,0x69,0x65,0x6E,0x63,0x65,0x20,0x69,0x6E, + 0x73,0x74,0x61,0x6C,0x6C,0x65,0x64,0x2C,0x20,0x79,0x6F,0x75, + 0x20,0x6E,0x65,0x65,0x64,0x20,0x74,0x6F,0x20,0x63,0x68,0x61, + 0x6E,0x67,0x65,0x2B,0x3E,0x40,0x58,0x30,0x33,0x35,0x74,0x68, + 0x65,0x20,0x6B,0x65,0x79,0x62,0x69,0x6E,0x64,0x69,0x6E,0x67, + 0x73,0x20,0x69,0x6E,0x20,0x69,0x74,0x73,0x20,0x73,0x65,0x74, + 0x74,0x69,0x6E,0x67,0x73,0x20,0x70,0x61,0x67,0x65,0x2E,0x56, + 0x6D,0x61,0x63,0x4F,0x53,0x2F,0x4F,0x53,0x20,0x58,0x3A,0x20, + 0x43,0x68,0x61,0x6E,0x67,0x65,0x20,0x41,0x4C,0x54,0x2B,0x46, + 0x34,0x2F,0x41,0x4C,0x54,0x2B,0x46,0x35,0x20,0x6B,0x65,0x79, + 0x73,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x4F,0x53,0x20, + 0x74,0x6F,0x20,0x73,0x6F,0x6D,0x65,0x74,0x68,0x69,0x6E,0x67, + 0x20,0x65,0x6C,0x73,0x65,0x2E,0x20,0x41,0x6C,0x73,0x6F,0x20, + 0x66,0x6F,0x72,0x20,0x47,0x4E,0x55,0x2F,0x4C,0x69,0x6E,0x75, + 0x78,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x2B,0x3E,0x40, + 0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x54,0x68,0x65,0x20,0x6D, + 0x6F,0x75,0x73,0x65,0x20,0x63,0x75,0x72,0x73,0x6F,0x72,0x20, + 0x69,0x73,0x20,0x64,0x65,0x6C,0x61,0x79,0x65,0x64,0x2F,0x6C, + 0x61,0x67,0x67,0x79,0x21,0x44,0x3E,0x40,0x43,0x30,0x30,0x32, + 0x41,0x3A,0x20,0x4D,0x61,0x6B,0x65,0x20,0x73,0x75,0x72,0x65, + 0x20,0x22,0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x6D, + 0x6F,0x75,0x73,0x65,0x22,0x20,0x69,0x73,0x20,0x64,0x69,0x73, + 0x61,0x62,0x6C,0x65,0x64,0x20,0x69,0x6E,0x20,0x43,0x6F,0x6E, + 0x66,0x69,0x67,0x20,0x2D,0x3E,0x20,0x4C,0x61,0x79,0x6F,0x75, + 0x74,0x2E,0x4B,0x3E,0x40,0x58,0x30,0x33,0x35,0x41,0x6C,0x74, + 0x65,0x72,0x6E,0x61,0x74,0x69,0x76,0x65,0x6C,0x79,0x2C,0x20, + 0x79,0x6F,0x75,0x20,0x63,0x61,0x6E,0x20,0x65,0x6E,0x61,0x62, + 0x6C,0x65,0x20,0x22,0x56,0x53,0x79,0x6E,0x63,0x20,0x6F,0x66, + 0x66,0x22,0x20,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x66,0x69,0x67, + 0x20,0x2D,0x3E,0x20,0x4D,0x69,0x73,0x63,0x65,0x6C,0x6C,0x61, + 0x6E,0x65,0x6F,0x75,0x73,0x2E,0x46,0x3E,0x54,0x68,0x69,0x73, + 0x20,0x68,0x6F,0x77,0x65,0x76,0x65,0x72,0x2C,0x20,0x77,0x69, + 0x6C,0x6C,0x20,0x69,0x6E,0x74,0x72,0x6F,0x64,0x75,0x63,0x65, + 0x20,0x73,0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x20, + 0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x74,0x68,0x65,0x20, + 0x72,0x65,0x6E,0x64,0x65,0x72,0x69,0x6E,0x67,0x20,0x72,0x61, + 0x74,0x65,0x20,0x69,0x73,0x22,0x3E,0x6E,0x6F,0x74,0x20,0x65, + 0x78,0x61,0x63,0x74,0x20,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72, + 0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,0x20,0x72, + 0x61,0x74,0x65,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x33, + 0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x57,0x69,0x6C, + 0x6C,0x20,0x79,0x6F,0x75,0x20,0x69,0x6D,0x70,0x6C,0x65,0x6D, + 0x65,0x6E,0x74,0x20,0x4D,0x49,0x44,0x49,0x20,0x6F,0x75,0x74, + 0x20,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x61,0x6C,0x69, + 0x74,0x79,0x3F,0x4D,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A, + 0x20,0x4E,0x6F,0x2C,0x20,0x73,0x6F,0x72,0x72,0x79,0x2E,0x20, + 0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x76,0x65,0x72,0x79, + 0x20,0x64,0x69,0x66,0x66,0x69,0x63,0x75,0x6C,0x74,0x20,0x74, + 0x6F,0x20,0x69,0x6D,0x70,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x20, + 0x63,0x6F,0x72,0x72,0x65,0x63,0x74,0x6C,0x79,0x20,0x77,0x68, + 0x65,0x6E,0x20,0x68,0x61,0x76,0x69,0x6E,0x67,0x3C,0x3E,0x40, + 0x58,0x30,0x33,0x35,0x68,0x69,0x67,0x68,0x65,0x72,0x20,0x61, + 0x75,0x64,0x69,0x6F,0x20,0x62,0x75,0x66,0x66,0x65,0x72,0x20, + 0x73,0x69,0x7A,0x65,0x73,0x20,0x28,0x62,0x75,0x66,0x66,0x65, + 0x72,0x65,0x64,0x20,0x72,0x65,0x70,0x6C,0x61,0x79,0x65,0x72, + 0x20,0x74,0x69,0x63,0x6B,0x73,0x29,0x2E,0x2E,0x2E,0x06,0x3E, + 0x40,0x58,0x30,0x32,0x30,0x30,0x3E,0x40,0x43,0x30,0x30,0x31, + 0x51,0x3A,0x20,0x57,0x68,0x65,0x72,0x65,0x20,0x69,0x73,0x20, + 0x74,0x68,0x65,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72, + 0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,0x69,0x6C,0x65,0x20,0x73, + 0x74,0x6F,0x72,0x65,0x64,0x3F,0x3F,0x3E,0x40,0x43,0x30,0x30, + 0x32,0x41,0x3A,0x20,0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,0x3A, + 0x20,0x5C,0x55,0x73,0x65,0x72,0x73,0x5C,0x55,0x53,0x45,0x52, + 0x5C,0x41,0x70,0x70,0x44,0x61,0x74,0x61,0x5C,0x52,0x6F,0x61, + 0x6D,0x69,0x6E,0x67,0x5C,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F, + 0x6E,0x65,0x5C,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x45,0x3E, + 0x40,0x58,0x30,0x33,0x35,0x4F,0x53,0x20,0x58,0x3A,0x20,0x2F, + 0x55,0x73,0x65,0x72,0x73,0x2F,0x55,0x53,0x45,0x52,0x2F,0x4C, + 0x69,0x62,0x72,0x61,0x72,0x79,0x2F,0x41,0x70,0x70,0x6C,0x69, + 0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x75,0x70,0x70,0x6F, + 0x72,0x74,0x2F,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65, + 0x2F,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x2F,0x47,0x4E,0x55, + 0x2F,0x4C,0x69,0x6E,0x75,0x78,0x3A,0x20,0x2F,0x68,0x6F,0x6D, + 0x65,0x2F,0x55,0x53,0x45,0x52,0x2F,0x2E,0x63,0x6F,0x6E,0x66, + 0x69,0x67,0x2F,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65, + 0x2F,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x01,0x3E,0x48,0x49, + 0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,0x62,0x65,0x20,0x73,0x74, + 0x6F,0x72,0x65,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20, + 0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x64,0x69,0x72,0x65, + 0x63,0x74,0x6F,0x72,0x79,0x20,0x69,0x66,0x20,0x74,0x68,0x65, + 0x20,0x70,0x61,0x74,0x68,0x20,0x63,0x6F,0x75,0x6C,0x64,0x6E, + 0x27,0x74,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x2E,0x4D, + 0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x70,0x75,0x74,0x20,0x74, + 0x68,0x65,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61, + 0x74,0x69,0x6F,0x6E,0x20,0x66,0x69,0x6C,0x65,0x20,0x69,0x6E, + 0x20,0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D, + 0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72,0x79,0x2C,0x20, + 0x69,0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,0x72,0x65,0x61,0x64, + 0x20,0x74,0x68,0x61,0x74,0x4A,0x6F,0x6E,0x65,0x20,0x61,0x6E, + 0x64,0x20,0x6E,0x6F,0x74,0x20,0x61,0x74,0x74,0x65,0x6D,0x70, + 0x74,0x20,0x74,0x6F,0x20,0x63,0x72,0x65,0x61,0x74,0x65,0x20, + 0x63,0x6F,0x6E,0x66,0x69,0x67,0x20,0x64,0x69,0x72,0x73,0x20, + 0x66,0x6F,0x72,0x20,0x74,0x68,0x65,0x20,0x4F,0x53,0x20,0x75, + 0x73,0x65,0x72,0x2E,0x20,0x28,0x70,0x6F,0x72,0x74,0x61,0x62, + 0x6C,0x65,0x20,0x6D,0x6F,0x64,0x65,0x29,0x06,0x3E,0x40,0x58, + 0x30,0x32,0x30,0x42,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A, + 0x20,0x43,0x61,0x6E,0x20,0x74,0x68,0x65,0x20,0x63,0x6C,0x6F, + 0x6E,0x65,0x20,0x72,0x65,0x61,0x64,0x20,0x46,0x54,0x32,0x2E, + 0x43,0x46,0x47,0x20,0x66,0x72,0x6F,0x6D,0x20,0x72,0x65,0x61, + 0x6C,0x20,0x46,0x54,0x32,0x2C,0x20,0x61,0x6E,0x64,0x20,0x76, + 0x69,0x63,0x65,0x20,0x76,0x65,0x72,0x73,0x61,0x3F,0x4C,0x3E, + 0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x59,0x65,0x73,0x2C, + 0x20,0x69,0x74,0x20,0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x77, + 0x6F,0x72,0x6B,0x20,0x6A,0x75,0x73,0x74,0x20,0x66,0x69,0x6E, + 0x65,0x2E,0x20,0x50,0x75,0x74,0x20,0x69,0x74,0x20,0x69,0x6E, + 0x20,0x74,0x68,0x65,0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F, + 0x72,0x79,0x20,0x73,0x68,0x6F,0x77,0x6E,0x20,0x61,0x62,0x6F, + 0x76,0x65,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x52,0x3E, + 0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x53,0x6D,0x70,0x2E, + 0x20,0x45,0x64,0x2E,0x3A,0x20,0x57,0x68,0x69,0x6C,0x65,0x20, + 0x7A,0x6F,0x6F,0x6D,0x69,0x6E,0x67,0x20,0x69,0x6E,0x2C,0x20, + 0x49,0x20,0x73,0x6F,0x6D,0x65,0x74,0x69,0x6D,0x65,0x73,0x20, + 0x63,0x61,0x6E,0x27,0x74,0x20,0x6D,0x61,0x72,0x6B,0x20,0x74, + 0x68,0x65,0x20,0x6C,0x61,0x73,0x74,0x20,0x73,0x61,0x6D,0x70, + 0x6C,0x65,0x20,0x70,0x6F,0x69,0x6E,0x74,0x21,0x47,0x3E,0x40, + 0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x54,0x68,0x69,0x73,0x20, + 0x69,0x73,0x20,0x6E,0x6F,0x72,0x6D,0x61,0x6C,0x2E,0x20,0x54, + 0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x61,0x20,0x6C,0x69,0x6D, + 0x69,0x74,0x61,0x74,0x69,0x6F,0x6E,0x20,0x69,0x6E,0x20,0x74, + 0x68,0x65,0x20,0x6E,0x61,0x74,0x75,0x72,0x65,0x20,0x6F,0x66, + 0x20,0x73,0x63,0x61,0x6C,0x69,0x6E,0x67,0x2E,0x06,0x3E,0x40, + 0x58,0x30,0x32,0x30,0x17,0x3E,0x40,0x43,0x30,0x30,0x31,0x51, + 0x3A,0x20,0x49,0x20,0x66,0x6F,0x75,0x6E,0x64,0x20,0x61,0x20, + 0x62,0x75,0x67,0x21,0x4B,0x3E,0x40,0x43,0x30,0x30,0x32,0x41, + 0x3A,0x20,0x50,0x6C,0x65,0x61,0x73,0x65,0x20,0x73,0x65,0x6E, + 0x64,0x20,0x61,0x20,0x6D,0x61,0x69,0x6C,0x20,0x74,0x6F,0x20, + 0x6F,0x6C,0x61,0x76,0x2E,0x73,0x6F,0x72,0x65,0x6E,0x73,0x65, + 0x6E,0x40,0x6C,0x69,0x76,0x65,0x2E,0x6E,0x6F,0x20,0x61,0x6E, + 0x64,0x20,0x74,0x72,0x79,0x20,0x74,0x6F,0x20,0x65,0x78,0x70, + 0x6C,0x61,0x69,0x6E,0x20,0x69,0x74,0x2E,0x00,0x03,0x45,0x4E, + 0x44,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, - 0x2A,0x2A,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, + 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A, - 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x0C,0x40,0x4C,0x4B,0x6E, - 0x6F,0x77,0x6E,0x20,0x62,0x75,0x67,0x73,0x06,0x3E,0x40,0x58, - 0x30,0x31,0x30,0x14,0x3E,0x40,0x43,0x30,0x30,0x31,0x53,0x61, - 0x6D,0x70,0x6C,0x65,0x20,0x65,0x64,0x69,0x74,0x6F,0x72,0x3A, - 0x06,0x3E,0x40,0x43,0x30,0x30,0x32,0x4E,0x3E,0x40,0x58,0x30, - 0x31,0x30,0x2D,0x20,0x57,0x68,0x65,0x6E,0x20,0x61,0x20,0x6C, - 0x6F,0x6F,0x70,0x65,0x64,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65, - 0x20,0x69,0x73,0x20,0x7A,0x6F,0x6F,0x6D,0x65,0x64,0x20,0x6F, - 0x75,0x74,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x73,0x61, - 0x6D,0x70,0x6C,0x65,0x20,0x65,0x64,0x69,0x74,0x6F,0x72,0x2C, - 0x20,0x79,0x6F,0x75,0x20,0x63,0x6F,0x75,0x6C,0x64,0x20,0x73, - 0x65,0x65,0x4D,0x3E,0x40,0x58,0x30,0x32,0x31,0x75,0x6E,0x77, - 0x61,0x6E,0x74,0x65,0x64,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65, - 0x20,0x64,0x61,0x74,0x61,0x20,0x61,0x74,0x20,0x74,0x68,0x65, - 0x20,0x6C,0x6F,0x6F,0x70,0x2D,0x65,0x6E,0x64,0x20,0x70,0x6F, - 0x69,0x6E,0x74,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x69,0x73, - 0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x6F,0x66,0x20, - 0x61,0x20,0x6B,0x6C,0x75,0x64,0x67,0x65,0x4B,0x66,0x6F,0x72, - 0x20,0x74,0x68,0x65,0x20,0x72,0x65,0x73,0x61,0x6D,0x70,0x6C, - 0x69,0x6E,0x67,0x20,0x69,0x6E,0x74,0x65,0x72,0x70,0x6F,0x6C, - 0x61,0x74,0x69,0x6F,0x6E,0x20,0x74,0x6F,0x20,0x77,0x6F,0x72, - 0x6B,0x20,0x66,0x61,0x73,0x74,0x65,0x72,0x20,0x69,0x6E,0x20, - 0x74,0x68,0x65,0x20,0x61,0x75,0x64,0x69,0x6F,0x20,0x6D,0x69, - 0x78,0x65,0x72,0x2C,0x20,0x61,0x6E,0x64,0x20,0x74,0x68,0x65, - 0x4B,0x6F,0x72,0x69,0x67,0x69,0x6E,0x61,0x6C,0x20,0x46,0x54, - 0x32,0x20,0x68,0x61,0x73,0x20,0x74,0x68,0x65,0x20,0x73,0x61, - 0x6D,0x65,0x20,0x70,0x72,0x6F,0x62,0x6C,0x65,0x6D,0x2E,0x20, - 0x49,0x20,0x68,0x61,0x76,0x65,0x20,0x6D,0x61,0x64,0x65,0x20, - 0x69,0x74,0x20,0x73,0x6F,0x20,0x74,0x68,0x61,0x74,0x20,0x69, - 0x66,0x20,0x79,0x6F,0x75,0x20,0x7A,0x6F,0x6F,0x6D,0x20,0x69, - 0x6E,0x20,0x74,0x6F,0x3B,0x73,0x65,0x65,0x20,0x74,0x68,0x65, - 0x20,0x69,0x6E,0x64,0x69,0x76,0x69,0x64,0x75,0x61,0x6C,0x20, - 0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x70,0x6F,0x69,0x6E,0x74, - 0x73,0x2C,0x20,0x69,0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,0x6C, - 0x6F,0x6F,0x6B,0x20,0x6C,0x69,0x6B,0x65,0x20,0x6E,0x6F,0x72, - 0x6D,0x61,0x6C,0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x17, - 0x3E,0x40,0x43,0x30,0x30,0x31,0x4D,0x6F,0x75,0x73,0x65,0x20, - 0x2F,0x20,0x6B,0x65,0x79,0x62,0x6F,0x61,0x72,0x64,0x3A,0x01, - 0x3E,0x4D,0x3E,0x40,0x43,0x30,0x30,0x32,0x2D,0x20,0x57,0x68, - 0x65,0x6E,0x20,0x79,0x6F,0x75,0x20,0x68,0x6F,0x6C,0x64,0x20, - 0x64,0x6F,0x77,0x6E,0x20,0x61,0x20,0x6B,0x65,0x79,0x20,0x28, - 0x66,0x2E,0x65,0x78,0x2E,0x20,0x70,0x6C,0x61,0x79,0x69,0x6E, - 0x67,0x20,0x61,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x29,0x2C, - 0x20,0x74,0x68,0x65,0x20,0x6D,0x6F,0x75,0x73,0x65,0x20,0x6D, - 0x6F,0x76,0x65,0x6D,0x65,0x6E,0x74,0x4A,0x3E,0x40,0x58,0x30, - 0x32,0x31,0x63,0x61,0x6E,0x20,0x62,0x65,0x20,0x63,0x68,0x6F, - 0x70,0x70,0x79,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x69,0x73, - 0x20,0x72,0x65,0x6C,0x61,0x74,0x65,0x64,0x20,0x74,0x6F,0x20, - 0x74,0x68,0x65,0x20,0x69,0x6E,0x70,0x75,0x74,0x20,0x71,0x75, - 0x65,0x75,0x65,0x20,0x62,0x65,0x69,0x6E,0x67,0x20,0x73,0x70, - 0x61,0x6D,0x6D,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x36,0x22, - 0x6B,0x65,0x79,0x20,0x64,0x6F,0x77,0x6E,0x22,0x20,0x65,0x76, - 0x65,0x6E,0x74,0x73,0x2C,0x20,0x64,0x65,0x6C,0x61,0x79,0x69, - 0x6E,0x67,0x20,0x74,0x68,0x65,0x20,0x6D,0x6F,0x75,0x73,0x65, - 0x20,0x70,0x6F,0x73,0x69,0x74,0x69,0x6F,0x6E,0x20,0x65,0x76, - 0x65,0x6E,0x74,0x73,0x2E,0x4E,0x49,0x20,0x6F,0x6E,0x6C,0x79, - 0x20,0x70,0x6F,0x6C,0x6C,0x20,0x69,0x6E,0x70,0x75,0x74,0x20, - 0x6F,0x6E,0x63,0x65,0x20,0x70,0x65,0x72,0x20,0x66,0x72,0x61, - 0x6D,0x65,0x20,0x28,0x36,0x30,0x48,0x7A,0x29,0x2C,0x20,0x73, - 0x6F,0x20,0x74,0x68,0x65,0x20,0x66,0x72,0x65,0x71,0x75,0x65, - 0x6E,0x63,0x79,0x20,0x69,0x73,0x20,0x61,0x20,0x74,0x61,0x64, - 0x20,0x6C,0x6F,0x77,0x2E,0x20,0x49,0x74,0x20,0x68,0x61,0x73, - 0x2E,0x74,0x6F,0x20,0x62,0x65,0x20,0x6C,0x69,0x6B,0x65,0x20, - 0x74,0x68,0x69,0x73,0x20,0x66,0x6F,0x72,0x20,0x73,0x65,0x76, - 0x65,0x72,0x61,0x6C,0x20,0x72,0x65,0x61,0x73,0x6F,0x6E,0x73, - 0x2C,0x20,0x74,0x68,0x6F,0x75,0x67,0x68,0x2E,0x2E,0x2E,0x06, - 0x3E,0x40,0x58,0x30,0x31,0x30,0x47,0x3E,0x40,0x43,0x30,0x30, - 0x32,0x2D,0x20,0x6D,0x61,0x63,0x4F,0x53,0x20,0x2F,0x20,0x4F, - 0x53,0x20,0x58,0x3A,0x20,0x22,0x48,0x61,0x72,0x64,0x77,0x61, - 0x72,0x65,0x20,0x6D,0x6F,0x64,0x65,0x22,0x20,0x6D,0x6F,0x75, - 0x73,0x65,0x20,0x6C,0x6F,0x6F,0x6B,0x73,0x20,0x62,0x6C,0x75, - 0x72,0x72,0x79,0x20,0x6F,0x6E,0x20,0x72,0x65,0x74,0x69,0x6E, - 0x61,0x20,0x4D,0x61,0x63,0x73,0x06,0x3E,0x40,0x58,0x30,0x31, - 0x30,0x48,0x3E,0x2D,0x20,0x6D,0x61,0x63,0x4F,0x53,0x20,0x2F, - 0x20,0x4F,0x53,0x20,0x58,0x3A,0x20,0x48,0x6F,0x6C,0x64,0x69, - 0x6E,0x67,0x20,0x64,0x6F,0x77,0x6E,0x20,0x61,0x20,0x6D,0x6F, - 0x75,0x73,0x65,0x20,0x62,0x75,0x74,0x74,0x6F,0x6E,0x20,0x77, - 0x6F,0x6E,0x27,0x74,0x20,0x74,0x72,0x61,0x70,0x20,0x74,0x68, - 0x65,0x20,0x6D,0x6F,0x75,0x73,0x65,0x20,0x63,0x75,0x72,0x73, - 0x6F,0x72,0x4D,0x3E,0x40,0x58,0x30,0x32,0x31,0x69,0x6E,0x73, - 0x69,0x64,0x65,0x20,0x74,0x68,0x65,0x20,0x77,0x69,0x6E,0x64, - 0x6F,0x77,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20, - 0x72,0x65,0x6C,0x61,0x74,0x65,0x64,0x20,0x74,0x6F,0x20,0x61, - 0x20,0x6B,0x6C,0x75,0x64,0x67,0x65,0x20,0x74,0x68,0x61,0x74, - 0x20,0x73,0x69,0x6D,0x70,0x6C,0x79,0x20,0x64,0x6F,0x65,0x73, - 0x6E,0x27,0x74,0x20,0x77,0x6F,0x72,0x6B,0x4F,0x76,0x65,0x72, - 0x79,0x20,0x77,0x65,0x6C,0x6C,0x20,0x69,0x6E,0x20,0x6D,0x61, - 0x63,0x4F,0x53,0x2E,0x20,0x54,0x68,0x65,0x20,0x6D,0x6F,0x75, - 0x73,0x65,0x20,0x6D,0x6F,0x76,0x65,0x6D,0x65,0x6E,0x74,0x20, - 0x77,0x6F,0x75,0x6C,0x64,0x20,0x66,0x72,0x65,0x65,0x7A,0x65, - 0x20,0x66,0x6F,0x72,0x20,0x73,0x6F,0x6D,0x65,0x20,0x74,0x69, - 0x6D,0x65,0x20,0x61,0x66,0x74,0x65,0x72,0x20,0x61,0x20,0x6D, - 0x6F,0x75,0x73,0x65,0x15,0x62,0x75,0x74,0x74,0x6F,0x6E,0x20, - 0x77,0x61,0x73,0x20,0x68,0x65,0x6C,0x64,0x20,0x64,0x6F,0x77, - 0x6E,0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x4B,0x3E,0x40, - 0x43,0x30,0x30,0x32,0x2D,0x20,0x54,0x68,0x65,0x20,0x22,0x63, - 0x6C,0x65,0x61,0x72,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x22, - 0x20,0x73,0x68,0x6F,0x72,0x74,0x63,0x75,0x74,0x20,0x28,0x73, - 0x68,0x69,0x66,0x74,0x20,0x2B,0x20,0x6E,0x75,0x6D,0x2D,0x70, - 0x61,0x64,0x20,0x44,0x65,0x6C,0x2F,0x27,0x2C,0x27,0x29,0x20, - 0x6F,0x6E,0x6C,0x79,0x20,0x77,0x6F,0x72,0x6B,0x73,0x20,0x69, - 0x66,0x37,0x3E,0x40,0x58,0x30,0x32,0x31,0x6E,0x75,0x6D,0x20, - 0x6C,0x6F,0x63,0x6B,0x20,0x69,0x73,0x20,0x6F,0x66,0x66,0x2E, - 0x20,0x54,0x68,0x65,0x72,0x65,0x27,0x73,0x20,0x6E,0x6F,0x20, - 0x77,0x61,0x79,0x20,0x49,0x20,0x63,0x61,0x6E,0x20,0x66,0x69, - 0x78,0x20,0x74,0x68,0x69,0x73,0x2E,0x2E,0x2E,0x06,0x3E,0x40, - 0x58,0x30,0x31,0x30,0x0C,0x3E,0x40,0x43,0x30,0x30,0x31,0x56, - 0x69,0x64,0x65,0x6F,0x3A,0x06,0x3E,0x40,0x43,0x30,0x30,0x32, - 0x4A,0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x54,0x68,0x65, - 0x20,0x73,0x63,0x6F,0x70,0x65,0x73,0x20,0x63,0x61,0x6E,0x20, - 0x6D,0x69,0x6C,0x64,0x6C,0x79,0x20,0x66,0x6C,0x69,0x63,0x6B, - 0x65,0x72,0x20,0x64,0x65,0x70,0x65,0x6E,0x64,0x69,0x6E,0x67, - 0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x20,0x77,0x61,0x76,0x65, - 0x66,0x6F,0x72,0x6D,0x20,0x61,0x6E,0x64,0x20,0x70,0x69,0x74, - 0x63,0x68,0x2E,0x4D,0x3E,0x40,0x58,0x30,0x32,0x31,0x54,0x68, - 0x69,0x73,0x20,0x69,0x73,0x20,0x62,0x65,0x63,0x61,0x75,0x73, - 0x65,0x20,0x74,0x68,0x65,0x69,0x72,0x20,0x66,0x72,0x65,0x71, - 0x75,0x65,0x6E,0x63,0x79,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74, - 0x20,0x63,0x6C,0x6F,0x63,0x6B,0x65,0x64,0x20,0x74,0x6F,0x20, - 0x65,0x78,0x61,0x63,0x74,0x6C,0x79,0x20,0x74,0x68,0x65,0x20, - 0x73,0x61,0x6D,0x65,0x20,0x72,0x61,0x74,0x65,0x4D,0x3E,0x61, - 0x74,0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x74,0x68,0x65,0x20, - 0x73,0x63,0x6F,0x70,0x65,0x73,0x20,0x61,0x72,0x65,0x20,0x72, - 0x65,0x6E,0x64,0x65,0x72,0x65,0x64,0x2E,0x20,0x49,0x74,0x27, - 0x73,0x20,0x63,0x6C,0x6F,0x73,0x65,0x2C,0x20,0x77,0x68,0x69, - 0x63,0x68,0x20,0x63,0x61,0x75,0x73,0x65,0x73,0x20,0x61,0x20, - 0x66,0x6C,0x69,0x63,0x6B,0x65,0x72,0x20,0x65,0x66,0x66,0x65, - 0x63,0x74,0x2E,0x01,0x3E,0x52,0x3E,0x40,0x58,0x30,0x31,0x30, - 0x2D,0x20,0x4E,0x6F,0x74,0x20,0x61,0x20,0x62,0x75,0x67,0x2C, - 0x20,0x62,0x75,0x74,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,0x72, - 0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,0x20,0x72, - 0x65,0x66,0x72,0x65,0x73,0x68,0x20,0x72,0x61,0x74,0x65,0x20, - 0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x73,0x65,0x74,0x20,0x74, - 0x6F,0x20,0x36,0x30,0x48,0x7A,0x20,0x28,0x6F,0x72,0x20,0x35, - 0x39,0x48,0x7A,0x29,0x4F,0x3E,0x40,0x58,0x30,0x32,0x31,0x79, - 0x6F,0x75,0x20,0x6D,0x61,0x79,0x20,0x65,0x78,0x70,0x65,0x72, - 0x69,0x65,0x6E,0x63,0x65,0x20,0x76,0x69,0x73,0x75,0x61,0x6C, - 0x20,0x73,0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x20, - 0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x56,0x53,0x79,0x6E, - 0x63,0x20,0x77,0x69,0x6C,0x6C,0x20,0x6E,0x6F,0x74,0x20,0x62, - 0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x74,0x68,0x65,0x6E,0x2E, - 0x49,0x49,0x20,0x68,0x69,0x67,0x68,0x6C,0x79,0x20,0x72,0x65, - 0x63,0x6F,0x6D,0x6D,0x65,0x6E,0x64,0x20,0x72,0x75,0x6E,0x6E, - 0x69,0x6E,0x67,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E, - 0x69,0x74,0x6F,0x72,0x20,0x61,0x74,0x20,0x36,0x30,0x48,0x7A, - 0x20,0x69,0x66,0x20,0x79,0x6F,0x75,0x27,0x72,0x65,0x20,0x61, - 0x20,0x68,0x61,0x72,0x64,0x63,0x6F,0x72,0x65,0x20,0x75,0x73, - 0x65,0x72,0x10,0x6F,0x66,0x20,0x74,0x68,0x69,0x73,0x20,0x70, - 0x72,0x6F,0x67,0x72,0x61,0x6D,0x2E,0x00,0x03,0x45,0x4E,0x44 + 0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x0C, + 0x40,0x4C,0x4B,0x6E,0x6F,0x77,0x6E,0x20,0x62,0x75,0x67,0x73, + 0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x14,0x3E,0x40,0x43,0x30, + 0x30,0x31,0x53,0x61,0x6D,0x70,0x6C,0x65,0x20,0x65,0x64,0x69, + 0x74,0x6F,0x72,0x3A,0x06,0x3E,0x40,0x43,0x30,0x30,0x32,0x4E, + 0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x57,0x68,0x65,0x6E, + 0x20,0x61,0x20,0x6C,0x6F,0x6F,0x70,0x65,0x64,0x20,0x73,0x61, + 0x6D,0x70,0x6C,0x65,0x20,0x69,0x73,0x20,0x7A,0x6F,0x6F,0x6D, + 0x65,0x64,0x20,0x6F,0x75,0x74,0x20,0x69,0x6E,0x20,0x74,0x68, + 0x65,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x65,0x64,0x69, + 0x74,0x6F,0x72,0x2C,0x20,0x79,0x6F,0x75,0x20,0x63,0x6F,0x75, + 0x6C,0x64,0x20,0x73,0x65,0x65,0x4D,0x3E,0x40,0x58,0x30,0x32, + 0x31,0x75,0x6E,0x77,0x61,0x6E,0x74,0x65,0x64,0x20,0x73,0x61, + 0x6D,0x70,0x6C,0x65,0x20,0x64,0x61,0x74,0x61,0x20,0x61,0x74, + 0x20,0x74,0x68,0x65,0x20,0x6C,0x6F,0x6F,0x70,0x2D,0x65,0x6E, + 0x64,0x20,0x70,0x6F,0x69,0x6E,0x74,0x2E,0x20,0x54,0x68,0x69, + 0x73,0x20,0x69,0x73,0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65, + 0x20,0x6F,0x66,0x20,0x61,0x20,0x6B,0x6C,0x75,0x64,0x67,0x65, + 0x4B,0x66,0x6F,0x72,0x20,0x74,0x68,0x65,0x20,0x72,0x65,0x73, + 0x61,0x6D,0x70,0x6C,0x69,0x6E,0x67,0x20,0x69,0x6E,0x74,0x65, + 0x72,0x70,0x6F,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x20,0x74,0x6F, + 0x20,0x77,0x6F,0x72,0x6B,0x20,0x66,0x61,0x73,0x74,0x65,0x72, + 0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x61,0x75,0x64,0x69, + 0x6F,0x20,0x6D,0x69,0x78,0x65,0x72,0x2C,0x20,0x61,0x6E,0x64, + 0x20,0x74,0x68,0x65,0x4B,0x6F,0x72,0x69,0x67,0x69,0x6E,0x61, + 0x6C,0x20,0x46,0x54,0x32,0x20,0x68,0x61,0x73,0x20,0x74,0x68, + 0x65,0x20,0x73,0x61,0x6D,0x65,0x20,0x70,0x72,0x6F,0x62,0x6C, + 0x65,0x6D,0x2E,0x20,0x49,0x20,0x68,0x61,0x76,0x65,0x20,0x6D, + 0x61,0x64,0x65,0x20,0x69,0x74,0x20,0x73,0x6F,0x20,0x74,0x68, + 0x61,0x74,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,0x20,0x7A,0x6F, + 0x6F,0x6D,0x20,0x69,0x6E,0x20,0x74,0x6F,0x3B,0x73,0x65,0x65, + 0x20,0x74,0x68,0x65,0x20,0x69,0x6E,0x64,0x69,0x76,0x69,0x64, + 0x75,0x61,0x6C,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x70, + 0x6F,0x69,0x6E,0x74,0x73,0x2C,0x20,0x69,0x74,0x20,0x77,0x69, + 0x6C,0x6C,0x20,0x6C,0x6F,0x6F,0x6B,0x20,0x6C,0x69,0x6B,0x65, + 0x20,0x6E,0x6F,0x72,0x6D,0x61,0x6C,0x2E,0x06,0x3E,0x40,0x58, + 0x30,0x31,0x30,0x17,0x3E,0x40,0x43,0x30,0x30,0x31,0x4D,0x6F, + 0x75,0x73,0x65,0x20,0x2F,0x20,0x6B,0x65,0x79,0x62,0x6F,0x61, + 0x72,0x64,0x3A,0x01,0x3E,0x4D,0x3E,0x40,0x43,0x30,0x30,0x32, + 0x2D,0x20,0x57,0x68,0x65,0x6E,0x20,0x79,0x6F,0x75,0x20,0x68, + 0x6F,0x6C,0x64,0x20,0x64,0x6F,0x77,0x6E,0x20,0x61,0x20,0x6B, + 0x65,0x79,0x20,0x28,0x66,0x2E,0x65,0x78,0x2E,0x20,0x70,0x6C, + 0x61,0x79,0x69,0x6E,0x67,0x20,0x61,0x20,0x73,0x61,0x6D,0x70, + 0x6C,0x65,0x29,0x2C,0x20,0x74,0x68,0x65,0x20,0x6D,0x6F,0x75, + 0x73,0x65,0x20,0x6D,0x6F,0x76,0x65,0x6D,0x65,0x6E,0x74,0x4A, + 0x3E,0x40,0x58,0x30,0x32,0x31,0x63,0x61,0x6E,0x20,0x62,0x65, + 0x20,0x63,0x68,0x6F,0x70,0x70,0x79,0x2E,0x20,0x54,0x68,0x69, + 0x73,0x20,0x69,0x73,0x20,0x72,0x65,0x6C,0x61,0x74,0x65,0x64, + 0x20,0x74,0x6F,0x20,0x74,0x68,0x65,0x20,0x69,0x6E,0x70,0x75, + 0x74,0x20,0x71,0x75,0x65,0x75,0x65,0x20,0x62,0x65,0x69,0x6E, + 0x67,0x20,0x73,0x70,0x61,0x6D,0x6D,0x65,0x64,0x20,0x77,0x69, + 0x74,0x68,0x36,0x22,0x6B,0x65,0x79,0x20,0x64,0x6F,0x77,0x6E, + 0x22,0x20,0x65,0x76,0x65,0x6E,0x74,0x73,0x2C,0x20,0x64,0x65, + 0x6C,0x61,0x79,0x69,0x6E,0x67,0x20,0x74,0x68,0x65,0x20,0x6D, + 0x6F,0x75,0x73,0x65,0x20,0x70,0x6F,0x73,0x69,0x74,0x69,0x6F, + 0x6E,0x20,0x65,0x76,0x65,0x6E,0x74,0x73,0x2E,0x4E,0x49,0x20, + 0x6F,0x6E,0x6C,0x79,0x20,0x70,0x6F,0x6C,0x6C,0x20,0x69,0x6E, + 0x70,0x75,0x74,0x20,0x6F,0x6E,0x63,0x65,0x20,0x70,0x65,0x72, + 0x20,0x66,0x72,0x61,0x6D,0x65,0x20,0x28,0x36,0x30,0x48,0x7A, + 0x29,0x2C,0x20,0x73,0x6F,0x20,0x74,0x68,0x65,0x20,0x66,0x72, + 0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x20,0x69,0x73,0x20,0x61, + 0x20,0x74,0x61,0x64,0x20,0x6C,0x6F,0x77,0x2E,0x20,0x49,0x74, + 0x20,0x68,0x61,0x73,0x2E,0x74,0x6F,0x20,0x62,0x65,0x20,0x6C, + 0x69,0x6B,0x65,0x20,0x74,0x68,0x69,0x73,0x20,0x66,0x6F,0x72, + 0x20,0x73,0x65,0x76,0x65,0x72,0x61,0x6C,0x20,0x72,0x65,0x61, + 0x73,0x6F,0x6E,0x73,0x2C,0x20,0x74,0x68,0x6F,0x75,0x67,0x68, + 0x2E,0x2E,0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x47,0x3E, + 0x40,0x43,0x30,0x30,0x32,0x2D,0x20,0x6D,0x61,0x63,0x4F,0x53, + 0x20,0x2F,0x20,0x4F,0x53,0x20,0x58,0x3A,0x20,0x22,0x48,0x61, + 0x72,0x64,0x77,0x61,0x72,0x65,0x20,0x6D,0x6F,0x64,0x65,0x22, + 0x20,0x6D,0x6F,0x75,0x73,0x65,0x20,0x6C,0x6F,0x6F,0x6B,0x73, + 0x20,0x62,0x6C,0x75,0x72,0x72,0x79,0x20,0x6F,0x6E,0x20,0x72, + 0x65,0x74,0x69,0x6E,0x61,0x20,0x4D,0x61,0x63,0x73,0x06,0x3E, + 0x40,0x58,0x30,0x31,0x30,0x48,0x3E,0x2D,0x20,0x6D,0x61,0x63, + 0x4F,0x53,0x20,0x2F,0x20,0x4F,0x53,0x20,0x58,0x3A,0x20,0x48, + 0x6F,0x6C,0x64,0x69,0x6E,0x67,0x20,0x64,0x6F,0x77,0x6E,0x20, + 0x61,0x20,0x6D,0x6F,0x75,0x73,0x65,0x20,0x62,0x75,0x74,0x74, + 0x6F,0x6E,0x20,0x77,0x6F,0x6E,0x27,0x74,0x20,0x74,0x72,0x61, + 0x70,0x20,0x74,0x68,0x65,0x20,0x6D,0x6F,0x75,0x73,0x65,0x20, + 0x63,0x75,0x72,0x73,0x6F,0x72,0x4D,0x3E,0x40,0x58,0x30,0x32, + 0x31,0x69,0x6E,0x73,0x69,0x64,0x65,0x20,0x74,0x68,0x65,0x20, + 0x77,0x69,0x6E,0x64,0x6F,0x77,0x2E,0x20,0x54,0x68,0x69,0x73, + 0x20,0x69,0x73,0x20,0x72,0x65,0x6C,0x61,0x74,0x65,0x64,0x20, + 0x74,0x6F,0x20,0x61,0x20,0x6B,0x6C,0x75,0x64,0x67,0x65,0x20, + 0x74,0x68,0x61,0x74,0x20,0x73,0x69,0x6D,0x70,0x6C,0x79,0x20, + 0x64,0x6F,0x65,0x73,0x6E,0x27,0x74,0x20,0x77,0x6F,0x72,0x6B, + 0x4F,0x76,0x65,0x72,0x79,0x20,0x77,0x65,0x6C,0x6C,0x20,0x69, + 0x6E,0x20,0x6D,0x61,0x63,0x4F,0x53,0x2E,0x20,0x54,0x68,0x65, + 0x20,0x6D,0x6F,0x75,0x73,0x65,0x20,0x6D,0x6F,0x76,0x65,0x6D, + 0x65,0x6E,0x74,0x20,0x77,0x6F,0x75,0x6C,0x64,0x20,0x66,0x72, + 0x65,0x65,0x7A,0x65,0x20,0x66,0x6F,0x72,0x20,0x73,0x6F,0x6D, + 0x65,0x20,0x74,0x69,0x6D,0x65,0x20,0x61,0x66,0x74,0x65,0x72, + 0x20,0x61,0x20,0x6D,0x6F,0x75,0x73,0x65,0x15,0x62,0x75,0x74, + 0x74,0x6F,0x6E,0x20,0x77,0x61,0x73,0x20,0x68,0x65,0x6C,0x64, + 0x20,0x64,0x6F,0x77,0x6E,0x2E,0x06,0x3E,0x40,0x58,0x30,0x31, + 0x30,0x4B,0x3E,0x40,0x43,0x30,0x30,0x32,0x2D,0x20,0x54,0x68, + 0x65,0x20,0x22,0x63,0x6C,0x65,0x61,0x72,0x20,0x73,0x61,0x6D, + 0x70,0x6C,0x65,0x22,0x20,0x73,0x68,0x6F,0x72,0x74,0x63,0x75, + 0x74,0x20,0x28,0x73,0x68,0x69,0x66,0x74,0x20,0x2B,0x20,0x6E, + 0x75,0x6D,0x2D,0x70,0x61,0x64,0x20,0x44,0x65,0x6C,0x2F,0x27, + 0x2C,0x27,0x29,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x77,0x6F,0x72, + 0x6B,0x73,0x20,0x69,0x66,0x37,0x3E,0x40,0x58,0x30,0x32,0x31, + 0x6E,0x75,0x6D,0x20,0x6C,0x6F,0x63,0x6B,0x20,0x69,0x73,0x20, + 0x6F,0x66,0x66,0x2E,0x20,0x54,0x68,0x65,0x72,0x65,0x27,0x73, + 0x20,0x6E,0x6F,0x20,0x77,0x61,0x79,0x20,0x49,0x20,0x63,0x61, + 0x6E,0x20,0x66,0x69,0x78,0x20,0x74,0x68,0x69,0x73,0x2E,0x2E, + 0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x0C,0x3E,0x40,0x43, + 0x30,0x30,0x31,0x56,0x69,0x64,0x65,0x6F,0x3A,0x06,0x3E,0x40, + 0x43,0x30,0x30,0x32,0x4A,0x3E,0x40,0x58,0x30,0x31,0x30,0x2D, + 0x20,0x54,0x68,0x65,0x20,0x73,0x63,0x6F,0x70,0x65,0x73,0x20, + 0x63,0x61,0x6E,0x20,0x6D,0x69,0x6C,0x64,0x6C,0x79,0x20,0x66, + 0x6C,0x69,0x63,0x6B,0x65,0x72,0x20,0x64,0x65,0x70,0x65,0x6E, + 0x64,0x69,0x6E,0x67,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x20, + 0x77,0x61,0x76,0x65,0x66,0x6F,0x72,0x6D,0x20,0x61,0x6E,0x64, + 0x20,0x70,0x69,0x74,0x63,0x68,0x2E,0x4D,0x3E,0x40,0x58,0x30, + 0x32,0x31,0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x62,0x65, + 0x63,0x61,0x75,0x73,0x65,0x20,0x74,0x68,0x65,0x69,0x72,0x20, + 0x66,0x72,0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x20,0x69,0x73, + 0x20,0x6E,0x6F,0x74,0x20,0x63,0x6C,0x6F,0x63,0x6B,0x65,0x64, + 0x20,0x74,0x6F,0x20,0x65,0x78,0x61,0x63,0x74,0x6C,0x79,0x20, + 0x74,0x68,0x65,0x20,0x73,0x61,0x6D,0x65,0x20,0x72,0x61,0x74, + 0x65,0x4D,0x3E,0x61,0x74,0x20,0x77,0x68,0x69,0x63,0x68,0x20, + 0x74,0x68,0x65,0x20,0x73,0x63,0x6F,0x70,0x65,0x73,0x20,0x61, + 0x72,0x65,0x20,0x72,0x65,0x6E,0x64,0x65,0x72,0x65,0x64,0x2E, + 0x20,0x49,0x74,0x27,0x73,0x20,0x63,0x6C,0x6F,0x73,0x65,0x2C, + 0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x63,0x61,0x75,0x73,0x65, + 0x73,0x20,0x61,0x20,0x66,0x6C,0x69,0x63,0x6B,0x65,0x72,0x20, + 0x65,0x66,0x66,0x65,0x63,0x74,0x2E,0x01,0x3E,0x52,0x3E,0x40, + 0x58,0x30,0x31,0x30,0x2D,0x20,0x4E,0x6F,0x74,0x20,0x61,0x20, + 0x62,0x75,0x67,0x2C,0x20,0x62,0x75,0x74,0x20,0x69,0x66,0x20, + 0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72, + 0x27,0x73,0x20,0x72,0x65,0x66,0x72,0x65,0x73,0x68,0x20,0x72, + 0x61,0x74,0x65,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x73, + 0x65,0x74,0x20,0x74,0x6F,0x20,0x36,0x30,0x48,0x7A,0x20,0x28, + 0x6F,0x72,0x20,0x35,0x39,0x48,0x7A,0x29,0x4F,0x3E,0x40,0x58, + 0x30,0x32,0x31,0x79,0x6F,0x75,0x20,0x6D,0x61,0x79,0x20,0x65, + 0x78,0x70,0x65,0x72,0x69,0x65,0x6E,0x63,0x65,0x20,0x76,0x69, + 0x73,0x75,0x61,0x6C,0x20,0x73,0x74,0x75,0x74,0x74,0x65,0x72, + 0x69,0x6E,0x67,0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20, + 0x56,0x53,0x79,0x6E,0x63,0x20,0x77,0x69,0x6C,0x6C,0x20,0x6E, + 0x6F,0x74,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x74, + 0x68,0x65,0x6E,0x2E,0x49,0x49,0x20,0x68,0x69,0x67,0x68,0x6C, + 0x79,0x20,0x72,0x65,0x63,0x6F,0x6D,0x6D,0x65,0x6E,0x64,0x20, + 0x72,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x79,0x6F,0x75,0x72, + 0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x20,0x61,0x74,0x20, + 0x36,0x30,0x48,0x7A,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,0x27, + 0x72,0x65,0x20,0x61,0x20,0x68,0x61,0x72,0x64,0x63,0x6F,0x72, + 0x65,0x20,0x75,0x73,0x65,0x72,0x10,0x6F,0x66,0x20,0x74,0x68, + 0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x2E,0x00, + 0x03,0x45,0x4E,0x44 }; #endif diff --git a/src/helpdata/ft2hlp_to_h.exe b/src/helpdata/ft2hlp_to_h.exe Binary files differ. diff --git a/vs2019_project/ft2-clone/ft2-clone.vcxproj b/vs2019_project/ft2-clone/ft2-clone.vcxproj @@ -357,6 +357,7 @@ <ClCompile Include="..\..\src\ft2_scopes.c" /> <ClCompile Include="..\..\src\ft2_scrollbars.c" /> <ClCompile Include="..\..\src\ft2_sysreqs.c" /> + <ClCompile Include="..\..\src\ft2_tables.c" /> <ClCompile Include="..\..\src\ft2_textboxes.c" /> <ClCompile Include="..\..\src\ft2_trim.c" /> <ClCompile Include="..\..\src\ft2_unicode.c" /> @@ -424,6 +425,7 @@ <ClInclude Include="..\..\src\ft2_scopes.h" /> <ClInclude Include="..\..\src\ft2_scrollbars.h" /> <ClInclude Include="..\..\src\ft2_sysreqs.h" /> + <ClInclude Include="..\..\src\ft2_tables.h" /> <ClInclude Include="..\..\src\ft2_textboxes.h" /> <ClInclude Include="..\..\src\ft2_trim.h" /> <ClInclude Include="..\..\src\ft2_unicode.h" /> diff --git a/vs2019_project/ft2-clone/ft2-clone.vcxproj.filters b/vs2019_project/ft2-clone/ft2-clone.vcxproj.filters @@ -70,6 +70,7 @@ </ClCompile> <ClCompile Include="..\..\src\ft2_palette.c" /> <ClCompile Include="..\..\src\ft2_scopedraw.c" /> + <ClCompile Include="..\..\src\ft2_tables.c" /> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\src\ft2_audio.h"> @@ -201,6 +202,9 @@ <ClInclude Include="..\..\src\ft2_scopedraw.h"> <Filter>headers</Filter> </ClInclude> + <ClInclude Include="..\..\src\ft2_tables.h"> + <Filter>headers</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <Filter Include="headers">