adlibtracker2-2.4.24/ 0000755 0000000 0000000 00000000000 13414571216 013016 5 ustar root root adlibtracker2-2.4.24/.gitignore 0000644 0000000 0000000 00000000047 13411003760 014776 0 ustar root root bin/*
release
*.o
*.ppu
*.res
adtrack2
adlibtracker2-2.4.24/adt2play/ 0000755 0000000 0000000 00000000000 13411003760 014525 5 ustar root root adlibtracker2-2.4.24/adt2play/a2data.pas 0000644 0000000 0000000 00000630632 13411003760 016400 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
unit A2data;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
interface
const
font8x8: array[0..511] of Dword = (
$0aa000000,$000000000,$0aa808080,$000808080,$0aaa0a0a0,$000a0a0a0,$0aaa8a8a8,$000a8a8a8,
$0aaaaaaaa,$000aaaaaa,$0fe387c38,$07c387cfe,$07c381010,$07c387cfe,$03c180000,$00000183c,
$0c3e7ffff,$0ffffe7c3,$042663c00,$0003c6642,$0bd99c3ff,$0ffc399bd,$07d0f070f,$078cccccc,
$06666663c,$0187e183c,$0303f333f,$0e0f07030,$0637f637f,$0c0e66763,$0e73c5a99,$0995a3ce7,
$0fef8e080,$00080e0f8,$0fe3e0e02,$000020e3e,$0187e3c18,$0183c7e18,$066666666,$000660066,
$07bdbdb7f,$0001b1b1b,$06c38633e,$078cc386c,$000000000,$0007e7e7e,$0187e3c18,$0ff183c7e,
$0187e3c18,$000181818,$018181818,$000183c7e,$0fe0c1800,$00000180c,$0fe603000,$000003060,
$0c0c00000,$00000fec0,$0ff662400,$000002466,$07e3c1800,$00000ffff,$07effff00,$00000183c,
$000000000,$000000000,$030787830,$000300030,$0006c6c6c,$000000000,$06cfe6c6c,$0006c6cfe,
$078c07c30,$00030f80c,$018ccc600,$000c66630,$076386c38,$00076ccdc,$000c06060,$000000000,
$060603018,$000183060,$018183060,$000603018,$0ff3c6600,$00000663c,$0fc303000,$000003030,
$000000000,$060303000,$0fc000000,$000000000,$000000000,$000303000,$030180c06,$00080c060,
$0decec67c,$0007ce6f6,$030307030,$000fc3030,$0380ccc78,$000fccc60,$0380ccc78,$00078cc0c,
$0cc6c3c1c,$0001e0cfe,$00cf8c0fc,$00078cc0c,$0f8c06038,$00078cccc,$0180cccfc,$000303030,
$078cccc78,$00078cccc,$07ccccc78,$00070180c,$000303000,$000303000,$000303000,$060303000,
$0c0603018,$000183060,$000fc0000,$00000fc00,$00c183060,$000603018,$0180ccc78,$000300030,
$0dedec67c,$00078c0de,$0cccc7830,$000ccccfc,$07c6666fc,$000fc6666,$0c0c0663c,$0003c66c0,
$066666cf8,$000f86c66,$0786862fe,$000fe6268,$0786862fe,$000f06068,$0c0c0663c,$0003e66ce,
$0fccccccc,$000cccccc,$030303078,$000783030,$00c0c0c1e,$00078cccc,$0786c66e6,$000e6666c,
$0606060f0,$000fe6662,$0fefeeec6,$000c6c6d6,$0def6e6c6,$000c6c6ce,$0c6c66c38,$000386cc6,
$07c6666fc,$000f06060,$0cccccc78,$0001c78dc,$07c6666fc,$000e6666c,$070e0cc78,$00078cc1c,
$03030b4fc,$000783030,$0cccccccc,$000fccccc,$0cccccccc,$0003078cc,$0d6c6c6c6,$000c6eefe,
$0386cc6c6,$000c66c38,$078cccccc,$000783030,$0188cc6fe,$000fe6632,$060606078,$000786060,
$0183060c0,$00002060c,$018181878,$000781818,$0c66c3810,$000000000,$000000000,$0ff000000,
$000183030,$000000000,$00c780000,$00076cc7c,$07c6060e0,$000dc6666,$0cc780000,$00078ccc0,
$07c0c0c1c,$00076cccc,$0cc780000,$00078c0fc,$0f0606c38,$000f06060,$0cc760000,$0f80c7ccc,
$0766c60e0,$000e66666,$030700030,$000783030,$00c0c000c,$078cccc0c,$06c6660e0,$000e66c78,
$030303070,$000783030,$0fecc0000,$000c6d6fe,$0ccf80000,$000cccccc,$0cc780000,$00078cccc,
$066dc0000,$0f0607c66,$0cc760000,$01e0c7ccc,$076dc0000,$000f06066,$0c07c0000,$000f80c78,
$0307c3010,$000183430,$0cccc0000,$00076cccc,$0cccc0000,$0003078cc,$0d6c60000,$0006cfefe,
$06cc60000,$000c66c38,$0cccc0000,$0f80c7ccc,$098fc0000,$000fc6430,$0e030301c,$0001c3030,
$000181818,$000181818,$01c3030e0,$000e03030,$00000dc76,$000000000,$06c381000,$000fec6c6,
$0ccc0cc78,$0780c1878,$0cc00cc00,$0007ecccc,$0cc78001c,$00078c0fc,$0063cc37e,$0003f663e,
$00c7800cc,$0007ecc7c,$00c7800e0,$0007ecc7c,$00c783030,$0007ecc7c,$0c0780000,$0380c78c0,
$0663cc37e,$0003c607e,$0cc7800cc,$00078c0fc,$0cc7800e0,$00078c0fc,$0307000cc,$000783030,
$01838c67c,$0003c1818,$0307000e0,$000783030,$0c66c38c6,$000c6c6fe,$078003030,$000ccfccc,
$060fc001c,$000fc6078,$00c7f0000,$0007fcc7f,$0fecc6c3e,$000cecccc,$07800cc78,$00078cccc,
$07800cc00,$00078cccc,$07800e000,$00078cccc,$0cc00cc78,$0007ecccc,$0cc00e000,$0007ecccc,
$0cc00cc00,$0f80c7ccc,$0663c18c3,$000183c66,$0cccc00cc,$00078cccc,$0c07e1818,$018187ec0,
$0f0646c38,$000fce660,$0fc78cccc,$03030fc30,$0faccccf8,$0c7c6cfc6,$03c181b0e,$070d81818,
$00c78001c,$0007ecc7c,$030700038,$000783030,$078001c00,$00078cccc,$0cc001c00,$0007ecccc,
$0f800f800,$000cccccc,$0eccc00fc,$000ccdcfc,$03e6c6c3c,$000007e00,$0386c6c38,$000007c00,
$060300030,$00078ccc0,$0fc000000,$00000c0c0,$0fc000000,$000000c0c,$0deccc6c3,$00fcc6633,
$0dbccc6c3,$003cf6f37,$018001818,$000181818,$0cc663300,$000003366,$03366cc00,$00000cc66,
$088228822,$088228822,$0aa55aa55,$0aa55aa55,$0eedb77db,$0eedb77db,$018181818,$018181818,
$018181818,$0181818f8,$018f81818,$0181818f8,$036363636,$0363636f6,$000000000,$0363636fe,
$018f80000,$0181818f8,$006f63636,$0363636f6,$036363636,$036363636,$006fe0000,$0363636f6,
$006f63636,$0000000fe,$036363636,$0000000fe,$018f81818,$0000000f8,$000000000,$0181818f8,
$018181818,$00000001f,$018181818,$0000000ff,$000000000,$0181818ff,$018181818,$01818181f,
$000000000,$0000000ff,$018181818,$0181818ff,$0181f1818,$01818181f,$036363636,$036363637,
$030373636,$00000003f,$0303f0000,$036363637,$000f73636,$0000000ff,$000ff0000,$0363636f7,
$030373636,$036363637,$000ff0000,$0000000ff,$000f73636,$0363636f7,$000ff1818,$0000000ff,
$036363636,$0000000ff,$000ff0000,$0181818ff,$000000000,$0363636ff,$036363636,$00000003f,
$0181f1818,$00000001f,$0181f0000,$01818181f,$000000000,$03636363f,$036363636,$0363636ff,
$018ff1818,$0181818ff,$018181818,$0000000f8,$000000000,$01818181f,$0ffffffff,$0ffffffff,
$000000000,$0ffffffff,$0f0f0f0f0,$0f0f0f0f0,$00f0f0f0f,$00f0f0f0f,$0ffffffff,$000000000,
$0dc760000,$00076dcc8,$0f8cc7800,$0c0c0f8cc,$0c0ccfc00,$000c0c0c0,$06c6cfe00,$0006c6c6c,
$03060ccfc,$000fccc60,$0d87e0000,$00070d8d8,$066666600,$0c0607c66,$018dc7600,$000181818,
$0cc7830fc,$0fc3078cc,$0fec66c38,$000386cc6,$0c6c66c38,$000ee6c6c,$07c18301c,$00078cccc,
$0db7e0000,$000007edb,$0db7e0c06,$0c0607edb,$0f8c06038,$0003860c0,$0cccccc78,$000cccccc,
$0fc00fc00,$00000fc00,$030fc3030,$000fc0030,$030183060,$000fc0060,$030603018,$000fc0018,
$0181b1b0e,$018181818,$018181818,$070d8d818,$0fc003030,$000303000,$000dc7600,$00000dc76,
$0386c6c38,$000000000,$018000000,$000000018,$000000000,$000000018,$00c0c0c0f,$01c3c6cec,
$06c6c6c78,$00000006c,$060301870,$000000078,$03c3c0000,$000003c3c,$000000000,$000000000);
const
font8x16: array[0..1023] of Dword = (
$000000000,$000000000,$000000000,$000000000,$0817e0000,$0a58181a5,$07e818199,$000000000,
$0ff7e0000,$0dbffffdb,$07effffe7,$000000000,$000000000,$0fefefe6c,$010387cfe,$000000000,
$000000000,$0fe7c3810,$00010387c,$000000000,$018000000,$0e7e73c3c,$03c1818e7,$000000000,
$018000000,$0ffff7e3c,$03c18187e,$000000000,$000000000,$03c180000,$00000183c,$000000000,
$0ffffffff,$0c3e7ffff,$0ffffe7c3,$0ffffffff,$000000000,$042663c00,$0003c6642,$000000000,
$0ffffffff,$0bd99c3ff,$0ffc399bd,$0ffffffff,$0061e0000,$0cc781a0e,$078cccccc,$000000000,
$0663c0000,$03c666666,$018187e18,$000000000,$0333f0000,$03030303f,$0e0f07030,$000000000,
$0637f0000,$06363637f,$0e6e76763,$0000000c0,$018000000,$0e73cdb18,$01818db3c,$000000000,
$0e0c08000,$0f8fef8f0,$080c0e0f0,$000000000,$00e060200,$03efe3e1e,$002060e1e,$000000000,
$03c180000,$01818187e,$000183c7e,$000000000,$066660000,$066666666,$066660066,$000000000,
$0db7f0000,$01b7bdbdb,$01b1b1b1b,$000000000,$060c67c00,$0c6c66c38,$0c60c386c,$00000007c,
$000000000,$000000000,$0fefefefe,$000000000,$03c180000,$01818187e,$07e183c7e,$000000000,
$03c180000,$01818187e,$018181818,$000000000,$018180000,$018181818,$0183c7e18,$000000000,
$000000000,$0fe0c1800,$00000180c,$000000000,$000000000,$0fe603000,$000003060,$000000000,
$000000000,$0c0c00000,$00000fec0,$000000000,$000000000,$0fe6c2800,$00000286c,$000000000,
$000000000,$07c383810,$000fefe7c,$000000000,$000000000,$07c7cfefe,$000103838,$000000000,
$000000000,$000000000,$000000000,$000000000,$03c180000,$018183c3c,$018180018,$000000000,
$066666600,$000000024,$000000000,$000000000,$06c000000,$06c6cfe6c,$06c6cfe6c,$000000000,
$0c67c1818,$0067cc0c2,$07cc68606,$000001818,$000000000,$0180cc6c2,$086c66030,$000000000,
$06c380000,$0dc76386c,$076cccccc,$000000000,$030303000,$000000060,$000000000,$000000000,
$0180c0000,$030303030,$00c183030,$000000000,$018300000,$00c0c0c0c,$030180c0c,$000000000,
$000000000,$0ff3c6600,$00000663c,$000000000,$000000000,$07e181800,$000001818,$000000000,
$000000000,$000000000,$018181800,$000000030,$000000000,$0fe000000,$000000000,$000000000,
$000000000,$000000000,$018180000,$000000000,$000000000,$0180c0602,$080c06030,$000000000,
$0c67c0000,$0f6decec6,$07cc6c6e6,$000000000,$038180000,$018181878,$07e181818,$000000000,
$0c67c0000,$030180c06,$0fec6c060,$000000000,$0c67c0000,$0063c0606,$07cc60606,$000000000,
$01c0c0000,$0fecc6c3c,$01e0c0c0c,$000000000,$0c0fe0000,$006fcc0c0,$07cc60606,$000000000,
$060380000,$0c6fcc0c0,$07cc6c6c6,$000000000,$0c6fe0000,$0180c0606,$030303030,$000000000,
$0c67c0000,$0c67cc6c6,$07cc6c6c6,$000000000,$0c67c0000,$0067ec6c6,$0780c0606,$000000000,
$000000000,$000001818,$000181800,$000000000,$000000000,$000001818,$030181800,$000000000,
$006000000,$06030180c,$0060c1830,$000000000,$000000000,$000007e00,$00000007e,$000000000,
$060000000,$0060c1830,$06030180c,$000000000,$0c67c0000,$018180cc6,$018180018,$000000000,
$07c000000,$0dedec6c6,$07cc0dcde,$000000000,$038100000,$0fec6c66c,$0c6c6c6c6,$000000000,
$066fc0000,$0667c6666,$0fc666666,$000000000,$0663c0000,$0c0c0c0c2,$03c66c2c0,$000000000,
$06cf80000,$066666666,$0f86c6666,$000000000,$066fe0000,$068786862,$0fe666260,$000000000,
$066fe0000,$068786862,$0f0606060,$000000000,$0663c0000,$0dec0c0c2,$03a66c6c6,$000000000,
$0c6c60000,$0c6fec6c6,$0c6c6c6c6,$000000000,$0183c0000,$018181818,$03c181818,$000000000,
$00c1e0000,$00c0c0c0c,$078cccccc,$000000000,$066e60000,$078786c66,$0e666666c,$000000000,
$060f00000,$060606060,$0fe666260,$000000000,$0eec60000,$0c6d6fefe,$0c6c6c6c6,$000000000,
$0e6c60000,$0cedefef6,$0c6c6c6c6,$000000000,$0c67c0000,$0c6c6c6c6,$07cc6c6c6,$000000000,
$066fc0000,$0607c6666,$0f0606060,$000000000,$0c67c0000,$0c6c6c6c6,$07cded6c6,$000000e0c,
$066fc0000,$06c7c6666,$0e6666666,$000000000,$0c67c0000,$00c3860c6,$07cc6c606,$000000000,
$07e7e0000,$01818185a,$03c181818,$000000000,$0c6c60000,$0c6c6c6c6,$07cc6c6c6,$000000000,
$0c6c60000,$0c6c6c6c6,$010386cc6,$000000000,$0c6c60000,$0d6d6c6c6,$06ceefed6,$000000000,
$0c6c60000,$038387c6c,$0c6c66c7c,$000000000,$066660000,$0183c6666,$03c181818,$000000000,
$0c6fe0000,$030180c86,$0fec6c260,$000000000,$0303c0000,$030303030,$03c303030,$000000000,
$080000000,$03870e0c0,$002060e1c,$000000000,$00c3c0000,$00c0c0c0c,$03c0c0c0c,$000000000,
$0c66c3810,$000000000,$000000000,$000000000,$000000000,$000000000,$000000000,$00000ff00,
$000183030,$000000000,$000000000,$000000000,$000000000,$07c0c7800,$076cccccc,$000000000,
$060e00000,$0666c7860,$07c666666,$000000000,$000000000,$0c0c67c00,$07cc6c0c0,$000000000,
$00c1c0000,$0cc6c3c0c,$076cccccc,$000000000,$000000000,$0fec67c00,$07cc6c0c0,$000000000,
$06c380000,$060f06064,$0f0606060,$000000000,$000000000,$0cccc7600,$07ccccccc,$00078cc0c,
$060e00000,$066766c60,$0e6666666,$000000000,$018180000,$018183800,$03c181818,$000000000,
$006060000,$006060e00,$006060606,$0003c6666,$060e00000,$0786c6660,$0e6666c78,$000000000,
$018380000,$018181818,$03c181818,$000000000,$000000000,$0d6feec00,$0c6d6d6d6,$000000000,
$000000000,$06666dc00,$066666666,$000000000,$000000000,$0c6c67c00,$07cc6c6c6,$000000000,
$000000000,$06666dc00,$07c666666,$000f06060,$000000000,$0cccc7600,$07ccccccc,$0001e0c0c,
$000000000,$06676dc00,$0f0606060,$000000000,$000000000,$060c67c00,$07cc60c38,$000000000,
$030100000,$03030fc30,$01c363030,$000000000,$000000000,$0cccccc00,$076cccccc,$000000000,
$000000000,$066666600,$0183c6666,$000000000,$000000000,$0d6c6c600,$06cfed6d6,$000000000,
$000000000,$0386cc600,$0c66c3838,$000000000,$000000000,$0c6c6c600,$07ec6c6c6,$000f80c06,
$000000000,$018ccfe00,$0fec66030,$000000000,$0180e0000,$018701818,$00e181818,$000000000,
$018180000,$018001818,$018181818,$000000000,$018700000,$0180e1818,$070181818,$000000000,
$0dc760000,$000000000,$000000000,$000000000,$000000000,$0c66c3810,$000fec6c6,$000000000,
$0663c0000,$0c0c0c0c2,$00c3c66c2,$000007c06,$000cc0000,$0cccccc00,$076cccccc,$000000000,
$030180c00,$0fec67c00,$07cc6c0c0,$000000000,$06c381000,$07c0c7800,$076cccccc,$000000000,
$000cc0000,$07c0c7800,$076cccccc,$000000000,$018306000,$07c0c7800,$076cccccc,$000000000,
$0386c3800,$07c0c7800,$076cccccc,$000000000,$000000000,$06060663c,$0060c3c66,$00000003c,
$06c381000,$0fec67c00,$07cc6c0c0,$000000000,$000c60000,$0fec67c00,$07cc6c0c0,$000000000,
$018306000,$0fec67c00,$07cc6c0c0,$000000000,$000660000,$018183800,$03c181818,$000000000,
$0663c1800,$018183800,$03c181818,$000000000,$018306000,$018183800,$03c181818,$000000000,
$01000c600,$0c6c66c38,$0c6c6c6fe,$000000000,$000386c38,$0c6c66c38,$0c6c6c6fe,$000000000,
$000603018,$07c6066fe,$0fe666060,$000000000,$000000000,$03676cc00,$06ed8d87e,$000000000,
$06c3e0000,$0ccfecccc,$0cecccccc,$000000000,$06c381000,$0c6c67c00,$07cc6c6c6,$000000000,
$000c60000,$0c6c67c00,$07cc6c6c6,$000000000,$018306000,$0c6c67c00,$07cc6c6c6,$000000000,
$0cc783000,$0cccccc00,$076cccccc,$000000000,$018306000,$0cccccc00,$076cccccc,$000000000,
$000c60000,$0c6c6c600,$07ec6c6c6,$000780c06,$07c00c600,$0c6c6c6c6,$07cc6c6c6,$000000000,
$0c600c600,$0c6c6c6c6,$07cc6c6c6,$000000000,$03c181800,$060606066,$018183c66,$000000000,
$0646c3800,$06060f060,$0fce66060,$000000000,$066660000,$0187e183c,$01818187e,$000000000,
$0ccccf800,$0deccc4f8,$0c6cccccc,$000000000,$0181b0e00,$0187e1818,$018181818,$0000070d8,
$060301800,$07c0c7800,$076cccccc,$000000000,$030180c00,$018183800,$03c181818,$000000000,
$060301800,$0c6c67c00,$07cc6c6c6,$000000000,$060301800,$0cccccc00,$076cccccc,$000000000,
$0dc760000,$06666dc00,$066666666,$000000000,$0c600dc76,$0defef6e6,$0c6c6c6ce,$000000000,
$06c6c3c00,$0007e003e,$000000000,$000000000,$06c6c3800,$0007c0038,$000000000,$000000000,
$030300000,$060303000,$07cc6c6c0,$000000000,$000000000,$0c0fe0000,$000c0c0c0,$000000000,
$000000000,$006fe0000,$000060606,$000000000,$0c2c0c000,$03018ccc6,$00c86dc60,$000003e18,
$0c2c0c000,$03018ccc6,$03e9ece66,$000000606,$018180000,$018181800,$0183c3c3c,$000000000,
$000000000,$0d86c3600,$00000366c,$000000000,$000000000,$0366cd800,$00000d86c,$000000000,
$044114411,$044114411,$044114411,$044114411,$0aa55aa55,$0aa55aa55,$0aa55aa55,$0aa55aa55,
$077dd77dd,$077dd77dd,$077dd77dd,$077dd77dd,$018181818,$018181818,$018181818,$018181818,
$018181818,$0f8181818,$018181818,$018181818,$018181818,$0f818f818,$018181818,$018181818,
$036363636,$0f6363636,$036363636,$036363636,$000000000,$0fe000000,$036363636,$036363636,
$000000000,$0f818f800,$018181818,$018181818,$036363636,$0f606f636,$036363636,$036363636,
$036363636,$036363636,$036363636,$036363636,$000000000,$0f606fe00,$036363636,$036363636,
$036363636,$0fe06f636,$000000000,$000000000,$036363636,$0fe363636,$000000000,$000000000,
$018181818,$0f818f818,$000000000,$000000000,$000000000,$0f8000000,$018181818,$018181818,
$018181818,$01f181818,$000000000,$000000000,$018181818,$0ff181818,$000000000,$000000000,
$000000000,$0ff000000,$018181818,$018181818,$018181818,$01f181818,$018181818,$018181818,
$000000000,$0ff000000,$000000000,$000000000,$018181818,$0ff181818,$018181818,$018181818,
$018181818,$01f181f18,$018181818,$018181818,$036363636,$037363636,$036363636,$036363636,
$036363636,$03f303736,$000000000,$000000000,$000000000,$037303f00,$036363636,$036363636,
$036363636,$0ff00f736,$000000000,$000000000,$000000000,$0f700ff00,$036363636,$036363636,
$036363636,$037303736,$036363636,$036363636,$000000000,$0ff00ff00,$000000000,$000000000,
$036363636,$0f700f736,$036363636,$036363636,$018181818,$0ff00ff18,$000000000,$000000000,
$036363636,$0ff363636,$000000000,$000000000,$000000000,$0ff00ff00,$018181818,$018181818,
$000000000,$0ff000000,$036363636,$036363636,$036363636,$03f363636,$000000000,$000000000,
$018181818,$01f181f18,$000000000,$000000000,$000000000,$01f181f00,$018181818,$018181818,
$000000000,$03f000000,$036363636,$036363636,$036363636,$0ff363636,$036363636,$036363636,
$018181818,$0ff18ff18,$018181818,$018181818,$018181818,$0f8181818,$000000000,$000000000,
$000000000,$01f000000,$018181818,$018181818,$0ffffffff,$0ffffffff,$0ffffffff,$0ffffffff,
$000000000,$0ff000000,$0ffffffff,$0ffffffff,$0f0f0f0f0,$0f0f0f0f0,$0f0f0f0f0,$0f0f0f0f0,
$00f0f0f0f,$00f0f0f0f,$00f0f0f0f,$00f0f0f0f,$0ffffffff,$000ffffff,$000000000,$000000000,
$000000000,$0d8dc7600,$076dcd8d8,$000000000,$0cc780000,$0ccd8cccc,$0ccc6c6c6,$000000000,
$0c6fe0000,$0c0c0c0c6,$0c0c0c0c0,$000000000,$000000000,$06c6c6cfe,$06c6c6c6c,$000000000,
$0fe000000,$0183060c6,$0fec66030,$000000000,$000000000,$0d8d87e00,$070d8d8d8,$000000000,
$000000000,$066666666,$060607c66,$0000000c0,$000000000,$01818dc76,$018181818,$000000000,
$07e000000,$066663c18,$07e183c66,$000000000,$038000000,$0fec6c66c,$0386cc6c6,$000000000,
$06c380000,$06cc6c6c6,$0ee6c6c6c,$000000000,$0301e0000,$0663e0c18,$03c666666,$000000000,
$000000000,$0dbdb7e00,$000007edb,$000000000,$003000000,$0dbdb7e06,$0c0607ef3,$000000000,
$0301c0000,$0607c6060,$01c306060,$000000000,$07c000000,$0c6c6c6c6,$0c6c6c6c6,$000000000,
$000000000,$0fe0000fe,$000fe0000,$000000000,$000000000,$0187e1818,$0ff000018,$000000000,
$030000000,$00c060c18,$07e003018,$000000000,$00c000000,$030603018,$07e000c18,$000000000,
$01b0e0000,$01818181b,$018181818,$018181818,$018181818,$018181818,$070d8d8d8,$000000000,
$000000000,$07e001818,$000181800,$000000000,$000000000,$000dc7600,$00000dc76,$000000000,
$06c6c3800,$000000038,$000000000,$000000000,$000000000,$018000000,$000000018,$000000000,
$000000000,$000000000,$000000018,$000000000,$00c0c0f00,$0ec0c0c0c,$01c3c6c6c,$000000000,
$06c6cd800,$0006c6c6c,$000000000,$000000000,$030d87000,$000f8c860,$000000000,$000000000,
$000000000,$07c7c7c7c,$0007c7c7c,$000000000,$000000000,$000000000,$000000000,$000000000);
const
picture_palette: array[0..191] of Dword = (
$000000000,$000003f1f,$002000001,$000020000,$000000200,$003000002,$000030000,$000000300,
$004000003,$000040000,$000000400,$005000004,$000050000,$000000500,$006000005,$000060000,
$000000600,$007000006,$000070000,$000000700,$008000007,$000080000,$000000800,$009000008,
$000090000,$000000900,$00a000009,$0000a0000,$000000a00,$00b00000a,$0000b0000,$000000b00,
$00c00000b,$0000c0000,$000000c00,$00d00000c,$0000d0000,$000000d00,$00e00000d,$0000e0000,
$000000e00,$00f00000e,$0000f0000,$000000f00,$01000000f,$000100000,$000001000,$011000010,
$000110000,$000001100,$012000011,$000120000,$000001200,$013000012,$000130000,$000001300,
$014000013,$000140000,$000001400,$015000014,$000150000,$000001500,$016000015,$000160000,
$000001600,$017000016,$000170000,$000001700,$018000017,$000180000,$000001800,$019000018,
$000190000,$000001900,$01a000019,$0001a0000,$000001a00,$01b00001a,$0001b0000,$000001b00,
$01c00001b,$0001c0000,$000001c00,$01d00001c,$0001d0000,$000001d00,$01e00001d,$0001e0000,
$000001e00,$01f00001e,$0001f0000,$000001f00,$02000001f,$000200000,$000002000,$021000020,
$000210000,$000002100,$022000021,$000220000,$000002200,$023000022,$000230000,$000002300,
$024000023,$000240000,$000002400,$025000024,$000250000,$000002500,$026000025,$000260000,
$000002600,$027000026,$000270000,$000002700,$028000027,$000280000,$000002800,$029000028,
$000290000,$000002900,$02a000029,$0002a0000,$000002a00,$02b00002a,$0002b0000,$000002b00,
$02c00002b,$0002c0000,$000002c00,$02d00002c,$0002d0000,$000002d00,$02e00002d,$0002e0000,
$000002e00,$02f00002e,$0002f0000,$000002f00,$03000002f,$000300000,$000003000,$031000030,
$000310000,$000003100,$032000031,$000320000,$000003200,$033000032,$000330000,$000003300,
$034000033,$000340000,$000003400,$035000034,$000350000,$000003500,$036000035,$000360000,
$000003600,$037000036,$000370000,$000003700,$038000037,$000380000,$000003800,$039000038,
$000390000,$000003900,$03a000039,$0003a0000,$000003a00,$03b00003a,$0003b0000,$000003b00,
$03c00003b,$0003c0000,$000003c00,$03d00003c,$0003d0000,$000003d00,$03e00003d,$0003e0000,
$000003e00,$03f00003e,$0003f0000,$000003f00,$03020103f,$016322212,$02a1a3626,$03f2f1f3a);
const
picture_bitmap: array[0..15999] of Dword = (
$032384146,$041373231,$04d4d4c49,$04d4d4e4e,$04e4e4d4d,$04f50504f,$04b4c4d4e,$046494a4b,
$042434344,$042424140,$046454544,$04a494847,$04d4c4b4b,$04e4e4e4d,$04f4f4f4e,$04f4f4f4f,
$050505050,$050505050,$050505050,$050505050,$050505050,$04f504f4f,$04f4f4f4e,$04f4e4e4e,
$04e4e4f4e,$04f4d4e4e,$04d4c5152,$04e4e4d4e,$0504f4c4d,$04d4d4c4e,$0504d4d4d,$04d4d4c50,
$04d4d4e4d,$0504f4c4c,$04d4d4f50,$04e4d4d4d,$04d4d4e4e,$04e4e4e4e,$04e4e4e4e,$04e4e4e4e,
$04e4e4e4e,$04f4f4e4f,$04f4f4f4f,$04f4f4f4f,$04f4f4e4f,$04f4f4f4f,$04e4e4e4f,$04e4e4e4e,
$04e4e4e4e,$05a544e4e,$05d5d5d5c,$050575b5c,$04d4d4b4c,$03e43474b,$03c3b3b3b,$0413e3d3c,
$04d4a4744,$056555350,$05b5a5958,$05b5b5c5b,$054565859,$050515253,$056525150,$04f575b5a,
$04f4e4d4c,$050504f4f,$04c4a4b4e,$04b4e4f4e,$04a4a4a4a,$04a4a4b4a,$049494a4a,$048484949,
$047474748,$04d4b4947,$04f4e4e4e,$04f504f4f,$042464b4e,$03e3e3e40,$03f3f3e3e,$046444241,
$033374147,$0443a3432,$04f4e4e4b,$04f4f4f4f,$04f4f4e4f,$050505050,$04c4c4d4f,$0484a4b4c,
$043454546,$043434140,$047464545,$04b4a4948,$04e4d4d4c,$0504f4f4e,$051505050,$051515151,
$052525151,$051515252,$052515151,$052525151,$051515152,$050515151,$050505050,$050505050,
$050505050,$04f4e4f50,$04e4d5252,$04f4f4f4f,$0524f4e4f,$04f4e4d51,$0524d4e4f,$04e4e4d52,
$04e4f4f4e,$0504d4c4d,$04f515252,$04f4f4f4f,$04f4f4f4f,$0504f504f,$050505050,$050505050,
$050505050,$050505050,$050505050,$050505050,$050505050,$050505050,$050505050,$04f4f4f50,
$04f4f4f4f,$058524f4f,$05b5c5d5b,$04f535759,$04e4d4d4e,$042464a4d,$0423f3e3f,$04c484644,
$05654524f,$05a595857,$05b5b5a5a,$057595a5a,$050525456,$0504f4f4f,$057535251,$0525a5d5c,
$0504f4e4d,$051515150,$04d4b4d4f,$04d50504f,$04b4c4c4b,$04b4c4c4c,$04a4b4b4b,$0494a4a4a,
$048484949,$04d4b4948,$051504f4f,$051515151,$043484d51,$03f3f3f41,$0403f3f3f,$045424141,
$034384248,$0483f3834,$0504f4f4d,$050505050,$0504f4f4f,$051515150,$04c4c4e50,$0494b4c4c,
$043464748,$044434140,$048464645,$04c4a4949,$04f4e4d4d,$05150504f,$052515151,$052525252,
$052525252,$052525252,$052525252,$052525252,$052525252,$052525252,$052525252,$051515151,
$051515151,$04f505151,$04e4f5453,$051515050,$0544f4f50,$0504f4f54,$0524e4f50,$04f4e4f54,
$04f50504f,$04d4d4e4f,$053535250,$0504f5051,$051505050,$051515151,$051515151,$051515151,
$051515151,$051515151,$051515152,$051515151,$051515151,$051515151,$051515151,$050505151,
$050515151,$052515150,$054565755,$050505152,$04f4e4f50,$04b4e5050,$0504d4a49,$058565452,
$05b5b5a59,$059595a5a,$055565758,$050515354,$04d4e4e4f,$04f4e4d4d,$056535251,$0555c5f5c,
$051504f4f,$052525251,$04d4c4e51,$04f51514f,$04d4d4d4d,$04c4d4d4d,$04c4c4c4c,$04b4b4b4b,
$0494a4a4a,$04e4b4949,$052515150,$052525252,$0454a5052,$03f3f4142,$0413f3f3f,$043424141,
$0383c454a,$04c463f39,$051515150,$051515251,$050505050,$051525151,$04e4e5051,$04b4d4e4e,
$044474849,$046444242,$049484746,$04c4b4a49,$050504f4e,$052515151,$053535353,$053535353,
$054545453,$054545454,$054545454,$054545354,$053535353,$054545453,$053545353,$053535353,
$052525353,$050525252,$04f525654,$052525251,$054505151,$051505155,$0524f5151,$050505255,
$051515151,$04f505151,$05553514f,$051515456,$052525251,$053525252,$053525252,$053525253,
$052525353,$053535352,$053535353,$053535353,$052535353,$053535353,$052535353,$052525252,
$052525252,$052525251,$052535352,$053535252,$059575554,$0595b5c5b,$05b5a5958,$05c5c5c5c,
$0585a5b5b,$053545557,$04f505051,$04f4f4f4f,$04f50504f,$04f4e4f4f,$056545251,$0585f605d,
$052515051,$054535352,$04e4e5053,$051535351,$04e4e4e4e,$04e4e4e4e,$04d4d4e4d,$04c4c4c4d,
$04b4b4b4c,$04f4c4a4a,$053535251,$054535353,$0474d5254,$041414243,$041414141,$042424141,
$041434a4e,$0504d4843,$052525352,$053535353,$052525252,$053535352,$050515253,$04c4e5050,
$04647484a,$047464344,$04a494847,$04e4c4c4a,$05151504f,$053535252,$054545454,$055555555,
$055555555,$055555555,$055555555,$055555555,$055555555,$055555555,$055555555,$054545555,
$054545454,$052535454,$051555754,$053535353,$054515253,$052515356,$052515353,$052535556,
$053525352,$052525353,$055515152,$054565757,$054545353,$054545454,$054545454,$054545454,
$054545454,$054545454,$054555454,$054545555,$054545454,$054545554,$055555454,$054545454,
$054545454,$054545453,$055545454,$05e5c5956,$063626160,$061636464,$05d5e5f60,$058595a5c,
$052535557,$04f4f5051,$04f4f4f4f,$05251504f,$055565553,$0504f5153,$057555452,$05c62625e,
$053525053,$055555454,$04f4f5255,$052555452,$050504f50,$04f4f5050,$04f4f4f4f,$04e4e4e4e,
$04c4d4d4e,$0504d4c4c,$054545453,$055545454,$0494f5455,$042424345,$041424141,$042424241,
$04b4c4f52,$053514f4c,$054545454,$054545454,$053535354,$055545453,$053545555,$04e515252,
$047484a4c,$049474445,$04b494948,$04f4d4d4b,$052525150,$055545453,$055555555,$056565656,
$055555556,$056565656,$057575756,$057575656,$057575757,$057575757,$056565656,$056565757,
$056565655,$053555555,$052575854,$054545554,$055525354,$054525659,$052535454,$057585756,
$054545354,$054545454,$052535454,$059595754,$055545457,$055555555,$055555555,$056565655,
$055555555,$056555555,$056565655,$056555656,$056565656,$056565656,$056565655,$055565556,
$056565656,$059585756,$05e5c5b5a,$066656361,$066666666,$063656566,$0595a5c60,$051525355,
$050505051,$050515050,$051515151,$059555251,$05c5e5d5c,$051515459,$058565453,$05f64635e,
$054535256,$056565555,$050525456,$054565552,$051515051,$050515151,$050515050,$04f4f5050,
$04e4e4f4f,$0514e4d4d,$055555454,$056565555,$04b525657,$043444446,$042424242,$043434342,
$051525354,$055545352,$055555555,$055555656,$054545454,$056555554,$054565757,$051525353,
$0484a4c4e,$04a484546,$04b4a4949,$04f4e4d4c,$053525151,$056555453,$056565656,$056565656,
$056565656,$057575756,$058585857,$058585757,$058585858,$058585858,$057575858,$057575757,
$057575757,$055565656,$053595954,$056565654,$055545555,$054535859,$053555555,$05b595753,
$055545659,$056565556,$054565656,$05a585453,$056565959,$057565656,$057575656,$057575757,
$057575657,$057575757,$057575757,$057575757,$057575757,$057575757,$057575757,$058575757,
$05a5a5959,$06563605c,$067666565,$067686767,$066676768,$05e616365,$052535459,$051515151,
$053535252,$052535353,$052525252,$05e585352,$05e606060,$05252565b,$058575553,$06266645d,
$055535359,$058575756,$051535658,$056575553,$052525153,$052525252,$052525252,$050515151,
$04f4f5050,$0514f4e4f,$056565554,$057575656,$04d535757,$043444548,$043434343,$043434343,
$055565656,$056565656,$056575756,$056575756,$055555556,$058575656,$056575959,$053545555,
$04a4d4f51,$04b484647,$04c4b4a4a,$0504f4e4d,$053535251,$056555554,$057575757,$057575757,
$056565757,$059585757,$059595959,$059595959,$059595959,$059595a5a,$059595959,$058595959,
$058585858,$057575757,$0555a5b57,$057575756,$055565657,$055555a5a,$056575757,$05b575455,
$056595b5c,$057575757,$057575757,$056545557,$0595b5c5a,$057575757,$058585757,$058585858,
$059595958,$059595959,$059595959,$059595959,$059595959,$0595a5a59,$05a595959,$0615f5d5c,
$066666563,$06a696967,$06869696a,$065666667,$05e616364,$056595b5d,$053535355,$054535353,
$05a5a5956,$054585a5b,$054545353,$05d585353,$05f5f5e5e,$05354595d,$059585754,$06567655d,
$05655555d,$059595958,$053545859,$057585654,$053535355,$053545353,$053535353,$052525253,
$050515152,$0524f4f50,$057575655,$058585757,$04f555858,$045454649,$043434344,$044444443,
$058585858,$057575758,$057575857,$057575757,$057575757,$05b5a5958,$0585b5b5b,$056575757,
$04a4e5153,$04c484546,$04d4c4b4b,$051504f4d,$054545252,$056565555,$058585857,$058585858,
$057575758,$05b595958,$05a5b5b5b,$05b5a5a5a,$05b5a5a5b,$05b5b5b5b,$05a5a5a5a,$05a5a5a5a,
$0595a5959,$059595959,$0575d5f5b,$058585957,$057575859,$056575b5b,$058585958,$057565758,
$05c5e5d5b,$058585758,$059595959,$056575859,$05c5b5a58,$05858595c,$0595a5959,$05a5a5a59,
$05a5a5a5a,$05a5a5a5a,$05b5a5a5a,$05b5a5a5b,$05b5b5b5b,$05e5d5c5b,$06663605f,$06b6a6967,
$06b6b6c6b,$06a6a6a6b,$063646769,$05c5d5e61,$058595a5b,$057575758,$055555656,$056555555,
$06364635d,$0565d6163,$055555554,$05b575454,$060605f5d,$054555b5e,$05b595755,$0686a665e,
$058565761,$05a5a5a59,$05457595a,$059595754,$055555557,$055555555,$054545455,$053545454,
$052525253,$052505151,$059585755,$05a595959,$052575959,$04646484c,$045444445,$045454545,
$05a5a5a5a,$059595a5a,$059595959,$059595959,$05b5a5a59,$05e5d5c5b,$05c5d5e5e,$058595a5a,
$0494d5155,$04b474546,$04d4d4c4c,$051504f4f,$055545353,$056555555,$058585857,$058585959,
$058585858,$05c5b5a59,$05c5c5c5c,$05c5c5c5c,$05c5c5b5b,$05c5c5c5c,$05b5b5b5c,$05b5b5c5b,
$05b5b5b5b,$05b5b5b5b,$0575e6160,$05a5a5a59,$058595a5a,$057595c5a,$05a5a5a5a,$057595a5a,
$05e5d5a57,$059595b5e,$05a5a5a59,$0595a5a5a,$05d595757,$05a5d5e5f,$05b5b5b5a,$05c5b5b5b,
$05c5c5c5c,$05c5c5c5c,$05c5c5c5c,$05d5d5d5c,$063615f5d,$06b696563,$06d6d6c6b,$06d6e6e6e,
$0696b6c6d,$064656566,$05a5b5e61,$05959595a,$059595959,$0595b5b5a,$057575757,$058565656,
$065666560,$0585f6263,$056565656,$05b565556,$06261615f,$055575d61,$05c5a5855,$06b6b675f,
$059575a64,$05b5b5b5b,$056595b5c,$05b5a5755,$056565759,$056565656,$055565656,$055555555,
$053545455,$053525253,$05a595856,$05b5b5a5a,$0555a5b5b,$04748494f,$046454647,$046464646,
$05c5c5b5b,$05b5b5b5c,$05b5b5b5a,$05c5c5b5b,$05f5f5e5d,$06060605f,$05e5f5f5f,$0595a5b5c,
$0484d5156,$04a454445,$04e4e4c4c,$05150504f,$054545353,$056555555,$059585858,$058595959,
$059585858,$05d5b5a59,$05d5e5d5d,$05d5d5d5d,$05d5d5d5d,$05d5d5d5d,$05d5d5d5d,$05c5d5d5d,
$05c5c5c5c,$0605c5c5c,$0595a6062,$05b5b5c5b,$0595b5c5b,$0585b5d5b,$05b5b5c5b,$05a5b5b5b,
$05d59585a,$05b5e5f5f,$05b5b5a5a,$05b5b5b5b,$05958595a,$05f615f5d,$05d5c5c5c,$05d5d5d5d,
$05e5d5d5d,$05d5d5d5e,$05e5d5d5d,$06462615f,$06e6d6b68,$06f6f6f6e,$06e6f6f6f,$0696a6c6d,
$05f626567,$05c5c5c5d,$05a5a5b5b,$0595a5a5a,$0625e5a5a,$062666764,$05857575c,$057575757,
$06464625d,$05a606264,$056575757,$05b565656,$065646260,$0575a6165,$05d5b5956,$06d6c665f,
$059585d67,$05d5c5b5b,$0575b5d5d,$05c5a5856,$05757585b,$058585757,$057575757,$055565656,
$054555555,$053535353,$05b5a5956,$05c5c5c5c,$0585c5d5d,$048494b51,$046474748,$046464646,
$05f5e5d5d,$05e5e5e5f,$05f5f5f5e,$061605f5f,$064636362,$063636364,$060626262,$05a5b5c5e,
$0484d5257,$048454445,$04e4e4d4d,$05251504f,$055545353,$057565655,$059595958,$059595959,
$05a595959,$05e5c5b5a,$05e5f5e5e,$05e5e5f5f,$05e5f5e5e,$05e5e5e5e,$05e5e5e5e,$05d5e5f5e,
$05d5d5e5e,$065605d5d,$05c5a5e62,$05d5d5d5c,$05b5d5d5d,$0595e5f5b,$05c5d5c5c,$05c5c5c5c,
$05a5a5b5c,$06161605d,$05c5c5c5f,$05d5d5c5c,$05a5c5c5c,$062615d5a,$05e5d6062,$05e5f5e5e,
$05f5f5e5e,$05f5f5f5f,$067646160,$0706e6d6b,$071717171,$06f707071,$0686a6c6e,$05f616365,
$05d5d5d5e,$05d5d5d5d,$05b5c5c5c,$05a5b5b5c,$06c665c5b,$0666a6c6c,$059585960,$058585959,
$06664625c,$05c626566,$058585858,$05b575758,$06a696661,$0595c6469,$05f5d5a57,$06f6d6660,
$05a59606b,$05e5d5d5c,$0595d5f5f,$05d5b5857,$058585a5d,$059595959,$058585859,$057575858,
$056565757,$054535455,$05d5c5a57,$05e5e5d5d,$05b5f5f5e,$0494a4d54,$048484949,$047474747,
$061616060,$062616161,$063626262,$066656464,$067676767,$066666767,$064656566,$05b5d5f61,
$0494e5358,$048464546,$04f4e4e4d,$05251504f,$055545452,$057565656,$05a5a5958,$05a5a5a5a,
$05a5a5a5a,$05f5e5d5c,$060606060,$05f606060,$060606060,$0605f5f5f,$05f5f6060,$05f5f605f,
$05f5f5f5f,$06466605f,$05e5c5a61,$05f5f5e5e,$05d5e5e5e,$05e61615b,$05e5e5d5c,$05e5e5e5e,
$05c5d5d5d,$063615c5a,$05d5e6264,$05e5e5e5e,$05e5e5e5e,$0615d5b5d,$05e606564,$060606060,
$062616060,$06a696865,$0726f696c,$073737372,$06f717272,$066686a6c,$060606264,$05e5e5f5f,
$05f5f5f5e,$06362605f,$05d5d5f62,$05c5c5c5d,$069665e5b,$066666668,$05a595a62,$0595a5a5a,
$06865625c,$05f666869,$05a59595a,$05b58595a,$071706a63,$05a5f686f,$0605e5a59,$0716e6661,
$05a5b636e,$05f5e5e5d,$05b5f6060,$05e5c5959,$05a5a5c5e,$05a5a5a5a,$0595a5a5a,$059595959,
$058585859,$055555657,$05e5d5b58,$05f5f5e5e,$05d60605f,$04a4c4f56,$0494a4a4a,$048484949,
$064636362,$065646363,$066666565,$069696867,$06a6a6a6a,$06b6b6a6a,$0696a6b6b,$05e616467,
$04d51555a,$04b49494a,$04f4e4e4e,$052515050,$055555453,$058575756,$05b5b5958,$05b5b5b5b,
$05c5c5b5b,$061605f5d,$061616161,$061616161,$061616161,$061616161,$061616261,$061616161,
$061616161,$064676561,$05f605c5e,$060606060,$05e5f5f60,$06363605c,$05f5e5f62,$05f5f5f5f,
$05f5f5f5f,$0615c5c5e,$061656565,$06060605f,$060616161,$05d5e6060,$060656662,$067676664,
$06e6b6968,$074747472,$073706c73,$06d707273,$065686a6c,$061616162,$060616161,$05f606060,
$062606060,$06f6f6d68,$05e60676c,$05d5d5e5e,$066625c5c,$067666566,$05b5a5e65,$05a5b5b5b,
$06966625c,$062686b6c,$05b5b5a5b,$05c5a5b5b,$075746f64,$05c636d74,$0605e5b5a,$0736e6661,
$05b5d6871,$060605f5d,$05d606161,$05f5d5a5a,$05b5b5e60,$05c5b5b5b,$05b5b5b5c,$05b5b5b5b,
$0595a5a5b,$056575858,$05f5e5c58,$060606060,$05e616160,$04c4d5259,$04a4a4b4b,$0494a4a4a,
$066656564,$067666666,$069686867,$06d6d6c6a,$070706f6e,$072727171,$06d707172,$06064676b,
$05154585c,$04b4b4c4e,$04d4c4c4c,$05252514f,$056555453,$058575757,$05b5b5959,$05c5b5b5b,
$05e5e5d5c,$06261605f,$062636363,$063636262,$062636363,$062626262,$062626262,$062626262,
$062626162,$063676964,$060615f5c,$061616161,$060606060,$064615c5e,$060626565,$06060605f,
$061616061,$05d5f5f60,$067676560,$062616060,$062626262,$064646362,$06d6c6b65,$075757472,
$076767575,$073757576,$06a676870,$063656769,$062626262,$062626262,$061616262,$061616161,
$066606061,$07072726f,$05e646a6d,$05e5e5e5f,$065605c5d,$069686767,$05c5b6067,$05b5c5c5c,
$06a66615c,$0656c6e6e,$05c5c5b5e,$05c5b5c5c,$076767064,$05d657076,$0615e5b5b,$0746d6563,
$05d616d74,$06161605e,$05f616161,$0615e5b5b,$05c5c6062,$05d5d5c5c,$05c5c5c5d,$05b5c5c5c,
$05a5b5b5b,$05858595a,$0605e5c59,$060616160,$060626160,$04d4e535b,$04b4b4c4c,$04a4a4a4b,
$069696767,$06c6a6a6a,$06f6e6d6d,$075747371,$077767675,$077777777,$06f737576,$06164686c,
$05456595d,$04a4b4f51,$04b4a4a4a,$05352514e,$056555454,$059585857,$05c5b5a59,$05d5c5c5c,
$061605f5e,$063636361,$064646464,$065646464,$064646464,$064646464,$063636464,$063636463,
$064636364,$05e666a6b,$06363625f,$062626262,$061626261,$05f5d5f61,$066686764,$062616162,
$062626262,$061626262,$068645f5f,$065636063,$06b6a6866,$075726f6c,$078777776,$078787878,
$072747577,$0686a6d6f,$063646466,$064636363,$063646364,$068656463,$065686969,$062626262,
$065616262,$06e6e6e6c,$05f666c6e,$05f5f5f5f,$065605d5e,$06e6c6a69,$05d5d626a,$05d5d5d5d,
$06f66605c,$06b727574,$05d5d5c62,$05c5c5c5d,$078766f62,$05f6a7478,$0625f5c5c,$0746c6564,
$05e657176,$06261615f,$061636362,$0625e5c5d,$05d5f6264,$05f5e5e5e,$05e5e5e5e,$05d5d5e5e,
$05b5c5d5d,$059595a5b,$0615f5c59,$062626161,$062636262,$04f51565d,$04c4c4d4e,$04c4c4c4c,
$0706f6d6d,$074737271,$077767675,$07a7a7978,$07a7a7a7a,$079797979,$06d727578,$05f626569,
$05556595c,$04d4f5254,$04a48494b,$05352504d,$056565554,$05a595858,$05d5c5b5b,$05e5d5d5d,
$06361605f,$065646463,$065656565,$066666565,$065656566,$065656565,$064656565,$064656464,
$069646465,$06062696c,$064646362,$063646464,$063636363,$060626363,$06a69645f,$06462636a,
$064646363,$064646464,$069646164,$0746f6868,$079787776,$07b7a7a79,$0797a7a7a,$073767778,
$067686a6e,$065656565,$066666566,$065656565,$064646465,$077726a64,$06d737677,$063636364,
$062616363,$0706d6d6a,$060686f71,$060606160,$0655f5e60,$073726e6b,$05e5f656e,$05e5e5e5e,
$07468615e,$070787a79,$05f5e5e65,$05d5d5e5e,$079736860,$0626d7679,$0625f5d5e,$0756b6564,
$05f687478,$06363615f,$063666564,$0635f5e60,$05e616465,$060605f5f,$060606060,$05f5f5f5f,
$05d5e5f5f,$05b5b5c5d,$062605d5a,$063636362,$064646464,$051535a61,$04e4e4e4f,$04d4d4d4e,
$078777675,$07a7a7979,$07b7b7b7a,$07b7b7c7c,$0797a7a7b,$077787879,$0696d7275,$05e5e6165,
$056575a5c,$04d505456,$04a48484a,$053514f4c,$057565554,$05b5a5a59,$05e5d5c5c,$0605f5f5e,
$064636261,$066666565,$066676767,$067676766,$067676767,$067666667,$066666666,$065666566,
$06d676565,$06360666b,$065656565,$064656565,$065656464,$063646465,$067636162,$06562696b,
$066666565,$069676666,$072706f6c,$07c7b7874,$07c7c7d7c,$07a7b7c7c,$072747679,$0676a6c6d,
$066666565,$066676666,$067676666,$066666566,$066656566,$078756d65,$06f747778,$064646366,
$062626364,$0716f6d68,$0626a7172,$061616261,$065606061,$07776706a,$05f616971,$060606060,
$07769615f,$0747b7c7c,$05f5f5f66,$05e5f5f5f,$0766d615e,$0656e7578,$0625f5e5f,$0756b6665,
$0616b7679,$065646260,$066676666,$062605f62,$05f626666,$061616160,$061616161,$060606061,
$05e5f6060,$05c5d5d5e,$062605d5b,$064646463,$065656565,$052555c63,$04f4f5051,$04e4e4e4e,
$07d7d7d7d,$07d7d7d7d,$07c7c7c7d,$07a7b7c7c,$076777879,$075767676,$0686c6f73,$05d5e6063,
$05455585b,$04a4d5153,$04a464546,$053504d4c,$058575554,$05d5c5b5a,$0605f5e5e,$062606060,
$066656463,$068686767,$068686868,$068686868,$068686868,$068686868,$067676768,$067676767,
$06d6e6767,$066646169,$067676666,$066666666,$066666666,$066666666,$063626565,$066646d6c,
$06d6a6867,$07a76736f,$07d7d7d7c,$07e7e7e7e,$07b7d7e7e,$071737679,$06d6c696d,$067676665,
$067686767,$069676867,$071726f6d,$06767686d,$066676667,$0726f6865,$06e737473,$065656467,
$063636565,$072706d66,$0656d7374,$063646362,$065616162,$07c7b746a,$060636c76,$061626261,
$076686160,$0797d7e7d,$06060616b,$05f606060,$073685e5d,$067717678,$063606061,$0756c6866,
$0636e797b,$067666361,$068686867,$063606164,$061646767,$063626262,$062626263,$061626262,
$060606161,$05d5e5f60,$063615e5c,$066666565,$067676766,$054585f66,$050515152,$04f4f4f4f,
$07f7f7f80,$07d7e7e7e,$07a7a7b7c,$077797a7a,$077767576,$074767677,$0666a6e71,$0585a5d61,
$050515356,$0494b4e50,$04e4a4646,$0534f4c4d,$05a585655,$05f5e5d5b,$061605f5f,$063626161,
$068676564,$069696868,$069696969,$069696969,$069696969,$069696969,$069686969,$068686868,
$06e706d69,$068676467,$068686868,$068686868,$067676768,$068686868,$068696868,$0716c706f,
$07d7a7775,$0807f7f7e,$07f7f8080,$07d7d7e7e,$070757a7c,$06868696c,$06d6b6667,$068686768,
$068686868,$075696868,$0777a7b7a,$068676d73,$067686868,$0706b6666,$06c727272,$066666567,
$063646666,$074706b65,$068707777,$064656463,$065636364,$0807f796c,$061646f7b,$062626362,
$06e646161,$07a7e7e7a,$06161636f,$05f616161,$070645d5e,$06a727676,$064616163,$0756c6968,
$066727b7c,$068676462,$06a6a6969,$064616267,$063676867,$064636362,$063636364,$063636363,
$061626262,$05e5f6061,$065625f5e,$068676766,$068686868,$0555a6268,$051525354,$050515151,
$081828384,$07e7f7f80,$07b7a7b7c,$0797b7c7c,$07a797979,$06f737779,$06064676b,$055575a5c,
$04f505152,$04a4c4e4f,$052504b48,$054504e4f,$05d5c5957,$06261605f,$064636262,$066666565,
$06b6a6968,$06d6d6c6c,$06d6d6d6d,$06e6e6e6d,$06d6d6e6e,$06d6d6d6d,$06d6c6d6d,$06c6c6c6d,
$06d72756f,$06c6c6a67,$06c6c6c6c,$06c6c6c6c,$06c6c6c6c,$0706e6d6c,$07f7c7874,$08482807f,
$085858585,$084848484,$07c7f8282,$07473767a,$06c6c6e72,$06c6c6c6c,$075716b6c,$06b6c6c71,
$06c6c6c6c,$0766d6b6c,$077777777,$06b6a7175,$06a6b6b6b,$0726b686a,$071747574,$06a6a696d,
$067696a6a,$07a736d68,$06f777e7f,$068696867,$067666768,$085858070,$064677783,$065656665,
$066616464,$07f828076,$064646976,$063656464,$071646161,$06f777a7a,$068646567,$0776f6e6c,
$06b798180,$06c6a6765,$06e6e6d6d,$06664666b,$0676b6c69,$067676665,$067676767,$067676767,
$065666666,$062636464,$068656261,$06c6c6b6a,$06c6c6c6c,$05a5f676c,$054555657,$053545454,
$083858687,$080818182,$07d7d7d7e,$0787a7c7d,$076767676,$065696d73,$05e5f6062,$056595b5d,
$04f505153,$04c4d4e4f,$053524e4b,$056535151,$0605e5c5a,$064646362,$067666565,$06a696968,
$0706e6d6c,$071717070,$071717171,$072727171,$071717272,$071727272,$071717272,$071707071,
$06b747878,$070706f6c,$070707170,$071727271,$074737271,$084807a75,$08a8a8988,$08a8a8a8a,
$08688898a,$07b7e8184,$074727679,$06f6c7578,$070707070,$070707070,$084827a72,$0707a8083,
$07070706f,$0726d6e6f,$07c7a7876,$06e6f777c,$06e706f6f,$0746d6b6d,$07a7b7978,$06e6c6d74,
$06b6d6e6e,$082786f6b,$074808788,$06c6d6b6b,$06a696b6c,$08b8a8372,$0676d7e89,$069696968,
$065646668,$085888578,$067676e7c,$067676768,$074656365,$0767d817e,$06a67696d,$07973716f,
$072808684,$0706d6a69,$072717170,$069686b70,$06b6f6f6d,$06b6a6a68,$06b6b6b6b,$06b6b6b6b,
$0696a696a,$067676868,$06c686565,$06f6f6f6d,$0706f6f6f,$05e656c70,$05758595b,$056575757,
$085878889,$07e818284,$077787a7c,$06c6e7275,$06d6d6b6b,$06061656a,$05d5d5e5f,$05457595b,
$04d4d4f51,$050504f4e,$054545351,$05b595654,$063615f5d,$067676665,$06a696868,$06e6d6c6b,
$073727170,$075757474,$075757575,$076757575,$075767676,$076767575,$075757676,$079747574,
$06f737a7e,$074747373,$076757574,$07b797776,$08987847f,$08f8f8e8b,$08f8f8f90,$088898c8e,
$0797e8486,$073737576,$073727373,$07370797a,$074737374,$073747373,$0898d8b7d,$076828888,
$073737371,$072707273,$0837f7d7a,$071737b83,$072737373,$077727070,$07e82807c,$072707178,
$070717272,$08a7b6e6d,$07b898f8f,$06f706e70,$06c6d6f6f,$08e8a7d70,$06b76848c,$06c6c6c6b,
$067686b6b,$08a8c8778,$06a6b7381,$06a6b6b6b,$074656668,$080868883,$06c6a6d75,$07b767472,
$078888c87,$073716d6d,$075747473,$06c6c7074,$070737370,$06f6e6d6c,$06f6f6f6f,$06e6f6f6f,
$06d6d6d6e,$06b6b6b6d,$06e6b696a,$073737271,$074737373,$0626a7174,$05a5b5d5e,$059595a5a,
$07f828586,$074777a7c,$0696b6e71,$062636668,$065656362,$05a5c5e62,$054555659,$04a4d4f51,
$04b494949,$058565350,$0595c5b59,$060605c59,$065636261,$069696867,$06d6b6b6a,$072716f6e,
$077767573,$07a797878,$079797979,$07a797979,$07a7a7a7a,$07a7a797a,$0797a7a79,$080787a79,
$078727b80,$07a7a7978,$07b7a7979,$0918d867e,$094949492,$092939394,$08c909192,$078828585,
$076777777,$077767777,$078777778,$0797d8482,$077767677,$076777777,$0868a877d,$078828785,
$076777674,$073737676,$08a87827c,$074767f8a,$076777676,$079747375,$0888d8981,$07673767f,
$074757676,$093817171,$085939696,$073727174,$06f707272,$09089786e,$06f7d8a90,$06f6f6f6e,
$0686b6e6e,$08e8f8976,$06e707b87,$06d6e6f6e,$072676a6c,$08b918f87,$06f6e727e,$07d797774,
$07f8e9088,$075737072,$079787776,$06f707478,$075787773,$072727171,$072727272,$072727272,
$071717172,$06e6f6f70,$0716d6c6e,$076767675,$078777676,$0676f7679,$05e5f6062,$05b5c5d5d,
$070737779,$067696b6d,$062636465,$05d5f6061,$05a5a5b5c,$04e505357,$046484a4c,$043434445,
$04a464543,$0605c5852,$068686662,$064666667,$067666564,$06d6c6b69,$0706f6e6d,$075747270,
$07b7a7977,$07d7d7c7c,$07e7e7d7d,$07e7e7e7e,$07e7e7e7e,$07e7e7e7e,$07e7e7e7e,$0827c7e7e,
$0817c7c83,$084838382,$08e8b8a87,$099999894,$093969798,$086888c90,$07c818485,$07a848378,
$07b7b7a78,$07b7b7b7b,$08f857c7b,$08b919394,$07b7a7982,$0797a7b7b,$087858179,$07e878e8a,
$07a7a7a78,$07577797a,$0918d857c,$0777d868f,$07a7b7a78,$07c777779,$095999387,$078767a8a,
$078797979,$096827475,$08b969a9b,$077767477,$072737476,$09389756e,$073818e93,$072737371,
$06a707272,$093938a74,$07174808c,$070717171,$072696e70,$09398978b,$071737785,$07e7c7976,
$087939388,$078757377,$07c7b7a79,$07374797d,$07a7c7976,$076757475,$076767777,$076767676,
$075757575,$072737374,$074707071,$07a7a7977,$07c7b7a7a,$06c757b7d,$061626366,$05f5f6061,
$06466686a,$05f606162,$05d5d5d5e,$054585b5c,$04a4c4d50,$041424447,$03e3e3f40,$03f3e3e3e,
$04c484542,$06b655f56,$087817870,$06d727b85,$06a69686a,$0706f6e6d,$072727171,$07a777573,
$07f7e7d7c,$081818080,$082828281,$083828282,$082828383,$083838282,$083838383,$089848584,
$098958e8d,$09a9a9999,$0999b9c9b,$092959697,$08487898c,$07f7f8082,$07f7e7e7e,$08188857d,
$07e7f7e7d,$07f7f7f7e,$09b94807e,$092969599,$07e7c7d89,$07c7d7f7f,$08c87807b,$08590968f,
$07e7e7d7c,$07a7b7d7e,$097948a80,$07b858c95,$07e7e7e7c,$07f7a7b7d,$09ea09d8f,$07b7a7f93,
$07b7c7d7d,$08c7a7678,$08e979998,$07a79767d,$076767879,$093847171,$079869095,$075767775,
$06d737576,$09c9a8d72,$0747a8a97,$073747474,$0716b7072,$09a9e9c8e,$074777f8d,$081807c78,
$091999587,$07b78777f,$0807e7d7c,$076787e82,$07e7f7b78,$07a79777a,$07a7a7b7b,$07a7a7a7a,
$079797979,$076767778,$077737475,$07e7e7d7b,$07f7f7f7e,$0717a8080,$06567686b,$062636465,
$05b5d5f60,$056575758,$052525354,$0464c5152,$03c3d3f42,$03a38383a,$03b3a3a3a,$03f3d3d3b,
$0524c4743,$07f746a5d,$098969089,$0808b9397,$06c6c6e74,$07271706e,$075747373,$07d7a7876,
$08280807f,$083838282,$085858483,$085858585,$085858485,$086868685,$08f8c8986,$09d9c9a95,
$0a1a19f9e,$09d9fa0a1,$08b90959a,$083858585,$082818182,$081828181,$081818181,$08f928a80,
$0807f8587,$080808080,$093887e7f,$092949395,$0817d808a,$07f7f8080,$08d87807d,$08a949690,
$080807e7f,$07c7d8080,$09e988b81,$0808c959d,$07f80807d,$07f7b7d7f,$0a3a4a394,$07c7b849b,
$07c7d7e7e,$08478787b,$0949b9a93,$07b7a7882,$078797a7a,$094807075,$07f8d9499,$078787777,
$071747677,$0a29d8b70,$07781949f,$074747575,$06e6d7173,$09d9f9a87,$07a848d96,$083827f7a,
$0989d9587,$07d7a7a88,$083817f7e,$0787c8183,$081807c79,$07c7a797c,$07c7c7d7d,$07c7c7c7c,
$07b7b7b7c,$078797a7a,$078757677,$080807f7c,$081818181,$0767e8282,$0686a6b6e,$065666767,
$04e515355,$047484a4b,$045444446,$03c414545,$035353638,$036343334,$03a393838,$0423e3c3b,
$0655a5047,$090897e71,$096979593,$094999996,$06e6f7586,$07271706e,$075747372,$07d7b7977,
$08180807f,$083838282,$085848483,$085858585,$088878686,$0918d8b8a,$0a09d9a95,$0a0a1a1a1,
$09d9c9d9f,$08a91979c,$082828386,$082838282,$083828182,$081808182,$084808080,$09a9b9b92,
$07e849198,$07f7f8180,$08a7f7c7e,$091919091,$07f7c818a,$07e7f7f7f,$08c847d7c,$08c969791,
$0807f7e81,$07c7e8081,$0a198887e,$07f8e9ca2,$07f807f7c,$07a7b7d7f,$0a0a29f8a,$07b7a8599,
$07c7c7c7d,$07f74787b,$09598988f,$07b797985,$0787a7a7a,$0947c6f75,$08591989b,$078787779,
$073757677,$0a29c8670,$0778699a2,$073747575,$0676b7072,$09c958573,$08594999c,$083817e7a,
$09c9d9386,$07c797c8c,$08281807e,$0797d8283,$081807c78,$07c7a7a7e,$07c7c7d7d,$07c7c7c7c,
$07a7b7b7b,$078797a7a,$077757778,$081807e7c,$081818181,$079808383,$06a6b6c70,$066676869,
$041424546,$03b3c3d3e,$03d3a3a3a,$0393c3f3f,$035353435,$037353435,$03b3a3837,$04e46403d,
$07d746659,$08b888380,$0898d8c8b,$09a968c82,$06f738294,$07373716f,$075747373,$07d7b7977,
$08281807f,$084838282,$086858584,$08a888686,$098938f8c,$0a09e9c9b,$0a0a1a1a0,$0989e9fa0,
$088889194,$082828588,$082828282,$083838282,$082828282,$080818181,$0857e7f80,$094939896,
$07d869196,$07f7e8180,$0857c7c7e,$09296918d,$07e7b828a,$07e807f7f,$08b817a7c,$08e969994,
$0807f7d83,$07c7e7f80,$0a39c887b,$07f91a1a4,$07f7f7d7c,$0797c7d7e,$09d9a8e7c,$07a7a8998,
$07c7c7d7c,$07973787b,$09496968b,$07a797b89,$07879797a,$092797075,$08d9a9e9d,$07777777b,
$072747577,$0a29b7f6e,$07c8c9ca2,$071727375,$0636a6f71,$09880675f,$0969ea09f,$082807d80,
$09d9d9184,$07a787e92,$081807f7e,$0797e8382,$082807b78,$07c7a7a80,$07c7c7d7c,$07c7c7c7c,
$07a7b7c7b,$0797a7a7a,$078767878,$081807e7b,$081818181,$07b818383,$06b6c6e73,$06869696a,
$037383a3c,$037373736,$03d393836,$03f444543,$036363739,$039383737,$044413d3b,$0534e4a47,
$0706c6258,$0827e7871,$083878684,$098897775,$0717d919a,$07372706f,$075747473,$07d7b7977,
$08282807f,$084838382,$08c888785,$09a97938f,$0a0a09f9d,$09fa0a1a1,$0979a9c9d,$0858c9295,
$081808a89,$082828283,$082818282,$089868382,$087918f8c,$08180807f,$07f7e7f81,$09191918c,
$07d868f95,$0807e7f7e,$0817a7b7e,$093958f88,$07d7b848b,$07e7f7f7f,$08a7e797d,$0929d9d97,
$07f7e7d85,$07d7e7f80,$0a49c8379,$08096a2a3,$07e7f7d7c,$0787c7d7e,$09a94867a,$07a7b8a97,
$07c7c7d7c,$07474797b,$096999889,$079797e8d,$07979797a,$093777276,$094a0a3a1,$07676777f,
$070747576,$09c8d716a,$08c959ea1,$071717480,$0666c6e70,$09369545c,$09da1a2a0,$082807d89,
$09e9c8e84,$07a788195,$0807f7f7d,$0797f8281,$0827e7a78,$07c7a7b81,$07c7c7c7c,$07c7c7c7c,
$07a7b7b7b,$0797a7a7a,$078777878,$081807e7b,$081828281,$07c818282,$06c6d7074,$069696b6b,
$034353637,$037373635,$0463e3a38,$0474e4f4c,$03a38383e,$04543423e,$046464645,$047444445,
$05754504b,$07d786d5d,$083858381,$0917a6f74,$0758b9a9c,$072727070,$075747473,$07d7b7977,
$08181807f,$087848382,$09c99948e,$0a0a0a09e,$09d9e9fa0,$09095999c,$085888a8c,$07f818384,
$080828b86,$082828382,$081828282,$09a988c81,$08f959799,$080807f7f,$07c7d7f80,$091918e84,
$07e899495,$07e7e7e7e,$07f797c7e,$096928b85,$07d7d8790,$07f807f7f,$08a7b797d,$099a1a09b,
$07f7e7d86,$07e7e7f7f,$09d8c7878,$083959c9f,$07d7e7c7c,$0777c7c7d,$096908174,$07a7d8a94,
$07c7d7d7b,$07376797b,$09a9c9886,$079798192,$07879797a,$091737377,$096a2a3a1,$075757782,
$06e727475,$086726468,$09a9c9d97,$070727f93,$06b6d6d6f,$08658505d,$09ca0a19d,$081807f8b,
$09c998b83,$079778294,$07f7f7e7c,$07a7f8281,$0827d7a78,$07b797c81,$07c7c7c7c,$07c7c7c7c,
$07b7b7b7c,$0797a7b7a,$077787978,$080807e7a,$081818181,$07d828282,$06e6f7176,$06a6b6c6d,
$036353434,$038373737,$04b433c3a,$04d535552,$0423f3f44,$043464746,$03f3e3f41,$04342403f,
$0514e4b46,$07b746655,$084848481,$088726c76,$07a939d9a,$072716f70,$074737373,$07d7b7876,
$08181807e,$08c848382,$0a0a09f9b,$0999c9e9f,$08b8e9296,$084858789,$083848384,$080828383,
$081878a84,$082838182,$080818281,$09493897f,$08b8d8f91,$0807f7d81,$07a7d8080,$0908f887f,
$07e899395,$07e7f7e7c,$07e797d7f,$099958c85,$07d7e8a94,$07f80807f,$08a797a7d,$09fa3a3a0,
$07e7c7d8c,$07d7e7e7f,$09481767a,$087979b9b,$07d7d7b7b,$0787c7d7d,$0958d7b71,$07a828f94,
$07c7d7d7b,$074787a7b,$0a0a09882,$0787a8798,$077787878,$0856f7476,$097a0a29d,$074777e8a,
$06d717274,$0615c6168,$0a1a19c81,$06f7590a0,$0676a6c6d,$06f504f5c,$0949a9b91,$08181838a,
$095908682,$077767e8e,$080807e7b,$07b808181,$0817d7978,$07b797d82,$07c7c7c7c,$07c7c7c7c,
$07c7c7c7c,$07a7a7b7b,$078797a79,$080807e7a,$080818181,$07e818180,$06f707177,$06c6c6d6e,
$03a383736,$042403e3c,$0504c4744,$051575754,$03c3c3f47,$03c3d3d3d,$03d3c3c3c,$041403f3e,
$04e4b4743,$079726152,$08383837f,$0806e6c79,$07c969d98,$071706f6f,$073727271,$07d7b7774,
$08180807e,$08c838382,$0979ea09d,$0878a8e92,$084848586,$083838483,$082838383,$085838182,
$08f90918d,$08181828c,$07f818282,$08e8b807e,$0888c8e8e,$07f7f7d81,$07a7c7e81,$0908c837b,
$081899497,$07e7f7e7b,$07c7a7d7f,$09d978e81,$07c7f8d9b,$07f7f7f7f,$084787b7e,$09fa1a39d,
$07d7b7b8e,$07c7d7e7e,$0907b757a,$089979b9a,$07d7c7a7b,$0797c7d7d,$0988b7771,$07c889599,
$07c7c7c7b,$07479797a,$0a3a2997e,$0787d8e9d,$075777877,$06f6b7373,$09b9f998b,$075859297,
$06d6f7073,$0535c676c,$0a3a1976a,$06e7a98a2,$065686b6c,$06051525d,$08f939284,$084838389,
$088858383,$075757a84,$0807f7e7a,$07c808180,$0817c7878,$07b7a7e82,$07c7c7c7c,$07c7c7c7c,
$07c7c7c7c,$07a7a7b7b,$078797a7a,$0807f7d7a,$080818180,$07f818180,$070717379,$06d6d6e70,
$04c494745,$04d50504e,$04e4b4a4b,$0565a5955,$03b3b3f4c,$03b3b3b3b,$03c3c3c3b,$0413f3e3d,
$04b484542,$0776f5c4f,$08483807c,$07a6c6c7c,$07d979d95,$0706f6e6f,$072717170,$07d7b7774,
$08080807e,$08a838281,$08795a09c,$083838384,$082838383,$082828383,$082828282,$094858081,
$0918e8e93,$0817f8791,$080808181,$08d887d7e,$090938e8e,$07f7f7c84,$07a7c7f7f,$0928b8179,
$0838d9598,$07e7f7e7b,$0777a7d7f,$0a29c8e7e,$07c8194a1,$07e7e7e7d,$079787b7e,$09b9e9b8b,
$07d7b7d8f,$07c7d7d7d,$08a76777a,$089959897,$07d7c7b7c,$07b7c7c7d,$097867274,$07e8e9b9e,
$07b7c7b7a,$07377787b,$0a4a39779,$0778093a0,$074767776,$060686f71,$09e967f6c,$07d979f9f,
$06d6e6f72,$04f5b686d,$0a2a08c57,$06c7e99a0,$06467696a,$05c51535e,$08b89887a,$084858288,
$07d7c7f81,$07474797d,$0807f7d79,$07e828281,$0807b7879,$07a7a7f82,$07c7c7c7b,$07c7c7c7c,
$07c7c7c7c,$07a7b7b7b,$078797a7a,$0807f7c79,$081808080,$080818180,$07272757b,$06f6f6f71,
$051525454,$042474c4f,$048403d3f,$05c5e5b54,$03b3c4452,$03b3b3b3b,$03c3c3b3b,$0403f3e3d,
$049464341,$0756b574d,$083827f7a,$0786d6f80,$07d969c94,$06f6e6d6e,$07271706f,$07c797673,
$080807f7d,$089828281,$086949f9b,$083838383,$085848483,$081838686,$081828282,$08a817f81,
$08c8d8c89,$0807e898d,$07f808080,$08a857c7d,$090938f8d,$07f7e7b84,$07c7d7f7f,$0968a7f79,
$0858f979b,$07e7f7e7b,$0787c7e7e,$0a3a1947d,$07c849ca3,$07d7e7e7e,$079797b7d,$0989b9582,
$07c7a7f90,$07c7c7c7d,$08675777b,$090969896,$07c7b7b80,$07b7c7c7c,$09b857176,$08095a1a3,
$07a7b7a7a,$07275787a,$0a3a18d72,$0818b99a2,$074747578,$0626a6e71,$0a0855d5d,$08ea2a3a3,
$06b6d6f72,$0515c6669,$09d987a50,$06b7d949b,$063656768,$05e56565d,$083808073,$07c7e7f83,
$071777c7c,$072717372,$0807f7d78,$07f838381,$0807b7879,$0797b8082,$07c7c7c7b,$07c7c7c7c,
$07c7c7c7c,$07a7b7b7b,$078787a7a,$0807f7b78,$081818080,$082828181,$07373777e,$071717172,
$04044494c,$038393a3c,$0453c3838,$061615d54,$03b3e4a59,$03b3a3a3b,$03c3c3b3b,$03f3e3d3d,
$047434141,$07366534c,$084827e79,$07f707483,$07b959d97,$06f6d6c6d,$072716f6f,$07b787673,
$0807f7e7d,$087838281,$08596a099,$082828382,$093918e86,$0818b9294,$081828282,$0827d8080,
$08b8f8e8a,$07f7e8a8d,$07e808080,$089827c7e,$09195908d,$07f7d7d87,$07c7d7f7f,$099887b7a,
$086969fa0,$07e7e7d7c,$0797c7d7e,$0a19e8b7a,$07c8c9fa1,$07e7e7e7e,$071797b80,$09596907a,
$07b7a808f,$07c7d7d7d,$082757a7b,$0969b9d97,$07c7b7c84,$0797b7b7b,$09f857076,$08399a3a4,
$0797b7b7a,$071747778,$09d8f7468,$0999c9fa2,$074747587,$069706f71,$09e74555f,$094a2a3a3,
$06a6c6d73,$0525d6568,$0928a6850,$069798a8f,$064656465,$067646363,$07a797871,$07a7b7c7d,
$06770787a,$0726f6b65,$081807c76,$080838381,$07e7a777a,$0797d8282,$07c7c7c7b,$07c7c7c7c,
$07c7c7c7d,$07a7b7b7c,$078787a7a,$0807e7a78,$081818181,$084838181,$073747980,$073727373,
$033343537,$036363534,$0433a3737,$063625e53,$03c414e5d,$03b3b3a3a,$03c3c3c3b,$03e3e3d3c,
$04442403f,$071625049,$085817c77,$08f7b7c85,$076909c9b,$06f6d6b6c,$07271706f,$07b787573,
$0807f7e7d,$086838281,$0869aa097,$081828283,$09090918b,$0818c8c90,$081828280,$0827c7f80,
$08b8f908c,$07e818b8c,$07f808080,$088807c7e,$09298938e,$07f7c808b,$07b7d7f7f,$09d87777a,
$08799a2a3,$07d7d7b7d,$07b7b7d7d,$0a096817b,$07d909f9f,$07d7e7e7c,$06e787b7d,$094968e74,
$07a7b8590,$07c7d7d7c,$07c747c7b,$0999f9e93,$07b7a7c89,$0787a7b7a,$09a7c6c75,$0889aa2a2,
$0777a797c,$06e737576,$07f665d62,$0a3a3a29c,$071737d9b,$0686e6e6f,$0905d515d,$092a0a1a1,
$0696b6c74,$0535d6366,$0857d6050,$066788181,$06e6d6a66,$07170716f,$0797a7774,$076777779,
$05e656e74,$0716d645c,$081807c75,$081828282,$07d78777b,$0797e8382,$07c7c7c7b,$07d7c7c7c,
$07c7c7c7d,$07a7b7b7c,$0787a7a7a,$0807d7978,$081818181,$084838281,$074767b81,$076747474,
$030303132,$036353431,$03f393737,$064625c4f,$03c445360,$03b3b3a3a,$03c3c3c3b,$03f3e3d3d,
$04341403f,$06e5d4d47,$085807a75,$09b8f8789,$06f84989e,$06f6d6b6b,$073727170,$07b787573,
$0807f7e7c,$085828281,$08a9d9f94,$07e818183,$08e8d8b84,$0838a8a8e,$08181817f,$07f7d7f80,
$08d8e8e89,$07d83898e,$080808080,$0867e7c80,$0979b968f,$07e7b818e,$07c7d7f7f,$09c81757b,
$08c9ea2a2,$07d7c7a7c,$07b7b7d7c,$09f937d79,$07d929ea0,$07c7d7d7a,$070787b7c,$097998b70,
$07a7c8a94,$07c7c7c7c,$076757c7b,$09ea3a191,$07a7a7f90,$077797a7a,$0886c6b75,$0959f9f96,
$07679858e,$06e717374,$05e556069,$0a4a4a395,$06f7085a2,$0656a6c6d,$07b53525d,$08c969a97,
$066696a74,$0575b6063,$07d776259,$06f767a7a,$075757370,$077757576,$076757677,$078767575,
$05b647279,$0706b5f57,$0807f7a74,$082838281,$07c77777c,$079808482,$07c7c7b7a,$07c7c7c7c,
$07b7b7c7c,$07a7b7b7b,$078797a7a,$0807d7978,$081818181,$084838282,$075777d82,$078757575,
$02f2f2f30,$036353331,$03c383737,$063615a4a,$03d485862,$03b3a3a3b,$03c3c3c3b,$03f3e3d3d,
$04341403f,$06c594c47,$087817a74,$09e9b938d,$06c778f9c,$06f6d6b6a,$073727170,$07a777573,
$07f7e7d7c,$084828180,$08e9e9f90,$07e808182,$08e8d8a81,$084888c8e,$08080817e,$07c7d7f80,
$095928c84,$07c848994,$08080807f,$0827a7c7f,$09e9f9e94,$07d7a8191,$07c7d7e7f,$08d78787b,
$0909b9e9d,$07c7b7a7d,$07b7c7d7b,$09d8c7978,$07f929b9e,$07e7e7e7b,$0747a7b7d,$09c9a876f,
$0797e8e99,$07c7c7c7b,$074777b7c,$0a1a4a38e,$079798296,$075787879,$06c5d6b73,$09fa09a81,
$0747f9a9e,$0716f7273,$04d556571,$0a4a3a285,$06e708da1,$065696b6c,$06d50535e,$0878b8f8c,
$062646576,$066666462,$077716867,$072757778,$075777572,$079767373,$0807c7677,$0877e8081,
$05a657382,$06f675953,$07f7c7771,$08283817f,$07a76787e,$07a808280,$07c7c7b79,$07b7b7b7b,
$07b7b7c7b,$07a7a7b7b,$079797a7a,$07f7c7978,$081818180,$084838282,$076797f84,$07c787776,
$02f2f2f30,$036343331,$03b383737,$063615646,$03f4c5b63,$03b3b3a3c,$03d3c3c3b,$03f3e3e3d,
$046444240,$06b594e49,$08c847c76,$09c9d9b94,$06b6e7f95,$06f6e6c6b,$072727271,$078767573,
$07e7d7c7a,$084818080,$0929f9d8c,$07f808182,$08f8d897f,$0868a8e8e,$080807f7f,$07c7d7f80,
$09d988e81,$07c868e9a,$07f80807e,$0827a7c7f,$0a0a0a299,$07c7b8399,$07c7d7d7e,$08677787b,
$0919a9c98,$07c7b7b7f,$07b7c7b7b,$099867778,$08494999c,$07e7e7e7b,$0777a7b7d,$0a097826f,
$07a8296a0,$07b7a7b7a,$06d76797a,$0a0a3a086,$0797d8a98,$074767778,$05b5e6b72,$0a3a0805b,
$07490a3a4,$06e6f7172,$04a56646c,$0a1a19a6e,$06c708b9d,$063686a6a,$06953545c,$086848586,
$06f6b6777,$073747271,$078737172,$072737376,$076757372,$07a7b7a77,$088867c77,$07f808384,
$0535e6e7c,$06e65544e,$07f7c756f,$08382807f,$07875797f,$07b80817d,$07c7b7a78,$07b7b7b7b,
$07b7b7b7b,$07a7b7b7b,$079797a7a,$07e7b7878,$081818180,$084838282,$0777a8084,$0807c7877,
$02f2f3030,$036343230,$03a393737,$0625e5142,$043515e63,$03c3b3c3d,$03e3d3d3c,$042413f3e,
$04f494643,$0796d6157,$097918981,$093999d9c,$0696a7084,$06f6d6c6a,$072727170,$076747373,
$07d7c7a79,$08280807f,$097a09c89,$07e808183,$08e8c887f,$0888e8f8f,$080807f7e,$07c7e7f80,
$0a19b8c7f,$07e85939e,$07f7f7f7e,$07f7a7c7e,$0a1a2a093,$07c7b869c,$07c7d7c7d,$07c71787a,
$0939a9a92,$07c7b7a82,$07d7b7a7b,$09982777a,$08b999c9f,$07d7c7a7c,$079797b7c,$0a3977e6f,
$07b869ca4,$07a7a7b79,$06a757879,$0a29a8e73,$08393989e,$074757777,$0646a7172,$0a49e6a5a,
$07799a4a4,$06d6e6f71,$04d58656a,$098998b5d,$072768e96,$0656d6e70,$0685e5c5d,$07e7e807d,
$078737076,$075777577,$072737273,$07b787574,$082807c7f,$0787d8180,$0817d7c7c,$06e737777,
$050566170,$06c62504b,$07e7b746e,$083828180,$077767b81,$07c81807c,$07b7b7a79,$07b7b7b7b,
$07b7b7a7a,$07a7a7a7a,$07879797a,$07e7a7878,$081808080,$083828281,$0777b8084,$0827e7a77,
$030303031,$036343230,$03a393737,$0615a4c3e,$048586264,$03d3d3d3f,$042413f3e,$049474543,
$0665d544d,$0857d756e,$09794928d,$07b899598,$067676970,$06f6c6b69,$072727170,$074727272,
$07b7a7876,$081807f7d,$09ba09a87,$07f808187,$0918e877d,$08c939695,$080807e80,$07c7e7f7f,
$0a29c8b7b,$07d8697a1,$07e7f7f7d,$07a7b7b7d,$09f9f9985,$07b7c8b9a,$07b7c7c7c,$077727a7a,
$09498988d,$07d7c7b87,$07a7b7b7c,$0977c767b,$08f9ca0a0,$07b7b7a7d,$078787a7b,$0a394766f,
$07c8a9da4,$078797a78,$066737678,$09c816a5c,$095a0a1a1,$073747578,$0646e7571,$0a4925859,
$07d9ea3a4,$06c6d6e6e,$04d59656a,$08b8e7e55,$070728e8e,$06c6c6a6e,$06e6b6d6d,$079797976,
$074737274,$070747372,$079777372,$0837f7e7a,$083857e8b,$07577767e,$06d6a6e72,$05c616567,
$05056595d,$06a5f4c4a,$07d78726d,$08382817f,$077777c82,$07e83817c,$07b7a797a,$07a7a7a7b,
$07b7b7a7a,$07a7a7a7a,$07879797a,$07d7a7778,$080808080,$082828181,$0787c8183,$082807c78,
$030313131,$035343231,$039383837,$06057483d,$04e5d6464,$043414143,$0504b4744,$05f5c5855,
$0726e6863,$0807c7875,$088878785,$06d7e888a,$066656769,$06c6b6a68,$07070706f,$073717070,
$07a797776,$0807f7d7c,$09da09784,$07f81828a,$0998d827c,$0919c9f9e,$080807e83,$07c7e7f7f,
$0a19a8376,$07d8b9da2,$07e7f8080,$0757b7b7e,$0a1a0947e,$07a7e929d,$07b7c7b7b,$076717a7c,
$0959a9a8d,$07c7a7d8d,$0797b7c7c,$09278757a,$0969ea19f,$07a7b7a82,$07b797a7c,$096836971,
$08b939e9f,$077777983,$068727477,$08b56565d,$0a2a4a4a3,$072737383,$0646b6e6f,$09e7b4f5a,
$07c969d9f,$06d6c6c6c,$05865666c,$081847253,$06e738482,$078767674,$074767778,$075747877,
$075767276,$078787873,$088837e7b,$085828887,$0787b7481,$064626770,$0615e5e61,$05b595d5e,
$04d56595d,$06a5d4947,$07c77706d,$08381817f,$076777e83,$07f84817b,$07a797879,$07a7a7a7a,
$07b7a7a7a,$07b7b7b7b,$07979797a,$07c797778,$08081807f,$082828181,$07a7e8283,$082807d79,
$030313133,$036343231,$03a393837,$05e55473d,$055616563,$054504c4c,$065615c58,$06b6a6968,
$06e6d6c6b,$06d6f6f6f,$079757370,$06c7f827e,$065656567,$06c6a6867,$07070706f,$073717070,
$079787775,$0807e7d7b,$09f9f9283,$07f81818d,$09d8e7f7d,$0919ea2a2,$0807f7d85,$07c7d7f80,
$09e917c77,$07e8c989c,$07f7f7f80,$0757a7b7d,$09f9f8c76,$07a83959c,$07b7b7b7a,$072757a7a,
$0999d9d8c,$07c7a8093,$0787b7c7c,$08e757679,$09ca2a3a1,$0797a7a87,$07877797b,$0876d606f,
$0a09fa29a,$076767f9c,$072727375,$0764e5f6a,$0a4a4a4a2,$06f70708e,$0636a6d6e,$09067505c,
$0788b9295,$07a737271,$0656b6a76,$07d7e7363,$07678807f,$075787c7b,$07c777573,$075737579,
$07c85837b,$08681837f,$07d7e7e80,$06f777f7b,$066616067,$05a5b5a62,$057565858,$058575b5b,
$04e555855,$068594848,$07c766f6c,$08282807e,$076787e83,$08084817b,$07978787a,$079797979,
$07b7b7a79,$07b7c7c7c,$07979797a,$07b787879,$08180807e,$083818181,$07a7f8383,$081807d79,
$031313234,$037353332,$03e3c3b39,$05c544841,$060656661,$06663605e,$06a6a6a68,$061646769,
$057575a5d,$054545656,$0756f6a60,$06e80807a,$064646566,$06b696865,$071706f6d,$074717171,
$079797776,$07f7d7c7b,$09f9e8c81,$080818292,$09c8b7d7e,$0909fa3a2,$0807e7e84,$07c7d7f80,
$099908179,$07e91999b,$07e7e7c7a,$076797b7c,$09c998572,$07b85969a,$07b7b7b7a,$06f777a7a,
$09d9f9b82,$07b7c8696,$0797c7d7c,$0886d7578,$09ea4a4a2,$078787a8f,$074767677,$061565c6f,
$0a3a3a185,$0757591a3,$074737374,$05e4c5d6b,$0a2a3a497,$06c6d6e90,$064696c6c,$08460545b,
$07c848488,$078716c6c,$074747376,$07c797573,$077797b7d,$072737476,$0837f756f,$082828588,
$07f837f7f,$0807e7a7f,$0646c6e75,$0615e5c5e,$05d575456,$0545c5b5b,$059565a55,$054585958,
$04d54514f,$063534849,$07b746e6b,$08281807e,$077797f83,$081837f79,$07978777a,$079797979,
$07d7c7a79,$07d7e7f7f,$0797a7b7b,$07b787879,$08281807e,$083828182,$07c818483,$0817f7c79,
$033323436,$03b383534,$04b46423e,$05c58534f,$068696661,$067676868,$05c606366,$04a4d5257,
$044444547,$04a474544,$0716b6558,$0707f7d77,$064636464,$06b696865,$071706f6d,$076727171,
$07a7a7979,$07f7d7c7b,$09f9b8781,$080818396,$0917e7b7d,$09ba0a3a0,$07f7f7e8a,$07b7d7e7f,
$096827779,$081949c9e,$07c7d7c7a,$077797b7c,$09f988072,$07b8a999d,$07a7a7b7b,$06d797a7a,
$0a09f9679,$07b7c8a9a,$078797a7c,$0746c7577,$09fa4a298,$0767f8b97,$072757676,$05c61646f,
$0a4a49a67,$073799da4,$06d707273,$0514e5e69,$09a9c9c86,$06b6c6e8c,$060666a6c,$07e5f5c5b,
$07b817e80,$07c7a736f,$07b7b7a7b,$072747777,$079787373,$077787374,$0868b8280,$087868b81,
$06d757b7c,$066706569,$05d5a5d62,$0565a5a59,$058575853,$05255595c,$05f585853,$053545358,
$04e525153,$05f4d4749,$079726d6a,$08180807d,$0757a8183,$081827d77,$07877767b,$079787878,
$086807c7b,$085898d8c,$07b7d7f81,$07a787879,$08282817e,$083828282,$07d818483,$0807e7b79,
$039373738,$049443f3c,$05c59534f,$05d5e605f,$0696a6560,$054575c64,$046494d50,$041414244,
$041414141,$047444342,$06f696153,$0737d7a75,$064636364,$06b6a6967,$072706f6d,$087787372,
$07a7b808a,$07d7c7b7a,$09f978480,$07e7f8499,$0897b7a7e,$09a9ea09b,$07e7d7f8f,$07c7e7e7e,
$09077757a,$084949b9a,$07c7d7b7a,$0797a7b7c,$0a1987c74,$07d909ca0,$07a7b7c7b,$0717a797a,
$0a3a29273,$0797c919e,$077787879,$0606b7376,$0a09f8f79,$074919d9f,$072747574,$064697373,
$0a4a48c5f,$07480a1a4,$06d6f7576,$04c505e68,$08d909076,$06b686f87,$06a6c6e6d,$077696668,
$0787f7f7d,$07c7d7976,$075747a7a,$0746f7479,$0817e807c,$084888282,$07c7e8787,$06a6e777a,
$0605f6766,$0585a635d,$056595e5c,$05b595657,$052555656,$052535757,$056545453,$054515259,
$051555152,$05949464b,$078706c68,$081807f7d,$0757a8182,$081807c76,$07776767c,$079777777,
$0988d817c,$0959b9e9d,$07e83888e,$07977797b,$08281807e,$082828282,$07e828383,$0807c7a79,
$04a464444,$05b56534f,$06262605e,$05d5f6162,$0696b6660,$043464e5d,$03e3e3f41,$03e3e3e3e,
$0403f3e3e,$046434140,$06e675e4f,$0777e7973,$066636365,$06d70716c,$073716f6d,$096817573,
$07a7b8899,$07c7a7a79,$09e91817f,$07d7f859b,$0887e7c7c,$09c9f9f96,$07d7d8194,$07c7e7e7d,
$08674767b,$08a949b97,$07d7d7c7c,$07a7a7c7c,$0a0927573,$081959ca0,$07a7a7a7b,$072787879,
$0a4a08b6d,$0788197a0,$076767777,$055667174,$0a1895b54,$080a1a3a2,$072737473,$05f646f72,
$0a3a0775b,$0868b9ea2,$06b7a8789,$04b526067,$08183886d,$0756b7481,$07b7b7979,$07a767679,
$0777a7b7d,$078757476,$07a737b75,$07b7e837d,$082828382,$07a7b7c7b,$069727172,$05f5e5f68,
$0535a605e,$059585455,$0525a5f5c,$05b5a5d55,$052545653,$04e4f5554,$05a514f51,$058545055,
$052555254,$05547484f,$0766f6c67,$081807e7c,$0767c8283,$0827f7974,$07675777e,$07d787776,
$0a19c8e84,$09ea1a2a2,$0848b9198,$078787a7e,$082817f7d,$082828182,$07f838382,$07e7a7879,
$059585757,$05b5b5b5a,$05658595b,$05c5c5654,$06a6c6760,$03e424d5e,$03c3c3d3d,$03d3d3c3c,
$0403f3e3e,$045434141,$06d675d4c,$07b7f7873,$06a646468,$072858c7c,$072706e6e,$098827573,
$07a7c8f9c,$07b797978,$09c8b7f7d,$07d7f889c,$0827b7c7b,$09c9f9f91,$07e7d8396,$07d7d7d7d,
$08573767b,$08a939a9b,$07c7d7b7e,$07a797b7c,$09f8c7173,$0879ca0a1,$0787a7a7c,$071767778,
$0a0937664,$08e959ca2,$075757679,$0646c7173,$0a1735c63,$08ca4a4a4,$070727272,$058656d6f,
$09a936250,$08990969a,$06f838788,$056575f65,$07c7f8367,$07c75777b,$07e7f7e7e,$07375787f,
$075787471,$07d817a79,$081878182,$080848489,$06f74797a,$05f616967,$05f5c5b5b,$05c57585c,
$05c59575d,$055555459,$0565a5657,$0595a5854,$053585952,$0535a5653,$055575050,$059565851,
$054524f57,$052454750,$0756e6c65,$0817f7e7b,$0767d8383,$0837f7773,$074737880,$0847b7674,
$0a3a0988c,$0a1a3a4a4,$0888f969c,$077787c81,$082807f7b,$082818182,$07f838382,$07d7a787a,
$054585c5e,$0494b4f52,$043444648,$05c554843,$06e6d6660,$03e435063,$03b3b3b3c,$03d3c3c3b,
$0403f3e3e,$046434140,$06d675c4b,$084897c73,$06c66646d,$07b949789,$071706e6e,$0917b7472,
$0787c919b,$079787877,$097847e7b,$07e7f8b9d,$07b777b7d,$0989b9c89,$07d7d8795,$07c7d7d7d,
$08174767a,$091969b99,$07c7b7c82,$0797a7c7c,$09f837076,$090a0a3a3,$07778797c,$070747777,
$08d715b62,$0a0a1a09f,$073747388,$06d757173,$097646062,$093a3a3a4,$07b797773,$04e6d7d7f,
$08d835342,$0808d8c8c,$07580817f,$06a6c6f71,$07b7d796f,$07c787b7d,$073757379,$07678797b,
$0887f827d,$08b868185,$077858789,$064657477,$067656a63,$05e615c5a,$051575b5c,$055535454,
$05a55575b,$055596057,$051525854,$05a565558,$05d59535b,$05458545b,$04f505050,$058515350,
$052545757,$04e44474d,$0726c6b61,$081807e7a,$0767f8282,$0827d7672,$073737981,$0867e7674,
$0a3a0998d,$0a0a2a3a3,$08990979c,$077787e83,$081807e7a,$082818181,$080828282,$07c79777b,
$041474e51,$0393a3b3d,$03c3b3b3a,$05b50423d,$0706d665f,$03e455568,$03b3c3c3c,$03d3c3c3c,
$0403f3e3e,$049444140,$06c665b4e,$08a8f7d72,$06f676673,$08298988b,$071706e6f,$084757271,
$0777d9498,$077767676,$08f7f7c7a,$07d7e8e9d,$077777b7c,$09a9c9783,$07d7e8b97,$07c7c7d7d,
$07c73787a,$0999e9c96,$07c7b7d88,$078797a7b,$09b787177,$096a0a3a1,$076777a82,$070737676,
$069555761,$0a4a4a399,$072737697,$0686e7172,$0885a5c5f,$0939d9e9f,$0898b8b86,$04c697e86,
$084774f3f,$077888582,$07b7d7e79,$0797a797a,$07a7a787a,$07a747576,$07d7a787a,$08a7c7e7f,
$0808a9286,$0767f7a7e,$0676f6e6d,$058576463,$05d5f595d,$056535951,$04e57574f,$051545353,
$0584e5558,$05355555c,$054545b53,$05a5a5253,$056575355,$059565156,$04f515359,$0504e4e4e,
$054545552,$04b47494c,$0706b695e,$081807d78,$078808382,$0817c7471,$072737a81,$0847f7873,
$0a09d958a,$09d9fa0a1,$0878d9398,$076797e82,$0807f7d78,$082818181,$080828282,$07c79787c,
$0373a3d3f,$035353435,$03a3a3936,$0594b3f3b,$0726d645e,$03f485c6c,$03c3c3c3c,$03d3d3d3d,
$0403f3f3e,$053474241,$06a665c58,$08d8e7b71,$06c676678,$08697917d,$0706f6d6f,$07b73706f,
$077819794,$076757576,$0897d7b78,$07e7f929c,$077787c7d,$09b9e9580,$07c809097,$07c7c7d7d,
$07672797a,$09ea19f92,$07b7b7d8f,$07678797a,$086666e75,$09c9fa098,$075758c99,$071727475,
$06163656c,$0a4a4a38d,$071717ca0,$06b6e7072,$0744d515d,$091939495,$0797c8185,$0606b7678,
$080746461,$076797c7e,$07c7f7c79,$078797c7b,$07e7b7073,$07e7c7777,$07e818782,$0877b7b83,
$0656e8085,$05d60606b,$0585a5867,$054535e59,$057515158,$05156534f,$058555552,$052535554,
$05a595655,$054545254,$052535455,$053545555,$05d535252,$058555458,$05153545f,$04f4f5251,
$052525556,$04b484c52,$06e6a685c,$081807d77,$07a828482,$0807a7171,$070737b81,$0827e7871,
$098958f87,$098999b9a,$084898e93,$0757a7e81,$0807e7c77,$081818181,$081828281,$07b78787d,
$035373839,$034343434,$03a393836,$058473e3b,$0726c625e,$0414e636f,$03c3c3c3d,$03c3c3c3c,
$03f3f3e3e,$0604a4341,$06b68646a,$08f8c7970,$06866687c,$08b94816e,$06d6d6c72,$076706e6e,
$07786998f,$076757576,$0857d7a77,$07e84999b,$0757a7c7d,$09d9e927f,$07c82939a,$07b7b7c7d,
$071757a7a,$09ea2a08d,$079798296,$074777979,$05e5b6b72,$0a1a09170,$0747999a1,$073717273,
$05d606673,$0a2a3a17b,$07b7785a0,$0777f817d,$06646425c,$088848788,$06c666274,$073767472,
$079737071,$07678797a,$078797676,$07d7c7274,$0898c797d,$0878f8884,$087858583,$06e686d7d,
$066696071,$05357555f,$0585b5957,$05b565d55,$05051575d,$05d56534f,$054525555,$058575852,
$052575758,$051565754,$055525556,$059585759,$0564c4f53,$05451565d,$054555352,$057545352,
$0524f5456,$04d494c54,$06c696559,$081807d76,$07b828382,$07e776f71,$06f737c81,$0807b756f,
$08e8c8984,$092939391,$08185898e,$0767a7e7f,$0807e7a76,$081818181,$081838281,$07a77787d,
$035363738,$033333334,$03a393735,$057443d3a,$0716a615f,$044556871,$03c3c3b3d,$03d3c3c3c,
$0403f3e3e,$0644c4341,$06b686c71,$0928b776f,$068666b83,$091947b6b,$06d6c6d75,$074706f6e,
$0788c9987,$075747476,$0837c7976,$07d8d9e9a,$073797b7c,$0a09f8e7a,$07c86999d,$07a7b7c7c,
$06e757778,$0a0a0997e,$07984909a,$074767777,$05c5d6b72,$0a3a07a59,$07488a2a3,$06f727274,
$05a5d636a,$09c9d9466,$0898b8e99,$0737f8487,$06450485b,$0807f8186,$07a766e75,$07c7b797b,
$074777779,$071707475,$0877e7774,$08a8d847c,$07d8b9085,$074808680,$074706e70,$0615d6066,
$05b545e5a,$0535e5959,$056565557,$051505153,$0505a5b5e,$05352524f,$04c545b52,$05859584c,
$053565452,$0565d5c57,$058525652,$055575359,$052565454,$051505458,$051565754,$05555554f,
$054504f51,$04c494c54,$06b696357,$080807d74,$07c828281,$07c746e72,$06e737c80,$07f79726d,
$085838281,$08d8e8d8a,$07e81858a,$0777c7e7d,$0807d7975,$081818181,$082838281,$07a77797e,
$035363737,$034333334,$039383635,$054433c3a,$07068605f,$0475a6b72,$03c3b3c3e,$03d3d3c3c,
$0403f3e3e,$05e494341,$06c676d70,$094897770,$068667089,$094947a6b,$06c6c6c79,$072706f6d,
$07c93967e,$075757677,$0817a7775,$07e919f98,$073797a7c,$0a29d8772,$07d909fa1,$0797a7b7c,
$067727577,$09f968166,$07f979c9d,$074757677,$0656e7371,$0a39b6c62,$07293a3a3,$074727173,
$04c556a75,$090918656,$083848d8d,$071797d80,$06966676a,$07d7d7c79,$07b7b7478,$074787d7e,
$0766f7178,$07e7f7b75,$0888b8781,$083888b90,$06f707e7e,$0686c6768,$05c5b606e,$05c5b5758,
$0615a5a5e,$04e58544f,$062585454,$0585a5659,$04f555a5b,$050524b4e,$04f575354,$055555755,
$054575952,$0605a545c,$05b575957,$054585b5a,$055594e55,$052505559,$051575553,$053515052,
$051515152,$049494e51,$06a696153,$0807f7b71,$07d818180,$07a726d73,$06d757d7f,$07d776f6c,
$07f7d7f7f,$0898a8884,$07c7d8085,$0797e807d,$07f7d7875,$081818180,$082838181,$079767a7f,
$035363737,$034333233,$039373635,$052413b3a,$06f666160,$04c616f73,$03c3c3c3f,$03d3d3c3c,
$041403f3e,$054474342,$06d676f6d,$094867670,$06766748c,$09691766a,$06c6c6d7f,$071706f6d,
$07f959178,$074747577,$07d797674,$07f959f94,$075797a7c,$0a1997b6d,$08196a0a2,$07878797a,
$064707376,$09a765a5a,$08da0a0a0,$072737475,$0616e7571,$09f8f6160,$07b97a1a1,$08687857f,
$03e4c6f83,$082867f4f,$07d7b8681,$0777a7d7e,$076747577,$0787e7c79,$074777774,$0797b7b78,
$08279767e,$08a8b8485,$086848788,$0666d7c83,$062636362,$054675857,$0575e5b5a,$0525b5557,
$0635e5b55,$04f545454,$05b58534f,$0575e5554,$057585a5d,$054524e4b,$055545357,$0514f4f51,
$057575751,$056545358,$054525653,$057545a57,$050555055,$052504e51,$050515857,$054514d53,
$053575451,$046484f54,$069685e4d,$07e7d786f,$07e81807f,$0776f6d74,$06e777f7e,$07c756d6b,
$07c7c7e7e,$0888a8781,$07c797c83,$07a7f807e,$07f7c7775,$081818180,$082828181,$078767b80,
$035373737,$034333333,$039373535,$04e3f3b3a,$06e65625f,$053677274,$03c3c3d42,$03d3d3c3c,
$045423f3e,$051474446,$06e6b756c,$094847771,$06666798d,$0968a7068,$06d6c6d83,$071706f6e,
$07c8f8773,$073737577,$07a777573,$0839b9f8f,$077787a7b,$09b8c6d6b,$0929aa0a1,$076787883,
$067717375,$08f646362,$098a2a2a1,$071727476,$05f686e70,$09b7b5659,$08c93999b,$07e84878b,
$054576878,$07d83745a,$075747d7e,$07b7a7c7b,$0787a7b7a,$074767875,$07d797975,$083837e7b,
$080808089,$082767a7e,$06567716f,$05a596263,$05a535654,$04e4b5458,$059595450,$0525b585c,
$05c574f50,$0565a5354,$04f535852,$053595250,$054595753,$053525153,$053575757,$054555251,
$05354545e,$053535254,$053585552,$05b595853,$051555259,$05558584f,$052515555,$058555853,
$055595657,$0484a5457,$068685b4b,$07d7c756c,$07f817f7e,$0746c6d76,$06e78807d,$07a736c6b,
$07e7d7e7e,$08c8d8983,$07d7c7f87,$07a80807f,$07f7b7675,$082818180,$082828281,$077777c81,
$037373737,$034343434,$039373534,$04a3e3b3a,$06e64645e,$0596c7676,$03c3c3e46,$03d3d3d3c,
$04a45403e,$04e47464a,$072717968,$095867873,$065687c8e,$093816b67,$06c6c6c83,$06f6f6e6d,
$0757a7570,$073737475,$076747272,$0889d9d87,$07677797b,$0846f636c,$09e9fa09a,$075777891,
$076737374,$07d60636a,$09da2a29f,$07573737e,$05e767d79,$098734749,$0858c8e92,$07c7e7f7d,
$06a6e7275,$07d7b726a,$078777a7d,$07a777a79,$072787978,$07f797c77,$089868c87,$07e868582,
$0797a7d7a,$05e606e71,$05d655562,$050595f5a,$05a545656,$052585457,$056615f58,$054575459,
$05a575050,$05e5b5256,$053525356,$05351504f,$05352574e,$053545450,$05158514e,$059595550,
$051595e58,$0595b5455,$053545152,$053515855,$052565355,$0585d5a54,$057555152,$052545859,
$05a515355,$0474c5459,$069675748,$07d7a7268,$07f807f7e,$0726b6d78,$06f7a7f7b,$079716a6b,
$0807e7e7d,$08e8e8a84,$08080838a,$07c818181,$07e797576,$081818180,$083838281,$076787e83,
$037383737,$034343436,$039373635,$0473e3b3a,$06d64655c,$060727a77,$03c3d3f4a,$03d3d3d3c,
$04946403e,$04c474748,$0797e7a62,$0968e7f79,$0676b808d,$089766a68,$06c6c6c7c,$06e6d6d6c,
$073716e6d,$071727373,$075727070,$08b9e997e,$074747779,$0615c6670,$0a1a19f85,$07475819d,
$071727373,$06d5e6067,$09b9e9f97,$089888388,$06077888b,$091695050,$07984848b,$07a7c7870,
$076777777,$078767576,$07676777a,$07d7a7672,$07f7d807d,$0868c8680,$07e808a85,$0646d737c,
$05f5c6667,$05b5a5a59,$05b56595b,$059595f58,$05c5f5b5b,$053575757,$0505a5d5e,$051545553,
$0575b594e,$057534d55,$04d554e58,$0524a4c4e,$04d4e4b52,$04b515c57,$05651544c,$05259514a,
$055575551,$054585a54,$056575452,$05c595355,$04f565954,$057585553,$051535957,$051545352,
$05a555556,$0474e5358,$069645246,$07c797067,$081807f7e,$0716a6f7b,$0727c7f7a,$0776f696a,
$0807f7e7c,$08a898682,$082838487,$07d818282,$07d787476,$08181807f,$084828281,$075797f84,
$037373737,$036353436,$039373736,$0453e3b3a,$06b646559,$066777d78,$03d3e4250,$03d3d3d3d,
$04845403e,$04a474647,$08684765a,$092948f88,$069708287,$0716b6969,$06b6a6a6e,$06c6b6c6c,
$06f6d6b6c,$06f707171,$0726f6f6f,$0949f9679,$072737679,$05363666f,$0a2a19b72,$0737389a0,
$06d6f7172,$05f565c66,$09094948a,$08088868a,$0686b6f76,$08b6d6464,$0777c808a,$07b7d7a74,
$075777678,$074737575,$07b7c7577,$08187797a,$0868c8e82,$0777e8383,$06a69766c,$05b616367,
$051555c5c,$054555552,$0585e5454,$0545d564f,$0535b5857,$053525157,$04f575655,$058575954,
$0524d4f57,$0514d5055,$055535753,$054575952,$051504d51,$053535a57,$05850544f,$0585a575c,
$052555851,$0575a5550,$057545251,$054535053,$052515451,$057505055,$04e505654,$053545451,
$055595753,$048505756,$069604c44,$07c776d67,$082817f7e,$06e6a737f,$0747e7f78,$0756c696b,
$080807e7b,$084838281,$083838484,$07e828282,$07b777378,$08181807f,$083838282,$0767a8184,
$038383737,$036363637,$03a383737,$0443e3c3b,$067626254,$06a797e76,$03d3f4455,$03d3d3d3d,
$044423f3e,$048464544,$0847c6951,$0848c8e8a,$06d798281,$06a6a6a6b,$06a6a6a69,$06a6a6a6b,
$06d6c6a6b,$06d6e6f6e,$06f6d6c6c,$09a9f9576,$07072747e,$042516a76,$0a09f925d,$073738e9e,
$07a7c7b77,$06648526b,$083858985,$0727c7382,$071706a65,$08774716f,$0767a7d85,$07d7a7775,
$07675777b,$07f7d7d77,$07c7f8684,$071818281,$0757b837b,$0666b5f71,$0605f5b5e,$050525156,
$058525757,$057555557,$052505450,$0544d4e54,$04c545659,$04c4d5852,$052575153,$057535e55,
$04e4b4b5b,$0575d5350,$054575557,$05559585f,$05b58514b,$05c565352,$051515654,$0544d5056,
$056524f50,$0605b5658,$05755575f,$050505252,$0595c5956,$057545354,$051515353,$0504f5253,
$04f50524e,$0494f5352,$0685b4844,$07b756b67,$082817f7e,$06d6b7580,$0777f7f77,$0726a696c,
$080807e7a,$082818181,$082828282,$080828282,$07a75737a,$08181807e,$083838282,$0767b8284,
$0393c3d3e,$036373838,$03a393837,$0423e3d3c,$0615b5a4c,$06e7a7c72,$03e3f475a,$03d3d3d3d,
$042413f3e,$047444342,$06e64554c,$07d7c7f7a,$07c82817f,$06b6b6d72,$06a6a696a,$06869696a,
$06b6a6868,$06c6d6d6c,$06d6a6b6b,$09d9f9173,$06e717284,$04150646c,$09b98814d,$083778d98,
$079858988,$06864656a,$07e7d8277,$07c787380,$077777778,$078757577,$075797878,$07d7b7470,
$07b7d7b7d,$085878280,$0727a7e84,$0656c6a71,$06160635e,$059585b56,$058565457,$053535657,
$059625754,$051575855,$05f5a5953,$052525258,$056626358,$04d4a4d50,$056565558,$051535654,
$054525353,$05a5a565c,$057595a4e,$05054574e,$05c554f4d,$04f525d57,$050535859,$050484951,
$0554f4e53,$0584f5058,$054525259,$058575b52,$06f6d5356,$056535457,$053544e55,$054545351,
$0524e5051,$046505551,$067564543,$07a746968,$08281807d,$06c6d7881,$078807d75,$0716a696e,
$081807e7a,$082818181,$082838282,$082838282,$07974747b,$082807f7d,$082828282,$0767d8283,
$03f424547,$03838393b,$03b3a3938,$03f3e3d3c,$0574c4944,$0727c796b,$03d404a5e,$03d3d3d3d,
$0403f3f3e,$046444241,$05c524e49,$07a76726d,$083837f7c,$06d6f777f,$06a6a696a,$06668696a,
$069686665,$06a6b6b6b,$06b696869,$09e9e886e,$06d6f7089,$04156656b,$091907248,$0867d878d,
$069737b80,$066696763,$07b7e7f75,$079787679,$077767678,$077757273,$07d7d7778,$07f847e7e,
$081838181,$0787c7d7c,$06063696f,$0615d6564,$0595e574f,$053515358,$05a5a5e5c,$057504e5c,
$04c57564f,$04d525a58,$057545253,$054515d5a,$05951595a,$04e51555d,$059525359,$056595555,
$05952555a,$04f515c66,$04f515450,$0525a574f,$05753594e,$0505a5954,$04e565654,$056514f52,
$053525054,$05655514d,$04f52515a,$0525a6e68,$07a735553,$04e535658,$054505451,$055555655,
$054515253,$0494f5150,$065524645,$07a716767,$08281807e,$06b6e7a82,$07b807c73,$06f696a70,
$081817f79,$081818182,$082828181,$083838282,$07773757d,$08281807d,$082828282,$0787e8283,
$046484848,$0393b3e42,$03c3b3a39,$03f3e3e3d,$051464341,$0747b7565,$03e414d62,$03d3d3d3d,
$03f3f3f3e,$046444140,$0564f4d49,$078747169,$0827f7d7b,$0737d8382,$06b6a6b6d,$065666769,
$068666565,$0696a6a69,$069676768,$09e9c7f6c,$06b6e708d,$0455a656a,$08b8d6a46,$07a7d8485,
$070717579,$06f6f7070,$077797a76,$076757476,$075727373,$07b817d77,$0828b817b,$077878a87,
$06d797875,$062656565,$057595f65,$056535453,$054505955,$052565850,$04f555650,$056655e52,
$05c555251,$050546054,$056505754,$055545856,$05759545b,$050555859,$04f4f5556,$058575150,
$05a545558,$0575c5e59,$054595356,$05b544f50,$052534e53,$050575556,$055574c49,$052545b64,
$050595952,$070575451,$057535362,$05a6f7c6b,$0786a5554,$052535660,$05456554e,$054505450,
$04e535658,$04e505350,$0624e4547,$07a706667,$08281807e,$06a707d83,$07d7f7a70,$06e696a73,
$081817f78,$080808181,$083828281,$082828282,$07672757e,$08181807c,$082828181,$0787f8383,
$049494948,$03d414447,$03d3c3c3c,$0403f3e3d,$04d454241,$074776f5f,$03e425065,$03e3e3e3d,
$03f3f3f3e,$047454241,$0524f4c49,$076726d61,$0817e7c78,$081858484,$06b6d6f78,$065646569,
$066656465,$069686968,$069676768,$09e99786b,$06a6c7191,$0505e646a,$089876a54,$075797f82,
$0767a7e7a,$075757575,$072727574,$07c7c7674,$07d7c7d7a,$08186827c,$075827f80,$0636e7576,
$05e645f62,$054565e57,$05259595b,$056545452,$056575558,$04e525355,$05355595e,$0535b6155,
$04d52534f,$0564a5150,$05d51525a,$052535054,$055515352,$053525657,$0594d4f5e,$05b52525e,
$05c575353,$05c605b52,$0575a5450,$05c4b4d57,$05d484d5b,$0525a5b60,$0555a4f4c,$05e615f65,
$050555a5e,$07b595e5c,$054585a76,$06c7c7e64,$07b625554,$056595368,$052535655,$0534f5051,
$04f4e5154,$04c525451,$05e4b4247,$0786d6668,$082817f7d,$06a737f83,$07e7f786e,$06c686a75,
$081807d77,$080818181,$083828281,$083838383,$07572777f,$081817f7b,$082828181,$0787f8283,
$04a494846,$04346484a,$03e3d3e41,$0403f3f3f,$049444140,$073716859,$03f445367,$03e3e3e3e,
$0403f3f3e,$048454341,$0514f4d4a,$0736e6555,$0827f7d79,$086858484,$06c707b85,$065666769,
$065646464,$067666766,$069676767,$09e94736b,$0696c7294,$064696a68,$085847068,$07d7e8182,
$0797b7c7c,$077747578,$075797776,$08687837b,$07f7d777b,$0767f827c,$060687170,$05d5e5d60,
$05c545257,$056565759,$04a4d5352,$056635653,$053575951,$051555355,$056535b50,$0595f5850,
$05b555a57,$059515452,$052505050,$0505b5857,$05e505254,$054545754,$05752504e,$05f555156,
$057585b4f,$053545858,$057555451,$04c4b4d5e,$0584e5153,$051554d57,$05d525757,$07d7f7d71,
$05765757a,$07d615454,$052576b7b,$07b7a795a,$0795d586d,$05357566f,$052515658,$052565450,
$053545052,$04c4f5155,$059484549,$0756a6667,$082807f7c,$06b758183,$0817f766c,$06b686c78,
$081807c74,$080818181,$083828181,$083838383,$074727980,$081817f7a,$081828282,$0797f8282,
$04845413f,$047484949,$03f404345,$03f3f3f3f,$047423f3f,$0726e6455,$040455569,$03f3f3f3f,
$0413f3f3f,$048454442,$0514f4d4a,$071645853,$0817f7b78,$085858583,$06c7a8586,$065666868,
$064646464,$067656665,$067666767,$09e8c6e6a,$0656a7597,$061606366,$0827b7165,$0797c8080,
$07c7a7878,$07e7b7c79,$07c7b807d,$0797f857e,$06b6e737d,$06060646c,$05d595f63,$05d5b565b,
$05b5d585f,$058555755,$05f545153,$0555a4d57,$05a5f584d,$051555453,$058585951,$055555054,
$05659555d,$0554e5752,$050515850,$055544e51,$056505154,$04f4c4d50,$0545b5b53,$050514b54,
$0545e5055,$05a565a58,$053584f52,$0504a5358,$0524e5358,$050585f59,$074575a52,$0646a7578,
$0637c7960,$079665352,$056697972,$069747754,$0765b6d7c,$051575c76,$054585756,$056565351,
$05b585456,$050505353,$05346474c,$072676663,$081807e7b,$06c778183,$0827e746a,$069696f7b,
$0817f7b72,$082828282,$083828282,$083838383,$072737b81,$081807e78,$081818181,$0797f8181,
$0433f3c3b,$048494947,$042444647,$03d3d3e3f,$04a44403e,$0706c6154,$041475868,$03f3f3f3f,
$0413f3f40,$048464442,$0524f4d4b,$063595653,$0807e7a70,$085858683,$06f848786,$065666767,
$064646465,$066666666,$067666667,$09c846c68,$057637a99,$057524e50,$06d65605b,$07a777672,
$0827f817a,$07e828483,$077787d80,$06d6e7278,$062606469,$0555e5e5f,$0555b5b64,$05b625855,
$05752575b,$05152545e,$060555755,$05c544b53,$0515a545d,$04f595752,$057575851,$055545658,
$048554d55,$05552544f,$052564e52,$0514d5159,$053575355,$051515257,$059665753,$04e504a4d,
$056524953,$0505a6355,$05f5c5855,$04f525658,$051585656,$05c7b7158,$070545652,$055505373,
$06a7b6150,$079695d56,$05b73755e,$05b747056,$067647a6b,$051535d78,$050535957,$056534f4e,
$055545253,$050535252,$04e43454b,$07166635e,$0817f7d7a,$06e7a8282,$0837d7269,$0696a717e,
$0817f7a71,$082828282,$083828282,$083838383,$071747c81,$0807f7c76,$081818180,$07a808181,
$03d3b3a3a,$048484642,$045464647,$03e3d3e42,$0534d4541,$06d6a6056,$041495a68,$040404141,
$041404041,$048464442,$0524f4d4b,$05a585554,$07e7a6d5f,$084838381,$075868584,$067676767,
$064656466,$065656565,$065656565,$0997a6b66,$04e5d7f9b,$04a474245,$0655a534d,$0857e766e,
$08480817d,$0707d7d80,$0636c6d72,$059576067,$05b595557,$055545861,$055565259,$058615b50,
$054545357,$052545b55,$058545653,$05b585552,$0534f555d,$05b545e59,$04f52525c,$053545659,
$04f595554,$04c5b554f,$051545a4d,$054505a55,$060544d54,$0524e5557,$0535b5b56,$05357564e,
$0585a5358,$05a555052,$057565553,$07e745753,$054595f7d,$076837262,$062594f5a,$0575a5875,
$0687b5f51,$0766d5c58,$0667b624f,$05e796a53,$073776e51,$055566579,$053575658,$059575050,
$052535456,$052514f53,$04b43444b,$06f65635a,$0807f7c78,$0717d8382,$0827b7069,$06a6b7480,
$0817f786f,$082828383,$082828282,$082828282,$070757d81,$07f7e7a74,$08181807f,$07d808081,
$03b3b3a3a,$04644403d,$046464647,$040414547,$0574e4440,$06c6b5f57,$0424b5b66,$041414141,
$042414141,$048464443,$0514f4d4b,$05a565553,$076695e5b,$08382817e,$07a878684,$067666767,
$064646465,$064656564,$064646464,$094726967,$05262869d,$03d3b3941,$05c514941,$0807d6f65,
$075717477,$062676671,$060596060,$05557575b,$059585855,$05754565a,$0525a5c53,$064645850,
$058525557,$056505757,$0595b5958,$0575a5f58,$05153585a,$059565659,$052555257,$056574f4b,
$04e515550,$054505254,$055515857,$057585353,$04f514e52,$0776a5353,$04c607c78,$051535c56,
$0545a544e,$059565259,$053515456,$0827c5f55,$05b595a78,$0807d725f,$05d5d4f6d,$058545877,
$05b7b796b,$075755854,$07379655b,$0677a655c,$07b6e5550,$054566d7a,$055555757,$056545352,
$053555355,$04f515150,$04a46484b,$06c656257,$0807f7c77,$074808382,$081796e6a,$06a6c7881,
$0817e776d,$082828383,$081818181,$081828181,$06f767e81,$07f7e7972,$081817f7f,$07f828180,
$03b3b3b3b,$0423f3d3c,$048464644,$03f454c4d,$0564c423e,$06c695d56,$045505d66,$042424142,
$042424242,$048464544,$0514e4d4b,$059575553,$0655f5d5a,$082807e74,$07e858484,$066666669,
$063636365,$064646463,$065646464,$0906e6867,$053678f9d,$038373843,$04e46413b,$06f6c6056,
$06061636a,$0585b5d5e,$057555658,$05656565a,$05a5b5757,$054535257,$04f535a55,$059545350,
$05c5d5d54,$058555255,$052545761,$04e505153,$050575a52,$0525a675d,$05851545a,$04a555459,
$04c555455,$054565154,$054504d53,$050564e53,$062756c5b,$07e79625b,$04b6f8380,$04d53534c,
$057585b56,$04f4b5051,$058545353,$0774f5256,$058565074,$06b707552,$056595f78,$076707379,
$05961797e,$07979585c,$07b767b78,$0727c5b6d,$074575158,$04d577178,$054535353,$04f4f4e4c,
$056575550,$04f4f5153,$04846494e,$06a646054,$0817f7c75,$077828482,$07f776c6c,$06a6e7a81,
$0807c756c,$080818181,$080807f80,$081818181,$070787f81,$07f7d7971,$081818080,$080828180,
$03c3b3b3b,$03e3e3d3c,$04c46433f,$0474d5353,$051494142,$06a655952,$04a5a6267,$043434345,
$043424243,$04a484745,$0524f4d4c,$059575554,$062605d5c,$0817f7b69,$081868483,$06868696c,
$062636365,$064646261,$066646564,$08a6c6867,$0556c949d,$038373745,$0463f3c38,$0605b544d,
$05a5c5762,$0565a5c5a,$05a595456,$054545556,$054595655,$056575355,$0545c5856,$04c525454,
$05b565b56,$0534b4e5a,$053524f56,$05953514c,$058555f50,$053565959,$04f535253,$0525a5552,
$059575956,$055534f52,$05e4c5358,$04d64746d,$06d838273,$07c725050,$05a7b8183,$05e62544f,
$0545b5b55,$04b525351,$0524e5653,$06e505a4c,$057555876,$0546a775a,$052577675,$0686e7976,
$0554b5864,$0757a5653,$07160636c,$077756177,$060555e60,$04f577576,$054544f52,$050535254,
$057585154,$04c4e5251,$04647494d,$068645f51,$0817f7c74,$07a838382,$07d746b6d,$06a707b80,
$07d7a726b,$0807f7f7f,$080808080,$081808080,$0717a8182,$07f7d7770,$081818180,$080828181,
$03c3c3c3c,$03d3e3d3c,$04d443e3d,$052585c57,$04a46454a,$06962564d,$054636669,$044444547,
$045434344,$04b494846,$0514f4e4c,$059575553,$064615e5c,$0807f7a68,$086868481,$06f757577,
$063646569,$064636262,$067666564,$0836b6867,$05f77999c,$037383948,$0423e3a38,$05a54504b,
$05a5b5859,$058555a60,$05455565c,$05354544f,$054565354,$04c535759,$0535b5b55,$05b5a5657,
$05956555d,$05650545a,$0594e4f54,$0584f5752,$058524f56,$056505756,$05b5b5155,$054575d4f,
$0605a544d,$067685a55,$06c4d4d5b,$048668285,$06d84826a,$083725053,$0657b8085,$054555358,
$051564d51,$04d4b4b58,$056585954,$064555958,$04c505c7b,$053617a5b,$050647b65,$05553756b,
$0584e504f,$0627c6452,$062585451,$07472747a,$055575954,$0505b635c,$057595251,$050525455,
$054535355,$04d505653,$045464b4b,$067655e4f,$082807c72,$07c838382,$07a716a6f,$06a717c7f,
$07c786f69,$0807f7e7e,$080808080,$082818080,$0737d8282,$07f7c7670,$081808080,$081828181,
$03c3c3c3c,$03d3e3e3d,$04b413e3e,$05c636459,$046444751,$0675d514a,$05b646568,$04545464a,
$045454545,$04c4a4947,$052504f4d,$05a585654,$06764615e,$081807869,$08f888582,$08d959693,
$064666a7c,$063636363,$067666564,$07c6c6a67,$05f7e9b9a,$037373d49,$0413c3b39,$0564d4b46,
$05859575a,$057565753,$04d555354,$051535050,$057545654,$05d585657,$058595a54,$055554f52,
$05153515b,$05555514f,$058565556,$05b524f52,$05e565566,$05654515a,$05e55564e,$053585b54,
$0505b5158,$08083806b,$05f55577b,$04a767f80,$0757e805d,$07f705454,$0747d7c77,$05a62505b,
$04c58555b,$04e4d5155,$053555755,$0584e5f63,$04a4e6c7b,$071728061,$0637b7e77,$056677e65,
$05252514e,$0637a6a52,$053525755,$0615a686a,$04e4f5356,$051565554,$05958514f,$04e4e5358,
$050555752,$050505154,$0474b5150,$066665d4c,$0817f7b70,$07d828182,$0786f6a71,$06b737d7e,
$07b766d68,$0807f7f7e,$080808080,$082828180,$0757e8282,$07e7b746f,$080808080,$081828180,
$03d3c3c3b,$03e3e3e3e,$0483f3f3e,$060676356,$043424853,$061584e49,$059606163,$04746464b,
$047464546,$04d4c4b49,$05352504f,$05c595754,$079736a61,$081827f77,$09c8e8683,$09d9f9f9f,
$065677694,$064636363,$067676665,$0756c6a68,$05d849d96,$038383e4c,$03d3b3a3a,$0564e4942,
$059595859,$05b5e5758,$053525053,$050525154,$05553514d,$0655c5856,$0524f5055,$04e505650,
$04f555556,$05553554e,$052555c58,$05259555c,$05f56574f,$056534e54,$050555150,$07d7a6b58,
$05a587087,$07f807c76,$05a565f7d,$05d7a837d,$07d807a5a,$080755654,$081876b78,$05351565d,
$050565957,$0504c5056,$057585b62,$0535c515b,$056506e77,$078777c62,$075806d73,$052687d5c,
$050505754,$057726454,$0564e5152,$059555657,$0524e505a,$054595356,$0534e4e50,$04d4d4f53,
$04f50514e,$055514e4e,$045495654,$065655b4a,$07f7d786c,$07f828080,$0766c6a73,$06c767e7e,
$07b746b68,$0807f7f7d,$080808080,$081818180,$0777f8282,$07d79726f,$08080807f,$081818180,
$03d3c3c3b,$03e3e3e3e,$0483f3e3e,$05c5d5852,$044434b54,$05a534b48,$0575b5c5c,$04746464c,
$049474647,$04f4d4c4a,$055545351,$05f5a5756,$095928870,$083858a91,$0a0978884,$0a0a19e9e,
$06569819c,$064636364,$068676766,$06f6c6a6a,$068909e92,$037374456,$03e393939,$0524a4642,
$053555a56,$055575654,$05456544f,$05155554f,$055544f57,$0504f5354,$052555851,$063545d59,
$05651545c,$056525358,$052505252,$04f5a5852,$059555650,$05e515456,$0607a766e,$08481764e,
$053547980,$07e7b826c,$053506b7f,$0577b8276,$08184724f,$080754f5f,$0807e617a,$0514e516e,
$050555557,$04f4d534c,$04e514e4e,$05459574f,$056537774,$0575b796d,$07e685054,$0506b746a,
$055505557,$050555c52,$057505354,$05a595d59,$057565556,$053565661,$04c4b4b4e,$04d535150,
$050544f4c,$05c575152,$0444c5357,$064635546,$07e7b7469,$080817f7f,$0746b6b76,$06d797f7d,
$07b736a68,$080807f7e,$080808080,$081818080,$079818282,$07c777070,$080807f7e,$081818180,
$03e3d3c3c,$03f3f3e3e,$0493f3e3f,$05b5d5a55,$046465359,$0544f4b4a,$0575a5a57,$04746464d,
$04a484747,$053504e4c,$0585a5d58,$0615b5958,$09b9c9780,$082817b91,$0a0988883,$0a1a2979a,
$0666a889e,$064636263,$069686866,$06e6c6b6a,$070969d8d,$03737495c,$03e3a3837,$050494542,
$0595c5c58,$050545559,$0535b574f,$04e4e5358,$057595050,$05c515254,$04e595558,$05751534d,
$057555b53,$05450515d,$059525254,$059524d54,$06d676161,$0714c4e5e,$06d7e7d7e,$0857f7351,
$051507f82,$084868373,$04f597b80,$06c7d816a,$083857c76,$081795365,$080775c7b,$055554e79,
$055565258,$0534c5053,$064535251,$0545b526b,$04e5a7e72,$04e587b75,$07550524f,$04e5c616e,
$057545c53,$058555a4e,$058545058,$04e545451,$052585452,$053525050,$04e4c5059,$05653584e,
$052535253,$053505256,$0464a4d52,$0645f5147,$07d7a7166,$08181807f,$072696c78,$0707c817d,
$07a706869,$08080807e,$080808081,$081818080,$07a818282,$07c766f71,$080807f7e,$081818180,
$03e3d3c3c,$03f3f3f3e,$04b403f3f,$0595f5f59,$047485357,$052514e4b,$058595853,$04747464d,
$04c4a4847,$06257514e,$072777c71,$0625d5d66,$0979e9982,$0837f7481,$0a0958683,$0a2a29fa0,
$0676d8d9f,$065656564,$06b696766,$06c6c6c6b,$073989a81,$03638475c,$03c393737,$04f49433e,
$059595957,$05453605c,$054565655,$051525455,$04f4f5253,$058555451,$0515d5854,$04d575852,
$058555751,$04f545252,$058545d50,$0585f685b,$07f7f7d79,$06a564c6f,$07c817d7f,$081847256,
$0526a807c,$0727f7f6a,$052667e7b,$0847d8065,$07d7c7e82,$082734f6d,$08274637d,$05b5b5d77,
$054555553,$0514f5354,$068515355,$05d506682,$05b5d7a7c,$0555b7a74,$0564e5154,$056605257,
$0534c4e4f,$05054534f,$059594d4c,$0575b5c50,$04e514f4e,$05552524c,$0504b5054,$055525a54,
$05352575a,$052525354,$046494e52,$0635c4c44,$07e796f65,$08282807f,$071696f7b,$0727f827c,
$0786e6869,$080807f7e,$07f7f8080,$081818080,$07c818281,$07a746e72,$080807f7e,$081818181,
$03e3d3d3d,$03f3f403f,$0473f3f3f,$053565653,$04a4e5555,$05253514d,$057585651,$04848484c,
$04d4b4a48,$07d675650,$088888786,$0625e6881,$09c9f997e,$085868993,$09e908784,$0a1a2a2a2,
$0677293a0,$066656564,$06b6a6867,$06d6d6c6b,$075979072,$036394859,$03c393836,$04b49443f,
$056525a54,$0584e5657,$05152515d,$058525353,$056535455,$056515051,$04f5b514e,$04d575750,
$057564f4e,$067565454,$055535969,$057758075,$0807e817c,$0634f5379,$07e797b7f,$0837b6d68,
$04f667e84,$05f7a8266,$060737e78,$0807f7c60,$081827d80,$0826d5279,$07c80807d,$05250697d,
$061505353,$04c545456,$057534c52,$0807e7c79,$0545b677b,$056585f5a,$055555255,$051535751,
$051495454,$04d515156,$054535152,$04e515851,$051565a51,$05951514e,$04e4d4b4f,$0514e5253,
$051525d56,$051575554,$0484e5050,$063584a45,$07d796d64,$08382807f,$06e6a727e,$0757f807a,
$0776c686a,$080807f7d,$07f7f8080,$08181807f,$07d818180,$079736e74,$081807f7d,$081818181,
$03e3e3e3d,$04040403f,$0433e3f3f,$056504d4b,$053565a5c,$0575a5654,$05a5a5854,$04a4b4c52,
$0504d4c4a,$082785c54,$07c73727a,$0615e7083,$09e9d9779,$08e989b9d,$09d8d8688,$09e9c9ea1,
$069809a9f,$067656565,$06c6b6a68,$06d6d6d6d,$07895856e,$0363b4c58,$03a373636,$04a48413f,
$054555653,$055545350,$054555256,$050535357,$055555955,$0595b5959,$052555658,$0504f5651,
$04f52524e,$07c62584e,$05554787b,$057737f78,$07d7e817a,$05b506684,$08688817c,$07a846e71,
$04c6d837f,$062828165,$05d7c8076,$07c81794c,$07e7c5f64,$08365527b,$07b807b82,$0595b797b,
$056505151,$05151544d,$052545552,$06d786e55,$050565864,$04e4f5258,$053525153,$04d585b4f,
$057545553,$050545757,$05a4f5856,$0534e5256,$05552514f,$0574f5054,$050555255,$050525454,
$04f525754,$04e535250,$04a525551,$062554946,$07d776b64,$08382807e,$06c6b7580,$0777f7e76,
$0756b686b,$080807f7d,$07f7f7f7f,$080808080,$07e818080,$079726e76,$081807f7e,$081818181,
$03f3f3e3d,$041413f3f,$0403f3f40,$065564d47,$05c59626c,$05f666260,$05e5c5a59,$04e51565c,
$0514f4e4d,$07a7f6456,$0615c5c63,$0605d646a,$095958f71,$0999a9795,$09e918791,$08783929e,
$073919e97,$068676667,$06e6e6b69,$06d6e6f6e,$07a917c6d,$0333e4d57,$039353636,$04a47403d,
$054535c51,$054545652,$051595552,$0534f5753,$05357534f,$05c5c5557,$04d535658,$053565452,
$051544f50,$0795d5a56,$0586b7a7e,$057697f7f,$079767e77,$052576e82,$07f7e7c74,$072817478,
$0556f8178,$05e7f8162,$06681836e,$07e817259,$07f745362,$07f6d6280,$072667385,$05d708280,
$055524a54,$050525857,$057595850,$04d595a5b,$04e4e5658,$0544f5554,$04f51535c,$04f52504c,
$052545252,$050525151,$05a505555,$04e51565b,$053535654,$05a535252,$0555d5453,$053505257,
$054515455,$04f515655,$04b545751,$061544746,$07c756864,$08281807f,$06a6b7780,$0797f7c74,
$07369686c,$0807f7f7c,$07f7f7f7f,$08080807f,$080818181,$077707078,$080807f7d,$081818181,
$03f3f3e3d,$042414140,$03f3f4041,$074604e44,$05e5b6676,$0686e6d68,$05f606063,$0575c5e5f,
$053515153,$07c846957,$05a595a5f,$05e5b5c5b,$0767a7765,$09a8f7d75,$09e918a99,$075778d9b,
$07f9a9e90,$06a696869,$06f6f6d6b,$06e6e6f70,$07b8c736c,$03441515a,$038383735,$04b423e3b,
$05550504e,$055525357,$05157544e,$05958595b,$04e56575b,$0505d5d64,$052585353,$0535b605c,
$053525852,$060575558,$063798079,$050627a7d,$06f727e6f,$04d5c797e,$07b737b73,$073828082,
$05d7d7f78,$072807c60,$07883867c,$07f827162,$080745a67,$07f6b6d81,$05b4e6082,$05878817b,
$04e53574d,$0575c5c53,$05f585a58,$04d565f63,$057545454,$0565b5552,$04f4d5155,$04d505b5a,
$055545152,$056625854,$0594d4d53,$04f585452,$054585250,$058585a53,$04e585750,$054555653,
$051525453,$05251514e,$04b505051,$060514446,$07b736664,$08180807f,$0696c7981,$07b807b71,
$07069686f,$07f7f7e79,$07f7f7f7f,$080808080,$081818181,$07670727b,$080807f7c,$081818181,
$0403f3e3d,$042424141,$040414142,$071604b42,$067616571,$06c717471,$061636165,$063646361,
$05655575d,$080876d59,$059585a62,$05d5b5b5a,$065656360,$092776b66,$09d8e8e9b,$0847e909c,
$080999f9a,$06b6a696a,$0706f6e6c,$06e6f6f70,$07d876f6c,$036454e5b,$0383b3934,$047433f3c,
$05355584c,$0564f5057,$054525458,$055524e52,$04d545254,$0555d5a50,$04f5b5a52,$051505959,
$059535f5a,$04d554f5b,$06e797b71,$054638279,$06c777d72,$04b657f7f,$0727d7d6a,$072818381,
$05c7d7d74,$080808262,$07f7f857f,$07b7f615d,$081694d62,$081696e82,$0595a657d,$05b7c8274,
$0555c5351,$05b54534f,$05260525d,$053525556,$05b555152,$0524f4d4d,$052505357,$050565354,
$04e504e4e,$05f5c5754,$053515458,$055524f59,$050505053,$063595352,$050515658,$051565752,
$05655514e,$054555051,$04e4e4e52,$05e4d4447,$07a6f6565,$0807f7e7e,$0686e7a81,$07e80796f,
$06e696a72,$07f7e7d77,$07f7f7f7f,$081808080,$081818181,$0756f737c,$080807f7c,$081818181,
$0413f3f3e,$043434241,$041414242,$05e504542,$071696263,$06a6f7375,$05d57555e,$068666461,
$05c5f6668,$0848a715d,$05b5a5c67,$05d5d5c5c,$06564625f,$094796b67,$099898c9b,$09a959b9f,
$075919d9e,$06d6c6a6c,$07171706e,$06e6f6f70,$07b816b6b,$0394d535c,$037353534,$049443f3b,
$055534f4c,$05a525158,$05357525d,$0564e5053,$04d555357,$0555f5651,$051575551,$052544d4d,
$05b585557,$058585d58,$0807f7c5f,$051627f7d,$05a78786e,$050787c7a,$06c7d7a5f,$06d817f81,
$0697e7f6d,$08084795d,$078817773,$07a7f5a6b,$082624d77,$07f6e7984,$05a535e77,$0535a635d,
$04e545d58,$050564d50,$04b4f595f,$052505454,$059515559,$058534951,$055525450,$05555524f,
$056555651,$065565156,$0534e525f,$052535053,$056565d56,$079725256,$04f565a63,$04e57544d,
$05c514f4b,$05453525a,$04e4f5153,$05c4a4447,$0776d6566,$07f7e7d7c,$069707c81,$07f7f796d,
$06c696a75,$07f7e7c75,$07f7f8080,$08181807f,$081818181,$0736e747d,$080807e7a,$081808080,
$0413f3f3e,$044444342,$043434444,$04b464443,$06b615952,$05a61686c,$0544f4c4f,$06b67635d,
$0686d6d6c,$089897064,$05f5e616e,$060616260,$06d716961,$09b8e766d,$08d858998,$09c9c9d99,
$0707c929a,$06f6e6c6e,$07071716f,$06e6f6f70,$07779676a,$03c51555c,$037373534,$049483f3a,
$05551504e,$056555354,$054575353,$0534f5354,$053555c53,$055545659,$05352595d,$050545a53,
$05a575652,$05b5b524f,$07d7e704f,$05b657e7d,$056787d6f,$05d7b7a70,$0677f7b63,$074827d75,
$06d838067,$07182815d,$0827e5a51,$0807b597c,$07c5b5a7b,$06657757e,$04c53515c,$0594c4e57,
$053565d57,$053564e53,$0544f5950,$051575757,$05a5e6155,$05a4f5052,$059545751,$04f5b5251,
$056565552,$0575b5351,$0594f4d52,$04b545552,$056707659,$076775b54,$0555c566b,$051555755,
$05554534f,$052565555,$04b515754,$058464548,$0756a6465,$0807f7d7c,$069737f81,$0807e776b,
$06a676b77,$07f7e7b73,$07f808080,$08181807f,$080818181,$0716e767e,$0807f7d78,$081808080,
$041403f3f,$046454443,$045454646,$044444444,$0514c4745,$0494b4f53,$0504f4c4a,$06a655c53,
$07472706e,$08f846d70,$06665697f,$064737f74,$08a8d7764,$099999289,$08583858e,$0878f8f89,
$06f717681,$06f6f6e6e,$06f707070,$06c6d6f70,$079766669,$03f51545b,$037343333,$043443f39,
$04f52534a,$057515653,$055585a56,$050545257,$050565855,$056545154,$056535460,$054575553,
$0554c5250,$058535a57,$07f7c5c51,$0585c7c7a,$0707a7f71,$0747e7b7b,$072807655,$07a878067,
$077817f5c,$071818261,$081775450,$07c716681,$058504e68,$0545d5a5a,$04f57594a,$053505755,
$05050544c,$054515253,$04f504d50,$05855585a,$053595c55,$04f4f5558,$051575c52,$0514e5855,
$053565861,$0545b504e,$04d4f4e4a,$0514f514f,$06a787b60,$07c7d6454,$054585170,$0584f5155,
$05559555a,$056585352,$04f525d55,$05246454a,$073686563,$0807f7d7b,$06a768081,$07f7c736a,
$069676d79,$07f7e7a71,$080808080,$081818080,$080818181,$06f6f787e,$07f7f7c76,$08180807f,
$043424140,$047464544,$046474847,$044444546,$045444343,$049474545,$0504e4c4b,$064595250,
$07874716c,$0907b6f79,$07e75818f,$0657e918e,$0968d7365,$08b959897,$083828486,$072868784,
$06f706f6c,$06f6f6e6e,$06f70706f,$06b6d6f6f,$07c736568,$041505261,$037343335,$0413f3e39,
$052574f46,$053545958,$056535659,$055575252,$055545e62,$056525258,$057595459,$05256574e,
$05151545a,$059515254,$07c6d525b,$054587b7f,$07e7c7c6e,$07c7c7c78,$07b826d50,$07384805f,
$07c817c53,$06e818060,$071615652,$057545e6e,$05754544e,$0595b4f62,$054515156,$051555759,
$04b4f5751,$057566151,$04f4d4b52,$053575757,$05a4d4d56,$04d5a5d57,$05151514a,$055545956,
$0645a5361,$0554f5c66,$0504d5156,$0574e5152,$07a7c7658,$07b786d66,$052505b76,$054504f51,
$054525054,$057555351,$056535558,$05044464b,$071666662,$07f7f7d7a,$06d788081,$0807a7069,
$068686f7b,$07f7d786f,$080818180,$081818180,$081818181,$06e70797f,$0807e7c75,$081818080,
$043434241,$048474645,$047484948,$044454647,$044444343,$049484745,$04f4e4d4b,$05853504f,
$078746e63,$0866f727a,$094919391,$064779095,$084786863,$06f798286,$08282827c,$074888885,
$06f6e6d6b,$06f6e6e6e,$06f6f706f,$0696c6e6f,$07d6f6566,$044515567,$035343236,$0423f3d3a,
$05555544c,$056575858,$05b5b5754,$053525557,$05752525a,$04c4e4e53,$05053524f,$05357504c,
$04f50585c,$056524d4f,$0775c5057,$0525c7c7b,$079807b6f,$0807e7c73,$0807e6b66,$06c767360,
$080847c52,$068707a69,$04b485056,$0575e5151,$0555c5c4c,$05356545a,$0555c4b52,$0525c5c53,
$04f585752,$0555b524e,$054524d53,$0534c5457,$056515358,$0535a474c,$04e4d5151,$05457524f,
$0807c6755,$0556c777e,$054555259,$056515359,$0787d6f52,$072737c7d,$051575c7b,$04d4e4e57,
$04e54594e,$056555353,$051515354,$04e44474c,$06e65665f,$07f7d7d79,$06f7a8080,$07f796e69,
$06869727d,$07f7c766d,$080818180,$08180807f,$081818181,$06e727b81,$0817f7b74,$081818181,
$044434343,$049484746,$049494949,$045464749,$045444444,$049484745,$0504f4e4c,$054514f50,
$078736659,$07068757a,$08f918e81,$063697c89,$06a676462,$06868686a,$083838277,$07a888785,
$06e6d6c6b,$06f6e6e6e,$06e6f6f6f,$06a6b6c6e,$07e756969,$04754576c,$035333238,$03f3f3d39,
$059534e45,$058525757,$053545f59,$052515251,$0505d5b57,$04f4e5753,$04f525757,$055545651,
$05459595a,$052535550,$06e584d51,$05266817a,$061807f70,$07c83685a,$0847f6671,$052565368,
$067736856,$050565053,$05650534d,$05d5c4f59,$056594e4a,$0525a4e5c,$05c59564e,$04d5c5d58,
$055534f4f,$04f545253,$0535b5653,$053564f56,$055505056,$0565a5453,$06c665450,$056515168,
$0687c7e62,$06b7f7166,$051585656,$05155534f,$0697c694e,$06c677a74,$04d55607b,$050525156,
$05153544e,$054575551,$053524f52,$04b44474e,$06d66675d,$07f7c7b78,$0717d8080,$07e776c69,
$06769747d,$07f7c756b,$080818180,$080808080,$081818181,$06e747e82,$0817f7a72,$081818181,
$046454444,$04a484747,$04a4a4a4a,$046464849,$045454645,$049474646,$050514e4c,$054525050,
$079736158,$06467787b,$073787469,$06263666c,$0726b6462,$06666666a,$084838171,$07e898785,
$06e6e6d6b,$06e6e6e6e,$06d6e6e6e,$06b6b6d6d,$07c70766a,$04a585770,$03633323c,$0413f3a38,
$05a504b45,$054515762,$055545353,$053524f52,$052565a5e,$059585152,$0514e5458,$05e535352,
$050565e5d,$05c4f5157,$067535659,$04c6d817d,$05f7c8172,$07e77544b,$07b79687c,$0534e4a5a,
$057515552,$056555853,$054505a54,$0524f4d56,$05050595e,$0595c5252,$05a525757,$0554e4c5b,
$05a594e5d,$05957515a,$0555a5958,$057585256,$0554b4a50,$058554f4f,$082827657,$05d647a80,
$04d628075,$07c7c5c56,$0504d5059,$06b636257,$06a7d6971,$0675f685b,$04c4f657b,$052585651,
$051544f4e,$056585551,$056525357,$04a454950,$06b676a5b,$07f7d7b75,$0747e8080,$07c736a6a,
$0676b767e,$07f7b7369,$080818180,$080808180,$082818281,$06e777f82,$0807d7871,$082828281,
$047464646,$049494848,$04a4a4a4a,$04747494a,$046464646,$04a474646,$051514f4c,$056535252,
$079715f5a,$0626b7a7b,$064646463,$063636364,$08b7c6663,$066666874,$08482816e,$083878786,
$06d6e6d6e,$06e6e6e6e,$06d6d6d6d,$06b6b6c6c,$077677b72,$04b555974,$03734333d,$0423f3938,
$053524c47,$0515a5c54,$052555553,$058595654,$04e555c5a,$055555555,$04f544f53,$057575351,
$0545f6054,$06256514a,$063525252,$051787e7a,$0627f7b6a,$0725f514f,$0525a566c,$05d5a5652,
$05d605254,$04c545759,$0555d555c,$05b5c4f4f,$04f4f5b5a,$055525854,$0564d4d55,$051515354,
$054595b54,$0534e575a,$050515a5b,$0524c5850,$071756c5e,$04c535463,$06870846d,$04f72786a,
$04f56726f,$07e795b53,$0766b5e64,$07e7c7c7c,$06e79657e,$068585251,$054586e7b,$05656574f,
$04f514e51,$05652504f,$05052575c,$04a474c4d,$0696a7564,$0807f7b73,$0767f8080,$07b71696b,
$0676e797f,$07f7a7168,$081818180,$081818181,$082828281,$070798082,$07f7c766f,$081818180,
$048474747,$04a4a4949,$04b4b4b4b,$048484a4b,$046474747,$04b494746,$052514f4d,$059565352,
$0786f5f5b,$0636f7b7c,$064636363,$063636464,$094836964,$068686c83,$083817c6b,$086878684,
$06d6e6c72,$06e6e6d6d,$06d6d6d6d,$06f6d6d6c,$06d667380,$04d525e75,$035333441,$0413c3937,
$04f504743,$04f585751,$053565650,$052575859,$054545655,$0514f5853,$050515354,$05a505159,
$056565355,$04a4d4e54,$05c53574f,$0657a7b78,$05a737c6d,$05351555a,$055595054,$058595253,
$051525158,$05c504e4f,$0595b5661,$0584a5055,$04d514e4f,$05a4b564e,$05b585657,$04d535951,
$0505b524c,$04b485256,$075645751,$05c4b5970,$07f7a8180,$052527382,$0584f7275,$04c505156,
$0515a5853,$0757d6a4e,$07d82735c,$0616b707c,$07775595d,$05a50525a,$0525a7476,$0534d5052,
$052515758,$05a585752,$05a525258,$04e494f51,$0686f8479,$0807e7b71,$079808181,$07970696d,
$0686f7b7f,$07f796f67,$082828281,$082828282,$082828282,$0727b8182,$07e7b746e,$08181807f,
$04a494949,$04c4b4b4a,$04c4c4c4c,$0494a4b4c,$048484849,$04c4a4848,$052504f4d,$05a585554,
$0796d5f5d,$065747e7c,$066666565,$065656565,$098846b66,$06a6a7591,$082807a6a,$088878483,
$06d6d6b76,$06d6d6d6e,$06c6d6d6d,$07d6e6d6c,$067677181,$053566475,$033313543,$03f3a3634,
$04e4b4343,$0575a5b51,$053535555,$054536364,$052525357,$0584e504d,$051505557,$053565353,
$04c525254,$054545f59,$05a566157,$05b6b7670,$058575f55,$0524b5758,$04f504f4e,$0515b514d,
$0504b5457,$053615d51,$056655c50,$04f4f5751,$0534e5750,$0564a5154,$0555c5852,$04e514c50,
$04d4b4e4a,$06f575e5d,$084888074,$0784d6681,$05c526680,$05469826f,$06b596a7c,$05655686f,
$055525957,$05e77826d,$05b625753,$057515a5e,$07a6e585a,$052515961,$0575b7673,$0504e5055,
$0554f5355,$056555352,$05b575457,$04a474b53,$067758a7b,$0807d786e,$07c818081,$0786e686f,
$068727d7f,$07f786d67,$083838382,$082828282,$082828282,$0747e8282,$07d79736e,$081807f7f,
$04c4c4b4b,$04d4c4c4c,$04d4e4d4d,$04b4c4d4d,$04a4a4b4b,$04d4b4949,$05351504f,$05c5a5856,
$0796b615e,$06a787f7e,$06c6a6968,$06665696c,$09a836c68,$06a6c8299,$08280776a,$086858383,
$06e6d6c7b,$06d6e6d6e,$06b6c6e6d,$087766e6c,$0646a757d,$051576976,$033323743,$03e393534,
$0504a4542,$056595a57,$059575550,$058575357,$050535352,$05b575051,$052565a55,$05b5a5754,
$053575453,$057575956,$05151565b,$04f50504e,$0565b5651,$056535155,$04f545152,$0534e4f51,
$04b526052,$04d4f5750,$05c524f4c,$0544e5b61,$0635e585f,$04951544f,$053534850,$0494a4b54,
$06c4d5257,$0847e5f67,$0696d717a,$080584f5c,$055544f6f,$058737c55,$07f7c7680,$063787a76,
$072525659,$05f63727c,$0544f4a4f,$05c565951,$07d664d50,$04e52505e,$0565a6d66,$052534f4f,
$052555551,$055525353,$058595351,$048484b53,$067788871,$07f7c766b,$07d818180,$0776c6972,
$06a757e7f,$07f776b67,$083838382,$082828282,$082828282,$0767f8282,$07d78726e,$0807f7f7e,
$04e4e4d4d,$04e4e4e4f,$04f4f4e4e,$04d4e4e4e,$04d4d4d4d,$04f4d4c4c,$055535250,$05f5d5b58,
$07b6b6461,$075828380,$086837e75,$0686c7d84,$0987e6b6a,$06b6e8a9b,$08280736a,$085858483,
$06e6e6d7f,$06d6d6d6e,$06b6b6c6c,$08585706d,$05c6d797f,$052596f77,$032313947,$03f3a3533,
$0534a4745,$04e515959,$0595b5450,$04e525959,$04f57544e,$05a554e50,$057535354,$04e4c5054,
$052575855,$0595b5654,$054575658,$04e504c53,$0544f5354,$050524e54,$05e4e5156,$056545754,
$04c495255,$053565f5b,$07c57535b,$052555c82,$058505d5e,$0595a4e4a,$05d554d54,$050665b56,
$0815c5152,$0737b5574,$04e514f55,$06a535257,$053525260,$0566e8165,$0647c8177,$07871564c,
$080694c5f,$05b5c506a,$058524c50,$05253515a,$07562524d,$04d53515c,$053555952,$052534f50,
$056575554,$052565655,$0545c5957,$048494d4f,$06771745c,$07f7b7469,$07f818180,$0766b6b75,
$06d79817f,$07d756a68,$082838281,$082828182,$082828282,$0777f8181,$07c77706e,$07f7f7f7e,
$053535251,$04f505152,$051515050,$050515151,$050504f50,$0514f4f4f,$058565553,$063615e5b,
$0836f6865,$0888c8a89,$09397958e,$06975868c,$094776c6b,$06c728f9c,$0827f6e6b,$085848483,
$06c6d6f80,$06c6c6d6d,$06c6b6b6c,$082867c6d,$056677c82,$0535d7574,$033323d4a,$0403a3534,
$0524a4845,$055585d56,$0585a5656,$050505356,$053555152,$051514f4f,$055585654,$057515058,
$055555151,$04f55514d,$05053574d,$0514e5156,$05b4b5052,$05452515d,$0504d4c4e,$05854575c,
$051595e57,$04e545b56,$07e6b5556,$0494d5d7f,$055515258,$056504f53,$07c5d5556,$06c836b60,
$0846f5950,$075724d75,$04e505553,$0534d585d,$0654d5466,$051587d81,$0536a806b,$07d624c56,
$0787b5462,$05e5b4f58,$0564f525e,$055535862,$05a5b5756,$051504e55,$053525356,$052535654,
$057575356,$053565553,$055575550,$04c4c4f54,$067675b4e,$07f7a7167,$082828281,$074696d79,
$06f7c827e,$07a716968,$08182817f,$082818181,$080828282,$0797f8180,$07b766f70,$07f7f7f7d,
$063635f5b,$052545a60,$053535352,$053535353,$054555453,$054535253,$05c595856,$06c6f665f,
$090847a6f,$08887888f,$09497968f,$0697a888f,$090736d6b,$06d79969d,$0807c6d6b,$084838281,
$06c6b7284,$06b6b6b6c,$06d6b6b6b,$082838674,$0575b7a82,$04c607b71,$03433404c,$03c383534,
$04e494342,$053555852,$054575255,$051515551,$04a515356,$055514f57,$056564f52,$0575a4a4d,
$05158514d,$05b5f5a50,$053525153,$056545c4f,$05a525856,$059515558,$05c545a56,$07e71655c,
$07b817d7d,$05d57526f,$07f784d52,$052524e75,$053504f4e,$0516c775f,$07e6e4948,$08381635a,
$0807a5068,$07c605376,$06e5d5760,$0525e596e,$082694e54,$0494d6675,$04d657b58,$07f645556,
$06a816462,$07d786f63,$0584f617f,$055515856,$05256555a,$0544f4e55,$057545551,$053535554,
$052585751,$053525252,$051515655,$049494e53,$066615348,$07f7a7066,$083828180,$070686f7c,
$0727e817b,$0766c6768,$08181807c,$081818181,$080818181,$07b808180,$07a746e72,$080807f7d,
$080817d79,$0565b6b7a,$057575655,$056565757,$0585a5a58,$059585757,$064605e5b,$085877a6b,
$09a989389,$084808593,$093959186,$06b7f8991,$08e726d6a,$06e809a9d,$07f786c6c,$085848482,
$06c6b7685,$06b6a6b6c,$06e6b6b6b,$083848883,$0595a6a82,$04e657c69,$031404a4f,$03a373533,
$04b434241,$053575655,$053525152,$051555856,$04a4f5153,$05a595651,$055555557,$051555452,
$04d4e4f50,$050535659,$04f524f58,$04e565553,$0544e5956,$05c4d5751,$062534e5c,$082878281,
$08383807f,$056576f80,$07f806050,$054564969,$05b585256,$066816d4a,$07082564d,$07c7d5e53,
$0637e6f7f,$07d62697b,$083827c7e,$04b575879,$06d7f6b51,$052565454,$059787256,$079776052,
$07e7e6957,$06970787d,$053566165,$0574f504f,$051524f53,$054524f4b,$04e525553,$05453565a,
$050555454,$053535053,$0544f535b,$0494c4e58,$0655d4e48,$07e796e65,$083828180,$06d68717e,
$0747f8078,$06f69676a,$0807f7c76,$081818080,$080808080,$07c818180,$079726e74,$080807f7d,
$08a8e8f8f,$0595e6e81,$05b5c5b5a,$05a5a5b5b,$06164625d,$06a666260,$07c79756e,$0888a8781,
$09a9a978d,$07f7e8694,$08e908d80,$06d7f868c,$08a706c69,$06e859b9c,$07f746a6c,$085858481,
$06c6b7a85,$06a696a6b,$07b6c6a6a,$084828389,$0595c5d76,$04f69765e,$0313a464d,$03a363533,
$04945423e,$054565353,$052585655,$053575554,$04c4e5252,$05357564d,$057514d55,$04f505a57,
$0565b5251,$04b52514f,$04d535254,$051505255,$05b545c58,$0576c7873,$07e624b5b,$07f7e8382,
$0807f837d,$05c627b7e,$07d81765b,$0504c5052,$0515c5256,$0826d534c,$062806670,$066745f57,
$052778470,$07d536e7d,$06164687d,$05857565a,$0486e7e59,$052524d4f,$07d775655,$05f7b817c,
$064625c56,$056595563,$052525452,$05b55524e,$055544f50,$0544f5255,$057545253,$051525355,
$051565853,$053545659,$053515457,$04b4e5256,$064594c48,$07d776a64,$08281807f,$06b69737e,
$0767f7e77,$06767676b,$07d79746e,$080807f7e,$080808080,$07f818181,$078716e76,$0807f7e7d,
$07d858a8f,$05f606772,$064666461,$05f5d5f62,$07e7f7769,$07e7c7a7a,$081818180,$082828281,
$0999a9689,$07b7e8995,$089867d77,$06f7d8185,$0846f6b68,$06f8a9d9b,$07f71696a,$086848380,
$06a6b8086,$069696a69,$088736a69,$07e838384,$0595b5d62,$0556d6d57,$0323c474e,$039353333,
$044423f3d,$05352514b,$050555150,$052575953,$051555d5b,$04f51544f,$05a5e504e,$04a56555a,
$05654504e,$051575053,$050535553,$051505450,$07b5f585b,$068808180,$082795758,$084848583,
$05c575470,$04f657d77,$0757f805f,$052575b62,$04f53605a,$0635b5b4c,$05372827e,$075714b4d,
$0545c5e4a,$06e537472,$04e4d4c75,$04c5f5854,$04f537e6c,$06d6d665f,$06d595a55,$0535a646f,
$04951554e,$052545c53,$054595651,$051576159,$05358565b,$05a555655,$057535357,$04f4f4f53,
$05f565854,$052555653,$050515352,$04b515255,$062554a46,$07c746764,$081807f7e,$06969757f,
$0787f7d74,$06666676c,$077706b67,$080807e7b,$081818180,$080828281,$076706f78,$07f7f7e7c,
$06b6e767f,$06c686769,$07b7f7a72,$069696e74,$08e918b79,$07e7e8086,$07e7e7e7e,$07f7e7f7e,
$097989488,$07a7d8995,$081766e71,$0717a7b81,$07b6c6a67,$071909d98,$07d6e6a6a,$086858381,
$06a6e8287,$069686969,$087816e6a,$06c828485,$058595c5b,$05c706555,$0333d4853,$037333334,
$04746413c,$059504d4b,$05a585152,$05859585b,$0504e505d,$04f525652,$05c58524f,$05754504f,
$05255544f,$052524e4e,$059565252,$0595c5250,$07f806446,$06483817e,$075816748,$07c826f70,
$058564b54,$05063826f,$0647d8571,$0594c4f5d,$051514c59,$0524e564f,$04964795e,$07d655152,
$04f565154,$06c597e69,$05757557b,$052585250,$07b777c72,$06e777e80,$057555e53,$053585156,
$04e4a4e54,$0555a5652,$04e595854,$051555e52,$04e505357,$04b4d5350,$0514e5050,$04f4e5252,
$054575753,$054515251,$054545553,$04a555353,$061514847,$07b726664,$0807f7f7d,$0686b7780,
$07a7f7b71,$06564676e,$06d686666,$0807f7b74,$081818080,$082828281,$0756f717a,$07f7f7e7b,
$06d65666d,$0847f7a75,$09094928b,$06e6f7885,$091938e7d,$07c7d7f88,$07c7d7d7d,$07d7c7d7c,
$096969185,$0777c8995,$0786b666d,$0757a7b80,$0746b6866,$077959d92,$07e6e6b6b,$085858382,
$068718486,$069696868,$08488796b,$05e778586,$0575a5c5e,$061705d54,$035414752,$035323231,
$04544413b,$053464846,$059505351,$0575a5457,$0545c5453,$0575c554e,$057555153,$05b56574d,
$04d554f52,$058504d52,$059534b51,$050575553,$07c7d846d,$07c7d7f81,$0576a5f5a,$071837856,
$056505551,$059597a7b,$0537b7b76,$058514e50,$054545155,$04c4d5258,$04e6a754c,$081605154,
$04b5c5661,$0655d845f,$052536785,$052545352,$06b6e725d,$053565d61,$0524b4e4e,$05a565c54,
$0594e5257,$05357595c,$04c4c5955,$04d4d5852,$0504f5754,$04e4c5052,$0514f5154,$051535450,
$050525354,$055534f4e,$055565955,$04c505657,$0604f4749,$0796f6565,$0807f7e7c,$0676d7a81,
$07c807a6e,$064646771,$067656564,$07f7d766d,$081818181,$082828181,$0746f737c,$07f7e7d7a,
$078676367,$08d8a8782,$0949a9993,$070707a89,$093938c7c,$07b7c808c,$07b7c7c7b,$07b7a7b7b,
$095948b7f,$0767d8993,$07062616d,$0797b7c7d,$06f6a6666,$07f9a9c8c,$082756d6c,$084838281,
$066748686,$06a676768,$086868872,$060648086,$0585b5d5f,$059635554,$03d483e4b,$036353432,
$03c3e3d3a,$04a41433d,$055524c48,$05654514c,$056525d54,$050555356,$04f4f5155,$056525250,
$050525451,$04d4d4e56,$0584e4d52,$068514f4d,$082838284,$0827d717a,$0534e4e71,$067837e5d,
$078525a55,$05c507481,$0476c8082,$0555a504e,$05e5c5150,$058545651,$0557a6a57,$081605c57,
$04b57546a,$05f698062,$04f566a87,$0534e4c52,$051565055,$052585d51,$051525853,$057595151,
$056525454,$0514d5256,$04a565853,$055585250,$04c535250,$04f4d4f4b,$0534e5150,$057575353,
$04f585753,$056534e50,$059585760,$04f515356,$05d4c4649,$0796d6465,$0807f7e7d,$068707d82,
$07e7f786c,$064646873,$066656565,$07f7c746a,$081818180,$082818181,$0726e757e,$07f7e7c78,
$07868666e,$08d8a8782,$093999892,$073737b88,$093928b7b,$07b7c838f,$07b7b7b7b,$07a7a7a7b,
$09290867b,$0747d8a93,$06c5e5f6d,$07b7b7a79,$06c686569,$0879c9b85,$082817170,$084838381,
$064748486,$06c686766,$084838680,$061606f84,$05a5d5f5f,$03b4b5156,$0494f282f,$034333431,
$037383736,$03e3c3837,$051544b41,$052554f4f,$04f4e5554,$053515452,$04d536252,$054545251,
$051505258,$04e50524d,$0544c4a4b,$07f635554,$073847d84,$0816b5059,$04e535379,$055767f76,
$07f725a5d,$06f4f6a7a,$05665827f,$0565f5856,$055505353,$05c595155,$05a836f56,$07853585b,
$04c4f4d73,$0566e7b5a,$04e515a6a,$053575b4d,$04e4f4c53,$05257504e,$055545459,$053595656,
$0514e4f53,$055575455,$052574b4e,$059574a4b,$04e575249,$05451544d,$04e4e4c51,$05351504c,
$04e535454,$05a525053,$05a575457,$04f535454,$05949464a,$0776a6365,$0807f7e7d,$069737f82,
$07e7e766b,$065666a75,$066666565,$07e7a7168,$08080807f,$081818181,$0716f767f,$07e7d7b77,
$076696f7c,$08b888681,$090949490,$076777c86,$09491887b,$07b7c8590,$07b7b7b7b,$07a7a7b7b,
$0908c837a,$0727b8892,$0685d616d,$07f7d7773,$06a67646e,$0919e9a80,$083857e75,$086858382,
$0646d8185,$0796b6866,$085848286,$06061607b,$05b5e5f5f,$03b4d5157,$03e412d2e,$032323333,
$032323031,$03b393432,$04e46443e,$058565354,$057535455,$053505555,$052575854,$04f5b5353,
$057545054,$04e575350,$05e4b554e,$07b74545e,$054717e7f,$07e6c5056,$06858537b,$0616f7f81,
$07f7d7c74,$07f586472,$04f567b82,$0655b5e5f,$053505f67,$052525358,$0667f5f4a,$06f514d4f,
$050545477,$0575c5750,$05b55514a,$0515f5759,$051556053,$05c565754,$05252534e,$0575e6054,
$04c505c5a,$0655e5951,$0545b4f4d,$050554e4e,$055515151,$052545353,$055554f4e,$052525451,
$057545052,$052504e52,$056595151,$053544f52,$05547484c,$073676363,$0807f7e7c,$06b768081,
$07f7d7369,$066676c78,$066656565,$07c776e67,$0807f7f7d,$081818181,$07070787f,$07e7d7b76,
$0776d798a,$089878580,$0878c8e8c,$0787a7f81,$09591867b,$07b7d8891,$07b7a7a7a,$0797a7a7b,
$0918c817a,$0727e8b91,$06b5e626f,$083817874,$069656373,$0989f9879,$083858882,$085858482,
$066667984,$086726a68,$082868485,$06061616a,$05c5e5e5f,$03f4f5458,$04a3e2c2f,$02f303234,
$02d2c2c2d,$03733312f,$04a443c3b,$0525a5554,$05a555457,$058515252,$054575159,$04d515357,
$053534e52,$05a5c5b50,$05250544e,$07b7d7058,$0534e7780,$0827e5150,$0826e4c71,$0817f7d80,
$0697d8185,$07d6f5354,$07f7f8384,$084857e7e,$0544f567a,$04e525956,$06a805a5a,$059505054,
$05453565a,$05a535457,$06255514e,$05e535557,$0564e5159,$04f525755,$0504e5151,$053595351,
$053575b5f,$05a585351,$058545558,$051524d57,$0544c5156,$050595b56,$04f51544c,$056545252,
$054565352,$051525452,$055595a51,$051534f52,$05146484c,$071646460,$080807f7b,$06d798181,
$07f7c7168,$06868707b,$066666767,$07c756b66,$0807f7e7d,$080818181,$06f727a7f,$07e7d7b75,
$07d7a8493,$089878682,$07d838889,$07b7e7e7b,$0948f837b,$07a7f8a92,$07b7a7a7a,$0797a7a7b,
$0908b807a,$073838d91,$06e60646e,$081807b78,$068646477,$09d9f9473,$082828791,$085848483,
$06866697f,$086816d69,$074878686,$060616260,$05d5f5f60,$04550565a,$05b522631,$02c2e3035,
$02c2b2b2b,$033302e2d,$0483e3c38,$04f515151,$05651545a,$0564e5055,$057535152,$04d525150,
$053575153,$051555659,$050514f4e,$07c7e7b5a,$052525e7c,$0807a6a58,$086754f66,$07c7e7e7b,
$053617278,$07f83704d,$07e817d83,$082837f7f,$04f4d4b6f,$0504a5858,$05d665a54,$05159534b,
$0505d564e,$04d4f494f,$04e56584f,$04f545553,$055504c4e,$051535554,$055544e4d,$055594e55,
$052515254,$052535b57,$058555458,$053525752,$04f4a545d,$05057514f,$053525b53,$051565054,
$052555453,$050515653,$054575751,$04d505250,$04e46474b,$06e64645f,$081807f7a,$06f7b8181,
$07f796f68,$06a6c747e,$067676869,$07b746b68,$07f7f7e7e,$080808080,$06f747c7f,$07f7d7a74,
$083858e98,$084858684,$0777d8183,$07c7f7b76,$0918d8079,$07b818c91,$07a7a7a7a,$079797a7a,
$08e887d79,$074848b8e,$06e62626c,$0827e7773,$06764657a,$09e9e8e6f,$083838693,$082838283,
$069696672,$08588786b,$0647f8887,$061626362,$05f5f6060,$04b52565c,$05b4e2934,$02a2d2d3a,
$02b2a292a,$0312e2c2b,$048403b37,$0564f4a4c,$053535256,$04f515751,$052515158,$04e544d50,
$057525656,$05750575f,$04f5e584e,$07b7c7f65,$04f59536e,$07c7a7a54,$0806d5359,$064727f7f,
$04b515053,$07f828367,$07f81817c,$07981857d,$050545259,$05351514b,$05e525755,$05b535454,
$056544c58,$04d5e544e,$05d535250,$05b4d5152,$059565b58,$0555c524e,$051505152,$04d494c5d,
$05658525b,$056545756,$05054564e,$050575150,$057504e4c,$05253524e,$0595c5152,$06052544e,
$053554e55,$053575659,$053555d54,$04f555652,$04b46494e,$06c63645c,$081807e79,$0727e8181,
$07e766c69,$06e747b80,$0696a6b6c,$07a726a69,$07f7e7e7d,$07f807f7f,$070767d80,$07f7d7973,
$08386909a,$07b7f8283,$0767a7c7a,$078797474,$08e877b75,$07b838d90,$0797a7a7a,$078797979,
$089817978,$07180868b,$071676568,$0837c7570,$06763687e,$09f9c866b,$084838592,$07a838384,
$06b6a6967,$088878572,$0616c8488,$062626564,$060606161,$04c53595d,$062482a38,$02b2d2e44,
$029292829,$02e2c2a2a,$045403832,$053524a46,$057524b52,$055515553,$04f555655,$051524e52,
$058515454,$0575e595d,$04b565f56,$0767e7c6c,$05e545659,$0747a7c66,$083725754,$04f526483,
$0524f4c51,$07a807d71,$07072727a,$0555b6465,$05c595f56,$059505658,$05e574f56,$0584b595c,
$050545453,$049505454,$064574c5b,$04f504e56,$0484f5152,$07e827c61,$057595c6b,$04d515856,
$051515254,$0544f5252,$055525249,$04a514d58,$0534f504e,$050545350,$04e555550,$05a525551,
$050515255,$051565353,$053545b56,$056545557,$048464a51,$06a636356,$081807d77,$0747f8181,
$07c736969,$07a7e8181,$06b707577,$079716a69,$07f7f7e7d,$08080807f,$070787f80,$07f7d7872,
$08386929c,$0757a7f81,$072787974,$074706a6d,$08a827673,$07b848d8e,$078797979,$077777878,
$0837a7676,$069777e84,$07f776964,$07c7a787a,$068636578,$09f997d6b,$084848694,$06b808484,
$0706b6967,$089878880,$065637689,$062636364,$060606161,$04f555a5e,$04d372e3c,$02e2f3343,
$02928292c,$02d2b2a29,$03f3b3833,$0554c453f,$0594f5057,$057504e57,$051575255,$054575453,
$059515356,$0575f5356,$04e505654,$0747a7f74,$062515551,$05c7a7f7b,$08176595a,$0515c5a78,
$050515153,$0626f7f71,$05f61494e,$0555b5755,$050545956,$0504d555d,$0535f5253,$056575658,
$04c525253,$052474a4d,$0574f5659,$056555051,$05b545a6c,$0736d717d,$05c546e7f,$04f525050,
$0534f514e,$0595b5555,$051504852,$0504a4d58,$055515253,$055595750,$0504d4f52,$04c515151,
$05651504f,$055575759,$052525354,$05453524f,$047464850,$067646353,$0817f7c74,$076808181,
$0776d676b,$086878680,$0757c8184,$0786f6a6d,$0807f7e7c,$081818080,$0727a8082,$07f7c7771,
$08388959d,$0767a8082,$070757676,$0706a6367,$0857d7271,$07a848b8b,$076777777,$071727475,
$0726d6f70,$05c646c73,$07d736962,$0696e737c,$06a666263,$09f997f6f,$085858999,$068738485,
$0786d6b69,$088868689,$065676780,$061626263,$060616161,$050565b5e,$02d2d2f42,$02d2f3031,
$027282a2c,$02b2a2928,$03f3c372f,$05a514744,$05752575d,$0554b5057,$050535157,$051525754,
$05a594c52,$0504f4f50,$059525555,$06e7e7d72,$0775e5150,$0526d827d,$07c7b5e50,$05350556a,
$0504e504b,$0524e5254,$0554c5458,$059535a56,$059575257,$050545a55,$0595a5250,$0515d5f52,
$04c504e4e,$050535a54,$05063614c,$05e564e51,$075597083,$05e524b76,$051527b70,$056505454,
$0554e5355,$054504d53,$04f4f4e52,$0554d4d53,$05657544e,$05556514f,$04f4f5251,$04c585151,
$05a564f4c,$05d545352,$053575457,$04f525254,$048484b4e,$066656050,$0807f7c71,$079808080,
$06f67676d,$08988867e,$07e848789,$0766e6c74,$081807f7c,$081818181,$0747c8182,$07f7c7771,
$0848a979e,$07b7d8182,$06d727478,$06d6a6465,$081776f6f,$076818785,$06e707273,$06366696b,
$0575d6361,$0524f5154,$064605d5a,$065636264,$0746e6b68,$0a19e917d,$085858a9b,$06a697c85,
$085726d6a,$085868587,$06465646d,$063636463,$061616162,$051585c5f,$02c2e3246,$02f2b2929,
$0272a2c2d,$02b292828,$0433c382e,$058574948,$055555a58,$04f515252,$05155564f,$054564d50,
$058516257,$053505254,$052565750,$0767c7c6b,$07f7d6060,$0565a737b,$07e785756,$0534f555f,
$0554d5853,$052554e4f,$05459575c,$05853514d,$057594c4b,$057545856,$04b4e5155,$054575d53,
$05251535b,$050555355,$05f83694d,$059565859,$07a59747b,$050535068,$053535857,$057535252,
$051555057,$056574d4c,$05d535253,$050574e52,$050524d4d,$053585553,$04f4f5651,$04d534f50,
$052525452,$05353524c,$057545759,$04c525359,$048494c4d,$06567604e,$07e7e7b6f,$07a7f8080,
$06b66676e,$08e88847b,$07f84898f,$0756d7078,$081807f7b,$081818181,$0767e8181,$07e7b7671,
$0848d999e,$07c7f8080,$06a6d7077,$0696a6866,$0776d6a6c,$06b777d7c,$05a5f6366,$04d505356,
$04c595f55,$0504c4a49,$068645e56,$06e6c6b6a,$0928b7e72,$0a1a19e98,$086858c9b,$06a686c80,
$0887f6e6b,$075868686,$064646463,$063636463,$062616162,$052595d60,$02c2e354b,$02b28292a,
$0292b2c2e,$02b292827,$0413e3830,$051504a46,$0585b5755,$04d50524f,$04f565d55,$05755514e,
$058575b55,$05c5c5b52,$04e4e4d54,$07e7d7c58,$07f7f7f7c,$054515474,$067665955,$05a4d484d,
$054515c5e,$055554d53,$056515651,$051544f53,$057514e58,$057585d4d,$04950544e,$06661595b,
$057525157,$05353757c,$06a816054,$050586159,$078547777,$059555569,$057534f52,$04f515555,
$053505253,$0514d494c,$057535353,$05a524c4f,$05a554a55,$05b555352,$052565953,$052515352,
$053555151,$053544c50,$055545752,$050515153,$0484b5052,$0656b604c,$07e7c776b,$07d808080,
$06d656771,$09a8d847d,$07d82919b,$0736c727a,$081807e7a,$081818080,$0777f8180,$07e7b7573,
$0828f9b9e,$07b7e7c7b,$06b6c7076,$06872706b,$065606369,$056626969,$04a4b4e51,$047474848,
$0494c4f4b,$056504c49,$0716d6860,$0827c7975,$09e9b9187,$09d9f9f9f,$084858996,$06b6a6773,
$08587786d,$0657d8585,$065656565,$063636363,$062616262,$0535a5e60,$02d313c4e,$02728292a,
$02a2b2d2c,$02d2a2827,$0433f3933,$052514e4a,$052525454,$04e565151,$056595457,$05a564d4f,
$0535b5554,$050555a52,$0504a4b4c,$07e7a6750,$0737d7d79,$059565056,$05161544e,$05f584f4d,
$056515253,$0505c5458,$051545757,$04b555557,$053515252,$05a5d544b,$0776d5e5c,$07e847c79,
$0664f5060,$04e6a7e7f,$06d7d5e4b,$0424f5653,$079577a69,$054535573,$05255594f,$051555855,
$052525c51,$05c5b5351,$057575450,$053565b5b,$05151575b,$058525851,$051545152,$059575056,
$055564e52,$05a565052,$054555550,$052545255,$0484a4e51,$0676e5f4c,$07e7c7469,$07f818080,
$06e656975,$09c8e827c,$07b80929d,$0716d757c,$0807f7d79,$080808080,$0797f8180,$07d7a7473,
$07b909b9d,$07c7c776f,$06f6e7378,$068747771,$051535f67,$04a545652,$048474848,$046464747,
$04a494847,$062544d4a,$083807b70,$086868686,$09a998f87,$08d909498,$07b868689,$06c6a6868,
$085868571,$0656c8385,$066666767,$063636364,$061616263,$0555b5e61,$02f344351,$02728292b,
$02a2c2e2b,$0312b2828,$04b463c36,$05657524e,$051555754,$051535556,$050545155,$051535755,
$05d5e585a,$051594f53,$05e585050,$065595b66,$05b61636c,$05352525d,$052574e51,$05654524e,
$05956534e,$04f535056,$04e504e54,$04c55594e,$054555351,$0545b4e50,$07d887f5e,$0626c6c73,
$06252545b,$056788283,$0787a574f,$0736a5854,$078607d7d,$05a555678,$058695559,$04f4a4b53,
$0505b6258,$05b565351,$057555556,$05657575b,$04e4e585a,$053525851,$04e555353,$053504f4f,
$054505154,$056565153,$0565c5652,$052555555,$0474a4d4e,$069705e4a,$07f7c7268,$081818080,
$06d656b77,$093857f7a,$0817e8a95,$0706e7982,$07f7e7d78,$081808080,$07a808181,$07c787475,
$079929b9c,$07c7a7269,$07473777b,$06e737775,$0494f606b,$0474d4e4a,$047474747,$046464646,
$04a484746,$0705f514d,$08686857e,$084858585,$08b8c8785,$085868788,$06d828686,$06e6b6867,
$08485857c,$066647685,$065666666,$064636464,$062626363,$0575c6062,$033384953,$028282a2c,
$02b2d2f2c,$038302929,$0514b413b,$0565c5953,$05a545151,$054555554,$050534f50,$04f4e4e53,
$055555550,$0484d5152,$05c50534e,$050575564,$05254514b,$0544d5455,$054505459,$0505d5953,
$05454534f,$04a524b57,$05455514b,$0505f5051,$050565e4a,$04d505556,$04e767d53,$05a58455b,
$0674f5a62,$06a80647d,$08572524f,$07d848180,$0666c807a,$0544c5c7c,$063816251,$0554f4f5a,
$058585a54,$04d4e5157,$05e575754,$054575455,$0554d4e55,$050595e4e,$050525454,$050504f4d,
$054535251,$054535856,$056585155,$052515154,$0474b5156,$06b6f5949,$07e7a7066,$08181807f,
$069666d7a,$0827f7f77,$08e8e8885,$06e6e7987,$07e7d7c76,$081807f7f,$07c808180,$07c777376,
$07b939997,$07a776d67,$078767779,$078797a7a,$049516471,$046474848,$046464646,$049484746,
$0504f4e4b,$072635753,$08585847e,$084858586,$087868584,$084858586,$067778484,$0776c6a69,
$084848385,$06765667e,$065666666,$064656464,$063646464,$0595e6163,$0353f5054,$0282a2b2e,
$02d2f3434,$03c362d2a,$051504940,$057535854,$050535150,$05654534d,$054534f55,$0545e5250,
$04d55594e,$04f535c50,$04f4d5851,$0585f534f,$056515854,$0524a5b5b,$050535059,$0515e574f,
$050514f50,$054574f52,$0724d5855,$0525b5169,$057505b52,$0594c584e,$05d797a56,$0565a5f5a,
$06c4d5157,$0806e557b,$0866d4e66,$0595d6678,$052747552,$05157737d,$056787153,$0524d5459,
$059564b54,$04f53504e,$05f59564e,$055545153,$055515555,$051525353,$05554514f,$050535051,
$053555854,$052535a51,$053505051,$0574f5156,$0474b5459,$06d6c5647,$07c786e66,$08180807e,
$065666f7c,$088857e71,$0969b978c,$06d6d7587,$07f7e7b75,$081807f7f,$07e818281,$07b767377,
$08094958c,$0706f6769,$0796e6c6e,$080828280,$04a526576,$047474849,$04b4a4847,$05251504d,
$057565654,$076695e59,$08485847f,$084858585,$085858584,$084848484,$069697c85,$083706b6a,
$083858585,$06868646e,$066676767,$064656465,$063636465,$05b5d6062,$036455456,$0292a2b2f,
$02f323638,$03e3c362d,$05a534d44,$056565b5b,$053595150,$052585a56,$056504d51,$051555551,
$053535050,$053565550,$050545954,$05555554f,$050565d53,$05558595c,$058564d55,$04e5d5353,
$056495154,$05350595c,$0856a5158,$056535a78,$05855535b,$054515951,$0607f6e52,$0616b6056,
$075544f58,$07a565377,$081635478,$04d534f67,$05a7a7453,$072797f69,$04e6b8079,$04f505658,
$052565054,$0545a564f,$05d5a5555,$04f524d50,$051565052,$054545450,$052505152,$0524e5050,
$05b555554,$052535258,$052515255,$0524d4e50,$04a565858,$06e675149,$07d766b67,$081807f7f,
$06567727e,$08c857769,$090999891,$06d6d717e,$07f7e7b74,$082818080,$080828282,$07b757379,
$088969081,$06362626d,$0796a6462,$083868683,$04d566878,$04e4c4b4b,$05453514f,$05c5a5856,
$06260605e,$07a716965,$084848380,$084858585,$084848484,$083848483,$06a676e7d,$0877d6d6b,
$077878785,$068676764,$066666767,$066656666,$063646465,$05c5e6062,$0394d5857,$038262c30,
$03537383d,$043403e36,$06159544b,$052566362,$0555d5850,$056535757,$05455555a,$053505555,
$053575152,$04d514b52,$04849474d,$056535753,$051555052,$05c5f5255,$05b5a5247,$05859585f,
$07a74665c,$05b737f7b,$0847f5a59,$052505c7e,$0575d5452,$04e535463,$07d806351,$07984817c,
$0774f5262,$0807a6f7d,$0815e657e,$051504f71,$05f827056,$07b746354,$04f526573,$051515c59,
$0554c5253,$0525b4f51,$055534e4e,$04e4d494d,$04d505053,$054535350,$052555553,$0514f5453,
$055535052,$052515156,$056515051,$053515051,$0505c5a55,$06e604c48,$07c746968,$081807f7e,
$06669747f,$07f766a65,$07b858784,$06d6c6d72,$0807e7a72,$082818181,$081828282,$07974747b,
$08e978c79,$067666876,$0776d6a69,$082858481,$0555f6f7c,$057545252,$0605e5b59,$06a666462,
$06f6e6f6d,$07f797471,$084838382,$083848584,$07f828383,$07076797b,$06b6a6869,$08586766d,
$068818887,$067676766,$066666667,$065666666,$063646565,$05d5f6162,$03b4f5758,$049503730,
$03e3d3c40,$04945413f,$063625f55,$055525e67,$05e525958,$05851555c,$0585c5455,$051555455,
$05151574f,$05d4f4d4e,$04e4a4b51,$058505350,$050544f58,$05450514d,$06c61534b,$0526e7c75,
$065827958,$0797e685c,$06d6b5f59,$0515f6181,$058525455,$05f5b5f57,$07e806354,$05d696772,
$0785c5a56,$06c717880,$0755c7d74,$05b595f7b,$0607f6754,$05752525d,$0504c4d50,$04f4e5559,
$0584f5352,$05a5e5353,$05c53494d,$051544c50,$04d535251,$052535554,$050505255,$0534f4f52,
$056514f51,$0504e4f53,$0504d5353,$053515250,$04e53514f,$06e594846,$07a72686a,$081807f7e,
$0666b7881,$06c676565,$06e71716f,$06d6c6c6d,$0807e7971,$081818180,$081828181,$07874757c,
$095978773,$07a767684,$07774797c,$083838380,$05f68757e,$0635f5c5b,$06f6c6a67,$076737271,
$07a7a7978,$0827f7b7a,$083848484,$07b7e8081,$06a6f7478,$068686868,$06c6b6a69,$085868370,
$066718688,$068676768,$066676768,$065666565,$064646465,$05f606162,$03b51565a,$04658593d,
$04c4d4945,$0524b4747,$0686d685e,$0565c636d,$059555754,$056555054,$05954534c,$04f555a59,
$04f4d4e52,$050555e53,$05254544e,$058594c4e,$0545a524f,$0524c4f4f,$07b7b7257,$050627376,
$050628563,$082685258,$0564c5a66,$04f4d727d,$0504f5953,$052505c51,$074815a4e,$04f4f5559,
$07f61564e,$050584f6f,$06d6f7a5d,$051585a7c,$059635b54,$051555d53,$04c4c5051,$0504f5052,
$05d575450,$059565056,$056525051,$0555a5255,$04951514e,$05253524d,$04f555351,$04d515653,
$054545b50,$052504e52,$0554e5357,$055505556,$04f535353,$06b564647,$07a70686b,$082807f7e,
$0686e7a81,$068676767,$06c6b6a69,$06d6c6b6b,$07f7d7870,$081818080,$081818180,$07873767d,
$09995816d,$0908e8d93,$0767d8a90,$08283827e,$06b717a80,$0706d6a68,$079777673,$07d7c7b7b,
$07f7f807f,$081807e7f,$0767a7e80,$06a6b6d71,$067676868,$06a6b6a68,$06f6c6a6a,$08586897d,
$067657986,$068696868,$065666767,$064646465,$064636464,$060616263,$03d52575c,$04a485746,
$0505a5c56,$063585350,$066706f69,$05452595e,$0594d4e53,$054524f4f,$0534e5354,$0504f5656,
$04c524e52,$053595e4c,$04d4d5652,$052555152,$07a6b5f52,$051566b77,$055697f5b,$0454c5856,
$054507664,$082614d57,$05c5c515f,$055527b79,$0555a5452,$0575f5653,$077705760,$0514f4c54,
$08560565f,$0524f4b6b,$0536a6556,$053585862,$054505252,$04f515057,$0534b4b48,$05b575053,
$054555b53,$04d4c5956,$054505455,$055504f4f,$04e4b4f59,$04e50524e,$052595452,$057585657,
$05255554f,$052565853,$057555254,$052515054,$051525250,$067514549,$0796e686b,$082807f7e,
$06a717c82,$068686869,$06b6a6a6a,$06d6c6c6b,$07f7d7770,$080807f7f,$081808080,$07773787f,
$0978f7969,$092959698,$07074828d,$08383827b,$076797e81,$079777574,$07f7d7d7a,$08081807f,
$07c7e8081,$07274767a,$068696b6e,$06a686767,$069696969,$06c6c6b6a,$0766f6d6d,$086858687,
$068676a81,$068696968,$067686867,$064656565,$063636564,$060626262,$04154585e,$047464a3c,
$05556524f,$06c62595a,$064767670,$05556575a,$057525757,$055524d52,$052535857,$04f525759,
$05451514b,$05052554f,$04f4e4d53,$04f4d5250,$0687b7b60,$0566f7b71,$04e6a7c5a,$04a56615c,
$053524d50,$07a7a614b,$04a505053,$0595c7c6b,$05956585d,$053505554,$07f6d4e5a,$0726b605f,
$07960787c,$0545d4f57,$0524f5352,$05956535b,$05654595c,$052554e54,$05354544d,$05054514b,
$052585556,$056525850,$053505958,$04f4a4c50,$0534a4e57,$054515459,$055544e58,$05c575154,
$052535552,$054515458,$055565052,$052515151,$0484d4b51,$0624c4343,$0776c696c,$082807f7e,
$06b747f82,$06969696a,$06b6a6a6a,$06e6d6c6c,$07f7d7973,$080807f7f,$081808080,$076747a80,
$0897e6f65,$080868a8c,$069696f78,$083827f76,$07d7f8182,$07e7e7d7c,$08080807f,$07b7e8081,
$06b6f7377,$067666769,$068696868,$06a6a6969,$06c6b6a6a,$0726f6e6c,$0867d7975,$085868687,
$069696872,$068686869,$067676866,$064656766,$062636464,$05f606162,$046555960,$03f47463b,
$0443f3b39,$063574b49,$05f6a736d,$0505e5d5a,$053545453,$058565352,$0555a5d58,$052505251,
$05a514f4e,$0524a4f52,$05152514e,$050545b59,$04f5d7f71,$0607d6b52,$07e7e765d,$0667c7d81,
$04f595254,$05a7b8363,$049595853,$057648063,$056565952,$057554d4f,$083624f5a,$081807b81,
$058596878,$050575a56,$057585553,$055555551,$0504d5356,$054514e4e,$054534f4d,$057565053,
$052525356,$05b5a5856,$04f535459,$04b505450,$050525854,$04f515957,$059514c4e,$051525354,
$054515052,$052504e51,$04f55514f,$0474c4b4e,$041424548,$060483e3e,$0766b6b6f,$08282807d,
$06d767f82,$06a6a6a6a,$06c6b6b6b,$0716e6e6c,$07f7e7c78,$080807f7f,$081808080,$075757b81,
$0726b6563,$06a6e7274,$066656668,$082807b70,$080818282,$080808080,$0777a7d7e,$0696c7175,
$066666768,$069686767,$069696a69,$06c6c6c6b,$072706f6d,$08c847a75,$096999692,$079848689,
$069696968,$066676869,$067676767,$065656566,$063636465,$060606263,$051595b5e,$040474841,
$039393735,$04d46413d,$0565f6357,$054515253,$053505255,$055555153,$059585150,$04e4b4e4d,
$050504d4f,$05554514e,$050505a5a,$052535555,$05a4a7577,$06f7a5764,$07a807062,$07d7a676d,
$067545b58,$0625e727d,$050594e51,$0536d7e5d,$0545c5c53,$054524f50,$06f57545a,$0565a6373,
$057545254,$059555659,$054526668,$055545660,$0504c5c5e,$050574b52,$051514e51,$05d515454,
$057525255,$05056575b,$04c505757,$052515951,$050595b54,$04f51584f,$0554f5151,$051525252,
$04f4d4a52,$04a494d4d,$04a4a474b,$041424649,$03d3d4041,$05d443b3b,$0746c6c6e,$08281807d,
$06f7a8182,$06b6b6b6c,$06c6c6c6c,$076716f6e,$07f7f7e7c,$080808080,$081808080,$074767d81,
$065636262,$063656666,$064636363,$0807c7469,$07d7f8181,$07476787b,$0686a6d70,$067676666,
$069696867,$06b6a6969,$06e6c6c6b,$078757370,$086837f7a,$09b958b87,$09b9f9f9d,$0697f868b,
$068686967,$066676868,$067676666,$066666666,$065646565,$061616264,$056595c5f,$041474646,
$037363434,$047423e39,$05959594f,$054545556,$0564f5055,$05156535b,$05a524e50,$059535956,
$052515055,$05552534d,$0525a5756,$05e5b5451,$056537272,$0797a5d53,$058675c56,$07953534e,
$07f656370,$056575c6f,$058585353,$057788057,$053575451,$05553534c,$0534f5961,$04e4f4e4e,
$05c504e4e,$04f4e4c52,$05551515a,$04b4e5a58,$04f545251,$055575654,$04b4d5362,$05058544f,
$053554d51,$0574e5056,$04f4c4b55,$05253534f,$051535551,$0514e544f,$04b4b5258,$0504d4d4d,
$04a4c4e4c,$04546484c,$043474243,$03c3e3e3f,$039393b3c,$0543d3939,$0726b6e6c,$081807f7c,
$0727d8382,$06c6c6c6d,$06e6d6c6d,$07c767170,$07f807f7f,$080808080,$081818080,$074777e81,
$063626262,$063636363,$063636363,$077726a64,$06e727578,$06667686b,$067676767,$068686767,
$06b6b6b69,$06f6d6c6c,$07b767170,$092918b83,$0888a8d90,$0938d8a89,$099a09d96,$06670858c,
$068686969,$067676868,$068676666,$067676768,$066656666,$062626366,$05a5a5e60,$04249484c,
$036353435,$0453f3b38,$059575349,$04f595855,$055555752,$056545358,$054505158,$055535150,
$051505552,$05353554e,$0524d4f5a,$05a575d56,$05a6b7d70,$07a837358,$0544d5360,$077565353,
$073775c7a,$05b4e5053,$058525a67,$052777459,$058555e58,$050565359,$062585c51,$050565559,
$054504b48,$0504b4c52,$05350534c,$04f545955,$05255525a,$0534f4f57,$04a555b5a,$05553554f,
$04f514f57,$056534f56,$05655514e,$04f4e4f4c,$053505051,$052504d51,$049494d50,$04d4e4949,
$043464846,$041424141,$03c3d3d3d,$038383a3b,$037373738,$04f3c3938,$0716c6f6a,$0807f7e7a,
$0747e8381,$06d6d6d6e,$0706e6d6d,$0807b7471,$080807f80,$081808080,$080808181,$074787e80,
$063626262,$062626363,$064636363,$069676564,$067676869,$068676666,$069686868,$06b6a6969,
$07672706d,$0807c7978,$08e888381,$09b9b9b97,$0898b939b,$08b898888,$0989f9b8f,$069687587,
$068686869,$068676767,$067686767,$067676767,$066656666,$063636465,$05e5b5f61,$0434a4a51,
$035343236,$0433f3b38,$057524c4a,$055575353,$051565a54,$058554e54,$04e51544f,$04e4c4d51,
$0504c5453,$051505051,$04d4a4a54,$05b545151,$07b7e7059,$07c6d787f,$05b685c63,$07c554e51,
$07a7e5a71,$0837c786b,$0504e6382,$056616058,$05b545a55,$0514e5050,$05650554f,$050515459,
$05152554b,$04e545352,$058515d4d,$052626056,$0534d5250,$052505359,$050575e51,$0565e5655,
$05152555b,$051525053,$04f4d5154,$04e4c4f52,$0504e5256,$0504e4b50,$047464a4e,$042434749,
$03d3e3e40,$03a3c3d3c,$037383939,$036363637,$038373736,$04e3e3d3b,$0706e746c,$07f7e7d78,
$076808281,$06e6e6e6f,$070706e6e,$0817f7972,$080808080,$080808080,$080808081,$074797f81,
$063636362,$063636363,$066656464,$067666665,$068686767,$06a696868,$06c6b6a6a,$074706e6d,
$0908b837a,$08d919393,$0948a8889,$09594989a,$0898e9a9b,$083848687,$09c9e9b8c,$06a6b6e88,
$068686869,$067686868,$069686767,$067676868,$066666767,$063646466,$05c5b5f61,$0444a4d54,
$035333139,$0413d3b37,$055534d49,$057595451,$053575856,$05b585455,$052535452,$05a544d5b,
$04e4e5055,$04e525249,$04f51574b,$0534f5251,$06a634e51,$07d5c5f6f,$0787c5c67,$07e735966,
$07c7a5f64,$069737d80,$04d4e505f,$052514f4c,$05350555b,$0554d574d,$04a525454,$0525a4c4c,
$056554f4e,$0475b5e5d,$0544c5b55,$0555a5b5b,$055535356,$052565251,$0595b5859,$05d585652,
$052514d54,$04e535355,$052575755,$05154524e,$04a525453,$044444649,$042414545,$03c3f4041,
$038393a3b,$035373838,$035353536,$038373636,$03b3a3939,$05544423e,$06f707c76,$07e7d7b76,
$079808281,$06e6e6e70,$072706f6f,$081817e77,$080808080,$080808080,$080808080,$0757b7f81,
$065656464,$065656565,$067666666,$068686767,$06b6a6a69,$06e6d6c6b,$07673716f,$087827e7b,
$09b9b988f,$0989c9c9c,$0928a898f,$08d8b8e93,$07e8b9996,$06e6f7278,$09c9b977f,$06b6d7d97,
$06968686a,$068686869,$069686867,$068686868,$065666667,$063636465,$05c5c5f62,$0464b5159,
$03434333c,$03f3b3b36,$0524d4644,$0545e5b51,$057565252,$04d4c5358,$05453504e,$0625a5054,
$0474d4f54,$0514e5a56,$0575a584f,$055525b51,$056555752,$07e694c55,$07b694d5e,$06f7e7d7f,
$067605457,$04c484c5e,$05055514c,$05c5a5150,$058575456,$051595351,$04e52554e,$04f565749,
$053585853,$051595851,$05354494b,$051544d56,$05a585853,$05d504e4e,$05650525a,$059575252,
$050524c4f,$04a554d52,$04e51554b,$049484b4d,$0424b4c4e,$040424341,$03c3c3d3e,$038393a3b,
$036363637,$036363636,$037353535,$039383737,$03d3b3a3a,$075564842,$07075888c,$07f7d7b75,
$07b818180,$06f6f6f71,$07471706f,$08081807b,$080808080,$080808080,$080807f7f,$0767c8080,
$06a696868,$067696a6a,$069686767,$06c6a6a69,$0706e6d6c,$07e7a7673,$08685827f,$08d898887,
$0979a9d97,$09d9c9796,$086878b95,$0807d8084,$06c849792,$06b696869,$0948b8474,$06b748f9a,
$06868696a,$068696869,$068686868,$067676869,$065666768,$063646465,$05c5e5f61,$04b4e555d,
$036353542,$03d3b3936,$053504741,$053535154,$046535653,$03133363c,$0463d3732,$0515d5652,
$04f535255,$04f4d4e4c,$059585854,$05a5c5755,$06f775d56,$0757e6b62,$059535054,$0585d6b68,
$050575a58,$05a575456,$05358555e,$05252524f,$052524d4e,$0494d5658,$05355574d,$04e555452,
$04d4e5955,$04b555a4e,$04d4e4e50,$04e545650,$0564f6255,$0535a524c,$05e4e4a58,$0504f4f53,
$04c515453,$04b514d49,$04e4d4d4c,$045454749,$03f3f4147,$03a3c3d3d,$03939393a,$036363737,
$036363536,$035363736,$035343435,$038383736,$0443d3a39,$090765c4f,$0727e939a,$07f7d7b74,
$07d838181,$06f6f6f73,$07972716f,$08081817f,$080808081,$07f7f7f80,$080807f7f,$0787e8180,
$075747271,$06d717677,$06c6b6b6b,$072706f6d,$07f7b7875,$088868582,$088888887,$0908b8988,
$093979d99,$09c9b9694,$073788193,$07b6d6c6e,$06c7f9594,$06b6a6a6a,$080736f6d,$06c7d9797,
$06868696a,$069696969,$067676869,$066676768,$065666767,$063636364,$05c5f6061,$04c4e5560,
$038383847,$03d3b3835,$059504641,$057555156,$033394c59,$039383736,$032323638,$051574b37,
$05452545b,$056534e4b,$05a49474f,$058514e54,$07f6f4e5b,$05a727f82,$04e4f4d4d,$052605255,
$04d4e5454,$04d4e595a,$057565353,$0504d5759,$0524f5356,$0524e5752,$058595556,$05b4c5653,
$053575055,$05e565e5a,$0564b5b59,$056594e52,$053534e55,$05055524f,$059585451,$04e4c4a51,
$04d504f4d,$04746484b,$043464b45,$03d3c3e42,$03a3b3e3e,$037373939,$036363637,$037363637,
$036363636,$034353536,$033323333,$0413e3a35,$052454042,$096826d60,$07586999e,$0807e7c77,
$07e838281,$06f6f6f74,$07e757170,$0807f8081,$080808181,$07f7f7f80,$080807f7f,$0797f8281,
$08e8c8987,$077848d8e,$078767473,$0807f7e7a,$086858482,$088888787,$089878788,$08e8b8a89,
$0989b9e97,$09b9f9c98,$0686a728c,$0836f6b68,$06b779096,$06a6a6a6a,$07a716e6c,$06c7d9694,
$06968696b,$06b6b6b6b,$06666686a,$067676867,$066666767,$063646465,$05c5f6161,$04b4d5662,
$034353a4a,$03d3b3735,$0534b4741,$054565759,$03e38374a,$042434242,$0393e4142,$052563f30,
$051535859,$056564e53,$0574b4856,$0534e4e54,$06052515c,$04d4f5e68,$0555a5853,$059575655,
$049545248,$0534f5a55,$058545355,$054575856,$056535754,$05554564a,$052574a4d,$05451484f,
$04d505353,$056585752,$04d4b5b56,$05253585a,$0505a5651,$0504d4e53,$051565256,$04b515450,
$047464b4d,$03e414146,$03c3e3f3e,$038393b3c,$036373839,$037383736,$036363736,$038373736,
$035363737,$033343434,$032303132,$0514d4739,$0584d4c50,$096817165,$07b8c9c9e,$081807f7d,
$07f838281,$0706f6f75,$0807a7371,$07f7f7f81,$080808080,$07f7f7f80,$081807f7f,$07a808282,
$09c9b9b9a,$089959a9c,$086858282,$085868686,$086868685,$087888787,$086868787,$081808083,
$0a0a09d8f,$099a0a1a0,$0696a6e84,$08c746c6a,$06b708495,$06d6b6a6a,$08073706e,$06c758f96,
$06b6a6a6a,$07474716d,$068686a6f,$067686868,$066666667,$063646565,$05d606161,$04c4a535c,
$034323e4b,$03e3b3736,$04b4a4441,$04e5b5653,$046423c3a,$046474747,$041464645,$0523a333c,
$055535051,$04b4c4e4c,$0564f4c4e,$0534f5754,$054515455,$0545e4d4d,$05b535555,$05655504f,
$052555759,$056595753,$05354594c,$052535153,$050535857,$0585a5655,$0534c4b51,$0575a4e50,
$05459504f,$0554f534e,$0595f604e,$0524e5352,$04f5f5158,$05453504e,$04d4c4e52,$0434a5045,
$041434a45,$03a3b3b3f,$03839393b,$036373838,$036363737,$036373837,$034353636,$038373635,
$035393838,$032343433,$0342f2f30,$055574f3b,$059515355,$0937f7165,$083939f9e,$080808182,
$07e828180,$0706f6f75,$0817e7771,$0807f7f81,$080818181,$07f7f7f7f,$08181807f,$07c818282,
$09c9c9d9d,$0939c9e9c,$08888888b,$086868788,$085858585,$081838485,$074787c7f,$0716d6e70,
$0a0a09b87,$0949fa1a0,$069696d79,$094826f6b,$06b6f7890,$07c726b6a,$0948a8585,$06c798c98,
$0726b6a6b,$094948f85,$0696a6c82,$067686868,$066666767,$063646565,$05d606163,$05466635c,
$03533424b,$03e3a3636,$04f4a4642,$041535451,$04846453e,$04a47484b,$044474745,$040303c43,
$0535a4e4f,$04d50524c,$052544d51,$04c545756,$05b525551,$0595b514f,$0534f4e4e,$053585652,
$04f555658,$05657514e,$05c595558,$05651515d,$05a515f53,$05756555b,$055574e5a,$05758534e,
$048555052,$04f53524c,$05653534d,$050575458,$04b4c4a4b,$0484b4a49,$042464946,$03c3e3e41,
$03c3d3c3d,$03738393a,$037373737,$037383737,$038373838,$035343637,$034343436,$03e393333,
$03d49443e,$033373b3c,$036302f30,$05d5e513b,$05853585b,$08e797064,$08998a09d,$07f808082,
$07b80817f,$071706f72,$081807b73,$080808080,$080818181,$080808080,$081818180,$07d828282,
$093949697,$0979d9b95,$08786888d,$085868686,$07c7f8284,$06f72767a,$068696a6c,$06e6a6867,
$09b9d9881,$0939c9b99,$0696a6d79,$09890776c,$06c707689,$0867c6c6b,$098999895,$06b6f7b8d,
$0856e6c6c,$09e9e9c97,$0696c7292,$068686868,$066676767,$064646666,$05e606263,$059777c62,
$03435484d,$03d3a3737,$04d49433e,$03d4d6055,$048474745,$046454749,$045454644,$0353b4245,
$0514f4f4e,$05456534e,$053534e52,$04f56524e,$059515651,$050505556,$04d505451,$04f5a5559,
$053535351,$05a504b49,$0585b5561,$0504f5953,$054565952,$065595253,$050545457,$054555750,
$04d534c4b,$054535252,$05150534b,$04d574d52,$046484c49,$043474643,$03c3d3e3f,$03a3b3c3b,
$037383738,$037363737,$037363737,$037363636,$038383938,$032333537,$036373433,$04d403132,
$04b56534e,$0363c4448,$036302f32,$065644f3b,$057546166,$085706c62,$08c9aa09a,$07f808082,
$0757d807f,$073717070,$081817f79,$081808180,$082818181,$081818181,$082818281,$07d828282,
$08c8c8c8c,$0999d978f,$08384888f,$07b7d8082,$06c6e7276,$067686869,$067676767,$06c696767,
$08c99937b,$096978e83,$06b6b7285,$09c998971,$074848b93,$077706c6d,$0848b8e88,$06b6c6c75,
$0836e6b6b,$09e9b948f,$0696b7796,$067686868,$066676868,$064646666,$05e5f6264,$0576e6d5c,
$0363b4c4d,$03b393a39,$04b47453f,$04247524e,$048474748,$044454648,$044454543,$035414446,
$0544f5043,$055535056,$054595157,$0534d5052,$0514f5855,$0544e4b52,$05253574c,$05154535b,
$04d505750,$056524c4a,$052546256,$0525b504c,$0564f5852,$054595f5a,$052525c5b,$052565050,
$0504d4f4a,$04e4f4b53,$04b49514b,$042454852,$040424748,$03c3e3c40,$0393a3a3a,$036373838,
$037363637,$037383838,$035353536,$034333435,$03b393937,$03a363439,$04346423d,$0533f3639,
$0565e5f5b,$03a414b50,$036313134,$069664d3c,$05756656b,$07d6a6760,$08b9a9f97,$080818082,
$071787e7f,$076727170,$08181807d,$081818181,$083828181,$081828282,$082828281,$07e828382,
$088898888,$09a9c958b,$07579818e,$06a6c6f72,$067676868,$067686768,$067676767,$06b686767,
$083958d75,$094887974,$06c6d7f91,$09c9b9177,$07d8f979a,$06c6c6b71,$06e707270,$06a6b6d6d,
$06f6c6b6a,$09b887773,$06a6c7a98,$068686969,$067676768,$064656667,$05e606364,$054655f59,
$0343e4c4f,$03c393a38,$04b45433f,$04547504d,$048484849,$045464748,$046464544,$03c444645,
$055524d41,$052525254,$056575453,$06d5a5255,$059504d51,$0524e4e54,$0504d514e,$055504f51,
$0514f5e52,$0514e514d,$056565a55,$052565358,$053565c5d,$05258584f,$0584d5652,$059505058,
$0575e4f5a,$046514f54,$047484a49,$04040413f,$03c3c3e40,$03737393c,$037363737,$037373737,
$038373838,$035373838,$034343435,$033333334,$04d43423a,$04f493f4d,$050535251,$0553f3d46,
$05b636562,$03c454d54,$036323237,$06a664c3a,$055566369,$07668655e,$08b999d91,$081818082,
$070737b80,$07a747271,$081818280,$081818282,$082828181,$082828383,$082828282,$07e828282,
$080828384,$0999a9084,$06b6e778c,$067676769,$067686767,$067676767,$068686767,$06a686768,
$084928370,$086766f70,$06c708790,$090928b74,$0717c858b,$06b6a6a6c,$06d6c6d6c,$06c6c6e6d,
$06d6d6c6d,$094786f6d,$06a6c8099,$068696a6a,$067676768,$065656766,$05d606364,$054635959,
$0363f4a4c,$03d3a3936,$045403f41,$047474e4c,$048484949,$045454546,$045454645,$041444545,
$056504c3f,$0525c5a57,$05a5a5254,$0645c535a,$05354534e,$0534e5154,$0514e4c4f,$052584e57,
$04f59524e,$05758534e,$055585857,$052505452,$061574f53,$051565454,$05d564e4a,$052535357,
$04e564d55,$042434748,$03d423d3d,$03a3b3d3d,$03738383a,$036363737,$037373737,$035353636,
$038373737,$034363838,$03c393635,$0373e423f,$05a555244,$05957515a,$055575758,$05741444f,
$0606b6f6a,$03f485055,$035333539,$065624a38,$055565f63,$07168655d,$0929c9b8b,$081818185,
$07071777f,$07f787371,$082828281,$081818282,$082828181,$082828383,$082828282,$07e828282,
$072737577,$09a998977,$06a6c778e,$066676768,$067676766,$067676867,$068686867,$069676868,
$0858e7c6d,$0736d6c70,$06b6e7f7e,$07377756d,$06c6d6e70,$06c6c6b6b,$06f6e6d6d,$0706f6f6f,
$06a6c7071,$08e726d6c,$06b6d889a,$069696a6a,$066676768,$065656666,$05e606263,$057645758,
$035424b4d,$03b3a3935,$044413f40,$04747504c,$047474848,$045444647,$046444545,$041444445,
$053544e40,$050505555,$05a524b4c,$04d535855,$051565552,$056524f55,$04c515152,$052515753,
$051545854,$053494d4c,$051555b57,$058525154,$05058564f,$04f505b59,$05b534948,$0464e4a4a,
$0423e4347,$03c3e413f,$03b3a393a,$03636363b,$037363737,$037373738,$036363636,$034333535,
$038383634,$0343b413a,$04c49433a,$03d494e4e,$060605a46,$05a5a595d,$056575859,$059444952,
$06470726d,$0414a5257,$03234383c,$0605e4c36,$055565b5d,$06d68655c,$0989e9983,$082838389,
$07071777f,$0817c7471,$082828282,$082828282,$082828281,$082828283,$082828182,$07e828282,
$06b6a6b6b,$09b968371,$0696c7a91,$067676768,$068686767,$068686968,$068686867,$068676868,
$07e83736a,$06b696a6d,$068696d6d,$06a696969,$06c6b6b6a,$06f6f6d6d,$073727170,$0867e7773,
$06c7c888b,$07f6e6d6c,$06b6f8c97,$06869696a,$066676768,$064656666,$05d616363,$05d665659,
$035454d4d,$03a383635,$046433e3d,$0484c4f4c,$049474747,$045454648,$048464545,$042454545,
$04e525246,$058555552,$05d5a4f52,$04d555e55,$057544e4c,$056504f58,$05553585b,$04f4d675f,
$04c4d514f,$04e515453,$04c545d4e,$04e4f5350,$047525153,$04a52504e,$044464847,$040434241,
$03b3d3c3e,$03838393a,$037363738,$035373636,$037363737,$036373838,$033353535,$036353433,
$043423936,$03e4e5849,$0514f4b41,$0414c5152,$068675d44,$05b5b5c64,$05657585a,$05a434b53,
$0626c6f6d,$0454d5557,$033363d41,$05e5e543f,$055575b5c,$06b68645b,$09b9f967c,$08383858d,
$070717880,$0827f7770,$082828282,$081828282,$081818181,$082818282,$082828182,$080828282,
$06a696a6b,$09a927d6f,$0696e7e94,$067676767,$069686867,$06a6a6a6a,$068696a6a,$067686868,
$06f706a68,$06968696a,$068686a6a,$068686868,$06f6c6b69,$079747271,$084837f7c,$099958b86,
$070859198,$0746d6c6b,$06b739191,$068696869,$066676768,$064656666,$05e626363,$06265565a,
$037464c4f,$03a383634,$044433f3d,$0494e5049,$047474747,$046464646,$046464646,$043454445,
$04e52554b,$056525254,$055524e54,$0524f4d54,$0514c5150,$053555554,$05851565a,$04f495750,
$051515053,$04e545952,$05d5f5b50,$04f4c4c5d,$04844484f,$04249494e,$03e404345,$039393c3d,
$03838383a,$036363637,$036363637,$035353536,$036353535,$035373838,$038353333,$04946423c,
$05551474a,$04a5a5f59,$0504b4545,$0434f5252,$074736441,$05b5a616e,$05657595a,$059414c53,
$05d666b6b,$04a505757,$038394247,$067665f4c,$055565b61,$06b69645b,$09d9f947a,$084848691,
$06f717a83,$0827f7870,$081828282,$080818182,$081808080,$082818181,$082828282,$081828382,
$06a69696a,$0998d786d,$06a6e8196,$068676768,$06c6a6867,$07673706e,$0696d7377,$068686868,
$06b696767,$06969696b,$068686969,$06a696868,$07c746e6b,$0938c8581,$08b949896,$095938d8b,
$074838b93,$0706c6c69,$06b79968c,$06869696a,$066676768,$064666666,$060626463,$06561565b,
$03b484b51,$039373536,$04343413d,$04a4e4c45,$047474949,$046464746,$045454545,$048464545,
$05253574e,$0534f5452,$054565452,$058515258,$0514c5251,$057575a54,$05855555a,$052515a55,
$05658524c,$050595a50,$04f4e4b4e,$0494c4651,$041404241,$03e3e3f42,$039393b3e,$036373738,
$037383736,$037373838,$035353637,$033343435,$037333333,$0403d3b3a,$04a453f38,$05251504e,
$05f534e53,$0505e6362,$04f48464b,$0464f5252,$074756641,$05c5a616f,$057585a5c,$058444c55,
$0585a6264,$04d535959,$03e3e464a,$071736c56,$056555c66,$06a69645b,$09f9f9277,$084858995,
$06f727d83,$0817e756f,$082828282,$080818182,$081818180,$082818181,$082828282,$081828383,
$069696969,$09788746c,$06a708597,$068686768,$077716a68,$08d89847e,$06c77888e,$06969696a,
$06a696868,$06a6b6b6b,$06a6a6a6a,$06e6c6b6a,$090877570,$096959492,$087919597,$08f8e8a85,
$0767d848e,$06f6c6b68,$06c819889,$068696a6b,$067676768,$065656667,$060626364,$0665e585b,
$03f494c53,$039383634,$045413f3e,$04c4e4b48,$04646494a,$045454746,$044444445,$04c474745,
$04d50544f,$0524f5953,$050575254,$05a52534f,$057504e53,$0545a5354,$051575152,$05959564f,
$05c514e49,$0484d4e52,$04644454c,$040414043,$03a3c3c3d,$038393a3a,$036363638,$036373737,
$036363536,$0363c3c37,$033343536,$031323333,$042323233,$0504c494a,$054535049,$054535454,
$066535154,$04f61696b,$04c46494c,$048505252,$06f706140,$05d5a5d6a,$0595b5d5d,$0564a4c55,
$05651585e,$04f555b5b,$04945494c,$06d716b5a,$0585b6267,$06c6c655c,$0a09f9175,$085858b99,
$06e747f84,$0807b726e,$082818182,$081818282,$081818080,$081818181,$082828281,$081828282,
$069696969,$09582716b,$06a728898,$069686768,$08e83716a,$097989794,$06c778a94,$06c6b6b6b,
$06b6b6b6c,$07172706e,$071706f6f,$0817d7975,$0908f8a85,$088888c8f,$0878d8e8e,$08b898681,
$0777b7e88,$06e6c6a68,$06e889984,$068696a6b,$067676869,$065666668,$05f636364,$0685b595c,
$040484b58,$039373533,$042403e3d,$055504f48,$04847454e,$045454546,$045444444,$0514b4746,
$04d525450,$055545152,$051535353,$04e4d5252,$05351504e,$055575259,$05352504f,$0524d5353,
$045444c4b,$04643484b,$041403d41,$03a3c3b3c,$037383838,$037363738,$037363738,$036363737,
$033333434,$0373a3a35,$033313336,$042383735,$04636404e,$05a5b5956,$057575451,$054545455,
$072555354,$0516c787b,$04a47494a,$046505252,$06c6c5f40,$05d5a5a63,$05b5d5e5e,$05c504a52,
$056535e63,$051575c5b,$0524d4c4e,$06767655c,$05c656968,$06d6e675e,$0a09e8f73,$085868d9b,
$06f768185,$07e786f6d,$082818180,$081818282,$081808080,$081818181,$081818181,$081828282,
$069696968,$0927d6f6a,$06a748b98,$069686768,$0998e786c,$08f95999c,$06f717d89,$07372706e,
$075717273,$08989847c,$086858486,$086888a89,$0747c8184,$06861676e,$0888f9086,$08783817e,
$07a828187,$06d6b696a,$07390987e,$0696a6a6c,$068686868,$065666667,$061646464,$06b59595e,
$0434a4c5d,$039373336,$040413e3b,$05c504a45,$048474955,$046464647,$046464545,$059574b47,
$05a565356,$053545256,$05b5c534f,$04e4b4d54,$05353504a,$053515050,$056534c4f,$044494d50,
$03f3f4749,$03c3d3d3e,$03b3d393a,$035363838,$036363737,$037373737,$035363837,$034343435,
$031323332,$03d3c3933,$03b363c40,$0473e3f3e,$0463a5763,$063646259,$057565456,$054545556,
$072525254,$0546d7678,$04a48494a,$046515451,$05d635d47,$05e5d5a57,$05d5e5f5e,$06a594a53,
$053596c74,$052585b5a,$055504e4f,$06766655e,$0636e6f69,$06e6f6961,$0a19d8c72,$08687919d,
$06f788285,$07d766d6d,$081818180,$081818182,$081808081,$081818181,$081818080,$081818181,
$068686868,$08e786c69,$06b778f98,$069686768,$09b91796c,$07a818e9a,$075737478,$087847e78,
$085848687,$093958f87,$07d899193,$0656c767a,$04f555b61,$051494a4c,$0888b8774,$0837f7f7f,
$07b7f8084,$06c6b686d,$08099977a,$0696b6a6c,$068686868,$066666767,$061646565,$067565a5e,
$0444d4f60,$038363436,$0413f3d3b,$0574e4b44,$0484c5056,$046474647,$04a474646,$055535658,
$05d595057,$050575056,$05253514d,$056534e52,$04d4f4f50,$04a4d4d4b,$0464b4a4c,$041414243,
$03c3c3f40,$038393b3c,$035353636,$036363636,$035353636,$037363634,$034363738,$033333334,
$03a313233,$04f4e4a3c,$0423d4952,$043434544,$03f3e4f51,$06f716d5c,$05857545e,$054555657,
$06c4d4d53,$055697071,$04a4a4b4d,$048505853,$058615c4f,$05e5d5951,$05c5e5f5e,$06c584b55,
$0515a6b76,$053585a57,$055515050,$06c6b685d,$0676f6f6d,$0706f6a64,$0a09b8870,$08588949f,
$06f7a8385,$07b746c6c,$08080807f,$080818180,$081808080,$081818181,$080808080,$081808080,
$068686867,$08a756b68,$06c7b9297,$069686768,$09a8e776c,$073748296,$088827d79,$09a99948e,
$0848b9399,$093938b82,$05d718a94,$051535658,$049535855,$0484e594a,$088877f61,$07b797b7f,
$07a787a7c,$06c6b6872,$0889c9677,$06a6a6b6d,$068686969,$066666768,$061656665,$05f555a5e,
$0444d4d62,$037343338,$03e3c3a3a,$0524d4e41,$050535554,$047484749,$05c544b47,$05256555c,
$053585455,$050545252,$0554f514f,$0544f5458,$04b4c4c51,$044434347,$03f41464a,$03b3a3b3d,
$03837383a,$036363638,$036353635,$034353535,$033333334,$038363432,$033373838,$037373632,
$049323738,$05d5d5048,$04743545d,$045444546,$03d424344,$0787c7a61,$059575464,$054565758,
$0684c4551,$05561686c,$04c4d4d50,$04a4e5a54,$0646c6758,$05d5b5754,$05b5d5e5d,$061514a57,
$04f596168,$053585854,$053515251,$06e6e685c,$0676b6b6d,$071716c66,$09e96816f,$08487949d,
$0717d8484,$079716b6c,$0807f7f7d,$081818180,$080808080,$081818181,$080808080,$081808080,
$068686766,$087726b68,$06e809496,$069686869,$0998a746b,$075728195,$0928d8a83,$09f9f9d97,
$0858c959c,$093918a83,$050638593,$05a646256,$05571786d,$0465b6a4f,$088877d59,$072737680,
$077747772,$06b6b6774,$0909d9173,$069686a71,$068686969,$066666768,$062636365,$058565a5d,
$045484154,$03736333b,$03e3d3b3a,$0534d4741,$055565655,$04f4f4d4f,$053575553,$05452534d,
$053525356,$04f545157,$04a4b4e51,$0474a4d4a,$044454444,$03d3e4044,$0383a3b3b,$035363838,
$035363536,$036363535,$035353637,$032333434,$032313334,$03d373131,$03c4c413d,$03e403f3a,
$04a363a3c,$067624d4d,$047475f67,$044454748,$03b414545,$073767860,$05a575463,$05657595a,
$0604f4450,$057555861,$04e4f4e54,$04b515b54,$068777560,$05c5a5555,$05b5c5c5c,$0594d4c57,
$0505a5f60,$053575652,$055525251,$06e6f6a5f,$067686a6d,$074726d67,$0968b7670,$085868f97,
$0737f8685,$0766e6b6c,$080807f7d,$080818180,$0807f7f80,$081808181,$080808080,$081808080,
$068686665,$083706a68,$070859795,$06968686a,$09685716c,$076728296,$0928c8781,$09d9e9c98,
$0858d959a,$0908d8680,$04d63858f,$069766f5e,$063797978,$045616a4f,$089857953,$06a6e7382,
$07672706b,$06c6a6776,$0969d8d70,$068696a75,$068686868,$065666768,$061636364,$04f565a5e,
$04642313d,$03835333d,$03e3e3a39,$0514d4541,$054565756,$055585351,$0514f4f53,$0594f4f54,
$04c515254,$0464e524a,$04746434a,$042444443,$03e3d3e3d,$039383a3b,$036373838,$035363537,
$034343435,$035343333,$035373736,$032323233,$032323233,$051413534,$04659514f,$042444441,
$03c3c3e40,$075694b44,$0484c6b75,$046474949,$036414545,$06c71725c,$05b59555c,$0575a5b5b,
$06052484a,$05a525661,$04f515057,$049535a52,$0626c6c5c,$05a585255,$0595b5b5a,$0564a4e56,
$0525e625f,$054565550,$056525251,$06d6d6c64,$063676b6d,$076736d66,$082776d71,$088888888,
$078838888,$0726a6a6d,$0807f7e7b,$080808080,$0807f7e7e,$080808080,$08080807f,$081808080,
$069686665,$07e6f6a69,$073899792,$06968696a,$094806f6b,$072728597,$0908b857e,$096979694,
$0858b9195,$08e8a827f,$04865858e,$069725a4c,$06a746f72,$04663674e,$08885754d,$066697482,
$0746a6866,$06c686a7a,$09a9c896f,$068686a7d,$068676768,$065666767,$062636465,$050575b5f,
$0483f2d40,$03934333d,$03f3c3b3a,$050484541,$052545456,$0554f5351,$04f535150,$04c4c504e,
$049515454,$041444547,$03e3d4042,$03a45403d,$03a393a3a,$035363737,$035343434,$034353536,
$031323334,$033323232,$039383736,$035343134,$034373636,$05842473b,$04f60605e,$043454543,
$03e3f3f40,$07b70483f,$04a52737b,$0484a4b4b,$037424747,$05f686b59,$05c5a5757,$0555b5d5d,
$06f624e44,$059526472,$050515058,$047545850,$060646354,$058565057,$0595a5959,$054484f56,
$055616461,$05557544e,$059535251,$0706f6e68,$05f666f70,$078746e65,$0716c6b72,$08a88867e,
$082888b8a,$06e696b75,$07f7e7c77,$07f7f7f7f,$0807f7e7e,$07f7f7f80,$07f7f7f7f,$080807f7f,
$069696867,$0796d6a69,$0768c978e,$06969696b,$0937d6f6b,$071768c99,$08d89847b,$08f8f8f8e,
$083868a8e,$08d887f7f,$0486a868d,$05f705f48,$06e70706c,$04966614e,$08685724a,$064677383,
$06e626162,$06b686f7c,$09c9b836f,$067686c86,$066676767,$065666767,$062646565,$051585c61,
$0493b3043,$03834353f,$0403c3a39,$04f474445,$050535455,$0504e4d52,$04b514d4e,$046474e4a,
$044444248,$03d3f4044,$0393b3b3d,$0383b3838,$036363637,$034353535,$036353535,$033343436,
$031313132,$0312f3030,$0483f3e3c,$03d3e3947,$0373b3c3e,$0583f4d41,$05a696565,$044464745,
$03f404142,$074693e3a,$04a546f74,$04b4d4c4c,$04343494a,$0515b5f54,$05c5a5753,$0565c5e5e,
$079684f45,$057516276,$04f4f5158,$04854564f,$06364614f,$058544f5c,$058585958,$053475157,
$058636562,$05657534e,$059535252,$0746e6964,$0656b7375,$079766f69,$06e6a6b73,$08c89867d,
$0888c8d8d,$06b686d7c,$07f7e7b74,$07f7f7f7f,$07f7f7f7f,$07f7f7f7f,$07e7e7f7f,$0807f7f7e,
$06a6a6869,$0746c6a69,$0788e9588,$06969696c,$0917a6e6b,$0727c919a,$08987837a,$0888b8a89,
$07d7f8285,$08c877e7d,$04c70878d,$053676b50,$0706b7165,$0546b5850,$086836a48,$061687785,
$06c60615f,$06a68717b,$09d987c6d,$068696e8b,$067676868,$066676767,$064656666,$0545a5e62,
$04a363448,$037343743,$03f3c3a39,$04c484442,$04c53544f,$04b494c4a,$04848484b,$047424347,
$03d3c3d49,$039393a3e,$036373737,$035353636,$035343435,$033333434,$037373534,$033333437,
$031313132,$0312f302f,$058505049,$042423e55,$03c3e4142,$05944413d,$068757370,$046484846,
$03f414244,$0756a3b39,$04c506772,$04f4f4e4e,$04b3f484e,$0515d615a,$05c5b5751,$0575b5d5d,
$0685f4a49,$0524f5c66,$0514f5258,$04a54544f,$06668604d,$057525160,$058585858,$051495257,
$05a626762,$05555514f,$055525152,$07970635c,$06c737e7e,$07a77716d,$06f686971,$08f8c877f,
$0888d8f90,$06866707f,$07f7e7b73,$07f7f7f7f,$07f80807f,$08080807f,$07e7e7f80,$080807f7e,
$06a6b6b6d,$0706b6969,$07c919381,$06b6a6a6e,$08e79706d,$07b85979a,$084848380,$082888785,
$0787b7f80,$08d857c79,$05175888d,$0545e6c55,$07173735d,$057644f50,$089836648,$0646a7888,
$06e666662,$06a677679,$09c93756d,$0696b7190,$067686868,$067676767,$066686967,$0565c6163,
$04a32394c,$037333a45,$0413c3b3a,$04746433f,$04a4c4a4b,$044464946,$041414141,$03c3e3d3f,
$037383a3a,$036363737,$035363535,$035363536,$033333434,$031323232,$03a383532,$034353b3a,
$036373837,$040353033,$062605c49,$04345445a,$03f3f4143,$05a3f3d3f,$069757776,$0494a4948,
$041434546,$06c654338,$04e4e5763,$05251504f,$0563d4750,$0576d756c,$05b59564e,$057595b5c,
$0635b464c,$04f505c62,$053515357,$04b545251,$068695f49,$055505362,$057585858,$0504a5357,
$05f646964,$055545053,$055535152,$080746659,$06f7a8889,$07878716e,$07067666e,$08f8e8a81,
$0888d8f8f,$06a667381,$07f7f7d76,$080807f7f,$07f808080,$080808080,$07e7e7f80,$080807f7f,
$06a6e7075,$06e6a6a69,$08293907c,$0706d6c70,$08e7e7673,$089919c9b,$081828588,$07e818181,
$075777c7d,$08c847b77,$0567a898d,$0646b6a51,$063716957,$0474a4447,$087806547,$06d6d7987,
$06f6d706d,$06a687a77,$09d8d716d,$06a6b7795,$067686869,$069696767,$06f766c6a,$0585e646a,
$047303c4e,$036323c46,$03d3b3b39,$04342413e,$042454345,$03d3d4143,$0383a3c3c,$036383838,
$035353636,$035363534,$037373535,$034353637,$031313233,$0302c2b31,$0484d3c29,$03d434c47,
$03a3d3f3f,$03b393639,$069686043,$045464a63,$03f414244,$054363c3e,$0656f7071,$04b4b4b4a,
$04347494a,$0605e503f,$04f4a4854,$05252514f,$0543f4a51,$0576b776a,$05a58534d,$057595b5b,
$06256444f,$04d576264,$054515455,$04e545152,$067685c48,$0554f5763,$057585757,$0514c5456,
$07077756b,$05453525d,$058555152,$08875655c,$06e798b90,$07878726f,$07165656e,$08c8d8a82,
$0898c8d8d,$06d677584,$0807f7d78,$080808080,$07f808080,$07f808080,$07f7f7f7f,$080808080,
$06d747c83,$06c69696a,$087948d78,$07e777175,$091898481,$08b959d9b,$07f818386,$07a797a7c,
$06f707377,$08b817874,$05d7e898c,$057615a4b,$0474e4b48,$045434141,$0867b6049,$06d6a7a88,
$077787370,$069687679,$09d89706d,$06a6c7d99,$068686969,$06b6b6968,$09097836d,$05a6a7a81,
$047304251,$036343f4b,$0383a3b38,$03f3d3c3b,$03c3d3e40,$0393a3b3b,$036363738,$035363636,
$034353636,$033333333,$037353233,$034353637,$033323133,$03f484933,$058574c4a,$041485a59,
$03e414143,$03c393b3c,$075756544,$04745516f,$041424546,$054303d3f,$05d6c7070,$04c4c4b4a,
$03f484c4d,$068675b44,$04e4a4c61,$052525150,$04d414c51,$05861645c,$05957524d,$057595a5a,
$062514350,$04d5d6769,$054505452,$050545053,$065665947,$0534e5962,$057565656,$0554e5456,
$0818d8471,$053535a6a,$05d595152,$08371615f,$06f758188,$079787471,$06c636470,$08b8b887e,
$08a8b8b8b,$06e667485,$081807d78,$080808081,$080808080,$07f808080,$07f7f7f7f,$081807f80,
$073818d93,$06b696a6c,$08d948773,$08882797c,$08f8a8888,$08c989e9a,$07c7e8085,$076737377,
$0686a7074,$0867b716a,$06381878a,$044454649,$04b484644,$0605c5750,$086837769,$066667581,
$06f6b6868,$06b69686b,$09d86716e,$06b6c849c,$06a69696a,$07c746d6b,$09fa09a88,$05e85979d,
$040344654,$03536414d,$038393a37,$03938393a,$037383a3b,$035363738,$035363535,$035363635,
$034333535,$031313133,$038323031,$04046433c,$03d3c3a37,$03e535139,$05c555654,$043516262,
$03f424344,$03c3b3c3d,$072746645,$04845536e,$043454748,$053353e42,$04e586465,$04d4d4c4a,
$03d484c4d,$071756647,$04e494e66,$052525150,$049444e51,$05b5e5f59,$05856504f,$058595a59,
$05f4b4452,$04f606868,$052515450,$052535155,$065665648,$052516064,$056565655,$05c505356,
$081918a78,$05356646f,$0615b5253,$07c746461,$07070757a,$07b797875,$066616573,$08b8b8578,
$08c8e8d8c,$06d646f83,$0817f7d77,$080808081,$080808080,$080808080,$07f7e7e7f,$080807f80,
$07a8e999e,$06b6a6a6d,$093938170,$087878384,$08c888686,$08c989d97,$075777a81,$06f6d6c71,
$062676b6f,$08071665e,$0687f8586,$0524d4c50,$06b65615a,$07c7b7873,$0787d7d7c,$065696e71,
$06864625f,$0716e6c6a,$09e917d76,$06b6e899d,$06b6a696a,$09b968b79,$0a1a3a29f,$05c79909c,
$0383a4b55,$036384349,$0373c3a37,$035363836,$034363636,$035353535,$035353535,$036373736,
$032333434,$031303132,$049303131,$052565a58,$041424443,$0333a3b3f,$061555848,$0435c6c6b,
$040434445,$0373b3c3d,$06e6e6436,$04846526a,$047474949,$056443e45,$044505e5f,$04d4c4c4a,
$03e494d4e,$06a6b6044,$04d475062,$052525150,$046464f50,$05f616158,$057554e51,$058595958,
$05d484753,$052626869,$05251544f,$052525355,$0786e564a,$0525c777e,$055555554,$05d505354,
$077848073,$05359696e,$0635b5253,$07b776c66,$075737478,$07d7b7b7a,$060616877,$08f8c8370,
$08c919090,$06c636a7d,$0807e7c76,$080808080,$080808180,$080808080,$07e7e7f7f,$07f7f7f7f,
$080949ea2,$06b6a6b70,$097927d6e,$086888a8f,$088858585,$087979b92,$071717177,$06967686d,
$0656d6c6b,$07b6b5e5c,$078838684,$0706b666a,$079797875,$074777879,$06164686d,$070716f69,
$06b6b6a68,$08d7e6f6d,$09f9e9994,$06c6e8b9c,$06e6a6a6a,$0a19f9b8b,$0a0a3a3a2,$05c63708f,
$037404e56,$0353a484c,$036393836,$035353433,$034353636,$033343434,$033323333,$036373736,
$032323335,$039373433,$04e30343a,$0595a585e,$044444647,$03b3c3f42,$071574c3a,$045657576,
$042444546,$0383c3d3f,$06a6c6235,$048475060,$0474a4b4a,$0694e3943,$0435d6f70,$04e4c4c49,
$0434a4d4e,$068645a40,$04d465565,$05352514f,$043495052,$061656455,$056544c54,$057585958,
$05b474a55,$056636769,$05152544e,$052515457,$08c76584c,$057678091,$054545453,$057515353,
$06f777064,$0525c6869,$0655b5352,$07e7a716a,$07e7c7c7e,$07e7c7e80,$05f616a79,$08f8a7f6a,
$088909090,$069626678,$07f7e7a75,$081818080,$07f808181,$080808080,$07e7e7f7f,$07e7f7e7e,
$085979fa2,$06a6a6c72,$099907a6e,$085878c95,$07c7a7c81,$08798988b,$06f706c70,$06765666a,
$06874726a,$075675f5d,$081868582,$07274767a,$065696d70,$05d5f6062,$05658595a,$0776f645d,
$06c6c6b6d,$09b92796e,$09b9d9e9d,$06b6d8294,$06c6a6a6a,$0a09c9680,$09ea2a2a2,$05d646784,
$037444f57,$0343f4f4c,$0363c3835,$036363433,$033353636,$032323233,$031303131,$03d3d3c36,
$039393a41,$0403d3837,$04b34383f,$05f625f5d,$04546464b,$03d3d3f43,$072573c3a,$047657073,
$045454647,$0373d3f41,$05b615941,$04948474e,$0474a4b4a,$073543843,$0445e747b,$04e4d4b47,
$0464a4c4e,$0645e553f,$04c475762,$05452524f,$0424c5153,$062646151,$056534c58,$058585958,
$05e464e56,$05f6a6c6e,$05153534f,$052525757,$08b755b50,$0606d768a,$054535354,$057515353,
$070766c63,$052606b6c,$0675a5352,$0857e736d,$087878687,$07e7d8084,$060626e7c,$08c877a66,
$0878d8e8d,$067626778,$07f7d7971,$081818180,$07f808181,$08080807f,$07e7f7f7f,$07e7e7d7d,
$086969da0,$069686a72,$0998d776c,$082878d97,$0726e7079,$08a989583,$06f706b71,$0696b6b6a,
$0656e716e,$06b5f5c60,$070787a78,$05e616569,$058595b5c,$058585858,$052555757,$07b726256,
$06c6b6a6f,$09794826e,$0848c9397,$06a6c7178,$06a6a6969,$09285796d,$09da0a09c,$05d636785,
$039475158,$035445449,$0363a3634,$037373534,$034353636,$031313133,$0322f2f30,$04d52523a,
$043434951,$0413d3c41,$048363a41,$069716b64,$04647474e,$03c3d3f44,$06d50323b,$046616c6d,
$046474747,$03d3e4244,$059625c4f,$04947434a,$047494a4a,$0654e3a44,$0485d656a,$04e4d4b45,
$0474b4d4e,$0665f513e,$04a495e68,$055535250,$0434f5254,$061655f4d,$055514e5c,$058585958,
$061475056,$07186867a,$051525256,$052545d5a,$076655651,$0666d727c,$054535256,$055505253,
$073756861,$055656e6f,$067585352,$08780746f,$08a8a8a89,$07f818487,$06165727d,$08a837465,
$0858a8b8b,$064626979,$0807d786e,$083838481,$080808183,$080807f7f,$07d7e8080,$07e7e7e7e,
$08190979a,$06766676f,$09889756a,$07d868d98,$06f6c6c71,$08c98927d,$073716a73,$070737573,
$06b6e7171,$0685d5864,$05d63686b,$059595a5a,$057575859,$058585757,$053555758,$07f776556,
$06b6a6a74,$07f7d746c,$06e71767c,$0696b6d6e,$068696969,$0736d6b69,$099999384,$05e626581,
$03d4c545a,$036454c40,$033353433,$036363533,$034363736,$030323333,$0332c2b2d,$05b5a563d,
$04a49515c,$0413f3f49,$041353c41,$06f747569,$046474654,$03d3e4245,$06850303b,$048596268,
$047484847,$0403c4344,$06a716e5f,$048474252,$0484a4a49,$061493d45,$04d616566,$04d4c4944,
$0474b4d4e,$068624d3e,$0494c626a,$055545350,$045505355,$061655e48,$0554f515f,$057575757,
$0644c5054,$076909582,$052525563,$05259625d,$06f635a51,$0686a6d75,$05352515a,$053505253,
$07272655e,$058686e6e,$066585452,$0867f7570,$08b8b8a89,$08185888a,$06367757f,$08e877465,
$08386878a,$063636a79,$0827e776c,$088878786,$080828487,$080807f7f,$07e7e8080,$0807f7e7e,
$07a868d90,$06667686e,$0998b776b,$074838f9a,$06c6b6a6b,$08e978c76,$0736d6975,$072737676,
$0666d7171,$05b59565e,$058595a5b,$058575858,$056565758,$057575756,$055565758,$0817a6a58,
$06b6a6b79,$06e6d6c6b,$06d6d6e6e,$0696d6e6e,$067686969,$06c6b6967,$0817d726d,$061626571,
$0414e565c,$03a474d3d,$031333433,$0413b3331,$03b4d4f43,$033373a3b,$02d2b2a2d,$066605935,
$04b4d5a66,$042424147,$037363d41,$06c707365,$047474655,$03f414446,$05c4f393c,$04446505d,
$047484847,$0413d4445,$068757460,$048464254,$0484a4a49,$05c433f45,$052626361,$04d4b4843,
$0484c4d4e,$069624841,$04953696c,$055545250,$048515355,$06a6d6247,$0534e5969,$055555655,
$063515153,$07182897a,$053525a6b,$0535f655d,$070645b52,$06d6e6d74,$05251525f,$050505353,
$06f70645b,$05f6c6c6a,$066585553,$087807771,$08b8a8a89,$083898b8a,$0656b7981,$097927b68,
$08182858e,$063646d7b,$08681786a,$089888888,$082858889,$080808080,$07f7f8080,$08181807f,
$0747c8082,$06466696d,$0998e7c6c,$06d7d8f9a,$06c6a6a6a,$090948472,$070696979,$0696b6e71,
$060636667,$05757585b,$058585757,$058585858,$057575758,$058585858,$059585859,$0837e705c,
$06b6b6c7d,$06f6c6b6b,$07a767371,$06c747e7e,$068686869,$06a6a6968,$0696b6b6a,$061636568,
$04550585e,$0393e443c,$030313437,$0514b3431,$04556554e,$03a3f4243,$02f2c2d31,$071685533,
$044456272,$042454745,$033373e41,$0676c6e5f,$047474550,$042434647,$06054453c,$04442515d,
$048484747,$03f3f4445,$062645f56,$048444359,$048494949,$05b404146,$057676965,$04d4c4743,
$04a4d4e4e,$0655d4644,$0495a6b6a,$05554524e,$04a525455,$086806d4a,$05052677d,$054545453,
$05b4f5053,$06b757769,$05253606b,$05665685c,$073635952,$07173757a,$052525465,$050515453,
$073766b5b,$066706c6c,$0665a5757,$088827972,$089878889,$084898c8b,$06a6f7c82,$09b998771,
$081828592,$06366707d,$087847969,$085848486,$084878987,$080808081,$080808080,$081808080,
$06a6f7274,$05f5f6366,$0988d7e6a,$06b788e9a,$06a696a6a,$093917d6e,$068686c80,$065666767,
$065676665,$058595d61,$058585858,$058585858,$058585858,$05c5b5a59,$05d5b5b5c,$083817661,
$06b6b6e7f,$07d6f6c6a,$098949089,$0708a9899,$06768696b,$06a696968,$06a6b6b6a,$063656668,
$049525a5e,$0393b3c3e,$02d2f3236,$0594f342e,$04b5a5654,$042454747,$03735363b,$076725636,
$0494b6977,$043464849,$039383e41,$05a63665d,$04747464b,$041444647,$0736d4e39,$043405b6d,
$047484747,$03d414446,$064615c51,$04743465d,$0484a4a49,$0553d4347,$05b686a65,$04d4c4745,
$04b4d4f4e,$0695b4447,$04b626b6c,$05352514d,$04b505353,$08c897051,$0505d6b76,$054535351,
$05f505053,$06c787868,$05255666c,$0596a6a5b,$077655552,$076797a7c,$053525669,$051535454,
$078796f5b,$069727070,$0655c5a5a,$087817a73,$086858688,$083858787,$074747e82,$09e9e9787,
$081828694,$06367737e,$086847a6a,$0817f7f82,$086888683,$07f808082,$07f7f7f7f,$07f7f7f7f,
$05e616365,$05a595a5b,$0968a7c67,$06d7b919a,$06a68696a,$0968e786d,$06c6e758a,$0686a6d6c,
$065676767,$0595c6063,$058585858,$05a595959,$05b5b5a5a,$05f5e5d5c,$061606060,$082817864,
$06c6b7281,$08f746e6c,$09e9d9c9a,$076949d9e,$068696a6c,$0736b6a69,$06e747f7c,$07767686a,
$04f55647d,$040434346,$02e30353b,$06050362e,$04f626363,$042434547,$03c3c3d3f,$0746f4e3d,
$0484b656f,$045474748,$0493b4043,$04a576059,$047474643,$042444748,$0756b4c39,$042435c6e,
$048484846,$03b424446,$064615c4e,$047434960,$0494a4a49,$04e3d4547,$061676961,$04d4b464c,
$04b4e4e4e,$0745c4148,$0526b7677,$05252504d,$04c4f5152,$07b766852,$05364696e,$053535251,
$05f505053,$0717d7967,$052596b70,$05f6e6b5a,$077635353,$0787b7b7e,$054545c6f,$053565756,
$076756c5a,$0626b6e71,$0655d5b59,$0837f7b74,$083828384,$083838383,$0877b8082,$09fa09f97,
$081828695,$06469767f,$083837c6b,$07f7c7b7e,$087888481,$07f7f8083,$07e7f7f7f,$07e7e7e7e,
$057585a5b,$057555656,$094887762,$06f82959a,$06868696a,$0988b746b,$0797a8594,$06b72797a,
$065676868,$05b5e6264,$05a5a5959,$05d5c5c5b,$05e5e5d5d,$06362605f,$064646464,$082817767,
$06c6b7581,$08a726e6c,$092939495,$07a989d98,$0696a6a6c,$08e786c69,$08d949998,$0866b6c7b,
$051567493,$04648494c,$032343940,$065483732,$04e676e6f,$046464644,$03f3f3f43,$0706e4e3c,
$048495e6c,$046484848,$0533f3f44,$0505d635c,$048474543,$043454748,$05f58443b,$03f4a5d60,
$048484845,$03c434547,$069665f4a,$047434f63,$049494a49,$0473f4647,$06365675a,$04d494550,
$04b4d4d4d,$07f5b4349,$0626e7d83,$052514e4f,$04d4e5152,$074675c51,$05967666b,$053535351,
$05c505153,$075807a65,$0535f7072,$066736b59,$076625356,$0797c7e7f,$058566477,$057595a59,
$067686157,$05c5e6062,$066605f5d,$07f7e7c74,$087868381,$084868789,$08f7d7b80,$09c9f9e9a,
$082828592,$0656c7981,$083837b6c,$0817f7c7e,$0898a8581,$07e7f8084,$07d7e7e7e,$07d7e7e7d,
$054555657,$055545555,$09084715d,$070869699,$066666769,$097867068,$08f90959a,$06f808d90,
$065676769,$05d606264,$05d5c5c5c,$05f5f5e5d,$06060605f,$065636261,$066666666,$082807368,
$06c6d7981,$0766e6d6b,$07475777a,$080979580,$06868696c,$099907469,$09a999495,$08f7b8695,
$052597d97,$04a4c4e51,$03a3b4145,$068483d3b,$054697172,$047484a49,$03e404245,$06768543a,
$04848515f,$045474848,$05f3f3d44,$054717870,$04746433e,$042454747,$05d543e3d,$03e4f5f5f,
$047474745,$03e444547,$069675f45,$046435466,$04a4a4a48,$043404547,$06567675a,$04b484556,
$04c4d4c4b,$07c604848,$06c6c737d,$052504c58,$04d505252,$073646052,$05d696c6f,$053525250,
$0574f5253,$074807c66,$055657170,$06b736959,$07763555b,$07d808481,$05a586579,$05b5b5b5a,
$05e5c5b59,$061605e5e,$06c666362,$08181817a,$089888784,$082888a8a,$083706c76,$090949490,
$08181838a,$0656e7b80,$084827868,$089888482,$0898d8b89,$07d7d7f83,$07d7d7d7d,$07d7c7d7d,
$052525354,$053525252,$0887b6a58,$06f859494,$064646567,$0917e6c66,$094969797,$06c7f8d92,
$064656667,$05e606162,$05e5e5d5d,$0605f5f5f,$061616060,$064636362,$066666665,$0807d6f69,
$06b6d7b81,$06d6c6d6c,$06c6a6a6b,$08494866f,$06666676b,$091937868,$08e83767b,$099959592,
$0525d8397,$0494c4f4f,$041424447,$063484141,$051626c70,$047474746,$03e424446,$05b5a4f40,
$04643424c,$045464747,$05a3d3e43,$05465726d,$04645423e,$042444646,$05a523b3e,$040535d5c,
$046464643,$03f434546,$068665b41,$045445966,$048494847,$042414547,$0706c6c63,$049464862,
$04a4b4a4a,$064554b48,$069666e74,$0504f4d5e,$04d505151,$0725f5e50,$0626c6f73,$052525051,
$0544e5152,$0747c796a,$0586b7370,$070736658,$0715e565e,$070767d7a,$05a585b68,$05b5c5c5b,
$0605f5f5e,$066646261,$0897d726b,$081878f8f,$08c8a8885,$0828a8d8e,$06a626271,$07e7b7b75,
$07e7e7e7f,$0636f7b7e,$0847f7264,$094918c86,$0878e9294,$07a7a7b80,$07a7a7a7b,$07a7a7a7a,
$051515152,$051515151,$07c6d6054,$06f85908d,$062626365,$085736763,$0888c8e8c,$067727e84,
$062636365,$05f606161,$0605f5f5f,$060606060,$06161605f,$064636262,$066656665,$07e796c69,
$06c707e80,$07372706d,$06766666e,$087907b69,$06565666c,$088907566,$06e69696d,$095918275,
$054628894,$04b4b4c51,$04346484a,$05e474142,$04c5c6667,$046474646,$03e424346,$060615845,
$045414056,$044464645,$0503a3f42,$0555c5c59,$04644403f,$041454646,$05b4d383f,$042576161,
$046464541,$03f434646,$06260553d,$042465d63,$048484645,$042424446,$07c7b7463,$04746556d,
$04a4b4a49,$05f534949,$067697270,$04f4e5163,$04d4f5050,$071575a4d,$0666e6f75,$051514f53,
$0524e5050,$07277756a,$05c70706e,$073726357,$060555763,$05b5e6363,$05b5a595a,$05d5d5c5c,
$06966625f,$0827b756f,$095928c87,$07c899496,$08e8c8882,$0858c8f90,$05f5e6477,$072686361,
$07b7a7978,$0626e787b,$082796960,$095938c87,$0838a9194,$07878797d,$077787879,$078787877,
$0504f4f50,$050505050,$071625751,$06e848d85,$060606163,$072686161,$071757877,$064666b6e,
$061626263,$060606060,$0605f5f60,$060605f60,$0605f5f5f,$063626261,$067666564,$0857b6d69,
$0767b8689,$08588867f,$06463677b,$08a8b7266,$062636472,$08b8b7164,$063636574,$08b7b6863,
$05565868e,$04c4d4e51,$044474a4b,$059463f42,$0464e595e,$046464645,$03d414245,$06d706249,
$04340415c,$044454544,$04b393f41,$0595d5b58,$045433f43,$041444645,$0594a3840,$043575e60,
$04545443f,$040434546,$0665f503a,$0414a6066,$047474644,$049414346,$06e74715f,$0464a6169,
$04a4b4a49,$05f544749,$0686b7169,$04f4c5464,$04d4f504f,$07059594d,$0666c6e76,$051514f56,
$0504f5051,$06e727166,$05c706e6b,$074705f56,$059585966,$05d5d5c5a,$05d5d5d5d,$068635f5e,
$085817a70,$0908f8d89,$092929292,$074808d90,$08a89857e,$084898b8a,$05c5d677a,$07168605c,
$077777674,$0606c7678,$07e72625d,$08e8b8784,$07e84898d,$07676777a,$076767776,$076767676,
$04e4e4e4e,$04f4f4f4f,$06a5c534f,$070848a7f,$05e5e5f62,$063605e5e,$066666666,$064656767,
$05f606162,$060606060,$0605f6060,$05f5f5f60,$05f5f5f5f,$062616160,$06c6a6865,$08e887b70,
$07f7f878d,$0848a8984,$062606b7b,$08a856c64,$061616478,$08c846962,$061616c84,$070636060,
$0545d727b,$04b4c4e50,$045474a4b,$0554b4143,$041465259,$044454544,$03c414244,$063675a46,
$0423e4557,$043444444,$047383f40,$05c5c5b59,$043423d48,$041444544,$05744393f,$047595d5e,
$04544433e,$03f434445,$070684d3b,$043546c74,$046464543,$046414346,$067675d57,$046506363,
$04a4a4a49,$05e544648,$06c6b6f65,$04e4c5969,$04e504f4e,$0705e564b,$068686b74,$051514f5d,
$04e505152,$0676c6c5e,$0565d6163,$0746c5c57,$05e5d5c69,$060615e5e,$068646260,$0847e776f,
$08f8e8d89,$08c8e8f8f,$08184878a,$06b6c797e,$08383817a,$080838583,$05a5c6878,$0726c625b,
$075757473,$05e697375,$0776b5f5b,$08483827e,$0797d8183,$074747476,$074757574,$074747474,
$04d4d4d4d,$04e4e4d4d,$06358504e,$070828476,$05b5c5d61,$05e5d5c5b,$069676462,$06d6f6f6c,
$05e5f6066,$05f5f5f5e,$05f5f5f5f,$05f5f6060,$05f5e5e5e,$06462605f,$07e7b766d,$08c8c8881,
$078787f88,$07a7e7c77,$0605e6a73,$0897f6762,$05f60637a,$082726260,$05e607382,$05e5d5d5d,
$053575a5e,$04a4b4c50,$045464849,$05e54464a,$03e4f5f60,$044444443,$03b3f4143,$05b585140,
$03f3c4956,$043434343,$042393f40,$05b5d5c56,$0433f3c4c,$041444443,$0533f3a3f,$04d5b5a57,
$04443413e,$041434344,$07a6c4f3d,$04d606b75,$046454441,$046424546,$066645a57,$04759605d,
$04b4b4a49,$05d504649,$06b6e7062,$04e4c5e68,$04f504f4f,$06f5f504b,$069646870,$051515063,
$04f525352,$056575852,$058565555,$073695b59,$0635f5e6c,$077736d67,$0827f7b79,$08b8b8986,
$087898b8b,$0757b8083,$063676b70,$0635b5f61,$07e7d7b74,$07b7d7e7e,$0595a6575,$0706f665c,
$073737271,$05b646f73,$071675d5a,$07c7c7b78,$07476797b,$072727273,$073737272,$072727272,
$04c4c4c4c,$04c4c4c4c,$05e544e4c,$072807f6f,$05a5b5d61,$05f5b5a5a,$079746d65,$07a7e7f7d,
$05e5f616e,$05e5e5e5d,$0605f5e5e,$05f5f6161,$0605f5f5f,$06e686462,$08483827a,$085878785,
$06f727982,$06b6c6969,$05e5d686b,$086776360,$05d5f667e,$066615f5e,$05c5d6269,$05b5b5b5b,
$05155585a,$04a4a4b4f,$044454748,$068584547,$03d50646b,$043434341,$03c3f4142,$058534c3c,
$03e3b4c55,$042424242,$03d3b3f3f,$05a5d5c53,$0423e3d4f,$041434343,$0533c3c3f,$0535e5d5c,
$042423f41,$03f424343,$0716a5443,$056656270,$046454443,$048424546,$0665f595b,$0495d615f,
$04a4a4a48,$05a4c4749,$0686d6d5f,$04d4f6266,$04f4f4f4e,$06f634d4c,$06864666c,$052515061,
$052535353,$056555353,$05b5a5857,$072675c5b,$07c776f70,$089888581,$088888888,$080838687,
$06e75797c,$05b5e6267,$05858595a,$05a565758,$07978756b,$075777979,$059585f6d,$06e6d6960,
$07071716f,$0585d676f,$06e685f5a,$075757371,$071727274,$071707070,$071717071,$070707071,
$04a4a4a4a,$04b4b4a4a,$059504c4b,$0747f7a68,$0595a5c62,$0625c5a59,$082817c70,$0767d8182,
$05e5e606a,$05f5f5f5e,$06361605e,$063646766,$06e6b6866,$07b787572,$07a7c7d7d,$081817c79,
$0696e777c,$0605f5b60,$05b5d6867,$08371605d,$05c5e6a80,$05c5c5c5c,$05b5c5d5c,$05b5a5a5b,
$051545b5c,$048494b4e,$044444647,$05e514242,$03d4e5860,$04242423f,$03c3f4042,$054504939,
$03d3d4e54,$042424240,$03a3b3e3f,$05a5a5a50,$0403d3e52,$041424242,$0563a3c3e,$05d636564,
$042413f48,$03f424242,$060584d42,$059605e67,$046464346,$044444646,$068615a56,$04d60605f,
$04a4a4a48,$05849474a,$0656a6b5f,$04d536265,$04f50504f,$0675e4c4d,$0585b6065,$052525053,
$055545453,$058565656,$0635e5a58,$07c77716a,$08787847f,$086878887,$0797d8084,$064696f74,
$0585c5e60,$055555657,$054555555,$054545454,$073726d60,$06d717373,$05b565863,$06d6c6a64,
$06d6e6e6e,$058585f69,$06c69625b,$0706f6e6d,$06f6f6e6f,$06f6f6e6e,$06f6f6f6f,$06d6d6e6e,
$048494949,$04a4a4a49,$0554d4a4a,$0767d7663,$059595b64,$0645b5958,$07f828076,$0686e747a,
$0605f5f61,$064646462,$0706b6664,$072737676,$077777674,$070737577,$05c61666b,$07b76645b,
$0666c7479,$05955555e,$0585c6764,$07e6a5d5b,$05b5d6f7f,$05b59595a,$06868625c,$0625b5c62,
$050577073,$047484b4d,$043434446,$0544d4141,$03e4f5657,$04141403d,$03b3e4041,$0554f4537,
$03c3f5055,$04141413f,$0393b3e3f,$05955544b,$03f3c4254,$03f414141,$0543f3c3d,$0606e7265,
$043414355,$041434343,$05a584d3f,$05b5b5e65,$04646424a,$043444646,$068615952,$052605f5f,
$04a4a4a47,$05647474a,$062686a63,$04d586561,$050515150,$0514e4c4e,$0504f4f50,$054535352,
$055555454,$0615c5857,$07c766e66,$084848380,$083848585,$0747a7e81,$05d61666d,$05556575a,
$054555555,$053535354,$052535353,$052525252,$06b685f55,$060666a6c,$05f575557,$06c6a6966,
$0696c6c6c,$058565961,$06a68655e,$06c6c6c6b,$06c6c6c6c,$06c6c6c6c,$06c6c6c6c,$06a6a6a6b,
$048484848,$049494848,$0524a4848,$0777b715f,$057595b66,$0625a5857,$0767e7e74,$06262636a,
$06b666362,$071727270,$0726e6e6f,$075777878,$0676a6e71,$054595d63,$04546484d,$072675046,
$0656b7274,$05552565f,$0565d655f,$07a655b59,$0595c717e,$05a585858,$07c7b7664,$075656978,
$05057727b,$046484a4d,$042424446,$0524b3f41,$03f4f5455,$041413f3c,$03c3e3f41,$0534e4137,
$03b425154,$041413f3e,$0393c3d3f,$05a5c5848,$03e3d4856,$03f40403f,$055423c3d,$05c656961,
$04340495b,$043434343,$057594b40,$05c5e6165,$046454250,$042454646,$06860564e,$058605d5f,
$04a4a4947,$05347494a,$061666964,$04d55635f,$051515150,$051515050,$053535252,$055535354,
$0625e5a56,$079756f69,$081817f7c,$080818181,$072777b7e,$05b60666c,$054545658,$053535354,
$052535353,$052525252,$051535353,$051515151,$05d585350,$054595d5e,$063595453,$06a696967,
$063696a6a,$05a56565a,$068676662,$06a6b6969,$069696969,$068686969,$068696969,$068686868,
$046464646,$048484747,$04f484747,$075766b5a,$056575b68,$05f585655,$06c797a70,$068635d5f,
$077736f6c,$075797a7a,$068646a70,$069737471,$04a4d525b,$043444546,$048454141,$06c5d4644,
$0626a706f,$05350535b,$0545c605a,$075605957,$0585e737c,$05a575657,$07c7c7a6e,$07a787a7d,
$050536676,$046484a4d,$041424445,$050483e40,$0434f5153,$0403f3e3a,$03c3e3f40,$0534c3e39,
$03a465253,$03f3f3e3d,$03b3c3d3e,$067635b44,$03d425161,$03f403f3f,$04d423c3d,$0565a5e54,
$043414e59,$043424243,$052554840,$05e5e6262,$046454355,$043464646,$068625249,$05d5f5a5f,
$04c4b4949,$04e484a4b,$06062625e,$04e4d5059,$051515050,$052525151,$056545352,$069635d59,
$07977746f,$07d7d7c7b,$0797a7c7c,$06f6e7176,$0595e6970,$053545657,$051515253,$052515151,
$051525252,$054525151,$053565957,$04f4f5051,$05151504f,$051515151,$0645e5652,$068686766,
$05b646767,$05e575455,$066666563,$068686767,$067666667,$066656666,$066666666,$066666666,
$045454545,$046464646,$04d474646,$074736657,$056575c69,$05c565455,$06874756a,$06c665c5b,
$07874716f,$073777979,$06160686f,$05e6d6f6b,$03e3f4049,$04f4b403c,$05a564949,$068564551,
$0616a6f6d,$055505259,$0545b5d59,$0705b5654,$056617579,$060565556,$06f6e7573,$070797a78,
$04f525662,$046484b4d,$041414345,$04e463e41,$047515253,$03f3f3d3a,$03c3d3f3f,$04f463b39,
$03a484f4f,$03e3e3d3b,$0413b3d3e,$071675d4a,$03d4b5864,$03f403f3f,$050413c3e,$0555a5c51,
$043415257,$043424142,$051524540,$05e5d615f,$046454659,$043464646,$066655546,$0605e575e,
$04c4c494a,$048494b4c,$066604f4a,$050504f5a,$051515050,$059565352,$06d68625e,$079787471,
$07a7a7a7a,$071747779,$06165696d,$05e55585c,$053566267,$051515252,$050505050,$053515150,
$050515253,$061565250,$05e686d6a,$04e4f5155,$04f4e4e4e,$0504f4f4f,$063615952,$066666564,
$0555d6365,$0605a5453,$064636362,$065656564,$063636364,$063636363,$063636363,$064646464,
$044444444,$045454444,$04b464545,$073706355,$055565e6b,$058545354,$067727164,$067615959,
$0726f6c6a,$06d717373,$05b586169,$05c696b66,$047453d45,$05b59473e,$057504a55,$0634e4456,
$05f686c6a,$058514f56,$0535b5c5a,$069575452,$055647475,$063545454,$05c5b6a72,$06173756b,
$050515356,$046484c54,$03f404245,$04e4a403f,$048505251,$03e3e3c3a,$03b3c3e3e,$052463a39,
$03e4c5655,$03d3d3c3a,$03f3a3d3d,$0655c574d,$03f51585a,$03f403f3e,$04f3f3d3f,$0575d5a4f,
$042445357,$043424242,$0544c4241,$05c5c6160,$045434a59,$045464646,$063635543,$0575c5c5e,
$04c4b4947,$04c4b4b4c,$0645d4f4e,$05150525d,$0615c5853,$0716d6a66,$077767573,$076777777,
$06c717375,$0575b6066,$050515253,$0564f5050,$051566062,$050505150,$0504f4f4f,$05d595451,
$051555c5e,$06f615451,$06c727473,$04d4f5663,$04d4d4c4d,$04f4d4d4d,$062615d54,$063646362,
$052565e62,$0605c5552,$062616161,$061626262,$060606061,$060606061,$061616160,$062626261,
$043434343,$044444443,$04b464444,$0716d6256,$05459616c,$055525252,$068706d60,$0635d5659,
$06b696765,$0666a6b6b,$056535860,$05c656761,$0514b3c46,$054584843,$052444856,$05c464254,
$05c666966,$058504b50,$0545c5c5b,$063545250,$054647271,$060535253,$05858656e,$060717263,
$05b565858,$047494d5b,$040414446,$04f514d43,$0494d504f,$03d3c3b3b,$03b3c3d3e,$057483939,
$045516162,$03d3d3b3b,$03b3b3c3d,$05a534c47,$043525154,$040403f3d,$04c3d3e3f,$0575c574d,
$040495658,$043434243,$056494041,$0595a5e5c,$045434f5b,$047474747,$058594f44,$0464a4f53,
$04c4b4a48,$04e4c4b4c,$064584e4e,$0655f5a61,$074726f6b,$075757575,$072737475,$064696d70,
$053585c60,$04d4d4e4f,$04d4d4d4d,$0524d4d4d,$051575f5d,$051515151,$0504f4e50,$06f6c6457,
$054616c6f,$0726b5b53,$06f6e6f72,$04d52606d,$04c4c4c4d,$0514d4c4c,$0605f5e58,$061616160,
$05253595f,$0615f5a54,$05f606061,$05f5f5f5f,$05f5e5e5e,$05e5e5f5f,$05f5f5f5f,$060605f5f,
$041414141,$042424242,$04b454342,$06e6a6358,$0565c646c,$053515253,$0686e695b,$05e59545a,
$063646361,$05d616363,$0534f5258,$05c63645d,$04f433a47,$052554446,$054474b55,$057413c4c,
$05b636462,$0584f4a50,$0545a5a5a,$05c524f4e,$053636e6c,$057525051,$05c5f6a69,$06c717168,
$06a656968,$05053545e,$046494d4f,$04f535147,$04d4d4e4d,$03c3b393f,$03a3b3c3d,$057493d39,
$04d515b65,$03c3c3a3e,$03a3b3c3d,$059524e47,$047524f4f,$040403f3c,$0463c3e3f,$0585c564a,
$03f4a5658,$044444342,$057493f42,$055565c5a,$04643525a,$047484747,$047454344,$04a4a4847,
$04b4b4a4b,$0524d4c4c,$06b676058,$071716e6c,$072727272,$06c6f7172,$05d62666a,$04e505458,
$04b4b4c4c,$04a4a4a4a,$04b4b4b4b,$04e4c4b4a,$0555b5e58,$0565a5a57,$0504f4f51,$071706b5e,
$05b677071,$06f6e6359,$0685f5f68,$04d54656d,$04b4b4b4b,$0544e4b4b,$05d5d5d5b,$05e5e5e5e,
$05c58565a,$06465635f,$05d5e5f61,$05d5d5d5d,$05c5c5c5d,$05d5c5c5d,$05d5d5d5d,$05d5d5d5d,
$03f3f3f3f,$040403f3f,$049434241,$06b655f55,$05a5f656b,$052515255,$0686b6558,$05b57545d,
$05e5e5d5c,$0575a5d5d,$0504c4e53,$05c626159,$04a3b394b,$051514147,$0514c4d52,$0513d3942,
$05b61605d,$0564f4e53,$053555758,$055504e4d,$053656c66,$0534f4e4f,$06a6a6b64,$06c6d6e6c,
$06966646b,$054585d64,$0474a4e51,$04c504b45,$051545552,$03b3a3944,$03a3b3b3b,$052493e39,
$04e4e5559,$03c3c3b43,$0393b3c3c,$0584d4c44,$04a535351,$03e3f3e3c,$0423d3d3f,$0585b5549,
$03f4e5656,$044444442,$057454143,$05556585a,$047434a53,$047474747,$04a474445,$04a4b4a4a,
$0504e4b49,$0665d5853,$06f6f6e6b,$06f6f6f6f,$06a6c6d6e,$0555c6267,$04c4d4f52,$04949494a,
$048494949,$049484848,$049494949,$04b4a4a49,$064635f55,$0666a6a67,$05150535c,$06f6b655a,
$063696e6f,$06c6c6661,$063575661,$04c56666b,$04a494a4b,$0564f4b4a,$05b5b5a5a,$0595b5b5b,
$067645d57,$0696b6a69,$05b5c5f65,$05b5b5a5b,$05a5a5a5b,$05b5a5b5b,$05b5b5b5b,$05b5b5b5b,
$03e3e3e3e,$03e3e3e3e,$04642413f,$067605a51,$05b5e6468,$052525558,$068686256,$05a5a5960,
$058585758,$052565959,$04b484b50,$05b5f5d54,$04838384c,$04f4b3e48,$04f4d4f50,$04e3c3e45,
$0595d5c5a,$051505153,$052525352,$0514d4b4b,$055656961,$04f4d4c4d,$06767665c,$061646566,
$06059545d,$05255585c,$0484b4d50,$04b484844,$0595e5c56,$03a393d4a,$0393a3b3a,$049433c39,
$04e4b5051,$03c3c3b48,$03a3b3c3c,$05548463e,$04c525151,$03e3e3d3d,$03e3d3f3f,$056585046,
$041525453,$044444342,$04f414244,$045494c51,$046464443,$047474746,$048474747,$0514d4a4a,
$064625e57,$06b6a6966,$06b6b6b6b,$06567686a,$055595e62,$0484a4c4f,$048484848,$047474748,
$047474746,$047474747,$047474747,$04a484848,$06a696454,$06a6b6a6b,$056555d67,$06a645f59,
$062676b6c,$06a696460,$0665d5b63,$04c566569,$04848484a,$057504a49,$058585858,$054585959,
$069676259,$06a6a6a69,$0595b6167,$059595959,$058585858,$058585858,$059595958,$058595959,
$03d3d3d3d,$03d3d3d3d,$044403f3e,$0625b544c,$05a5c6265,$054555759,$066655f57,$0585b5d62,
$054525254,$04d525555,$04745464a,$0595c5950,$04436394d,$050463c48,$04d464b51,$0483a3e48,
$055595855,$0504e4f4f,$051505051,$04e4b4a4a,$05664655b,$04b4a4a4c,$055585750,$04e4f5154,
$059584f4d,$051535557,$0494c4d50,$051454347,$052605f55,$03a39444b,$0393a3a3a,$047443938,
$04d4e514e,$03c3b3c49,$0393b3c3c,$05247443b,$04e514f50,$03f3e3d40,$03d3d3f3f,$053544e45,
$042535251,$044444442,$041414344,$045444442,$045474646,$046464746,$0504b4746,$064605a55,
$067686766,$066666767,$061646565,$04f515a5f,$048494a4c,$046464747,$046464646,$045454645,
$045464545,$046454545,$046464646,$049474646,$068686456,$067656466,$05b5c6368,$065605d5c,
$060666868,$065625c5a,$067656465,$04c566367,$047474748,$055504948,$056565656,$04f535656,
$064636057,$066656464,$0575a6066,$057575757,$056565757,$056565656,$056565656,$056565656,
$03c3c3b3b,$03d3d3d3c,$0403e3d3d,$05c534c45,$0575a5f61,$056555556,$063615c58,$054575a60,
$0504f4e50,$0494e5151,$044414245,$05859554b,$03e353c4f,$0463c3843,$03b393e46,$046393739,
$051555551,$04c4a4849,$04b4e5250,$04c4a4847,$056616257,$04848484a,$049494949,$049494949,
$05557534a,$051525354,$04a4c5053,$050454548,$04c5b5c53,$0393a484a,$0393a3a39,$045423838,
$04d4d504a,$03b3a3e4a,$0393b3c3c,$051484239,$051514f4f,$03f3e3c44,$03c3e3f3f,$050514e46,
$03f494e50,$043444341,$044444344,$046464645,$045454545,$04b484645,$0605d5851,$063636362,
$05f626363,$05356595c,$051505353,$047495558,$046464747,$044454546,$044444444,$044444444,
$044444444,$044444444,$044444444,$047464545,$064646153,$0635f5d60,$0575a6164,$05e585656,
$060636362,$05d565056,$064646261,$04a566164,$046464647,$0524e4847,$054545453,$04b4d5254,
$05858564f,$0625c5757,$055595f63,$055545454,$053545555,$053535353,$054545353,$053545454,
$03b3b3b3b,$03c3c3b3b,$03d3c3c3c,$0584d4641,$054585e5f,$055545352,$0615f5956,$052555a5f,
$04f4e4d4f,$0484c4e4f,$042414245,$056575148,$038363f51,$036343439,$036353435,$04b423c39,
$04c515352,$044434346,$046464846,$04c4a4948,$057616156,$04747484a,$047474847,$048474747,
$05454544d,$054535354,$04c4e575c,$04b48474a,$04b52524c,$0393d4847,$03a3a3a3a,$046413839,
$04d4c5048,$03b3a414b,$03b3c3c3b,$0514a433a,$053535050,$03f3f3c48,$03c3f4040,$04446453f,
$0413f3f41,$044444343,$044444444,$047464644,$0504e4b48,$05e5b5753,$061616160,$0595b5e60,
$04c515557,$047464749,$04b464647,$046495355,$046464646,$044444546,$044444444,$043434344,
$043434343,$043434343,$044434343,$046454444,$064635e4f,$063605f62,$04f535d62,$0524c4b4d,
$061615e59,$0514c4e59,$0615f5d59,$04a576163,$046464647,$0514d4747,$054545453,$04a4b5054,
$04b4d4c4a,$05e554c4a,$055595f61,$053535353,$052525353,$052525252,$053525252,$052525353,
$03b3b3b3b,$03c3b3b3b,$03c3b3b3c,$05349423e,$050565d5c,$054535250,$0605c5755,$04f53595e,
$04d4d4d4e,$047494a4c,$042434547,$055544e45,$03638424f,$038363536,$0423f3d3b,$04b494644,
$049494a4b,$043424748,$048474645,$0534f4d4a,$05860615c,$04747474a,$046474848,$04a484747,
$053535352,$058535353,$04c515c5e,$048454549,$04a4e4d47,$039414a4a,$03a3a3a3a,$0453f383a,
$04c4c5048,$03c3a444b,$03c3d3d3c,$0504b413b,$053535150,$0403f3d4a,$03f404141,$041413f3f,
$044434342,$044444444,$048464645,$05755534e,$0605f5e5b,$05e606161,$054585a5c,$046484c50,
$044444445,$046454444,$048454646,$04a4c5452,$05250504f,$044454a52,$043434343,$043424343,
$043434343,$043434343,$043434343,$046444443,$063625b4c,$063636363,$0484b5760,$04a494747,
$05f5c544d,$04c4a4e5a,$05f5d5a53,$04a565f61,$046464647,$0524c4747,$055555555,$04e4e5355,
$0484c4e4f,$05b504847,$0545a5f60,$053535353,$051525253,$052525251,$052525252,$051525252,
$03b3b3b3b,$03b3b3b3b,$03b3b3c3b,$04e463f3c,$04c555b59,$052504e4b,$05e595453,$04a4d565d,
$04a4b4c4c,$04a484849,$04344484c,$053514a44,$03e3f464f,$04241403f,$043434343,$042434444,
$046423f40,$045464b48,$049474746,$05d5c5953,$0555d5f5f,$049474749,$047474949,$04f494848,
$052525253,$058535252,$043515d5e,$03f3b3e40,$04e4f4a45,$039454b4d,$03b3b3b3b,$0453d393a,
$0494d5048,$03d3c484a,$03e3e3d3e,$04f4b3e3c,$0484b4c4e,$0403f3d41,$041424141,$043434342,
$045444444,$0504c4946,$059575753,$06060605e,$05e5f6060,$04f55595c,$044454649,$043434444,
$043434343,$045444343,$047474847,$058505550,$05f5f5f5e,$04446555e,$043434343,$042434243,
$043424242,$043434343,$043434343,$045444443,$062615849,$062626263,$0484a535f,$049484847,
$05e594e4a,$04d494d59,$060605e58,$049535d60,$047464647,$0574f4948,$058585a5b,$058575859,
$04a515659,$0584d4746,$054595e5e,$052515152,$051515252,$051515151,$051515051,$050515151,
$03a3a3a3a,$03b3b3b3a,$03a3b3b3b,$04a423d3b,$04a545954,$04b494746,$05b534d4b,$0474a555b,
$0494b4b4a,$04b484748,$04444464c,$04f4c4542,$043454a4e,$03f414243,$03c3c3d3e,$03c3c3c3c,
$0413d3a3c,$045474c47,$04a464645,$05d5d5b56,$04b545a5c,$0524b4848,$04c4f5253,$05351504d,
$051515151,$056545251,$03f505c5c,$03d3a3d3e,$04d4e4743,$03b474d4c,$03b3b3b3b,$0453b3a3b,
$04b4d4f4b,$03e3e4949,$03e3f3e3f,$044423b3d,$03e3e3f42,$04141403f,$042424141,$044434342,
$0514c4846,$05e5d5b56,$05f5f5f5f,$05c5e5f5f,$04d545759,$045464749,$042434343,$043434343,
$042424242,$04f4a4543,$04f575855,$05a52544e,$060605f5e,$04348585f,$042434343,$042424242,
$043424242,$043434443,$043434343,$045444443,$0615e5447,$060606061,$0474a555e,$04d4d4b47,
$05c5b534d,$04d484a55,$05f5f5d58,$0484d575d,$049474647,$05d574f4b,$0585b5e5e,$05b5a5958,
$04b54585b,$054494545,$053595d5c,$050505051,$050505050,$05050504f,$050504f50,$050505050,
$03a3a3a3a,$03a3a3a3a,$03a3a3b3b,$047413c3a,$04b555851,$045444445,$0584f4845,$0464a555b,
$04c4d4c49,$04b49494a,$044474749,$04846413f,$03e404447,$03c3c3d3d,$03b3b3b3b,$03b3b3b3b,
$0413b393a,$045494d48,$048454545,$054565751,$0494a4e51,$053524c49,$054535353,$051525455,
$050505150,$04e505151,$041505b59,$03b3a3c3e,$04d4d4844,$03d4a4f4d,$03d3d3c3b,$04745403d,
$04c4c4d4c,$03e3e4948,$03f3f3f3f,$03f3e3e3e,$04142413f,$041414141,$045434342,$053504c48,
$05e5c5a57,$05e5e5e5e,$05a5c5d5e,$04c515558,$042434547,$043434242,$043424242,$043434343,
$042424243,$05c595145,$0585e5f5e,$04f52534e,$05f5e5954,$0444a5a5f,$042434343,$042424242,
$043434342,$043434343,$044434343,$044444444,$05f5c5046,$05d5c5c5f,$0484e595d,$05959544b,
$0595c5b58,$049474850,$059595650,$0484c5358,$0514d4a49,$05e5c5955,$055595c5e,$05a595654,
$04c53575a,$051474445,$053595c5a,$04f4f4f50,$04f4f4f50,$04f4f4f4f,$04f4f4f4f,$05050504f,
$03a3a3a3a,$03b3a3a3a,$03a3a3b3b,$0453f3b3a,$04c55574e,$044444446,$0554c4645,$0454a5559,
$04e4d4c48,$04c4c4c4c,$0484c4b4b,$040414041,$03c3c3d3e,$03b3b3b3b,$03b3a3a3b,$03b3b3b3a,
$0413b393a,$0454b4e49,$045444444,$0494a4a48,$04c494848,$054535350,$052515456,$050515353,
$050505050,$046485050,$042525a54,$03a3b3c3e,$04f4d4842,$0424d5051,$03e3d3d3c,$0433f413d,
$04748494c,$03e3c4044,$041404140,$042424241,$042424241,$049454242,$05754514d,$05d5c5b59,
$05c5d5d5d,$0585a5b5c,$0484c5054,$042424445,$041414142,$042424140,$045434242,$050514f4a,
$042424348,$05b595446,$0585e5e5e,$04951514c,$05e5a4c47,$0454f5c5e,$042424243,$042424242,
$043424242,$043434343,$045444443,$044444545,$05d594c45,$05751535c,$04b555b5b,$05c5a554b,
$052595b5c,$04847474a,$0504e4c49,$04f505454,$058555251,$05c5b5a59,$05255595c,$058565251,
$04c515457,$04d454345,$053595b57,$04f4f4f50,$04f4f4f4f,$04e4e4e4f,$04f4f4f4e,$04f4f4f4f,
$03a3a3a3b,$03a3a3a3a,$0393a3a3a,$0433e3b39,$04f57564c,$043434447,$052494544,$0454c5658,
$04d4c4a46,$04a4b4b4b,$043494848,$03b3b3c3e,$03b3b3b3b,$03a3b3b3b,$03a3a3a3a,$03a3a3a3a,
$0443b3a3a,$0454c4e4a,$044444444,$047474645,$0534c4948,$056545454,$050525556,$050525352,
$04f504f50,$044424b4f,$04354594f,$03a3b3d3e,$0514f4942,$0464e5052,$03f3e3e3d,$03c3b3d3e,
$03d3d3f42,$041413f3d,$042424241,$042424242,$049474543,$05956524c,$05c5c5c5b,$05b5b5c5c,
$05254585a,$046494c50,$042424243,$041414242,$040414041,$041414040,$0554b4242,$05b5c5b59,
$042454e57,$0504a4743,$0595d5d5b,$04c504e4b,$05c554948,$04a575d5d,$042424244,$042424242,
$043434343,$044434343,$046454444,$044464848,$05b564945,$04c494f59,$04c565854,$057544d48,
$04a505457,$04b494848,$0514e4b4c,$056565756,$054555656,$059565252,$050545759,$05552504f,
$04a4f5254,$04a444244,$054595954,$04e4e4e50,$04e4e4e4e,$04e4e4e4e,$04e4e4e4e,$04e4e4f4f,
$03a3b3c3e,$03a393a39,$0393a3a3a,$0413c3a39,$05156544a,$042424348,$04e464443,$0454e5656,
$047484644,$043444445,$03e414242,$03a3a3a3b,$03a3a3a3a,$03a3a3a3a,$039393939,$03a3a3939,
$0463d3b3a,$0454c4e4c,$043434343,$04f4b4644,$054535251,$054545253,$054555455,$04f515353,
$04f4f4e4e,$04441434c,$04554564a,$03b3c3d3f,$04f4d4a42,$04a4f4f50,$03f3f3f3e,$03e3e3e3f,
$042413f3f,$042424242,$045434343,$04d494847,$058575552,$05b5a5a59,$057595a5a,$04d4f5255,
$04243464a,$0403f4041,$0403f3f3f,$03f3f3f40,$03f3f3f3f,$03f3f3f3f,$05a534340,$05a5a5b5b,
$0434c585b,$048434241,$05a5c5c57,$04f4e4a4e,$0574e4a4e,$0505a5b5a,$042434345,$042424242,
$043424242,$045434343,$0524f4b48,$0464f5453,$0574f4644,$046464d56,$049504f49,$04e4c4947,
$04a4a4c4e,$053514f4c,$056545454,$052545656,$044484c50,$0524a4241,$04f535555,$0514f4d4d,
$04a4e5051,$047424144,$054585751,$04e4e4e50,$04d4d4d4d,$04d4d4e4d,$04d4d4d4d,$04d4d4d4d,
$03a3c4245,$039393939,$03939393a,$0403b3939,$052565247,$042424349,$04a444242,$047505653,
$043434344,$042424242,$03e404141,$03a3a3a3b,$03a3a3a3a,$03a3a3a3a,$03939393a,$03c3b3a3a,
$0473e3c3c,$0474c4d4c,$043424243,$057544c45,$057585858,$054535254,$054535254,$04f525354,
$04d4e4e4e,$042414045,$047555446,$03c3d3e3f,$04e4d493f,$04f504e4e,$040414246,$042403f3f,
$042424242,$049474543,$0534f4e4c,$059585756,$059595959,$055565758,$0474b4f52,$041414244,
$03f3f3f40,$03f3f3f3f,$03f3f3f3e,$03f3f3f3f,$03f3f3f3f,$03f3f3e3e,$05a524340,$0514f5359,
$045545a59,$045424141,$05a5a5a53,$04e494956,$04b4c4f50,$0555a5850,$042434348,$042424242,
$042424242,$04b444343,$059595753,$049545959,$050484444,$044444851,$047484645,$053524e49,
$050505253,$055555350,$04f525456,$043474a4c,$036383c40,$04b413a38,$04e525352,$04e4c4b4b,
$04b4d4e4e,$045424146,$05558554d,$04d4e4e50,$04d4c4d4d,$04c4c4d4d,$04c4c4c4c,$04c4c4c4c,
$03b3e464a,$03939393a,$039393939,$03e3a3939,$052554f45,$041414349,$048434241,$04a535652,
$046464646,$041424345,$03e3f4041,$0393a3a3c,$03a3a3a39,$03a3a3a3a,$03a3a3a3a,$03d3c3c3b,
$0463f3e3d,$0474c4c4b,$042424242,$057555045,$053555657,$053525252,$0524f4d50,$04e505254,
$0454a4c4c,$04141403f,$04b565245,$03c3d3f41,$04e4d4a3f,$05151514e,$04143484f,$042424141,
$04c494644,$057545250,$059585858,$057585959,$051535556,$04447494c,$03f404142,$03f404141,
$03e3e3f3f,$03e3e3e3e,$03f3e3e3e,$03f3e3e3f,$03e3e3e3e,$03f3f3e3e,$059504240,$04e474855,
$045535958,$043414141,$05857554c,$047444f58,$0494f4f4c,$056595448,$042434349,$042424242,
$043424242,$050444343,$058585857,$047515657,$046434243,$043434447,$04e4c4743,$059585753,
$04f525558,$05453514d,$03e434c53,$03637393b,$03a373939,$048424441,$04d51514f,$04a49494a,
$04a4c4b4b,$043414247,$05657534a,$04d4d4e51,$04c4c4c4c,$04b4c4c4c,$04b4b4b4b,$04b4b4b4b,
$03b3f474c,$038383939,$038393938,$03c393838,$052534c42,$03f41434a,$04641403f,$050555550,
$04e4d4c4c,$04042464b,$03e3e3f3f,$0393a3a3c,$03a3a3a39,$03a3a3a3a,$03b3b3a3a,$03e3d3c3c,
$0453f3e3e,$0484c4c4a,$041414141,$0514f4943,$04e4c4d50,$051515150,$054504e4f,$047494e52,
$03e404344,$0403f3f3f,$04f554f43,$03d3d3e41,$04d4c4a3f,$04d4d4d4d,$0464a4c4d,$04d494645,
$057555350,$058585757,$056575858,$04a515555,$041434647,$03f3f3f3f,$03f3f3e3e,$03f3f3f3f,
$03e3e3f3f,$03e3d3d3e,$03e3d3d3d,$03e3e3e3e,$03e3e3e3e,$03f3f3e3e,$0574d413f,$056525257,
$0424e5758,$041404041,$0524a4743,$043465357,$04a4e4b44,$05558554a,$042424349,$042424141,
$042414141,$04c434242,$050525352,$043464a4e,$043424142,$042444646,$053504c44,$058585755,
$04c505457,$051514e4b,$03337454f,$039343534,$03e414643,$045464844,$04e50504d,$04847484a,
$0494a4948,$0413f4146,$055565147,$04b4c4d51,$04b4b4b4b,$04a4a4a4a,$04a4a4a4a,$04a4a4a49,
$03b40484c,$038383839,$038383838,$03b383737,$052524a41,$03f3f434b,$044403f3f,$05556544d,
$053545454,$040424a50,$03e3e3e3f,$03a3a3b3c,$03a3a3a3a,$03b3b3a3a,$03c3b3b3b,$03e3d3d3c,
$0433f3e3e,$0484b4b49,$0403f4041,$045434240,$04b454243,$05251504d,$051545353,$03e3f434c,
$03f3e3e3e,$03f3f3e3e,$04f534b41,$03d3d3e41,$04b4a463e,$04d4c4c4c,$04e4e4d4d,$056555350,
$057575756,$054555656,$04f505153,$0464c4f4f,$03f404142,$03e3e3e3e,$0423f3e3e,$04c494744,
$03e3e4148,$03d3d3d3e,$03d3d3d3d,$03e3e3e3e,$03e3e3e3e,$03f3f3e3e,$0564b403f,$058585858,
$041475458,$041404041,$04d434241,$043475456,$050514e46,$052565753,$041424246,$041414141,
$041414141,$044424241,$045464747,$043434344,$044424141,$043484f4d,$0504e4a44,$057575552,
$04c4f5356,$0504f4c4a,$03335444e,$03d393f3b,$03d454847,$04246463d,$04e4f4e4b,$04847474a,
$0494a4949,$0403f4146,$055544e45,$04a4b4d51,$04a4a4a4a,$049494a4a,$049494949,$04a494949,
$03b41494c,$038383839,$038383838,$03a383737,$05250483f,$03e3f434b,$0423f3e3e,$05656524a,
$053555556,$03f42484f,$03d3e3e3f,$03b3b3c3d,$03b3b3b3b,$03b3b3b3b,$03c3b3b3b,$03e3d3d3c,
$0423f3e3e,$0494a4a48,$03f3f4042,$03f3f3f3f,$049423f3f,$050504e4b,$0484f5151,$03e3f3e40,
$03e3e3e3e,$03f3f3e3e,$04a4f453f,$03d3d3d3f,$04b49423d,$0504e4d4c,$054535251,$056565655,
$052535555,$04d4e4f50,$04c4c4c4c,$04b4d4c4c,$03e404246,$03e3d3e3e,$0504b423e,$055555452,
$03e404b53,$03d3d3d3e,$03d3d3d3d,$03e3e3d3e,$03e3e3e3d,$03f3f3f3e,$05548403f,$057575757,
$042465257,$041404041,$04f454241,$044475255,$05655544d,$04c545656,$041414244,$041414141,
$041414141,$043434242,$042424243,$04a494342,$045424246,$0464f5350,$04d4b4742,$05352504e,
$04a4d5153,$04f4e4a49,$03235434d,$03d3e443d,$03e454546,$03e43453d,$04d4e4d48,$04846474a,
$048494949,$03f3e4246,$054534c43,$0494a4c51,$049494949,$049494949,$049494949,$049494949,
$03c42494c,$038383839,$038383838,$03a383737,$0514f473e,$03e3f434c,$0413f3e3e,$055545048,
$052545555,$03e40444c,$03d3d3e3e,$03b3b3c3d,$03b3b3b3b,$03b3b3b3b,$03b3b3b3b,$03d3d3d3c,
$0413e3d3d,$0484a4947,$03f3f4043,$03d3d3e3e,$047413e3e,$04f4e4c4a,$03e484e4f,$03e3e3e3d,
$03e3e3e3e,$03e3e3e3e,$04548413f,$03d3d3d3e,$04c49433e,$05452514e,$055555555,$052535455,
$04b4d4e50,$04b4b4b4b,$04b4b4b4b,$04a4a4a4a,$03e3f454a,$03d3d3d3d,$05452483e,$055555554,
$03e425054,$03d3d3d3d,$03d3d3c3c,$03d3d3d3d,$03e3d3d3d,$03f413f3e,$053463f3e,$056555656,
$0414a5356,$042413f40,$052494342,$043455054,$05555534b,$0454e5456,$041414142,$041414141,
$042414141,$046434242,$041414346,$04f4c4341,$04541434b,$048515350,$04b494541,$04f4e4d4b,
$0494b4f50,$04e4d4949,$03135434c,$03c3f4339,$03f444446,$03b3e453e,$04c4d4c46,$04745464a,
$047484849,$03e3e4246,$053524b42,$049494c50,$048484949,$048484848,$048484848,$048484848);
implementation
end.
adlibtracker2-2.4.24/adt2play/a2depack.pas 0000644 0000000 0000000 00000107064 13411003760 016714 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
unit A2depack;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
interface
// Compression algorithm: RDC
// Algorithm developed by Ed Ross
function RDC_decompress(var source,dest; size: Word): Word;
// Compression algorithm: LZSS
// Algorithm developed by Lempel-Ziv-Storer-Szymanski
function LZSS_decompress(var source,dest; size: Word): Word;
// Compression algorithm: LZW
// Algorithm developed by Lempel-Ziv-Welch
function LZW_decompress(var source,dest): Word;
// Compression algorithm: SixPack
// Algorithm developed by Philip G. Gage
function SIXPACK_decompress(var source,dest; size: Word): Word;
// Compression algorithm: aPack
// Algorithm developed by Joergen Ibsen
function APACK_decompress(var source,dest): Dword;
// Compression algorithm: LZH
// Algorithm developed by Haruhiko Okomura & Haruyasu Yoshizaki
function LZH_decompress(var source,dest; size: Dword): Dword;
implementation
uses
A2fileIO;
const
WORKMEM_SIZE = 64*1024;
var
work_mem: array[0..PRED(WORKMEM_SIZE)] of Byte;
ibufCount,ibufSize: Word;
input_size,output_size: Word;
input_ptr,output_ptr,work_ptr: Pointer;
var
ibuf_idx,ibuf_end,obuf_idx,obuf_src: Pointer;
ctrl_bits,ctrl_mask,
command,count,offs: Word;
procedure RDC_decode;
begin
asm
mov ctrl_mask,0
mov eax,input_ptr
mov ibuf_end,eax
xor eax,eax
mov ax,input_size
add ibuf_end,eax
mov eax,input_ptr
mov ibuf_idx,eax
mov eax,output_ptr
mov obuf_idx,eax
@@1: xor ecx,ecx
mov eax,ibuf_idx
cmp eax,ibuf_end
jnb @@7
mov ax,ctrl_mask
shr ax,1
mov ctrl_mask,ax
or ax,ax
jnz @@2
mov esi,ibuf_idx
lodsw
mov ctrl_bits,ax
add ibuf_idx,2
mov ctrl_mask,8000h
@@2: mov ax,ctrl_bits
and ax,ctrl_mask
or ax,ax
jnz @@3
mov esi,ibuf_idx
mov edi,obuf_idx
movsb
inc ibuf_idx
inc obuf_idx
jmp @@1
@@3: xor ah,ah
mov esi,ibuf_idx
lodsb
shr ax,4
and ax,0fh
mov command,ax
xor ah,ah
mov esi,ibuf_idx
lodsb
and ax,0fh
mov count,ax
inc ibuf_idx
cmp command,0
jnz @@4
add count,3
mov edi,obuf_idx
mov cx,count
mov esi,ibuf_idx
lodsb
rep stosb
inc ibuf_idx
mov cx,count
add obuf_idx,ecx
jmp @@1
@@4: cmp command,1
jnz @@5
xor ah,ah
mov esi,ibuf_idx
lodsb
shl ax,4
add count,ax
inc ibuf_idx
add count,19
mov edi,obuf_idx
mov cx,count
mov esi,ibuf_idx
lodsb
rep stosb
inc ibuf_idx
mov cx,count
add obuf_idx,ecx
jmp @@1
@@5: cmp command,2
jnz @@6
mov ax,count
add ax,3
mov offs,ax
xor ah,ah
mov esi,ibuf_idx
lodsb
shl ax,4
add offs,ax
inc ibuf_idx
xor ah,ah
mov esi,ibuf_idx
lodsb
mov count,ax
inc ibuf_idx
add count,16
mov eax,obuf_idx
mov cx,offs
sub eax,ecx
mov obuf_src,eax
mov esi,eax
mov edi,obuf_idx
mov cx,count
rep movsb
mov cx,count
add obuf_idx,ecx
jmp @@1
@@6: mov ax,count
add ax,3
mov offs,ax
xor ah,ah
mov esi,ibuf_idx
lodsb
shl ax,4
add offs,ax
inc ibuf_idx
mov eax,obuf_idx
mov cx,offs
sub eax,ecx
mov obuf_src,eax
mov esi,eax
mov edi,obuf_idx
mov cx,command
rep movsb
mov cx,command
add obuf_idx,ecx
jmp @@1
@@7: mov eax,obuf_idx
sub eax,output_ptr
mov output_size,ax
end;
end;
function RDC_decompress(var source,dest; size: Word): Word;
begin
input_ptr := @source;
output_ptr := @dest;
input_size := size;
RDC_decode;
RDC_decompress := output_size;
end;
const
N = 4096;
F = 18;
T = 2;
procedure GetChar; assembler;
asm
push ebx
mov bx,ibufCount
cmp bx,ibufSize
jb @@1
jmp @@2
@@1: push edi
mov edi,input_ptr
mov al,byte ptr [edi+ebx]
pop edi
inc ebx
mov ibufCount,bx
pop ebx
clc
jmp @@3
@@2: pop ebx
stc
@@3:
end;
procedure PutChar; assembler;
asm
push ebx
mov bx,output_size
push edi
mov edi,output_ptr
mov byte ptr [edi+ebx],al
pop edi
inc ebx
mov output_size,bx
pop ebx
end;
procedure LZSS_decode;
begin
asm
mov ibufCount,0
mov ax,input_size
mov ibufSize,ax
mov output_size,0
xor ebx,ebx
xor edx,edx
mov edi,N-F
@@1: shr dx,1
or dh,dh
jnz @@2
call GetChar
jc @@5
mov dh,0ffh
mov dl,al
@@2: test dx,1
jz @@3
call GetChar
jc @@5
push esi
mov esi,work_ptr
add esi,edi
mov byte ptr [esi],al
pop esi
inc edi
and edi,N-1
call PutChar
jmp @@1
@@3: call GetChar
jc @@5
mov ch,al
call GetChar
jc @@5
mov bh,al
mov cl,4
shr bh,cl
mov bl,ch
mov cl,al
and cl,0fh
add cl,T
inc cl
@@4: and ebx,N-1
push esi
mov esi,work_ptr
mov al,byte ptr [esi+ebx]
add esi,edi
mov byte ptr [esi],al
pop esi
inc edi
and edi,N-1
call PutChar
inc ebx
dec cl
jnz @@4
jmp @@1
@@5:
end;
end;
function LZSS_decompress(var source,dest; size: Word): Word;
begin
input_ptr := @source;
output_ptr := @dest;
work_ptr := @work_mem;
input_size := size;
FillChar(work_ptr^,WORKMEM_SIZE,0);
LZSS_decode;
LZSS_decompress := output_size;
end;
var
le76,le77: Byte;
le6a,le6c,le6e,le70,le72,le74,le78,
le7a_0,le7a_2,le7a_4,le7a_6,le7a_8,le82a,le82b: Word;
procedure NextCode; assembler;
asm
mov bx,le82a
mov ax,le82b
add bx,le78
adc ax,0
xchg bx,le82a
xchg ax,le82b
mov cx,bx
and cx,7
shr ax,1
rcr bx,1
shr ax,1
rcr bx,1
shr ax,1
rcr bx,1
mov esi,input_ptr
mov ax,[ebx+esi]
mov dl,[ebx+esi+2]
or cx,cx
jz @@2
@@1: shr dl,1
rcr ax,1
loop @@1
@@2: mov bx,le78
sub bx,9
shl bx,1
and ax,[ebx+le7a_0]
end;
function LZW_decode: Word;
var
result: Word;
begin
asm
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov le72,0
mov le78,9
mov le70,102h
mov le74,200h
mov edi,output_ptr
xor eax,eax
mov le6a,ax
mov le6c,ax
mov le6e,ax
mov le76,al
mov le77,al
mov le82a,ax
mov le82b,ax
mov le7a_0,1ffh
mov le7a_2,3ffh
mov le7a_4,7ffh
mov le7a_6,0fffh
mov le7a_8,1fffh
@@1: call NextCode
cmp ax,101h
jnz @@2
jmp @@9
@@2: cmp ax,100h
jnz @@3
mov le78,9
mov le74,200h
mov le70,102h
call NextCode
mov le6a,ax
mov le6c,ax
mov le77,al
mov le76,al
mov al,le77
mov byte ptr [edi],al
inc edi
jmp @@1
@@3: mov le6a,ax
mov le6e,ax
cmp ax,le70
jb @@4
mov ax,le6c
mov le6a,ax
mov al,le76
push eax
inc le72
@@4: cmp le6a,0ffh
jbe @@5
mov esi,work_ptr
mov bx,le6a
shl bx,1
add bx,le6a
mov al,[ebx+esi+2]
push eax
inc le72
mov ax,[ebx+esi]
mov le6a,ax
jmp @@4
@@5: mov ax,le6a
mov le76,al
mov le77,al
push eax
inc le72
xor ecx,ecx
mov cx,le72
jecxz @@7
@@6: pop eax
mov byte ptr [edi],al
inc edi
loop @@6
@@7: mov le72,0
push esi
mov bx,le70
shl bx,1
add bx,le70
mov esi,work_ptr
mov al,le77
mov [ebx+esi+2],al
mov ax,le6c
mov [ebx+esi],ax
inc le70
pop esi
mov ax,le6e
mov le6c,ax
mov bx,le70
cmp bx,le74
jl @@8
cmp le78,14
jz @@8
inc le78
shl le74,1
@@8: jmp @@1
@@9: mov output_size,ax
mov result,ax
end;
LZW_decode := result;
end;
function LZW_decompress(var source,dest): Word;
begin
input_ptr := @source;
output_ptr := @dest;
work_ptr := @work_mem;
LZW_decode;
LZW_decompress := output_size;
end;
const
MAXFREQ = 2000;
MINCOPY = 3;
MAXCOPY = 255;
COPYRANGES = 6;
TERMINATE = 256;
FIRSTCODE = 257;
ROOT = 1;
CODESPERRANGE = MAXCOPY-MINCOPY+1;
MAXCHAR = FIRSTCODE+COPYRANGES*CODESPERRANGE-1;
SUCCMAX = MAXCHAR+1;
TWICEMAX = 2*MAXCHAR+1;
MAXBUF = PRED(64*1024);
MAXDISTANCE = 21389;
MAXSIZE = 21389+MAXCOPY;
const
BitValue: array[1..14] of Word = (1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192);
CopyBits: array[0..PRED(COPYRANGES)] of Word = (4,6,8,10,12,14);
CopyMin: array[0..PRED(COPYRANGES)] of Word = (0,16,80,336,1360,5456);
var
leftC,rghtC: array[0..MAXCHAR] of Word;
dad,frq: array[0..TWICEMAX] of Word;
index,ibitCount,ibitBuffer,obufCount: Word;
procedure InitTree;
begin
asm
xor edi,edi
mov di,2
mov bx,2
mov cx,1
@@1: xor dx,dx
mov ax,di
div bx
push edi
shl di,1
mov word ptr dad[edi],ax
mov word ptr frq[edi],cx
pop edi
inc di
cmp di,TWICEMAX
jbe @@1
mov di,1
@@2: xor dx,dx
mov ax,di
mul bx
push edi
shl di,1
mov word ptr leftC[edi],ax
inc ax
mov word ptr rghtC[edi],ax
pop edi
inc di
cmp di,MAXCHAR
jbe @@2
end;
end;
procedure UpdateFreq(a,b: Word);
begin
asm
xor ecx,ecx
xor edi,edi
@@1: mov di,a
shl di,1
mov bx,word ptr frq[edi]
mov di,b
shl di,1
add bx,word ptr frq[edi]
mov di,a
shl di,1
mov dx,word ptr dad[edi]
mov di,dx
shl di,1
mov word ptr frq[edi],bx
mov a,dx
cmp a,ROOT
jz @@3
mov di,a
shl di,1
mov di,word ptr dad[edi]
mov ax,di
shl di,1
mov bx,word ptr leftC[edi]
cmp a,bx
jnz @@2
mov di,ax
shl di,1
mov bx,word ptr rghtC[edi]
mov b,bx
jmp @@3
@@2: mov di,ax
shl di,1
mov bx,word ptr leftC[edi]
mov b,bx
@@3: cmp a,ROOT
jnz @@1
mov bx,MAXFREQ
mov di,ROOT
shl di,1
cmp word ptr frq[edi],bx
jnz @@5
lea esi,[frq]
lea edi,[frq]
mov cx,TWICEMAX
movsw
@@4: lodsw
shr ax,1
stosw
loop @@4
@@5:
end;
end;
procedure UpdateModel(code: Word);
begin
asm
xor ecx,ecx
xor edi,edi
mov bx,code
add bx,SUCCMAX
mov di,bx
shl di,1
mov ax,di
mov cx,word ptr frq[edi]
inc cx
mov word ptr frq[edi],cx
mov di,ax
mov cx,ROOT
cmp word ptr dad[edi],cx
jz @@10
mov dx,word ptr dad[edi]
push edi
lea edi,[leftC]
mov cx,dx
shl cx,1
add edi,ecx
mov si,word ptr [edi]
pop edi
cmp si,bx
jnz @@1
mov di,dx
shl di,1
mov si,word ptr rghtC[edi]
@@1: push ebx
push edx
push ebx
push esi
call UpdateFreq
pop edx
pop ebx
@@2: xor edi,edi
mov di,dx
shl di,1
mov ax,word ptr dad[edi]
mov di,ax
shl di,1
mov cx,di
cmp word ptr leftC[edi],dx
jnz @@3
mov di,cx
mov si,word ptr rghtC[edi]
jmp @@4
@@3: mov si,word ptr leftC[edi]
@@4: xor edi,edi
mov di,bx
shl di,1
push eax
mov ax,word ptr frq[edi]
mov di,si
shl di,1
mov cx,ax
pop eax
cmp cx,word ptr frq[edi]
jbe @@9
mov di,ax
shl di,1
mov cx,di
cmp word ptr leftC[edi],dx
jnz @@5
mov di,cx
mov word ptr rghtC[edi],bx
jmp @@6
@@5: xor edi,edi
mov di,cx
mov word ptr leftC[edi],bx
@@6: lea edi,[leftC]
xor ecx,ecx
mov cx,dx
shl cx,1
add edi,ecx
cmp word ptr [edi],bx
jnz @@7
mov word ptr [edi],si
xor edi,edi
mov di,cx
mov cx,word ptr rghtC[edi]
jmp @@8
@@7: xor edi,edi
mov di,cx
mov word ptr rghtC[edi],si
mov cx,word ptr leftC[edi]
@@8: xor edi,edi
mov di,si
shl di,1
mov word ptr dad[edi],dx
mov di,bx
shl di,1
mov word ptr dad[edi],ax
push esi
push esi
push ecx
call UpdateFreq
pop ebx
@@9: xor edi,edi
mov di,bx
shl di,1
mov bx,word ptr dad[edi]
mov di,bx
shl di,1
mov dx,word ptr dad[edi]
cmp dx,ROOT
jnz @@2
@@10:
end;
end;
function InputCode(bits: Word): Word;
var
result: Word;
begin
asm
xor bx,bx
xor ecx,ecx
mov cx,1
@@1: cmp ibitCount,0
jnz @@3
cmp ibufCount,MAXBUF
jnz @@2
mov ax,input_size
mov ibufCount,0
@@2: mov edi,input_ptr
xor edx,edx
mov dx,ibufCount
shl dx,1
add edi,edx
mov ax,[edi]
mov ibitBuffer,ax
inc ibufCount
mov ibitCount,15
jmp @@4
@@3: dec ibitCount
@@4: cmp ibitBuffer,7fffh
jbe @@5
xor edi,edi
mov di,cx
dec di
shl di,1
mov ax,word ptr BitValue[edi]
or bx,ax
@@5: shl ibitBuffer,1
inc cx
cmp cx,bits
jbe @@1
mov ax,bx
mov result,ax
end;
InputCode := result;
end;
function Uncompress: Word;
var
result: Word;
begin
asm
xor eax,eax
xor ebx,ebx
mov bx,1
mov dx,ibitCount
mov cx,ibitBuffer
mov ax,ibufCount
@@1: or dx,dx
jnz @@3
cmp ax,MAXBUF
jnz @@2
mov ax,input_size
xor ax,ax
@@2: shl ax,1
mov edi,input_ptr
add edi,eax
shr ax,1
mov cx,[edi]
inc ax
mov dx,15
jmp @@4
@@3: dec dx
@@4: cmp cx,7fffh
jbe @@5
mov edi,ebx
shl edi,1
mov bx,word ptr rghtC[edi]
jmp @@6
@@5: mov edi,ebx
shl edi,1
mov bx,word ptr leftC[edi]
@@6: shl cx,1
cmp bx,MAXCHAR
jle @@1
sub bx,SUCCMAX
mov ibitCount,dx
mov ibitBuffer,cx
mov ibufCount,ax
push ebx
push ebx
call UpdateModel
pop eax
mov result,ax
end;
Uncompress := result;
end;
procedure SIXPACK_decode;
begin
asm
mov ibitCount,0
mov ibitBuffer,0
mov obufCount,0
mov ibufCount,0
xor ebx,ebx
xor ecx,ecx
mov count,0
call InitTree
call Uncompress
@@1: cmp ax,TERMINATE
jz @@10
cmp ax,256
jae @@3
mov edi,output_ptr
push ebx
mov bx,obufCount
add edi,ebx
pop ebx
stosb
inc obufCount
mov bx,MAXBUF
cmp obufCount,bx
jnz @@2
mov output_size,bx
mov obufCount,0
@@2: mov edi,work_ptr
push ebx
mov bx,count
add edi,ebx
pop ebx
stosb
inc count
cmp count,MAXSIZE
jnz @@9
mov count,0
jmp @@9
@@3: sub ax,FIRSTCODE
mov cx,ax
xor dx,dx
mov bx,CODESPERRANGE
div bx
mov index,ax
xor dx,dx
mul bx
mov bx,cx
add bx,MINCOPY
sub bx,ax
mov si,bx
xor edi,edi
mov di,index
shl di,1
mov bx,word ptr CopyBits[edi]
push ebx
call InputCode
add ax,si
xor edi,edi
mov di,index
shl di,1
add ax,word ptr CopyMin[edi]
mov bx,count
mov dx,bx
sub dx,ax
mov cx,dx
cmp count,ax
jae @@4
add cx,MAXSIZE
@@4: xor dx,dx
@@5: mov edi,work_ptr
add edi,ecx
mov al,byte ptr [edi]
mov edi,output_ptr
push ebx
mov bx,obufCount
add edi,ebx
pop ebx
mov byte ptr [edi],al
inc obufCount
mov ax,MAXBUF
cmp obufCount,ax
jnz @@6
mov output_size,ax
mov obufCount,0
@@6: mov edi,work_ptr
push edi
add edi,ecx
mov al,byte ptr [edi]
pop edi
add edi,ebx
mov byte ptr [edi],al
inc bx
cmp bx,MAXSIZE
jnz @@7
xor bx,bx
@@7: inc cx
cmp cx,MAXSIZE
jnz @@8
xor cx,cx
@@8: inc dx
cmp dx,si
jb @@5
mov ax,si
add count,ax
cmp count,MAXSIZE
jb @@9
sub count,MAXSIZE
@@9: call Uncompress
jmp @@1
@@10: mov bx,obufCount
mov output_size,bx
end;
end;
function SIXPACK_decompress(var source,dest; size: Word): Word;
begin
input_ptr := @source;
output_ptr := @dest;
work_ptr := @work_mem;
input_size := size;
SIXPACK_decode;
SIXPACK_decompress := output_size;
end;
function APACK_decompress(var source,dest): Dword;
var
temp,result: Dword;
begin
asm
mov esi,[source]
mov edi,[dest]
cld
mov dl,80h
@@1: movsb
@@2: add dl,dl
jnz @@3
mov dl,[esi]
inc esi
adc dl,dl
@@3: jnc @@1
xor ecx,ecx
add dl,dl
jnz @@4
mov dl,[esi]
inc esi
adc dl,dl
@@4: jnc @@8
xor eax,eax
add dl,dl
jnz @@5
mov dl,[esi]
inc esi
adc dl,dl
@@5: jnc @@15
inc ecx
mov al,10h
@@6: add dl,dl
jnz @@7
mov dl,[esi]
inc esi
adc dl,dl
@@7: adc al,al
jnc @@6
jnz @@24
stosb
jmp @@2
@@8: inc ecx
@@9: add dl,dl
jnz @@10
mov dl,[esi]
inc esi
adc dl,dl
@@10: adc ecx,ecx
add dl,dl
jnz @@11
mov dl,[esi]
inc esi
adc dl,dl
@@11: jc @@9
dec ecx
loop @@16
xor ecx,ecx
inc ecx
@@12: add dl,dl
jnz @@13
mov dl,[esi]
inc esi
adc dl,dl
@@13: adc ecx,ecx
add dl,dl
jnz @@14
mov dl,[esi]
inc esi
adc dl,dl
@@14: jc @@12
jmp @@23
@@15: lodsb
shr eax,1
jz @@25
adc ecx,ecx
jmp @@20
@@16: xchg eax,ecx
dec eax
shl eax,8
lodsb
xor ecx,ecx
inc ecx
@@17: add dl,dl
jnz @@18
mov dl,[esi]
inc esi
adc dl,dl
@@18: adc ecx,ecx
add dl,dl
jnz @@19
mov dl,[esi]
inc esi
adc dl,dl
@@19: jc @@17
cmp eax,32000
jae @@20
cmp ah,5
jae @@21
cmp eax,7fh
ja @@22
@@20: inc ecx
@@21: inc ecx
@@22: xchg eax,temp
@@23: mov eax,temp
@@24: push esi
mov esi,edi
sub esi,eax
rep movsb
pop esi
jmp @@2
@@25: sub edi,[dest]
mov result,edi
end;
APACK_decompress := result;
end;
const
{ DEFAULT COMPRESSION: dictionary 8kb }
DIC_SIZE_DEF = 1 SHL 13;
{ ULTRA COMPRESSION: dictionary 16kb }
DIC_SIZE_MAX = 1 SHL 14;
const
MATCH_BIT = 8;
MAX_MATCH = 1 SHL MATCH_BIT;
THRESHOLD = 2;
PBIT = 14;
TBIT = 15;
CBIT = 16;
DIC_BIT = 14;
CODE_BIT = 16;
NC = 255 + MAX_MATCH + 2 - THRESHOLD;
NP = DIC_BIT + 1;
NT = CODE_BIT + 3;
MAX_HASH_VAL = 3 * (1 SHL DIC_BIT) + ((1 SHL DIC_BIT) SHR 9 + 1) * 255;
PERC_FLAG = 32768;
const
DIC_SIZE: Word = DIC_SIZE_DEF;
type
pWORD = ^tWORD;
tWORD = array[0..PRED((1 SHL DIC_BIT))] of Integer;
pBYTE = ^tBYTE;
tBYTE = array[0..PRED(2*(1 SHL DIC_BIT))] of Byte;
var
l_tree,r_tree: array[0..2*(NC-1)] of Word;
p_table: array[0..255] of Word;
p_len: array[0..PRED(NT)] of Byte;
c_table: array[0..4095] of Word;
c_len: array[0..PRED(NC)] of Byte;
var
dec_counter: Integer;
bit_buf,sbit_buf,bit_count,block_size,dec_ptr: Word;
input_buffer,output_buffer: pGENERIC_IO_BUFFER;
input_buffer_idx,output_buffer_idx: Dword;
size_unpacked,input_buffer_size: Dword;
function ReadDataBlock(ptr: Pointer; size: Word): Word;
var
result: Word;
begin
If (input_buffer_size-input_buffer_idx >= size) then
result := size
else result := input_buffer_size-input_buffer_idx;
Move(input_buffer^[input_buffer_idx],ptr^,result);
Inc(input_buffer_idx,result);
ReadDataBlock := result;
end;
procedure WriteDataBlock(ptr: Pointer; size: Word);
begin
Move(ptr^,output_buffer^[output_buffer_idx],size);
Inc(output_buffer_idx,size);
end;
procedure FillBitBuffer(bits: Integer);
begin
bit_buf := (bit_buf SHL bits);
While (bits > bit_count) do
begin
Dec(bits,bit_count);
bit_buf := bit_buf OR (sbit_buf SHL bits);
If (input_buffer_idx <= input_buffer_size) then
begin
sbit_buf := input_buffer^[input_buffer_idx];
Inc(input_buffer_idx);
end
else sbit_buf := 0;
bit_count := 8;
end;
Dec(bit_count,bits);
bit_buf := bit_buf OR (sbit_buf SHR bit_count);
end;
function GetBits(bits: Integer): Word;
begin
GetBits := bit_buf SHR (16-bits);
FillBitBuffer(bits);
end;
procedure PutBits(bits: Integer; xbits: Word);
begin
If (bits < bit_count) then
begin
Dec(bit_count,bits);
sbit_buf := sbit_buf OR (xbits SHL bit_count);
end
else begin
Dec(bits,bit_count);
output_buffer^[output_buffer_idx] := sbit_buf OR (xbits SHR bits);
Inc(output_buffer_idx);
If (bits < 8) then
begin
bit_count := 8-bits;
sbit_buf := xbits SHL bit_count;
end
else begin
output_buffer^[output_buffer_idx] := xbits SHR (bits-8);
Inc(output_buffer_idx);
bit_count := 16-bits;
sbit_buf := xbits SHL bit_count;
end;
end;
end;
procedure MakeTable(n_char: Integer;
bit_len: pBYTE;
bits: Integer;
table: pWORD);
var
count,weight: array[1..16] of Word;
start: array[1..17] of Word;
idx,idx2,len,chr,j_bits,avail,next_c,mask: Integer;
ptr: pWORD;
begin
FillChar(count,SizeOf(count),0);
FillChar(weight,SizeOf(weight),0);
FillChar(start,SizeOf(start),0);
For idx := 0 to PRED(n_char) do
Inc(count[bit_len^[idx]]);
start[1] := 0;
For idx := 1 to 16 do
start[SUCC(idx)] := start[idx]+(count[idx] SHL (16-idx));
j_bits := 16-bits;
For idx := 1 to bits do
begin
start[idx] := start[idx] SHR j_bits;
weight[idx] := 1 SHL (bits-idx);
end;
idx := SUCC(bits);
While (idx <= 16) do
begin
weight[idx] := 1 SHL (16-idx);
Inc(idx);
end;
idx := start[SUCC(bits)] SHR j_bits;
If (idx <> 0) then
begin
idx2 := 1 SHL bits;
If (idx <> idx2) then
begin
FillWord(table^[idx],idx2-idx,0);
idx := idx2;
end;
end;
avail := n_char;
mask := 1 SHL (15-bits);
For chr := 0 to PRED(n_char) do
begin
len := bit_len^[chr];
If (len = 0) then
CONTINUE;
idx2 := start[len];
next_c := idx2+weight[len];
If (len <= bits) then
For idx := idx2 to PRED(next_c) do
table^[idx] := chr
else begin
ptr := Addr(table^[WORD(idx2) SHR j_bits]);
idx := len-bits;
While (idx <> 0) do
begin
If (ptr^[0] = 0) then
begin
r_tree[avail] := 0;
l_tree[avail] := 0;
ptr^[0] := avail;
Inc(avail);
end;
If (idx2 AND mask <> 0) then
ptr := Addr(r_tree[ptr^[0]])
else ptr := Addr(l_tree[ptr^[0]]);
idx2 := idx2 SHL 1;
Dec(idx);
end;
ptr^[0] := chr;
end;
start[len] := next_c;
end;
end;
procedure ReadPtrLen(n_char,n_bit,i_bit: Integer);
var
idx,chr,bits: Integer;
mask: Word;
begin
bits := GetBits(n_bit);
If (bits = 0) then
begin
chr := GetBits(n_bit);
FillChar(p_len,SizeOf(p_len),0);
FillWord(p_table,SizeOf(p_table) DIV 2,chr);
end
else begin
idx := 0;
While (idx < bits) do
begin
chr := bit_buf SHR (16-3);
If (chr = 7) then
begin
mask := 1 SHL (16-4);
While (mask AND bit_buf <> 0) do
begin
mask := mask SHR 1;
Inc(chr);
end;
end;
If (chr < 7) then
FillBitBuffer(3)
else FillBitBuffer(chr-3);
p_len[idx] := chr;
Inc(idx);
If (idx = i_bit) then
begin
chr := PRED(GetBits(2));
While (chr >= 0) do
begin
p_len[idx] := 0;
Inc(idx);
Dec(chr);
end;
end;
end;
If (idx < n_char) then
begin
FillWord(p_len[idx],n_char-idx,0);
idx := n_char;
end;
MakeTable(n_char,@p_len,8,@p_table);
end;
end;
procedure ReadCharLen;
var
idx,chr,bits: Integer;
mask: Word;
begin
bits := GetBits(CBIT);
If (bits = 0) then
begin
chr := GetBits(CBIT);
FillChar(c_len,SizeOf(c_len),0);
FillWord(c_table,SizeOf(c_table) DIV 2,chr);
end
else begin
idx := 0;
While (idx < bits) do
begin
chr := p_table[bit_buf SHR (16-8)];
If (chr >= NT) then
begin
mask := 1 SHL (16-9);
Repeat
If (bit_buf AND mask <> 0) then
chr := r_tree[chr]
else chr := l_tree[chr];
mask := mask SHR 1;
until (chr < NT);
end;
FillBitBuffer(p_len[chr]);
If (chr <= 2) then
begin
If (chr = 1) then
chr := 2+GetBits(4)
else If (chr = 2) then
chr := 19+GetBits(CBIT);
While (chr >= 0) do
begin
c_len[idx] := 0;
Inc(idx);
Dec(chr);
end;
end
else begin
c_len[idx] := chr-2;
Inc(idx);
end;
end;
While (idx < NC) do
begin
c_len[idx] := 0;
Inc(idx);
end;
MakeTable(NC,@c_len,12,@c_table);
end;
end;
function DecodeChar: Word;
var
chr,mask: Word;
begin
If (block_size = 0) then
begin
block_size := GetBits(16);
ReadPtrLen(NT,TBIT,3);
ReadCharLen;
ReadPtrLen(NP,PBIT,-1);
end;
Dec(block_size);
chr := c_table[bit_buf SHR (16-12)];
If (chr >= NC) then
begin
mask := 1 SHL (16-13);
Repeat
If (bit_buf AND mask <> 0) then
chr := r_tree[chr]
else chr := l_tree[chr];
mask := mask SHR 1;
until (chr < NC);
end;
FillBitBuffer(c_len[chr]);
DecodeChar := chr;
end;
function DecodePtr: Word;
var
ptr,mask: Word;
begin
ptr := p_table[bit_buf SHR (16-8)];
If (ptr >= NP) then
begin
mask := 1 SHL (16-9);
Repeat
If (bit_buf AND mask <> 0) then
ptr := r_tree[ptr]
else ptr := l_tree[ptr];
mask := mask SHR 1;
until (ptr < NP);
end;
FillBitBuffer(p_len[ptr]);
If (ptr <> 0) then
begin
Dec(ptr);
ptr := (1 SHL ptr)+GetBits(ptr);
end;
DecodePtr := ptr;
end;
procedure DecodeBuffer(count: Word; buffer: pBYTE);
var
idx,idx2: Word;
begin
idx2 := 0;
Dec(dec_counter);
While (dec_counter >= 0) do
begin
buffer^[idx2] := buffer^[dec_ptr];
dec_ptr := SUCC(dec_ptr) AND PRED(DIC_SIZE);
Inc(idx2);
If (idx2 = count) then
EXIT;
Dec(dec_counter);
end;
Repeat
idx := DecodeChar;
If (idx <= 255) then
begin
buffer^[idx2] := idx;
Inc(idx2);
If (idx2 = count) then
EXIT;
end
else begin
dec_counter := idx-(256-THRESHOLD);
dec_ptr := (idx2-DecodePtr-1) AND PRED(DIC_SIZE);
Dec(dec_counter);
While (dec_counter >= 0) do
begin
buffer^[idx2] := buffer^[dec_ptr];
dec_ptr := SUCC(dec_ptr) AND PRED(DIC_SIZE);
Inc(idx2);
If (idx2 = count) then
EXIT;
Dec(dec_counter);
end;
end;
until FALSE;
end;
function LZH_decompress(var source,dest; size: Dword): Dword;
var
ptr: pBYTE;
size_temp: Dword;
ultra_compression_flag: Boolean;
begin
LZH_decompress := 0;
input_buffer := Addr(source);
input_buffer_idx := 0;
ultra_compression_flag := BOOLEAN(input_buffer^[input_buffer_idx]);
Inc(input_buffer_idx);
input_buffer_size := size;
output_buffer := Addr(dest);
output_buffer_idx := 0;
Move(input_buffer^[input_buffer_idx],size_unpacked,SizeOf(size_unpacked));
Inc(input_buffer_idx,SizeOf(size_unpacked));
size := size_unpacked;
If ultra_compression_flag then DIC_SIZE := DIC_SIZE_MAX
else DIC_SIZE := DIC_SIZE_DEF;
GetMem(ptr,DIC_SIZE);
bit_buf := 0;
sbit_buf := 0;
bit_count := 0;
FillBitBuffer(16);
block_size := 0;
dec_counter := 0;
While (size > 0) do
begin
If (size > DIC_SIZE) then
size_temp := DIC_SIZE
else size_temp := size;
DecodeBuffer(size_temp,ptr);
WriteDataBlock(ptr,size_temp);
Dec(size,size_temp);
end;
FreeMem(ptr,DIC_SIZE);
LZH_decompress := size_unpacked;
end;
end.
adlibtracker2-2.4.24/adt2play/typconst.inc 0000644 0000000 0000000 00000031373 13411003760 017112 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
const
NULL = $0ffffffff;
BYTE_NULL = BYTE(NULL);
WORD_NULL = WORD(NULL);
DWORD_NULL = LONGINT(NULL);
const
FFVER_A2M = 14;
FFVER_A2T = 14;
FFVER_A2I = 10;
FFVER_A2F = 2;
FFVER_A2P = 11;
FFVER_A2B = 10;
FFVER_A2W = 3;
type
tFM_INST_DATA = Record
AM_VIB_EG_modulator,
AM_VIB_EG_carrier,
KSL_VOLUM_modulator,
KSL_VOLUM_carrier,
ATTCK_DEC_modulator,
ATTCK_DEC_carrier,
SUSTN_REL_modulator,
SUSTN_REL_carrier,
WAVEFORM_modulator,
WAVEFORM_carrier,
FEEDBACK_FM: Byte;
end;
type
tADTRACK2_INS = Record
fm_data: tFM_INST_DATA;
panning: Byte;
fine_tune: Shortint;
perc_voice: Byte;
end;
type
tOLD_ADTRACK2_INS = Record
fm_data: tFM_INST_DATA;
panning: Byte;
fine_tune: Shortint;
end;
type
tARPEGGIO_TABLE = Record
length,
speed,
loop_begin,
loop_length,
keyoff_pos: Byte;
data: array[1..255] of Byte;
end;
type
tVIBRATO_TABLE = Record
length,
speed,
delay,
loop_begin,
loop_length,
keyoff_pos: Byte;
data: array[1..255] of Shortint;
end;
type
tREGISTER_TABLE_DEF = Record
fm_data: tFM_INST_DATA;
freq_slide: Smallint;
panning: Byte;
duration: Byte;
end;
type
tREGISTER_TABLE = Record
length,
loop_begin,
loop_length,
keyoff_pos,
arpeggio_table,
vibrato_table: Byte;
data: array[1..255] of tREGISTER_TABLE_DEF;
end;
type
tMACRO_TABLE = Record
arpeggio: tARPEGGIO_TABLE;
vibrato: tVIBRATO_TABLE;
end;
type
tARP_VIB_MACRO_TABLE = array[1..255] of tMACRO_TABLE;
type
tFM_PARAMETER_TABLE = Record
adsrw_car,
adsrw_mod: Record
attck,dec,sustn,rel,
wform: Byte;
end;
connect,
feedb,
multipM,kslM,tremM,vibrM,ksrM,sustM,
multipC,kslC,tremC,vibrC,ksrC,sustC: Byte;
end;
type
tDIS_FMREG_COL = array[0..27] of Boolean;
type
tINS_4OP_FLAGS = Record
num_4op: Byte;
idx_4op: array[1..128] of Byte;
end;
type
pOLD_FIXED_SONGDATA = ^tOLD_FIXED_SONGDATA;
tOLD_FIXED_SONGDATA = Record
songname: String[42];
composer: String[42];
instr_names: array[1..250] of String[32];
instr_data: array[1..250] of tOLD_ADTRACK2_INS;
pattern_order: array[0..$7f] of Byte;
tempo: Byte;
speed: Byte;
common_flag: Byte;
end;
const
MB_SIGNATURE = 'MB_1'; // Message Board v1.0
MB_HSIZE = 50; // 50x20 chr
MB_VSIZE = 20;
type
pMESSAGE_BOARD_DATA = ^tMESSAGE_BOARD_DATA;
tMESSAGE_BOARD_DATA = Record
signature: array[0..3] of Char;
data: array[1..MB_VSIZE] of String[MB_HSIZE];
end;
type
pFIXED_SONGDATA = ^tFIXED_SONGDATA;
tFIXED_SONGDATA = Record
songname: String[42];
composer: String[42];
instr_names: array[1..255] of String[42];
instr_data: array[1..255] of tADTRACK2_INS;
instr_macros: array[1..255] of tREGISTER_TABLE;
macro_table: tARP_VIB_MACRO_TABLE;
pattern_order: array[0..$7f] of Byte;
tempo: Byte;
speed: Byte;
common_flag: Byte;
patt_len: Word;
nm_tracks: Byte;
macro_speedup: Word;
flag_4op: Byte;
lock_flags: array[1..20] of Byte;
pattern_names: array[0..$7f] of String[42];
dis_fmreg_col: array[1..255] of tDIS_FMREG_COL;
ins_4op_flags: tINS_4OP_FLAGS;
reserved_data: array[0..PRED(1024)] of Byte;
bpm_data: Record
rows_per_beat: Byte;
tempo_finetune: Integer;
end;
end;
type
tOLD_CHUNK = Record
note: Byte;
instr_def: Byte;
effect_def: Byte;
effect: Byte;
end;
type
tCHUNK = Record
note: Byte;
instr_def: Byte;
effect_def: Byte;
effect: Byte;
effect_def2: Byte;
effect2: Byte;
end;
type
tOLD_VARIABLE_DATA1 = array[0..$0f] of array[0..$3f] of
array[1..9] of tOLD_CHUNK;
type
tOLD_VARIABLE_DATA2 = array[0..7] of array[1..18] of
array[0..$3f] of tOLD_CHUNK;
type
tVARIABLE_DATA = array[0..7] of array[1..20] of
array[0..$0ff] of tCHUNK;
type
tPATTERN_DATA = array[0..15] of tVARIABLE_DATA;
type
tPLAY_STATUS = (isPlaying,isPaused,isStopped);
type
tByteSet = Set of Byte;
const
INSTRUMENT_SIZE = SizeOf(tADTRACK2_INS);
CHUNK_SIZE = SizeOf(tCHUNK);
PATTERN_SIZE = 20*256*CHUNK_SIZE;
type
tCHAR8x8 = array[char] of array[0..7] of Byte;
tCHAR8x16 = array[char] of array[0..15] of Byte;
type
tRGB = Record r,g,b: Byte end;
tRGB_PALETTE = array[0..255] of tRGB;
const
ef_Arpeggio = 0;
ef_FSlideUp = 1;
ef_FSlideDown = 2;
ef_TonePortamento = 3;
ef_Vibrato = 4;
ef_TPortamVolSlide = 5;
ef_VibratoVolSlide = 6;
ef_FSlideUpFine = 7;
ef_FSlideDownFine = 8;
ef_SetModulatorVol = 9;
ef_VolSlide = 10;
ef_PositionJump = 11;
ef_SetInsVolume = 12;
ef_PatternBreak = 13;
ef_SetTempo = 14;
ef_SetSpeed = 15;
ef_TPortamVSlideFine = 16;
ef_VibratoVSlideFine = 17;
ef_SetCarrierVol = 18;
ef_SetWaveform = 19;
ef_VolSlideFine = 20;
ef_RetrigNote = 21;
ef_Tremolo = 22;
ef_Tremor = 23;
ef_ArpggVSlide = 24;
ef_ArpggVSlideFine = 25;
ef_MultiRetrigNote = 26;
ef_FSlideUpVSlide = 27;
ef_FSlideDownVSlide = 28;
ef_FSlUpFineVSlide = 29;
ef_FSlDownFineVSlide = 30;
ef_FSlUpVSlF = 31;
ef_FSlDownVSlF = 32;
ef_FSlUpFineVSlF = 33;
ef_FSlDownFineVSlF = 34;
ef_Extended = 35;
ef_Extended2 = 36;
ef_SetGlobalVolume = 37;
ef_SwapArpeggio = 38;
ef_SwapVibrato = 39;
ef_ForceInsVolume = 40;
ef_Extended3 = 41;
ef_ExtraFineArpeggio = 42;
ef_ExtraFineVibrato = 43;
ef_ExtraFineTremolo = 44;
ef_SetCustomSpeedTab = 45;
ef_GlobalFSlideUp = 46;
ef_GlobalFSlideDown = 47;
ef_ex_SetTremDepth = 0;
ef_ex_SetVibDepth = 1;
ef_ex_SetAttckRateM = 2;
ef_ex_SetDecayRateM = 3;
ef_ex_SetSustnLevelM = 4;
ef_ex_SetRelRateM = 5;
ef_ex_SetAttckRateC = 6;
ef_ex_SetDecayRateC = 7;
ef_ex_SetSustnLevelC = 8;
ef_ex_SetRelRateC = 9;
ef_ex_SetFeedback = 10;
ef_ex_SetPanningPos = 11;
ef_ex_PatternLoop = 12;
ef_ex_PatternLoopRec = 13;
ef_ex_ExtendedCmd = 14;
ef_ex_cmd_MKOffLoopDi = 0;
ef_ex_cmd_MKOffLoopEn = 1;
ef_ex_cmd_TPortaFKdis = 2;
ef_ex_cmd_TPortaFKenb = 3;
ef_ex_cmd_RestartEnv = 4;
ef_ex_cmd_4opVlockOff = 5;
ef_ex_cmd_4opVlockOn = 6;
ef_ex_cmd_ForceBpmSld = 7;
ef_ex_ExtendedCmd2 = 15;
ef_ex_cmd2_RSS = 0;
ef_ex_cmd2_ResetVol = 1;
ef_ex_cmd2_LockVol = 2;
ef_ex_cmd2_UnlockVol = 3;
ef_ex_cmd2_LockVP = 4;
ef_ex_cmd2_UnlockVP = 5;
ef_ex_cmd2_VSlide_mod = 6;
ef_ex_cmd2_VSlide_car = 7;
ef_ex_cmd2_VSlide_def = 8;
ef_ex_cmd2_LockPan = 9;
ef_ex_cmd2_UnlockPan = 10;
ef_ex_cmd2_VibrOff = 11;
ef_ex_cmd2_TremOff = 12;
ef_ex_cmd2_FVib_FGFS = 13;
ef_ex_cmd2_FTrm_XFGFS = 14;
ef_ex_cmd2_NoRestart = 15;
ef_ex2_PatDelayFrame = 0;
ef_ex2_PatDelayRow = 1;
ef_ex2_NoteDelay = 2;
ef_ex2_NoteCut = 3;
ef_ex2_FineTuneUp = 4;
ef_ex2_FineTuneDown = 5;
ef_ex2_GlVolSlideUp = 6;
ef_ex2_GlVolSlideDn = 7;
ef_ex2_GlVolSlideUpF = 8;
ef_ex2_GlVolSlideDnF = 9;
ef_ex2_GlVolSldUpXF = 10;
ef_ex2_GlVolSldDnXF = 11;
ef_ex2_VolSlideUpXF = 12;
ef_ex2_VolSlideDnXF = 13;
ef_ex2_FreqSlideUpXF = 14;
ef_ex2_FreqSlideDnXF = 15;
ef_ex3_SetConnection = 0;
ef_ex3_SetMultipM = 1;
ef_ex3_SetKslM = 2;
ef_ex3_SetTremoloM = 3;
ef_ex3_SetVibratoM = 4;
ef_ex3_SetKsrM = 5;
ef_ex3_SetSustainM = 6;
ef_ex3_SetMultipC = 7;
ef_ex3_SetKslC = 8;
ef_ex3_SetTremoloC = 9;
ef_ex3_SetVibratoC = 10;
ef_ex3_SetKsrC = 11;
ef_ex3_SetSustainC = 12;
const
ef_fix1 = $80;
ef_fix2 = $90;
const
_panning: array[0..2] of Byte = ($30,$10,$20);
const
_instr_data_ofs: array[1..13] of Byte = (1,0,3,2,5,4,7,6,9,8,10,11,12);
_instr: array[0..11] of Byte = ($20, $20,
$40, $40,
$60, $60,
$80, $80,
$0e0,$0e0,
$0c0,
$0bd);
type
tTRACK_ADDR = array[1..20] of Word;
const { 01 - 02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 }
_chmm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$006,$007,$008,$103,$100,$104,$101,$105,$102,$106,$107,$108,BYTE_NULL,BYTE_NULL);
_chmm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$010,$011,$012,$108,$100,$109,$101,$10a,$102,$110,$111,$112,BYTE_NULL,BYTE_NULL);
_chmm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$013,$014,$015,$10b,$103,$10c,$104,$10d,$105,$113,$114,$115,BYTE_NULL,BYTE_NULL);
{ BD SD TT TC HH }
_chpm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$106,$107,$108,$103,$100,$104,$101,$105,$102,$006,$007,$008,$008,$007);
_chpm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$110,$111,$112,$108,$100,$109,$101,$10a,$102,$010,$014,$012,$015,$011);
_chpm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$113,$114,$115,$10b,$103,$10c,$104,$10d,$105,$013,BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL);
var
_chan_n: tTRACK_ADDR;
_chan_m: tTRACK_ADDR;
_chan_c: tTRACK_ADDR;
const
_4op_tracks_hi: Set of Byte = [1,3,5,10,12,14];
_4op_tracks_lo: Set of Byte = [2,4,6,11,13,15];
_4op_main_chan: array[1..6] of Byte = (2,4,6,11,13,15);
const
_debug_str_: String = '';
adlibtracker2-2.4.24/adt2play/adt2play.pas 0000644 0000000 0000000 00000042364 13411003760 016763 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
program AdT2_Player;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
uses
DOS,GO32,
A2player,A2fileIO,A2scrIO,
StringIO,TxtScrIO;
const
VERSION_STR = '0.46';
const
modname: array[1..15] of String[39] = (
'/´DLiB TR/´CK3R ][ module',
'/´DLiB TR/´CK3R ][ G3 module',
'/´DLiB TR/´CK3R ][ tiny module',
'/´DLiB TR/´CK3R ][ G3 tiny module',
'Amusic module',
'XMS-Tracker module',
'BoomTracker 4.0 module',
'Digital-FM module',
'HSC AdLib Composer / HSC-Tracker module',
'MPU-401 tr’kkîr module',
'Reality ADlib Tracker module',
'Scream Tracker 3.x module',
'FM-Kingtracker module',
'Surprise! AdLib Tracker module',
'Surprise! AdLib Tracker 2.0 module');
var
fkey: Word;
index,last_order: Byte;
dirinfo: SearchRec;
dos_memavail: Word;
mem_info: TFPCHeapStatus;
free_mem: Longint;
var
temp,temp2: Byte;
_ParamStr: array[0..255] of String[80];
const
jukebox: Boolean = FALSE;
const
kBkSPC = $0e08;
kESC = $011b;
kENTER = $1c0d;
function keypressed: Boolean; assembler;
asm
mov ah,01h
int 16h
mov al,TRUE
jnz @@1
mov al,FALSE
@@1:
end;
procedure _list_title;
begin
If iVGA then
begin
CWriteLn('',$07,0);
CWriteLn(' subz3ro''s',$09,0);
CWriteLn(' ÄÂÄ ÄÄ',$09,0);
CWriteLn(' /´DLiB³R/´CK3R ³³ PLAYER',$09,0);
CWriteLn(' ³ ³ ÄÄ '+VERSION_STR,$09,0);
CWriteLn('',$07,0);
end
else begin
WriteLn;
WriteLn(' subz3ro''s');
WriteLn(' ÄÂÄ ÄÄ');
WriteLn(' /´DLiB³R/´CK3R ³³ PLAYER');
WriteLn(' ³ ³ ÄÄ '+VERSION_STR);
WriteLn;
end;
end;
function _gfx_mode: Boolean;
var
result: Boolean;
temp: Byte;
begin
result := FALSE;
For temp := 1 to ParamCount do
If (Lower(_ParamStr[temp]) = '/gfx') then
begin
result := TRUE;
BREAK;
end;
_gfx_mode := result;
end;
var
old_exit_proc: procedure;
procedure new_exit_proc;
var
temp: Byte;
begin
asm mov ax,03h; xor bh,bh; int 10h end;
ExitProc := @old_exit_proc;
If (ExitCode <> 0) then
begin
WriteLn('ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ');
WriteLn('Û ABNORMAL PROGRAM TERMiNATiON Û');
WriteLn('ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß');
WriteLn('PROGRAM VERSION: ',VERSION_STR);
WriteLn('ERROR #'+Num2str(ExitCode,10)+' at '+ExpStrL(Num2str(LONGINT(ErrorAddr),16),8,'0'));
WriteLn('DEBUG INFO -> ',_debug_str_);
WriteLn;
WriteLn('Please send this information with brief description what you were doing');
WriteLn('when you encountered this error to following email address:');
WriteLn;
WriteLn('subz3ro.altair@gmail.com');
WriteLn;
WriteLn('Thanks and sorry for your inconvenience! :-)');
ErrorAddr := NIL;
HALT(ExitCode);
end
else HALT(0);
end;
begin
For temp := 0 to 255 do
_ParamStr[temp] := ParamStr(temp);
asm
mov bx,0ffffh
mov ah,48h
int 21h
mov dos_memavail,bx
end;
If (dos_memavail*16 DIV 1024 < 120) then
begin
If _gfx_mode then _list_title;
WriteLn('ERROR(1) - Insufficient DOS memory!');
HALT(1);
end;
If NOT iVGA then
begin
WriteLn('ERROR(2) - Insufficient video equipment!');
HALT(2);
end;
For temp := 1 to ParamCount do
If (Lower(_ParamStr[temp]) = '/jukebox') then
jukebox := TRUE;
For temp := 1 to ParamCount do
If (Lower(_ParamStr[temp]) = '/latency') then
opl3out := opl2out;
index := 0;
If (ParamCount = 0) then
begin
If _gfx_mode then _list_title;
CWriteLn('Syntax: '+BaseNameOnly(_ParamStr[0])+' files|wildcards [files|wildcards{...}] [options]',$07,0);
CWriteLn('',$07,0);
CWriteLn('Command-line options:',$07,0);
CWriteLn(' /jukebox play modules w/ no repeat',$07,0);
CWriteLn(' /gfx graphical interface',$07,0);
CWriteLn(' /latency compatibility mode for OPL3 latency',$07,0);
HALT;
end;
@old_exit_proc := ExitProc;
ExitProc := @new_exit_proc;
mem_info := GetFPCHeapStatus;
free_mem := mem_info.CurrHeapFree*1000;
error_code := 0;
temp := $80;
Repeat
If (free_mem > PATTERN_SIZE*temp) then
begin
max_patterns := temp;
BREAK;
end
else If (temp-$10 >= $10) then Dec(temp,$10)
else begin
error_code := -2;
BREAK;
end;
until FALSE;
If (error_code <> -2) then
GetMem(pattdata,PATTERN_SIZE*max_patterns);
FillChar(decay_bar,SizeOf(decay_bar),0);
play_status := isStopped;
init_songdata;
init_timer_proc;
If _gfx_mode then
toggle_picture_mode
else begin
FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700);
dosmemput($0b800,0,screen_ptr^,MAX_SCREEN_MEM_SIZE);
GotoXY(1,1);
_list_title;
end;
Repeat
If NOT (index <> 0) then
begin
CWriteLn(FilterStr(DietStr('úù-Ä--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄ--ùú úù-ÄÄ-Äùú',
PRED(MaxCol)),
'.',' '),$01,0);
CWriteLn( ' ~[~SPACE~]~ Fast-Forward ~[~Ä~]~ Restart ~[~ÄÙ~]~ Next ~[~ESC~]~ Quit',$09,$01);
CWriteLn(FilterStr(DietStr('úù-ÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Äùú',
PRED(MaxCol)),
'.',' '),$01,0);
CWriteLn('',$07,0);
_window_top := WhereY;
end;
Inc(index);
If (_ParamStr[index][1] <> '/') then
begin
FindFirst(_ParamStr[index],AnyFile-VolumeID-Directory,dirinfo);
If (DosError <> 0) then
begin
CWriteLn(DietStr('ERROR(2) - No such file "'+
Lower(_ParamStr[index])+'"',
PRED(MaxCol)),$07,0);
CWriteLn('',$07,0);
FindNext(dirinfo);
CONTINUE;
end;
While NOT (DosError <> 0) do
begin
If (PathOnly(_ParamStr[index]) <> '') then
songdata_source := Upper(PathOnly(_ParamStr[index])+dirinfo.name)
else songdata_source := Upper(dirinfo.name);
C3Write(DietStr('Loading "'+songdata_source+'" (please wait)',
PRED(MaxCol)),$07,0,0);
wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color);
wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color);
wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+' ',_pos_str_color);
wtext2(_fname_xpos,_fname_ypos,ExpStrR(NameOnly(songdata_source),12,' '),_fname_color);
wtext(_pos_str_xpos,_pos_str_ypos,ExpStrR('Loading...',35,' '),_pos_str_color);
For temp := 1 to 10 do WaitRetrace;
limit_exceeded := FALSE;
load_flag := BYTE_NULL;
_decay_bars_initialized := FALSE;
// If _gfx_mode then decay_bars_refresh;
a2m_file_loader;
If (load_flag = BYTE_NULL) then a2t_file_loader;
If (load_flag = BYTE_NULL) then amd_file_loader;
If (load_flag = BYTE_NULL) then cff_file_loader;
If (load_flag = BYTE_NULL) then dfm_file_loader;
If (load_flag = BYTE_NULL) then mtk_file_loader;
If (load_flag = BYTE_NULL) then rad_file_loader;
If (load_flag = BYTE_NULL) then s3m_file_loader;
If (load_flag = BYTE_NULL) then fmk_file_loader;
If (load_flag = BYTE_NULL) then sat_file_loader;
If (load_flag = BYTE_NULL) then sa2_file_loader;
If (load_flag = BYTE_NULL) then hsc_file_loader;
If (load_flag = BYTE_NULL) or
(load_flag = $7f) then
begin
CWriteLn(DietStr(ExpStrR('ERROR(3) - Invalid module ('+songdata_source+')',
PRED(MaxCol),' '),
PRED(MaxCol)),$07,0);
CWriteLn('',$07,0);
FindNext(dirinfo);
CONTINUE;
end;
last_order := 0;
entries := 0;
If limit_exceeded then
begin
CWriteLn(DietStr(ExpStrR('ERROR(1) - Insufficient memory!',
PRED(MaxCol),' '),
PRED(MaxCol)),$07,0);
CWriteLn('',$07,0);
FindNext(dirinfo);
CONTINUE;
end;
count_order(entries);
correction := calc_following_order(0);
entries2 := entries;
If (correction <> -1) then Dec(entries,correction)
else entries := 0;
CWriteLn(DietStr(ExpStrR('Playing '+modname[load_flag]+' "'+
songdata_source+'"',
PRED(MaxCol),' '),
PRED(MaxCol)),$07,0);
temp2 := PRED(WhereY);
If (entries = 0) then
begin
If NOT _picture_mode then GotoXY(1,temp2);
CWriteLn(DietStr(ExpStrR('Playing '+modname[load_flag]+' "'+
songdata_source+'"',
PRED(MaxCol),' '),
PRED(MaxCol)),$08,0);
CWriteLn(DietStr(ExpStrR(''+NameOnly(songdata_source)+' [stopped] ['+
ExpStrL(Num2str(TRUNC(time_playing) DIV 60,10),2,'0')+
':'+ExpStrL(Num2str(TRUNC(time_playing) MOD 60,10),2,'0')+']',
PRED(MaxCol),' '),
PRED(MaxCol)),$07,0);
CWriteLn('',$07,0);
FindNext(dirinfo);
CONTINUE;
end;
start_playing;
set_overall_volume(63);
Repeat
If (overall_volume = 63) then
C3Write(DietStr(_position_str+' ',PRED(MaxCol)),$0f,0,0);
wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color);
wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color);
wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+' ',_pos_str_color);
If (inportb($60) = $39) { SPACE pressed } then
begin
If (overall_volume > 32) then
For temp := 63 downto 32 do
begin
set_overall_volume(temp);
delay_counter := 0;
While (delay_counter < overall_volume DIV 20) do
begin
If timer_200hz_flag then
begin
timer_200hz_flag := FALSE;
Inc(delay_counter);
C3Write(DietStr(_position_str+'',PRED(MaxCol)),$0f,0,0);
wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color);
wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color);
wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+'',_pos_str_color);
If timer_50hz_flag then
begin
timer_50hz_flag := FALSE;
If NOT fast_forward then
decay_bars_refresh;
end;
end;
MEMW[0:$041c] := MEMW[0:$041a];
end;
end
else begin
If timer_200hz_flag then
begin
timer_200hz_flag := FALSE;
C3Write(DietStr(_position_str+'',PRED(MaxCol)),$0f,0,0);
wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color);
wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color);
wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+'',_pos_str_color);
If timer_50hz_flag then
begin
timer_50hz_flag := FALSE;
If NOT fast_forward then
decay_bars_refresh;
end;
end;
MEMW[0:$041c] := MEMW[0:$041a];
end;
fast_forward := TRUE;
end
else If (inportb($60) = $0b9) { SPACE released } then
begin
fast_forward := FALSE;
If (overall_volume < 63) then
For temp := 32 to 63 do
begin
set_overall_volume(temp);
delay_counter := 0;
While (delay_counter < overall_volume DIV 20) do
begin
If (timer_200hz_counter = 0) then
begin
Inc(delay_counter);
C3Write(DietStr(_position_str+' ',PRED(MaxCol)),$0f,0,0);
wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color);
wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color);
wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+' ',_pos_str_color);
If timer_50hz_flag then
begin
timer_50hz_flag := FALSE;
decay_bars_refresh;
end;
end;
MEMW[0:$041c] := MEMW[0:$041a];
end;
end;
end;
If (NOT fast_forward and timer_50hz_flag) or
(fast_forward and timer_20hz_flag) then
begin
If NOT fast_forward then timer_50hz_flag := FALSE
else timer_20hz_flag := FALSE;
decay_bars_refresh;
end;
If NOT keypressed then fkey := WORD_NULL
else asm
xor ax,ax
int 16h
mov fkey,ax
end;
MEMW[0:$041c] := MEMW[0:$041a];
If jukebox and (last_order <> current_order) then
begin
If (last_order > current_order) and
(last_order = PRED(entries2)) then BREAK
else last_order := current_order;
end;
If (fkey = kBkSPC) then
begin
fade_out;
stop_playing;
set_overall_volume(63);
start_playing;
end;
until (fkey = kENTER) or
(fkey = kESC);
fade_out;
stop_playing;
If NOT _picture_mode then GotoXY(1,temp2);
CWriteLn(DietStr(ExpStrR('Playing '+modname[load_flag]+' "'+
songdata_source+'"',
PRED(MaxCol),' '),
PRED(MaxCol)),$08,0);
CWriteLn(DietStr(ExpStrR(''+NameOnly(songdata_source)+' [stopped] ['+
ExpStrL(Num2str(TRUNC(time_playing) DIV 60,10),2,'0')+
':'+ExpStrL(Num2str(TRUNC(time_playing) MOD 60,10),2,'0')+']',
PRED(MaxCol),' '),
PRED(MaxCol)),$07,0);
CWriteLn('',$07,0);
If (fkey = kESC) then BREAK;
FindNext(dirinfo);
end;
end;
until (index = ParamCount);
done_timer_proc;
end.
adlibtracker2-2.4.24/adt2play/parserio.pas 0000644 0000000 0000000 00000010021 13411003760 017050 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
unit ParserIO;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
interface
function SensitiveScan(var buf; skip,size: Longint; str: String): Longint;
function Update16(var buf; size: Longint; crc: Word): Word;
function Update32(var buf; size: Longint; crc: Longint): Longint;
implementation
function SensitiveScan(var buf; skip,size: Longint; str: String): Longint;
var
result: Longint;
begin
asm
mov edi,[buf]
add edi,skip
lea esi,[str]
mov ecx,size
sub ecx,skip
xor eax,eax
jecxz @@3
cld
lodsb
cmp al,1
jb @@5
ja @@1
lodsb
repne scasb
jne @@3
jmp @@5
@@1: xor ah,ah
mov ebx,eax
dec ebx
mov edx,ecx
sub edx,eax
jb @@3
lodsb
add edx,2
@@2: dec edx
mov ecx,edx
repne scasb
jne @@3
mov edx,ecx
mov ecx,ebx
rep cmpsb
je @@4
sub ecx,ebx
add esi,ecx
add edi,ecx
inc edi
or edx,edx
jne @@2
@@3: xor eax,eax
jmp @@6
@@4: sub edi,ebx
@@5: mov eax,edi
sub eax,dword ptr [buf]
@@6: dec eax
mov result,eax
end;
SensitiveScan := result;
end;
var
CRC16_table: array[BYTE] of Word;
CRC32_table: array[BYTE] of Longint;
function Update16(var buf; size: Longint; crc: Word): Word;
var
result: Word;
begin
asm
mov esi,[buf]
lea edi,[CRC16_table]
mov bx,crc
mov ecx,size
jecxz @@2
@@1: xor ax,ax
lodsb
mov dl,bh
xor dh,dh
xor bh,bh
xor bx,ax
and ebx,000000ffh
shl ebx,1
mov bx,[edi+ebx]
xor bx,dx
loop @@1
@@2: mov ax,bx
mov result,ax
end;
Update16 := result;
end;
function Update32(var buf; size: Longint; crc: Longint): Longint;
var
result: Longint;
begin
asm
mov esi,[buf]
lea edi,[CRC32_table]
mov ebx,crc
mov ecx,size
jecxz @@2
@@1: xor eax,eax
lodsb
xor ebx,eax
mov edx,ebx
and ebx,000000ffh
shl ebx,2
mov ebx,[edi+ebx]
shr edx,8
and edx,00ffffffh
xor ebx,edx
loop @@1
@@2: mov eax,ebx
mov result,eax
end;
Update32 := result;
end;
procedure make_table_16bit;
var
crc: Word;
n,index: Byte;
begin
For index := 0 to 255 do
begin
crc := index;
For n := 1 to 8 do
If Odd(crc) then crc := crc SHR 1 XOR $0a001
else crc := crc SHR 1;
CRC16_table[index] := crc;
end;
end;
procedure make_table_32bit;
var
crc: Dword;
n,index: Byte;
begin
For index := 0 to 255 do
begin
crc := index;
For n := 1 to 8 do
If Odd(crc) then crc := crc SHR 1 XOR $0edb88320
else crc := crc SHR 1;
CRC32_table[index] := crc;
end;
end;
begin
make_table_16bit;
make_table_32bit;
end.
adlibtracker2-2.4.24/adt2play/stringio.pas 0000644 0000000 0000000 00000022111 13411003760 017065 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
unit StringIO;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
interface
function byte2hex(value: Byte): String;
function byte2dec(value: Byte): String;
function Capitalize(str: String): String;
function Upper(str: String): String;
function Lower(str: String): String;
function ExpStrL(str: String; size: Byte; chr: Char): String;
function ExpStrR(str: String; size: Byte; chr: Char): String;
function DietStr(str: String; size: Byte): String;
function CutStr(str: String): String;
function FilterStr(str: String; chr0,chr1: Char): String;
function Num2str(num: Longint; base: Byte): String;
function Str2num(str: String; base: Byte): Longint;
function PathOnly(path: String): String;
function NameOnly(path: String): String;
function BaseNameOnly(path: String): String;
function ExtOnly(path: String): String;
implementation
uses
DOS;
function byte2hex(value: Byte): String;
const
data: array[0..15] of char = '0123456789ABCDEF';
begin
asm
mov edi,@RESULT
lea ebx,[data]
mov al,2
stosb
mov al,value
xor ah,ah
mov cl,16
div cl
xlat
stosb
mov al,ah
xlat
stosb
end;
end;
function byte2dec(value: Byte): String;
const
data: array[0..9] of char = '0123456789';
begin
asm
mov edi,@RESULT
lea ebx,[data]
mov al,value
xor ah,ah
mov cl,100
div cl
mov ch,ah
xchg ah,al
or ah,ah
jz @@1
mov al,3
stosb
xchg ah,al
xlat
stosb
mov al,ch
jmp @@2
@@1: mov al,2
stosb
mov al,value
@@2: xor ah,ah
mov cl,10
div cl
xlat
stosb
mov al,ah
xlat
stosb
end;
end;
function Capitalize(str: String): String;
begin
asm
lea esi,[str]
mov edi,@RESULT
mov al,[esi]
inc esi
mov [edi],al
inc edi
xor ecx,ecx
mov cl,al
jecxz @@4
mov al,[esi]
inc esi
cmp al,'a'
jb @@0
cmp al,'z'
ja @@0
sub al,20h
@@0: mov [edi],al
inc edi
@@1: mov ah,al
mov al,[esi]
inc esi
cmp ah,' '
jnz @@2
cmp al,'a'
jb @@2
cmp al,'z'
ja @@2
sub al,20h
jmp @@3
@@2: cmp al,'A'
jb @@3
cmp al,'Z'
ja @@3
add al,20h
@@3: mov [edi],al
inc edi
loop @@1
@@4:
end;
end;
function Upper(str: String): String;
begin
asm
lea esi,[str]
mov edi,@RESULT
mov al,[esi]
inc esi
mov [edi],al
inc edi
xor ecx,ecx
mov cl,al
jecxz @@3
@@1: mov al,[esi]
inc esi
cmp al,'a'
jb @@2
cmp al,'z'
ja @@2
sub al,20h
@@2: mov [edi],al
inc edi
loop @@1
@@3:
end;
end;
function Lower(str: String): String;
begin
asm
lea esi,[str]
mov edi,@RESULT
mov al,[esi]
inc esi
mov [edi],al
inc edi
xor ecx,ecx
mov cl,al
jecxz @@3
@@1: mov al,[esi]
inc esi
cmp al,'A'
jb @@2
cmp al,'Z'
ja @@2
add al,20h
@@2: mov [edi],al
inc edi
loop @@1
@@3:
end;
end;
function ExpStrL(str: String; size: Byte; chr: Char): String;
begin
asm
lea esi,[str]
mov edi,@RESULT
cld
xor ecx,ecx
lodsb
cmp al,size
jge @@1
mov ah,al
mov al,size
stosb
mov al,ah
mov cl,size
sub cl,al
mov al,chr
rep stosb
mov cl,ah
rep movsb
jmp @@2
@@1: stosb
mov cl,al
rep movsb
@@2:
end;
end;
function ExpStrR(str: String; size: Byte; chr: Char): String;
begin
asm
lea esi,[str]
mov edi,@RESULT
cld
xor ecx,ecx
lodsb
cmp al,size
jge @@1
mov ah,al
mov al,size
stosb
mov cl,ah
rep movsb
mov al,ah
mov cl,size
sub cl,al
mov al,chr
rep stosb
jmp @@2
@@1: stosb
mov cl,al
rep movsb
@@2:
end;
end;
function DietStr(str: String; size: Byte): String;
begin
If (Length(str) <= size) then
begin
DietStr := str;
EXIT;
end;
Repeat
Delete(str,size DIV 2,1)
until (Length(str)+3 = size);
Insert('...',str,size DIV 2);
DietStr := str
end;
function CutStr(str: String): String;
begin
While (str[0] <> #0) and (str[1] in [#00,#32]) do Delete(str,1,1);
While (str[0] <> #0) and (str[Length(str)] in [#00,#32]) do Delete(str,Length(str),1);
CutStr := str;
end;
function FilterStr(str: String; chr0,chr1: Char): String;
begin
asm
lea esi,[str]
mov edi,@RESULT
mov al,[esi]
inc esi
mov [edi],al
inc edi
xor ecx,ecx
mov cl,al
jecxz @@3
@@1: mov al,[esi]
inc esi
cmp al,chr0
jnz @@2
mov al,chr1
@@2: mov [edi],al
inc edi
loop @@1
@@3:
end;
end;
function Num2str(num: Longint; base: Byte): String;
const
hexa: array[0..PRED(16)+32] of Char = '0123456789ABCDEF'+
#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0;
begin
asm
xor eax,eax
xor edx,edx
xor edi,edi
xor esi,esi
mov eax,num
xor ebx,ebx
mov bl,base
cmp bl,2
jb @@3
cmp bl,16
ja @@3
mov edi,32
@@1: dec edi
xor edx,edx
div ebx
mov esi,edx
mov dl,byte ptr [hexa+esi]
mov byte ptr [hexa+edi+16],dl
and eax,eax
jnz @@1
mov esi,edi
mov ecx,32
sub ecx,edi
mov edi,@RESULT
mov al,cl
stosb
@@2: mov al,byte ptr [hexa+esi+16]
stosb
inc esi
loop @@2
jmp @@4
@@3: mov edi,@RESULT
xor al,al
stosb
@@4:
end;
end;
const
digits: array[0..15] of Char = '0123456789ABCDEF';
function Digit2index(digit: Char): Byte;
var
index: Byte;
begin
digit := UpCase(digit);
index := 15;
While (index > 0) and (digit <> digits[index]) do Dec(index);
Digit2index := Index;
end;
function position_value(position,base: Byte): Longint;
var
value: Longint;
index: Byte;
begin
value := 1;
For index := 2 to position do value := value*base;
position_value := value;
end;
function Str2num(str: String; base: Byte): Longint;
var
value: Longint;
index: Byte;
begin
value := 0;
If (base in [2,10,16]) then
For index := 1 to Length(str) do
Inc(value,Digit2index(str[index])*
position_value(Length(str)-index+1,base));
Str2num := value;
end;
var
dir: DirStr;
name: NameStr;
ext: ExtStr;
function PathOnly(path: String): String;
begin
FSplit(path,dir,name,ext);
PathOnly := dir;
end;
function NameOnly(path: String): String;
begin
If (Pos('\',path) <> 0) then
begin
FSplit(path,dir,name,ext);
NameOnly := name+ext;
end
else NameOnly := path;
end;
function BaseNameOnly(path: String): String;
begin
FSplit(path,dir,name,ext);
BaseNameOnly := name;
end;
function ExtOnly(path: String): String;
begin
FSplit(path,dir,name,ext);
Delete(ext,1,1);
ExtOnly := Lower(ext);
end;
end.
adlibtracker2-2.4.24/adt2play/a2player.pas 0000644 0000000 0000000 00000510365 13411003760 016763 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
unit A2player;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
interface
const
___UNIT_DATA_START___: Dword = 0;
const
MAX_IRQ_FREQ = 1000;
MIN_IRQ_FREQ = 50;
timer_poll_proc_ptr: Pointer = NIL;
timer_initialized: Boolean = FALSE;
{$i typconst.inc}
const
opl3port: Word = $388;
error_code: Integer = 0;
current_order: Byte = 0;
current_pattern: Byte = 0;
current_line: Byte = 0;
tempo: Byte = 50;
speed: Byte = 6;
macro_speedup: Word = 1;
max_patterns: Byte = 128;
fast_forward: Boolean = FALSE;
overall_volume: Byte = 63;
global_volume: Byte = 63;
fade_out_volume: Byte = 63;
const
song_timer: Word = 0;
song_timer_tenths: Word = 0;
ticklooper: Longint = 0;
macro_ticklooper: Longint = 0;
timer_ticklooper: Longint = 0;
timer_200hz_counter: Longint = 0;
timer_50hz_counter: Longint = 0;
timer_20hz_counter: Longint = 0;
timer_200hz_flag: Boolean = FALSE;
timer_50hz_flag: Boolean = FALSE;
timer_20hz_flag: Boolean = FALSE;
var
timer_temp: Word;
ticks,tick0,tickD,
tickXF: Longint;
limit_exceeded: Boolean;
var
time_playing: Real;
pattdata: ^tPATTERN_DATA;
songdata: tFIXED_SONGDATA;
old_songdata: tOLD_FIXED_SONGDATA;
old_hash_buffer: tOLD_VARIABLE_DATA1;
hash_buffer: tOLD_VARIABLE_DATA2;
const
IRQ_freq: Word = 50;
IRQ_freq_shift: Integer = 0;
playback_speed_shift: Longint = 0;
timer_fix: Boolean = TRUE;
pattern_break: Boolean = FALSE;
pattern_break_loop: Boolean = FALSE;
pattern_break_docmd: Boolean = FALSE;
pattern_break_oldord: Byte = BYTE_NULL;
pattern_delay: Boolean = FALSE;
next_line: Byte = 0;
play_status: tPLAY_STATUS = isStopped;
replay_forbidden: Boolean = TRUE;
force_macro_keyon: Boolean = FALSE;
type
tDECAY_BAR = Record
dir: Integer;
lvl,max_lvl: Real;
end;
var
decay_bar: array[1..96] of tDECAY_BAR;
procedure start_playing;
procedure set_overall_volume(level: Byte);
procedure stop_playing;
procedure init_old_songdata;
procedure init_songdata;
procedure init_timer_proc;
procedure done_timer_proc;
procedure get_chunk(pattern,line,chan: Byte; var chunk: tCHUNK);
procedure put_chunk(pattern,line,chan: Byte; chunk: tCHUNK);
procedure count_order(var entries: Byte);
procedure timer_poll_proc;
procedure opl2out_proc(reg,data: Word);
procedure opl3out_proc(reg,data: Word);
procedure opl3exp_proc(data: Word);
procedure DisableTimerIRQ_proc;
procedure EnableTimerIRQ_proc;
function calc_following_order(order: Byte): Integer;
function is_4op_chan(chan: Byte): Boolean;
function min(value: Longint; minimum: Longint): Longint;
function max(value: Longint; maximum: Longint): Longint;
function asciiz_string(str: String): String;
type
tOPLOUT_proc = procedure(reg,data: Word);
tOPLEXP_proc = procedure(data: Word);
const
opl2out: tOPLOUT_proc = opl2out_proc;
opl3out: tOPLOUT_proc = opl3out_proc;
opl3exp: tOPLEXP_proc = opl3exp_proc;
DisableTimerIRQ: procedure = DisableTimerIRQ_proc;
EnableTimerIRQ: procedure = EnableTimerIRQ_proc;
const
___UNIT_DATA_END___: Dword = 0;
implementation
uses
DOS,GO32,ISS_TIM,
A2fileIO;
const
___IRQ_DATA_START___: Dword = 0;
procedure ___IRQ_CODE_START___; begin end;
const
keyoff_flag = $080;
fixed_note_flag = $090;
pattern_loop_flag = $0e0;
pattern_break_flag = $0f0;
const
MACRO_NOTE_RETRIG_FLAG = $80;
MACRO_ENVELOPE_RESTART_FLAG = $40;
MACRO_ZERO_FREQ_FLAG = $20;
const
def_vibtrem_speed_factor: Byte = 1;
def_vibtrem_table_size: Byte = 32;
def_vibtrem_table: array[0..255] of Byte = (
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,
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,
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,
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,
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,
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,
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,
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);
var
vibtrem_speed_factor: Byte;
vibtrem_table_size: Byte;
vibtrem_table: array[0..255] of Byte;
type
tVIBRATO_TREMOLO_TABLE =
array[1..20] of Record
pos: Byte;
dir: Byte;
speed: Byte;
depth: Byte;
fine: Boolean;
end;
var
vibr_table: tVIBRATO_TREMOLO_TABLE;
vibr_table2: tVIBRATO_TREMOLO_TABLE;
trem_table: tVIBRATO_TREMOLO_TABLE;
trem_table2: tVIBRATO_TREMOLO_TABLE;
var
fmpar_table: array[1..20] of tFM_PARAMETER_TABLE;
volume_lock: array[1..20] of Boolean;
vol4op_lock: array[1..20] of Boolean;
volume_table: array[1..20] of Word;
vscale_table: array[1..20] of Word;
peak_lock: array[1..20] of Boolean;
pan_lock: array[1..20] of Boolean;
event_table: array[1..20] of tCHUNK;
voice_table: array[1..20] of Byte;
modulator_vol: array[1..20] of Byte;
carrier_vol: array[1..20] of Byte;
freq_table: array[1..20] of Word;
zero_fq_table: array[1..20] of Word;
effect_table: array[1..20] of Word;
effect_table2: array[1..20] of Word;
fslide_table: array[1..20] of Byte;
fslide_table2: array[1..20] of Byte;
glfsld_table: array[1..20] of Word;
glfsld_table2: array[1..20] of Word;
porta_table: array[1..20] of Record freq: Word; speed: Byte; end;
porta_table2: array[1..20] of Record freq: Word; speed: Byte; end;
portaFK_table: array[1..20] of Boolean;
arpgg_table: array[1..20] of Record state,note,add1,add2: Byte; end;
arpgg_table2: array[1..20] of Record state,note,add1,add2: Byte; end;
retrig_table: array[1..20] of Byte;
retrig_table2: array[1..20] of Byte;
tremor_table: array[1..20] of Record pos: Integer; volume: Word; end;
tremor_table2: array[1..20] of Record pos: Integer; volume: Word; end;
panning_table: array[1..20] of Byte;
last_effect: array[1..20] of Word;
last_effect2: array[1..20] of Word;
volslide_type: array[1..20] of Byte;
event_new: array[1..20] of Boolean;
notedel_table: array[1..20] of Byte;
notecut_table: array[1..20] of Byte;
ftune_table: array[1..20] of Shortint;
keyoff_loop: array[1..20] of Boolean;
macro_table: array[1..20] of Record
fmreg_pos,arpg_pos,vib_pos: Word;
fmreg_count,fmreg_duration,arpg_count,
vib_count,vib_delay: Byte;
vib_paused: Boolean;
fmreg_table,arpg_table,vib_table: Byte;
arpg_note: Byte;
vib_freq: Word;
end;
loopbck_table: array[1..20] of Byte;
loop_table: array[1..20,0..255] of Byte;
misc_register: Byte;
const
current_tremolo_depth: Byte = 0;
current_vibrato_depth: Byte = 0;
var
speed_update,lockvol,panlock,lockVP: Boolean;
tremolo_depth,vibrato_depth: Byte;
volume_scaling,percussion_mode: Boolean;
last_order: Byte;
reset_chan: array[1..20] of Boolean;
var
_opl_regs_cache: array[WORD] of Word;
procedure opl2out_proc(reg,data: Word);
begin
If (_opl_regs_cache[reg] <> data) then
_opl_regs_cache[reg] := data
else EXIT;
asm
mov ax,reg
mov dx,word ptr [opl3port]
or ah,ah
jz @@1
add dx,2
@@1: out dx,al
mov ecx,6
@@2: in al,dx
loop @@2
inc dl
mov ax,data
out dx,al
dec dl
mov ecx,36
@@3: in al,dx
loop @@3
end;
end;
procedure opl3out_proc(reg,data: Word);
begin
If (_opl_regs_cache[reg] <> data) then
_opl_regs_cache[reg] := data
else EXIT;
asm
mov ax,reg
mov dx,word ptr [opl3port]
or ah,ah
jz @@1
add dx,2
@@1: out dx,al
inc dl
mov ax,data
out dx,al
dec dl
mov ecx,26
@@2: in al,dx
loop @@2
end;
end;
procedure opl3exp_proc(data: Word);
begin
if (_opl_regs_cache[(data AND $ff) OR $100] <> data SHR 8) then
_opl_regs_cache[(data AND $ff) OR $100] := data SHR 8
else EXIT;
asm
mov ax,data
mov dx,word ptr [opl3port]
add dx,2
out dx,al
mov ecx,6
@@1: in al,dx
loop @@1
inc dl
mov al,ah
out dx,al
mov ecx,36
@@2: in al,dx
loop @@2
end;
end;
const
FreqStart = $156;
FreqEnd = $2ae;
FreqRange = FreqEnd-FreqStart;
function nFreq(note: Byte): Word;
const
Fnum: array[0..11] of Word = (
$157,$16b,$181,$198,$1b0,$1ca,$1e5,$202,$220,$241,$263,$287);
var
result: Word;
begin
asm
xor ebx,ebx
mov al,[note]
xor ah,ah
cmp ax,12*8
jae @@1
push eax
mov bl,12
div bl
mov bl,ah
xor bh,bh
shl bx,1
pop eax
mov cl,12
div cl
xor ah,ah
shl ax,10
add ax,word ptr [Fnum+ebx]
jmp @@2
@@1: mov ax,7
shl ax,10
add ax,FreqEnd
@@2: mov result,ax
end;
nFreq := result;
end;
function calc_freq_shift_up(freq,shift: Word): Word;
var
result: Word;
begin
asm
mov cx,freq
mov ax,shift
mov bx,cx
and bx,0000001111111111b
mov dx,cx
and dx,0001110000000000b
add bx,ax
and cx,1110000000000000b
shr dx,10
cmp bx,FreqEnd
jb @@2
cmp dx,7
jnz @@1
mov bx,FreqEnd
jmp @@2
@@1: sub bx,FreqRange
inc dx
@@2: mov ax,cx
shl dx,10
add ax,dx
add ax,bx
mov result,ax
end;
calc_freq_shift_up := result;
end;
function calc_freq_shift_down(freq,shift: Word): Word;
var
result: Word;
begin
asm
mov cx,freq
mov ax,shift
mov bx,cx
and bx,0000001111111111b
mov dx,cx
and dx,0001110000000000b
sub bx,ax
and cx,1110000000000000b
shr dx,10
cmp bx,FreqStart
ja @@2
or dx,dx
jnz @@1
mov bx,FreqStart
jmp @@2
@@1: add bx,FreqRange
dec dx
@@2: mov ax,cx
shl dx,10
add ax,dx
add ax,bx
mov result,ax
end;
calc_freq_shift_down := result;
end;
function calc_vibtrem_shift(chan: Byte; var table_data): Word;
var
pos,dir,depth: Byte;
result: Word;
begin
pos := tVIBRATO_TREMOLO_TABLE(table_data)[chan].pos;
depth := tVIBRATO_TREMOLO_TABLE(table_data)[chan].depth;
asm
xor ebx,ebx
mov al,depth
xor ah,ah
mov bl,pos
xor bh,bh
mov dh,bl
mov cl,byte ptr [vibtrem_table_size]
dec cl
and bl,cl
mov dl,byte ptr [vibtrem_table+ebx]
mul dl
rol ax,1
xchg ah,al
and ah,1
mov dir,1
mov dl,byte ptr [vibtrem_table_size]
test dh,dl
jne @@1
mov dir,0
@@1: mov result,ax
end;
tVIBRATO_TREMOLO_TABLE(table_data)[chan].dir := dir;
calc_vibtrem_shift := result;
end;
procedure change_freq(chan: Byte; freq: Word);
begin
If is_4op_chan(chan) and (chan in _4op_tracks_hi) then
begin
freq_table[SUCC(chan)] := freq_table[chan];
chan := SUCC(chan);
end;
asm
xor ebx,ebx
mov bl,chan
dec ebx
shl ebx,1
mov ax,freq
and ax,1fffh
mov dx,word ptr [freq_table+ebx]
and dx,NOT 1fffh
add ax,dx
mov word ptr [freq_table+ebx],ax
xor edx,edx
mov dx,word ptr [_chan_n+ebx]
add dx,0a0h
push edx
xor edx,edx
mov dl,al
push edx
mov dx,word ptr [_chan_n+ebx]
add dx,0b0h
push edx
xor edx,edx
mov dl,ah
push edx
call opl3out
call opl3out
@@1:
end;
If is_4op_chan(chan) then
freq_table[PRED(chan)] := freq_table[chan];
end;
function ins_parameter(ins,param: Byte): Byte;
var
result: Byte;
begin
asm
xor ebx,ebx
lea esi,[songdata.instr_data]
mov bl,ins
dec ebx
mov eax,INSTRUMENT_SIZE
mul ebx
add esi,eax
mov bl,param
add esi,ebx
lodsb
mov result,al
end;
ins_parameter := result;
end;
function is_chan_adsr_data_empty(chan: Byte): Boolean;
begin
is_chan_adsr_data_empty :=
(fmpar_table[chan].adsrw_car.attck = 0) and
(fmpar_table[chan].adsrw_mod.attck = 0) and
(fmpar_table[chan].adsrw_car.dec = 0) and
(fmpar_table[chan].adsrw_mod.dec = 0) and
(fmpar_table[chan].adsrw_car.sustn = 0) and
(fmpar_table[chan].adsrw_mod.sustn = 0) and
(fmpar_table[chan].adsrw_car.rel = 0) and
(fmpar_table[chan].adsrw_mod.rel = 0);
end;
function is_ins_adsr_data_empty(ins: Byte): Boolean;
begin
is_ins_adsr_data_empty :=
(ins_parameter(ins,5) SHR 4 = 0) and
(ins_parameter(ins,4) SHR 4 = 0) and
(ins_parameter(ins,5) AND $0f = 0) and
(ins_parameter(ins,4) AND $0f = 0) and
(ins_parameter(ins,7) SHR 4 = 0) and
(ins_parameter(ins,6) SHR 4 = 0) and
(ins_parameter(ins,7) AND $0f = 0) and
(ins_parameter(ins,6) AND $0f = 0);
end;
function is_data_empty(var buf; size: Longint): Boolean;
var
result: Boolean;
begin
asm
xor edx,edx
mov eax,size
cmp eax,16
jb @@3
mov ecx,4
div ecx
mov ecx,eax
jecxz @@1
mov edi,[buf]
xor eax,eax
repz scasd
jnz @@2
mov ecx,edx
jecxz @@1
repz scasb
jnz @@2
@@1: mov result,TRUE
jmp @@6
@@2: mov result,FALSE
jmp @@6
@@3: mov ecx,size
jecxz @@4
mov edi,[buf]
xor eax,eax
repz scasb
jnz @@5
@@4: mov result,TRUE
jmp @@6
@@5: mov result,FALSE
@@6:
end;
is_data_empty := result;
end;
function min(value: Longint; minimum: Longint): Longint;
begin
If (value > minimum) then min := value
else min := minimum;
end;
function max(value: Longint; maximum: Longint): Longint;
begin
If (value < maximum) then max := value
else max := maximum;
end;
function asciiz_string(str: String): String;
begin
If (Pos(#0,str) <> 0) then asciiz_string := Copy(str,1,Pos(#0,str)-1)
else asciiz_string := '';
end;
function concw(lo,hi: Byte): Word;
begin
concw := lo+(hi SHL 8);
end;
procedure synchronize_song_timer;
begin
song_timer := TRUNC(time_playing);
song_timer_tenths := TRUNC(time_playing*100) MOD 100;
timer_temp := song_timer_tenths;
end;
procedure change_frequency(chan: Byte; freq: Word);
begin
macro_table[chan].vib_paused := TRUE;
change_freq(chan,freq);
If is_4op_chan(chan) then
If (chan in _4op_tracks_hi) then
begin
macro_table[SUCC(chan)].vib_count := 1;
macro_table[SUCC(chan)].vib_pos := 0;
macro_table[SUCC(chan)].vib_freq := freq;
macro_table[SUCC(chan)].vib_paused := FALSE;
end
else
begin
macro_table[PRED(chan)].vib_count := 1;
macro_table[PRED(chan)].vib_pos := 0;
macro_table[PRED(chan)].vib_freq := freq;
macro_table[PRED(chan)].vib_paused := FALSE;
end;
macro_table[chan].vib_count := 1;
macro_table[chan].vib_pos := 0;
macro_table[chan].vib_freq := freq;
macro_table[chan].vib_paused := FALSE;
end;
function _macro_speedup: Word;
begin
If (macro_speedup > 0) then _macro_speedup := macro_speedup
else _macro_speedup := macro_speedup+1;
end;
procedure TimerSetup(Hz: Longint); forward;
procedure update_timer(Hz: Word);
begin
If (Hz = 0) then begin TimerSetup(18); EXIT end
else tempo := Hz;
If (tempo = 18) and timer_fix then IRQ_freq := TRUNC((tempo+0.2)*20)
else IRQ_freq := 250;
While (IRQ_freq MOD (tempo*_macro_speedup) <> 0) do Inc(IRQ_freq);
If (IRQ_freq > MAX_IRQ_FREQ) then IRQ_freq := MAX_IRQ_FREQ;
While (IRQ_freq+IRQ_freq_shift+playback_speed_shift > MAX_IRQ_FREQ) and
(playback_speed_shift > 0) do
Dec(playback_speed_shift);
While (IRQ_freq+IRQ_freq_shift+playback_speed_shift > MAX_IRQ_FREQ) and
(IRQ_freq_shift > 0) do
Dec(IRQ_freq_shift);
TimerSetup(max(IRQ_freq+IRQ_freq_shift+playback_speed_shift,MAX_IRQ_FREQ));
end;
procedure update_playback_speed(speed_shift: Longint);
begin
If (speed_shift = 0) then EXIT
else If (speed_shift > 0) and (IRQ_freq+playback_speed_shift+speed_shift > MAX_IRQ_FREQ) then
While (IRQ_freq+IRQ_freq_shift+playback_speed_shift+speed_shift > MAX_IRQ_FREQ) do
Dec(speed_shift)
else If (speed_shift < 0) and (IRQ_freq+IRQ_freq_shift+playback_speed_shift+speed_shift < MIN_IRQ_FREQ) then
While (IRQ_freq+IRQ_freq_shift+playback_speed_shift+speed_shift < MIN_IRQ_FREQ) do
Inc(speed_shift);
playback_speed_shift := playback_speed_shift+speed_shift;
update_timer(tempo);
end;
procedure key_on(chan: Byte);
begin
If NOT (is_4op_chan(chan) and (chan in _4op_tracks_hi)) then
opl3out($0b0+_chan_n[chan],0)
else opl3out($0b0+_chan_n[SUCC(chan)],0);
end;
procedure key_off(chan: Byte);
begin
freq_table[chan] := LO(freq_table[chan])+
(HI(freq_table[chan]) AND NOT $20) SHL 8;
change_freq(chan,freq_table[chan]);
event_table[chan].note := event_table[chan].note OR keyoff_flag;
end;
procedure release_sustaining_sound(chan: Byte);
begin
opl3out(_instr[02]+_chan_m[chan],63);
opl3out(_instr[03]+_chan_c[chan],63);
FillChar(fmpar_table[chan].adsrw_car,
SizeOf(fmpar_table[chan].adsrw_car),0);
FillChar(fmpar_table[chan].adsrw_mod,
SizeOf(fmpar_table[chan].adsrw_mod),0);
key_on(chan);
opl3out(_instr[04]+_chan_m[chan],BYTE_NULL);
opl3out(_instr[05]+_chan_c[chan],BYTE_NULL);
opl3out(_instr[06]+_chan_m[chan],BYTE_NULL);
opl3out(_instr[07]+_chan_c[chan],BYTE_NULL);
key_off(chan);
event_table[chan].instr_def := 0;
reset_chan[chan] := TRUE;
end;
function scale_volume(volume,scale_factor: Byte): Byte;
begin
scale_volume := 63-Round((63-volume)/63*
(63-scale_factor));
end;
function _4op_data_flag(chan: Byte): Dword;
var
_4op_conn: Byte;
_4op_mode: Boolean;
_4op_ch1,_4op_ch2: Byte;
_4op_ins1,_4op_ins2: Byte;
begin
_4op_mode := FALSE;
If is_4op_chan(chan) then
begin
_4op_mode := TRUE;
If (chan in _4op_tracks_hi) then
begin
_4op_ch1 := chan;
_4op_ch2 := SUCC(chan);
end
else
begin
_4op_ch1 := PRED(chan);
_4op_ch2 := chan;
end;
_4op_ins1 := event_table[_4op_ch1].instr_def;
If (_4op_ins1 = 0) then _4op_ins1 := voice_table[_4op_ch1];
_4op_ins2 := event_table[_4op_ch2].instr_def;
If (_4op_ins2 = 0) then _4op_ins2 := voice_table[_4op_ch2];
If (_4op_ins1 <> 0) and (_4op_ins2 <> 0) then
begin
_4op_mode := TRUE;
_4op_conn := (pBYTE(@Addr(songdata.instr_data[_4op_ins1])^)[_instr_data_ofs[11]] AND 1) SHL 1 +
(pBYTE(@Addr(songdata.instr_data[_4op_ins2])^)[_instr_data_ofs[11]] AND 1);
end;
end;
{------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---}
{ BIT |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0 }
{------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---}
{ DATA |..|..|..|..|..|F7|F6|F5|F4|F3|F2|F1|F0|E7|E6|E5|E4|E3|E2|E1|E0|D3|D2|D1|D0|C3|C2|C1|C0|B1|B0|A0 }
{------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---}
_4op_data_flag := ORD(_4op_mode) + {1-bit: A0}
(_4op_conn AND 3) SHL 1 + {2-bit: B1-B0}
(_4op_ch1 AND 15) SHL 3 + {4-bit: C3-C0}
(_4op_ch2 AND 15) SHL 7 + {4-bit: D3-D0}
_4op_ins1 SHL 11 + {8-bit: E7-E0}
_4op_ins2 SHL 19; {8-bit: F7-F0}
end;
function _4op_vol_valid_chan(chan: Byte): Boolean;
var
_4op_flag: Dword;
begin
_4op_flag := _4op_data_flag(chan);
_4op_vol_valid_chan := BOOLEAN(_4op_flag AND 1) and vol4op_lock[chan] and
(BYTE(_4op_flag SHR 11) <> 0) and
(BYTE(_4op_flag SHR 19) <> 0);
end;
procedure set_ins_volume(modulator,carrier,chan: Byte);
var
temp: Byte;
begin
If (modulator <> BYTE_NULL) then
begin
temp := modulator;
If volume_scaling then
If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
(percussion_mode and (chan in [17..20])) then
modulator := scale_volume(ins_parameter(voice_table[chan],2) AND $3f,modulator);
If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
(percussion_mode and (chan in [17..20])) then
opl3out(_instr[02]+_chan_m[chan],
scale_volume(scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+LO(vscale_table[chan]))
else
opl3out(_instr[02]+_chan_m[chan],
temp+LO(vscale_table[chan]));
volume_table[chan] := concw(temp,HI(volume_table[chan]));
If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
(percussion_mode and (chan in [17..20])) then
modulator_vol[chan] := 63-scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume))
else modulator_vol[chan] := 63-modulator;
end;
If (carrier <> BYTE_NULL) then
begin
temp := carrier;
If volume_scaling then
carrier := scale_volume(ins_parameter(voice_table[chan],3) AND $3f,carrier);
opl3out(_instr[03]+_chan_c[chan],
scale_volume(scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+HI(vscale_table[chan]));
volume_table[chan] := concw(LO(volume_table[chan]),temp);
carrier_vol[chan] := 63-scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume));
end;
end;
procedure set_ins_volume_4op(volume,chan: Byte);
var
_4op_flag: Dword;
_4op_conn: Byte;
_4op_ch1,_4op_ch2: Byte;
procedure set_volume(modulator,carrier,chan: Byte);
var
temp: Byte;
begin
If (modulator <> BYTE_NULL) then
begin
temp := modulator;
modulator := scale_volume(ins_parameter(voice_table[chan],2) AND $3f,modulator);
opl3out(_instr[02]+_chan_m[chan],
scale_volume(scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+LO(vscale_table[chan]));
volume_table[chan] := concw(temp,HI(volume_table[chan]));
modulator_vol[chan] := 63-scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume))
end;
If (carrier <> BYTE_NULL) then
begin
temp := carrier;
carrier := scale_volume(ins_parameter(voice_table[chan],3) AND $3f,carrier);
opl3out(_instr[03]+_chan_c[chan],
scale_volume(scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+HI(vscale_table[chan]));
volume_table[chan] := concw(LO(volume_table[chan]),temp);
carrier_vol[chan] := 63-scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume));
end;
end;
begin
_4op_flag := _4op_data_flag(chan);
_4op_conn := (_4op_flag SHR 1) AND 3;
_4op_ch1 := (_4op_flag SHR 3) AND 15;
_4op_ch2 := (_4op_flag SHR 7) AND 15;
If _4op_vol_valid_chan(chan) then
Case _4op_conn of
// FM/FM
0: If (volume = BYTE_NULL) then
set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1)
else set_volume(BYTE_NULL,volume,_4op_ch1);
// FM/AM
1: If (volume = BYTE_NULL) then
begin
set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1);
set_volume(LO(volume_table[_4op_ch2]),BYTE_NULL,_4op_ch2);
end
else begin
set_volume(BYTE_NULL,volume,_4op_ch1);
set_volume(volume,BYTE_NULL,_4op_ch2);
end;
// AM/FM
2: If (volume = BYTE_NULL) then
begin
set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1);
set_volume(BYTE_NULL,HI(volume_table[_4op_ch2]),_4op_ch2);
end
else begin
set_volume(BYTE_NULL,volume,_4op_ch1);
set_volume(BYTE_NULL,volume,_4op_ch2);
end;
// AM/AM
3: If (volume = BYTE_NULL) then
begin
set_volume(LO(volume_table[_4op_ch1]),HI(volume_table[_4op_ch1]),_4op_ch1);
set_volume(LO(volume_table[_4op_ch2]),BYTE_NULL,_4op_ch2);
end
else begin
set_volume(volume,volume,_4op_ch1);
set_volume(volume,BYTE_NULL,_4op_ch2);
end;
end;
end;
procedure reset_ins_volume(chan: Byte);
begin
If NOT volume_scaling then
set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f,
ins_parameter(voice_table[chan],3) AND $3f,chan)
else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f,0,chan)
else set_ins_volume(0,0,chan);
end;
procedure set_global_volume;
var
chan: Byte;
begin
For chan := 1 to songdata.nm_tracks do
If _4op_vol_valid_chan(chan) then
set_ins_volume_4op(BYTE_NULL,chan)
else If NOT ((carrier_vol[chan] = 0) and
(modulator_vol[chan] = 0)) then
If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(BYTE_NULL,HI(volume_table[chan]),chan)
else set_ins_volume(LO(volume_table[chan]),HI(volume_table[chan]),chan);
end;
procedure set_overall_volume(level: Byte);
begin
overall_volume := max(level,63);
set_global_volume;
end;
procedure init_macro_table(chan,note,ins: Byte; freq: Word);
begin
macro_table[chan].fmreg_count := 1;
macro_table[chan].fmreg_pos := 0;
macro_table[chan].fmreg_duration := 0;
macro_table[chan].fmreg_table := ins;
macro_table[chan].arpg_count := 1;
macro_table[chan].arpg_pos := 0;
macro_table[chan].arpg_table := songdata.instr_macros[ins].arpeggio_table;
macro_table[chan].arpg_note := note;
macro_table[chan].vib_count := 1;
macro_table[chan].vib_paused := FALSE;
macro_table[chan].vib_pos := 0;
macro_table[chan].vib_table := songdata.instr_macros[ins].vibrato_table;
macro_table[chan].vib_freq := freq;
macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay;
zero_fq_table[chan] := 0;
end;
procedure set_ins_data(ins,chan: Byte);
var
old_ins: Byte;
begin
If (ins <> event_table[chan].instr_def) or reset_chan[chan] then
begin
opl3out(_instr[02]+_chan_m[chan],63);
opl3out(_instr[03]+_chan_c[chan],63);
If NOT pan_lock[chan] then
panning_table[chan] := ins_parameter(ins,11)
else panning_table[chan] := songdata.lock_flags[chan] AND 3;
opl3out(_instr[00]+_chan_m[chan],ins_parameter(ins,0));
opl3out(_instr[01]+_chan_c[chan],ins_parameter(ins,1));
opl3out(_instr[04]+_chan_m[chan],ins_parameter(ins,4));
opl3out(_instr[05]+_chan_c[chan],ins_parameter(ins,5));
opl3out(_instr[06]+_chan_m[chan],ins_parameter(ins,6));
opl3out(_instr[07]+_chan_c[chan],ins_parameter(ins,7));
opl3out(_instr[08]+_chan_m[chan],ins_parameter(ins,8));
opl3out(_instr[09]+_chan_c[chan],ins_parameter(ins,9));
opl3out(_instr[10]+_chan_n[chan],ins_parameter(ins,10) OR _panning[panning_table[chan]]);
fmpar_table[chan].connect := ins_parameter(ins,10) AND 1;
fmpar_table[chan].feedb := ins_parameter(ins,10) SHR 1 AND 7;
fmpar_table[chan].multipM := ins_parameter(ins,0) AND $0f;
fmpar_table[chan].kslM := ins_parameter(ins,2) SHR 6;
fmpar_table[chan].tremM := ins_parameter(ins,0) SHR 7;
fmpar_table[chan].vibrM := ins_parameter(ins,0) SHR 6 AND 1;
fmpar_table[chan].ksrM := ins_parameter(ins,0) SHR 4 AND 1;
fmpar_table[chan].sustM := ins_parameter(ins,0) SHR 5 AND 1;
fmpar_table[chan].multipC := ins_parameter(ins,1) AND $0f;
fmpar_table[chan].kslC := ins_parameter(ins,3) SHR 6;
fmpar_table[chan].tremC := ins_parameter(ins,1) SHR 7;
fmpar_table[chan].vibrC := ins_parameter(ins,1) SHR 6 AND 1;
fmpar_table[chan].ksrC := ins_parameter(ins,1) SHR 4 AND 1;
fmpar_table[chan].sustC := ins_parameter(ins,1) SHR 5 AND 1;
fmpar_table[chan].adsrw_car.attck := ins_parameter(ins,5) SHR 4;
fmpar_table[chan].adsrw_mod.attck := ins_parameter(ins,4) SHR 4;
fmpar_table[chan].adsrw_car.dec := ins_parameter(ins,5) AND $0f;
fmpar_table[chan].adsrw_mod.dec := ins_parameter(ins,4) AND $0f;
fmpar_table[chan].adsrw_car.sustn := ins_parameter(ins,7) SHR 4;
fmpar_table[chan].adsrw_mod.sustn := ins_parameter(ins,6) SHR 4;
fmpar_table[chan].adsrw_car.rel := ins_parameter(ins,7) AND $0f;
fmpar_table[chan].adsrw_mod.rel := ins_parameter(ins,6) AND $0f;
fmpar_table[chan].adsrw_car.wform := ins_parameter(ins,9) AND $07;
fmpar_table[chan].adsrw_mod.wform := ins_parameter(ins,8) AND $07;
If NOT reset_chan[chan] then
keyoff_loop[chan] := FALSE;
If reset_chan[chan] then
begin
voice_table[chan] := ins;
reset_ins_volume(chan);
reset_chan[chan] := FALSE;
end;
If (event_table[chan].note AND $7f in [1..12*8+1]) then
init_macro_table(chan,event_table[chan].note AND $7f,ins,freq_table[chan])
else init_macro_table(chan,0,ins,freq_table[chan]);
end;
vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6,
fmpar_table[chan].kslC SHL 6);
voice_table[chan] := ins;
old_ins := event_table[chan].instr_def;
event_table[chan].instr_def := ins;
If NOT volume_lock[chan] or (ins <> old_ins) then
reset_ins_volume(chan);
end;
procedure update_modulator_adsrw(chan: Byte);
begin
opl3out(_instr[04]+_chan_m[chan],
fmpar_table[chan].adsrw_mod.attck SHL 4+
fmpar_table[chan].adsrw_mod.dec);
opl3out(_instr[06]+_chan_m[chan],
fmpar_table[chan].adsrw_mod.sustn SHL 4+
fmpar_table[chan].adsrw_mod.rel);
opl3out(_instr[08]+_chan_m[chan],
fmpar_table[chan].adsrw_mod.wform);
end;
procedure update_carrier_adsrw(chan: Byte);
begin
opl3out(_instr[05]+_chan_c[chan],
fmpar_table[chan].adsrw_car.attck SHL 4+
fmpar_table[chan].adsrw_car.dec);
opl3out(_instr[07]+_chan_c[chan],
fmpar_table[chan].adsrw_car.sustn SHL 4+
fmpar_table[chan].adsrw_car.rel);
opl3out(_instr[09]+_chan_c[chan],
fmpar_table[chan].adsrw_car.wform);
end;
procedure update_fmpar(chan: Byte);
begin
opl3out(_instr[00]+_chan_m[chan],fmpar_table[chan].multipM+
fmpar_table[chan].ksrM SHL 4+
fmpar_table[chan].sustM SHL 5+
fmpar_table[chan].vibrM SHL 6+
fmpar_table[chan].tremM SHL 7);
opl3out(_instr[01]+_chan_c[chan],fmpar_table[chan].multipC+
fmpar_table[chan].ksrC SHL 4+
fmpar_table[chan].sustC SHL 5+
fmpar_table[chan].vibrC SHL 6+
fmpar_table[chan].tremC SHL 7);
opl3out(_instr[10]+_chan_n[chan],(fmpar_table[chan].connect+
fmpar_table[chan].feedb SHL 1) OR
_panning[panning_table[chan]]);
vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6,
fmpar_table[chan].kslC SHL 6);
set_ins_volume(LO(volume_table[chan]),
HI(volume_table[chan]),chan);
end;
function is_4op_chan(chan: Byte): Boolean;
var
result: Boolean;
begin
asm
mov al,byte ptr [songdata.flag_4op]
mov ah,chan
test al,1
jz @@1
cmp ah,1
jb @@1
cmp ah,2
ja @@1
mov result,TRUE
jmp @@7
@@1: test al,2
jz @@2
cmp ah,3
jb @@2
cmp ah,4
ja @@2
mov result,TRUE
jmp @@7
@@2: test al,4
jz @@3
cmp ah,5
jb @@3
cmp ah,6
ja @@3
mov result,TRUE
jmp @@7
@@3: test al,8
jz @@4
cmp ah,10
jb @@4
cmp ah,11
ja @@4
mov result,TRUE
jmp @@7
@@4: test al,10h
jz @@5
cmp ah,12
jb @@5
cmp ah,13
ja @@5
mov result,TRUE
jmp @@7
@@5: test al,20h
jz @@6
cmp ah,14
jb @@6
cmp ah,15
ja @@6
mov result,TRUE
jmp @@7
@@6: mov result,FALSE
@@7:
end;
is_4op_chan := result;
end;
procedure output_note(note,ins,chan: Byte;
restart_macro,restart_adsr: Boolean);
var
pos: Byte;
freq: Word;
begin
If (note = 0) and (ftune_table[chan] = 0) then EXIT;
If NOT (note in [1..12*8+1]) then freq := freq_table[chan]
else begin
freq := nFreq(note-1)+SHORTINT(ins_parameter(ins,12));
If restart_adsr then key_on(chan);
freq_table[chan] := concw(LO(freq_table[chan]),
HI(freq_table[chan]) OR $20);
pos := Round(25/(12*8+1)*note);
If (decay_bar[pos].lvl <> 0) then
If (pos > 1) and
(decay_bar[pos-1].dir <> 1) then
Dec(pos)
else If (pos < 25) and
(decay_bar[pos+1].lvl <> 1) then
Inc(pos);
If is_4op_chan(chan) then
begin
decay_bar[pos].dir := 1;
If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
decay_bar[pos].max_lvl :=
(carrier_vol[PRED(chan)]+carrier_vol[chan]) DIV 2
else decay_bar[pos].max_lvl :=
(carrier_vol[PRED(chan)]+modulator_vol[PRED(chan)]+
carrier_vol[chan]+modulator_vol[chan]) DIV 4;
end
else
begin
decay_bar[pos].dir := 1;
If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
decay_bar[pos].max_lvl :=
carrier_vol[chan]
else decay_bar[pos].max_lvl :=
(carrier_vol[chan]+modulator_vol[chan]) DIV 2;
end;
end;
If (ftune_table[chan] = -127) then ftune_table[chan] := 0;
freq := freq+ftune_table[chan];
change_frequency(chan,freq);
If (note <> 0) then
begin
event_table[chan].note := note;
If is_4op_chan(chan) then
event_table[PRED(chan)].note := note;
If restart_macro then
With event_table[chan] do
If NOT (((effect_def = ef_Extended) and
(effect DIV 16 = ef_ex_ExtendedCmd2) and
(effect MOD 16 = ef_ex_cmd2_NoRestart)) or
((effect_def2 = ef_Extended) and
(effect2 DIV 16 = ef_ex_ExtendedCmd2) and
(effect2 MOD 16 = ef_ex_cmd2_NoRestart))) then
init_macro_table(chan,note,ins,freq)
else macro_table[chan].arpg_note := note;
end;
end;
procedure generate_custom_vibrato(value: Byte);
const
vibtab_size: array[0..15] of Byte = (
16,16,16,16,32,32,32,32,64,64,64,64,128,128,128,128);
var
mul_r: Real;
mul_b: Byte;
idx,idx2: Byte;
function min0(value: Longint): Longint;
begin
If (value >= 0) then min0 := value
else min0 := 0;
end;
begin
Case value of
// set default speed table
0: begin
vibtrem_table_size := def_vibtrem_table_size;
Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table));
end;
// set custom speed table (fixed size = 32)
1..239:
begin
vibtrem_table_size := def_vibtrem_table_size;
mul_r := value/16;
For idx2 := 0 to 7 do
begin
vibtrem_table[idx2*32] := 0;
For idx := 1 to 16 do
vibtrem_table[idx2*32+idx] := ROUND(idx*mul_r);
For idx := 17 to 31 do
vibtrem_table[idx2*32+idx] := ROUND((32-idx)*mul_r);
end;
end;
// set custom speed table (speed factor = 1-4)
240..255:
begin
vibtrem_speed_factor := SUCC((value-240) MOD 4);
vibtrem_table_size := 2*vibtab_size[value-240];
mul_b := 256 DIV (vibtab_size[value-240]);
For idx2 := 0 to PRED(128 DIV vibtab_size[value-240]) do
begin
vibtrem_table[2*vibtab_size[value-240]*idx2] := 0;
For idx := 1 to vibtab_size[value-240] do
vibtrem_table[2*vibtab_size[value-240]*idx2+idx] :=
min0(idx*mul_b-1);
For idx := vibtab_size[value-240]+1 to
2*vibtab_size[value-240]-1 do
vibtrem_table[2*vibtab_size[value-240]*idx2+idx] :=
min0((2*vibtab_size[value-240]-idx)*mul_b-1);
end;
end;
end;
end;
procedure update_fine_effects(chan: Byte); forward;
procedure play_line;
var
chan,idx: Byte;
event: array[1..20] of tCHUNK;
eLo,eHi,eLo2,eHi2: array[1..20] of Byte;
tporta_flag: Boolean;
function no_loop(current_chan,current_line: Byte): Boolean;
var
result: Boolean;
chan: Byte;
begin
result := TRUE;
For chan := 1 to PRED(current_chan) do
If (loop_table[chan][current_line] <> 0) and
(loop_table[chan][current_line] <> BYTE_NULL) then
begin
result := FALSE;
BREAK;
end;
no_loop := result;
end;
begin
_debug_str_ := 'A2PLAYER.PAS:play_line';
If (current_line = 0) and
(current_order = calc_following_order(0)) then
time_playing := 0;
If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and
(current_order <> last_order) then
begin
FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL);
FillChar(loop_table,SizeOf(loop_table),BYTE_NULL);
last_order := current_order;
end;
For chan := 1 to songdata.nm_tracks do
begin
event[chan] := pattdata^[current_pattern DIV 8][current_pattern MOD 8]
[chan][current_line];
If (effect_table[chan] <> 0) then last_effect[chan] := effect_table[chan];
If (glfsld_table[chan] <> 0) then effect_table[chan] := glfsld_table[chan]
else effect_table[chan] := effect_table[chan] AND $0ff00;
If (effect_table2[chan] <> 0) then last_effect2[chan] := effect_table2[chan];
If (glfsld_table2[chan] <> 0) then effect_table2[chan] := glfsld_table2[chan]
else effect_table2[chan] := effect_table2[chan] AND $0ff00;
ftune_table[chan] := 0;
If (event[chan].note = BYTE_NULL) then
event[chan].note := event_table[chan].note OR keyoff_flag
else If (event[chan].note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then
event[chan].note := event[chan].note-fixed_note_flag;
If (event[chan].note <> 0) or
(event[chan].effect_def <> 0) or
(event[chan].effect_def2 <> 0) or
((event[chan].effect_def = 0) and (event[chan].effect <> 0)) or
((event[chan].effect_def2 = 0) and (event[chan].effect2 <> 0)) then
event_new[chan] := TRUE
else event_new[chan] := FALSE;
If (event[chan].note <> 0) or
(event[chan].instr_def <> 0) or
(event[chan].effect_def+event[chan].effect <> 0) or
(event[chan].effect_def2+event[chan].effect2 <> 0) then
begin
event_table[chan].effect_def := event[chan].effect_def;
event_table[chan].effect := event[chan].effect;
event_table[chan].effect_def2 := event[chan].effect_def2;
event_table[chan].effect2 := event[chan].effect2;
end;
If (event[chan].instr_def <> 0) then
If NOT is_data_empty(songdata.instr_data[event[chan].instr_def],
INSTRUMENT_SIZE) then
set_ins_data(event[chan].instr_def,chan)
else begin
release_sustaining_sound(chan);
set_ins_data(event[chan].instr_def,chan);
end;
If NOT (event[chan].effect_def in [ef_Vibrato,ef_ExtraFineVibrato,
ef_VibratoVolSlide,ef_VibratoVSlideFine]) then
FillChar(vibr_table[chan],SizeOf(vibr_table[chan]),0);
If NOT (event[chan].effect_def2 in [ef_Vibrato,ef_ExtraFineVibrato,
ef_VibratoVolSlide,ef_VibratoVSlideFine]) then
FillChar(vibr_table2[chan],SizeOf(vibr_table2[chan]),0);
If NOT (event[chan].effect_def in [ef_RetrigNote,ef_MultiRetrigNote]) then
FillChar(retrig_table[chan],SizeOf(retrig_table[chan]),0);
If NOT (event[chan].effect_def2 in [ef_RetrigNote,ef_MultiRetrigNote]) then
FillChar(retrig_table2[chan],SizeOf(retrig_table2[chan]),0);
If NOT (event[chan].effect_def in [ef_Tremolo,ef_ExtraFineTremolo]) then
FillChar(trem_table[chan],SizeOf(trem_table[chan]),0);
If NOT (event[chan].effect_def2 in [ef_Tremolo,ef_ExtraFineTremolo]) then
FillChar(trem_table2[chan],SizeOf(trem_table2[chan]),0);
If NOT (((event[chan].effect_def = ef_Arpeggio) and (event[chan].effect <> 0)) or
(event[chan].effect_def = ef_ExtraFineArpeggio)) and
(arpgg_table[chan].note <> 0) and (arpgg_table[chan].state <> 1) then
begin
arpgg_table[chan].state := 1;
change_frequency(chan,nFreq(arpgg_table[chan].note-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
end
else If NOT (((event[chan].effect_def2 = ef_Arpeggio) and (event[chan].effect2 <> 0)) or
(event[chan].effect_def2 = ef_ExtraFineArpeggio)) and
(arpgg_table2[chan].note <> 0) and (arpgg_table2[chan].state <> 1) then
begin
arpgg_table2[chan].state := 1;
change_frequency(chan,nFreq(arpgg_table2[chan].note-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
end;
If (event[chan].effect_def = ef_GlobalFSlideUp) or
(event[chan].effect_def = ef_GlobalFSlideDown) then
begin
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_ForceBpmSld) then
begin
If (event[chan].effect_def = ef_GlobalFSlideUp) then
update_playback_speed(event[chan].effect)
else update_playback_speed(-event[chan].effect);
end
else
begin
Case event[chan].effect_def of
ef_GlobalFSlideUp:
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
event[chan].effect)
else If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
effect_table[chan] := concw(ef_FSlideUpFine,event[chan].effect)
else effect_table[chan] := concw(ef_FSlideUp,event[chan].effect);
ef_GlobalFSlideDown:
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
event[chan].effect)
else If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
effect_table[chan] := concw(ef_FSlideDownFine,event[chan].effect)
else effect_table[chan] := concw(ef_FSlideDown,event[chan].effect);
end;
For idx := chan to songdata.nm_tracks do
begin
fslide_table[idx] := event[chan].effect;
glfsld_table[idx] := effect_table[chan];
end;
end;
end;
If (event[chan].effect_def2 = ef_GlobalFSlideUp) or
(event[chan].effect_def2 = ef_GlobalFSlideDown) then
begin
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_ForceBpmSld) then
begin
If (event[chan].effect_def2 = ef_GlobalFSlideUp) then
update_playback_speed(event[chan].effect2)
else update_playback_speed(-event[chan].effect2);
end
else
begin
Case event[chan].effect_def2 of
ef_GlobalFSlideUp:
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
event[chan].effect2)
else If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
effect_table2[chan] := concw(ef_FSlideUpFine,event[chan].effect2)
else effect_table2[chan] := concw(ef_FSlideUp,event[chan].effect2);
ef_GlobalFSlideDown:
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
event[chan].effect2)
else If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
effect_table2[chan] := concw(ef_FSlideDownFine,event[chan].effect2)
else effect_table2[chan] := concw(ef_FSlideDown,event[chan].effect2);
end;
For idx := chan to songdata.nm_tracks do
begin
fslide_table2[idx] := event[chan].effect2;
glfsld_table2[idx] := effect_table2[chan];
end;
end;
end;
end;
For chan := 1 to songdata.nm_tracks do
begin
If event_new[chan] and is_4op_chan(chan) then
If (chan in _4op_tracks_hi) then
event_new[SUCC(chan)] := TRUE
else event_new[PRED(chan)] := TRUE;
If (tremor_table[chan].pos <> 0) and
(event[chan].effect_def <> ef_Tremor) then
begin
tremor_table[chan].pos := 0;
set_ins_volume(LO(tremor_table[chan].volume),
HI(tremor_table[chan].volume),chan);
end;
If (tremor_table2[chan].pos <> 0) and
(event[chan].effect_def2 <> ef_Tremor) then
begin
tremor_table2[chan].pos := 0;
set_ins_volume(LO(tremor_table2[chan].volume),
HI(tremor_table2[chan].volume),chan);
end;
eLo[chan] := LO(last_effect[chan]);
eHi[chan] := HI(last_effect[chan]);
eLo2[chan] := LO(last_effect2[chan]);
eHi2[chan] := HI(last_effect2[chan]);
end;
For chan := 1 to songdata.nm_tracks do
Case event[chan].effect_def of
ef_Arpeggio,
ef_ExtraFineArpeggio,
ef_ArpggVSlide,
ef_ArpggVSlideFine:
If (event[chan].effect_def <> ef_Arpeggio) or
(event[chan].effect <> 0) then
begin
Case event[chan].effect_def of
ef_Arpeggio:
effect_table[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect);
ef_ExtraFineArpeggio:
effect_table[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect);
ef_ArpggVSlide,
ef_ArpggVSlideFine:
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
else effect_table[chan] := effect_table[chan] AND $0ff00;
end;
If (event[chan].note AND $7f in [1..12*8+1]) then
begin
arpgg_table[chan].state := 0;
arpgg_table[chan].note := event[chan].note AND $7f;
If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
begin
arpgg_table[chan].add1 := event[chan].effect DIV 16;
arpgg_table[chan].add2 := event[chan].effect MOD 16;
end;
end
else If (event[chan].note = 0) and
(event_table[chan].note AND $7f in [1..12*8+1]) then
begin
If NOT (eLo[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio,
ef_ArpggVSlide,ef_ArpggVSlideFine]) then
arpgg_table[chan].state := 0;
arpgg_table[chan].note := event_table[chan].note AND $7f;
If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
begin
arpgg_table[chan].add1 := event[chan].effect DIV 16;
arpgg_table[chan].add2 := event[chan].effect MOD 16;
end;
end
else effect_table[chan] := 0;
end;
ef_FSlideUp,
ef_FSlideDown,
ef_FSlideUpFine,
ef_FSlideDownFine:
begin
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect);
fslide_table[chan] := event[chan].effect;
end;
ef_FSlideUpVSlide,
ef_FSlUpVSlF,
ef_FSlideDownVSlide,
ef_FSlDownVSlF,
ef_FSlUpFineVSlide,
ef_FSlUpFineVSlF,
ef_FSlDownFineVSlide,
ef_FSlDownFineVSlF:
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide,
ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF,
ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
else effect_table[chan] := effect_table[chan] AND $0ff00;
ef_TonePortamento:
If (event[chan].note in [1..12*8+1]) then
begin
If (event[chan].effect <> 0) then
effect_table[chan] := concw(ef_TonePortamento,event[chan].effect)
else If (eLo[chan] = ef_TonePortamento) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(ef_TonePortamento,eHi[chan])
else effect_table[chan] := ef_TonePortamento;
porta_table[chan].speed := HI(effect_table[chan]);
porta_table[chan].freq := nFreq(event[chan].note-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12));
end
else If (eLo[chan] = ef_TonePortamento) then
begin
If (event[chan].effect <> 0) then
effect_table[chan] := concw(ef_TonePortamento,event[chan].effect)
else If (eLo[chan] = ef_TonePortamento) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(ef_TonePortamento,eHi[chan])
else effect_table[chan] := ef_TonePortamento;
porta_table[chan].speed := HI(effect_table[chan]);
end;
ef_TPortamVolSlide,
ef_TPortamVSlideFine:
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
else effect_table[chan] := effect_table[chan] AND $0ff00;
ef_Vibrato,
ef_ExtraFineVibrato:
begin
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
else effect_table[chan] := event[chan].effect_def;
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
vibr_table[chan].fine := TRUE;
vibr_table[chan].speed := HI(effect_table[chan]) DIV 16;
vibr_table[chan].depth := HI(effect_table[chan]) MOD 16;
end;
ef_Tremolo,
ef_ExtraFineTremolo:
begin
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
else effect_table[chan] := event[chan].effect_def;
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
trem_table[chan].fine := TRUE;
trem_table[chan].speed := HI(effect_table[chan]) DIV 16;
trem_table[chan].depth := HI(effect_table[chan]) MOD 16;
end;
ef_VibratoVolSlide,
ef_VibratoVSlideFine:
begin
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and
(HI(effect_table[chan]) <> 0) then
effect_table[chan] := concw(event[chan].effect_def,HI(effect_table[chan]))
else effect_table[chan] := effect_table[chan] AND $0ff00;
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
vibr_table[chan].fine := TRUE;
end;
ef_SetCarrierVol:
set_ins_volume(BYTE_NULL,63-event[chan].effect,chan);
ef_SetModulatorVol:
set_ins_volume(63-event[chan].effect,BYTE_NULL,chan);
ef_SetInsVolume:
If _4op_vol_valid_chan(chan) then
set_ins_volume_4op(63-event[chan].effect,chan)
else If percussion_mode and (chan in [17..20]) then
set_ins_volume(63-event[chan].effect,BYTE_NULL,chan)
else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(BYTE_NULL,63-event[chan].effect,chan)
else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan);
ef_ForceInsVolume:
If percussion_mode and (chan in [17..20]) then
set_ins_volume(63-event[chan].effect,BYTE_NULL,chan)
else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect),63-event[chan].effect,chan)
else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan);
ef_PositionJump:
If no_loop(chan,current_line) then
begin
pattern_break := TRUE;
next_line := pattern_break_flag+chan;
end;
ef_PatternBreak:
If no_loop(chan,current_line) then
begin
pattern_break := TRUE;
next_line := max(event[chan].effect,PRED(songdata.patt_len));
end;
ef_SetSpeed:
speed := event[chan].effect;
ef_SetTempo:
update_timer(event[chan].effect);
ef_SetWaveform:
begin
If (event[chan].effect DIV 16 in [0..7]) then
begin
fmpar_table[chan].adsrw_car.wform := event[chan].effect DIV 16;
update_carrier_adsrw(chan);
end;
If (event[chan].effect MOD 16 in [0..7]) then
begin
fmpar_table[chan].adsrw_mod.wform := event[chan].effect MOD 16;
update_modulator_adsrw(chan);
end;
end;
ef_VolSlide:
effect_table[chan] := concw(ef_VolSlide,event[chan].effect);
ef_VolSlideFine:
effect_table[chan] := concw(ef_VolSlideFine,event[chan].effect);
ef_RetrigNote:
If (event[chan].effect <> 0) then
begin
If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
retrig_table[chan] := 1;
effect_table[chan] := concw(ef_RetrigNote,event[chan].effect);
end;
ef_SetGlobalVolume:
begin
global_volume := event[chan].effect;
set_global_volume;
end;
ef_MultiRetrigNote:
If (event[chan].effect DIV 16 <> 0) then
begin
If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
retrig_table[chan] := 1;
effect_table[chan] := concw(ef_MultiRetrigNote,event[chan].effect);
end;
ef_Tremor:
If (event[chan].effect DIV 16 <> 0) and
(event[chan].effect MOD 16 <> 0) then
begin
If (eLo[chan] <> ef_Tremor) then
begin
tremor_table[chan].pos := 0;
tremor_table[chan].volume := volume_table[chan];
end;
effect_table[chan] := concw(ef_Tremor,event[chan].effect);
end;
ef_Extended:
Case (event[chan].effect DIV 16) of
ef_ex_SetTremDepth:
Case (event[chan].effect MOD 16) of
0: begin
opl3out(_instr[11],misc_register AND $07f);
current_tremolo_depth := 0;
end;
1: begin
opl3out(_instr[11],misc_register OR $080);
current_tremolo_depth := 1;
end;
end;
ef_ex_SetVibDepth:
Case (event[chan].effect MOD 16) of
0: begin
opl3out(_instr[11],misc_register AND $0bf);
current_vibrato_depth := 0;
end;
1: begin
opl3out(_instr[11],misc_register OR $040);
current_vibrato_depth := 1;
end;
end;
ef_ex_SetAttckRateM:
begin
fmpar_table[chan].adsrw_mod.attck := event[chan].effect MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetDecayRateM:
begin
fmpar_table[chan].adsrw_mod.dec := event[chan].effect MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetSustnLevelM:
begin
fmpar_table[chan].adsrw_mod.sustn := event[chan].effect MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetRelRateM:
begin
fmpar_table[chan].adsrw_mod.rel := event[chan].effect MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetAttckRateC:
begin
fmpar_table[chan].adsrw_car.attck := event[chan].effect MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetDecayRateC:
begin
fmpar_table[chan].adsrw_car.dec := event[chan].effect MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetSustnLevelC:
begin
fmpar_table[chan].adsrw_car.sustn := event[chan].effect MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetRelRateC:
begin
fmpar_table[chan].adsrw_car.rel := event[chan].effect MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetFeedback:
begin
fmpar_table[chan].feedb := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex_SetPanningPos:
begin
panning_table[chan] := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex_PatternLoop,
ef_ex_PatternLoopRec:
If (event[chan].effect MOD 16 = 0) then
loopbck_table[chan] := current_line
else If (loopbck_table[chan] <> BYTE_NULL) then
begin
If (loop_table[chan][current_line] = BYTE_NULL) then
loop_table[chan][current_line] := event[chan].effect MOD 16;
If (loop_table[chan][current_line] <> 0) then
begin
pattern_break := TRUE;
next_line := pattern_loop_flag+chan;
end
else If (event[chan].effect DIV 16 = ef_ex_PatternLoopRec) then
loop_table[chan][current_line] := BYTE_NULL;
end;
ef_ex_ExtendedCmd:
Case (event[chan].effect MOD 16) of
ef_ex_cmd_MKOffLoopDi: keyoff_loop[chan] := FALSE;
ef_ex_cmd_MKOffLoopEn: keyoff_loop[chan] := TRUE;
ef_ex_cmd_TPortaFKdis: portaFK_table[chan] := FALSE;
ef_ex_cmd_TPortaFKenb: portaFK_table[chan] := TRUE;
ef_ex_cmd_RestartEnv:
begin
key_on(chan);
change_freq(chan,freq_table[chan]);
end;
ef_ex_cmd_4opVlockOff:
If is_4op_chan(chan) then
begin
vol4op_lock[chan] := FALSE;
If (chan in _4op_tracks_hi) then
vol4op_lock[SUCC(chan)] := FALSE
else vol4op_lock[PRED(chan)] := FALSE;
end;
ef_ex_cmd_4opVlockOn:
If is_4op_chan(chan) then
begin
vol4op_lock[chan] := TRUE;
If (chan in _4op_tracks_hi) then
vol4op_lock[SUCC(chan)] := TRUE
else vol4op_lock[PRED(chan)] := TRUE;
end;
end;
ef_ex_ExtendedCmd2:
Case (event[chan].effect MOD 16) of
ef_ex_cmd2_RSS: release_sustaining_sound(chan);
ef_ex_cmd2_ResetVol: reset_ins_volume(chan);
ef_ex_cmd2_LockVol: volume_lock [chan] := TRUE;
ef_ex_cmd2_UnlockVol: volume_lock [chan] := FALSE;
ef_ex_cmd2_LockVP: peak_lock [chan] := TRUE;
ef_ex_cmd2_UnlockVP: peak_lock [chan] := FALSE;
ef_ex_cmd2_VSlide_def: volslide_type[chan] := 0;
ef_ex_cmd2_LockPan: pan_lock [chan] := TRUE;
ef_ex_cmd2_UnlockPan: pan_lock [chan] := FALSE;
ef_ex_cmd2_VibrOff: change_frequency(chan,freq_table[chan]);
ef_ex_cmd2_TremOff:
If is_4op_chan(chan) then
set_ins_volume_4op(BYTE_NULL,chan)
else set_ins_volume(LO(volume_table[chan]),
HI(volume_table[chan]),chan);
ef_ex_cmd2_VSlide_car:
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+
ef_ex_cmd2_VSlide_mod) then
volslide_type[chan] := 3
else volslide_type[chan] := 1;
ef_ex_cmd2_VSlide_mod:
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+
ef_ex_cmd2_VSlide_car) then
volslide_type[chan] := 3
else volslide_type[chan] := 2;
end;
end;
ef_Extended2:
Case (event[chan].effect DIV 16) of
ef_ex2_PatDelayFrame,
ef_ex2_PatDelayRow:
begin
pattern_delay := TRUE;
If (event[chan].effect DIV 16 = ef_ex2_PatDelayFrame) then
tickD := (event[chan].effect MOD 16)
else tickD := speed*(event[chan].effect MOD 16);
end;
ef_ex2_NoteDelay:
begin
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0);
notedel_table[chan] := event[chan].effect MOD 16;
end;
ef_ex2_NoteCut:
begin
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0);
notecut_table[chan] := event[chan].effect MOD 16;
end;
ef_ex2_FineTuneUp:
Inc(ftune_table[chan],event[chan].effect MOD 16);
ef_ex2_FineTuneDown:
Dec(ftune_table[chan],event[chan].effect MOD 16);
ef_ex2_GlVolSlideUp:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp,
event[chan].effect MOD 16);
ef_ex2_GlVolSlideDn:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn,
event[chan].effect MOD 16);
ef_ex2_GlVolSlideUpF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF,
event[chan].effect MOD 16);
ef_ex2_GlVolSlideDnF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF,
event[chan].effect MOD 16);
ef_ex2_GlVolSldUpXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF,
event[chan].effect MOD 16);
ef_ex2_GlVolSldDnXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF,
event[chan].effect MOD 16);
ef_ex2_VolSlideUpXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF,
event[chan].effect MOD 16);
ef_ex2_VolSlideDnXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF,
event[chan].effect MOD 16);
ef_ex2_FreqSlideUpXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
event[chan].effect MOD 16);
ef_ex2_FreqSlideDnXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
event[chan].effect MOD 16);
end;
ef_Extended3:
Case (event[chan].effect DIV 16) of
ef_ex3_SetConnection:
begin
fmpar_table[chan].connect := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetMultipM:
begin
fmpar_table[chan].multipM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKslM:
begin
fmpar_table[chan].kslM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetTremoloM:
begin
fmpar_table[chan].tremM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetVibratoM:
begin
fmpar_table[chan].vibrM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKsrM:
begin
fmpar_table[chan].ksrM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetSustainM:
begin
fmpar_table[chan].sustM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetMultipC:
begin
fmpar_table[chan].multipC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKslC:
begin
fmpar_table[chan].kslC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetTremoloC:
begin
fmpar_table[chan].tremC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetVibratoC:
begin
fmpar_table[chan].vibrC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKsrC:
begin
fmpar_table[chan].ksrC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetSustainC:
begin
fmpar_table[chan].sustC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
end;
end;
For chan := 1 to songdata.nm_tracks do
Case event[chan].effect_def2 of
ef_Arpeggio,
ef_ExtraFineArpeggio,
ef_ArpggVSlide,
ef_ArpggVSlideFine:
If (event[chan].effect_def2 <> ef_Arpeggio) or
(event[chan].effect2 <> 0) then
begin
Case event[chan].effect_def2 of
ef_Arpeggio:
effect_table2[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect2);
ef_ExtraFineArpeggio:
effect_table2[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect2);
ef_ArpggVSlide,
ef_ArpggVSlideFine:
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
else effect_table2[chan] := effect_table2[chan] AND $0ff00;
end;
If (event[chan].note AND $7f in [1..12*8+1]) then
begin
arpgg_table2[chan].state := 0;
arpgg_table2[chan].note := event[chan].note AND $7f;
If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
begin
arpgg_table2[chan].add1 := event[chan].effect2 DIV 16;
arpgg_table2[chan].add2 := event[chan].effect2 MOD 16;
end;
end
else If (event[chan].note = 0) and
(event_table[chan].note AND $7f in [1..12*8+1]) then
begin
If NOT (eLo2[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio,
ef_ArpggVSlide,ef_ArpggVSlideFine]) then
arpgg_table2[chan].state := 0;
arpgg_table2[chan].note := event_table[chan].note AND $7f;
If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
begin
arpgg_table2[chan].add1 := event[chan].effect2 DIV 16;
arpgg_table2[chan].add2 := event[chan].effect2 MOD 16;
end;
end
else effect_table2[chan] := 0;
end;
ef_FSlideUp,
ef_FSlideDown,
ef_FSlideUpFine,
ef_FSlideDownFine:
begin
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2);
fslide_table2[chan] := event[chan].effect2;
end;
ef_FSlideUpVSlide,
ef_FSlUpVSlF,
ef_FSlideDownVSlide,
ef_FSlDownVSlF,
ef_FSlUpFineVSlide,
ef_FSlUpFineVSlF,
ef_FSlDownFineVSlide,
ef_FSlDownFineVSlF:
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide,
ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF,
ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
else effect_table2[chan] := effect_table2[chan] AND $0ff00;
ef_TonePortamento:
If (event[chan].note in [1..12*8+1]) then
begin
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2)
else If (eLo2[chan] = ef_TonePortamento) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan])
else effect_table2[chan] := ef_TonePortamento;
porta_table2[chan].speed := HI(effect_table2[chan]);
porta_table2[chan].freq := nFreq(event[chan].note-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12));
end
else If (eLo2[chan] = ef_TonePortamento) then
begin
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2)
else If (eLo2[chan] = ef_TonePortamento) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan])
else effect_table2[chan] := ef_TonePortamento;
porta_table2[chan].speed := HI(effect_table2[chan]);
end;
ef_TPortamVolSlide,
ef_TPortamVSlideFine:
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
else effect_table2[chan] := effect_table2[chan] AND $0ff00;
ef_Vibrato,
ef_ExtraFineVibrato:
begin
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
else effect_table2[chan] := event[chan].effect_def2;
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
vibr_table2[chan].fine := TRUE;
vibr_table2[chan].speed := HI(effect_table2[chan]) DIV 16;
vibr_table2[chan].depth := HI(effect_table2[chan]) MOD 16;
end;
ef_Tremolo,
ef_ExtraFineTremolo:
begin
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
else effect_table2[chan] := event[chan].effect_def2;
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
trem_table2[chan].fine := TRUE;
trem_table2[chan].speed := HI(effect_table2[chan]) DIV 16;
trem_table2[chan].depth := HI(effect_table2[chan]) MOD 16;
end;
ef_VibratoVolSlide,
ef_VibratoVSlideFine:
begin
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and
(HI(effect_table2[chan]) <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,HI(effect_table2[chan]))
else effect_table2[chan] := effect_table2[chan] AND $0ff00;
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
vibr_table2[chan].fine := TRUE;
end;
ef_SetCarrierVol:
set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan);
ef_SetModulatorVol:
set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan);
ef_SetInsVolume:
If _4op_vol_valid_chan(chan) then
set_ins_volume_4op(63-event[chan].effect2,chan)
else If percussion_mode and (chan in [17..20]) then
set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan)
else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan)
else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan);
ef_ForceInsVolume:
If percussion_mode and (chan in [17..20]) then
set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan)
else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect2),63-event[chan].effect2,chan)
else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan);
ef_PositionJump:
If no_loop(chan,current_line) then
begin
pattern_break := TRUE;
next_line := pattern_break_flag+chan;
end;
ef_PatternBreak:
If no_loop(chan,current_line) then
begin
pattern_break := TRUE;
next_line := max(event[chan].effect2,PRED(songdata.patt_len));
end;
ef_SetSpeed:
speed := event[chan].effect2;
ef_SetTempo:
update_timer(event[chan].effect2);
ef_SetWaveform:
begin
If (event[chan].effect2 DIV 16 in [0..7]) then
begin
fmpar_table[chan].adsrw_car.wform := event[chan].effect2 DIV 16;
update_carrier_adsrw(chan);
end;
If (event[chan].effect2 MOD 16 in [0..7]) then
begin
fmpar_table[chan].adsrw_mod.wform := event[chan].effect2 MOD 16;
update_modulator_adsrw(chan);
end;
end;
ef_VolSlide:
effect_table2[chan] := concw(ef_VolSlide,event[chan].effect2);
ef_VolSlideFine:
effect_table2[chan] := concw(ef_VolSlideFine,event[chan].effect2);
ef_RetrigNote:
If (event[chan].effect2 <> 0) then
begin
If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
retrig_table2[chan] := 1;
effect_table2[chan] := concw(ef_RetrigNote,event[chan].effect2);
end;
ef_SetGlobalVolume:
begin
global_volume := event[chan].effect2;
set_global_volume;
end;
ef_MultiRetrigNote:
If (event[chan].effect2 DIV 16 <> 0) then
begin
If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
retrig_table2[chan] := 1;
effect_table2[chan] := concw(ef_MultiRetrigNote,event[chan].effect2);
end;
ef_Tremor:
If (event[chan].effect2 DIV 16 <> 0) and
(event[chan].effect2 MOD 16 <> 0) then
begin
If (eLo2[chan] <> ef_Tremor) then
begin
tremor_table2[chan].pos := 0;
tremor_table2[chan].volume := volume_table[chan];
end;
effect_table2[chan] := concw(ef_Tremor,event[chan].effect2);
end;
ef_Extended:
Case (event[chan].effect2 DIV 16) of
ef_ex_SetTremDepth:
Case (event[chan].effect2 MOD 16) of
0: begin
opl3out(_instr[11],misc_register AND $07f);
current_tremolo_depth := 0;
end;
1: begin
opl3out(_instr[11],misc_register OR $080);
current_tremolo_depth := 1;
end;
end;
ef_ex_SetVibDepth:
Case (event[chan].effect2 MOD 16) of
0: begin
opl3out(_instr[11],misc_register AND $0bf);
current_vibrato_depth := 0;
end;
1: begin
opl3out(_instr[11],misc_register OR $040);
current_vibrato_depth := 1;
end;
end;
ef_ex_SetAttckRateM:
begin
fmpar_table[chan].adsrw_mod.attck := event[chan].effect2 MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetDecayRateM:
begin
fmpar_table[chan].adsrw_mod.dec := event[chan].effect2 MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetSustnLevelM:
begin
fmpar_table[chan].adsrw_mod.sustn := event[chan].effect2 MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetRelRateM:
begin
fmpar_table[chan].adsrw_mod.rel := event[chan].effect2 MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetAttckRateC:
begin
fmpar_table[chan].adsrw_car.attck := event[chan].effect2 MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetDecayRateC:
begin
fmpar_table[chan].adsrw_car.dec := event[chan].effect2 MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetSustnLevelC:
begin
fmpar_table[chan].adsrw_car.sustn := event[chan].effect2 MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetRelRateC:
begin
fmpar_table[chan].adsrw_car.rel := event[chan].effect2 MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetFeedback:
begin
fmpar_table[chan].feedb := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex_SetPanningPos:
begin
panning_table[chan] := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex_PatternLoop,
ef_ex_PatternLoopRec:
If (event[chan].effect2 MOD 16 = 0) then
loopbck_table[chan] := current_line
else If (loopbck_table[chan] <> BYTE_NULL) then
begin
If (loop_table[chan][current_line] = BYTE_NULL) then
loop_table[chan][current_line] := event[chan].effect2 MOD 16;
If (loop_table[chan][current_line] <> 0) then
begin
pattern_break := TRUE;
next_line := pattern_loop_flag+chan;
end
else If (event[chan].effect2 DIV 16 = ef_ex_PatternLoopRec) then
loop_table[chan][current_line] := BYTE_NULL;
end;
ef_ex_ExtendedCmd:
Case (event[chan].effect2 MOD 16) of
ef_ex_cmd_MKOffLoopDi: keyoff_loop[chan] := FALSE;
ef_ex_cmd_MKOffLoopEn: keyoff_loop[chan] := TRUE;
ef_ex_cmd_TPortaFKdis: portaFK_table[chan] := FALSE;
ef_ex_cmd_TPortaFKenb: portaFK_table[chan] := TRUE;
ef_ex_cmd_RestartEnv:
begin
key_on(chan);
change_freq(chan,freq_table[chan]);
end;
ef_ex_cmd_4opVlockOff:
If is_4op_chan(chan) then
begin
vol4op_lock[chan] := FALSE;
If (chan in _4op_tracks_hi) then
vol4op_lock[SUCC(chan)] := FALSE
else vol4op_lock[PRED(chan)] := FALSE;
end;
ef_ex_cmd_4opVlockOn:
If is_4op_chan(chan) then
begin
vol4op_lock[chan] := TRUE;
If (chan in _4op_tracks_hi) then
vol4op_lock[SUCC(chan)] := TRUE
else vol4op_lock[PRED(chan)] := TRUE;
end;
end;
ef_ex_ExtendedCmd2:
Case (event[chan].effect2 MOD 16) of
ef_ex_cmd2_RSS: release_sustaining_sound(chan);
ef_ex_cmd2_ResetVol: reset_ins_volume(chan);
ef_ex_cmd2_LockVol: volume_lock [chan] := TRUE;
ef_ex_cmd2_UnlockVol: volume_lock [chan] := FALSE;
ef_ex_cmd2_LockVP: peak_lock [chan] := TRUE;
ef_ex_cmd2_UnlockVP: peak_lock [chan] := FALSE;
ef_ex_cmd2_VSlide_def: volslide_type[chan] := 0;
ef_ex_cmd2_LockPan: pan_lock [chan] := TRUE;
ef_ex_cmd2_UnlockPan: pan_lock [chan] := FALSE;
ef_ex_cmd2_VibrOff: change_frequency(chan,freq_table[chan]);
ef_ex_cmd2_TremOff:
If _4op_vol_valid_chan(chan) then
set_ins_volume_4op(BYTE_NULL,chan)
else set_ins_volume(LO(volume_table[chan]),
HI(volume_table[chan]),chan);
ef_ex_cmd2_VSlide_car:
If NOT ((event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+
ef_ex_cmd2_VSlide_mod)) then
volslide_type[chan] := 1;
ef_ex_cmd2_VSlide_mod:
If NOT ((event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+
ef_ex_cmd2_VSlide_car)) then
volslide_type[chan] := 2;
end;
end;
ef_Extended2:
Case (event[chan].effect2 DIV 16) of
ef_ex2_PatDelayFrame,
ef_ex2_PatDelayRow:
begin
pattern_delay := TRUE;
If (event[chan].effect2 DIV 16 = ef_ex2_PatDelayFrame) then
tickD := (event[chan].effect2 MOD 16)
else tickD := speed*(event[chan].effect2 MOD 16);
end;
ef_ex2_NoteDelay:
begin
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0);
notedel_table[chan] := event[chan].effect2 MOD 16;
end;
ef_ex2_NoteCut:
begin
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0);
notecut_table[chan] := event[chan].effect2 MOD 16;
end;
ef_ex2_FineTuneUp:
Inc(ftune_table[chan],event[chan].effect2 MOD 16);
ef_ex2_FineTuneDown:
Dec(ftune_table[chan],event[chan].effect2 MOD 16);
ef_ex2_GlVolSlideUp:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp,
event[chan].effect2 MOD 16);
ef_ex2_GlVolSlideDn:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn,
event[chan].effect2 MOD 16);
ef_ex2_GlVolSlideUpF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF,
event[chan].effect2 MOD 16);
ef_ex2_GlVolSlideDnF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF,
event[chan].effect2 MOD 16);
ef_ex2_GlVolSldUpXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF,
event[chan].effect2 MOD 16);
ef_ex2_GlVolSldDnXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF,
event[chan].effect2 MOD 16);
ef_ex2_VolSlideUpXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF,
event[chan].effect2 MOD 16);
ef_ex2_VolSlideDnXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF,
event[chan].effect2 MOD 16);
ef_ex2_FreqSlideUpXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
event[chan].effect2 MOD 16);
ef_ex2_FreqSlideDnXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
event[chan].effect2 MOD 16);
end;
ef_Extended3:
Case (event[chan].effect2 DIV 16) of
ef_ex3_SetConnection:
begin
fmpar_table[chan].connect := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetMultipM:
begin
fmpar_table[chan].multipM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKslM:
begin
fmpar_table[chan].kslM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetTremoloM:
begin
fmpar_table[chan].tremM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetVibratoM:
begin
fmpar_table[chan].vibrM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKsrM:
begin
fmpar_table[chan].ksrM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetSustainM:
begin
fmpar_table[chan].sustM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetMultipC:
begin
fmpar_table[chan].multipC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKslC:
begin
fmpar_table[chan].kslC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetTremoloC:
begin
fmpar_table[chan].tremC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetVibratoC:
begin
fmpar_table[chan].vibrC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKsrC:
begin
fmpar_table[chan].ksrC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetSustainC:
begin
fmpar_table[chan].sustC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
end;
end;
For chan := 1 to songdata.nm_tracks do
begin
tporta_flag := (event[chan].effect_def in [ef_TonePortamento,
ef_TPortamVolSlide,
ef_TPortamVSlideFine]) or
(event[chan].effect_def2 in [ef_TonePortamento,
ef_TPortamVolSlide,
ef_TPortamVSlideFine]);
If (event[chan].effect_def+event[chan].effect = 0) then
If (glfsld_table[chan] = 0) then effect_table[chan] := 0
else begin
event_table[chan].effect_def := event[chan].effect_def;
event_table[chan].effect := event[chan].effect;
end;
If (event[chan].effect_def2+event[chan].effect2 = 0) then
If (glfsld_table2[chan] = 0) then effect_table2[chan] := 0
else begin
event_table[chan].effect_def2 := event[chan].effect_def2;
event_table[chan].effect2 := event[chan].effect2;
end;
If (event[chan].note = event[chan].note OR keyoff_flag) then key_off(chan)
else If NOT (LO(effect_table[chan]) in [ef_TonePortamento,
ef_TPortamVolSlide,
ef_TPortamVSlideFine,
ef_extended2+ef_fix2+ef_ex2_NoteDelay]) and
NOT (LO(effect_table2[chan]) in [ef_TonePortamento,
ef_TPortamVolSlide,
ef_TPortamVSlideFine,
ef_extended2+ef_fix2+ef_ex2_NoteDelay]) then
If NOT (((event[chan].effect_def2 = ef_SwapArpeggio) or
(event[chan].effect_def2 = ef_SwapVibrato)) and
(event[chan].effect_def = ef_Extended) and
(event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart)) and
NOT (((event[chan].effect_def = ef_SwapArpeggio) or
(event[chan].effect_def = ef_SwapVibrato)) and
(event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart)) then
output_note(event[chan].note,voice_table[chan],chan,TRUE,TRUE)
else output_note(event[chan].note,voice_table[chan],chan,TRUE,FALSE)
else If (event[chan].note <> 0) and tporta_flag and
(event_table[chan].note = event_table[chan].note OR keyoff_flag) then
output_note(event_table[chan].note AND NOT keyoff_flag,voice_table[chan],chan,FALSE,TRUE)
else If (event[chan].note <> 0) then
If portaFK_table[chan] and tporta_flag then
output_note(event[chan].note,event[chan].instr_def,chan,FALSE,TRUE)
else event_table[chan].note := event[chan].note;
Case event[chan].effect_def of
ef_SwapArpeggio:
begin
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart) then
begin
If (macro_table[chan].arpg_pos >
songdata.macro_table[event[chan].effect].arpeggio.length) then
macro_table[chan].arpg_pos :=
songdata.macro_table[event[chan].effect].arpeggio.length;
macro_table[chan].arpg_table := event[chan].effect;
end
else begin
macro_table[chan].arpg_count := 1;
macro_table[chan].arpg_pos := 0;
macro_table[chan].arpg_table := event[chan].effect;
macro_table[chan].arpg_note := event_table[chan].note;
end;
end;
ef_SwapVibrato:
begin
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart) then
begin
If (macro_table[chan].vib_table >
songdata.macro_table[event[chan].effect].vibrato.length) then
macro_table[chan].vib_pos :=
songdata.macro_table[event[chan].effect].vibrato.length;
macro_table[chan].vib_table := event[chan].effect;
end
else begin
macro_table[chan].vib_count := 1;
macro_table[chan].vib_pos := 0;
macro_table[chan].vib_table := event[chan].effect;
macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay;
end;
end;
ef_SetCustomSpeedTab:
generate_custom_vibrato(event[chan].effect);
end;
Case event[chan].effect_def2 of
ef_SwapArpeggio:
begin
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart) then
begin
If (macro_table[chan].arpg_pos >
songdata.macro_table[event[chan].effect2].arpeggio.length) then
macro_table[chan].arpg_pos :=
songdata.macro_table[event[chan].effect2].arpeggio.length;
macro_table[chan].arpg_table := event[chan].effect2;
end
else begin
macro_table[chan].arpg_count := 1;
macro_table[chan].arpg_pos := 0;
macro_table[chan].arpg_table := event[chan].effect2;
macro_table[chan].arpg_note := event_table[chan].note;
end;
end;
ef_SwapVibrato:
begin
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart) then
begin
If (macro_table[chan].vib_table >
songdata.macro_table[event[chan].effect2].vibrato.length) then
macro_table[chan].vib_pos :=
songdata.macro_table[event[chan].effect2].vibrato.length;
macro_table[chan].vib_table := event[chan].effect2;
end
else begin
macro_table[chan].vib_count := 1;
macro_table[chan].vib_pos := 0;
macro_table[chan].vib_table := event[chan].effect2;
macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay;
end;
end;
ef_SetCustomSpeedTab:
generate_custom_vibrato(event[chan].effect2);
end;
update_fine_effects(chan);
end;
If pattern_delay then
begin
time_playing := time_playing+1/tempo*tickD;
If (time_playing > 3600-1) then time_playing := 0;
end
else begin
time_playing := time_playing+1/tempo*speed;
If (time_playing > 3600-1) then time_playing := 0;
end;
end;
procedure portamento_up(chan: Byte; slide: Word; limit: Word);
var
freq: Word;
begin
If (freq_table[chan] AND $1fff = 0) then EXIT;
freq := calc_freq_shift_up(freq_table[chan] AND $1fff,slide);
If (freq <= limit) then change_frequency(chan,freq)
else change_frequency(chan,limit);
end;
procedure portamento_down(chan: Byte; slide: Word; limit: Word);
var
freq: Word;
begin
If (freq_table[chan] AND $1fff = 0) then EXIT;
freq := calc_freq_shift_down(freq_table[chan] AND $1fff,slide);
If (freq >= limit) then change_frequency(chan,freq)
else change_frequency(chan,limit);
end;
procedure macro_vibrato__porta_up(chan: Byte; depth: Byte);
var
freq: Word;
begin
freq := calc_freq_shift_up(macro_table[chan].vib_freq AND $1fff,depth);
If (freq <= nFreq(12*8+1)) then change_freq(chan,freq)
else change_freq(chan,nFreq(12*8+1));
end;
procedure macro_vibrato__porta_down(chan: Byte; depth: Byte);
var
freq: Word;
begin
freq := calc_freq_shift_down(macro_table[chan].vib_freq AND $1fff,depth);
If (freq >= nFreq(0)) then change_freq(chan,freq)
else change_freq(chan,nFreq(0));
end;
procedure tone_portamento(chan: Byte);
begin
If (freq_table[chan] AND $1fff > porta_table[chan].freq) then
portamento_down(chan,porta_table[chan].speed,porta_table[chan].freq)
else If (freq_table[chan] AND $1fff < porta_table[chan].freq) then
portamento_up(chan,porta_table[chan].speed,porta_table[chan].freq);
end;
procedure tone_portamento2(chan: Byte);
begin
If (freq_table[chan] AND $1fff > porta_table2[chan].freq) then
portamento_down(chan,porta_table2[chan].speed,porta_table2[chan].freq)
else If (freq_table[chan] AND $1fff < porta_table2[chan].freq) then
portamento_up(chan,porta_table2[chan].speed,porta_table2[chan].freq);
end;
procedure slide_carrier_volume_up(chan: Byte; slide,limit: Byte);
var
vol: Word;
vLo,vHi: Byte;
begin
vLo := LO(volume_table[chan]);
vHi := HI(volume_table[chan]);
If (vHi-slide >= limit) then vol := concw(vLo,vHi-slide)
else vol := concw(vLo,limit);
set_ins_volume(BYTE_NULL,HI(vol),chan);
volume_table[chan] := vol;
end;
procedure slide_modulator_volume_up(chan: Byte; slide,limit: Byte);
var
vol: Word;
vLo,vHi: Byte;
begin
vLo := LO(volume_table[chan]);
vHi := HI(volume_table[chan]);
If (vLo-slide >= limit) then vol := concw(vLo-slide,vHi)
else vol := concw(limit,vHi);
set_ins_volume(LO(vol),BYTE_NULL,chan);
volume_table[chan] := vol;
end;
procedure slide_volume_up(chan,slide: Byte);
var
limit1,limit2: Byte;
limit1_4op,limit2_4op: Word;
_4op_flag: Dword;
_4op_conn: Byte;
_4op_ch1,_4op_ch2: Byte;
_4op_ins1,_4op_ins2: Byte;
begin
_4op_flag := _4op_data_flag(chan);
_4op_conn := (_4op_flag SHR 1) AND 3;
_4op_ch1 := (_4op_flag SHR 3) AND 15;
_4op_ch2 := (_4op_flag SHR 7) AND 15;
_4op_ins1 := BYTE(_4op_flag SHR 11);
_4op_ins2 := BYTE(_4op_flag SHR 19);
If _4op_vol_valid_chan(chan) then
begin
If NOT peak_lock[_4op_ch1] then limit1_4op := 0
else limit1_4op := ins_parameter(_4op_ins1,3) AND $3f SHL 16 +
ins_parameter(_4op_ins1,2) AND $3f;
If NOT peak_lock[_4op_ch2] then limit2_4op := 0
else limit2_4op := ins_parameter(_4op_ins2,3) AND $3f SHL 16 +
ins_parameter(_4op_ins2,2) AND $3f;
end
else begin
If NOT peak_lock[chan] then limit1 := 0
else limit1 := ins_parameter(event_table[chan].instr_def,3) AND $3f;
If NOT peak_lock[chan] then limit2 := 0
else limit2 := ins_parameter(event_table[chan].instr_def,2) AND $3f;
end;
Case volslide_type[chan] of
0: begin
If NOT _4op_vol_valid_chan(chan) then
begin
slide_carrier_volume_up(chan,slide,limit1);
If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
(percussion_mode and (chan in [17..20])) then
slide_modulator_volume_up(chan,slide,limit2);
end
else
Case _4op_conn of
// FM/FM
0: slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op));
// FM/AM
1: begin
slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op));
slide_modulator_volume_up(_4op_ch2,slide,LO(limit2_4op));
end;
// AM/FM
2: begin
slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op));
slide_carrier_volume_up(_4op_ch2,slide,HI(limit2_4op));
end;
// AM/AM
3: begin
slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op));
slide_modulator_volume_up(_4op_ch1,slide,LO(limit1_4op));
slide_modulator_volume_up(_4op_ch2,slide,LO(limit2_4op));
end;
end;
end;
1: slide_carrier_volume_up(chan,slide,limit1);
2: slide_modulator_volume_up(chan,slide,limit2);
3: begin
slide_carrier_volume_up(chan,slide,limit1);
slide_modulator_volume_up(chan,slide,limit2);
end;
end;
end;
procedure slide_carrier_volume_down(chan: Byte; slide: Byte);
var
vol: Word;
vLo,vHi: Byte;
begin
vLo := LO(volume_table[chan]);
vHi := HI(volume_table[chan]);
If (vHi+slide <= 63) then vol := concw(vLo,vHi+slide)
else vol := concw(vLo,63);
set_ins_volume(BYTE_NULL,HI(vol),chan);
volume_table[chan] := vol;
end;
procedure slide_modulator_volume_down(chan: Byte; slide: Byte);
var
vol: Word;
vLo,vHi: Byte;
begin
vLo := LO(volume_table[chan]);
vHi := HI(volume_table[chan]);
If (vLo+slide <= 63) then vol := concw(vLo+slide,vHi)
else vol := concw(63,vHi);
set_ins_volume(LO(vol),BYTE_NULL,chan);
volume_table[chan] := vol;
end;
procedure slide_volume_down(chan,slide: Byte);
var
_4op_flag: Dword;
_4op_conn: Byte;
_4op_ch1,_4op_ch2: Byte;
begin
_4op_flag := _4op_data_flag(chan);
_4op_conn := (_4op_flag SHR 1) AND 3;
_4op_ch1 := (_4op_flag SHR 3) AND 15;
_4op_ch2 := (_4op_flag SHR 7) AND 15;
Case volslide_type[chan] of
0: begin
If NOT _4op_vol_valid_chan(chan) then
begin
slide_carrier_volume_down(chan,slide);
If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
(percussion_mode and (chan in [17..20])) then
slide_modulator_volume_down(chan,slide);
end
else
Case _4op_conn of
// FM/FM
0: slide_carrier_volume_down(_4op_ch1,slide);
// FM/AM
1: begin
slide_carrier_volume_down(_4op_ch1,slide);
slide_modulator_volume_down(_4op_ch2,slide);
end;
// AM/FM
2: begin
slide_carrier_volume_down(_4op_ch1,slide);
slide_carrier_volume_down(_4op_ch2,slide);
end;
// AM/AM
3: begin
slide_carrier_volume_down(_4op_ch1,slide);
slide_modulator_volume_down(_4op_ch1,slide);
slide_modulator_volume_down(_4op_ch2,slide);
end;
end;
end;
1: slide_carrier_volume_down(chan,slide);
2: slide_modulator_volume_down(chan,slide);
3: begin
slide_carrier_volume_down(chan,slide);
slide_modulator_volume_down(chan,slide);
end;
end;
end;
procedure volume_slide(chan,up_speed,down_speed: Byte);
begin
If (up_speed <> 0) then slide_volume_up(chan,up_speed)
else If (down_speed <> 0) then slide_volume_down(chan,down_speed);
end;
procedure global_volume_slide(up_speed,down_speed: Byte);
begin
If (up_speed <> BYTE_NULL) then
global_volume := max(global_volume+up_speed,63);
If (down_speed <> BYTE_NULL) then
If (global_volume >= down_speed) then Dec(global_volume,down_speed)
else global_volume := 0;
set_global_volume;
end;
procedure arpeggio(chan: Byte);
const
arpgg_state: array[0..2] of Byte = (1,2,0);
var
freq: Word;
begin
Case arpgg_table[chan].state of
0: freq := nFreq(arpgg_table[chan].note-1);
1: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add1);
2: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add2);
end;
arpgg_table[chan].state := arpgg_state[arpgg_table[chan].state];
change_frequency(chan,freq+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
end;
procedure arpeggio2(chan: Byte);
const
arpgg_state: array[0..2] of Byte = (1,2,0);
var
freq: Word;
begin
Case arpgg_table2[chan].state of
0: freq := nFreq(arpgg_table2[chan].note-1);
1: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add1);
2: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add2);
end;
arpgg_table2[chan].state := arpgg_state[arpgg_table2[chan].state];
change_frequency(chan,freq+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
end;
procedure vibrato(chan: Byte);
var
freq,old_freq: Word;
begin
Inc(vibr_table[chan].pos,vibr_table[chan].speed*vibtrem_speed_factor);
freq := calc_vibtrem_shift(chan,vibr_table);
old_freq := freq_table[chan];
If (vibr_table[chan].dir = 0) then portamento_down(chan,freq,nFreq(0))
else portamento_up(chan,freq,nFreq(12*8+1));
freq_table[chan] := old_freq;
end;
procedure vibrato2(chan: Byte);
var
freq,old_freq: Word;
begin
Inc(vibr_table2[chan].pos,vibr_table2[chan].speed*vibtrem_speed_factor);
freq := calc_vibtrem_shift(chan,vibr_table2);
old_freq := freq_table[chan];
If (vibr_table2[chan].dir = 0) then portamento_down(chan,freq,nFreq(0))
else portamento_up(chan,freq,nFreq(12*8+1));
freq_table[chan] := old_freq;
end;
procedure tremolo(chan: Byte);
var
vol,old_vol: Word;
begin
Inc(trem_table[chan].pos,trem_table[chan].speed*vibtrem_speed_factor);
vol := calc_vibtrem_shift(chan,trem_table);
old_vol := volume_table[chan];
If (trem_table[chan].dir = 0) then slide_volume_down(chan,vol)
else slide_volume_up(chan,vol);
volume_table[chan] := old_vol;
end;
procedure tremolo2(chan: Byte);
var
vol,old_vol: Word;
begin
Inc(trem_table2[chan].pos,trem_table2[chan].speed*vibtrem_speed_factor);
vol := calc_vibtrem_shift(chan,trem_table2);
old_vol := volume_table[chan];
If (trem_table2[chan].pos = 0) then slide_volume_down(chan,vol)
else slide_volume_up(chan,vol);
volume_table[chan] := old_vol;
end;
procedure update_effects;
var
chan,eLo,eHi,
eLo2,eHi2: Byte;
function chanvol(chan: Byte): Byte;
begin
If (ins_parameter(voice_table[chan],10) AND 1 = 0) then chanvol := 63-HI(volume_table[chan])
else chanvol := 63-Round((LO(volume_table[chan])+HI(volume_table[chan]))/2);
end;
begin
For chan := 1 to songdata.nm_tracks do
begin
eLo := LO(effect_table[chan]);
eHi := HI(effect_table[chan]);
eLo2 := LO(effect_table2[chan]);
eHi2 := HI(effect_table2[chan]);
Case eLo of
ef_Arpeggio+ef_fix1:
arpeggio(chan);
ef_ArpggVSlide:
begin
volume_slide(chan,eHi DIV 16,eHi MOD 16);
arpeggio(chan);
end;
ef_ArpggVSlideFine:
arpeggio(chan);
ef_FSlideUp:
portamento_up(chan,eHi,nFreq(12*8+1));
ef_FSlideDown:
portamento_down(chan,eHi,nFreq(0));
ef_FSlideUpVSlide:
begin
portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
volume_slide(chan,eHi DIV 16,eHi MOD 16);
end;
ef_FSlUpVSlF:
portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
ef_FSlideDownVSlide:
begin
portamento_down(chan,fslide_table[chan],nFreq(0));
volume_slide(chan,eHi DIV 16,eHi MOD 16);
end;
ef_FSlDownVSlF:
portamento_down(chan,fslide_table[chan],nFreq(0));
ef_FSlUpFineVSlide:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_FSlDownFineVSlide:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_TonePortamento:
tone_portamento(chan);
ef_TPortamVolSlide:
begin
volume_slide(chan,eHi DIV 16,eHi MOD 16);
tone_portamento(chan);
end;
ef_TPortamVSlideFine:
tone_portamento(chan);
ef_Vibrato:
If NOT vibr_table[chan].fine then
vibrato(chan);
ef_Tremolo:
If NOT trem_table[chan].fine then
tremolo(chan);
ef_VibratoVolSlide:
begin
volume_slide(chan,eHi DIV 16,eHi MOD 16);
If NOT vibr_table[chan].fine then
vibrato(chan);
end;
ef_VibratoVSlideFine:
If NOT vibr_table[chan].fine then
vibrato(chan);
ef_VolSlide:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_RetrigNote:
If (retrig_table[chan] >= eHi) then
begin
retrig_table[chan] := 0;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Inc(retrig_table[chan]);
ef_MultiRetrigNote:
If (retrig_table[chan] >= eHi DIV 16) then
begin
Case eHi MOD 16 of
0,8: ;
1: slide_volume_down(chan,1);
2: slide_volume_down(chan,2);
3: slide_volume_down(chan,4);
4: slide_volume_down(chan,8);
5: slide_volume_down(chan,16);
9: slide_volume_up(chan,1);
10: slide_volume_up(chan,2);
11: slide_volume_up(chan,4);
12: slide_volume_up(chan,8);
13: slide_volume_up(chan,16);
6: slide_volume_down(chan,chanvol(chan)-
Round(chanvol(chan)*2/3));
7: slide_volume_down(chan,chanvol(chan)-
Round(chanvol(chan)*1/2));
14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)-
chanvol(chan),63));
15: slide_volume_up(chan,max(Round(chanvol(chan)*2)-
chanvol(chan),63));
end;
retrig_table[chan] := 0;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Inc(retrig_table[chan]);
ef_Tremor:
If (tremor_table[chan].pos >= 0) then
begin
If (SUCC(tremor_table[chan].pos) <= eHi DIV 16) then
Inc(tremor_table[chan].pos)
else begin
slide_volume_down(chan,63);
tremor_table[chan].pos := -1;
end;
end
else If (PRED(tremor_table[chan].pos) >= -(eHi MOD 16)) then
Dec(tremor_table[chan].pos)
else begin
set_ins_volume(LO(tremor_table[chan].volume),
HI(tremor_table[chan].volume),chan);
tremor_table[chan].pos := 1;
end;
ef_extended2+ef_fix2+ef_ex2_NoteDelay:
If (notedel_table[chan] = 0) then
begin
notedel_table[chan] := BYTE_NULL;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Dec(notedel_table[chan]);
ef_extended2+ef_fix2+ef_ex2_NoteCut:
If (notecut_table[chan] = 0) then
begin
notecut_table[chan] := BYTE_NULL;
key_off(chan);
end
else Dec(notecut_table[chan]);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp:
global_volume_slide(eHi,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn:
global_volume_slide(BYTE_NULL,eHi);
end;
Case eLo2 of
ef_Arpeggio+ef_fix1:
arpeggio2(chan);
ef_ArpggVSlide:
begin
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
arpeggio2(chan);
end;
ef_ArpggVSlideFine:
arpeggio2(chan);
ef_FSlideUp:
portamento_up(chan,eHi2,nFreq(12*8+1));
ef_FSlideDown:
portamento_down(chan,eHi2,nFreq(0));
ef_FSlideUpVSlide:
begin
portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
end;
ef_FSlUpVSlF:
portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
ef_FSlideDownVSlide:
begin
portamento_down(chan,fslide_table2[chan],nFreq(0));
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
end;
ef_FSlDownVSlF:
portamento_down(chan,fslide_table2[chan],nFreq(0));
ef_FSlUpFineVSlide:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_FSlDownFineVSlide:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_TonePortamento:
tone_portamento2(chan);
ef_TPortamVolSlide:
begin
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
tone_portamento2(chan);
end;
ef_TPortamVSlideFine:
tone_portamento2(chan);
ef_Vibrato:
If NOT vibr_table2[chan].fine then
vibrato2(chan);
ef_Tremolo:
If NOT trem_table2[chan].fine then
tremolo2(chan);
ef_VibratoVolSlide:
begin
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
If NOT vibr_table2[chan].fine then
vibrato2(chan);
end;
ef_VibratoVSlideFine:
If NOT vibr_table2[chan].fine then
vibrato2(chan);
ef_VolSlide:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_RetrigNote:
If (retrig_table2[chan] >= eHi2) then
begin
retrig_table2[chan] := 0;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Inc(retrig_table2[chan]);
ef_MultiRetrigNote:
If (retrig_table2[chan] >= eHi2 DIV 16) then
begin
Case eHi2 MOD 16 of
0,8: ;
1: slide_volume_down(chan,1);
2: slide_volume_down(chan,2);
3: slide_volume_down(chan,4);
4: slide_volume_down(chan,8);
5: slide_volume_down(chan,16);
9: slide_volume_up(chan,1);
10: slide_volume_up(chan,2);
11: slide_volume_up(chan,4);
12: slide_volume_up(chan,8);
13: slide_volume_up(chan,16);
6: slide_volume_down(chan,chanvol(chan)-
Round(chanvol(chan)*2/3));
7: slide_volume_down(chan,chanvol(chan)-
Round(chanvol(chan)*1/2));
14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)-
chanvol(chan),63));
15: slide_volume_up(chan,max(Round(chanvol(chan)*2)-
chanvol(chan),63));
end;
retrig_table2[chan] := 0;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Inc(retrig_table2[chan]);
ef_Tremor:
If (tremor_table2[chan].pos >= 0) then
begin
If (SUCC(tremor_table2[chan].pos) <= eHi2 DIV 16) then
Inc(tremor_table2[chan].pos)
else begin
slide_volume_down(chan,63);
tremor_table2[chan].pos := -1;
end;
end
else If (PRED(tremor_table2[chan].pos) >= -(eHi2 MOD 16)) then
Dec(tremor_table2[chan].pos)
else begin
set_ins_volume(LO(tremor_table2[chan].volume),
HI(tremor_table2[chan].volume),chan);
tremor_table2[chan].pos := 1;
end;
ef_extended2+ef_fix2+ef_ex2_NoteDelay:
If (notedel_table[chan] = 0) then
begin
notedel_table[chan] := BYTE_NULL;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Dec(notedel_table[chan]);
ef_extended2+ef_fix2+ef_ex2_NoteCut:
If (notecut_table[chan] = 0) then
begin
notecut_table[chan] := BYTE_NULL;
key_off(chan);
end
else Dec(notecut_table[chan]);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp:
global_volume_slide(eHi2,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn:
global_volume_slide(BYTE_NULL,eHi2);
end;
end;
end;
procedure update_fine_effects(chan: Byte);
var
eLo,eHi,
eLo2,eHi2: Byte;
begin
eLo := LO(effect_table[chan]);
eHi := HI(effect_table[chan]);
eLo2 := LO(effect_table2[chan]);
eHi2 := HI(effect_table2[chan]);
Case eLo of
ef_ArpggVSlideFine:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_FSlideUpFine:
portamento_up(chan,eHi,nFreq(12*8+1));
ef_FSlideDownFine:
portamento_down(chan,eHi,nFreq(0));
ef_FSlUpVSlF:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_FSlDownVSlF:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_FSlUpFineVSlide:
portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
ef_FSlUpFineVSlF:
begin
portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
volume_slide(chan,eHi DIV 16,eHi MOD 16);
end;
ef_FSlDownFineVSlide:
portamento_down(chan,fslide_table[chan],nFreq(0));
ef_FSlDownFineVSlF:
begin
portamento_down(chan,fslide_table[chan],nFreq(0));
volume_slide(chan,eHi DIV 16,eHi MOD 16);
end;
ef_TPortamVSlideFine:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_Vibrato:
If vibr_table[chan].fine then
vibrato(chan);
ef_Tremolo:
If trem_table[chan].fine then
tremolo(chan);
ef_VibratoVolSlide:
If vibr_table[chan].fine then
vibrato(chan);
ef_VibratoVSlideFine:
begin
volume_slide(chan,eHi DIV 16,eHi MOD 16);
If vibr_table[chan].fine then
vibrato(chan);
end;
ef_VolSlideFine:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF:
global_volume_slide(eHi,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF:
global_volume_slide(BYTE_NULL,eHi);
end;
Case eLo2 of
ef_ArpggVSlideFine:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_FSlideUpFine:
portamento_up(chan,eHi2,nFreq(12*8+1));
ef_FSlideDownFine:
portamento_down(chan,eHi2,nFreq(0));
ef_FSlUpVSlF:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_FSlDownVSlF:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_FSlUpFineVSlide:
portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
ef_FSlUpFineVSlF:
begin
portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
end;
ef_FSlDownFineVSlide:
portamento_down(chan,fslide_table2[chan],nFreq(0));
ef_FSlDownFineVSlF:
begin
portamento_down(chan,fslide_table2[chan],nFreq(0));
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
end;
ef_TPortamVSlideFine:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_Vibrato:
If vibr_table2[chan].fine then
vibrato2(chan);
ef_Tremolo:
If trem_table2[chan].fine then
tremolo2(chan);
ef_VibratoVolSlide:
If vibr_table2[chan].fine then
vibrato2(chan);
ef_VibratoVSlideFine:
begin
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
If vibr_table2[chan].fine then
vibrato2(chan);
end;
ef_VolSlideFine:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF:
global_volume_slide(eHi2,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF:
global_volume_slide(BYTE_NULL,eHi2);
end;
end;
procedure update_extra_fine_effects;
var
chan,eLo,eHi,
eLo2,eHi2: Byte;
begin
For chan := 1 to songdata.nm_tracks do
begin
eLo := LO(effect_table[chan]);
eHi := HI(effect_table[chan]);
eLo2 := LO(effect_table2[chan]);
eHi2 := HI(effect_table2[chan]);
Case eLo of
ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF:
global_volume_slide(eHi,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF:
global_volume_slide(BYTE_NULL,eHi);
ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF:
volume_slide(chan,eHi,0);
ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF:
volume_slide(chan,0,eHi);
ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF:
portamento_up(chan,eHi,nFreq(12*8+1));
ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF:
portamento_down(chan,eHi,nFreq(0));
ef_ExtraFineArpeggio:
arpeggio(chan);
ef_ExtraFineVibrato:
If NOT vibr_table[chan].fine then
vibrato(chan);
ef_ExtraFineTremolo:
If NOT trem_table[chan].fine then
tremolo(chan);
end;
Case eLo2 of
ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF:
global_volume_slide(eHi2,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF:
global_volume_slide(BYTE_NULL,eHi2);
ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF:
volume_slide(chan,eHi2,0);
ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF:
volume_slide(chan,0,eHi2);
ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF:
portamento_up(chan,eHi2,nFreq(12*8+1));
ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF:
portamento_down(chan,eHi2,nFreq(0));
ef_ExtraFineArpeggio:
arpeggio2(chan);
ef_ExtraFineVibrato:
If NOT vibr_table2[chan].fine then
vibrato2(chan);
ef_ExtraFineTremolo:
If NOT trem_table2[chan].fine then
tremolo2(chan);
end;
end;
end;
function calc_following_order(order: Byte): Integer;
var
result: Integer;
index,jump_count: Byte;
begin
_debug_str_ := 'A2PLAYER.PAS:calc_following_order';
result := -1;
index := order;
jump_count := 0;
Repeat
If (songdata.pattern_order[index] < $80) then result := index
else begin
index := songdata.pattern_order[index]-$80;
Inc(jump_count);
end;
until (jump_count > $7f) or
(result <> -1);
calc_following_order := result;
end;
function calc_order_jump: Integer;
var
temp: Byte;
result: Integer;
begin
_debug_str_ := 'A2PLAYER.PAS:calc_order_jump';
result := 0;
temp := 0;
Repeat
If (songdata.pattern_order[current_order] > $7f) then
current_order := songdata.pattern_order[current_order]-$80;
Inc(temp);
until (temp > $7f) or (songdata.pattern_order[current_order] < $80);
If (temp > $7f) then begin stop_playing; result := -1; end;
calc_order_jump := result;
end;
procedure update_song_position;
var
temp: Byte;
begin
_debug_str_ := 'A2PLAYER.PAS:update_song_position';
If (current_line < PRED(songdata.patt_len)) and NOT pattern_break then Inc(current_line)
else begin
If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and
(current_order < $7f) then
begin
FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL);
FillChar(loop_table,SizeOf(loop_table),BYTE_NULL);
Inc(current_order);
end;
If pattern_break and (next_line AND $0f0 = pattern_loop_flag) then
begin
temp := next_line-pattern_loop_flag;
next_line := loopbck_table[temp];
If (loop_table[temp][current_line] <> 0) then
Dec(loop_table[temp][current_line]);
end
else If pattern_break and (next_line AND $0f0 = pattern_break_flag) then
begin
If (event_table[next_line-pattern_break_flag].effect_def2 = ef_PositionJump) then
current_order := event_table[next_line-pattern_break_flag].effect2
else current_order := event_table[next_line-pattern_break_flag].effect;
pattern_break := FALSE;
end
else If (current_order > $7f) then
current_order := 0;
If (songdata.pattern_order[current_order] > $7f) then
If (calc_order_jump = -1) then EXIT;
current_pattern := songdata.pattern_order[current_order];
If NOT pattern_break then current_line := 0
else begin
pattern_break := FALSE;
current_line := next_line;
end;
end;
For temp := 1 to songdata.nm_tracks do
begin
glfsld_table[temp] := 0;
glfsld_table2[temp] := 0;
end;
If (current_line = 0) and
(current_order = calc_following_order(0)) and speed_update then
begin
tempo := songdata.tempo;
speed := songdata.speed;
update_timer(tempo);
end;
end;
procedure poll_proc;
var
temp: Byte;
var
_debug_str_bak_: String;
begin
_debug_str_bak_ := _debug_str_;
_debug_str_ := 'A2PLAYER.PAS:_poll_proc';
If (NOT pattern_delay and (ticks-tick0+1 >= speed)) or
fast_forward then
begin
If (songdata.pattern_order[current_order] > $7f) then
If (calc_order_jump = -1) then EXIT;
current_pattern := songdata.pattern_order[current_order];
play_line;
If NOT fast_forward then update_effects
else For temp := 1 to speed do
begin
update_effects;
If (temp MOD 4 = temp) then
update_extra_fine_effects;
Inc(ticks);
end;
pattern_break_docmd := pattern_break;
pattern_break_oldord := current_order;
If fast_forward or NOT pattern_delay then
update_song_position;
If (pattern_break_docmd = TRUE) then
pattern_break_loop := current_order = pattern_break_oldord;
tick0 := ticks;
If fast_forward then
If NOT pattern_delay then synchronize_song_timer;
If fast_forward and pattern_delay then
begin
tickD := 0;
pattern_delay := FALSE;
end;
end
else
begin
update_effects;
Inc(ticks);
If pattern_delay and (tickD > 1) then Dec(tickD)
else begin
If pattern_delay then
begin
tick0 := ticks;
update_song_position;
end;
pattern_delay := FALSE;
end;
end;
Inc(tickXF);
If (tickXF MOD 4 = 0) then
begin
update_extra_fine_effects;
Dec(tickXF,4);
end;
_debug_str_ := _debug_str_bak_;
end;
procedure macro_poll_proc;
const
IDLE = $0fff;
FINISHED = $0ffff;
var
chan: Byte;
finished_flag: Word;
var
_debug_str_bak_: String;
begin
_debug_str_bak_ := _debug_str_;
_debug_str_ := 'A2PLAYER.PAS:macro_poll_proc';
For chan := 1 to songdata.nm_tracks do
begin
If NOT keyoff_loop[chan] then finished_flag := FINISHED
else finished_flag := IDLE;
With macro_table[chan] do
begin
With songdata.instr_macros[fmreg_table] do
If (fmreg_table <> 0) and (speed <> 0) then
If (fmreg_duration > 1) then Dec(fmreg_duration)
else begin
fmreg_count := 1;
If (fmreg_pos <= length) then
If (loop_begin <> 0) and (loop_length <> 0) then
If (fmreg_pos = loop_begin+PRED(loop_length)) then
fmreg_pos := loop_begin
else If (fmreg_pos < length) then Inc(fmreg_pos)
else fmreg_pos := finished_flag
else If (fmreg_pos < length) then Inc(fmreg_pos)
else fmreg_pos := finished_flag
else fmreg_pos := finished_flag;
If (freq_table[chan] OR $2000 = freq_table[chan]) and
(keyoff_pos <> 0) and
(fmreg_pos >= keyoff_pos) then
fmreg_pos := IDLE
else If (freq_table[chan] OR $2000 <> freq_table[chan]) and
(fmreg_pos <> 0) and (keyoff_pos <> 0) and
((fmreg_pos < keyoff_pos) or (fmreg_pos = IDLE)) then
fmreg_pos := keyoff_pos;
If (fmreg_pos <> 0) and
(fmreg_pos <> IDLE) and (fmreg_pos <> finished_flag) then
begin
fmreg_duration := data[fmreg_pos].duration;
If (fmreg_duration <> 0) then
With data[fmreg_pos] do
begin
// force KEY-ON with missing ADSR instrument data
force_macro_keyon := FALSE;
If (fmreg_pos = 1) then
If is_ins_adsr_data_empty(voice_table[chan]) and
NOT (songdata.dis_fmreg_col[fmreg_table][0] and
songdata.dis_fmreg_col[fmreg_table][1] and
songdata.dis_fmreg_col[fmreg_table][2] and
songdata.dis_fmreg_col[fmreg_table][3] and
songdata.dis_fmreg_col[fmreg_table][12] and
songdata.dis_fmreg_col[fmreg_table][13] and
songdata.dis_fmreg_col[fmreg_table][14] and
songdata.dis_fmreg_col[fmreg_table][15]) then
force_macro_keyon := TRUE;
If NOT songdata.dis_fmreg_col[fmreg_table][0] then
fmpar_table[chan].adsrw_mod.attck := fm_data.ATTCK_DEC_modulator SHR 4;
If NOT songdata.dis_fmreg_col[fmreg_table][1] then
fmpar_table[chan].adsrw_mod.dec := fm_data.ATTCK_DEC_modulator AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][2] then
fmpar_table[chan].adsrw_mod.sustn := fm_data.SUSTN_REL_modulator SHR 4;
If NOT songdata.dis_fmreg_col[fmreg_table][3] then
fmpar_table[chan].adsrw_mod.rel := fm_data.SUSTN_REL_modulator AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][4] then
fmpar_table[chan].adsrw_mod.wform := fm_data.WAVEFORM_modulator AND $07;
If NOT songdata.dis_fmreg_col[fmreg_table][6] then
fmpar_table[chan].kslM := fm_data.KSL_VOLUM_modulator SHR 6;
If NOT songdata.dis_fmreg_col[fmreg_table][7] then
fmpar_table[chan].multipM := fm_data.AM_VIB_EG_modulator AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][8] then
fmpar_table[chan].tremM := fm_data.AM_VIB_EG_modulator SHR 7;
If NOT songdata.dis_fmreg_col[fmreg_table][9] then
fmpar_table[chan].vibrM := fm_data.AM_VIB_EG_modulator SHR 6 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][10] then
fmpar_table[chan].ksrM := fm_data.AM_VIB_EG_modulator SHR 4 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][11] then
fmpar_table[chan].sustM := fm_data.AM_VIB_EG_modulator SHR 5 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][12] then
fmpar_table[chan].adsrw_car.attck := fm_data.ATTCK_DEC_carrier SHR 4;
If NOT songdata.dis_fmreg_col[fmreg_table][13] then
fmpar_table[chan].adsrw_car.dec := fm_data.ATTCK_DEC_carrier AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][14] then
fmpar_table[chan].adsrw_car.sustn := fm_data.SUSTN_REL_carrier SHR 4;
If NOT songdata.dis_fmreg_col[fmreg_table][15] then
fmpar_table[chan].adsrw_car.rel := fm_data.SUSTN_REL_carrier AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][16] then
fmpar_table[chan].adsrw_car.wform := fm_data.WAVEFORM_carrier AND $07;
If NOT songdata.dis_fmreg_col[fmreg_table][18] then
fmpar_table[chan].kslC := fm_data.KSL_VOLUM_carrier SHR 6;
If NOT songdata.dis_fmreg_col[fmreg_table][19] then
fmpar_table[chan].multipC := fm_data.AM_VIB_EG_carrier AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][20] then
fmpar_table[chan].tremC := fm_data.AM_VIB_EG_carrier SHR 7;
If NOT songdata.dis_fmreg_col[fmreg_table][21] then
fmpar_table[chan].vibrC := fm_data.AM_VIB_EG_carrier SHR 6 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][22] then
fmpar_table[chan].ksrC := fm_data.AM_VIB_EG_carrier SHR 4 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][23] then
fmpar_table[chan].sustC := fm_data.AM_VIB_EG_carrier SHR 5 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][24] then
fmpar_table[chan].connect := fm_data.FEEDBACK_FM AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][25] then
fmpar_table[chan].feedb := fm_data.FEEDBACK_FM SHR 1 AND 7;
If NOT songdata.dis_fmreg_col[fmreg_table][27] then
If NOT pan_lock[chan] then
panning_table[chan] := panning;
If NOT songdata.dis_fmreg_col[fmreg_table][5] then
set_ins_volume(63-fm_data.KSL_VOLUM_modulator AND $3f,
BYTE_NULL,chan);
If NOT songdata.dis_fmreg_col[fmreg_table][17] then
set_ins_volume(BYTE_NULL,
63-fm_data.KSL_VOLUM_carrier AND $3f,chan);
update_modulator_adsrw(chan);
update_carrier_adsrw(chan);
update_fmpar(chan);
If force_macro_keyon or
NOT (fm_data.FEEDBACK_FM OR MACRO_NOTE_RETRIG_FLAG <> fm_data.FEEDBACK_FM) then
begin
If NOT (is_4op_chan(chan) and (chan in _4op_tracks_hi)) then
begin
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,FALSE,TRUE);
If (is_4op_chan(chan) and (chan in _4op_tracks_lo)) then
init_macro_table(PRED(chan),0,voice_table[PRED(chan)],0);
end;
end
else
If NOT (fm_data.FEEDBACK_FM OR MACRO_ENVELOPE_RESTART_FLAG <> fm_data.FEEDBACK_FM) then
begin
key_on(chan);
change_freq(chan,freq_table[chan]);
end
else
If NOT (fm_data.FEEDBACK_FM OR MACRO_ZERO_FREQ_FLAG <> fm_data.FEEDBACK_FM) then
If (freq_table[chan] <> 0) then
begin
zero_fq_table[chan] := freq_table[chan];
freq_table[chan] := freq_table[chan] AND NOT $1fff;
change_freq(chan,freq_table[chan]);
end
else
else
If (zero_fq_table[chan] <> 0) then
begin
freq_table[chan] := zero_fq_table[chan];
zero_fq_table[chan] := 0;
change_freq(chan,freq_table[chan]);
end;
If NOT songdata.dis_fmreg_col[fmreg_table][26] then
If (freq_slide > 0) then
portamento_up(chan,freq_slide,nFreq(12*8+1))
else If (freq_slide < 0) then
portamento_down(chan,Abs(freq_slide),nFreq(0));
end;
end;
end;
With songdata.macro_table[arpg_table].arpeggio do
If (arpg_table <> 0) and (speed <> 0) then
If (arpg_count = speed) then
begin
arpg_count := 1;
If (arpg_pos <= length) then
If (loop_begin <> 0) and (loop_length <> 0) then
If (arpg_pos = loop_begin+PRED(loop_length)) then
arpg_pos := loop_begin
else If (arpg_pos < length) then Inc(arpg_pos)
else arpg_pos := finished_flag
else If (arpg_pos < length) then Inc(arpg_pos)
else arpg_pos := finished_flag
else arpg_pos := finished_flag;
If (freq_table[chan] OR $2000 = freq_table[chan]) and
(keyoff_pos <> 0) and
(arpg_pos >= keyoff_pos) then
arpg_pos := IDLE
else If (freq_table[chan] OR $2000 <> freq_table[chan]) and
(keyoff_pos <> 0) and (keyoff_pos <> 0) and
((arpg_pos < keyoff_pos) or (arpg_pos = IDLE)) then
arpg_pos := keyoff_pos;
If (arpg_pos <> 0) and
(arpg_pos <> IDLE) and (arpg_pos <> finished_flag) then
Case data[arpg_pos] of
0: change_frequency(chan,
nFreq(arpg_note-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
1..96:
change_frequency(chan,
nFreq(max(arpg_note+data[arpg_pos],97)-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
$80..$80+12*8+1:
change_frequency(chan,nFreq(data[arpg_pos]-$80-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
end;
end
else Inc(arpg_count);
With songdata.macro_table[vib_table].vibrato do
If NOT vib_paused and
(vib_table <> 0) and (speed <> 0) then
If (vib_count = speed) then
If (vib_delay <> 0) then Dec(vib_delay)
else begin
vib_count := 1;
If (vib_pos <= length) then
If (loop_begin <> 0) and (loop_length <> 0) then
If (vib_pos = loop_begin+PRED(loop_length)) then
vib_pos := loop_begin
else If (vib_pos < length) then Inc(vib_pos)
else vib_pos := finished_flag
else If (vib_pos < length) then Inc(vib_pos)
else vib_pos := finished_flag
else vib_pos := finished_flag;
If (freq_table[chan] OR $2000 = freq_table[chan]) and
(keyoff_pos <> 0) and
(vib_pos >= keyoff_pos) then
vib_pos := IDLE
else If (freq_table[chan] OR $2000 <> freq_table[chan]) and
(vib_pos <> 0) and (keyoff_pos <> 0) and
((vib_pos < keyoff_pos) or (vib_pos = IDLE)) then
vib_pos := keyoff_pos;
If (vib_pos <> 0) and
(vib_pos <> IDLE) and (vib_pos <> finished_flag) then
If (data[vib_pos] > 0) then
macro_vibrato__porta_up(chan,data[vib_pos])
else If (data[vib_pos] < 0) then
macro_vibrato__porta_down(chan,Abs(data[vib_pos]))
else change_freq(chan,vib_freq);
end
else Inc(vib_count);
end;
end;
_debug_str_ := _debug_str_bak_;
end;
procedure timer_poll_proc;
var
_debug_str_bak_: String;
begin
_debug_str_bak_ := _debug_str_;
_debug_str_ := 'A2PLAYER.PAS:timer_poll_proc';
If (timer_200hz_counter < (IRQ_freq+IRQ_freq_shift+playback_speed_shift) DIV 200) then
Inc(timer_200hz_counter)
else begin
timer_200hz_counter := 0;
timer_200hz_flag := TRUE;
end;
If (timer_50hz_counter < (IRQ_freq+IRQ_freq_shift+playback_speed_shift) DIV 50) then
Inc(timer_50hz_counter)
else begin
timer_50hz_counter := 0;
timer_50hz_flag := TRUE;
end;
If (timer_20hz_counter < (IRQ_freq+IRQ_freq_shift+playback_speed_shift) DIV 20) then
Inc(timer_20hz_counter)
else begin
timer_20hz_counter := 0;
timer_20hz_flag := TRUE;
end;
If NOT replay_forbidden then
begin
If (current_order = 0) and (current_line = 0) and
(tick0 = ticks) then
begin
song_timer := 0;
timer_temp := 0;
song_timer_tenths := 0;
end;
If (play_status = isPlaying) then
begin
song_timer_tenths := TRUNC(100/(IRQ_freq+IRQ_freq_shift+playback_speed_shift)*timer_temp);
If (song_timer_tenths >= 100) then song_timer_tenths := 0;
If (timer_temp < IRQ_freq+IRQ_freq_shift+playback_speed_shift) then Inc(timer_temp)
else begin
Inc(song_timer);
timer_temp := 1;
end;
end;
If (song_timer > 3600-1) then
begin
song_timer := 0;
timer_temp := 0;
song_timer_tenths := 0;
end;
If (ticklooper = 0) or fast_forward then
poll_proc;
If (macro_ticklooper = 0) then
macro_poll_proc;
Inc(ticklooper);
If (ticklooper >= IRQ_freq DIV tempo) then
ticklooper := 0;
Inc(macro_ticklooper);
If (macro_ticklooper >= IRQ_freq DIV (tempo*_macro_speedup)) then
macro_ticklooper := 0;
end;
_debug_str_ := _debug_str_bak_;
end;
const
___IRQ_DATA_END___: Dword = 0;
procedure ___IRQ_CODE_END___; begin end;
procedure DisableTimerIRQ_proc;
begin
asm
in al,21h
or al,1
out 21h,al
end;
end;
procedure EnableTimerIRQ_proc;
begin
asm
in al,21h
and al,0feh
out 21h,al
end;
end;
procedure TimerSetup(Hz: Longint);
begin
_debug_str_ := 'A2PLAYER.PAS:TimerSetup';
If (Hz < 19) then Hz := 19;
If (Hz > 1193180) then Hz := 1193180;
DisableTimerIRQ;
If (timer_poll_proc_ptr <> NIL) then ISS_StopTimer(timer_poll_proc_ptr);
timer_poll_proc_ptr := @timer_poll_proc;
ISS_StartTimer(timer_poll_proc_ptr,ISS_TimerSpeed DIV Hz);
EnableTimerIRQ;
end;
procedure TimerDone;
begin
_debug_str_ := 'A2PLAYER.PAS:TimerDone';
DisableTimerIRQ;
If (timer_poll_proc_ptr <> NIL) then ISS_StopTimer(timer_poll_proc_ptr);
timer_poll_proc_ptr := NIL;
EnableTimerIRQ;
end;
procedure init_timer_proc;
begin
_debug_str_ := 'A2PLAYER.PAS:init_time_proc';
If timer_initialized then EXIT;
timer_initialized := TRUE;
TimerSetup(50);
end;
procedure done_timer_proc;
begin
_debug_str_ := 'A2PLAYER.PAS:done_timer_proc';
If NOT timer_initialized then EXIT;
timer_initialized := FALSE;
TimerDone;
end;
function calc_pattern_pos(pattern: Byte): Byte;
var
index: Integer;
jump_count,pattern_pos: Byte;
begin
_debug_str_ := 'A2PLAYER.PAS:calc_pattern_pos';
pattern_pos := BYTE_NULL;
jump_count := 0;
index := calc_following_order(0);
While (index <> -1) and (jump_count < $7f) do
If (songdata.pattern_order[index] <> pattern) then
If NOT (index < $7f) then BREAK
else begin
Inc(index);
index := calc_following_order(index);
Inc(jump_count);
end
else begin
pattern_pos := index;
BREAK;
end;
calc_pattern_pos := pattern_pos;
end;
procedure init_buffers;
var
temp: Byte;
begin
_debug_str_ := 'A2PLAYER.PAS:init_buffers';
FillChar(fmpar_table,SizeOf(fmpar_table),0);
FillChar(pan_lock,SizeOf(pan_lock),BYTE(panlock));
FillChar(volume_table,SizeOf(volume_table),0);
FillChar(vscale_table,SizeOf(vscale_table),0);
FillChar(modulator_vol,SizeOf(modulator_vol),0);
FillChar(carrier_vol,SizeOf(carrier_vol),0);
FillChar(event_table,SizeOf(event_table),0);
FillChar(freq_table,SizeOf(freq_table),0);
FillChar(zero_fq_table,SizeOf(zero_fq_table),0);
FillChar(effect_table,SizeOf(effect_table),0);
FillChar(effect_table2,SizeOf(effect_table2),0);
FillChar(fslide_table,SizeOf(fslide_table),0);
FillChar(fslide_table2,SizeOf(fslide_table2),0);
FillChar(glfsld_table,SizeOf(glfsld_table),0);
FillChar(glfsld_table2,SizeOf(glfsld_table2),0);
FillChar(porta_table,SizeOf(porta_table),0);
FillChar(porta_table2,SizeOf(porta_table2),0);
FillChar(portaFK_table,SizeOf(portaFK_table),BYTE(FALSE));
FillChar(arpgg_table,SizeOf(arpgg_table),0);
FillChar(arpgg_table2,SizeOf(arpgg_table2),0);
FillChar(vibr_table,SizeOf(vibr_table),0);
FillChar(vibr_table2,SizeOf(vibr_table2),0);
FillChar(trem_table,SizeOf(trem_table),0);
FillChar(trem_table2,SizeOf(trem_table2),0);
FillChar(retrig_table,SizeOf(retrig_table),0);
FillChar(retrig_table2,SizeOf(retrig_table2),0);
FillChar(tremor_table,SizeOf(tremor_table),0);
FillChar(tremor_table2,SizeOf(tremor_table2),0);
FillChar(last_effect,SizeOf(last_effect),0);
FillChar(last_effect2,SizeOf(last_effect2),0);
FillChar(voice_table,SizeOf(voice_table),0);
FillChar(event_new,SizeOf(event_new),0);
FillChar(notedel_table,SizeOf(notedel_table),BYTE_NULL);
FillChar(notecut_table,SizeOf(notecut_table),BYTE_NULL);
FillChar(ftune_table,SizeOf(ftune_table),0);
FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL);
FillChar(loop_table,SizeOf(loop_table),BYTE_NULL);
FillChar(reset_chan,SizeOf(reset_chan),BYTE(FALSE));
FillChar(keyoff_loop,SizeOf(keyoff_loop),BYTE(FALSE));
FillChar(macro_table,SizeOf(macro_table),0);
If NOT lockvol then FillChar(volume_lock,SizeOf(volume_lock),0)
else For temp := 1 to 20 do volume_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 4 AND 1);
If NOT panlock then FillChar(panning_table,SizeOf(panning_table),0)
else For temp := 1 to 20 do panning_table[temp] := songdata.lock_flags[temp] AND 3;
If NOT lockVP then FillChar(peak_lock,SizeOf(peak_lock),0)
else For temp := 1 to 20 do peak_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 5 AND 1);
FillChar(vol4op_lock,SizeOf(vol4op_lock),BYTE(FALSE));
For temp := 1 to 6 do
begin
vol4op_lock[_4op_main_chan[temp]] :=
(songdata.lock_flags[_4op_main_chan[temp]] OR $40 = songdata.lock_flags[_4op_main_chan[temp]]);
vol4op_lock[PRED(_4op_main_chan[temp])] :=
(songdata.lock_flags[PRED(_4op_main_chan[temp])] OR $40 = songdata.lock_flags[PRED(_4op_main_chan[temp])]);
end;
For temp := 1 to 20 do
volslide_type[temp] := songdata.lock_flags[temp] SHR 2 AND 3;
end;
procedure init_player;
var
temp: Byte;
begin
_debug_str_ := 'A2PLAYER.PAS:init_player';
opl2out($01,0);
For temp := 1 to 18 do opl2out($0b0+_chan_n[temp],0);
For temp := $080 to $08d do opl2out(temp,BYTE_NULL);
For temp := $090 to $095 do opl2out(temp,BYTE_NULL);
speed_update := BOOLEAN(songdata.common_flag AND 1);
lockvol := BOOLEAN(songdata.common_flag SHR 1 AND 1);
lockVP := BOOLEAN(songdata.common_flag SHR 2 AND 1);
tremolo_depth := songdata.common_flag SHR 3 AND 1;
vibrato_depth := songdata.common_flag SHR 4 AND 1;
panlock := BOOLEAN(songdata.common_flag SHR 5 AND 1);
percussion_mode := BOOLEAN(songdata.common_flag SHR 6 AND 1);
volume_scaling := BOOLEAN(songdata.common_flag SHR 7 AND 1);
current_tremolo_depth := tremolo_depth;
current_vibrato_depth := vibrato_depth;
init_buffers;
If NOT percussion_mode then
begin
_chan_n := _chmm_n;
_chan_m := _chmm_m;
_chan_c := _chmm_c;
end
else
begin
_chan_n := _chpm_n;
_chan_m := _chpm_m;
_chan_c := _chpm_c;
end;
misc_register := tremolo_depth SHL 7+
vibrato_depth SHL 6+
BYTE(percussion_mode) SHL 5;
opl2out($01,$20);
opl2out($08,$40);
opl3exp($0105);
opl3exp($04+songdata.flag_4op SHL 8);
key_off(17);
key_off(18);
opl2out(_instr[11],misc_register);
global_volume := 63;
vibtrem_speed_factor := def_vibtrem_speed_factor;
vibtrem_table_size := def_vibtrem_table_size;
Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table));
For temp := 1 to 20 do
begin
arpgg_table[temp].state := 1;
voice_table[temp] := temp;
end;
end;
procedure stop_playing;
var
temp: Byte;
begin
_debug_str_ := 'A2PLAYER.PAS:stop_playing';
play_status := isStopped;
replay_forbidden := TRUE;
global_volume := 63;
current_tremolo_depth := tremolo_depth;
current_vibrato_depth := vibrato_depth;
pattern_break := FALSE;
current_order := 0;
current_pattern := 0;
current_line := 0;
song_timer := 0;
timer_temp := 0;
song_timer_tenths := 0;
playback_speed_shift := 0;
For temp := 1 to 20 do release_sustaining_sound(temp);
opl2out(_instr[11],0);
opl3exp($0004);
opl3exp($0005);
init_buffers;
end;
procedure init_old_songdata;
begin
_debug_str_ := 'A2PLAYER.PAS:init_old_songdata';
FillChar(old_songdata,SizeOf(old_songdata),0);
FillChar(old_songdata.pattern_order,SizeOf(old_songdata.pattern_order),$080);
FillChar(old_songdata.instr_data,SizeOf(old_songdata.instr_data),0);
end;
procedure init_songdata;
begin
_debug_str_ := 'A2PLAYER.PAS:init_songdata';
If (play_status <> isStopped) then stop_playing
else init_buffers;
FillChar(songdata,SizeOf(songdata),0);
FillChar(songdata.pattern_order,SizeOf(songdata.pattern_order),$080);
FillChar(pattdata^,PATTERN_SIZE*max_patterns,0);
songdata.patt_len := 64;
songdata.nm_tracks := 9;
songdata.tempo := tempo;
songdata.speed := speed;
songdata.macro_speedup := 1;
songdata.bpm_data.tempo_finetune := IRQ_freq_shift;
speed_update := FALSE;
lockvol := FALSE;
panlock := FALSE;
lockVP := FALSE;
tremolo_depth := 0;
vibrato_depth := 0;
volume_scaling := FALSE;
If (songdata.nm_tracks <= 18) then
begin
percussion_mode := FALSE;
_chan_n := _chmm_n;
_chan_m := _chmm_m;
_chan_c := _chmm_c;
end
else
begin
percussion_mode := TRUE;
_chan_n := _chpm_n;
_chan_m := _chpm_m;
_chan_c := _chpm_c;
end;
end;
procedure start_playing;
begin
_debug_str_ := 'A2PLAYER.PAS:start_playing';
stop_playing;
If (error_code <> 0) then EXIT
else init_player;
current_order := 0;
If (songdata.pattern_order[current_order] > $7f) then
If (calc_order_jump = -1) then EXIT;
current_pattern := songdata.pattern_order[current_order];
current_line := 0;
pattern_break := FALSE;
pattern_delay := FALSE;
tickXF := 0;
ticks := 0;
tick0 := 0;
next_line := 0;
song_timer := 0;
timer_temp := 0;
song_timer_tenths := 0;
replay_forbidden := FALSE;
play_status := isPlaying;
time_playing := 0;
ticklooper := 0;
macro_ticklooper := 0;
speed := songdata.speed;
IRQ_freq_shift := songdata.bpm_data.tempo_finetune;
macro_speedup := songdata.macro_speedup;
playback_speed_shift := 0;
update_timer(songdata.tempo);
end;
procedure get_chunk(pattern,line,chan: Byte; var chunk: tCHUNK);
begin
asm
mov esi,[pattdata]
mov edi,[chunk]
mov al,pattern
inc al
cmp al,max_patterns
jbe @@1
mov ecx,CHUNK_SIZE
xor al,al
rep stosb
jmp @@2
@@1: xor eax,eax
mov al,line
mov ebx,CHUNK_SIZE
mul ebx
mov ecx,eax
xor eax,eax
mov al,chan
dec eax
mov ebx,256*CHUNK_SIZE
mul ebx
add ecx,eax
xor eax,eax
mov al,pattern
mov ebx,8
div ebx
push eax
mov eax,edx
mov ebx,20*256*CHUNK_SIZE
mul ebx
add ecx,eax
pop eax
mov ebx,8*20*256*CHUNK_SIZE
mul ebx
add ecx,eax
add esi,ecx
mov ecx,CHUNK_SIZE
rep movsb
@@2:
end;
end;
procedure put_chunk(pattern,line,chan: Byte; chunk: tCHUNK);
begin
asm
lea esi,[chunk]
mov edi,[pattdata]
mov al,pattern
inc al
cmp al,max_patterns
jbe @@1
mov limit_exceeded,TRUE
jmp @@2
@@1: xor eax,eax
mov al,line
mov ebx,CHUNK_SIZE
mul ebx
mov ecx,eax
xor eax,eax
mov al,chan
dec eax
mov ebx,256*CHUNK_SIZE
mul ebx
add ecx,eax
xor eax,eax
mov al,pattern
mov ebx,8
div ebx
push eax
mov eax,edx
mov ebx,20*256*CHUNK_SIZE
mul ebx
add ecx,eax
pop eax
mov ebx,8*20*256*CHUNK_SIZE
mul ebx
add ecx,eax
add edi,ecx
mov ecx,CHUNK_SIZE
rep movsb
@@2:
end;
end;
procedure count_order(var entries: Byte);
var
index,
index2: Byte;
begin
_debug_str_ := 'A2PLAYER.PAS:count_order';
index := 0;
index2 := 0;
Repeat
If (songdata.pattern_order[index] <> $80) then
begin
If (songdata.pattern_order[index] > $80) then
If (songdata.pattern_order[index]-$80 <> index2) then
begin
index := songdata.pattern_order[index]-$80;
index2 := index;
end
else BREAK;
end
else BREAK;
If (index < $80) then Inc(index);
until (index > $7f);
entries := index;
end;
var
old_exit_proc: procedure;
procedure new_exit_proc;
begin
Unlock_Data(___UNIT_DATA_START___,DWORD(Addr(___UNIT_DATA_END___))-DWORD(Addr(___UNIT_DATA_START___)));
Unlock_Data(___IRQ_DATA_START___,DWORD(Addr(___IRQ_DATA_END___))-DWORD(Addr(___IRQ_DATA_START___)));
Unlock_Code(@___IRQ_CODE_START___,DWORD(@___IRQ_CODE_END___)-DWORD(@___IRQ_CODE_START___));
ExitProc := @old_exit_proc;
end;
begin
FillWord(_opl_regs_cache,SizeOf(_opl_regs_cache) DIV SizeOf(WORD),NOT 0);
Lock_Data(___UNIT_DATA_START___,DWORD(Addr(___UNIT_DATA_END___))-DWORD(Addr(___UNIT_DATA_START___)));
Lock_Data(___IRQ_DATA_START___,DWORD(Addr(___IRQ_DATA_END___))-DWORD(Addr(___IRQ_DATA_START___)));
Lock_Code(@___IRQ_CODE_START___,DWORD(@___IRQ_CODE_END___)-DWORD(@___IRQ_CODE_START___));
@old_exit_proc := ExitProc;
ExitProc := @new_exit_proc;
end.
adlibtracker2-2.4.24/adt2play/txtscrio.pas 0000644 0000000 0000000 00000033403 13411003760 017114 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
unit TxtScrIO;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
interface
const
Black = $00; DGray = $08;
Blue = $01; LBlue = $09;
Green = $02; LGreen = $0a;
Cyan = $03; LCyan = $0b;
Red = $04; LRed = $0c;
Magenta = $05; LMagenta = $0d;
Brown = $06; Yellow = $0e;
LGray = $07; White = $0f;
Blink = $80;
const
MAX_SCREEN_MEM_SIZE = 180*60*2;
SCREEN_MEM_SIZE: Longint = MAX_SCREEN_MEM_SIZE;
type
tSCREEN_MEM = array[0..PRED(MAX_SCREEN_MEM_SIZE)] of Byte;
tSCREEN_MEM_PTR = ^tSCREEN_MEM;
var
text_screen_shadow: tSCREEN_MEM;
const
screen_ptr: Pointer = Addr(text_screen_shadow);
v_seg: Word = $0b800;
v_ofs: Word = 0;
v_mode: Byte = $03;
MaxLn: Byte = 80;
MaxCol: Byte = 25;
var
cursor_backup: Longint;
DispPg: Byte;
type
tFADE = (first,fadeOut,fadeIn);
tDELAY = (fast,delayed);
type
tFADE_BUF = Record
action: tFADE;
pal0: array[0..255] of Record r,g,b: Byte end;
pal1: array[0..255] of Record r,g,b: Byte end;
end;
const
fade_speed: Byte = 63;
type
tVIDEO_STATE = Record
cursor: Longint;
font: Byte;
MaxLn,MaxCol,v_mode,DispPg: Byte;
v_seg,v_ofs: Word;
screen: tSCREEN_MEM;
data: array[0..PRED(4096)] of Byte;
end;
procedure ShowC3Str(var dest; x,y: Byte; str: String; atr1,atr2,atr3: Byte);
function iVGA: Boolean;
function WhereX: Byte;
function WhereY: Byte;
procedure GotoXY(x,y: Byte);
function GetCursor: Longint;
procedure SetCursor(cursor: Longint);
procedure ThinCursor;
procedure WideCursor;
procedure HideCursor;
function GetCursorShape: Word;
procedure SetCursorShape(shape: Word);
procedure GetRGBitem(color: Byte; var red,green,blue: Byte);
procedure SetRGBitem(color: Byte; red,green,blue: Byte);
procedure GetPalette(var pal; first,last: Word);
procedure SetPalette(var pal; first,last: Word);
procedure WaitRetrace;
procedure VgaFade(var data: tFADE_BUF; fade: tFADE; delay: tDELAY);
procedure GetVideoState(var data: tVIDEO_STATE);
procedure SetVideoState(var data: tVIDEO_STATE; restore_screen: Boolean);
implementation
uses
GO32;
var
absolute_pos: Word;
procedure DupChar; assembler;
asm
pushad { IN/ al -column }
xor ebx,ebx { ah -line }
xchg ax,bx { dl -character }
xor eax,eax { dh -attribute }
xchg ax,bx { ecx -count }
mov bl,al { edi -ptr. to write }
mov al,MaxCol
mul ah
add ax,bx
mov bl,MaxCol
sub ax,bx
dec ax
shl ax,1
jecxz @@1
add edi,eax
xchg ax,dx
rep stosw
xchg ax,dx
@@1: mov absolute_pos,ax
popad
end;
procedure ShowC3Str(var dest; x,y: Byte; str: String; atr1,atr2,atr3: Byte);
begin
asm
lea esi,[str]
mov edi,dword ptr [dest]
lodsb
xor ecx,ecx
mov cl,al
jecxz @@3
push ecx
mov al,x
mov ah,y
xor ecx,ecx
call DupChar
xor edx,edx
mov dx,absolute_pos
pop ecx
add edi,edx
mov ah,atr1
mov bl,atr2
mov bh,atr3
@@1: lodsb
cmp al,'~'
jz @@2
cmp al,'`'
jz @@3
stosw
loop @@1
jmp @@4
@@2: xchg ah,bl
loop @@1
jmp @@4
@@3: xchg ah,bh
loop @@1
@@4:
end;
end;
procedure ScreenMemCopy(source,dest: tSCREEN_MEM_PTR);
begin
cursor_backup := GetCursor;
asm
xor edx,edx
mov eax,SCREEN_MEM_SIZE
cmp eax,16
jb @@1
mov ecx,4
div ecx
mov ecx,eax
jecxz @@1
mov esi,dword ptr [source]
mov edi,dword ptr [dest]
cld
rep movsd
mov ecx,edx
jecxz @@2
rep movsb
jmp @@2
@@1: mov ecx,SCREEN_MEM_SIZE
mov esi,dword ptr [source]
mov edi,dword ptr [dest]
cld
rep movsb
@@2:
end;
end;
function WhereX: Byte;
var
result: Byte;
begin
asm
mov bh,DispPg
mov ah,03h
int 10h
inc dl
mov result,dl
end;
WhereX := result;
end;
function WhereY: Byte;
var
result: Byte;
begin
asm
mov bh,DispPg
mov ah,03h
int 10h
inc dh
mov result,dh
end;
WhereY := result;
end;
procedure GotoXY(x,y: Byte);
begin
asm
mov dh,y
mov dl,x
dec dh
dec dl
mov bh,DispPg
mov ah,02h
int 10h
end;
end;
function GetCursor: Longint;
var
result: Longint;
begin
asm
xor edx,edx
mov bh,DispPg
mov ah,03h
int 10h
shl edx,16
xor eax,eax
push edx
call GetCursorShape
pop edx
add edx,eax
mov result,edx
end;
GetCursor := result;
end;
procedure SetCursor(cursor: Longint);
begin
asm
xor eax,eax
mov ax,word ptr [cursor]
push eax
call SetCursorShape
mov dx,word ptr [cursor+2]
mov bh,DispPg
mov ah,02h
int 10h
end;
end;
procedure ThinCursor;
begin
SetCursorShape($0d0e);
end;
procedure WideCursor;
begin
SetCursorShape($010e);
end;
procedure HideCursor;
begin
SetCursorShape($1010);
end;
function GetCursorShape: Word;
var
result: Word;
begin
asm
mov dx,03d4h
mov al,0ah
out dx,al
inc dx
in al,dx
and al,1fh
mov ah,al
dec dx
mov al,0bh
out dx,al
inc dx
in al,dx
and al,1fh
mov result,ax
end;
GetCursorShape := result;
end;
procedure SetCursorShape(shape: Word);
begin
asm
mov dx,03d4h
mov al,0ah
out dx,al
inc dx
in al,dx
mov ah,byte ptr [shape+1]
and al,0e0h
or al,ah
out dx,al
dec dx
mov al,0bh
out dx,al
inc dx
in al,dx
mov ah,byte ptr [shape]
and al,0e0h
or al,ah
out dx,al
end;
end;
procedure initialize;
begin
asm
mov ah,0fh
int 10h
and al,7fh
mov v_mode,al
mov DispPg,bh
end;
MaxCol := MEM[0:$44a];
MaxLn := SUCC(MEM[0:$484]);
FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700);
end;
function iVGA: Boolean;
var
result: Boolean;
begin
asm
mov ax,1a00h
int 10h
cmp al,1ah
jnz @@1
cmp bl,7
jb @@1
cmp bl,0ffh
jnz @@2
@@1: mov result,FALSE
jmp @@3
@@2: mov result,TRUE
@@3:
end;
iVGA := result;
end;
procedure GetRGBitem(color: Byte; var red,green,blue: Byte);
begin
outportb($3c7,color);
red := inportb($3c9);
green := inportb($3c9);
blue := inportb($3c9);
end;
procedure SetRGBitem(color: Byte; red,green,blue: Byte);
begin
outportb($3c8,color);
outportb($3c9,red);
outportb($3c9,green);
outportb($3c9,blue);
end;
procedure GetPalette(var pal; first,last: Word);
begin
asm
xor eax,eax
xor ecx,ecx
mov ax,first
mov cx,last
sub ecx,eax
inc ecx
mov dx,03c7h
out dx,al
add dx,2
mov edi,[pal]
add edi,eax
add edi,eax
add edi,eax
mov eax,ecx
add ecx,eax
add ecx,eax
rep insb
end;
end;
procedure SetPalette(var pal; first,last: Word);
begin
asm
mov dx,03dah
@@1: in al,dx
test al,8
jz @@1
xor eax,eax
xor ecx,ecx
mov ax,first
mov cx,last
sub ecx,eax
inc ecx
mov dx,03c8h
out dx,al
inc dx
mov esi,[pal]
add esi,eax
add esi,eax
add esi,eax
mov eax,ecx
add ecx,eax
add ecx,eax
rep outsb
end;
end;
procedure WaitRetrace;
begin
asm
mov dx,3dah
@@1: in al,dx
and al,08h
jnz @@1
@@2: in al,dx
and al,08h
jz @@2
end;
end;
const
fade_first: Byte = 0;
fade_last: Byte = 255;
procedure VgaFade(var data: tFADE_BUF; fade: tFADE; delay: tDELAY);
var
i,j: Byte;
begin
If (fade = fadeOut) and (data.action in [first,fadeIn]) then
begin
GetPalette(data.pal0,fade_first,fade_last);
If delay = delayed then
For i := fade_speed downto 0 do
begin
For j := fade_first to fade_last do
begin
data.pal1[j].r := data.pal0[j].r * i DIV fade_speed;
data.pal1[j].g := data.pal0[j].g * i DIV fade_speed;
data.pal1[j].b := data.pal0[j].b * i DIV fade_speed;
end;
SetPalette(data.pal1,fade_first,fade_last);
WaitRetrace;
end
else
begin
FillChar(data.pal1,SizeOf(data.pal1),0);
SetPalette(data.pal1,fade_first,fade_last);
end;
data.action := fadeOut;
end;
If (fade = fadeIn) and (data.action = fadeOut) then
begin
If delay = delayed then
For i := 0 to fade_speed do
begin
For j := fade_first to fade_last do
begin
data.pal1[j].r := data.pal0[j].r * i DIV fade_speed;
data.pal1[j].g := data.pal0[j].g * i DIV fade_speed;
data.pal1[j].b := data.pal0[j].b * i DIV fade_speed;
end;
SetPalette(data.pal1,fade_first,fade_last);
WaitRetrace;
end
else
SetPalette(data.pal0,fade_first,fade_last);
data.action := fadeIn;
end;
end;
var
regs: tRealRegs;
dos_sel,dos_seg: Word;
dos_mem_adr: Dword;
bios_data_backup: array[0..167] of Byte;
procedure GetVideoState(var data: tVIDEO_STATE);
begin
asm
mov ah,0fh
int 10h
and al,7fh
mov v_mode,al
mov DispPg,bh
end;
dosmemget(v_seg,v_ofs,data.screen,MAX_SCREEN_MEM_SIZE);
data.cursor := GetCursor;
data.font := MEMW[Seg0040:$85];
data.v_seg := $0b800;
data.v_ofs := MEM[Seg0040:$4e];
data.DispPg := DispPg;
data.v_mode := v_mode;
data.MaxCol := MEM[Seg0040:$4a];
data.MaxLn := SUCC(MEM[Seg0040:$84]);
dosmemget(Seg0040,0,bios_data_backup,168);
dos_mem_adr := global_dos_alloc(SizeOf(tVIDEO_STATE(data).data));
dos_sel := WORD(dos_mem_adr);
dos_seg := WORD(dos_mem_adr SHR 16);
regs.cx := 7;
regs.es := dos_seg;
regs.ax := $1c01;
RealIntr($10,regs);
dosmemput(Seg0040,0,bios_data_backup,168);
dosmemget(dos_seg,0,tVIDEO_STATE(data).data,SizeOf(tVIDEO_STATE(data).data));
global_dos_free(dos_sel);
end;
procedure SetVideoState(var data: tVIDEO_STATE; restore_screen: Boolean);
begin
v_seg := data.v_seg;
v_ofs := data.v_ofs;
v_mode := data.v_mode;
DispPg := data.DispPg;
asm
movzx ax,v_mode
mov bh,DispPg
int 10h
end;
MaxCol := data.MaxCol;
MaxLn := data.MaxLn;
dosmemget(Seg0040,0,bios_data_backup,168);
dos_mem_adr := global_dos_alloc(SizeOf(tVIDEO_STATE(data).data));
dos_sel := WORD(dos_mem_adr);
dos_seg := WORD(dos_mem_adr SHR 16);
dosmemput(dos_seg,0,tVIDEO_STATE(data).data,SizeOf(tVIDEO_STATE(data).data));
regs.cx := 7;
regs.es := dos_seg;
regs.ax := $1c02;
RealIntr($10,regs);
global_dos_free(dos_sel);
dosmemput(Seg0040,0,bios_data_backup,168);
MEM[Seg0040:$4e] := data.v_ofs;
MEM[Seg0040:$4a] := MaxCol;
MEM[Seg0040:$84] := PRED(MaxLn);
Case data.font of
8: asm mov ax,1112h; xor bl,bl; int 10h end;
14: asm mov ax,1111h; xor bl,bl; int 10h end;
else asm mov ax,1114h; xor bl,bl; int 10h end;
end;
SetCursor(data.cursor);
If restore_screen then
dosmemput(v_seg,v_ofs,data.screen,MAX_SCREEN_MEM_SIZE);
end;
begin
initialize;
end.
adlibtracker2-2.4.24/adt2play/iss_tim.pas 0000644 0000000 0000000 00000021060 13411003760 016700 0 ustar root root
{ þ Inquisition's Timer Services Unit þ }
{ þ This file is part of the Inquisition Sound Server for the Free þ }
{ þ Pascal Compiler (http://www.freepascal.org) but also can be þ }
{ þ be distributed separately. The source code is FREE FOR ANY NON þ }
{ þ COMMERCIAL USAGE. þ }
{ þ You can modify this file, but you musn't distribute the þ }
{ þ modified file, only the original version. Instead, send your þ }
{ þ modification to us, so we can add it to the official version. þ }
{ þ Please note, that we can't quarantee the compatibility with þ }
{ þ previous versions. þ }
{ þ If we'll stop the development of this unit in the future, þ }
{ þ the source code will be freely available for any use. þ }
{ þ You can always download the newest version from our website, þ }
{ þ http://scenergy.dfmk.hu/inqcoders/ þ }
{ þ About Inquisition itself, see þ }
{ þ http://scenergy.dfmk.hu/inquisition/ þ }
{ þ Comments, notes, suggestions, bug reports are welcome. þ }
{ þ Send your mails to charlie@scenergy.dfmk.hu þ }
{ þ Please prefer hungarian or english languages. þ }
{ þ ISS_TIM - Timer Unit (GO32V2 Only!) þ }
{ þ Coding Starts : 10. October. 1998. þ }
{ þ Last Modification : 01. March. 2001. þ }
{ þ Note: req. FPC version 1.0.0+ for GO32V2 to compile þ }
{$ASMMODE INTEL}
{$MODE FPC}
Unit ISS_Tim;
Interface
Uses GO32;
Const ISS_TimerSpeed : DWord = 1193180;
ISS_MaxTimers = $8; { þ Maximum Number of Timers þ }
TimerIRQ = $8; { þ HW IRQ Number þ }
ISS_TENoFree = $01; { þ Can't add new timer. All timers locked. þ }
ISS_TENotFound = $02; { þ Can't find specified Timer, to stop. þ }
Type TTimerStruc = Record
TSpeed : DWord;
TCount : DWord; { þ Tick Counter þ }
TPrevCount : DWord; { þ Tick Counter state at prev. activity þ }
TProc : Pointer; { þ Procedure To Call Offset þ }
TActive : Boolean; { þ 1 If The Timer Is On þ }
End;
Var ISS_TimersData : Array[1..ISS_MaxTimers] Of TTimerStruc;
ISS_TimerError : DWord; { þ Contains the last timer error code. þ }
Function ISS_StartTimer(Var NewTProc : Pointer; NewTSpeed : DWord) : Boolean;
Function ISS_StopTimer(Var TimerProc : Pointer) : Boolean;
Function ISS_GetTimerNumber(TimerProc : Pointer) : DWord;
Implementation
Var TimerSpeed : DWord;
OldTimer : TSegInfo;
OldTimerCnt : DWord;
NewIRQActive : Boolean;
NewTimerHandler : TSegInfo;
BackupDS : Word; External Name '___v2prt0_ds_alias';
Procedure UpdateUserTimers;
Type Proc = Procedure;
Var Counter : Word;
Begin
For Counter:=1 To ISS_MaxTimers Do Begin
With ISS_TimersData[Counter] Do Begin
If TActive Then Begin
Inc(TCount,TimerSpeed);
If (TCount>TSpeed) Then Begin
Dec(TCount,TSpeed);
TPrevCount:=TCount;
Proc(TProc); { þ Calling the specified routine þ }
End;
End;
End;
End;
End;
Procedure UpdateUserTimers_Dummy; Begin End;
Procedure SysTimerIRQ; Assembler;
Asm
CLI
PUSH DS
PUSH ES
PUSH FS
PUSH GS
PUSHAD
MOV AX,CS:[BackupDS]
MOV DS,AX
MOV ES,AX
MOV AX,DosMemSelector
MOV FS,AX
CALL UpdateUserTimers
MOV EAX,TimerSpeed
ADD OldTimerCnt,EAX
CMP OldTimerCnt,$10000
JB @NotUpdateClock
SUB OldTimerCnt,$10000
INC WORD PTR FS:[1132]
JNZ @Timer_2
INC WORD PTR FS:[1134]
@Timer_2:
MOV AX,$018
CMP FS:[1134],AX
JNZ @Timer_3
MOV AX,$0B0
CMP FS:[1132],AX
JNZ @Timer_3
MOV WORD PTR FS:[1134],$0
MOV WORD PTR FS:[1132],$0
MOV BYTE PTR FS:[1136],$1
@Timer_3:
@NotUpdateClock:
MOV DX,$20 { þ Interrupt request acknowledge þ }
MOV AL,$20
OUT DX,AL
POPAD
POP GS
POP FS
POP ES
POP DS
IRET
End;
Procedure SysTimerIRQ_Dummy; Begin End;
Procedure SetTimerSpeed(NewTimerSpeed : DWord);
Begin
If NewTimerSpeed<>TimerSpeed Then Begin
Asm
PUSH EAX
CLI
MOV AL,00110110B
OUT 43H,AL
MOV EAX,NEWTIMERSPEED
OUT 40H,AL
MOV AL,AH
OUT 40H,AL
STI
POP EAX
End;
TimerSpeed:=NewTimerSpeed;
End;
End;
Function GetTimerSpeed : DWord;
Var Counter : DWord;
TFastest : DWord;
Begin
TFastest:=$10000;
For Counter:=1 To ISS_MaxTimers Do Begin
If ISS_TimersData[Counter].TActive And
(ISS_TimersData[Counter].TSpeed < TFastest) Then
TFastest:=ISS_TimersData[Counter].TSpeed;
End;
GetTimerSpeed:=TFastest;
End;
Function ISS_StartTimer(Var NewTProc : Pointer; NewTSpeed : DWord) : Boolean;
Var Counter : Word;
TNumber : Word;
Begin
Counter:=0; TNumber:=0;
Repeat
Inc(Counter);
If Not ISS_TimersData[Counter].TActive Then TNumber:=Counter;
Until (TNumber<>0) Or (Counter=ISS_MaxTimers);
If TNumber=0 Then Begin
ISS_TimerError:=ISS_TENoFree;
ISS_StartTimer:=False;
Exit;
End;
If Not NewIRQActive Then Begin
Lock_Data(ISS_TimersData,SizeOf(ISS_TimersData));
Lock_Data(DosMemSelector,SizeOf(DosMemSelector));
Lock_Code(@SysTimerIRQ,DWord(@SysTimerIRQ_Dummy)-DWord(@SysTimerIRQ));
Lock_Code(@UpdateUserTimers,DWord(@UpdateUserTimers_Dummy)-DWord(@UpdateUserTimers));
NewTimerHandler.Offset:=@SysTimerIRQ;
NewTimerHandler.Segment:=Get_CS;
Get_PM_Interrupt(TimerIRQ,OldTimer);
Set_PM_Interrupt(TimerIRQ,NewTimerHandler);
End;
ISS_TimersData[TNumber].TSpeed:=NewTSpeed;
ISS_TimersData[TNumber].TCount:=0;
ISS_TimersData[TNumber].TProc:=NewTProc;
ISS_TimersData[TNumber].TActive:=True;
SetTimerSpeed(GetTimerSpeed);
ISS_StartTimer:=True;
End;
Function ISS_StopTimer(Var TimerProc : Pointer) : Boolean;
Var TNumber : Word;
Counter : Word;
LastTimer : Boolean;
Begin
Disable;
TNumber:=0;
For Counter:=1 To ISS_MaxTimers Do Begin
With ISS_TimersData[Counter] Do Begin
If TActive And (TProc=TimerProc) Then TNumber:=Counter;
End;
End;
If TNumber=0 Then Begin
ISS_TimerError:=ISS_TENotFound;
ISS_StopTimer:=False;
Enable;
End Else Begin
ISS_TimersData[TNumber].TActive:=False;
LastTimer:=True;
For Counter:=1 To ISS_MaxTimers Do Begin
If ISS_TimersData[Counter].TActive=True Then LastTimer:=False;
End;
If LastTimer Then Begin
TimerSpeed:=0;
SetTimerSpeed($10000);
Set_PM_Interrupt(TimerIRQ,OldTimer);
Unlock_Data(DosMemSelector,SizeOf(DosMemSelector));
Unlock_Data(ISS_TimersData,SizeOf(ISS_TimersData));
UnLock_Code(@SysTimerIRQ,DWord(@SysTimerIRQ_Dummy)-DWord(@SysTimerIRQ));
UnLock_Code(@UpdateUserTimers,DWord(@UpdateUserTimers_Dummy)-DWord(@UpdateUserTimers));
End;
ISS_StopTimer:=True;
Enable;
End;
End;
Function ISS_GetTimerNumber(TimerProc : Pointer) : DWord;
Var Counter : DWord;
Begin
For Counter:=1 To ISS_MaxTimers Do Begin
With ISS_TimersData[Counter] Do Begin
If TActive And (TProc=TimerProc) Then Begin
ISS_GetTimerNumber:=Counter;
Exit;
End;
End;
End;
End;
Begin
FillChar(ISS_TimersData,SizeOf(ISS_TimersData),#0);
NewIRQActive:=False;
TimerSpeed:=0;
End.
{ þ ISS_TIM.PAS - (C) 1998-2001 Charlie/Inquisition þ }
{ þ Changelog : þ }
{ þ 1.1.1 - Some code cleanup for less compiler hacking... þ }
{ þ - Webpage and email addresses fixed in the header comment. þ }
{ þ [01.march.2001] þ }
{ þ 1.1.0 - Major update, a new IRQ routine which contains less compiler þ }
{ þ hacking. Based on the docs of FPC 1.0.2. Not tested with þ }
{ þ versions below 1.0.0. GNU AS no longer required to compile. þ }
{ þ [03.december.2000] þ }
{ þ 1.0.2 - Header comment fixed. þ }
{ þ [18.apr.2000] þ }
{ þ 1.0.1 - Removed a limitation which made smartlinking impossible. þ }
{ þ (Reported by Surgi/Terror Opera) þ }
{ þ [13.apr.2000] þ }
{ þ 1.0.0 - First Public Version þ }
{ þ [08.jan.2000] þ }
adlibtracker2-2.4.24/adt2play/a2scrio.pas 0000644 0000000 0000000 00000036061 13411003760 016602 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
unit A2scrIO;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
interface
const
_title_xpos = 10;
_title_ypos = 8;
_title_color = 160;
_title_offset = 320*40;
_timer_xpos = 198;
_timer_ypos = 5;
_timer_color = 1;
_place_holder_color = 150;
_progress_xpos = 8;
_progress_ypos = 155;
_progress_color = 251;
_fname_xpos = 8;
_fname_ypos = 170;
_fname_color = 255;
_pos_str_xpos = 8;
_pos_str_ypos = 186;
_pos_str_color = 252;
const
_decay_bars_initialized: Boolean = FALSE;
_decay_bar_xpos = 10;
_decay_bar_ypos = 140;
_decay_bar_palette_start = 250;
_picture_mode: Boolean = FALSE;
_window_top: Byte = 8;
var
correction: Integer;
entries,
entries2: Byte;
delay_counter: Byte;
procedure refresh_decay_bar(xpos: Word; level: Byte);
procedure decay_bars_refresh;
procedure wtext(xstart,ystart: Word; txt: String; color: Byte);
procedure wtext2(xstart,ystart: Word; txt: String; color: Byte);
procedure C3Write(str: String; atr1,atr2,atr3: Byte);
procedure C3WriteLn(str: String; atr1,atr2,atr3: Byte);
procedure CWriteLn(str: String; atr1,atr2: Byte);
function _progress_str: String;
function _timer_str: String;
function _position_str: String;
function _position_str2: String;
procedure toggle_picture_mode;
procedure fade_out;
implementation
uses
GO32,
A2data,A2player,A2fileIO,
StringIO,TxtScrIO;
const
_ptr_font8x8: Pointer = @font8x8;
_ptr_font8x16: Pointer = @font8x16;
_ptr_picture_palette: Pointer = @picture_palette;
_ptr_picture_bitmap: Pointer = @picture_bitmap;
const
decay_bar_rise: Real = 50.0;
decay_bar_fall: Real = 5.00;
var
old_decay_bar_value: array[1..25] of Byte;
vmem_320x200: array[0..PRED(320*200)] of Byte;
vmem_320x200_mirror: array[0..PRED(320*200)] of Byte;
fade_buf,fade_buf2: tFADE_BUF;
procedure refresh_decay_bar(xpos: Word; level: Byte);
var
_data_ofs: Dword;
begin
_data_ofs := DWORD(Addr(vmem_320x200));
asm
mov edi,_data_ofs
mov edx,[_ptr_picture_palette]
mov esi,[_ptr_picture_bitmap]
mov eax,_decay_bar_ypos
mov ebx,320
mul ebx
movzx ebx,xpos
add eax,ebx
add edi,eax
cmp level,BYTE_NULL
jnz @@1
mov level,0
jmp @@2
@@1: cmp level,2
jae @@2
mov level,2
@@2: mov ecx,10
jecxz @@10
@@3: push ecx
push edi
mov ecx,63*4/3
jecxz @@9
@@4: mov ebx,63*4/3
sub ebx,ecx
movzx eax,level
cmp ebx,eax
jnae @@5
mov ebx,edi
sub ebx,_data_ofs
add ebx,esi
movzx eax,byte ptr [ebx]
jmp @@8
@@5: mov eax,63*4/3
push edx
xor edx,edx
sub eax,ecx
mov ebx,5
div ebx
mov eax,edx
pop edx
cmp eax,3
jbe @@6
mov ebx,edi
sub ebx,_data_ofs
add ebx,esi
movzx eax,byte ptr [ebx]
jmp @@8
@@6: or eax,eax
jnz @@7
xor eax,eax
jmp @@8
@@7: add eax,_decay_bar_palette_start
cmp level,2
jnbe @@8
mov eax,_place_holder_color
@@8: mov byte ptr [edi],al
sub edi,320
loop @@4
@@9: pop edi
pop ecx
inc edi
loop @@3
@@10:
end;
end;
procedure decay_bars_refresh;
var
temp: Byte;
begin
_debug_str_:= 'A2SCRIO.PAS:decay_bars_refresh';
If NOT _picture_mode then EXIT;
dosmemget($0a000,_title_offset,vmem_320x200[_title_offset],
320*_decay_bar_ypos-_title_offset);
If NOT _decay_bars_initialized then
begin
_decay_bars_initialized := TRUE;
For temp := 1 to 25 do
old_decay_bar_value[temp] := BYTE_NULL;
For temp := 1 to 25 do
begin
decay_bar[temp].lvl := 0;
decay_bar[temp].dir := -1;
refresh_decay_bar(_decay_bar_xpos+PRED(temp)*12,0);
end;
end;
For temp := 1 to 25 do
begin
If (decay_bar[temp].dir = 1) then
decay_bar[temp].lvl := decay_bar[temp].lvl+
decay_bar[temp].dir*(decay_bar_rise/IRQ_freq*100)
else
decay_bar[temp].lvl := decay_bar[temp].lvl+
decay_bar[temp].dir*(decay_bar_fall/IRQ_freq*100);
If (decay_bar[temp].lvl < 0) then decay_bar[temp].lvl := 0;
If (decay_bar[temp].lvl > decay_bar[temp].max_lvl) then
begin
decay_bar[temp].dir := -1;
If (decay_bar[temp].lvl > 63) then
decay_bar[temp].lvl := 63;
end;
If (old_decay_bar_value[temp] <> ROUND(decay_bar[temp].lvl*4/3)) then
begin
refresh_decay_bar(_decay_bar_xpos+PRED(temp)*12,
ROUND(decay_bar[temp].lvl*4/3));
old_decay_bar_value[temp] := ROUND(decay_bar[temp].lvl*4/3);
end;
end;
dosmemput($0a000,_title_offset,vmem_320x200[_title_offset],
320*_decay_bar_ypos-_title_offset);
end;
procedure wtext(xstart,ystart: Word; txt: String; color: Byte);
var
x,y: Word;
temp,i,j,b: Word;
begin
_debug_str_:= 'A2SCRIO.PAS:wtext';
If NOT _picture_mode then EXIT;
dosmemget($0a000,320*ystart,vmem_320x200[320*ystart],(8+1)*320);
Move(pGENERIC_IO_BUFFER(_ptr_picture_bitmap)^[320*ystart],
vmem_320x200_mirror[320*ystart],(8+1)*320);
x := xstart+1;
y := ystart+1;
For temp := 1 to Length(txt) do
begin
For j := 0 to 7 do
begin
b := tCHAR8x8(_ptr_font8x8^)[txt[temp]][j];
For i := 7 downto 0 do
If (b OR (1 SHL i) = b) then
vmem_320x200_mirror[x+7-i+(y+j)*320] := 0
end;
Inc(x,8);
end;
x := xstart;
y := ystart;
For temp := 1 to Length(txt) do
begin
For j := 0 to 7 do
begin
b := tCHAR8x8(_ptr_font8x8^)[txt[temp]][j];
For i := 7 downto 0 do
If (b OR (1 SHL i) = b) then
vmem_320x200[x+7-i+(y+j)*320] := color
else vmem_320x200[x+7-i+(y+j)*320] := vmem_320x200_mirror[x+7-i+(y+j)*320];
end;
Inc(x,8);
end;
dosmemput($0a000,320*ystart,vmem_320x200[320*ystart],(8+1)*320);
end;
procedure wtext2(xstart,ystart: Word; txt: String; color: Byte);
const
_double: array[0..15] of Byte = (0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7);
var
x,y: Word;
temp,i,j,b: Word;
begin
_debug_str_:= 'A2SCRIO.PAS:wtext2';
If NOT _picture_mode then EXIT;
dosmemget($0a000,320*ystart,vmem_320x200[320*ystart],(16+1)*320);
Move(pGENERIC_IO_BUFFER(_ptr_picture_bitmap)^[320*ystart],
vmem_320x200_mirror[320*ystart],(16+1)*320);
x := xstart+1;
y := ystart+1;
For temp := 1 to Length(txt) do
begin
For j := 0 to 15 do
begin
b := tCHAR8x16(_ptr_font8x16^)[txt[temp]][j];
For i := 15 downto 0 do
If (b OR (1 SHL _double[i]) = b) then
vmem_320x200_mirror[x+15-i+(y+j)*320] := 0
end;
Inc(x,16);
end;
x := xstart;
y := ystart;
For temp := 1 to Length(txt) do
begin
For j := 0 to 15 do
begin
b := tCHAR8x16(_ptr_font8x16^)[txt[temp]][j];
For i := 15 downto 0 do
If (b OR (1 SHL _double[i]) = b) then
vmem_320x200[x+15-i+(y+j)*320] := color
else vmem_320x200[x+15-i+(y+j)*320] := vmem_320x200_mirror[x+15-i+(y+j)*320];
end;
Inc(x,16);
end;
dosmemput($0a000,320*ystart,vmem_320x200[320*ystart],(16+1)*320);
end;
procedure C3Write(str: String; atr1,atr2,atr3: Byte);
begin
_debug_str_:= 'A2SCRIO.PAS:CWrite';
If _picture_mode then EXIT;
dosmemget($0b800,0,screen_ptr^,MAX_SCREEN_MEM_SIZE);
ShowC3Str(screen_ptr^,WhereX,WhereY,str,atr1,atr2,atr3);
dosmemput($0b800,0,screen_ptr^,MAX_SCREEN_MEM_SIZE);
GotoXY(1,WhereY);
end;
procedure C3WriteLn(str: String; atr1,atr2,atr3: Byte);
begin
_debug_str_:= 'A2SCRIO.PAS:C3WriteLn';
If _picture_mode then EXIT;
ShowC3Str(screen_ptr^,WhereX,WhereY,str,
atr1,atr2,atr3);
WriteLn;
end;
procedure CWriteLn(str: String; atr1,atr2: Byte);
var
temp: Word;
attr,posx,posy: Byte;
color2: Boolean;
begin
_debug_str_:= 'A2SCRIO.PAS:CWriteLn';
If _picture_mode then EXIT;
color2 := FALSE;
attr := atr1;
posx := WhereX;
posy := WhereY;
For temp := 1 to Length(str) do
If (str[temp] <> '~') then
begin
dosmemput($0b800,(posx-1+(posy-1)*MaxCol) SHL 1,BYTE(str[temp]),1);
dosmemput($0b800,(posx-1+(posy-1)*MaxCol) SHL 1+1,attr,1);
If (posx < MaxCol) then Inc(posx)
else begin
posx := 1;
Inc(posy);
If (posy > MaxLn) then
begin
asm
mov ah,06h
mov al,1
mov bh,07h
mov ch,_window_top
mov cl,1
mov dh,MaxLn
mov dl,MaxCol
dec ch
dec cl
dec dh
dec dl
int 10h
end;
Dec(posy);
end;
end;
end
else begin
color2 := NOT color2;
If color2 then attr := atr2 else attr := atr1;
end;
Inc(posy);
If (posy > MaxLn) then
begin
asm
mov ah,06h
mov al,1
mov bh,07h
mov ch,_window_top
mov cl,1
mov dh,MaxLn
mov dl,MaxCol
dec ch
dec cl
dec dh
dec dl
int 10h
end;
Dec(posy);
end;
posx := 1;
GotoXY(posx,posy);
end;
function __progress_str(value: Byte): String;
var
result: String;
begin
result := '';
Repeat
If (value > 4) then
begin
result := result+#4;
Dec(value,4);
end;
If (value <= 4) and (value <> 0) then
result := result+CHR(0+value)
until (value <= 4);
__progress_str := result;
end;
function _progress_str: String;
begin
If (songdata.patt_len = 0) then EXIT;
If (entries <> 0) then
_progress_str :=
ExpStrR(__progress_str(
ROUND(4*38/entries*(current_order-correction+
1/songdata.patt_len*(current_line+1)))),38,#0)
else _progress_str := ExpStrR('',38,#0);
end;
function _timer_str: String;
begin
_timer_str := ExpStrL(Num2str(song_timer DIV 60,10),2,'0')+':'+
ExpStrL(Num2str(song_timer MOD 60,10),2,'0')+'.'+
Num2str(song_timer_tenths DIV 10,10);
end;
function _position_str: String;
begin
If (songdata.patt_len = 0) then EXIT;
If (entries <> 0) then
_position_str :=
'Order '+ExpStrL(Num2str(current_order,10),3,'0')+'/'+
ExpStrL(Num2str(PRED(entries2),10),3,'0')+', '+
'pattern '+ExpStrL(Num2str(current_pattern,10),3,'0')+', '+
'row '+ExpStrL(Num2str(current_line,10),3,'0')+' '+
'['+ExpStrL(Num2str(ROUND(100/entries*(current_order-correction+
1/songdata.patt_len*(current_line+1))),10),3,'0')+'%] '+
'['+_timer_str+']'+' '
else _position_str :=
'Order '+ExpStrL(Num2str(current_order,10),3,'0')+'/'+
ExpStrL(Num2str(PRED(entries2),10),3,'0')+', '+
'pattern '+ExpStrL(Num2str(current_pattern,10),3,'0')+', '+
'row '+ExpStrL(Num2str(current_line,10),3,'0')+' '+
'['+ExpStrL('',3,'0')+'%] '+
'['+_timer_str+']'+' ';
end;
function _position_str2: String;
begin
_position_str2 :=
'Order '+ExpStrL(Num2str(current_order,10),3,'0')+'/'+
ExpStrL(Num2str(PRED(entries2),10),3,'0')+', '+
'pattern '+ExpStrL(Num2str(current_pattern,10),3,'0')+', '+
'row '+ExpStrL(Num2str(current_line,10),3,'0')+' ';
end;
procedure toggle_picture_mode;
var
index: Byte;
begin
_debug_str_:= 'A2SCRIO.PAS:toggle_picture_mode';
If NOT _picture_mode then
begin
fade_speed := 16;
fade_buf.action := first;
VgaFade(fade_buf,fadeOut,delayed);
For index := 1 to 20 do WaitRetrace;
asm mov ax,13h; int 10h end;
For index := 1 to 20 do WaitRetrace;
For index := 0 to 255 do
SetRGBitem(index,tRGB_PALETTE(_ptr_picture_palette^)[index].r,
tRGB_PALETTE(_ptr_picture_palette^)[index].g,
tRGB_PALETTE(_ptr_picture_palette^)[index].b);
fade_speed := 16;
fade_buf.action := first;
VgaFade(fade_buf2,fadeOut,fast);
dosmemput($0a000,0,_ptr_picture_bitmap^,320*200);
_picture_mode := NOT _picture_mode;
wtext(_title_xpos,_title_ypos,'/´T2 PLAYER',_title_color);
VgaFade(fade_buf2,fadeIn,delayed);
end
else begin
_picture_mode := NOT _picture_mode;
VgaFade(fade_buf2,fadeOut,delayed);
asm
mov ax,03h
xor bh,bh
int 10h
end;
end;
end;
procedure fade_out;
var
temp: Byte;
begin
_debug_str_:= 'A2SCRIO.PAS:fade_out';
For temp := overall_volume downto 0 do
begin
set_overall_volume(temp);
delay_counter := 0;
While (delay_counter < overall_volume DIV 20) do
begin
If timer_200hz_flag then
begin
timer_200hz_flag := FALSE;
Inc(delay_counter);
C3Write(DietStr(_position_str+'',PRED(MaxCol)),$0f,0,0);
wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color);
wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color);
wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+'',_pos_str_color);
If timer_50hz_flag then
begin
timer_50hz_flag := FALSE;
decay_bars_refresh;
end;
end;
MEMW[0:$041c] := MEMW[0:$041a];
end;
end;
end;
end.
adlibtracker2-2.4.24/adt2play/iloaders.inc 0000644 0000000 0000000 00000611421 13411003760 017027 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
{
procedure import_old_a2m_event1(patt,line,chan: Byte; old_chunk: tOLD_CHUNK;
processing_whole_song: Boolean);
procedure replace_old_adsr(patterns: Byte);
procedure import_old_a2m_patterns1(block: Byte; count: Byte);
procedure import_old_a2m_event2(patt,line,chan: Byte; old_chunk: tOLD_CHUNK);
procedure import_old_a2m_patterns2(block: Byte; count: Byte);
procedure import_old_flags;
procedure import_old_songdata(old_songdata: pOLD_FIXED_SONGDATA);
procedure import_old_instruments(old_songdata: pOLD_FIXED_SONGDATA;
new_songdata: pFIXED_SONGDATA;
instr,count: Byte);
procedure import_single_old_instrument(old_songdata: pOLD_FIXED_SONGDATA;
pos,instr: Byte);
function insert_command(cmd,cmd2: Word; patterns: Byte; chan: Byte; exceptions: tByteSet): Boolean;
procedure a2m_file_loader;
procedure a2t_file_loader;
procedure a2p_file_loader;
function dec2hex(dec: Byte): Byte;
function truncate_string(str: String): String;
procedure amd_file_loader;
procedure import_cff_event(patt,line,chan,byte0,byte1,byte2: Byte);
procedure import_cff_patterns(var data; patterns: Byte);
procedure cff_file_loader;
procedure import_standard_instrument(inst: Byte; var data);
procedure dfm_file_loader;
procedure import_hsc_event(patt,line,chan: Byte; event: Word);
procedure import_hsc_patterns(var data; patterns: Byte);
procedure import_hsc_instrument(inst: Byte; var data);
procedure hsc_file_loader;
procedure mtk_file_loader;
procedure rad_file_loader;
procedure fix_s3m_commands(patterns: Byte);
procedure fix_single_pattern(patt: Byte);
procedure s3m_file_loader;
procedure fix_fmk_commands(patterns: Byte);
procedure import_fin_instrument(inst: Byte; var data);
procedure fmk_file_loader;
procedure import_sat_instrument(inst: Byte; var data);
function import_sat_instrument_name(var data; inst: Byte): String;
procedure sat_file_loader;
function _sal(op1,op2: Word): Byte;
function _sar(op1,op2: Word): Byte;
procedure import_sa2_effect(effect,def1,def2: Byte;
var out1,out2: Byte);
procedure sa2_file_loader;
}
var
adsr_carrier: array[1..9] of Boolean;
procedure import_old_a2m_event1(patt,line,chan: Byte; old_chunk: tOLD_CHUNK;
processing_whole_song: Boolean);
const
fx_Arpeggio = $00;
fx_FSlideUp = $01;
fx_FSlideDown = $02;
fx_FSlideUpFine = $03;
fx_FSlideDownFine = $04;
fx_TonePortamento = $05;
fx_TPortamVolSlide = $06;
fx_Vibrato = $07;
fx_VibratoVolSlide = $08;
fx_SetOpIntensity = $09;
fx_SetInsVolume = $0a;
fx_PatternBreak = $0b;
fx_PatternJump = $0c;
fx_SetTempo = $0d;
fx_SetTimer = $0e;
fx_Extended = $0f;
fx_ex_DefAMdepth = $00;
fx_ex_DefVibDepth = $01;
fx_ex_DefWaveform = $02;
fx_ex_ManSlideUp = $03;
fx_ex_ManSlideDown = $04;
fx_ex_VSlideUp = $05;
fx_ex_VSlideDown = $06;
fx_ex_VSlideUpFine = $07;
fx_ex_VSlideDownFine = $08;
fx_ex_RetrigNote = $09;
fx_ex_SetAttckRate = $0a;
fx_ex_SetDecayRate = $0b;
fx_ex_SetSustnLevel = $0c;
fx_ex_SetReleaseRate = $0d;
fx_ex_SetFeedback = $0e;
fx_ex_ExtendedCmd = $0f;
var
chunk: tCHUNK;
begin
FillChar(chunk,SizeOf(chunk),0);
chunk.note := old_chunk.note;
chunk.instr_def := old_chunk.instr_def;
chunk.effect_def := old_chunk.effect_def;
chunk.effect := old_chunk.effect;
Case old_chunk.effect_def of
fx_Arpeggio: chunk.effect_def := ef_Arpeggio;
fx_FSlideUp: chunk.effect_def := ef_FSlideUp;
fx_FSlideDown: chunk.effect_def := ef_FSlideDown;
fx_FSlideUpFine: chunk.effect_def := ef_FSlideUpFine;
fx_FSlideDownFine: chunk.effect_def := ef_FSlideDownFine;
fx_TonePortamento: chunk.effect_def := ef_TonePortamento;
fx_TPortamVolSlide: chunk.effect_def := ef_TPortamVolSlide;
fx_Vibrato: chunk.effect_def := ef_Vibrato;
fx_VibratoVolSlide: chunk.effect_def := ef_VibratoVolSlide;
fx_SetInsVolume: chunk.effect_def := ef_SetInsVolume;
fx_PatternJump: chunk.effect_def := ef_PositionJump;
fx_PatternBreak: chunk.effect_def := ef_PatternBreak;
fx_SetTempo: chunk.effect_def := ef_SetSpeed;
fx_SetTimer: chunk.effect_def := ef_SetTempo;
fx_SetOpIntensity:
If (old_chunk.effect DIV 16 <> 0) then
begin
chunk.effect_def := ef_SetCarrierVol;
chunk.effect := 3+(old_chunk.effect DIV 16)*4;
end
else If (old_chunk.effect MOD 16 <> 0) then
begin
chunk.effect_def := ef_SetModulatorVol;
chunk.effect := 3+(old_chunk.effect MOD 16)*4;
end
else chunk.effect_def := 0;
fx_Extended:
Case old_chunk.effect DIV 16 of
fx_ex_DefAMdepth:
begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetTremDepth*16+old_chunk.effect MOD 16;
end;
fx_ex_DefVibDepth:
begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetVibDepth*16+old_chunk.effect MOD 16;
end;
fx_ex_DefWaveform:
begin
chunk.effect_def := ef_SetWaveform;
Case old_chunk.effect MOD 16 of
0..3: chunk.effect := (old_chunk.effect MOD 16)*16+$0f;
4..7: chunk.effect := $0f0+(old_chunk.effect MOD 16)-4;
end;
end;
fx_ex_VSlideUp:
begin
chunk.effect_def := ef_VolSlide;
chunk.effect := (old_chunk.effect MOD 16)*16;
end;
fx_ex_VSlideDown:
begin
chunk.effect_def := ef_VolSlide;
chunk.effect := old_chunk.effect MOD 16;
end;
fx_ex_VSlideUpFine:
begin
chunk.effect_def := ef_VolSlideFine;
chunk.effect := (old_chunk.effect MOD 16)*16;
end;
fx_ex_VSlideDownFine:
begin
chunk.effect_def := ef_VolSlideFine;
chunk.effect := old_chunk.effect MOD 16;
end;
fx_ex_ManSlideUp:
begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_FineTuneUp*16+old_chunk.effect MOD 16;
end;
fx_ex_ManSlideDown:
begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_FineTuneDown*16+old_chunk.effect MOD 16;
end;
fx_ex_RetrigNote:
begin
chunk.effect_def := ef_RetrigNote;
chunk.effect := SUCC(old_chunk.effect MOD 16);
end;
fx_ex_SetAttckRate:
begin
chunk.effect_def := ef_Extended;
chunk.effect := old_chunk.effect MOD 16;
If NOT adsr_carrier[chan] then
Inc(chunk.effect,ef_ex_SetAttckRateM*16)
else Inc(chunk.effect,ef_ex_SetAttckRateC*16);
end;
fx_ex_SetDecayRate:
begin
chunk.effect_def := ef_Extended;
chunk.effect := old_chunk.effect MOD 16;
If NOT adsr_carrier[chan] then
Inc(chunk.effect,ef_ex_SetDecayRateM*16)
else Inc(chunk.effect,ef_ex_SetDecayRateC*16);
end;
fx_ex_SetSustnLevel:
begin
chunk.effect_def := ef_Extended;
chunk.effect := old_chunk.effect MOD 16;
If NOT adsr_carrier[chan] then
Inc(chunk.effect,ef_ex_SetSustnLevelM*16)
else Inc(chunk.effect,ef_ex_SetSustnLevelC*16);
end;
fx_ex_SetReleaseRate:
begin
chunk.effect_def := ef_Extended;
chunk.effect := old_chunk.effect MOD 16;
If NOT adsr_carrier[chan] then
Inc(chunk.effect,ef_ex_SetRelRateM*16)
else Inc(chunk.effect,ef_ex_SetRelRateC*16);
end;
fx_ex_SetFeedback:
begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetFeedback*16+old_chunk.effect MOD 16;
end;
fx_ex_ExtendedCmd:
If (old_chunk.effect MOD 16 in [0..9]) then
begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_ExtendedCmd2*16;
Case old_chunk.effect MOD 16 of
0: Inc(chunk.effect,ef_ex_cmd2_RSS);
1: Inc(chunk.effect,ef_ex_cmd2_LockVol);
2: Inc(chunk.effect,ef_ex_cmd2_UnlockVol);
3: Inc(chunk.effect,ef_ex_cmd2_LockVP);
4: Inc(chunk.effect,ef_ex_cmd2_UnlockVP);
5: begin
If processing_whole_song then chunk.effect_def := 255
else chunk.effect_def := 0;
chunk.effect := 0;
adsr_carrier[chan] := TRUE;
end;
6: begin
If processing_whole_song then chunk.effect_def := 255
else chunk.effect_def := 0;
If processing_whole_song then chunk.effect := 1
else chunk.effect := 0;
adsr_carrier[chan] := FALSE;
end;
7: Inc(chunk.effect,ef_ex_cmd2_VSlide_car);
8: Inc(chunk.effect,ef_ex_cmd2_VSlide_mod);
9: Inc(chunk.effect,ef_ex_cmd2_VSlide_def);
end;
end
else begin
chunk.effect_def := 0;
chunk.effect := 0;
end;
end;
end;
put_chunk(patt,line,chan,chunk);
end;
procedure replace_old_adsr(patterns: Byte);
var
chunk,chunk2: tCHUNK;
temp2,temp3: Byte;
patt_break: Byte;
order,patt: Byte;
patts: String;
begin
patts := '';
FillChar(adsr_carrier,SizeOf(adsr_carrier),0);
order := 0; patt := BYTE_NULL;
Repeat
If (songdata.pattern_order[order] >= $80) then Inc(order)
else
begin
patt := songdata.pattern_order[order];
patt_break := BYTE_NULL;
For temp2 := 0 to $3f do
For temp3 := 1 to 9 do
begin
get_chunk(patt,temp2,temp3,chunk);
chunk2 := chunk;
If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then
patt_break := temp2;
If (chunk.effect_def in [$ff,ef_Extended]) then
begin
If (chunk.effect_def = $ff) then
begin
chunk2.effect_def := 0;
chunk2.effect := 0;
If (temp2 <= patt_break) then
Case chunk.effect of
0: adsr_carrier[temp3] := TRUE;
1: adsr_carrier[temp3] := FALSE;
end;
end;
If (chunk.effect_def = ef_Extended) then
Case chunk.effect DIV 16 of
ef_ex_SetAttckRateM,
ef_ex_SetAttckRateC:
If adsr_carrier[temp3] then
chunk2.effect := ef_ex_SetAttckRateC*16+chunk.effect MOD 16
else chunk2.effect := ef_ex_SetAttckRateM*16+chunk.effect MOD 16;
ef_ex_SetDecayRateM,
ef_ex_SetDecayRateC:
If adsr_carrier[temp3] then
chunk2.effect := ef_ex_SetDecayRateC*16+chunk.effect MOD 16
else chunk2.effect := ef_ex_SetDecayRateM*16+chunk.effect MOD 16;
ef_ex_SetSustnLevelM,
ef_ex_SetSustnLevelC:
If adsr_carrier[temp3] then
chunk2.effect := ef_ex_SetSustnLevelC*16+chunk.effect MOD 16
else chunk2.effect := ef_ex_SetSustnLevelM*16+chunk.effect MOD 16;
ef_ex_SetRelRateM,
ef_ex_SetRelRateC:
If adsr_carrier[temp3] then
chunk2.effect := ef_ex_SetRelRateC*16+chunk.effect MOD 16
else chunk2.effect := ef_ex_SetRelRateM*16+chunk.effect MOD 16;
end;
If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then
If (chunk.effect_def <> chunk2.effect_def) or
(chunk.effect <> chunk2.effect) then
put_chunk(patt,temp2,temp3,chunk2);
end;
end;
Inc(order);
patts := patts+CHR(patt);
end;
until (patt >= patterns) or (order > $7f);
end;
procedure import_old_a2m_patterns1(block: Byte; count: Byte);
procedure get_old_chunk(pattern,line,channel: Byte; var chunk: tOLD_CHUNK);
begin chunk := old_hash_buffer[pattern][line][channel]; end;
var
patt,line,chan: Byte;
chunk: tOLD_CHUNK;
begin { import_old_a2m_patterns1 }
For patt := 0 to max(PRED(count),15) do
For line := 0 to $3f do
For chan := 1 to 9 do
begin
get_old_chunk(patt,line,chan,chunk);
import_old_a2m_event1(block*16+patt,line,chan,chunk,TRUE);
end;
end;
procedure import_old_a2m_event2(patt,line,chan: Byte; old_chunk: tOLD_CHUNK);
const
ef_ManualFSlide = 22;
var
chunk: tCHUNK;
begin
FillChar(chunk,SizeOf(chunk),0);
chunk.note := old_chunk.note;
chunk.instr_def := old_chunk.instr_def;
If (old_chunk.effect_def <> ef_ManualFSlide) then
begin
chunk.effect_def := old_chunk.effect_def;
chunk.effect := old_chunk.effect;
end
else If (old_chunk.effect DIV 16 <> 0) then
begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_FineTuneUp*16+old_chunk.effect DIV 16;
end
else begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_FineTuneDown*16+old_chunk.effect MOD 16;
end;
put_chunk(patt,line,chan,chunk);
end;
procedure import_old_a2m_patterns2(block: Byte; count: Byte);
procedure get_old_chunk(pattern,line,channel: Byte; var chunk: tOLD_CHUNK);
begin chunk := hash_buffer[pattern][channel][line]; end;
var
patt,line,chan: Byte;
chunk: tOLD_CHUNK;
begin { import_old_a2m_patterns2 }
For patt := 0 to max(PRED(count),7) do
For line := 0 to $3f do
For chan := 1 to 18 do
begin
get_old_chunk(patt,line,chan,chunk);
import_old_a2m_event2(block*8+patt,line,chan,chunk);
end;
end;
procedure import_old_flags;
var
temp: Byte;
begin
If (songdata.common_flag OR 2 = songdata.common_flag) then
For temp := 1 to 20 do
songdata.lock_flags[temp] := songdata.lock_flags[temp] OR $10;
If (songdata.common_flag OR 4 = songdata.common_flag) then
For temp := 1 to 20 do
songdata.lock_flags[temp] := songdata.lock_flags[temp] OR $20;
If (songdata.common_flag OR $20 = songdata.common_flag) then
For temp := 1 to 20 do
songdata.lock_flags[temp] := songdata.lock_flags[temp] AND NOT 3;
end;
procedure import_old_songdata(old_songdata: pOLD_FIXED_SONGDATA);
var
temp: Byte;
begin
songdata.songname := old_songdata^.songname;
songdata.composer := old_songdata^.composer;
For temp := 1 to 250 do
begin
songdata.instr_names[temp] := old_songdata^.instr_names[temp];
songdata.instr_data[temp].fm_data := old_songdata^.instr_data[temp].fm_data;
songdata.instr_data[temp].panning := old_songdata^.instr_data[temp].panning;
songdata.instr_data[temp].fine_tune := old_songdata^.instr_data[temp].fine_tune;
songdata.instr_data[temp].perc_voice := 0;
end;
Move(old_songdata^.pattern_order,
songdata.pattern_order,
SizeOf(old_songdata^.pattern_order));
songdata.tempo := old_songdata^.tempo;
songdata.speed := old_songdata^.speed;
songdata.common_flag := old_songdata^.common_flag;
import_old_flags;
end;
function insert_command(cmd,cmd2: Word; patterns: Byte; chan: Byte; exceptions: tByteSet): Boolean;
var
chunk: tCHUNK;
temp2,temp3: Byte;
patt_break: Byte;
order,patt: Byte;
patts: String;
begin
patts := '';
order := 0;
patt := BYTE_NULL;
insert_command := FALSE;
Repeat
If (Pos(CHR(songdata.pattern_order[order]),patts) <> 0) or
(songdata.pattern_order[order] >= $80) then Inc(order)
else
begin
patt := songdata.pattern_order[order];
patt_break := songdata.patt_len;
For temp3 := 1 to songdata.nm_tracks do
For temp2 := 0 to PRED(songdata.patt_len) do
begin
get_chunk(patt,temp2,temp3,chunk);
If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) or
(chunk.effect_def2 in [ef_PositionJump,ef_PatternBreak]) then
patt_break := temp2;
If (temp3 = chan) and (temp2 <= patt_break) then
If (cmd2 = 0) then
If (chunk.effect_def+chunk.effect = 0) or
(chunk.effect_def SHL 8 + chunk.effect = cmd) or
(chunk.effect_def in exceptions) then
begin
chunk.effect_def := HI(cmd);
chunk.effect := LO(cmd);
put_chunk(patt,temp2,temp3,chunk);
insert_command := TRUE;
EXIT;
end
else If (chunk.effect_def2+chunk.effect2 = 0) or
(chunk.effect_def2 SHL 8 + chunk.effect2 = cmd2) or
(chunk.effect_def2 in exceptions) then
begin
chunk.effect_def2 := HI(cmd);
chunk.effect2 := LO(cmd);
put_chunk(patt,temp2,temp3,chunk);
insert_command := TRUE;
EXIT;
end
else
else If ((chunk.effect_def+chunk.effect = 0) or
(chunk.effect_def SHL 8 + chunk.effect = cmd) or
(chunk.effect_def in exceptions)) and
((chunk.effect_def2+chunk.effect2 = 0) or
(chunk.effect_def2 SHL 8 + chunk.effect2 = cmd2) or
(chunk.effect_def2 in exceptions)) then
begin
chunk.effect_def := HI(cmd);
chunk.effect := LO(cmd);
chunk.effect_def2 := HI(cmd2);
chunk.effect2 := LO(cmd2);
put_chunk(patt,temp2,temp3,chunk);
insert_command := TRUE;
EXIT;
end;
end;
Inc(order);
patts := patts+CHR(patt);
end;
until (patt >= patterns) or (order > $7f);
end;
procedure a2m_file_loader;
type
tOLD_HEADER = Record
ident: array[1..10] of Char;
crc32: Longint;
ffver: Byte;
patts: Byte;
b0len: Word;
b1len: Word;
b2len: Word;
b3len: Word;
b4len: Word;
b5len: Word;
b6len: Word;
b7len: Word;
b8len: Word;
end;
type
tHEADER = Record
ident: array[1..10] of Char;
crc32: Longint;
ffver: Byte;
patts: Byte;
b0len: Longint;
b1len: array[0..15] of Longint;
end;
const
id = '_A2module_';
const
old_a2m_header_size = 26;
var
f: File;
header: tHEADER;
header2: tOLD_HEADER;
temp,temp2: Longint;
crc: Longint;
xlen: array[0..6] of Word;
begin
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and (header.ident = id)) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
If NOT (header.ffver in [1..FFVER_A2M]) then
begin
CloseF(f);
EXIT;
end;
init_old_songdata;
If (header.ffver in [1..4]) then
begin
FillChar(adsr_carrier,SizeOf(adsr_carrier),BYTE(FALSE));
ResetF(f);
BlockReadF(f,header2,SizeOf(header2),temp);
If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then
begin
CloseF(f);
EXIT;
end;
xlen[0] := header2.b2len;
xlen[1] := header2.b3len;
xlen[2] := header2.b4len;
SeekF(f,old_a2m_header_size);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
crc := DWORD_NULL;
BlockReadF(f,buf1,header2.b0len,temp);
If NOT (temp = header2.b0len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header2.b1len,temp);
If NOT (temp = header2.b1len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
For temp2 := 0 to 2 do
If ((header2.patts-1) DIV 16 > temp2) then
begin
BlockReadF(f,buf1,xlen[temp2],temp);
If NOT (temp = xlen[temp2]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
end;
crc := Update32(header2.b0len,2,crc);
crc := Update32(header2.b1len,2,crc);
For temp2 := 0 to 2 do
crc := Update32(xlen[temp2],2,crc);
If (crc <> header2.crc32) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 9
else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9;
SeekF(f,old_a2m_header_size);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,buf1,header2.b0len,temp);
If NOT (temp = header2.b0len) then
begin
CloseF(f);
EXIT;
end;
Case header2.ffver of
4: Move(buf1,old_songdata,header2.b0len);
3: LZSS_decompress(buf1,old_songdata,header2.b0len);
2: LZW_decompress(buf1,old_songdata);
1: SIXPACK_decompress(buf1,old_songdata,header2.b0len);
end;
For temp := 1 to 250 do
old_songdata.instr_data[temp].panning := 0;
BlockReadF(f,buf1,header2.b1len,temp);
If NOT (temp = header2.b1len) then
begin
CloseF(f);
EXIT;
end;
Case header2.ffver of
4: Move(buf1,old_hash_buffer,header2.b1len);
3: LZSS_decompress(buf1,old_hash_buffer,header2.b1len);
2: LZW_decompress(buf1,old_hash_buffer);
1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b1len);
end;
import_old_a2m_patterns1(0,16);
For temp2 := 0 to 2 do
If ((header2.patts-1) DIV 16 > temp2) then
begin
BlockReadF(f,buf1,xlen[temp2],temp);
If NOT (temp = xlen[temp2]) then
begin
CloseF(f);
EXIT;
end;
Case header2.ffver of
4: Move(buf1,old_hash_buffer,xlen[temp2]);
3: LZSS_decompress(buf1,old_hash_buffer,xlen[temp2]);
2: LZW_decompress(buf1,old_hash_buffer);
1: SIXPACK_decompress(buf1,old_hash_buffer,xlen[temp2]);
end;
import_old_a2m_patterns1(SUCC(temp2),16);
end;
replace_old_adsr(header2.patts);
import_old_songdata(Addr(old_songdata));
end;
If (header.ffver in [5..8]) then
begin
ResetF(f);
BlockReadF(f,header2,SizeOf(header2),temp);
If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then
begin
CloseF(f);
EXIT;
end;
xlen[0] := header2.b2len;
xlen[1] := header2.b3len;
xlen[2] := header2.b4len;
xlen[3] := header2.b5len;
xlen[4] := header2.b6len;
xlen[5] := header2.b7len;
xlen[6] := header2.b8len;
crc := DWORD_NULL;
BlockReadF(f,buf1,header2.b0len,temp);
If NOT (temp = header2.b0len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header2.b1len,temp);
If NOT (temp = header2.b1len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
For temp2 := 0 to 6 do
If ((header2.patts-1) DIV 8 > temp2) then
begin
BlockReadF(f,buf1,xlen[temp2],temp);
If NOT (temp = xlen[temp2]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
end;
crc := Update32(header2.b0len,2,crc);
crc := Update32(header2.b1len,2,crc);
For temp2 := 0 to 6 do
crc := Update32(xlen[temp2],2,crc);
If (crc <> header2.crc32) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 18
else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18;
SeekF(f,SizeOf(header2));
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,buf1,header2.b0len,temp);
If NOT (temp = header2.b0len) then
begin
CloseF(f);
EXIT;
end;
Case header2.ffver of
8: Move(buf1,old_songdata,header2.b0len);
7: LZSS_decompress(buf1,old_songdata,header2.b0len);
6: LZW_decompress(buf1,old_songdata);
5: SIXPACK_decompress(buf1,old_songdata,header2.b0len);
end;
BlockReadF(f,buf1,header2.b1len,temp);
If NOT (temp = header2.b1len) then
begin
CloseF(f);
EXIT;
end;
Case header2.ffver of
8: Move(buf1,hash_buffer,header2.b1len);
7: LZSS_decompress(buf1,hash_buffer,header2.b1len);
6: LZW_decompress(buf1,hash_buffer);
5: SIXPACK_decompress(buf1,hash_buffer,header2.b1len);
end;
import_old_a2m_patterns2(0,8);
For temp2 := 0 to 6 do
If ((header2.patts-1) DIV 8 > temp2) then
begin
BlockReadF(f,buf1,xlen[temp2],temp);
If NOT (temp = xlen[temp2]) then
begin
CloseF(f);
EXIT;
end;
Case header2.ffver of
8: Move(buf1,hash_buffer,header2.b2len);
7: LZSS_decompress(buf1,hash_buffer,header2.b2len);
6: LZW_decompress(buf1,hash_buffer);
5: SIXPACK_decompress(buf1,hash_buffer,header2.b2len);
end;
import_old_a2m_patterns2(SUCC(temp2),8);
end;
import_old_songdata(Addr(old_songdata));
end;
If (header.ffver in [9,10,11]) then
begin
crc := DWORD_NULL;
BlockReadF(f,buf1,header.b0len,temp);
If NOT (temp = header.b0len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b1len[0],temp);
If NOT (temp = header.b1len[0]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
For temp2 := 1 to 15 do
If ((header.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header.b1len[temp2],temp);
If NOT (temp = header.b1len[temp2]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
end;
crc := Update32(header.b0len,2,crc);
For temp2 := 0 to 15 do
crc := Update32(header.b1len[temp2],2,crc);
If (crc <> header.crc32) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
SeekF(f,SizeOf(header));
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,buf1,header.b0len,temp);
If NOT (temp = header.b0len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata);
BlockReadF(f,buf1,header.b1len[0],temp);
If NOT (temp = header.b1len[0]) then
begin
CloseF(f);
EXIT;
end;
If (header.ffver = 9) then
import_old_flags;
APACK_decompress(buf1,pattdata^[0]);
For temp2 := 1 to 15 do
If ((header.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header.b1len[temp2],temp);
If NOT (temp = header.b1len[temp2]) then
begin
CloseF(f);
EXIT;
end;
If (temp2*8+8 <= max_patterns) then
APACK_decompress(buf1,pattdata^[temp2])
else limit_exceeded := TRUE;
end;
end;
If (header.ffver in [12,13,FFVER_A2M]) then
begin
crc := DWORD_NULL;
BlockReadF(f,buf1,header.b0len,temp);
If NOT (temp = header.b0len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b1len[0],temp);
If NOT (temp = header.b1len[0]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
For temp2 := 1 to 15 do
If ((header.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header.b1len[temp2],temp);
If NOT (temp = header.b1len[temp2]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
end;
crc := Update32(header.b0len,2,crc);
For temp2 := 0 to 15 do
crc := Update32(header.b1len[temp2],2,crc);
If (crc <> header.crc32) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
SeekF(f,SizeOf(header));
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,buf1,header.b0len,temp);
If NOT (temp = header.b0len) then
begin
CloseF(f);
EXIT;
end;
LZH_decompress(buf1,songdata,header.b0len);
BlockReadF(f,buf1,header.b1len[0],temp);
If NOT (temp = header.b1len[0]) then
begin
CloseF(f);
EXIT;
end;
LZH_decompress(buf1,pattdata^[0],header.b1len[0]);
For temp2 := 1 to 15 do
If ((header.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header.b1len[temp2],temp);
If NOT (temp = header.b1len[temp2]) then
begin
CloseF(f);
EXIT;
end;
If (temp2*8+8 <= max_patterns) then
begin
LZH_decompress(buf1,pattdata^[temp2],header.b1len[temp2]);
end
else limit_exceeded := TRUE;
end;
end;
speed := songdata.speed;
tempo := songdata.tempo;
CloseF(f);
songdata_title := NameOnly(songdata_source);
Case header.ffver of
1..4: load_flag := 1;
else load_flag := 2;
end;
end;
procedure a2t_file_loader;
type
tOLD_HEADER1 = Record
ident: array[1..15] of Char;
crc32: Longint;
ffver: Byte;
patts: Byte;
tempo: Byte;
speed: Byte;
b0len: Word;
b1len: Word;
b2len: Word;
b3len: Word;
b4len: Word;
b5len: Word;
end;
type
tOLD_HEADER2 = Record
ident: array[1..15] of Char;
crc32: Longint;
ffver: Byte;
patts: Byte;
tempo: Byte;
speed: Byte;
cflag: Byte;
b0len: Word;
b1len: Word;
b2len: Word;
b3len: Word;
b4len: Word;
b5len: Word;
b6len: Word;
b7len: Word;
b8len: Word;
b9len: Word;
end;
type
tOLD_HEADER3 = Record
ident: array[1..15] of Char;
crc32: Longint;
ffver: Byte;
patts: Byte;
tempo: Byte;
speed: Byte;
cflag: Byte;
patln: Word;
nmtrk: Byte;
mcspd: Word;
b0len: Longint;
b1len: Longint;
b2len: Longint;
b3len: Longint;
b4len: array[0..15] of Longint;
end;
type
tOLD_HEADER4 = Record
ident: array[1..15] of Char;
crc32: Longint;
ffver: Byte;
patts: Byte;
tempo: Byte;
speed: Byte;
cflag: Byte;
patln: Word;
nmtrk: Byte;
mcspd: Word;
is4op: Byte;
locks: array[1..20] of Byte;
b0len: Longint;
b1len: Longint;
b2len: Longint;
b3len: Longint;
b4len: array[0..15] of Longint;
end;
type
tHEADER = Record
ident: array[1..15] of Char;
crc32: Longint;
ffver: Byte;
patts: Byte;
tempo: Byte;
speed: Byte;
cflag: Byte;
patln: Word;
nmtrk: Byte;
mcspd: Word;
is4op: Byte;
locks: array[1..20] of Byte;
b0len: Longint;
b1len: Longint;
b2len: Longint;
b3len: Longint;
b4len: Longint;
b5len: array[0..15] of Longint;
end;
const
id = '_A2tiny_module_';
var
f: File;
header: tHEADER;
header2: tOLD_HEADER1;
header3: tOLD_HEADER2;
header4: tOLD_HEADER3;
header5: tOLD_HEADER4;
temp,temp2: Longint;
crc: Longint;
xlen: array[0..6] of Word;
begin
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and (header.ident = id)) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
If NOT (header.ffver in [1..FFVER_A2T]) then
begin
CloseF(f);
EXIT;
end;
init_old_songdata;
If (header.ffver in [1..4]) then
begin
FillChar(adsr_carrier,SizeOf(adsr_carrier),BYTE(FALSE));
ResetF(f);
BlockReadF(f,header2,SizeOf(header2),temp);
If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then
begin
CloseF(f);
EXIT;
end;
xlen[0] := header2.b3len;
xlen[1] := header2.b4len;
xlen[2] := header2.b5len;
crc := DWORD_NULL;
BlockReadF(f,buf1,header2.b0len,temp);
If NOT (temp = header2.b0len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header2.b1len,temp);
If NOT (temp = header2.b1len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header2.b2len,temp);
If NOT (temp = header2.b2len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
For temp2 := 0 to 2 do
If ((header2.patts-1) DIV 16 > temp2) then
begin
BlockReadF(f,buf1,xlen[temp2],temp);
If NOT (temp = xlen[temp2]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
end;
crc := Update32(header2.b0len,2,crc);
crc := Update32(header2.b1len,2,crc);
crc := Update32(header2.b2len,2,crc);
For temp2 := 0 to 2 do
crc := Update32(xlen[temp2],2,crc);
If (crc <> header2.crc32) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 9
else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9;
SeekF(f,SizeOf(header2));
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,buf1,header2.b0len,temp);
If NOT (temp = header2.b0len) then
begin
CloseF(f);
EXIT;
end;
old_songdata.tempo := header2.tempo;
old_songdata.speed := header2.speed;
Case header2.ffver of
4: Move(buf1,old_songdata.instr_data,header2.b0len);
3: LZSS_decompress(buf1,old_songdata.instr_data,header2.b0len);
2: LZW_decompress(buf1,old_songdata.instr_data);
1: SIXPACK_decompress(buf1,old_songdata.instr_data,header2.b0len);
end;
For temp := 1 to 250 do
old_songdata.instr_data[temp].panning := 0;
BlockReadF(f,buf1,header2.b1len,temp);
If NOT (temp = header2.b1len) then
begin
CloseF(f);
EXIT;
end;
Case header2.ffver of
4: Move(buf1,old_songdata.pattern_order,header2.b1len);
3: LZSS_decompress(buf1,old_songdata.pattern_order,header2.b1len);
2: LZW_decompress(buf1,old_songdata.pattern_order);
1: SIXPACK_decompress(buf1,old_songdata.pattern_order,header2.b1len);
end;
BlockReadF(f,buf1,header2.b2len,temp);
If NOT (temp = header2.b2len) then
begin
CloseF(f);
EXIT;
end;
FillChar(old_hash_buffer,SizeOf(old_hash_buffer),0);
Case header2.ffver of
4: Move(buf1,old_hash_buffer,header2.b2len);
3: LZSS_decompress(buf1,old_hash_buffer,header2.b2len);
2: LZW_decompress(buf1,old_hash_buffer);
1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b2len);
end;
import_old_a2m_patterns1(0,16);
For temp2 := 0 to 2 do
If ((header2.patts-1) DIV 16 > temp2) then
begin
BlockReadF(f,buf1,xlen[temp2],temp);
If NOT (temp = xlen[temp2]) then
begin
CloseF(f);
EXIT;
end;
FillChar(old_hash_buffer,SizeOf(old_hash_buffer),0);
Case header2.ffver of
4: Move(buf1,old_hash_buffer,header2.b3len);
3: LZSS_decompress(buf1,old_hash_buffer,header2.b3len);
2: LZW_decompress(buf1,old_hash_buffer);
1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b3len);
end;
import_old_a2m_patterns1(SUCC(temp2),16);
end;
replace_old_adsr(header2.patts);
import_old_songdata(Addr(old_songdata));
end;
If (header.ffver in [5..8]) then
begin
ResetF(f);
BlockReadF(f,header3,SizeOf(header3),temp);
If NOT ((temp = SizeOf(header3)) and (header3.ident = id)) then
begin
CloseF(f);
EXIT;
end;
xlen[0] := header3.b3len;
xlen[1] := header3.b4len;
xlen[2] := header3.b5len;
xlen[3] := header3.b6len;
xlen[4] := header3.b7len;
xlen[5] := header3.b8len;
xlen[6] := header3.b9len;
crc := DWORD_NULL;
BlockReadF(f,buf1,header3.b0len,temp);
If NOT (temp = header3.b0len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header3.b1len,temp);
If NOT (temp = header3.b1len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header3.b2len,temp);
If NOT (temp = header3.b2len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
For temp2 := 0 to 6 do
If ((header3.patts-1) DIV 8 > temp2) then
begin
BlockReadF(f,buf1,xlen[temp2],temp);
If NOT (temp = xlen[temp2]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
end;
crc := Update32(header3.b0len,2,crc);
crc := Update32(header3.b1len,2,crc);
crc := Update32(header3.b2len,2,crc);
For temp2 := 0 to 6 do
crc := Update32(xlen[temp2],2,crc);
If (crc <> header3.crc32) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 18
else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18;
SeekF(f,SizeOf(header3));
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,buf1,header3.b0len,temp);
If NOT (temp = header3.b0len) then
begin
CloseF(f);
EXIT;
end;
old_songdata.tempo := header3.tempo;
old_songdata.speed := header3.speed;
old_songdata.common_flag := header3.cflag;
Case header3.ffver of
8: Move(buf1,old_songdata.instr_data,header3.b0len);
7: LZSS_decompress(buf1,old_songdata.instr_data,header3.b0len);
6: LZW_decompress(buf1,old_songdata.instr_data);
5: SIXPACK_decompress(buf1,old_songdata.instr_data,header3.b0len);
end;
BlockReadF(f,buf1,header3.b1len,temp);
If NOT (temp = header3.b1len) then
begin
CloseF(f);
EXIT;
end;
Case header3.ffver of
8: Move(buf1,old_songdata.pattern_order,header3.b1len);
7: LZSS_decompress(buf1,old_songdata.pattern_order,header3.b1len);
6: LZW_decompress(buf1,old_songdata.pattern_order);
5: SIXPACK_decompress(buf1,old_songdata.pattern_order,header3.b1len);
end;
BlockReadF(f,buf1,header3.b2len,temp);
If NOT (temp = header3.b2len) then
begin
CloseF(f);
EXIT;
end;
FillChar(hash_buffer,SizeOf(hash_buffer),0);
Case header3.ffver of
8: Move(buf1,hash_buffer,header3.b2len);
7: LZSS_decompress(buf1,hash_buffer,header3.b2len);
6: LZW_decompress(buf1,hash_buffer);
5: SIXPACK_decompress(buf1,hash_buffer,header3.b2len);
end;
import_old_a2m_patterns2(0,8);
For temp2 := 0 to 6 do
If ((header3.patts-1) DIV 8 > temp2) then
begin
BlockReadF(f,buf1,xlen[temp2],temp);
If NOT (temp = xlen[temp2]) then
begin
CloseF(f);
EXIT;
end;
FillChar(hash_buffer,SizeOf(hash_buffer),0);
Case header3.ffver of
8: Move(buf1,hash_buffer,header3.b3len);
7: LZSS_decompress(buf1,hash_buffer,header3.b3len);
6: LZW_decompress(buf1,hash_buffer);
5: SIXPACK_decompress(buf1,hash_buffer,header3.b3len);
end;
import_old_a2m_patterns2(SUCC(temp2),8);
end;
import_old_songdata(Addr(old_songdata));
end;
If (header.ffver = 9) then
begin
ResetF(f);
BlockReadF(f,header4,SizeOf(header4),temp);
If NOT ((temp = SizeOf(header4)) and (header4.ident = id)) then
begin
CloseF(f);
EXIT;
end;
crc := DWORD_NULL;
BlockReadF(f,buf1,header4.b0len,temp);
If NOT (temp = header4.b0len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header4.b1len,temp);
If NOT (temp = header4.b1len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header4.b2len,temp);
If NOT (temp = header4.b2len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header4.b3len,temp);
If NOT (temp = header4.b3len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header4.b4len[0],temp);
If NOT (temp = header4.b4len[0]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
For temp2 := 1 to 15 do
If ((header4.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header4.b4len[temp2],temp);
If NOT (temp = header4.b4len[temp2]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
end;
crc := Update32(header4.b0len,2,crc);
crc := Update32(header4.b1len,2,crc);
crc := Update32(header4.b2len,2,crc);
crc := Update32(header4.b3len,2,crc);
For temp2 := 0 to 15 do
crc := Update32(header4.b4len[temp2],2,crc);
If (crc <> header4.crc32) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
SeekF(f,SizeOf(header4));
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,buf1,header4.b0len,temp);
If NOT (temp = header4.b0len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata.instr_data);
BlockReadF(f,buf1,header4.b1len,temp);
If NOT (temp = header4.b1len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata.instr_macros);
BlockReadF(f,buf1,header4.b2len,temp);
If NOT (temp = header4.b2len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata.macro_table);
BlockReadF(f,buf1,header4.b3len,temp);
If NOT (temp = header4.b3len) then
begin
CloseF(f);
EXIT;
end;
songdata.tempo := header4.tempo;
songdata.speed := header4.speed;
songdata.common_flag := header4.cflag;
songdata.patt_len := header4.patln;
songdata.nm_tracks := header4.nmtrk;
songdata.macro_speedup := header4.mcspd;
import_old_flags;
APACK_decompress(buf1,songdata.pattern_order);
BlockReadF(f,buf1,header4.b4len[0],temp);
If NOT (temp = header4.b4len[0]) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,pattdata^[0]);
For temp2 := 1 to 15 do
If ((header4.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header4.b4len[temp2],temp);
If NOT (temp = header4.b4len[temp2]) then
begin
CloseF(f);
EXIT;
end;
If (temp2*8+8 <= max_patterns) then
APACK_decompress(buf1,pattdata^[temp2])
else limit_exceeded := TRUE;
end;
end;
If (header.ffver = 10) then
begin
ResetF(f);
BlockReadF(f,header5,SizeOf(header5),temp);
If NOT ((temp = SizeOf(header5)) and (header5.ident = id)) then
begin
CloseF(f);
EXIT;
end;
crc := DWORD_NULL;
BlockReadF(f,buf1,header5.b0len,temp);
If NOT (temp = header5.b0len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header5.b1len,temp);
If NOT (temp = header5.b1len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header5.b2len,temp);
If NOT (temp = header5.b2len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header5.b3len,temp);
If NOT (temp = header5.b3len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header5.b4len[0],temp);
If NOT (temp = header5.b4len[0]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
For temp2 := 1 to 15 do
If ((header5.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header5.b4len[temp2],temp);
If NOT (temp = header5.b4len[temp2]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
end;
crc := Update32(header5.b0len,2,crc);
crc := Update32(header5.b1len,2,crc);
crc := Update32(header5.b2len,2,crc);
crc := Update32(header5.b3len,2,crc);
For temp2 := 0 to 15 do
crc := Update32(header5.b4len[temp2],2,crc);
If (crc <> header5.crc32) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
SeekF(f,SizeOf(header5));
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,buf1,header5.b0len,temp);
If NOT (temp = header5.b0len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata.instr_data);
BlockReadF(f,buf1,header5.b1len,temp);
If NOT (temp = header5.b1len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata.instr_macros);
BlockReadF(f,buf1,header5.b2len,temp);
If NOT (temp = header5.b2len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata.macro_table);
BlockReadF(f,buf1,header5.b3len,temp);
If NOT (temp = header5.b3len) then
begin
CloseF(f);
EXIT;
end;
songdata.tempo := header5.tempo;
songdata.speed := header5.speed;
songdata.common_flag := header5.cflag;
songdata.patt_len := header5.patln;
songdata.nm_tracks := header5.nmtrk;
songdata.macro_speedup := header5.mcspd;
songdata.flag_4op := header5.is4op;
Move(header5.locks,songdata.lock_flags,SizeOf(songdata.lock_flags));
APACK_decompress(buf1,songdata.pattern_order);
BlockReadF(f,buf1,header5.b4len[0],temp);
If NOT (temp = header5.b4len[0]) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,pattdata^[0]);
For temp2 := 1 to 15 do
If ((header5.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header5.b4len[temp2],temp);
If NOT (temp = header5.b4len[temp2]) then
begin
CloseF(f);
EXIT;
end;
If (temp2*8+8 <= max_patterns) then
APACK_decompress(buf1,pattdata^[temp2])
else limit_exceeded := TRUE;
end;
end;
If (header.ffver = 11) then
begin
crc := DWORD_NULL;
BlockReadF(f,buf1,header.b0len,temp);
If NOT (temp = header.b0len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b1len,temp);
If NOT (temp = header.b1len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b2len,temp);
If NOT (temp = header.b2len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b3len,temp);
If NOT (temp = header.b3len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b4len,temp);
If NOT (temp = header.b4len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b5len[0],temp);
If NOT (temp = header.b5len[0]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
For temp2 := 1 to 15 do
If ((header.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header.b5len[temp2],temp);
If NOT (temp = header.b5len[temp2]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
end;
crc := Update32(header.b0len,2,crc);
crc := Update32(header.b1len,2,crc);
crc := Update32(header.b2len,2,crc);
crc := Update32(header.b3len,2,crc);
crc := Update32(header.b4len,2,crc);
For temp2 := 0 to 15 do
crc := Update32(header.b5len[temp2],2,crc);
If (crc <> header.crc32) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
SeekF(f,SizeOf(header));
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,buf1,header.b0len,temp);
If NOT (temp = header.b0len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata.instr_data);
BlockReadF(f,buf1,header.b1len,temp);
If NOT (temp = header.b1len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata.instr_macros);
BlockReadF(f,buf1,header.b2len,temp);
If NOT (temp = header.b2len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata.macro_table);
BlockReadF(f,buf1,header.b3len,temp);
If NOT (temp = header.b3len) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,songdata.dis_fmreg_col);
BlockReadF(f,buf1,header.b4len,temp);
If NOT (temp = header.b4len) then
begin
CloseF(f);
EXIT;
end;
songdata.tempo := header.tempo;
songdata.speed := header.speed;
songdata.common_flag := header.cflag;
songdata.patt_len := header.patln;
songdata.nm_tracks := header.nmtrk;
songdata.macro_speedup := header.mcspd;
songdata.flag_4op := header.is4op;
Move(header.locks,songdata.lock_flags,SizeOf(songdata.lock_flags));
APACK_decompress(buf1,songdata.pattern_order);
BlockReadF(f,buf1,header.b5len[0],temp);
If NOT (temp = header.b5len[0]) then
begin
CloseF(f);
EXIT;
end;
APACK_decompress(buf1,pattdata^[0]);
For temp2 := 1 to 15 do
If ((header.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header.b5len[temp2],temp);
If NOT (temp = header.b5len[temp2]) then
begin
CloseF(f);
EXIT;
end;
If (temp2*8+8 <= max_patterns) then
APACK_decompress(buf1,pattdata^[temp2])
else limit_exceeded := TRUE;
end;
end;
If (header.ffver in [12,13,FFVER_A2T]) then
begin
crc := DWORD_NULL;
BlockReadF(f,buf1,header.b0len,temp);
If NOT (temp = header.b0len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b1len,temp);
If NOT (temp = header.b1len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b2len,temp);
If NOT (temp = header.b2len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b3len,temp);
If NOT (temp = header.b3len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b4len,temp);
If NOT (temp = header.b4len) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
BlockReadF(f,buf1,header.b5len[0],temp);
If NOT (temp = header.b5len[0]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
For temp2 := 1 to 15 do
If ((header.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header.b5len[temp2],temp);
If NOT (temp = header.b5len[temp2]) then
begin
CloseF(f);
EXIT;
end;
crc := Update32(buf1,temp,crc);
end;
crc := Update32(header.b0len,2,crc);
crc := Update32(header.b1len,2,crc);
crc := Update32(header.b2len,2,crc);
crc := Update32(header.b3len,2,crc);
crc := Update32(header.b4len,2,crc);
For temp2 := 0 to 15 do
crc := Update32(header.b5len[temp2],2,crc);
If (crc <> header.crc32) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
SeekF(f,SizeOf(header));
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,buf1,header.b0len,temp);
If NOT (temp = header.b0len) then
begin
CloseF(f);
EXIT;
end;
temp := LZH_decompress(buf1,buf2,header.b0len);
temp2 := 0;
If (header.ffver = FFVER_A2T) then
begin
Move(buf2[temp2],songdata.bpm_data,SizeOf(songdata.bpm_data));
Inc(temp2,SizeOf(songdata.bpm_data));
end;
Move(buf2[temp2],songdata.ins_4op_flags,SizeOf(songdata.ins_4op_flags));
Inc(temp2,SizeOf(songdata.ins_4op_flags));
Move(buf2[temp2],songdata.reserved_data,SizeOf(songdata.reserved_data));
Inc(temp2,SizeOf(songdata.reserved_data));
Move(buf2[temp2],songdata.instr_data,temp-temp2);
If (header.b1len <> 0) then
begin
BlockReadF(f,buf1,header.b1len,temp);
If NOT (temp = header.b1len) then
begin
CloseF(f);
EXIT;
end;
LZH_decompress(buf1,songdata.instr_macros,header.b1len);
end;
If (header.b2len <> 0) then
begin
BlockReadF(f,buf1,header.b2len,temp);
If NOT (temp = header.b2len) then
begin
CloseF(f);
EXIT;
end;
LZH_decompress(buf1,songdata.macro_table,header.b2len);
end;
If (header.b3len <> 0) then
begin
BlockReadF(f,buf1,header.b3len,temp);
If NOT (temp = header.b3len) then
begin
CloseF(f);
EXIT;
end;
LZH_decompress(buf1,songdata.dis_fmreg_col,header.b3len);
end;
BlockReadF(f,buf1,header.b4len,temp);
If NOT (temp = header.b4len) then
begin
CloseF(f);
EXIT;
end;
songdata.tempo := header.tempo;
songdata.speed := header.speed;
songdata.common_flag := header.cflag;
songdata.patt_len := header.patln;
songdata.nm_tracks := header.nmtrk;
songdata.macro_speedup := header.mcspd;
songdata.flag_4op := header.is4op;
Move(header.locks,songdata.lock_flags,SizeOf(songdata.lock_flags));
LZH_decompress(buf1,songdata.pattern_order,header.b4len);
BlockReadF(f,buf1,header.b5len[0],temp);
If NOT (temp = header.b5len[0]) then
begin
CloseF(f);
EXIT;
end;
LZH_decompress(buf1,pattdata^[0],header.b5len[0]);
For temp2 := 1 to 15 do
If ((header.patts-1) DIV 8 > PRED(temp2)) then
begin
BlockReadF(f,buf1,header.b5len[temp2],temp);
If NOT (temp = header.b5len[temp2]) then
begin
CloseF(f);
EXIT;
end;
If (temp2*8+8 <= max_patterns) then
begin
LZH_decompress(buf1,pattdata^[temp2],header.b5len[temp2]);
end
else limit_exceeded := TRUE;
end;
end;
speed := songdata.speed;
tempo := songdata.tempo;
CloseF(f);
songdata_title := NameOnly(songdata_source);
Case header.ffver of
1..4: load_flag := 3;
else load_flag := 4;
end;
end;
function dec2hex(dec: Byte): Byte;
begin dec2hex := (dec DIV 10)*16 +(dec MOD 10); end;
function truncate_string(str: String): String;
begin
While (Length(str) > 0) and (str[Length(str)] in [#0,#32,#255]) do
Delete(str,Length(str),1);
truncate_string := str;
end;
procedure amd_file_loader;
type
tPATDAT = array[0..$24] of
array[0..$3f] of array[1..9] of
array[0..2] of Byte;
type
tINSDAT = Record
iName: array[1..23] of Char; { Instrument name }
iData: array[0..10] of Byte; { Instrument data }
end;
type
tHEADER = Record
sname: array[1..24] of Char; { Name of song [ASCIIZ] }
aname: array[1..24] of Char; { Name of author [ASCIIZ] }
instr: array[0..25] of tINSDAT; { 26 instruments }
snlen: Byte; { Song length }
nopat: Byte; { Number of patterns -1 }
order: array[0..$7f] of Byte; { Pattern table }
ident: array[1..9] of Char; { ID }
versn: Byte; { Version 10h=normal module }
{ 11h=packed module }
end;
const
id_amd = ' 0) then
chunk.instr_def := (byte2 SHR 4)+(byte1 AND 1) SHL 4;
If (byte1 SHR 4 in [1..12]) and ((byte1 SHR 1) AND 7 in [0..7]) then
chunk.note := 12*((byte1 SHR 1) AND 7)+(byte1 SHR 4);
param := byte3 AND $7f;
Case byte2 AND $0f of
{ ARPEGGIO }
$00: begin
chunk.effect_def := ef_Arpeggio;
chunk.effect := dec2hex(param);
end;
{ SLIDE FREQUENCY UP }
$01: begin
chunk.effect_def := ef_FSlideUp;
chunk.effect := param;
end;
{ SLIDE FREQUENCY DOWN }
$02: begin
chunk.effect_def := ef_FSlideDown;
chunk.effect := param;
end;
{ SET CARRIER/MODULATOR INTENSITY }
$03: If (param DIV 10 in [1..9]) then
begin
chunk.effect_def := ef_SetCarrierVol;
chunk.effect := (param DIV 10)*7;
end
else If (param MOD 10 in [1..9]) then
begin
chunk.effect_def := ef_SetModulatorVol;
chunk.effect := (param MOD 10)*7;
end;
{ SET THE VOLUME }
$04: begin
chunk.effect_def := ef_SetInsVolume;
If (param < 64) then chunk.effect := param
else chunk.effect := 63;
end;
{ JUMP INTO PATTERN }
$05: begin
chunk.effect_def := ef_PositionJump;
If (param < 100) then chunk.effect := param
else chunk.effect := 99;
end;
{ PATTERNBREAK }
$06: begin
chunk.effect_def := ef_PatternBreak;
If (param < 64) then chunk.effect := param
else chunk.effect := 63;
end;
{ SET SONGSPEED }
$07: If (param < 99) then
If (param in [1..31]) then
begin
chunk.effect_def := ef_SetSpeed;
chunk.effect := param;
end
else begin
chunk.effect_def := ef_SetTempo;
If (param = 0) then chunk.effect := 18
else chunk.effect := param;
end;
{ TONEPORTAMENTO }
$08: begin
chunk.effect_def := ef_TonePortamento;
chunk.effect := param;
end;
{ EXTENDED COMMAND }
$09: If (param < 60) then
Case param DIV 10 of
{ DEFINE CELL-TREMOLO }
0: If (param MOD 10 < 2) then
begin
chunk.effect_def := ef_Extended;
chunk.effect := dec2hex(param);
end;
{ DEFINE CELL-VIBRATO }
1: If (param MOD 10 < 2) then
begin
chunk.effect_def := ef_Extended;
chunk.effect := $10+dec2hex(param);
end;
{ INCREASE VOLUME FAST }
2: begin
chunk.effect_def := ef_VolSlide;
chunk.effect := (param MOD 10)*16;
end;
{ DECREASE VOLUME FAST }
3: begin
chunk.effect_def := ef_VolSlide;
chunk.effect := param MOD 10;
end;
{ INCREASE VOLUME FINE }
4: begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_VolSlideUpXF*16+(param MOD 10);
end;
{ DECREASE VOLUME FINE }
5: begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_VolSlideDnXF*16+(param MOD 10);
end;
end;
end;
// specific corrections for Amusic event
If (chunk.note = 0) then chunk.instr_def := 0;
put_chunk(pattern,line,channel,chunk);
end;
procedure import_amd_packed_patterns(var data; patterns: Byte);
var
temp,temp2,temp3,temp4,temp5: Word;
count: Byte;
var
tracks: Word;
track_order: array[0..$3f] of array[1..9] of Word;
track: array[0..$3f] of tCHUNK;
begin
temp := (patterns+1)*9*SizeOf(WORD);
Move(data,track_order,temp);
tracks := pBYTE(@data)[temp]+(pBYTE(@data)[temp+1]) SHL 8;
Inc(temp,2);
temp3 := 0;
temp4 := 0;
count := 0;
Repeat
If (count = 0) then
begin
If (temp3 = 0) then
begin
temp2 := pBYTE(@data)[temp]+(pBYTE(@data)[temp+1]) SHL 8;
Inc(temp,2);
end;
If (pBYTE(@data)[temp] OR $80 <> pBYTE(@data)[temp]) then
begin
If (temp2 DIV 9 <= $3f) and (temp2 MOD 9 < 9) then
import_amd_event(temp2 DIV 9,temp3,temp2 MOD 9 +1,
pBYTE(@data)[temp+2],
pBYTE(@data)[temp+1],
pBYTE(@data)[temp+0]);
Inc(temp,3);
end
else
begin
count := (pBYTE(@data)[temp] AND $7f)-1;
Inc(temp);
end;
end
else Dec(count);
Inc(temp3);
If (temp3 > $3f) then
begin
temp3 := 0;
count := 0;
Inc(temp4);
end;
until NOT (temp4 < tracks);
For temp := 0 to patterns do
For temp2 := 1 to 9 do
begin
temp3 := track_order[temp][temp2];
temp4 := temp3 DIV 9;
If (temp3 < 64*9) then
begin
For temp5 := 0 to $3f do
get_chunk(temp4,temp5,temp3 MOD 9 +1,track[temp5]);
For temp5 := 0 to $3f do
put_chunk( temp,temp5,temp2,track[temp5]);
end;
end;
end;
function get_byte(var pos: Longint): Byte;
begin
If (pos = SizeOf(buf1)) then
begin
Move(buf3,buf1,SizeOf(buf3));
pos := 0;
end;
get_byte := buf1[pos];
Inc(pos);
end;
begin
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and
((header.ident = id_amd) or (header.ident = id_xms))) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
If NOT (header.versn in [$10,$11]) then
begin
CloseF(f);
EXIT;
end;
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,buf1,SizeOf(buf1),temp);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
tmp2 := WORD_NULL;
If (temp = SizeOf(buf1)) then
begin
FillChar(buf3,SizeOf(buf3),0);
BlockReadF(f,buf3,SizeOf(buf3),tmp2);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
end;
init_songdata;
load_flag := 0;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 9
else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9;
tempo := 50;
speed := 6;
songdata.tempo := tempo;
songdata.speed := speed;
For temp2 := 0 to header.snlen-1 do
If (temp2 < 128) and (header.order[temp2] in [0..header.nopat]) then
songdata.pattern_order[temp2] := header.order[temp2];
For temp2 := 0 to 25 do
begin
import_amd_instrument(temp2+1,header.instr[temp2].iData);
songdata.instr_names[temp2+1] :=
Copy(songdata.instr_names[temp2+1],1,9)+
truncate_string(header.instr[temp2].iName);
end;
temp := 0;
If (header.versn = $10) then
For temp2 := 0 to header.nopat do
For temp3 := 0 to $3f do
For temp4 := 1 to 9 do
begin
byte3 := get_byte(temp);
byte2 := get_byte(temp);
byte1 := get_byte(temp);
import_amd_event(temp2,temp3,temp4,byte1,byte2,byte3);
end
else
import_amd_packed_patterns(buf1,header.nopat);
songdata.common_flag := songdata.common_flag OR $80;
songdata.songname := CutStr(asciiz_string(header.sname));
songdata.composer := CutStr(asciiz_string(header.aname));
import_old_flags;
CloseF(f);
songdata_title := NameOnly(songdata_source);
If (header.ident = id_amd) then load_flag := 5
else load_flag := 6;
end;
procedure import_hsc_instrument(inst: Byte; var data); forward;
procedure import_cff_event(patt,line,chan,byte0,byte1,byte2: Byte);
var
chunk: tCHUNK;
temp1,temp2,temp3,temp4: Byte;
begin
FillChar(chunk,SizeOf(chunk),0);
temp1 := byte2;
temp2 := temp1 DIV 16;
temp3 := temp1 MOD 16;
Case CHAR(byte1) of
{ SET SPEED }
'A': If (temp1 > 0) then
begin
chunk.effect_def := ef_SetSpeed;
chunk.effect := temp1;
end;
{ SET CARRIER WAVEFORM }
'B': If (temp1 < 4) then
begin
chunk.effect_def := ef_SetWaveform;
chunk.effect := temp1*16;
end;
{ SET MODULATOR VOLUME }
'C': begin
chunk.effect_def := ef_SetModulatorVol;
If (temp1 < 64) then chunk.effect := 63-temp1
else chunk.effect := 0;
end;
{ VOLUME SLIDE UP/DOWN }
'D': begin
chunk.effect_def := ef_VolSlide;
chunk.effect := temp1;
end;
{ SLIDE DOWN }
'E': If (temp1 <> 0) then
begin
chunk.effect_def := ef_FSlideDown;
chunk.effect := temp1;
end;
{ SLIDE UP }
'F': If (temp1 <> 0) then
begin
chunk.effect_def := ef_FSlideUp;
chunk.effect := temp1;
end;
{ SET CARRIER VOLUME }
'G': begin
chunk.effect_def := ef_SetCarrierVol;
If (temp1 < 64) then chunk.effect := 63-temp1
else chunk.effect := 0;
end;
{ SET TEMPO }
'H': If (temp1 > 0) then
begin
chunk.effect_def := ef_SetTempo;
If NOT (temp1 > 21) then temp1 := 125;
temp4 := 1412926 DIV LONGINT(temp1 SHR 1);
chunk.effect := 1;
While (1193180 DIV chunk.effect > temp4) and
(chunk.effect < 255) do
Inc(chunk.effect);
end;
{ SET INSTRUMENT }
'I': If (temp1 < 47) then
begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol;
chunk.instr_def := temp1+1;
end;
{ ARPEGGIO }
'J': begin
chunk.effect_def := ef_Arpeggio;
chunk.effect := temp1;
end;
{ JUMP TO ORDER }
'K': If (temp1 < 128) then
begin
chunk.effect_def := ef_PositionJump;
chunk.effect := temp1;
end;
{ JUMP TO NEXT PATTERN IN ORDER }
'L': chunk.effect_def := ef_PatternBreak;
{ SET TREMOLO HIGHER / SET VIBRATO DEEPER }
'M': begin
chunk.effect_def := ef_Extended;
If (temp2 = 1) and (temp3 = 0) then chunk.effect := dec2hex(01);
If (temp2 = 0) and (temp3 = 1) then chunk.effect := dec2hex(10);
If (temp2 = 1) and (temp3 = 1) then chunk.effect := dec2hex(11);
end;
end;
Case byte0 of
{ REGULAR NOTE }
1..12*8+1: begin
If NOT fix_c_note_bug then chunk.note := byte0
else begin
chunk.note := byte0+1;
If (chunk.note > 12*8+1) then
chunk.note := 12*8+1;
end;
end;
{ PAUSE }
$6d: chunk.note := BYTE_NULL;
end;
put_chunk(patt,line,chan,chunk);
end;
procedure import_cff_patterns(var data; patterns: Byte);
type
tPATDAT = array[0..$24] of
array[0..$3f] of array[1..9] of
array[0..2] of Byte;
var
voice: array[1..9] of Byte;
arpgg: array[1..9] of Byte;
chunk: tCHUNK;
temp,temp2,temp3,temp4: Byte;
order,patt: Byte;
patt_break: Byte;
patts: String;
function _empty_event(var data): Boolean;
begin
_empty_event := (pBYTE(@data)[0] = 0) and
(pBYTE(@data)[1] = 0) and
(pBYTE(@data)[2] = 0);
end;
begin
patts := '';
FillChar(arpgg,SizeOf(arpgg),0);
If NOT accurate_conv then
For temp := 1 to 9 do voice[temp] := temp
else For temp := 1 to 9 do voice[temp] := 0;
For temp := 0 to $24 do
For temp2 := 0 to $3f do
For temp3 := 1 to 9 do
If NOT _empty_event(tPATDAT(data)[temp][temp2][temp3]) then
import_cff_event(temp,temp2,temp3,tPATDAT(data)[temp][temp2][temp3][0],
tPATDAT(data)[temp][temp2][temp3][1],
tPATDAT(data)[temp][temp2][temp3][2]);
order := 0;
patt := BYTE_NULL;
Repeat
If (songdata.pattern_order[order] > $24) then Inc(order)
else
begin
patt := songdata.pattern_order[order];
patt_break := BYTE_NULL;
For temp2 := 0 to $3f do
For temp3 := 1 to 9 do
begin
get_chunk(patt,temp2,temp3,chunk);
temp4 := tPATDAT(data)[patt][temp2][temp3][2];
Case CHAR(tPATDAT(data)[patt][temp2][temp3][1]) of
{ SET MODULATOR VOLUME }
'C': If (chunk.instr_def = 0) and NOT accurate_conv then
chunk.instr_def := voice[temp3]
else If (chunk.instr_def = 0) and
(voice[temp3] = 0) then chunk.instr_def := temp3;
{ SET CARRIER VOLUME }
'G': If (chunk.instr_def = 0) and NOT accurate_conv then
chunk.instr_def := voice[temp3]
else If (chunk.instr_def = 0) and
(voice[temp3] = 0) then chunk.instr_def := temp3;
{ SET INSTRUMENT }
'I': If (temp4 < 47) then
If (temp2 <> patt_break) then
begin
voice[temp3] := temp4+1;
If NOT accurate_conv then
chunk.instr_def := voice[temp3];
end;
{ ARPEGGIO }
'J': begin
chunk.effect_def := ef_Arpeggio;
If (temp4 <> 0) then
begin
chunk.effect := temp4;
arpgg[temp3] := temp4;
end
else chunk.effect := arpgg[temp3];
end;
{ JUMP TO ORDER }
'K': If (temp4 < 128) then
patt_break := temp2+1;
{ JUMP TO NEXT PATTERN IN ORDER }
'L': patt_break := temp2+1;
end;
Case tPATDAT(data)[patt][temp2][temp3][0] of
{ REGULAR NOTE }
1..12*8+1: begin
If accurate_conv then
If (voice[temp3] = 0) then
begin
voice[temp3] := temp3;
chunk.instr_def := voice[temp3];
end;
If NOT accurate_conv then
chunk.instr_def := voice[temp3];
end;
end;
If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then
put_chunk(patt,temp2,temp3,chunk);
end;
Inc(order);
patts := patts+CHR(patt);
end;
until (patt >= patterns) or (order > $40);
end;
procedure cff_file_loader;
type
tHEADER = Record
ident: array[1..16] of Char; { Identification }
versn: Byte; { Format version }
fsize: Word; { Filesize -32 }
cflag: Byte; { Flag 1=compressed data }
resrv: array[0..11] of Byte; { Reserved }
end;
type
tINSDAT = Record
iData: array[0..11] of Byte; { Instrument data }
iName: array[1..20] of Char; { Instrument name }
end;
type
tHEADR2 = Record
instr: array[0..46] of tINSDAT; { 47 instruments }
nopat: Byte; { Number of patterns }
ascii: array[1..31] of Char; { ASCII blab }
writr: array[1..20] of Char; { Song writer }
sname: array[1..20] of Char; { Song name }
order: array[0..64] of Byte; { Pattern order }
end;
const
_PRE_ASCII_BLAB_SIZE = $5e1; // SizeOf(tHEADR2.instr)+SizeOf(tHEADR2.nopat)
const
id = ''+#26+CHR($de)+CHR($e0);
ascii_blab = 'CUD-FM-File - SEND A POSTCARD -';
var
f: File;
header: tHEADER;
headr2: tHEADR2;
temp,temp2: Longint;
offs,out_size: Longint;
function LZTYR_decompress(var input,output): Longint;
type
tSTRING = array[0..255] of Byte;
var
input_idx: Longint;
the_string,
temp_string: tSTRING;
old_code_length: Byte;
repeat_length: Byte;
repeat_counter: Longint;
output_length: Longint;
code_length: Byte;
bits_buffer: Longint;
bits_left: Word;
old_code: Longint;
new_code: Longint;
idx: Word;
_cff_heap_length: Word;
_cff_dictionary_length: Word;
_cff_dictionary: array[0..32767] of Pointer;
function get_code: Longint;
var
code: Longint;
begin
While (bits_left < code_length) do
begin
bits_buffer := bits_buffer OR (pBYTE(@input)[input_idx] SHL
bits_left);
Inc(input_idx);
Inc(bits_left,8);
end;
code := bits_buffer AND ((1 SHL code_length)-1);
bits_buffer := bits_buffer SHR code_length;
Dec(bits_left,code_length);
get_code := code;
end;
procedure translate_code(code: Longint; var str: tSTRING);
var
translated_string: tSTRING;
begin
If (code >= $104) then
Move(_cff_dictionary[code-$104]^,translated_string,
BYTE(_cff_dictionary[code-$104]^)+1)
else begin
translated_string[0] := 1;
translated_string[1] := (code-4) AND $0ff;
end;
Move(translated_string,str,256);
end;
procedure startup;
var
idx: Longint;
begin
old_code := get_code;
translate_code(old_code,the_string);
If (the_string[0] > 0) then
For idx := 0 to the_string[0]-1 do
begin
pBYTE(@output)[output_length] := the_string[idx+1];
Inc(output_length);
end;
end;
procedure cleanup;
begin
code_length := 9;
bits_buffer := 0;
bits_left := 0;
_cff_heap_length := 0;
_cff_dictionary_length := 0;
end;
procedure expand__cff_dictionary(str: tSTRING);
begin
If (str[0] >= $0f0) then EXIT;
Move(str,buf3[_cff_heap_length],str[0]+1);
_cff_dictionary[_cff_dictionary_length] := Addr(buf3[_cff_heap_length]);
Inc(_cff_dictionary_length);
Inc(_cff_heap_length,str[0]+1);
end;
begin
input_idx := 0;
output_length := 0;
cleanup;
startup;
Repeat
new_code := get_code;
// $00: end of data
If (new_code = 0) then BREAK;
// $01: end of block
If (new_code = 1) then
begin
cleanup;
startup;
CONTINUE;
end;
// $02: expand code length
If (new_code = 2) then
begin
Inc(code_length);
CONTINUE;
end;
// $03: RLE
If (new_code = 3) then
begin
old_code_length := code_length;
code_length := 2;
repeat_length := get_code+1;
code_length := 4 SHL get_code;
repeat_counter := get_code;
For idx := 0 to PRED(repeat_counter*repeat_length) do
begin
pBYTE(@output)[output_length] :=
pBYTE(@output)[output_length-repeat_length];
Inc(output_length);
end;
code_length := old_code_length;
startup;
CONTINUE;
end;
If (new_code >= $104+_cff_dictionary_length) then
begin
Inc(the_string[0]);
the_string[the_string[0]] := the_string[1];
end
else begin
translate_code(new_code,temp_string);
Inc(the_string[0]);
the_string[the_string[0]] := temp_string[1];
end;
expand__cff_dictionary(the_string);
translate_code(new_code,the_string);
For idx := 0 to PRED(the_string[0]) do
begin
pBYTE(@output)[output_length] := the_string[idx+1];
Inc(output_length);
end;
old_code := new_code;
until FALSE;
LZTYR_decompress := output_length;
end;
begin
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and (header.ident = id)) or
(FileSize(f) > SizeOf(buf1)) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
If (header.cflag = 1) then
begin
FillChar(buf1,SizeOf(buf1),0);
ResetF(f);
BlockReadF(f,buf1,SizeOf(buf1),temp);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
CloseF(f);
temp := LZTYR_decompress(buf1[$30],hash_buffer);
out_size := temp;
offs := SensitiveScan(hash_buffer,0,temp,ascii_blab);
If (offs <> _PRE_ASCII_BLAB_SIZE) then
begin
EXIT;
end;
FillChar(buf1,SizeOf(buf1),0);
Move(hash_buffer,headr2,SizeOf(headr2));
Move(pBYTE(@hash_buffer)[SizeOf(headr2)],buf1,out_size-SizeOf(headr2));
end
else
begin
BlockReadF(f,headr2,SizeOf(headr2),temp);
If NOT ((temp = SizeOf(headr2)) and (headr2.ascii = ascii_blab)) then
begin
CloseF(f);
EXIT;
end;
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,buf1,SizeOf(buf1),temp);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
CloseF(f);
end;
init_songdata;
load_flag := 0;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 9
else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9;
tempo := 51;
speed := 6;
songdata.tempo := tempo;
songdata.speed := speed;
For temp2 := 0 to 64 do
If (headr2.order[temp2] in [0..headr2.nopat]) then
songdata.pattern_order[temp2] := headr2.order[temp2];
For temp2 := 0 to 46 do
begin
import_hsc_instrument(temp2+1,headr2.instr[temp2].iData);
songdata.instr_data[temp2+1].fine_tune := 0;
songdata.instr_names[temp2+1] :=
Copy(songdata.instr_names[temp2+1],1,9)+
truncate_string(headr2.instr[temp2].iName);
end;
songdata.common_flag := songdata.common_flag OR 2;
songdata.songname := CutStr(headr2.sname);
songdata.composer := CutStr(headr2.writr);
import_old_flags;
import_cff_patterns(buf1,headr2.nopat);
songdata_title := NameOnly(songdata_source);
load_flag := 7;
end;
procedure import_standard_instrument(inst: Byte; var data);
begin
With songdata.instr_data[inst] do
begin
fm_data.AM_VIB_EG_modulator := pBYTE(@data)[0];
fm_data.AM_VIB_EG_carrier := pBYTE(@data)[1];
fm_data.KSL_VOLUM_modulator := pBYTE(@data)[2];
fm_data.KSL_VOLUM_carrier := pBYTE(@data)[3];
fm_data.ATTCK_DEC_modulator := pBYTE(@data)[4];
fm_data.ATTCK_DEC_carrier := pBYTE(@data)[5];
fm_data.SUSTN_REL_modulator := pBYTE(@data)[6];
fm_data.SUSTN_REL_carrier := pBYTE(@data)[7];
fm_data.WAVEFORM_modulator := pBYTE(@data)[8] AND 3;
fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 3;
fm_data.FEEDBACK_FM := pBYTE(@data)[10] AND $0f;
end;
songdata.instr_data[inst].panning := 0;
songdata.instr_data[inst].fine_tune := 0;
end;
procedure dfm_file_loader;
const
id = 'DFM'+#26;
var
header: Record
ident: array[1..4] of Char;
versn: Word;
sname: String[32];
tempo: Byte;
instn: array[1..32] of String[11];
instd: array[1..32] of tFM_INST_DATA;
order: array[1..128] of Byte;
patts: Byte;
end;
var
f: File;
temp,temp2,temp3: Longint;
pattern,line,channel,byte1,byte2: Byte;
procedure import_dfm_event(patt,line,chan,byte1,byte2: Byte);
var
chunk: tCHUNK;
begin
FillChar(chunk,SizeOf(chunk),0);
If (byte1 AND $0f in [1..12,15]) and ((byte1 SHR 4) AND 7 in [0..7]) then
If (byte1 AND $0f <> 15) then
chunk.note := SUCC(PRED(byte1 AND $0f)+((byte1 SHR 4) AND 7)*12)
else chunk.note := BYTE_NULL;
Case byte2 SHR 5 of
{ INSTRUMENT CHANGE }
1: chunk.instr_def := SUCC(byte2 AND $1f);
{ SET INSTRUMENT VOLUME }
2: begin
chunk.effect_def := ef_SetInsVolume;
chunk.effect := (byte2 AND $1f)*2;
end;
{ TEMPO CHANGE }
3: begin
chunk.effect_def := ef_SetSpeed;
chunk.effect := SUCC(byte2 AND $1f);
end;
{ SLIDE UP }
4: begin
chunk.effect_def := ef_FSlideUpFine;
chunk.effect := byte2 AND $1f;
end;
{ SLIDE DOWN }
5: begin
chunk.effect_def := ef_FSlideDownFine;
chunk.effect := byte2 AND $1f;
end;
{ END OF PATTERN }
7: chunk.effect_def := ef_PatternBreak;
end;
put_chunk(patt,line,chan,chunk);
end;
procedure process_dfm_patterns(patterns: Byte);
var
chunk: tCHUNK;
temp2,temp3: Byte;
order,patt: Byte;
patts: String;
instr_cache: array[1..18] of Byte;
begin
patts := '';
FillChar(instr_cache,SizeOf(instr_cache),0);
order := 0;
patt := BYTE_NULL;
Repeat
If (songdata.pattern_order[order] >= $80) then Inc(order)
else
begin
patt := songdata.pattern_order[order];
For temp2 := 0 to $3f do
For temp3 := 1 to 9 do
begin
get_chunk(patt,temp2,temp3,chunk);
If (chunk.instr_def <> 0) then
begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol;
instr_cache[temp3] := chunk.instr_def;
If NOT (chunk.note in [1..12*8+1]) and
NOT accurate_conv then
chunk.instr_def := 0;
end
else If (chunk.note in [1..12*8+1]) and
(chunk.instr_def = 0) and NOT accurate_conv then
chunk.instr_def := instr_cache[temp3];
If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then
put_chunk(patt,temp2,temp3,chunk);
end;
Inc(order);
patts := patts+CHR(patt);
end;
until (patt >= patterns) or (order > $7f);
end;
begin
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and (header.ident = id)) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,buf1,SizeOf(buf1),temp);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 9
else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9;
tempo := 135;
speed := SUCC(header.tempo);
songdata.songname := CutStr(header.sname);
songdata.tempo := tempo;
songdata.speed := speed;
songdata.common_flag := songdata.common_flag OR 1;
songdata.common_flag := songdata.common_flag OR 2;
songdata.common_flag := songdata.common_flag OR 8;
songdata.common_flag := songdata.common_flag OR $10;
import_old_flags;
For temp2 := 1 to 128 do
If (header.order[temp2] in [0..$7f]) then
songdata.pattern_order[temp2-1] := header.order[temp2]
else If (header.order[temp2] = $80) then BREAK
else songdata.pattern_order[temp2-1] := $80+temp2;
For temp2 := 1 to 32 do
begin
songdata.instr_names[temp2] :=
Copy(songdata.instr_names[temp2],1,9)+
CutStr(header.instn[temp2]);
While (BYTE(songdata.instr_names[temp2][
Length(songdata.instr_names[temp2])]) < 32) and
(Length(songdata.instr_names[temp2]) <> 0) do
Delete(songdata.instr_names[temp2],
Length(songdata.instr_names[temp2]),1);
import_standard_instrument(temp2,header.instd[temp2]);
end;
temp2 := 0;
temp3 := 0;
Repeat
pattern := buf1[temp2];
If (pattern > 127) then
begin
CloseF(f);
EXIT;
end;
Inc(temp2);
Inc(temp3);
For line := 0 to $3f do
For channel := 1 to 9 do
begin
byte1 := buf1[temp2];
If (temp2 >= temp) then
begin
CloseF(f);
EXIT;
end
else Inc(temp2);
If (byte1 OR $80 <> byte1) then byte2 := 0
else begin
byte2 := buf1[temp2];
Inc(temp2);
end;
import_dfm_event(pattern,line,channel,byte1,byte2);
end;
until (temp2 >= temp);
process_dfm_patterns(temp3);
CloseF(f);
songdata_title := NameOnly(songdata_source);
load_flag := 8;
end;
type
tHSC_PATTERNS = array[0..$31] of
array[0..$3f] of array[1..9] of Word;
type
tHSC_DATA = Record
instr: array[0..$7f] of array[0..$0b] of Byte;
order: array[0..$31] of Byte;
patts: tHSC_PATTERNS;
end;
procedure import_hsc_event(patt,line,chan: Byte; event: Word);
var
chunk: tCHUNK;
begin
FillChar(chunk,SizeOf(chunk),0);
Case HI(event) of
{ REGULAR NOTE }
1..12*8+1: If NOT fix_c_note_bug then chunk.note := HI(event)
else begin
chunk.note := HI(event)+1;
If (chunk.note > 12*8+1) then
chunk.note := 12*8+1;
end;
{ PAUSE }
$7f: chunk.note := BYTE_NULL;
{ INSTRUMENT }
$80: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol;
chunk.instr_def := LO(event)+1;
chunk.note := BYTE_NULL;
end;
end;
If (HI(event) <> $80) then
Case (LO(event) AND $0f0) of
{ PATTERNBREAK }
$00: If (LO(event) AND $0f = 1) then
chunk.effect_def := ef_PatternBreak;
{ MANUAL SLIDE UP }
$10: begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_FineTuneUp*16+
max(LO(event) AND $0f +1,15);
end;
{ MANUAL SLIDE DOWN }
$20: begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_FineTuneDown*16+
max(LO(event) AND $0f +1,15);
end;
{ SET CARRIER VOLUME }
$a0: begin
chunk.effect_def := ef_SetCarrierVol;
chunk.effect := 63-(LO(event) AND $0f)*4;
chunk.instr_def := LO(event)+1;
end;
{ SET MODULATOR VOLUME }
$b0: begin
chunk.effect_def := ef_SetModulatorVol;
chunk.effect := 63-(LO(event) AND $0f)*4;
end;
{ SET INSTRUMENT VOLUME }
$c0: begin
chunk.effect_def := ef_SetInsVolume;
chunk.effect := 63-(LO(event) AND $0f)*4;
end;
{ SET SPEED }
$f0: begin
chunk.effect_def := ef_SetSpeed;
chunk.effect := (LO(event) AND $0f)+1;
end;
end;
put_chunk(patt,line,chan,chunk);
end;
procedure import_hsc_patterns(var data; patterns: Byte);
var
voice: array[1..9] of Byte;
event: Word;
chunk: tCHUNK;
temp,temp2,temp3: Byte;
order,patt: Byte;
patt_break: Byte;
patts: String;
function _hsc_event(patt,line,chan: Byte): Word;
begin
_hsc_event := LO(tHSC_PATTERNS(data)[patt][line][chan+1])+
HI(tHSC_PATTERNS(data)[patt][line][chan]) SHL 8;
end;
begin { import_hsc_patterns }
patts := '';
If NOT accurate_conv then
For temp := 1 to 9 do voice[temp] := temp
else For temp := 1 to 9 do voice[temp] := 0;
For temp := 0 to $31 do
For temp2 := 0 to $3f do
For temp3 := 1 to 9 do
If (_hsc_event(temp,temp2,temp3) <> 0) then
import_hsc_event(temp,temp2,temp3,_hsc_event(temp,temp2,temp3));
order := 0;
patt := BYTE_NULL;
Repeat
If (songdata.pattern_order[order] > $31) then Inc(order)
else
begin
patt := songdata.pattern_order[order];
patt_break := BYTE_NULL;
For temp2 := 0 to $3f do
For temp3 := 1 to 9 do
begin
get_chunk(patt,temp2,temp3,chunk);
event := _hsc_event(patt,temp2,temp3);
Case HI(event) of
{ REGULAR NOTE }
1..12*8+1: begin
If accurate_conv then
If (voice[temp3] = 0) then
begin
voice[temp3] := temp3;
chunk.instr_def := voice[temp3];
end;
If NOT accurate_conv then
chunk.instr_def := voice[temp3];
end;
{ INSTRUMENT }
$80: If (temp2 <> patt_break) then
begin
voice[temp3] := LO(event)+1;
If NOT accurate_conv then
begin
chunk.instr_def := voice[temp3];
chunk.note := BYTE_NULL;
end;
end;
end;
If (HI(event) <> $80) then
Case (LO(event) AND $0f0) of
{ PATTERNBREAK }
$00: If (LO(event) AND $0f = 1) then
patt_break := temp2+1;
{ SET CARRIER VOLUME }
$a0: If (chunk.instr_def = 0) and NOT accurate_conv then
chunk.instr_def := voice[temp3]
else If (chunk.instr_def = 0) and
(voice[temp3] = 0) then chunk.instr_def := temp3;
{ SET MODULATOR VOLUME }
$b0: If (chunk.instr_def = 0) and NOT accurate_conv then
chunk.instr_def := voice[temp3]
else If (chunk.instr_def = 0) and
(voice[temp3] = 0) then chunk.instr_def := temp3;
{ SET INSTRUMENT VOLUME }
$c0: If (chunk.instr_def = 0) and NOT accurate_conv then
chunk.instr_def := voice[temp3]
else If (chunk.instr_def = 0) and
(voice[temp3] = 0) then chunk.instr_def := temp3;
end;
If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then
put_chunk(patt,temp2,temp3,chunk);
end;
Inc(order);
patts := patts+CHR(patt);
end;
until (patt >= patterns) or (order > $7f);
end;
procedure import_hsc_instrument(inst: Byte; var data);
begin
With songdata.instr_data[inst] do
begin
fm_data.AM_VIB_EG_carrier := pBYTE(@data)[0];
fm_data.AM_VIB_EG_modulator := pBYTE(@data)[1];
fm_data.KSL_VOLUM_carrier := pBYTE(@data)[2];
fm_data.KSL_VOLUM_modulator := pBYTE(@data)[3];
fm_data.ATTCK_DEC_carrier := pBYTE(@data)[4];
fm_data.ATTCK_DEC_modulator := pBYTE(@data)[5];
fm_data.SUSTN_REL_carrier := pBYTE(@data)[6];
fm_data.SUSTN_REL_modulator := pBYTE(@data)[7];
fm_data.FEEDBACK_FM := pBYTE(@data)[8] AND $0f;
fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 3;
fm_data.WAVEFORM_modulator := pBYTE(@data)[10] AND 3;
end;
songdata.instr_data[inst].panning := 0;
songdata.instr_data[inst].fine_tune := pBYTE(@data)[11] SHR 4;
end;
var
hscbuf: tHSC_DATA;
procedure hsc_file_loader;
const
HSC_KSL: array[0..3] of Byte = (0,3,2,1);
var
f: File;
temp,temp2,temp3: Longint;
begin
If (Lower(ExtOnly(songdata_source)) <> 'hsc') then
begin
load_flag := $7f;
EXIT;
end;
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
FillChar(hscbuf,SizeOf(hscbuf),0);
BlockReadF(f,hscbuf,SizeOf(hscbuf),temp);
If (temp < SizeOf(hscbuf.instr)+SizeOf(hscbuf.order)) then
begin
CloseF(f);
EXIT;
end;
For temp2 := 0 to $31 do
If (hscbuf.order[temp2] > $b0) then hscbuf.order[temp2] := $080;
temp3 := 0;
While (temp3 < temp-SizeOf(hscbuf.instr)-SizeOf(hscbuf.order)) do
begin
If NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3+1] in
[1..12*8+1,$00,$7f,$80]) or
NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3] AND $0f0 in
[$00,$10,$20,$a0,$b0,$c0,$f0]) then
begin
If NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3+1] in
[1..12*8+1,$00,$7f,$80]) then
pBYTE(@Addr(hscbuf.patts)^)[temp3+1] := $00;
If NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3] AND $0f0 in
[$00,$10,$20,$a0,$b0,$c0,$f0]) then
pBYTE(@Addr(hscbuf.patts)^)[temp3] := 0;
end;
Inc(temp3,2);
end;
init_songdata;
load_flag := 0;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 9
else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9;
tempo := 18;
speed := 2;
songdata.common_flag := songdata.common_flag OR 2;
songdata.tempo := tempo;
songdata.speed := speed;
import_old_flags;
For temp2 := 0 to $31 do
songdata.pattern_order[temp2] := hscbuf.order[temp2];
import_hsc_patterns(hscbuf.patts,(temp-SizeOf(hscbuf.instr)
-SizeOf(hscbuf.order)-1) DIV $480);
// specific corrections for HSC-Tracker instrument
For temp2 := 0 to $7f do
begin
import_hsc_instrument(temp2+1,hscbuf.instr[temp2]);
With songdata.instr_data[temp2+1].fm_data do
begin
KSL_VOLUM_modulator := KSL_VOLUM_modulator AND $3f+
HSC_KSL[KSL_VOLUM_modulator SHR 6] SHL 6;
KSL_VOLUM_carrier := KSL_VOLUM_carrier AND $3f+
HSC_KSL[KSL_VOLUM_carrier SHR 6] SHL 6;
end;
end;
CloseF(f);
songdata_title := NameOnly(songdata_source);
load_flag := 9;
end;
type
tMTK_DATA = Record
sname: String[33];
compo: String[33];
instn: array[0..$7f] of String[33];
instt: array[0..$7f] of array[0..$0b] of Byte;
order: array[0..$7f] of Byte;
patts: tHSC_PATTERNS;
dummy: Byte;
end;
var
buffer2: tMTK_DATA;
procedure mtk_file_loader;
var
f: File;
temp,temp2: Longint;
crc: Word;
old_c_fix: Boolean;
const
id = 'mpu401tr'#146'kk'#238'r@data';
var
header: Record
id_string: array[1..18] of Char;
crc_16bit: Word;
data_size: Word;
end;
begin
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and (header.id_string = id)) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,buf1,SizeOf(buf1),temp);
crc := 0;
crc := Update16(buf1,temp,crc);
If (crc <> header.crc_16bit) then
begin
CloseF(f);
EXIT;
end;
FillChar(buffer2,SizeOf(buffer2),0);
temp2 := RDC_decompress(buf1,buffer2,temp);
If NOT (temp2 = header.data_size) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 9
else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9;
tempo := 18;
speed := 2;
songdata.common_flag := songdata.common_flag OR 2;
songdata.tempo := tempo;
songdata.speed := speed;
import_old_flags;
For temp2 := 0 to $31 do
If (buffer2.order[temp2] <> $ff) then songdata.pattern_order[temp2] := buffer2.order[temp2]
else songdata.pattern_order[temp2] := $080;
old_c_fix := fix_c_note_bug;
fix_c_note_bug := FALSE;
import_hsc_patterns(buffer2.patts,
(header.data_size-SizeOf(buffer2.sname)
-SizeOf(buffer2.compo)
-SizeOf(buffer2.instn)
-SizeOf(buffer2.instt)
-SizeOf(buffer2.order)-1) DIV $480);
fix_c_note_bug := old_c_fix;
// specific corrections for MPU-401 TRAKKER instrument
For temp2 := 0 to $7f do
begin
import_hsc_instrument(temp2+1,buffer2.instt[temp2]);
With songdata.instr_data[temp2+1].fm_data do
begin
If (KSL_VOLUM_modulator > 128) then
KSL_VOLUM_modulator := KSL_VOLUM_modulator DIV 3;
If (KSL_VOLUM_carrier > 128) then
KSL_VOLUM_carrier := KSL_VOLUM_carrier DIV 3;
end;
songdata.instr_names[temp2+1] :=
Copy(songdata.instr_names[temp2+1],1,9)+
truncate_string(Copy(buffer2.instn[temp2],10,32));
end;
songdata.songname := CutStr(buffer2.sname);
songdata.composer := CutStr(buffer2.compo);
CloseF(f);
songdata_title := NameOnly(songdata_source);
load_flag := 10;
end;
procedure rad_file_loader;
const
id = 'RAD by REALiTY!!';
var
header: Record
ident: array[1..16] of Char; { Use this to recognize a RAD tune }
rmver: Byte; { Version of RAD file (10h) }
xbyte: Byte; { bit7 Set if a description follows }
end; { bit6 Set if it's a "slow-timer" tune }
{ bit[4..0] The initial speed of the tune }
var
f: File;
dscbuf: array[0..PRED(80*22)] of Char;
pattoffs: array[0..$1f] of Word;
temp,temp2,temp3,temp4,temp5,offs0: Longint;
procedure import_rad_event(pattern,line,channel,byte1,byte2,byte3: Byte);
var
chunk: tCHUNK;
begin
FillChar(chunk,SizeOf(chunk),0);
If ((byte2 SHR 4)+(byte1 SHR 7) SHL 4 <> 0) then
chunk.instr_def := (byte2 SHR 4)+(byte1 SHR 7) SHL 4;
If (byte1 AND $0f in [1..12]) then chunk.note := 12*((byte1 SHR 4) AND 7)+(byte1 AND $0f)+1
else If (byte1 AND $0f = $0f) then chunk.note := BYTE_NULL;
Case byte2 AND $0f of
{ PORTAMENTO (FREQUENCY SLIDE) UP }
$01: begin
chunk.effect_def := ef_FSlideUp;
chunk.effect := byte3;
end;
{ PORTAMENTO (FREQUENCY SLIDE) DOWN }
$02: begin
chunk.effect_def := ef_FSlideDown;
chunk.effect := byte3;
end;
{ PORTAMENTO TO NOTE }
$03: begin
chunk.effect_def := ef_TonePortamento;
chunk.effect := byte3;
end;
{ PORTAMENTO TO NOTE WITH VOLUME SLIDE }
$05: If (byte3 in [1..49]) then
begin
chunk.effect_def := ef_TPortamVolSlide;
chunk.effect := max(byte3,15);
If (byte3 > 15) then
begin
chunk.effect_def2 := ef_TPortamVolSlide;
chunk.effect2 := max(byte3-15,15);
end;
end
else If (byte3 in [51..99]) then
begin
chunk.effect_def := ef_TPortamVolSlide;
chunk.effect := max(byte3-50,15)*16;
If (byte3-50 > 15) then
begin
chunk.effect_def2 := ef_TPortamVolSlide;
chunk.effect2 := max(byte3-50-15,15);
end;
end;
{ VOLUME SLIDE }
$0a: If (byte3 in [1..49]) then
begin
chunk.effect_def := ef_VolSlide;
chunk.effect := max(byte3,15);
If (byte3 > 15) then
begin
chunk.effect_def2 := ef_VolSlide;
chunk.effect2 := max(byte3-15,15);
end;
end
else If (byte3 in [51..99]) then
begin
chunk.effect_def := ef_VolSlide;
chunk.effect := max(byte3-50,15)*16;
If (byte3-50 > 15) then
begin
chunk.effect_def2 := ef_VolSlide;
chunk.effect2 := max(byte3-50-15,15);
end;
end;
{ SET VOLUME }
$0c: begin
chunk.effect_def := ef_SetInsVolume;
If (byte3 < 64) then chunk.effect := byte3
else chunk.effect := 63;
end;
{ JUMP TO NEXT PATTERN IN ORDER LIST }
$0d: begin
chunk.effect_def := ef_PatternBreak;
If (byte3 < 64) then chunk.effect := byte3
else chunk.effect := 63;
end;
{ SET SPEED }
$0f: begin
chunk.effect_def := ef_SetSpeed;
chunk.effect := byte3;
end;
end;
// specific corrections for RAd-Tracker event
If (chunk.effect_def in [ef_TonePortamento,
ef_TPortamVolSlide]) and
(chunk.note = BYTE_NULL) then chunk.note := 0;
If (chunk.effect_def in [ef_TonePortamento,
ef_TPortamVolSlide]) then chunk.instr_def := 0;
If (chunk.note = 0) then chunk.instr_def := 0;
put_chunk(pattern,line,channel+1,chunk);
end;
// *******************************
// ADT2plug RAD description loader
// *******************************
{$IFDEF PLUGIN}
procedure load_rad_description(length: Word);
var
temp: Word;
row,temp2: Byte;
xstart,ystart: Byte;
desc: String;
procedure insertdesc;
begin
radinstr_used := true;
While (SYSTEM.Length(desc) > maxmemolinelen) do
begin
radinstr_names[row] := Copy(desc,1,maxmemolinelen);
desc := Copy(desc,maxmemolinelen+1,system.length(desc)-maxmemolinelen);
Inc(row);
end;
radinstr_names[row] := desc;
end;
begin
temp := 0;
row := 1;
desc := '';
While (dscbuf[temp] <> #0) and (temp < length) do
begin
Case dscbuf[temp] of
#1: If (row < 255) then
begin
insertdesc;
Inc(row);
desc := '';
end;
#2..#31: For temp2 := 1 to BYTE(dscbuf[temp]) do
desc := desc+' ';
#32..#255: desc := desc+dscbuf[temp];
end;
Inc(temp);
end;
insertdesc;
end;
{$ENDIF}
begin
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and (header.ident = id)) then
begin
CloseF(f);
EXIT;
end;
If (header.rmver <> $10) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,buf1,SizeOf(buf1),temp);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
temp2 := 0;
offs0 := SizeOf(header);
If (header.xbyte OR $80 = header.xbyte) then
begin
While (temp2 < temp) and (buf1[temp2] <> 0) do Inc(temp2);
If (temp2 >= temp) then
begin
CloseF(f);
EXIT;
end;
Inc(offs0,temp2+1);
Dec(temp,temp2+1);
Move(buf1,dscbuf,temp2+1);
Move(buf1[temp2+1],buf1,temp);
{$IFDEF PLUGIN}
load_rad_description(temp2+1);
{$ENDIF}
end;
init_songdata;
load_flag := 0;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 9
else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9;
If (header.xbyte OR $40 = header.xbyte) then tempo := 18
else tempo := 50;
If (header.xbyte AND $1f in [1..31]) then speed := header.xbyte AND $1f
else speed := 2;
songdata.tempo := tempo;
songdata.speed := speed;
temp2 := 0;
Repeat
temp3 := buf1[temp2];
Inc(temp2);
If (temp3 <> 0) and (temp2+11 < temp) then
begin
import_hsc_instrument(temp3,buf1[temp2]);
songdata.instr_data[temp3].fine_tune := 0;
Inc(temp2,11);
end;
until (temp3 = 0) or (temp3 >= temp);
Inc(offs0,temp2);
Dec(temp,temp2);
Move(buf1[temp2],buf1,temp);
Inc(offs0,buf1[0]+1);
If (buf1[0] <> 0) then
Move(buf1[1],songdata.pattern_order,buf1[0]);
Inc(offs0,32*SizeOf(WORD));
Dec(temp,buf1[0]+1+32*SizeOf(WORD));
Move(buf1[buf1[0]+1],pattoffs,32*SizeOf(WORD));
Move(buf1[buf1[0]+32*SizeOf(WORD)+1],buf1,temp);
temp5 := temp;
For temp := 0 to 31 do
begin
temp2 := 0;
temp3 := 0;
If (pattoffs[temp] <> 0) and
(pattoffs[temp] <= FileSize(f)) then
Repeat
temp2 := buf1[pattoffs[temp]-offs0+temp3];
Repeat
Inc(temp3);
temp4 := buf1[pattoffs[temp]-offs0+temp3];
If (buf1[pattoffs[temp]-offs0+temp3+2] AND $0f <> 0) then
begin
If (temp4 AND $0f in [0..8]) then
import_rad_event(temp,temp2 AND $3f,temp4 AND $0f,
buf1[pattoffs[temp]-offs0+temp3+1],
buf1[pattoffs[temp]-offs0+temp3+2],
buf1[pattoffs[temp]-offs0+temp3+3]);
Inc(temp3,3);
end
else begin
If (temp4 AND $0f in [0..8]) then
import_rad_event(temp,temp2 AND $3f,temp4 AND $0f,
buf1[pattoffs[temp]-offs0+temp3+1],
buf1[pattoffs[temp]-offs0+temp3+2],
0);
Inc(temp3,2);
end;
until (temp4 OR $80 = temp4) or (temp3 > temp5);
Inc(temp3);
until (temp2 OR $80 = temp2) or (temp3 > temp5);
end;
CloseF(f);
songdata_title := NameOnly(songdata_source);
load_flag := 11;
end;
const
temp_ef_Arpeggio = $0f0;
temp_ef_rep = $0f1;
temp_ef_XFVSlide = $0f2;
var
ins_c4factor: array[1..99] of Shortint;
procedure fix_s3m_commands(patterns: Byte);
var
chunk,chunk2: tCHUNK;
temp,temp4: Byte;
patt_break: Byte;
order,patt: Byte;
patts: String;
ins_cache,
misc_cache,
arpg_cache,
volsld_cache,
slide_cache,
note_cache,
patloop_cache: array[1..20] of Byte;
prev_cache: array[1..20] of Record
effect_def,
effect,
effect_def2,
effect2: Byte;
end;
procedure fix_single_pattern(patt: Byte);
var
temp2,temp3: Byte;
begin
FillChar(prev_cache,SizeOf(prev_cache),0);
FillChar(patloop_cache,SizeOf(patloop_cache),BYTE_NULL);
patt_break := BYTE_NULL;
For temp2 := 0 to $3f do
For temp3 := 1 to 20 do
begin
get_chunk(patt,temp2,temp3,chunk);
If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then
patt_break := temp2;
If (chunk.instr_def <> 0) and (temp2 <= patt_break) then
ins_cache[temp3] := chunk.instr_def;
If (chunk.note in [1..12*8+1]) and (temp2 <= patt_break) then
note_cache[temp3] := chunk.note;
If (chunk.instr_def <> 0) or ((chunk.instr_def = 0) and
(chunk.note in [1..12*8+1]) and
(ins_cache[temp3] <> 0)) then
begin
If (chunk.instr_def <> 0) then temp4 := chunk.instr_def
else temp4 := ins_cache[temp3];
If (ins_c4factor[temp4] <> 0) and
NOT (Pos(CHR(songdata.pattern_order[order]),patts) <> 0) then
begin
If (ins_c4factor[temp4] <> -127) then
chunk.note := min(max(chunk.note+ins_c4factor[temp4],12*8+1),1)
else chunk.note := 1;
put_chunk(patt,temp2,temp3,chunk);
end;
end;
If (chunk.effect_def = ef_Extended) and
(chunk.effect DIV 16 = ef_ex_PatternLoop) and
(chunk.effect MOD 16 <> 0) then
If NOT (patloop_cache[temp3] in [0,BYTE_NULL]) and (temp2 <> 0) then
begin
If (prev_cache[temp3].effect_def = 0) and
(prev_cache[temp3].effect = 0) then
begin
get_chunk(patt,PRED(temp2),temp3,chunk2);
chunk2.effect_def := ef_Extended;
chunk2.effect := ef_ex_PatternLoop*16;
If NOT ((chunk2.effect_def = chunk2.effect_def2) and
(chunk2.effect = chunk2.effect2)) then
begin
put_chunk(patt,PRED(temp2),temp3,chunk2);
prev_cache[temp3].effect_def := chunk.effect_def;
prev_cache[temp3].effect := chunk.effect;
end;
end
else If (prev_cache[temp3].effect_def2 = 0) and
(prev_cache[temp3].effect2 = 0) then
begin
get_chunk(patt,PRED(temp2),temp3,chunk2);
chunk2.effect_def2 := ef_Extended;
chunk2.effect2 := ef_ex_PatternLoop*16;
If NOT ((chunk2.effect_def2 = chunk2.effect_def) and
(chunk2.effect2 = chunk2.effect)) then
begin
put_chunk(patt,PRED(temp2),temp3,chunk2);
prev_cache[temp3].effect_def2 := chunk.effect_def2;
prev_cache[temp3].effect2 := chunk.effect2;
end;
end;
end
else If (patloop_cache[temp3] <> 0) and (temp2 <> 0) then
begin
get_chunk(patt,0,temp3,chunk2);
If (chunk2.effect_def = 0) and
(chunk2.effect = 0) then
begin
chunk2.effect_def := ef_Extended;
chunk2.effect := ef_ex_PatternLoop*16;
If NOT ((chunk2.effect_def = chunk2.effect_def2) and
(chunk2.effect = chunk2.effect2)) then
put_chunk(patt,0,temp3,chunk2);
end
else If (chunk2.effect_def2 = 0) and
(chunk2.effect2 = 0) then
begin
chunk2.effect_def2 := ef_Extended;
chunk2.effect2 := ef_ex_PatternLoop*16;
If NOT ((chunk2.effect_def2 = chunk2.effect_def) and
(chunk2.effect2 = chunk2.effect)) then
put_chunk(patt,0,temp3,chunk2);
end;
end;
If (temp2 <= patt_break) then
begin
If (chunk.effect DIV 16 <> 0) then
misc_cache[temp3] := chunk.effect AND $0f0+
misc_cache[temp3] AND $0f
else If (chunk.effect_def in [ef_Vibrato,
ef_ExtraFineVibrato,
ef_Tremolo,
ef_Tremor,
ef_MultiRetrigNote]) then
begin
chunk.effect := misc_cache[temp3] AND $0f0+
chunk.effect AND $0f;
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect MOD 16 <> 0) then
misc_cache[temp3] := misc_cache[temp3] AND $0f0+
chunk.effect AND $0f
else If (chunk.effect_def in [ef_Vibrato,
ef_ExtraFineVibrato,
ef_Tremolo,
ef_Tremor,
ef_MultiRetrigNote]) then
begin
chunk.effect := chunk.effect AND $0f0+
misc_cache[temp3] AND $0f;
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def = temp_ef_Arpeggio) then
If (chunk.effect <> 0) then arpg_cache[temp3] := chunk.effect
else begin
chunk.effect := arpg_cache[temp3];
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine,
ef_FSlideUp,ef_FSlideUpFine,
ef_TonePortamento]) then
If (chunk.effect <> 0) then slide_cache[temp3] := chunk.effect
else begin
chunk.effect := slide_cache[temp3];
put_chunk(patt,temp2,temp3,chunk);
end;
// experimental method to fix up frequency slide
If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine,
ef_FSlideUp,ef_FSlideUpFine,
ef_Vibrato,
ef_ExtraFineVibrato,
ef_TonePortamento]) then
If (note_cache[temp3] <> 0) then
begin
If (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato]) then
begin
temp := chunk.effect AND $0f0;
chunk.effect := chunk.effect MOD 16;
end;
Case SUCC(PRED(note_cache[temp3]) DIV 12) of
1: chunk.effect := max(Round(chunk.effect*0.55),255);
2: chunk.effect := max(Round(chunk.effect*0.75),255);
3: chunk.effect := max(Round(chunk.effect*0.95),255);
4: chunk.effect := max(Round(chunk.effect*1.15),255);
5: chunk.effect := max(Round(chunk.effect*1.35),255);
6: chunk.effect := max(Round(chunk.effect*1.55),255);
7: chunk.effect := max(Round(chunk.effect*1.75),255);
8: chunk.effect := max(Round(chunk.effect*1.95),255);
end;
If (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato]) then
chunk.effect := max(chunk.effect,15)+temp;
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def = ef_Extended2) and
(chunk.effect DIV 16 in [ef_ex2_FreqSlideDnXF,ef_ex2_FreqSlideUpXF]) then
If (chunk.effect MOD 16 <> 0) then slide_cache[temp3] := chunk.effect MOD 16
else begin
chunk.effect := chunk.effect AND $0f0+slide_cache[temp3] AND $0f;
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def in [ef_TPortamVolSlide,ef_VibratoVolSlide,
ef_VolSlide,ef_VolSlideFine]) and
(temp2 <= patt_break) then
begin
If (chunk.effect <> 0) then volsld_cache[temp3] := chunk.effect
else begin
chunk.effect := volsld_cache[temp3];;
put_chunk(patt,temp2,temp3,chunk);
end;
end;
If (chunk.effect_def = ef_Extended2) and
(chunk.effect DIV 16 in [ef_ex2_VolSlideDnXF,ef_ex2_VolSlideUpXF]) then
If (chunk.effect MOD 16 <> 0) then
Case chunk.effect DIV 16 of
ef_ex2_VolSlideDnXF:
volsld_cache[temp3] := chunk.effect MOD 16;
ef_ex2_VolSlideUpXF:
volsld_cache[temp3] := chunk.effect MOD 16 SHL 4;
end
else begin
Case chunk.effect DIV 16 of
ef_ex2_VolSlideDnXF:
chunk.effect := chunk.effect AND $0f0+volsld_cache[temp3] AND $0f;
ef_ex2_VolSlideUpXF:
chunk.effect := volsld_cache[temp3] AND $0f0+chunk.effect AND $0f;
end;
put_chunk(patt,temp2,temp3,chunk);
end;
end;
If (prev_cache[temp3].effect_def in [ef_Vibrato,ef_ExtraFineVibrato,ef_VibratoVolSlide]) and
NOT (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato,ef_VibratoVolSlide]) then
If (chunk.effect_def = 0) and (chunk.effect = 0) then
begin
chunk2 := chunk;
chunk2.effect_def := ef_Extended;
chunk2.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff;
If NOT ((chunk2.effect_def = chunk2.effect_def2) and
(chunk2.effect = chunk2.effect2)) then
begin
put_chunk(patt,temp2,temp3,chunk2);
chunk := chunk2;
end;
end
else If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then
begin
chunk2 := chunk;
chunk2.effect_def2 := ef_Extended;
chunk2.effect2 := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff;
If NOT ((chunk2.effect_def2 = chunk2.effect_def) and
(chunk2.effect2 = chunk2.effect)) then
begin
put_chunk(patt,temp2,temp3,chunk2);
chunk := chunk2;
end;
end;
If (chunk.effect_def = ef_Extended) and
(chunk.effect DIV 16 = ef_ex_PatternLoop) then
patloop_cache[temp3] := chunk.effect MOD 16;
prev_cache[temp3].effect_def := chunk.effect_def;
prev_cache[temp3].effect := chunk.effect;
prev_cache[temp3].effect_def2 := chunk.effect_def2;
prev_cache[temp3].effect2 := chunk.effect2;
If (chunk.effect_def = temp_ef_Arpeggio) then
begin
chunk2 := chunk;
chunk2.effect_def := ef_Arpeggio;
put_chunk(patt,temp2,temp3,chunk2);
end;
end;
end;
begin { fix_s3m_commands }
FillChar(ins_cache,SizeOf(ins_cache),0);
FillChar(note_cache,SizeOf(note_cache),0);
FillChar(volsld_cache,SizeOf(volsld_cache),0);
FillChar(slide_cache,SizeOf(slide_cache),0);
FillChar(misc_cache,SizeOf(misc_cache),0);
FillChar(arpg_cache,SizeOf(arpg_cache),0);
patts := '';
order := 0; patt := BYTE_NULL;
Repeat
If (songdata.pattern_order[order] >= $80) then Inc(order)
else
begin
patt := songdata.pattern_order[order];
If NOT (Pos(CHR(patt),patts) <> 0) then
fix_single_pattern(patt);
Inc(order);
patts := patts+CHR(patt);
end;
until (patt >= patterns) or (order > $7f);
For patt := 0 to PRED(patterns) do
If NOT (Pos(CHR(patt),patts) <> 0) then
fix_single_pattern(patt);
end;
procedure s3m_file_loader;
type
tS3M_HEADER = Record
songname: array[1..28] of Char; { ASCIIZ }
byte1a: Byte; { 1Ah }
ftype: Byte; { File type: 16=ST3 module }
resrvd1: array[0..1] of Byte;
ordnum: Word; { Number of orders in file (should be even!) }
insnum: Word; { Number of instruments in file }
patnum: Word; { Number of patterns in file }
flags: Word; { [ These are old flags for Ffv1. Not supported in ST3.01 }
{ | +1:st2vibrato }
{ | +2:st2tempo }
{ | +4:amigaslides }
{ | +32:enable filter/sfx with sb }
{ ] }
{ +8: 0vol optimizations }
{ Automatically turn off looping notes whose volume }
{ is zero for >2 note rows. }
{ +16: amiga limits }
{ Disallow any notes that go beyond the amiga hardware }
{ limits (like amiga does). This means that sliding }
{ up stops at B#5 etc. Also affects some minor amiga }
{ compatibility issues. }
{ +64: st3.00 volumeslides }
{ Normally volumeslide is NOT performed on first }
{ frame of each row (this is according to amiga }
{ playing). If this is set, volumeslide is performed }
{ ALSO on the first row. This is set by default }
{ if the Cwt/v files is 0x1300 }
{ +128: special custom data in file (see below) }
cwt_v: Word; { Created with tracker / version: &0xfff=version, >>12=tracker }
{ ST3.00:0x1300 (NOTE: volumeslides on EVERY frame) }
{ ST3.01:0x1301 }
{ ST3.03:0x1303 }
{ ST3.20:0x1320 }
ffi: Word; { File format information }
{ 1=[VERY OLD] signed samples }
{ 2=unsigned samples }
id: array[1..4] of Char; { "SCRM" }
g_v: Byte; { global volume (see next section) }
i_s: Byte; { initial speed (command A) }
i_t: Byte; { initial tempo (command T) }
m_v: Byte; { master volume (see next section) 7 lower bits }
{ bit 8: stereo(1) / mono(0) }
u_c: Byte; { ultra click removal }
d_p: Byte; { 252 when default channel pan positions are present }
{ in the end of the header (xxx3). If !=252 ST3 doesn't }
{ try to load channel pan settings. }
resrvd2: array[0..7] of Byte;
special: Word;
chan_set: array[1..32] of Byte;
end;
type
tS3M_ADLINS = Record
itype: Byte; { 2:amel 3:abd 4:asnare 5:atom 6:acym 7:ahihat }
dosname: array[1..12] of Char;
id0: array[0..2] of Char;
fmdata: array[0..11] of Byte; { D00..D0B contains the adlib instrument specs packed like this: }
{ modulator: carrier: }
{ D00=[freq.muliplier]+[?scale env.]*16+[?sustain]*32+ =D01 }
{ [?pitch vib]*64+[?vol.vib]*128 }
{ D02=[63-volume]+[levelscale&1]*128+[l.s.&2]*64 =D03 }
{ D04=[attack]*16+[decay] =D05 }
{ D06=[15-sustain]*16+[release] =D07 }
{ D08=[wave select] =D09 }
{ D0A=[modulation feedback]*2+[?additive synthesis] }
{ D0B=unused }
vol: Byte; { Default volume 0..64 }
dsk: Byte;
resrvd1: array[0..1] of Byte;
c2spd: Word; { 'Herz' for middle C. ST3 only uses lower 16 bits. }
{ Actually this is a modifier since there is no }
{ clear frequency for adlib instruments. It scales }
{ the note freq sent to adlib. }
hi_c2sp: Word;
resrvd2: array[0..11] of Byte;
smpname: array[1..28] of Char; { ASCIIZ }
id: array[1..4] of Char; { "SCRI" or "SCRS" }
end;
const
id_mod = 'SCRM';
id_ins_adl = 'SCRI';
id_ins_smp = 'SCRS';
var
f: File;
header: tS3M_HEADER;
order_list: array[0..254] of Byte;
paraptr_ins: array[1..99] of Word;
default_vol: array[1..99] of Byte;
paraptr_pat: array[0..99] of Word;
temp,temp2: Longint;
insdata: tS3M_ADLINS;
pat,row,chan: Byte;
note,ins,vol,cmd,info: Byte;
patlen,index: Word;
procedure import_s3m_event(pattern,line,channel,note,ins,vol,cmd,info: Byte);
var
chunk: tCHUNK;
function scale_slide(slide: Byte): Byte;
begin
If (slide > 16) then scale_slide := Round(16+slide/8)
else scale_slide := Round(slide*(2-slide/16));
end;
begin
FillChar(chunk,SizeOf(chunk),0);
chunk.instr_def := ins;
Case note of
254: chunk.note := BYTE_NULL;
255: chunk.note := 0;
else If (note AND $0f in [0..11]) then
chunk.note := 12*((note SHR 4) AND 7)+(note AND $0f)+1
end;
If (vol <> BYTE_NULL) then
begin
chunk.effect_def2 := ef_SetInsVolume;
chunk.effect2 := max(vol,63);
end
else
If NOT (note in [254,255]) and
(ins <> 0) and
(max(default_vol[ins],63) <> 63) then
begin
chunk.effect_def2 := ef_SetInsVolume;
chunk.effect2 := max(default_vol[ins],63);
end;
Case CHR(cmd+ORD('A')-1) of
{ NONE }
'@': chunk.effect := info;
{ SET SPEED }
'A': If (info <> 0) then
begin
chunk.effect_def := ef_SetSpeed;
chunk.effect := info;
end;
{ JUMP TO ORDER }
'B': If (info <= 254) then
begin
chunk.effect_def := ef_PositionJump;
chunk.effect := info;
end;
{ BREAK PATTERN }
'C': If (info < 64) then
begin
chunk.effect_def := ef_PatternBreak;
chunk.effect := Str2num(Num2str(info,16),10);
end;
{ VOLUME SLIDE }
'D': { VOLUME SLIDE DOWN }
Case info DIV 16 of
{ NORMAL }
0: begin
chunk.effect_def := ef_VolSlide;
chunk.effect := info MOD 16;
end;
{ FINE }
15: begin
chunk.effect_def := ef_VolSlideFine;
chunk.effect := info MOD 16;
end;
else
{ VOLUME SLIDE UP }
Case info MOD 16 of
{ NORMAL }
0: begin
chunk.effect_def := ef_VolSlide;
chunk.effect := info AND $0f0;
end;
{ FINE }
15: begin
chunk.effect_def := ef_VolSlideFine;
chunk.effect := info AND $0f0;
end;
end;
end;
{ SLIDE DOWN }
'E': Case info DIV 16 of
{ NORMAL }
0..13: begin
chunk.effect_def := ef_FSlideDown;
chunk.effect := scale_slide(info);
end;
{ EXTRA FINE }
14: begin
chunk.effect_def := ef_Extended2;
If (info <> 0) then
chunk.effect := ef_ex2_FreqSlideDnXF*16+min((info AND $0f) DIV 4,1)
else chunk.effect := ef_ex2_FreqSlideDnXF*16;
end;
{ FINE }
15: begin
chunk.effect_def := ef_FSlideDownFine;
chunk.effect := info AND $0f;
end;
end;
{ SLIDE UP }
'F': Case info DIV 16 of
{ NORMAL }
0..13: begin
chunk.effect_def := ef_FSlideUp;
chunk.effect := scale_slide(info);
end;
{ EXTRA FINE }
14: begin
chunk.effect_def := ef_Extended2;
If (info <> 0) then
chunk.effect := ef_ex2_FreqSlideUpXF*16+min((info AND $0f) DIV 4,1)
else chunk.effect := ef_ex2_FreqSlideUpXF*16;
end;
{ FINE }
15: begin
chunk.effect_def := ef_FSlideUpFine;
chunk.effect := info AND $0f;
end;
end;
{ TONE PORTAMENTO }
'G': begin
chunk.effect_def := ef_TonePortamento;
chunk.effect := scale_slide(info);
end;
{ VIBRATO }
'H': begin
chunk.effect_def := ef_Vibrato;
chunk.effect := info;
end;
{ FINE VIBRATO }
'U': begin
chunk.effect_def := ef_ExtraFineVibrato;
chunk.effect := info;
end;
{ TREMOR }
'I': begin
chunk.effect_def := ef_Tremor;
chunk.effect := info;
end;
{ ARPEGGIO }
'J': begin
chunk.effect_def := temp_ef_Arpeggio;
chunk.effect := info;
end;
{ VIBRATO + VOLUME SLIDE }
'K': begin
chunk.effect_def := ef_VibratoVolSlide;
chunk.effect := info;
end;
{ TONE PORTAMENTO + VOLUME SLIDE }
'L': begin
chunk.effect_def := ef_TPortamVolSlide;
chunk.effect := info;
end;
{ RETRIG NOTE + VOLUME SLIDE }
'Q': begin
chunk.effect_def := ef_MultiRetrigNote;
chunk.effect := (info MOD 16)*16+info DIV 16;
end;
{ TREMOLO }
'R': begin
chunk.effect_def := ef_Tremolo;
chunk.effect := info;
end;
{ SPECIAL COMMAND }
'S': Case info DIV 16 of
{ PATTERN LOOP }
$0b: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_PatternLoop*16+info MOD 16;
end;
{ NOTE CUT }
$0c: begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_NoteCut*16+info MOD 16;
end;
{ NOTE DELAY }
$0d: begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_NoteDelay*16+info MOD 16;
end;
{ PATTERN DELAY }
$0e: begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_PatDelayRow*16+info MOD 16;
end;
end;
{ TEMPO }
'T': If (info >= 32) then
begin
chunk.effect_def := ef_SetTempo;
chunk.effect := Round(info/2.5);
end;
{ SET GLOBAL VOLUME }
'V': begin
chunk.effect_def := ef_SetGlobalVolume;
chunk.effect := max(info,63);
end;
end;
If (chunk.effect_def = 0) and (chunk.effect <> 0) then
chunk.effect := 0;
put_chunk(pattern,line,channel,chunk);
end;
// experimental method to fix up note fine-tuning
function find_scale_factor(freq: Longint; var fine_tune: Shortint): Shortint;
const
_factor: array[-3..3+1] of Real = (1/8,1/4,1/2,1,2,4,8,16);
const
_freq: array[1..12+1] of Word =
{ C-2 C#2 D-2 }
( 33453 DIV 4,35441 DIV 4,37679 DIV 4,
{ D#2 E-2 F-2 }
39772 DIV 4,42441 DIV 4,44744 DIV 4,
{ F#2 G-2 G#2 }
47727 DIV 4,50416 DIV 4,53426 DIV 4,
{ A-2 A#2 B-2 }
56370 DIV 4,59658 DIV 4,63354 DIV 4,
{ C-3 }
33453 DIV 2);
const
_fm_freq: array[1..12+1] of Word =
($156, $16b, $181, $198, $1b0, $1ca,
$1e5, $202, $220, $241, $263, $287,
$2ae);
var
factor: Real;
temp,scaler: Shortint;
begin
scaler := -3;
fine_tune := 0;
For scaler := -3 to 3+1 do
For temp := 1 to 12 do
begin
factor := _factor[scaler];
If (freq >= Round(_freq[temp]*factor)) and
(freq <= Round(_freq[SUCC(temp)]*factor)) then
If (freq-Round(_freq[temp]*factor) < Round(_freq[SUCC(temp)]*factor)-freq) then
begin
fine_tune := Round((_fm_freq[SUCC(temp)]-_fm_freq[temp])/
(_freq[SUCC(temp)]-_freq[temp])*
(freq-Round(_freq[temp]*factor)));
find_scale_factor := scaler*12+PRED(temp);
EXIT;
end
else
begin
fine_tune := Round((_fm_freq[SUCC(temp)]-_fm_freq[temp])/
(_freq[SUCC(temp)]-_freq[temp])*
(freq-Round(_freq[SUCC(temp)]*factor)));
If (temp <> 12) then find_scale_factor := scaler*12+temp
else find_scale_factor := SUCC(scaler)*12;
EXIT;
end;
end;
find_scale_factor := -127;
fine_tune := 0;
end;
(* // another method -- it's hard to say whether more or less accurate :)
function find_scale_factor(freq: Longint; var fine_tune: Shortint): Shortint;
const
_factor: array[-3..3+1] of Real = (1/8,1/4,1/2,1,2,4,8,16);
_finetune_factor: array[-3..3+1] of Real = (8,4,2,1,1/2,1/4,1/8,1/16);
const
_freq: array[1..12+1] of Word =
{ C-2 C#2 D-2 }
( 33453 DIV 4,35441 DIV 4,37679 DIV 4,
{ D#2 E-2 F-2 }
39772 DIV 4,42441 DIV 4,44744 DIV 4,
{ F#2 G-2 G#2 }
47727 DIV 4,50416 DIV 4,53426 DIV 4,
{ A-2 A#2 B-2 }
56370 DIV 4,59658 DIV 4,63354 DIV 4,
{ C-3 }
33453 DIV 2);
var
factor: Real;
temp,scaler: Shortint;
begin
scaler := -3;
fine_tune := 0;
For scaler := -3 to 3+1 do
For temp := 1 to 12 do
begin
factor := _factor[scaler];
If (freq >= Round(_freq[temp]*factor)) and
(freq <= Round(_freq[SUCC(temp)]*factor)) then
If (freq-Round(_freq[temp]*factor) < Round(_freq[SUCC(temp)]*factor)-freq) then
begin
fine_tune := Round((freq-Round(_freq[temp]*factor))/
Round(16/_finetune_factor[scaler]));
find_scale_factor := scaler*12+PRED(temp);
EXIT;
end
else
begin
If (temp = 12) then Inc(scaler);
fine_tune := Round((freq-Round(_freq[SUCC(temp)]*factor))/
Round(16/_finetune_factor[scaler]));
If (temp = 12) then temp := 0;
find_scale_factor := scaler*12+temp;
EXIT;
end;
end;
find_scale_factor := -127;
fine_tune := 0;
end;
*)
begin
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and (header.id = id_mod)) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
If (header.byte1a <> $1a) or (header.ftype <> $10) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,order_list,header.ordnum,temp);
If (IOresult <> 0) or (temp <> header.ordnum) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,paraptr_ins,header.insnum*2,temp);
If (IOresult <> 0) or (temp <> header.insnum*2) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,paraptr_pat,header.patnum*2,temp);
If (IOresult <> 0) or (temp <> header.patnum*2) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
If (header.i_s <> 0) then speed := header.i_s
else speed := 1;
If (Round(header.i_t/2.5) < 255) then tempo := Round(header.i_t/2.5)
else tempo := 255;
songdata.tempo := tempo;
songdata.speed := speed;
songdata.songname := truncate_string(asciiz_string(header.songname));
songdata.common_flag := songdata.common_flag OR $80;
import_old_flags;
For temp := 32 downto 1 do
If (header.chan_set[temp] <> 255) then BREAK;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := max(temp,18)
else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18;
For temp := 1 to max(header.ordnum,128) do
Case order_list[temp-1] of
254: songdata.pattern_order[temp-1] := $80+temp;
255: songdata.pattern_order[temp-1] := $80;
else songdata.pattern_order[temp-1] := order_list[temp-1];
end;
FillChar(ins_c4factor,SizeOf(ins_c4factor),0);
For temp := 1 to header.insnum do
begin
SeekF(f,paraptr_ins[temp]*16);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,insdata,SizeOf(insdata),temp2);
If (IOresult <> 0) or (temp2 <> SizeOf(insdata)) then
begin
CloseF(f);
EXIT;
end;
If (truncate_string(insdata.smpname) <> '') then
songdata.instr_names[temp] :=
Copy(songdata.instr_names[temp],1,9)+
Copy(truncate_string(asciiz_string(insdata.smpname)),1,32)
else
songdata.instr_names[temp] :=
Copy(songdata.instr_names[temp],1,9)+
truncate_string(insdata.dosname);
If (insdata.itype in [2..7]) then
begin
If (insdata.id <> id_ins_adl) and (insdata.id <> id_ins_smp) then
begin
CloseF(f);
EXIT;
end;
import_standard_instrument(temp,insdata.fmdata);
end;
default_vol[temp] := insdata.vol;
If (insdata.c2spd <> 0) and
(insdata.c2spd <> 8363) then
ins_c4factor[temp] := find_scale_factor(insdata.c2spd,songdata.instr_data[temp].fine_tune);
end;
For pat := 0 to PRED(header.patnum) do
begin
SeekF(f,paraptr_pat[pat]*16);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,patlen,SizeOf(patlen),temp2);
If (temp2 <> SizeOf(patlen)) then
begin
CloseF(f);
EXIT;
end;
If (patlen = 0) then CONTINUE;
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,buf1,patlen-2,temp2);
index := 0;
row := 0;
Repeat
If (buf1[index] <> 0) then
begin
note := BYTE_NULL;
ins := 0;
vol := BYTE_NULL;
cmd := 0;
info := 0;
temp := buf1[index];
Inc(index);
chan := SUCC(temp AND 31);
If (temp OR $20 = temp) then
begin
note := buf1[index];
Inc(index);
ins := buf1[index];
Inc(index);
end;
If (temp OR $40 = temp) then
begin
vol := buf1[index];
Inc(index);
end;
If (temp OR $80 = temp) then
begin
cmd := buf1[index];
Inc(index);
info := buf1[index];
Inc(index);
end;
If (chan > songdata.nm_tracks) then songdata.nm_tracks := max(chan,18);
If (chan in [1..songdata.nm_tracks]) then
import_s3m_event(pat,row,chan,note,ins,vol,cmd,info);
end
else
begin
Inc(row);
Inc(index);
end;
until (row = 64);
end;
fix_s3m_commands(header.patnum);
CloseF(f);
songdata_title := NameOnly(songdata_source);
load_flag := 12;
end;
procedure fix_fmk_commands(patterns: Byte);
var
chunk,chunk2,
chunk3: tCHUNK;
patt_break: Byte;
order,patt: Byte;
patts: String;
ins_cache,
misc_cache,
arpg_cache,
forcevol_cache,
volsld_cache,
xfvolsld_cache,
slide_cache: array[1..20] of Byte;
_1st_ins_load: array[1..20] of Boolean;
_speed_table_fixed: array[0..$7f] of Boolean;
prev_cache: array[1..20] of Record
effect_def,
effect,
effect_def2,
effect2: Byte;
end;
procedure fix_single_pattern(patt: Byte);
var
temp2,temp3: Byte;
begin
FillChar(prev_cache,SizeOf(prev_cache),0);
patt_break := BYTE_NULL;
If NOT _speed_table_fixed[patt] then
For temp2 := 0 to $3f do
begin
For temp3 := 1 to 20 do
begin
get_chunk(patt,temp2,temp3,chunk);
If (chunk.effect_def = 0) then
begin
chunk.effect_def := ef_SetCustomSpeedTab;
chunk.effect := $0fa;
put_chunk(patt,temp2,temp3,chunk);
_speed_table_fixed[patt] := TRUE;
end
else If (chunk.effect_def2 = 0) then
begin
chunk.effect_def2 := ef_SetCustomSpeedTab;
chunk.effect2 := $0fa;
put_chunk(patt,temp2,temp3,chunk);
_speed_table_fixed[patt] := TRUE;
end;
If _speed_table_fixed[patt] then BREAK;
end;
If _speed_table_fixed[patt] then BREAK;
end;
For temp2 := 0 to $3f do
For temp3 := 1 to 20 do
begin
get_chunk(patt,temp2,temp3,chunk);
If (chunk.effect_def = temp_ef_rep) then
begin
chunk.effect_def := prev_cache[temp3].effect_def;
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def = temp_ef_XFVSlide) then
begin
chunk.effect_def := ef_Extended2;
If (xfvolsld_cache[temp3] <> 0) then
chunk.effect := ef_ex2_VolSlideUpXF*16+volsld_cache[temp3] DIV 16
else chunk.effect := ef_ex2_VolSlideDnXF*16+volsld_cache[temp3] MOD 16;
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then
patt_break := temp2;
If (temp2 <= patt_break) and
(chunk.instr_def <> ins_cache[temp3]) and
(chunk.effect_def2 <> ef_ForceInsVolume) then
If (chunk.instr_def <> 0) then
forcevol_cache[temp3] := 0;
If ((chunk.effect_def = ef_Extended) and
(chunk.effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol)) or
((chunk.effect_def2 = ef_Extended) and
(chunk.effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol)) then
forcevol_cache[temp3] := 0;
If (chunk.effect_def2 = ef_ForceInsVolume) and
(temp2 <= patt_break) then
forcevol_cache[temp3] := 1;
If (chunk.instr_def <> 0) and (temp2 <= patt_break) then
ins_cache[temp3] := chunk.instr_def;
If (chunk.instr_def <> 0) or ((chunk.instr_def = 0) and
(chunk.note in [1..12*8+1]) and
(ins_cache[temp3] <> 0)) then
put_chunk(patt,temp2,temp3,chunk);
If (temp2 <= patt_break) then
begin
If (chunk.effect DIV 16 <> 0) then
misc_cache[temp3] := chunk.effect AND $0f0+
misc_cache[temp3] AND $0f
else If (chunk.effect_def in [ef_Vibrato,
ef_Tremolo]) then
begin
chunk.effect := misc_cache[temp3] AND $0f0+
chunk.effect AND $0f;
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect MOD 16 <> 0) then
misc_cache[temp3] := misc_cache[temp3] AND $0f0+
chunk.effect AND $0f
else If (chunk.effect_def in [ef_Vibrato,
ef_Tremolo]) then
begin
chunk.effect := chunk.effect AND $0f0+
misc_cache[temp3] AND $0f;
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def = ef_RetrigNote) then
If (chunk.effect <> 0) then misc_cache[temp3] := chunk.effect
else begin
chunk.effect := misc_cache[temp3];
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def = temp_ef_Arpeggio) then
If (chunk.effect <> 0) then arpg_cache[temp3] := chunk.effect
else begin
chunk.effect := arpg_cache[temp3];
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine,
ef_FSlideUp,ef_FSlideUpFine,
ef_TonePortamento]) then
If (chunk.effect <> 0) then slide_cache[temp3] := chunk.effect
else begin
chunk.effect := slide_cache[temp3];
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def = ef_Extended2) and
(chunk.effect DIV 16 in [ef_ex2_FreqSlideDnXF,ef_ex2_FreqSlideUpXF]) then
If (chunk.effect MOD 16 <> 0) then slide_cache[temp3] := chunk.effect MOD 16
else begin
chunk.effect := chunk.effect AND $0f0+slide_cache[temp3] AND $0f;
put_chunk(patt,temp2,temp3,chunk);
end;
If (chunk.effect_def in [ef_TPortamVolSlide,ef_VibratoVolSlide,
ef_VolSlide,ef_VolSlideFine]) and
(temp2 <= patt_break) then
begin
If (chunk.effect <> 0) then volsld_cache[temp3] := chunk.effect
else begin
chunk.effect := volsld_cache[temp3];;
put_chunk(patt,temp2,temp3,chunk);
end;
end;
If (chunk.effect_def = ef_Extended2) and
(chunk.effect DIV 16 in [ef_ex2_VolSlideDnXF,ef_ex2_VolSlideUpXF]) then
If (chunk.effect MOD 16 <> 0) then
Case chunk.effect DIV 16 of
ef_ex2_VolSlideDnXF:
begin
volsld_cache[temp3] := chunk.effect MOD 16;
xfvolsld_cache[temp3] := 0;
end;
ef_ex2_VolSlideUpXF:
begin
volsld_cache[temp3] := chunk.effect MOD 16*16;
xfvolsld_cache[temp3] := 1;
end;
end;
end;
If (prev_cache[temp3].effect_def in [ef_Vibrato,ef_VibratoVolSlide]) and
NOT (chunk.effect_def in [ef_Vibrato,ef_VibratoVolSlide]) then
If (chunk.effect_def = 0) and (chunk.effect = 0) then
begin
chunk2 := chunk;
chunk2.effect_def := ef_Extended;
chunk2.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff;
If NOT ((chunk2.effect_def = chunk2.effect_def2) and
(chunk2.effect = chunk2.effect2)) then
begin
put_chunk(patt,temp2,temp3,chunk2);
chunk := chunk2;
end;
end
else If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then
begin
chunk2 := chunk;
chunk2.effect_def2 := ef_Extended;
chunk2.effect2 := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff;
If NOT ((chunk2.effect_def2 = chunk2.effect_def) and
(chunk2.effect2 = chunk2.effect)) then
begin
put_chunk(patt,temp2,temp3,chunk2);
chunk := chunk2;
end;
end;
If (_1st_ins_load[temp3] and (chunk.instr_def <> 0)) or
(forcevol_cache[temp3] <> 0) and
(temp2 <= patt_break) and
(chunk.instr_def <> 0) then
If (chunk.effect_def2+chunk.effect2 = 0) then
If NOT (chunk.effect_def in [ef_SetModulatorVol,ef_SetCarrierVol]) then
begin
chunk.effect_def2 := ef_Extended;
chunk.effect2 := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol;
put_chunk(patt,temp2,temp3,chunk);
forcevol_cache[temp3] := 0;
_1st_ins_load[temp3] := FALSE;
end
else begin
chunk.effect_def2 := chunk.effect_def;
chunk.effect2 := chunk.effect;
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol;
put_chunk(patt,temp2,temp3,chunk);
forcevol_cache[temp3] := 0;
_1st_ins_load[temp3] := FALSE;
end;
prev_cache[temp3].effect_def := chunk.effect_def;
prev_cache[temp3].effect := chunk.effect;
prev_cache[temp3].effect_def2 := chunk.effect_def2;
prev_cache[temp3].effect2 := chunk.effect2;
If is_4op_chan(temp3) and
(temp3 in _4op_tracks_hi) then
begin
get_chunk(patt,temp2,SUCC(temp3),chunk3);
If (chunk.instr_def = 0) and (chunk3.instr_def <> 0) then
begin
If (ins_cache[temp3] <> 0) then
chunk.instr_def := ins_cache[temp3]
else chunk.instr_def := chunk3.instr_def;
put_chunk(patt,temp2,temp3,chunk);
end;
end;
If (chunk.effect_def = temp_ef_Arpeggio) then
begin
chunk2 := chunk;
chunk2.effect_def := ef_Arpeggio;
put_chunk(patt,temp2,temp3,chunk2);
end;
If (chunk.effect_def in [ef_SetModulatorVol,ef_SetCarrierVol]) and
(chunk.effect_def2 = ef_ForceInsVolume) then
begin
chunk2 := chunk;
chunk2.effect_def := chunk.effect_def2;
chunk2.effect := chunk.effect2;
chunk2.effect_def2 := chunk.effect_def;
chunk2.effect2 := chunk.effect;
put_chunk(patt,temp2,temp3,chunk2);
end;
end;
end;
begin { fix_fmk_commands }
FillChar(ins_cache,SizeOf(ins_cache),0);
FillChar(_1st_ins_load,SizeOf(_1st_ins_load),TRUE);
FillChar(_speed_table_fixed,SizeOf(_speed_table_fixed),FALSE);
FillChar(xfvolsld_cache,SizeOf(volsld_cache),0);
FillChar(volsld_cache,SizeOf(volsld_cache),0);
FillChar(slide_cache,SizeOf(slide_cache),0);
FillChar(misc_cache,SizeOf(misc_cache),0);
FillChar(arpg_cache,SizeOf(arpg_cache),0);
FillChar(forcevol_cache,SizeOf(forcevol_cache),0);
patts := '';
order := 0; patt := BYTE_NULL;
Repeat
If (songdata.pattern_order[order] >= $80) then Inc(order)
else
begin
patt := songdata.pattern_order[order];
fix_single_pattern(patt);
Inc(order);
patts := patts+CHR(patt);
end;
until (patt >= patterns) or (order > $7f);
For patt := 0 to PRED(patterns) do
If NOT (Pos(CHR(patt),patts) <> 0) then
fix_single_pattern(patt);
end;
procedure import_fin_instrument(inst: Byte; var data);
begin
With songdata.instr_data[inst] do
begin
fm_data.AM_VIB_EG_modulator := pBYTE(@data)[0];
fm_data.AM_VIB_EG_carrier := pBYTE(@data)[1];
fm_data.KSL_VOLUM_modulator := pBYTE(@data)[2];
fm_data.KSL_VOLUM_carrier := pBYTE(@data)[3];
fm_data.ATTCK_DEC_modulator := pBYTE(@data)[4];
fm_data.ATTCK_DEC_carrier := pBYTE(@data)[5];
fm_data.SUSTN_REL_modulator := pBYTE(@data)[6];
fm_data.SUSTN_REL_carrier := pBYTE(@data)[7];
fm_data.WAVEFORM_modulator := pBYTE(@data)[8] AND 7;
fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 7;
fm_data.FEEDBACK_FM := pBYTE(@data)[10] AND $0f;
end;
songdata.instr_data[inst].panning := 0;
songdata.instr_data[inst].fine_tune := 0;
end;
procedure fmk_file_loader;
type
tFMK_HEADER = Record
id: array[1..4] of Char; { FMK! }
songname: array[1..28] of Char; { Song name (28) }
composer: array[1..28] of Char; { Composer name (28) }
bytef4: Byte; { Value 244 (f4h), just for check. }
ftype: Byte; { File type {1=evolution 1, 2=evolution 2 }
glob_var: Byte; { Global variables, bits : 0 = stereo, 1 = opl3, 2 = rhythm }
{ 3 = 4.8 db tremolo 4 = 14 cent vibrato. }
base_spd: Byte; { Song basespeed, ticks / second. this version : fixed 50. }
init_spd: Byte; { Song initial speed. }
reserved: array[0..8] of Byte; { Reserved }
ordnum: Byte; { Length of song (order). }
insnum: Byte; { Number of instruments. }
patnum: Byte; { Number of patterns. }
trk_pan: array[1..5] of Byte; { Track stereo pan positions, bits 0-1, 2-3, 4-5, 6-7. }
{ value 0 = left 1 = both 2 = right, from track 1 to 18. }
trk_set: array[1..20] of Byte; { Track initial settings, 255=unused, bits : }
{ 0-2, type value: 0 = normal 1=hihat 2=cymbal 3=tom tom 4=snare 5=bass }
{ 6 = 4op 7=unused }
{ 3-7, OPL-channel number (1-18), 21 = none. }
{ ### if ftype=2 --> trk_set: 1..18; type_value: 0 = normal 6 = 4op 7=unused }
end;
const
id = 'FMK!';
const
_conv_fmk_pan: array[0..2] of Byte = (1,0,2);
type
tFIN_DATA = Record
dname: array[1..12] of Char;
iname: array[1..27] of Char;
idata: tFM_INST_DATA;
end;
var
f: File;
header: tFMK_HEADER;
order_list: array[0..254] of Byte;
paraptr_ins: array[1..99] of Word;
paraptr_pat: array[0..63] of Longint;
paraptr_msg: Word;
insdata: tFIN_DATA;
temp,temp2,fpos_bak: Longint;
pat,row,chan,
desc_rows: Byte;
note,ins,vol,cmd,info: Byte;
patlen,index: Word;
dscbuf: array[0..PRED(20*24)] of Char;
procedure import_fmk_event(pattern,line,channel,note,ins,vol,cmd,info: Byte);
var
chunk: tCHUNK;
begin
FillChar(chunk,SizeOf(chunk),0);
If (ins in [1..99]) then chunk.instr_def := ins;
Case note of
254: chunk.note := BYTE_NULL;
255: chunk.note := 0;
else If (note AND $0f in [1..12]) then
chunk.note := 12*(note SHR 4)+(note AND $0f)
end;
If (vol <> BYTE_NULL) then
begin
chunk.effect_def2 := ef_ForceInsVolume;
chunk.effect2 := 63-max(vol,63)
end;
Case CHR(cmd+ORD('A')-1) of
{ SET SPEED }
'A': If (info <> 0) then
begin
chunk.effect_def := ef_SetSpeed;
chunk.effect := info;
end;
{ JUMP TO ORDER }
'B': If (info <= 254) then
begin
chunk.effect_def := ef_PositionJump;
chunk.effect := info;
end;
{ CARRIER PARAM }
'C': Case info DIV 16 of
1: begin
chunk.effect_def := ef_Extended3;
chunk.effect := ef_ex3_SetMultipC*16+info MOD 16;
end;
2: begin
chunk.effect_def := ef_Extended3;
chunk.effect := ef_ex3_SetKslC*16+(info MOD 16) AND 3;
end;
3: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetAttckRateC*16+info MOD 16;
end;
4: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetDecayRateC*16+info MOD 16;
end;
5: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetSustnLevelC*16+info MOD 16;
end;
6: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetRelRateC*16+info MOD 16;
end;
7: begin
chunk.effect_def := ef_SetWaveform;
chunk.effect := info AND 7 SHL 4+$0f;
end;
8: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetFeedback*16+info AND 7;
end;
end;
{ VOLUME SLIDE }
'D': { VOLUME SLIDE DOWN }
Case info DIV 16 of
{ NORMAL }
0: If (info MOD 16 = 0) then chunk.effect_def := temp_ef_XFVSlide
else begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_VolSlideDnXF*16+info MOD 16
end;
{ FINE }
15: begin
chunk.effect_def := ef_VolSlideFine;
chunk.effect := info MOD 16;
end;
else
{ VOLUME SLIDE UP }
Case info MOD 16 of
{ NORMAL }
0: If (info DIV 16 = 0) then chunk.effect_def := temp_ef_XFVSlide
else begin
chunk.effect_def := ef_Extended2;
chunk.effect := ef_ex2_VolSlideUpXF*16+info DIV 16;
end;
{ FINE }
15: begin
chunk.effect_def := ef_VolSlideFine;
chunk.effect := info AND $0f0;
end;
end;
end;
{ SLIDE DOWN }
'E': Case info DIV 16 of
{ NORMAL }
0..14: begin
chunk.effect_def := ef_FSlideDown;
chunk.effect := info;
end;
{ FINE }
15: begin
chunk.effect_def := ef_FSlideDownFine;
chunk.effect := info AND $0f;
end;
end;
{ SLIDE UP }
'F': Case info DIV 16 of
{ NORMAL }
0..14: begin
chunk.effect_def := ef_FSlideUp;
chunk.effect := info;
end;
{ FINE }
15: begin
chunk.effect_def := ef_FSlideUpFine;
chunk.effect := info AND $0f;
end;
end;
{ TONE PORTAMENTO }
'G': begin
chunk.effect_def := ef_TonePortamento;
chunk.effect := info;
end;
{ VIBRATO }
'H': begin
chunk.effect_def := ef_Vibrato;
If (info <> 0) and (info DIV 16 = 0) then
chunk.effect := $10+info AND $0f
else If (info <> 0) and (info MOD 16 = 0) then
chunk.effect := info AND $0f0+1
else chunk.effect := info;
end;
{ RETRIG NOTE }
'I': begin
chunk.effect_def := ef_RetrigNote;
If (info <> 0) then chunk.effect := max(info*2,255);
end;
{ ARPEGGIO }
'J': begin
chunk.effect_def := temp_ef_Arpeggio;
chunk.effect := info;
end;
{ MODLATOR PARAM }
'M': Case info DIV 16 of
1: begin
chunk.effect_def := ef_Extended3;
chunk.effect := ef_ex3_SetMultipM*16+info MOD 16;
end;
2: begin
chunk.effect_def := ef_Extended3;
chunk.effect := ef_ex3_SetKslM*16+(info MOD 16) AND 3;
end;
3: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetAttckRateM*16+info MOD 16;
end;
4: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetDecayRateM*16+info MOD 16;
end;
5: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetSustnLevelM*16+info MOD 16;
end;
6: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetRelRateM*16+info MOD 16;
end;
7: begin
chunk.effect_def := ef_SetWaveform;
chunk.effect := $0f0+info AND 7;
end;
8: begin
chunk.effect_def := ef_Extended;
chunk.effect := ef_ex_SetFeedback*16+info AND 7;
end;
end;
{ SET VIBRATO/TREMOLO WAVEFORM }
'N': ;
{ BREAK PATTERN }
'P': If (info < 64) then
begin
chunk.effect_def := ef_PatternBreak;
chunk.effect := Str2num(Num2str(info,16),10);
end;
{ TREMOLO }
'R': begin
chunk.effect_def := ef_Tremolo;
If (info <> 0) and (info DIV 16 = 0) then
chunk.effect := $10+info AND $0f
else If (info <> 0) and (info MOD 16 = 0) then
chunk.effect := info AND $0f0+1
else chunk.effect := info;
end;
{ STEREO CONTROL }
'S': If (header.glob_var AND 1 = 1) then
begin
chunk.effect_def := ef_Extended;
Case info of
1: chunk.effect := ef_ex_SetPanningPos*16+1;
2: chunk.effect := ef_ex_SetPanningPos*16+0;
3: chunk.effect := ef_ex_SetPanningPos*16+2;
end;
end;
{ MODULATOR VOLUME }
'T': begin
chunk.effect_def := ef_SetModulatorVol;
chunk.effect := info AND $3f;
end;
{ CARRIER VOLUME }
'U': begin
chunk.effect_def := ef_SetCarrierVol;
chunk.effect := info AND $3f;
end;
end;
If (chunk.effect_def = 0) and (chunk.effect <> 0) then
chunk.effect := 0;
put_chunk(pattern,line,channel,chunk);
end;
begin
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and (header.id = id)) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
If (header.bytef4 <> $f4) or NOT (header.ftype in [1,2]) then
begin
CloseF(f);
EXIT;
end;
If (header.ftype = 2) then
begin
SeekF(f,SizeOf(header)-2);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
end;
If (header.ordnum <> 0) then
begin
BlockReadF(f,order_list,header.ordnum,temp);
If (IOresult <> 0) or (temp <> header.ordnum) then
begin
CloseF(f);
EXIT;
end;
end;
BlockReadF(f,paraptr_msg,SizeOf(paraptr_msg),temp);
If (IOresult <> 0) or (temp <> SizeOf(paraptr_msg)) then
begin
CloseF(f);
EXIT;
end;
fpos_bak := FilePos(f);
If (paraptr_msg <> 0) then
begin
SeekF(f,paraptr_msg);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,desc_rows,SizeOf(desc_rows),temp);
If (IOresult <> 0) or (temp <> SizeOf(desc_rows)) then
begin
CloseF(f);
EXIT;
end;
If (desc_rows <> 0) then
begin
BlockReadF(f,dscbuf,desc_rows*20,temp);
If (IOresult <> 0) or (temp <> desc_rows*20) then
begin
CloseF(f);
EXIT;
end;
end;
end;
SeekF(f,fpos_bak);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
If (header.insnum <> 0) then
begin
BlockReadF(f,paraptr_ins,header.insnum*2,temp);
If (IOresult <> 0) or (temp <> header.insnum*2) then
begin
CloseF(f);
EXIT;
end;
end;
If (header.patnum <> 0) then
begin
BlockReadF(f,paraptr_pat,header.patnum*4,temp);
If (IOresult <> 0) or (temp <> header.patnum*4) then
begin
CloseF(f);
EXIT;
end;
end;
init_songdata;
load_flag := 0;
If (header.init_spd <> 0) then speed := header.init_spd
else speed := 1;
If (header.base_spd <> 0) then tempo := header.base_spd
else tempo := 50;
songdata.tempo := tempo;
songdata.speed := speed;
songdata.songname := truncate_string(header.songname);
songdata.composer := truncate_string(header.composer);
songdata.common_flag := songdata.common_flag OR 1;
songdata.common_flag := songdata.common_flag OR 2;
songdata.common_flag := songdata.common_flag OR $80;
For temp := 18 downto 1 do
If NOT (header.trk_set[temp] AND 7 = 7) then BREAK;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := temp
else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18;
For temp2 := 1 to temp do
If (header.trk_set[temp2] AND 7 = 6) then
Case temp2 of
1,2: songdata.flag_4op := songdata.flag_4op OR 1;
3,4: songdata.flag_4op := songdata.flag_4op OR 2;
5,6: songdata.flag_4op := songdata.flag_4op OR 4;
10,11: songdata.flag_4op := songdata.flag_4op OR 8;
12,13: songdata.flag_4op := songdata.flag_4op OR $10;
14,15: songdata.flag_4op := songdata.flag_4op OR $20;
end;
If (header.glob_var AND 1 = 1) then
songdata.common_flag := songdata.common_flag OR $20;
If (header.glob_var SHR 3 AND 1 = 1) then
songdata.common_flag := songdata.common_flag OR 8;
If (header.glob_var SHR 4 AND 1 = 1) then
songdata.common_flag := songdata.common_flag OR $10;
import_old_flags;
If (header.glob_var AND 1 = 1) then
begin
Inc(songdata.lock_flags[1], _conv_fmk_pan[header.trk_pan[1] AND 3]);
Inc(songdata.lock_flags[2], _conv_fmk_pan[header.trk_pan[1] SHR 2 AND 3]);
Inc(songdata.lock_flags[3], _conv_fmk_pan[header.trk_pan[1] SHR 4 AND 3]);
Inc(songdata.lock_flags[4], _conv_fmk_pan[header.trk_pan[1] SHR 6 AND 3]);
Inc(songdata.lock_flags[5], _conv_fmk_pan[header.trk_pan[2] AND 3]);
Inc(songdata.lock_flags[6], _conv_fmk_pan[header.trk_pan[2] SHR 2 AND 3]);
Inc(songdata.lock_flags[7], _conv_fmk_pan[header.trk_pan[2] SHR 4 AND 3]);
Inc(songdata.lock_flags[8], _conv_fmk_pan[header.trk_pan[2] SHR 6 AND 3]);
Inc(songdata.lock_flags[9], _conv_fmk_pan[header.trk_pan[3] AND 3]);
Inc(songdata.lock_flags[10],_conv_fmk_pan[header.trk_pan[3] SHR 2 AND 3]);
Inc(songdata.lock_flags[11],_conv_fmk_pan[header.trk_pan[3] SHR 4 AND 3]);
Inc(songdata.lock_flags[12],_conv_fmk_pan[header.trk_pan[3] SHR 6 AND 3]);
Inc(songdata.lock_flags[13],_conv_fmk_pan[header.trk_pan[4] AND 3]);
Inc(songdata.lock_flags[14],_conv_fmk_pan[header.trk_pan[4] SHR 2 AND 3]);
Inc(songdata.lock_flags[15],_conv_fmk_pan[header.trk_pan[4] SHR 4 AND 3]);
Inc(songdata.lock_flags[16],_conv_fmk_pan[header.trk_pan[4] SHR 6 AND 3]);
Inc(songdata.lock_flags[17],_conv_fmk_pan[header.trk_pan[5] AND 3]);
Inc(songdata.lock_flags[18],_conv_fmk_pan[header.trk_pan[5] SHR 2 AND 3]);
end;
For temp := 1 to max(header.ordnum,128) do
Case order_list[temp-1] of
255: songdata.pattern_order[temp-1] := $80;
else songdata.pattern_order[temp-1] := order_list[temp-1];
end;
For temp := 1 to header.insnum do
begin
SeekF(f,paraptr_ins[temp]);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,insdata,SizeOf(insdata),temp2);
If (IOresult <> 0) or (temp2 <> SizeOf(insdata)) then
begin
CloseF(f);
EXIT;
end;
If (truncate_string(insdata.iname) <> '') then
songdata.instr_names[temp] :=
Copy(songdata.instr_names[temp],1,9)+
Copy(truncate_string(insdata.iname),1,32)
else
songdata.instr_names[temp] :=
Copy(songdata.instr_names[temp],1,9)+
truncate_string(insdata.dname);
import_fin_instrument(temp,insdata.idata);
end;
For pat := 0 to PRED(header.patnum) do
begin
SeekF(f,paraptr_pat[pat]);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
If (paraptr_pat[pat] = 0) then CONTINUE;
BlockReadF(f,patlen,SizeOf(patlen),temp2);
If (temp2 <> SizeOf(patlen)) then
begin
CloseF(f);
EXIT;
end;
If (patlen = 0) then CONTINUE;
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,buf1,patlen,temp2);
index := 0;
row := 0;
Repeat
If (buf1[index] <> 0) then
begin
note := BYTE_NULL;
ins := 0;
vol := BYTE_NULL;
cmd := 0;
info := 0;
temp := buf1[index];
Inc(index);
chan := SUCC(temp AND 31);
If (temp OR $20 = temp) then
begin
note := buf1[index];
Inc(index);
ins := buf1[index];
Inc(index);
end;
If (temp OR $40 = temp) then
begin
vol := buf1[index];
Inc(index);
end;
If (temp OR $80 = temp) then
begin
cmd := buf1[index];
Inc(index);
info := buf1[index];
Inc(index);
end;
If (PRED(chan) in [1..18]) then
import_fmk_event(pat,row,PRED(chan),note,ins,vol,cmd,info);
end
else
begin
Inc(row);
Inc(index);
end;
until (row = 64);
end;
fix_fmk_commands(header.patnum);
CloseF(f);
songdata_title := NameOnly(songdata_source);
load_flag := 13;
end;
procedure import_sat_instrument(inst: Byte; var data);
begin
With songdata.instr_data[inst] do
begin
fm_data.FEEDBACK_FM := pBYTE(@data)[0] AND $0f;
fm_data.AM_VIB_EG_modulator := pBYTE(@data)[1];
fm_data.AM_VIB_EG_carrier := pBYTE(@data)[2];
fm_data.ATTCK_DEC_modulator := pBYTE(@data)[3];
fm_data.ATTCK_DEC_carrier := pBYTE(@data)[4];
fm_data.SUSTN_REL_modulator := pBYTE(@data)[5];
fm_data.SUSTN_REL_carrier := pBYTE(@data)[6];
fm_data.WAVEFORM_modulator := pBYTE(@data)[7] AND 3;
fm_data.WAVEFORM_carrier := pBYTE(@data)[8] AND 3;
fm_data.KSL_VOLUM_modulator := pBYTE(@data)[9];
fm_data.KSL_VOLUM_carrier := pBYTE(@data)[10];
end;
songdata.instr_data[inst].panning := 0;
songdata.instr_data[inst].fine_tune := 0;
end;
function import_sat_instrument_name(var data; inst: Byte): String;
var
temp1: Word;
temp2: Byte;
temp3: String;
begin
temp1 := 0;
temp2 := 0;
temp3 := '';
While (temp1 < 496) do
begin
If (pBYTE(@data)[temp1] = BYTE(#16)) then Inc(temp2);
Inc(temp1);
If (temp2 = inst+1) then
begin
While (pBYTE(@data)[temp1] in [$20..$0ff]) and
(Length(temp3) < 22) do
begin
temp3 := temp3+CHR(pBYTE(@data)[temp1]);
Inc(temp1);
end;
BREAK;
end;
end;
import_sat_instrument_name := temp3;
end;
procedure import_sa2_effect(effect,def1,def2: Byte;
var out1,out2: Byte); forward;
procedure sat_file_loader;
type
tHEADER = Record { version 1 }
ident: array[1..4] of Char; { ident_string }
vernm: Byte; { version_number (1) }
instt: array[0..$1e] of { 31_instruments }
array[0..$0a] of Byte;
instn: array[0..495] of Byte; { 31_instrument_names }
order: array[0..254] of Byte; { pattern_order }
nopat: Word; { number of patterns }
snlen: Byte; { song_length }
rspos: Byte; { restart_position }
calls: Word; { calls_per_second }
end;
type
tHEADR2 = Record { version 6 }
ident: array[1..4] of Char; { ident_string }
vernm: Byte; { version_number (1) }
instt: array[0..$1e] of { 31_instruments }
array[0..$0e] of Byte;
instn: array[0..495] of Byte; { 31_instrument_names }
order: array[0..$7f] of Byte; { pattern_order }
nopat: Word; { number of patterns }
snlen: Byte; { song_length }
rspos: Byte; { restart_position }
calls: Word; { calls_per_second }
arpgd: array[1..512] of Byte; { arpeggio_data }
end;
const
id = 'SAdT';
var
f: File;
header: tHEADER;
headr2: tHEADR2;
SATver: Byte;
temp,tmp2,tmp3,temp2,temp3,
temp4,temp5: Longint;
byte1,byte2,byte3,byte4,byte5,note_inc: Byte;
procedure import_sat_event(pattern,line,channel,
byte1,byte2,byte3,byte4,byte5: Byte);
var
chunk: tCHUNK;
begin
FillChar(chunk,SizeOf(chunk),0);
If (byte2 in [1..31]) then chunk.instr_def := byte2;
If (byte1 in [1..12*8+1]) then chunk.note := byte1+note_inc;
import_sa2_effect(byte3,byte4,byte5,chunk.effect_def,chunk.effect);
If (chunk.effect_def = ef_Extended) and
(chunk.effect = ef_ex_ExtendedCmd2*16) and (chunk.note = 0) then
begin
chunk.note := BYTE_NULL;
chunk.effect_def := 0;
chunk.effect := 0;
end;
put_chunk(pattern,line,channel,chunk);
end;
var
absolute: Longint;
function get_byte(var pos: Longint): Byte;
begin
If (pos = SizeOf(buf1)-5) then
begin
If NOT (absolute > SizeOf(buf1)-5) then Move(buf3,buf1,SizeOf(buf3)-5)
else Move(buf4,buf1,SizeOf(buf4)-5);
pos := 0;
end;
get_byte := buf1[pos];
Inc(pos);
Inc(absolute);
end;
begin
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and (header.ident = id)) then
begin
CloseF(f);
EXIT;
end;
If NOT (header.vernm in [1,5,6]) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
SATver := header.vernm;
If (SATver in [5,6]) then
begin
SeekF(f,0);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,headr2,SizeOf(headr2),temp);
If (temp <> SizeOf(headr2)) then
begin
CloseF(f);
EXIT;
end;
end;
temp5 := (FileSize(f)-temp) DIV (64*9*5);
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,buf1,SizeOf(buf1)-5,temp);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
tmp2 := WORD_NULL;
If (temp = SizeOf(buf1)-5) then
begin
FillChar(buf3,SizeOf(buf3),0);
BlockReadF(f,buf3,SizeOf(buf3)-5,tmp2);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
end;
tmp3 := WORD_NULL;
If (tmp2 = SizeOf(buf3)-5) then
begin
FillChar(buf4,SizeOf(buf4),0);
BlockReadF(f,buf4,SizeOf(buf4)-5,tmp3);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
end;
init_songdata;
load_flag := 0;
songdata.common_flag := songdata.common_flag OR 8;
songdata.common_flag := songdata.common_flag OR $10;
import_old_flags;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 9
else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9;
For temp := 1 to 20 do
songdata.lock_flags[temp] := songdata.lock_flags[temp] OR 4 OR 8;
If (SATver = 1) then
begin
speed := 6;
If (header.calls < 255) then tempo := header.calls
else tempo := 255;
songdata.tempo := tempo;
songdata.speed := speed;
For temp := 0 to max(header.snlen-1,127) do
If (temp < 128) and (header.order[temp] in [0..63]) then
songdata.pattern_order[temp] := header.order[temp];
If (header.rspos < 128) and (SUCC(temp) < 128) then
songdata.pattern_order[SUCC(temp)] := $80+header.rspos;
temp5 := max(temp5,header.nopat);
For temp := 0 to $1e do
begin
import_sat_instrument(temp+1,header.instt[temp]);
songdata.instr_names[temp+1] :=
Copy(songdata.instr_names[temp+1],1,9)+
truncate_string(import_sat_instrument_name(header.instn,temp));
end;
end
else
begin
speed := 6;
If (headr2.calls < 255) then tempo := headr2.calls
else tempo := 255;
songdata.tempo := tempo;
songdata.speed := speed;
For temp := 0 to headr2.snlen-1 do
If (temp < 128) and (headr2.order[temp] in [0..63]) then
songdata.pattern_order[temp] := headr2.order[temp];
If (headr2.rspos < 128) and (SUCC(temp) < 128) then
songdata.pattern_order[SUCC(temp)] := $80+headr2.rspos;
temp5 := max(temp5,headr2.nopat);
For temp := 0 to $1e do
begin
import_sat_instrument(temp+1,headr2.instt[temp]);
songdata.instr_names[temp+1] :=
Copy(songdata.instr_names[temp+1],1,9)+
truncate_string(import_sat_instrument_name(headr2.instn,temp));
end;
end;
temp := 0;
absolute := 0;
Case SATver of
1: note_inc := 24;
5: note_inc := 12;
6: note_inc := 0;
end;
For temp2 := 0 to temp5-1 do
For temp3 := 0 to 63 do
For temp4 := 1 to 9 do
begin
byte1 := get_byte(temp);
byte2 := get_byte(temp);
byte3 := get_byte(temp);
byte4 := get_byte(temp);
byte5 := get_byte(temp);
import_sat_event(temp2,temp3,temp4,byte1,byte2,byte3,byte4,byte5);
end;
CloseF(f);
songdata_title := NameOnly(songdata_source);
load_flag := 14;
end;
function _sal(op1,op2: Integer): Byte;
begin
_sal := op1 SHL op2;
end;
function _sar(op1,op2: Integer): Byte;
begin
_sar := op1 SHR op2;
end;
procedure import_sa2_effect(effect,def1,def2: Byte;
var out1,out2: Byte);
begin
Case effect of
{ NORMAL PLAY OR ARPEGGIO }
$00: begin
out1 := ef_Arpeggio;
out2 := def1*16+def2;
end;
{ SLIDE UP }
$01: begin
out1 := ef_FSlideUp;
out2 := def1*16+def2;
end;
{ SLIDE DOWN }
$02: begin
out1 := ef_FSlideDown;
out2 := def1*16+def2;
end;
{ TONE PORTAMENTO }
$03: begin
out1 := ef_TonePortamento;
out2 := def1*16+def2;
end;
{ VIBRATO }
$04: begin
out1 := ef_Vibrato;
out2 := def1*16+def2;
end;
{ TONE PORTAMENTO + VOLUME SLIDE }
$05: If (def1+def2 <> 0) then
If (def1 in [1..15]) then
begin
out1 := ef_TPortamVolSlide;
out2 := min(_sar(def1,2),1)*16;
end
else begin
out1 := ef_TPortamVolSlide;
out2 := min(_sar(def2,2),1);
end
else
begin
out1 := ef_TPortamVolSlide;
out2 := def1*16+def2;
end;
{ VIBRATO + VOLUME SLIDE }
$06: If (def1+def2 <> 0) then
If (def1 in [1..15]) then
begin
out1 := ef_VibratoVolSlide;
out2 := min(_sar(def1,2),1)*16;
end
else begin
out1 := ef_VibratoVolSlide;
out2 := min(_sar(def2,2),1);
end
else
begin
out1 := ef_VibratoVolSlide;
out2 := def1*16+def2;
end;
{ RELEASE SUSTAINING SOUND }
$08: begin
out1 := ef_Extended;
out2 := ef_ex_ExtendedCmd2*16+0;
end;
{ VOLUME SLIDE }
$0a: If (def1+def2 <> 0) then
If (def1 in [1..15]) then
begin
out1 := ef_VolSlide;
out2 := min(_sar(def1,2),1)*16;
end
else begin
out1 := ef_VolSlide;
out2 := min(_sar(def2,2),1);
end
else
begin
out1 := ef_VolSlide;
out2 := def1*16+def2;
end;
{ POSITION JUMP }
$0b: If (def1*16+def2 < 128) then
begin
out1 := ef_PositionJump;
out2 := def1*16+def2;
end;
{ SET VOLUME }
$0c: begin
out1 := ef_SetInsVolume;
out2 := def1*16+def2;
If (out2 > 63) then out2 := 63;
end;
{ PATTERN BREAK }
$0d: If (def1*16+def2 < 64) then
begin
out1 := ef_PatternBreak;
out2 := def1*16+def2;
end;
{ SET SPEED }
$0f: If (def1*16+def2 < $20) then
begin
out1 := ef_SetSpeed;
out2 := def1*16+def2;
end
else If (def1 < 16) and (def2 < 16) then
begin
out1 := ef_SetTempo;
out2 := Round((def1*16+def2)/2.5);
end;
else begin
out1 := 0;
out2 := 0;
end;
end;
end;
procedure sa2_file_loader;
type
tHEADER = Record
ident: array[1..4] of Char; { These bytes mark a song }
vernm: Byte; { Version number (9) }
instt: array[0..$1e] of { 31 instruments }
array[0..$0e] of Byte;
instn: array[0..495] of Byte; { 31_instrument_names }
order: array[0..$7f] of Byte; { Pattern order }
nopat: Word; { Number of patterns }
snlen: Byte; { Length of song }
rspos: Byte; { Restart position }
snbpm: Word; { BPM }
arpgd: array[1..512] of Byte; { Arpeggio data (list+commands) }
ordr2: array[0..63] of { Track order }
array[1..9] of Byte;
chans: Word; { Active channels }
end;
const
id = 'SAdT';
var
f: File;
header: tHEADER;
temp,temp2,temp3,temp4,temp5: Longint;
procedure import_sa2_event(pattern,line,channel,
byte1,byte2,byte3: Byte);
var
chunk: tCHUNK;
temp: Byte;
begin
FillChar(chunk,SizeOf(chunk),0);
temp := (byte1 AND 1) SHL 4 +(byte2 SHR 4);
If (temp in [1..31]) then chunk.instr_def := temp;
If (byte1 SHR 1 in [1..12*8+1]) then chunk.note := (byte1 SHR 1);
import_sa2_effect(byte2 AND $0f,byte3 SHR 4,byte3 AND $0f,
chunk.effect_def,chunk.effect);
If (chunk.effect_def = ef_Extended) and
(chunk.effect = ef_ex_ExtendedCmd2*16) and (chunk.note = 0) then
begin
chunk.note := BYTE_NULL;
chunk.effect_def := 0;
chunk.effect := 0;
end;
put_chunk(pattern,line,channel,chunk);
end;
begin { sa2_file_loader }
{$i-}
Assign(f,songdata_source);
ResetF(f);
{$i+}
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
BlockReadF(f,header,SizeOf(header),temp);
If NOT ((temp = SizeOf(header)) and (header.ident = id)) then
begin
CloseF(f);
EXIT;
end;
If NOT (header.vernm in [8,9]) then
begin
CloseF(f);
EXIT;
end;
load_flag := $7f;
If (header.vernm = 8) then
begin
SeekF(f,FilePos(f)-2);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
end;
FillChar(buf1,SizeOf(buf1),0);
BlockReadF(f,buf1,SizeOf(buf1)-3,temp);
If (IOresult <> 0) then
begin
CloseF(f);
EXIT;
end;
init_songdata;
load_flag := 0;
songdata.common_flag := songdata.common_flag OR 8;
songdata.common_flag := songdata.common_flag OR $10;
import_old_flags;
songdata.patt_len := 64;
If adjust_tracks then songdata.nm_tracks := 9
else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9;
For temp := 1 to 20 do
songdata.lock_flags[temp] := songdata.lock_flags[temp] OR 4 OR 8;
speed := 6;
If (Round(header.snbpm/2.5) < 255) then tempo := Round(header.snbpm/2.5)
else tempo := 255;
songdata.tempo := tempo;
songdata.speed := speed;
temp2 := 0;
temp3 := 0;
temp4 := 1;
Repeat
While (header.ordr2[temp2][temp4] = 0) and
(temp2 <= header.nopat-1) do
begin
Inc(temp4);
If (temp4 > 9) then begin temp4 := 1; Inc(temp2); end;
end;
If (temp2 <= header.nopat-1) then
begin
temp5 := 64*3*(header.ordr2[temp2][temp4]-1)+temp3*3;
import_sa2_event(temp2,temp3,temp4,buf1[temp5],
buf1[temp5+1],
buf1[temp5+2]);
Inc(temp3);
If (temp3 > $3f) then
begin
temp3 := 0;
If (temp4 < 9) then Inc(temp4)
else begin temp4 := 1; Inc(temp2); end;
end;
end;
until (temp2 > header.nopat-1);
For temp := 0 to header.snlen-1 do
If (temp < 128) and (header.order[temp] in [0..63]) then
songdata.pattern_order[temp] := header.order[temp];
If (header.rspos < 128) and (SUCC(temp) < 128) then
songdata.pattern_order[SUCC(temp)] := $80+header.rspos;
For temp := 0 to $1e do
begin
import_sat_instrument(temp+1,header.instt[temp]);
songdata.instr_names[temp+1] := Copy(songdata.instr_names[temp+1],1,9)+
truncate_string(import_sat_instrument_name(header.instn,temp));
end;
CloseF(f);
songdata_title := NameOnly(songdata_source);
load_flag := 15;
end;
adlibtracker2-2.4.24/adt2play/a2fileio.pas 0000644 0000000 0000000 00000005225 13411003760 016730 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
unit A2fileIO;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
interface
const
_debug_str_: String = '';
const
GENERIC_IO_BUFFER_SIZE = 1500*1024; // 1.5 MB I/O Buffer
type
pGENERIC_IO_BUFFER = ^tGENERIC_IO_BUFFER;
tGENERIC_IO_BUFFER = array[0..PRED(GENERIC_IO_BUFFER_SIZE)] of Byte;
var
buf1: tGENERIC_IO_BUFFER;
buf2: tGENERIC_IO_BUFFER;
buf3: array[WORD] of Byte;
buf4: array[WORD] of Byte;
const
adjust_tracks: Boolean = TRUE;
accurate_conv: Boolean = TRUE;
fix_c_note_bug: Boolean = TRUE;
var
songdata_source: String;
songdata_title: String;
load_flag: Byte;
procedure a2m_file_loader;
procedure a2t_file_loader;
procedure amd_file_loader;
procedure cff_file_loader;
procedure dfm_file_loader;
procedure mtk_file_loader;
procedure rad_file_loader;
procedure s3m_file_loader;
procedure fmk_file_loader;
procedure sat_file_loader;
procedure sa2_file_loader;
procedure hsc_file_loader;
procedure ResetF(var f: File);
procedure BlockReadF(var f: File; var data; size: Longint; var bytes_read: Longint);
procedure SeekF(var f: File; fpos: Longint);
procedure CloseF(var f: File);
implementation
uses
DOS,
A2player,A2depack,
StringIO,ParserIO;
{$i iloaders.inc}
procedure ResetF(var f: File);
var
fattr: Word;
begin
_debug_str_:= 'ADT2SYS.PAS:ResetF_RW';
GetFAttr(f,fattr);
If (fattr AND ReadOnly = ReadOnly) then FileMode := 0;
{$i-}
Reset(f,1);
{$i+}
end;
procedure BlockReadF(var f: File; var data; size: Longint; var bytes_read: Longint);
begin
_debug_str_:= 'ADT2SYS.PAS:BlockReadF';
{$i-}
BlockRead(f,data,size,bytes_read);
{$i+}
If (IOresult <> 0) then bytes_read := 0;
end;
procedure SeekF(var f: File; fpos: Longint);
begin
_debug_str_:= 'ADT2SYS.PAS:SeekF';
{$i-}
Seek(f,fpos);
{$i+}
end;
procedure CloseF(var f: File);
begin
_debug_str_:= 'ADT2SYS.PAS:CloseF';
{$i-}
Close(f);
{$i+}
If (IOresult <> 0) then ;
end;
end.
adlibtracker2-2.4.24/typcons1.inc 0000644 0000000 0000000 00000113114 13411003760 015261 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
const
NULL = $0ffffffff;
BYTE_NULL = BYTE(NULL);
WORD_NULL = WORD(NULL);
DWORD_NULL = LONGINT(NULL);
const
FFVER_A2M = 14;
FFVER_A2T = 14;
FFVER_A2I = 10;
FFVER_A2F = 2;
FFVER_A2P = 11;
FFVER_A2B = 10;
FFVER_A2W = 3;
const
GENERIC_IO_BUFFER_SIZE = 1500*1024; // 1.5MB I/O Buffer
type
pGENERIC_IO_BUFFER = ^tGENERIC_IO_BUFFER;
tGENERIC_IO_BUFFER = array[0..PRED(GENERIC_IO_BUFFER_SIZE)] of Byte;
type
tFM_INST_DATA = Record
AM_VIB_EG_modulator,
AM_VIB_EG_carrier,
KSL_VOLUM_modulator,
KSL_VOLUM_carrier,
ATTCK_DEC_modulator,
ATTCK_DEC_carrier,
SUSTN_REL_modulator,
SUSTN_REL_carrier,
WAVEFORM_modulator,
WAVEFORM_carrier,
FEEDBACK_FM: Byte;
end;
type
tADTRACK2_INS = Record
fm_data: tFM_INST_DATA;
panning: Byte;
fine_tune: Shortint;
perc_voice: Byte;
end;
type
tOLD_ADTRACK2_INS = Record
fm_data: tFM_INST_DATA;
panning: Byte;
fine_tune: Shortint;
end;
type
tARPEGGIO_TABLE = Record
length,
speed,
loop_begin,
loop_length,
keyoff_pos: Byte;
data: array[1..255] of Byte;
end;
type
tVIBRATO_TABLE = Record
length,
speed,
delay,
loop_begin,
loop_length,
keyoff_pos: Byte;
data: array[1..255] of Shortint;
end;
type
tREGISTER_TABLE_DEF = Record
fm_data: tFM_INST_DATA;
freq_slide: Smallint;
panning: Byte;
duration: Byte;
end;
type
tREGISTER_TABLE = Record
length,
loop_begin,
loop_length,
keyoff_pos,
arpeggio_table,
vibrato_table: Byte;
data: array[1..255] of tREGISTER_TABLE_DEF;
end;
type
tMACRO_TABLE = Record
arpeggio: tARPEGGIO_TABLE;
vibrato: tVIBRATO_TABLE;
end;
type
tARP_VIB_MACRO_TABLE = array[1..255] of tMACRO_TABLE;
type
tFM_PARAMETER_TABLE = Record
adsrw_car,
adsrw_mod: Record
attck,dec,sustn,rel,
wform: Byte;
end;
connect,
feedb,
multipM,kslM,tremM,vibrM,ksrM,sustM,
multipC,kslC,tremC,vibrC,ksrC,sustC: Byte;
end;
type
tDIS_FMREG_COL = array[0..27] of Boolean;
type
tINS_4OP_FLAGS = Record
num_4op: Byte;
idx_4op: array[1..128] of Byte;
end;
type
pOLD_FIXED_SONGDATA = ^tOLD_FIXED_SONGDATA;
tOLD_FIXED_SONGDATA = Record
songname: String[42];
composer: String[42];
instr_names: array[1..250] of String[32];
instr_data: array[1..250] of tOLD_ADTRACK2_INS;
pattern_order: array[0..$7f] of Byte;
tempo: Byte;
speed: Byte;
common_flag: Byte;
end;
const
MB_SIGNATURE = 'MB_1'; // Message Board v1.0
MB_HSIZE = 50; // 50x20 chr
MB_VSIZE = 20;
type
pMESSAGE_BOARD_DATA = ^tMESSAGE_BOARD_DATA;
tMESSAGE_BOARD_DATA = Record
signature: array[0..3] of Char;
data: array[1..MB_VSIZE] of String[MB_HSIZE];
end;
type
pFIXED_SONGDATA = ^tFIXED_SONGDATA;
tFIXED_SONGDATA = Record
songname: String[42];
composer: String[42];
instr_names: array[1..255] of String[42];
instr_data: array[1..255] of tADTRACK2_INS;
instr_macros: array[1..255] of tREGISTER_TABLE;
macro_table: tARP_VIB_MACRO_TABLE;
pattern_order: array[0..$7f] of Byte;
tempo: Byte;
speed: Byte;
common_flag: Byte;
patt_len: Word;
nm_tracks: Byte;
macro_speedup: Word;
flag_4op: Byte;
lock_flags: array[1..20] of Byte;
pattern_names: array[0..$7f] of String[42];
dis_fmreg_col: array[1..255] of tDIS_FMREG_COL;
ins_4op_flags: tINS_4OP_FLAGS;
reserved_data: array[0..PRED(1024)] of Byte;
bpm_data: Record
rows_per_beat: Byte;
tempo_finetune: Integer;
end;
end;
type
tOLD_CHUNK = Record
note: Byte;
instr_def: Byte;
effect_def: Byte;
effect: Byte;
end;
type
tCHUNK = Record
note: Byte;
instr_def: Byte;
effect_def: Byte;
effect: Byte;
effect_def2: Byte;
effect2: Byte;
end;
type
tOLD_VARIABLE_DATA1 = array[0..$0f] of array[0..$3f] of
array[1..9] of tOLD_CHUNK;
type
tOLD_VARIABLE_DATA2 = array[0..7] of array[1..18] of
array[0..$3f] of tOLD_CHUNK;
type
tVARIABLE_DATA = array[0..7] of array[1..20] of
array[0..$0ff] of tCHUNK;
type
tPATTERN_DATA = array[0..15] of tVARIABLE_DATA;
type
tCOPY_OBJECT = (objNone,
objPatternDef,objPatternTable,
objInstrument,objInstrumentBank,
objNote,objInstrumentDef,objEffect,objEffect2,
objLine,objTrack,objPattern,objMarkedBlock,
objMacroTableLine,objMacroTableColumn,objMacroTable,
objInstrumentWithMacros);
type
tMACRO_TABLE_TYPE = (mttFM_reg_table,mttArpeggio_table,mttVibrato_table);
type
tCLIPBOARD = Record
object_type: tCOPY_OBJECT;
block_hsize: Byte;
block_vsize: Byte;
pattern_order: array[0..$7f] of Byte;
pattern: array[1..20] of array[0..$0ff] of tCHUNK;
instrument: Record
names: array[1..255] of String[32];
data: array[1..255] of tADTRACK2_INS;
macros: array[1..255] of tREGISTER_TABLE;
arpvib: array[1..255] of tMACRO_TABLE;
dis_fmreg_col: array[1..255] of tDIS_FMREG_COL;
end;
mcrtab_type: tMACRO_TABLE_TYPE;
fmreg_table: tREGISTER_TABLE;
macro_table: tMACRO_TABLE;
fmtab_def_typ: Byte;
_string: String;
end;
type
tDECAY_BAR = Record
dir1: Integer;
dir2: Integer;
lvl1: Real;
lvl2: Real;
end;
type
tVOLUM_BAR = Record
dir: Integer;
lvl: Real;
end;
type
tPLAY_STATUS = (isPlaying,isPaused,isStopped);
type
{$IFDEF GO32V2}
tRGB = Record r,g,b: Byte end;
{$ELSE}
tRGB = Record r,g,b,a: Byte end;
{$ENDIF}
type
tByteSet = Set of Byte;
const
INSTRUMENT_SIZE = SizeOf(tADTRACK2_INS);
CHUNK_SIZE = SizeOf(tCHUNK);
PATTERN_SIZE = 20*256*CHUNK_SIZE;
const
status_layout: array[tPLAY_STATUS] of String[10] = ('PLAYiNG ',
'PAUSED ',
'STOPPED ');
{$IFDEF UNIX}
const
PATHSEP: Char = '/';
WILDCARD_ASTERISK: String = '*';
{$ELSE}
const
PATHSEP: Char = '\';
WILDCARD_ASTERISK: String = '*.*';
{$ENDIF}
const
kF1 = $3b00; kLEFT = $4b00; kENTER = $1c0d; kWeird = $2960;
kF2 = $3c00; kShLEFT = $4b34; kCtENTR = $1c0a; kCtrlE = $1205;
kShF2 = $5500; kCtLEFT = $7300; kESC = $011b; kCtrlG = $2207;
kF3 = $3d00; kRIGHT = $4d00; kTAB = $0f09; kCtrlQ = $1011;
kShF3 = $5600; kShRGHT = $4d36; kShTAB = $0f00; kCtLbr = $1a1b;
kF4 = $3e00; kCtRGHT = $7400; kSPACE = $3920; kCtRbr = $1b1d;
kF5 = $3f00; kUP = $4800; kBkSPC = $0e08; kCtrlF3 = $6000;
kShF5 = $5800; kNPUp = $4838; kNPastr = $372a; kAltV = $2f00;
kF6 = $4000; kDOWN = $5000; kNPplus = $4e2b; kAstrsk = $092a;
kShF6 = $5900; kNPDown = $5032; kNPmins = $4a2d; kNPins = $5230;
kF7 = $4100; kPgUP = $4900; kAlt1 = $7800; kNPdel = $532e;
kF8 = $4200; kNPPgUP = $4939; kAlt2 = $7900; kCHastr = $092a;
kShF8 = $5b00; kCtPgUP = $8400; kAlt3 = $7a00; kCtrlP = $1910;
kF9 = $4300; kPgDOWN = $5100; kAlt4 = $7b00; kCtBkSp = $0e7f;
kShF9 = $5c00; kNPPgDN = $5133; kAlt5 = $7c00; kAltF5 = $6c00;
kF10 = $4400; kCtPgDN = $7600; kAlt6 = $7d00; kAltF6 = $6d00;
kCtrlB = $3002; kHOME = $4700; kAlt7 = $7e00; kAltF8 = $6f00;
kCtrlC = $2e03; kNPHOME = $4737; kAlt8 = $7f00; kAltF9 = $7000;
kCtrlD = $2004; kCtHOME = $7700; kAlt9 = $8000; kCtrlY = $1519;
kCtrlF = $2106; kEND = $4f00; kAlt0 = $8100; kAltE = $1200;
kCtrlI = $1709; kNPEND = $4f31; kAltB = $3000; kAltZ = $2c00;
kCtrlK = $250b; kCtEND = $7500; kAltC = $2e00; kAltI = $1700;
kCtrlM = $320d; kINSERT = $5200; kAltD = $2000; kAltH = $2300;
kCtrlN = $310e; kDELETE = $5300; kAltF = $2100; kAltU = $1600;
kCtrlO = $180f; kCtrlL = $260c; kAltK = $2500; kAltG = $2200;
kCtrlV = $2f16; kCtrlS = $1f13; kAltM = $3200;
kCtrlX = $2d18; kCtrlA = $1e01; kAltN = $3100;
kCtrlZ = $2c1a; kAltF2 = $6900; kAltO = $1800;
kAltL = $2600; kAltA = $1e00; kAltP = $1900;
kCtrlF2 = $5f00; kCHplus = $0d2b; kAltQ = $1000;
kAltX = $2d00; kCHmins = $0c2d; kAltR = $1300;
kCtrlT = $1414; kCHlbrk = $1a5b; kAltS = $1f00;
kCtrlR = $1312; kCHrbrk = $1b5d; kAltT = $1400;
kCtrlW = $1117; kCtrlH = $2308; kAltW = $1100;
kSlash = $352f; kCtrlF8 = $6500;
kSlashR = $2b5c; kCtrlF9 = $6600;
const
SC_ESCAPE = $01;
SC_1 = $02;
SC_2 = $03;
SC_3 = $04;
SC_4 = $05;
SC_5 = $06;
SC_6 = $07;
SC_7 = $08;
SC_8 = $09;
SC_9 = $0A;
SC_0 = $0B;
SC_MINUS = $0C;
SC_EQUALS = $0D;
SC_BACKSPACE = $0E;
SC_TAB = $0F;
SC_Q = $10;
SC_W = $11;
SC_E = $12;
SC_R = $13;
SC_T = $14;
SC_Y = $15;
SC_U = $16;
SC_I = $17;
SC_O = $18;
SC_P = $19;
SC_LEFTBRACKET = $1A;
SC_RIGHTBRACKET = $1B;
SC_ENTER = $1C;
{$IFDEF GO32V2}
SC_CTRL = $1D;
{$ENDIF}
SC_A = $1E;
SC_S = $1F;
SC_D = $20;
SC_F = $21;
SC_G = $22;
SC_H = $23;
SC_J = $24;
SC_K = $25;
SC_L = $26;
SC_SEMICOLON = $27;
SC_QUOTE = $28;
SC_TILDE = $29;
SC_LSHIFT = $2A;
SC_BACKSLASH = $2B;
SC_Z = $2C;
SC_X = $2D;
SC_C = $2E;
SC_V = $2F;
SC_B = $30;
SC_N = $31;
SC_M = $32;
SC_COMMA = $33;
SC_PERIOD = $34;
SC_SLASH = $35;
SC_RSHIFT = $36;
SC_MULTIPLY = $37;
{$IFDEF GO32V2}
SC_ALT = $38;
{$ENDIF}
SC_SPACE = $39;
SC_CAPSLOCK = $3A;
SC_F1 = $3B;
SC_F2 = $3C;
SC_F3 = $3D;
SC_F4 = $3E;
SC_F5 = $3F;
SC_F6 = $40;
SC_F7 = $41;
SC_F8 = $42;
SC_F9 = $43;
SC_F10 = $44;
SC_NUMLOCK = $45;
SC_SCROLLLOCK = $46;
SC_HOME = $47;
SC_UP = $48;
SC_PAGEUP = $49;
SC_MINUS2 = $4A;
SC_LEFT = $4B;
SC_RIGHT = $4D;
SC_PLUS = $4E;
SC_END = $4F;
SC_DOWN = $50;
SC_PAGEDOWN = $51;
SC_INSERT = $52;
SC_DELETE = $53;
SC_F11 = $57;
SC_F12 = $58;
SC_LWIN = $7D;
SC_RWIN = $7E;
SC_MENU = $7F;
{$IFNDEF GO32V2}
{ Fictive scan codes }
SC_LALT = $FC; { Left ALT }
SC_RALT = $FD; { Right ALT }
SC_LCTRL = $FE; { Left CTRL }
SC_RCTRL = $FF; { Right CTRL }
{$ENDIF}
const
inst_vpos_max = 21;
inst_hpos_max = 7;
const
inst_hpos: array[1..inst_vpos_max,1..inst_hpos_max] of Byte = (
{1} (+15,+0,+0,+0,+0,+0,+0),
{2} (+15,+52,+0,+0,+0,+0,+0),
{3} (+52,+0,+0,+0,+0,+0,+0),
{4} (+15,+52,+0,+0,+0,+0,+0),
{5} (+15,+52,+0,+0,+0,+0,+0),
{6} (+52,+0,+0,+0,+0,+0,+0),
{7} (+15,+52,+0,+0,+0,+0,+0),
{8} (+52,+0,+0,+0,+0,+0,+0),
{9} (+52,+0,+0,+0,+0,+0,+0),
{10}(+2,+0,+0,+0,+0,+0,+0),
{11}(+2,+0,+0,+0,+0,+0,+0),
{12}(+0,+0,+0,+0,+0,+0,+0),
{13}(+0,+0,+0,+0,+0,+0,+0),
{14}(+0,+0,+0,+0,+0,+0,+0),
{15}(+0,+0,+0,+0,+0,+0,+0),
{16}(+0,+0,+0,+0,+0,+0,+0),
{17}(+0,+0,+0,+0,+0,+0,+0),
{18}(+2,+0,+0,+0,+0,+0,+0),
{19}(+2,+29,+36,+43,+50,+57,+64),
{20}(+2,+29,+36,+43,+50,+57,+64),
{21}(+2,+29,+36,+43,+50,+0,+0));
const
inst_hpos_ext_2op: array[1..6,1..inst_hpos_max] of Byte = (
{12}(+2,+22,+51,+0,+0,+0,+0),
{13}(+2,+22,+0,+0,+0,+0,+0),
{14}(+0,+0,+0,+0,+0,+0,+0),
{15}(+0,+0,+0,+0,+0,+0,+0),
{16}(+0,+51,+0,+0,+0,+0,+0),
{17}(+1,+9,+17,+0,+0,+0,+0));
const
inst_hpos_ext_perc: array[1..6,1..inst_hpos_max] of Byte = (
{12}(+2,+0,+0,+0,+0,+0,+0),
{13}(+2,+0,+0,+0,+0,+0,+0),
{14}(+0,+0,+0,+0,+0,+0,+0),
{15}(+0,+0,+0,+0,+0,+0,+0),
{16}(+0,+51,+0,+0,+0,+0,+0),
{17}(+1,+9,+17,+0,+0,+0,+0));
const
inst_hpos_ext_4op: array[1..6,1..inst_hpos_max] of Byte = (
{12}(+2,+0,+51,+0,+0,+0,+0),
{13}(+2,+0,+0,+0,+0,+0,+0),
{14}(+22,+0,+0,+0,+0,+0,+0),
{15}(+22,+0,+0,+0,+0,+0,+0),
{16}(+22,+51,+0,+0,+0,+0,+0),
{17}(+1,+9,+17,+22,+0,+0,+0));
const
inst_vpos: array[1..inst_vpos_max] of Byte = (+1,+2,+3,+4,+5,+6,+7,+8,+9,+10,+11,+12,+13,+14,+15,+16,
+17,+20,+21,+22,+23);
const
note_layout: array[0..12*8+1] of String[3] = (
' ',
'C-1','C#1','D-1','D#1','E-1','F-1','F#1','G-1','G#1','A-1','A#1','%-1',
'C-2','C#2','D-2','D#2','E-2','F-2','F#2','G-2','G#2','A-2','A#2','%-2',
'C-3','C#3','D-3','D#3','E-3','F-3','F#3','G-3','G#3','A-3','A#3','%-3',
'C-4','C#4','D-4','D#4','E-4','F-4','F#4','G-4','G#4','A-4','A#4','%-4',
'C-5','C#5','D-5','D#5','E-5','F-5','F#5','G-5','G#5','A-5','A#5','%-5',
'C-6','C#6','D-6','D#6','E-6','F-6','F#6','G-6','G#6','A-6','A#6','%-6',
'C-7','C#7','D-7','D#7','E-7','F-7','F#7','G-7','G#7','A-7','A#7','%-7',
'C-8','C#8','D-8','D#8','E-8','F-8','F#8','G-8','G#8','A-8','A#8','%-8',
'C-9');
const
board_scancodes: array[1..29] of Byte = (
$2c,$1f,$2d,$20,$2e,$2f,$22,$30,$23,$31,$24,$32,
$10,$03,$11,$04,$12,$13,$06,$14,$07,$15,$08,$16,$17,$0a,$18,$0b,$19);
const
fx_digits: array[0..47] of Char = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ&%!@=#$~^`><';
NM_FX_DIGITS = SizeOf(fx_digits);
const
b_note: Char = 'b';
connection_str: array[0..1] of String[2] = ('FM','AM');
macro_retrig_str: array[0..7] of String = (#250,#159,#11,#250,#13,#250,#250,#250);
const
pos1: array[1..22] of Byte = (+07,+14,+21,+28,+35,+42,+49,+56,+63,+70,+77,+84,+91,+98,+105,+112,+119,+126,+133,+140,+147,+154);
pos2: array[1..13] of Byte = (+00,+01,+03,+04,+06,+07,+09,+10,+12,+13,+14,+15,+16);
{ 0123456789ABCDEF }
{ ... 00 000 000 }
{ ^ ^ ^ ^ }
pos3: array[1..44] of Byte = (+00,+04,+07,+11, {1}
+15,+19,+22,+26, {2}
+30,+34,+37,+41, {3}
+45,+49,+52,+56, {4}
+60,+64,+67,+71, {5}
+75,+79,+82,+86, {6}
+90,+94,+97,+101, {7}
+105,+109,+112,+116, {8}
+120,+124,+127,+131, {9}
+135,+139,+142,+146, {10}
+150,+154,+157,+161); {11}
{ 0123456789ABCDEF }
{ ... 00 000 000 }
{ ^ ^ ^^ ^^^ ^^^ }
pos4: array[1..110] of Byte = (+00,+02,+04,+05,+07,+08,+09,+11,+12,+13, {1}
+15,+17,+19,+20,+22,+23,+24,+26,+27,+28, {2}
+30,+32,+34,+35,+37,+38,+39,+41,+42,+43, {3}
+45,+47,+49,+50,+52,+53,+54,+56,+57,+58, {4}
+60,+62,+64,+65,+67,+68,+69,+71,+72,+73, {5}
+75,+77,+79,+80,+82,+83,+84,+86,+87,+88, {6}
+90,+92,+94,+95,+97,+98,+99,+101,+102,+103, {7}
+105,+107,+109,+110,+112,+113,+114,+116,+117,+118, {8}
+120,+122,+124,+125,+127,+128,+129,+131,+132,+133, {9}
+135,+137,+139,+140,+142,+143,+144,+146,+147,+148, {10}
+150,+152,+154,+155,+157,+158,+159,+161,+162,+163); {11}
pos5: array[1..35] of Byte = (+1,+3,+5,+7,+9,+11,+12,+14,+16,+18,
+19,+20,+21,+23,+25,+27,+29,+31,+33,+34,
+36,+38,+40,+41,+42,+43,+45,+47,
+49,+50,+51,+52,+54,+56,+57);
pos5vw: array[1..35] of Byte = (+1,+3,+5,+7,+9,+11,+11,+14,+16,+18,
+19,+20,+21,+23,+25,+27,+29,+31,+33,+33,
+36,+38,+40,+41,+42,+43,+45,+47,
+49,+49,+49,+49,+54,+56,+56);
pos6: array[1..11] of Byte = (+1,+2,+3,+5,+6,+8,+9,+10,+12,+13,+14);
const
_valid_characters: Set of Char = [#0,#32..#127,#176..#223,#254,#255];
_valid_characters_fname: Set of Char = [#0,#32..#127,#255];
const
_panning: array[0..2] of Byte = ($30,$10,$20);
const
_instr_data_ofs: array[1..13] of Byte = (1,0,3,2,5,4,7,6,9,8,10,11,12);
_instr: array[0..11] of Byte = ($20, $20,
$40, $40,
$60, $60,
$80, $80,
$0e0,$0e0,
$0c0,
$0bd);
type
tTRACK_ADDR = array[1..20] of Word;
const { 01 - 02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 }
_chmm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$006,$007,$008,$103,$100,$104,$101,$105,$102,$106,$107,$108,BYTE_NULL,BYTE_NULL);
_chmm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$010,$011,$012,$108,$100,$109,$101,$10a,$102,$110,$111,$112,BYTE_NULL,BYTE_NULL);
_chmm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$013,$014,$015,$10b,$103,$10c,$104,$10d,$105,$113,$114,$115,BYTE_NULL,BYTE_NULL);
{ BD SD TT TC HH }
_chpm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$106,$107,$108,$103,$100,$104,$101,$105,$102,$006,$007,$008,$008,$007);
_chpm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$110,$111,$112,$108,$100,$109,$101,$10a,$102,$010,$014,$012,$015,$011);
_chpm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$113,$114,$115,$10b,$103,$10c,$104,$10d,$105,$013,BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL);
const
_4op_tracks_hi: Set of Byte = [1,3,5,10,12,14];
_4op_tracks_lo: Set of Byte = [2,4,6,11,13,15];
const
_4op_main_chan: array[1..6] of Byte = (2,4,6,11,13,15);
_perc_sim_chan: array[19..20] of Byte = (18,17);
var
_chan_n: tTRACK_ADDR;
_chan_m: tTRACK_ADDR;
_chan_c: tTRACK_ADDR;
_ch_tmp: tTRACK_ADDR;
const
fade_delay_tab: array[0..63] of Byte = (
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,
5,5,5,5);
const
tracing: Boolean = FALSE;
track_notes: Boolean = FALSE;
marking: Boolean = FALSE;
debugging: Boolean = FALSE;
quick_cmd: Boolean = FALSE;
const
ef_Arpeggio = 0;
ef_FSlideUp = 1;
ef_FSlideDown = 2;
ef_TonePortamento = 3;
ef_Vibrato = 4;
ef_TPortamVolSlide = 5;
ef_VibratoVolSlide = 6;
ef_FSlideUpFine = 7;
ef_FSlideDownFine = 8;
ef_SetModulatorVol = 9;
ef_VolSlide = 10;
ef_PositionJump = 11;
ef_SetInsVolume = 12;
ef_PatternBreak = 13;
ef_SetTempo = 14;
ef_SetSpeed = 15;
ef_TPortamVSlideFine = 16;
ef_VibratoVSlideFine = 17;
ef_SetCarrierVol = 18;
ef_SetWaveform = 19;
ef_VolSlideFine = 20;
ef_RetrigNote = 21;
ef_Tremolo = 22;
ef_Tremor = 23;
ef_ArpggVSlide = 24;
ef_ArpggVSlideFine = 25;
ef_MultiRetrigNote = 26;
ef_FSlideUpVSlide = 27;
ef_FSlideDownVSlide = 28;
ef_FSlUpFineVSlide = 29;
ef_FSlDownFineVSlide = 30;
ef_FSlUpVSlF = 31;
ef_FSlDownVSlF = 32;
ef_FSlUpFineVSlF = 33;
ef_FSlDownFineVSlF = 34;
ef_Extended = 35;
ef_Extended2 = 36;
ef_SetGlobalVolume = 37;
ef_SwapArpeggio = 38;
ef_SwapVibrato = 39;
ef_ForceInsVolume = 40;
ef_Extended3 = 41;
ef_ExtraFineArpeggio = 42;
ef_ExtraFineVibrato = 43;
ef_ExtraFineTremolo = 44;
ef_SetCustomSpeedTab = 45;
ef_GlobalFSlideUp = 46;
ef_GlobalFSlideDown = 47;
ef_ex_SetTremDepth = 0;
ef_ex_SetVibDepth = 1;
ef_ex_SetAttckRateM = 2;
ef_ex_SetDecayRateM = 3;
ef_ex_SetSustnLevelM = 4;
ef_ex_SetRelRateM = 5;
ef_ex_SetAttckRateC = 6;
ef_ex_SetDecayRateC = 7;
ef_ex_SetSustnLevelC = 8;
ef_ex_SetRelRateC = 9;
ef_ex_SetFeedback = 10;
ef_ex_SetPanningPos = 11;
ef_ex_PatternLoop = 12;
ef_ex_PatternLoopRec = 13;
ef_ex_ExtendedCmd = 14;
ef_ex_cmd_MKOffLoopDi = 0;
ef_ex_cmd_MKOffLoopEn = 1;
ef_ex_cmd_TPortaFKdis = 2;
ef_ex_cmd_TPortaFKenb = 3;
ef_ex_cmd_RestartEnv = 4;
ef_ex_cmd_4opVlockOff = 5;
ef_ex_cmd_4opVlockOn = 6;
ef_ex_cmd_ForceBpmSld = 7;
ef_ex_ExtendedCmd2 = 15;
ef_ex_cmd2_RSS = 0;
ef_ex_cmd2_ResetVol = 1;
ef_ex_cmd2_LockVol = 2;
ef_ex_cmd2_UnlockVol = 3;
ef_ex_cmd2_LockVP = 4;
ef_ex_cmd2_UnlockVP = 5;
ef_ex_cmd2_VSlide_mod = 6;
ef_ex_cmd2_VSlide_car = 7;
ef_ex_cmd2_VSlide_def = 8;
ef_ex_cmd2_LockPan = 9;
ef_ex_cmd2_UnlockPan = 10;
ef_ex_cmd2_VibrOff = 11;
ef_ex_cmd2_TremOff = 12;
ef_ex_cmd2_FVib_FGFS = 13;
ef_ex_cmd2_FTrm_XFGFS = 14;
ef_ex_cmd2_NoRestart = 15;
ef_ex2_PatDelayFrame = 0;
ef_ex2_PatDelayRow = 1;
ef_ex2_NoteDelay = 2;
ef_ex2_NoteCut = 3;
ef_ex2_FineTuneUp = 4;
ef_ex2_FineTuneDown = 5;
ef_ex2_GlVolSlideUp = 6;
ef_ex2_GlVolSlideDn = 7;
ef_ex2_GlVolSlideUpF = 8;
ef_ex2_GlVolSlideDnF = 9;
ef_ex2_GlVolSldUpXF = 10;
ef_ex2_GlVolSldDnXF = 11;
ef_ex2_VolSlideUpXF = 12;
ef_ex2_VolSlideDnXF = 13;
ef_ex2_FreqSlideUpXF = 14;
ef_ex2_FreqSlideDnXF = 15;
ef_ex3_SetConnection = 0;
ef_ex3_SetMultipM = 1;
ef_ex3_SetKslM = 2;
ef_ex3_SetTremoloM = 3;
ef_ex3_SetVibratoM = 4;
ef_ex3_SetKsrM = 5;
ef_ex3_SetSustainM = 6;
ef_ex3_SetMultipC = 7;
ef_ex3_SetKslC = 8;
ef_ex3_SetTremoloC = 9;
ef_ex3_SetVibratoC = 10;
ef_ex3_SetKsrC = 11;
ef_ex3_SetSustainC = 12;
const
ef_fix1 = $80;
ef_fix2 = $90;
const
home_dir_path: String = '';
a2m_default_path: String = '';
a2t_default_path: String = '';
a2i_default_path: String = '';
a2f_default_path: String = '';
a2p_default_path: String = '';
a2b_default_path: String = '';
a2w_default_path: String = '';
{$IFDEF GO32V2}
screen_mode: Byte = 0;
comp_text_mode: Byte = 0;
fps_down_factor: Byte = 0;
mouse_hspeed: Word = 50;
mouse_vspeed: Word = 50;
mouse_threshold: Word = 0;
typematic_rate: Byte = 0;
typematic_delay: Byte = 0;
mouse_disabled: Boolean = FALSE;
custom_svga_mode: Boolean = FALSE;
{$ELSE}
sdl_screen_mode: Byte = 0;
sdl_opl3_emulator: Byte = 0;
{$IFNDEF UNIX}
sdl_wav_directory: String = 'wav_files\';
{$ELSE}
sdl_wav_directory: String = 'wav_files/';
{$ENDIF}
sdl_sample_rate: Longint = 49716;
sdl_sample_buffer: Longint = 2048;
sdl_frame_rate: Byte = 100;
{$IFNDEF GO32V2}
sdl_timer_slowdown: Byte = 2;
{$ENDIF}
sdl_typematic_delay: Longint = 250;
sdl_typematic_rate: Longint = 30;
{$ENDIF}
init_tempo: Byte = 50;
init_speed: Byte = 6;
init_macro_speedup: Word = 1;
midiboard: Boolean = TRUE;
default_octave: Byte = 4;
patt_len: Word = 64;
nm_tracks: Byte = 18;
mod_description: Boolean = FALSE;
highlight_controls: Boolean = TRUE;
use_H_for_B: Boolean = FALSE;
linefeed: Boolean = TRUE;
lf_in_mboard_mode: Boolean = FALSE;
update_ins: Boolean = FALSE;
cycle_pattern: Boolean = TRUE;
keep_track_pos: Boolean = FALSE;
remember_ins_pos: Boolean = TRUE;
command_typing: Byte = 1;
backspace_dir: Byte = 1;
mark_line: Byte = 4;
scroll_bars: Boolean = TRUE;
fforward_factor: Byte = 1;
rewind_factor: Byte = 1;
ssaver_time: Longint = 300;
timer_fix: Boolean = TRUE;
decay_bar_rise: Real = 3.00;
decay_bar_fall: Real = 0.30;
force_ins: Byte = 0;
pattern_layout: Byte = 0;
trace_by_default: Boolean = TRUE;
nosync_by_default: Boolean = FALSE;
keep_position: Boolean = TRUE;
alt_ins_name: Boolean = TRUE;
adjust_tracks: Boolean = TRUE;
mark_lines: Boolean = FALSE;
accurate_conv: Boolean = FALSE;
fix_c_note_bug: Boolean = TRUE;
analyzer_bckg: Byte = $010;
analyzer: Byte = $03;
analyzer_ovrllvol: Byte = $03;
analyzer_volumelvl: Byte = $07;
analyzer_modulator: Byte = $02;
analyzer_carrier: Byte = $03;
pattern_bckg: Byte = $010;
pattern_border: Byte = $0f;
pattern_pos_indic: Byte = $0b;
pattern_pan_indic: Byte = $03;
pattern_gpan_indic: Byte = $0f;
pattern_lock_indic: Byte = $07;
pattern_4op_indic: Byte = $0e;
pattern_perc_indic: Byte = $0f;
pattern_chan_indic: Byte = $0e;
pattern_row_bckg: Byte = $050;
pattern_row_bckg_p: Byte = $0c0;
pattern_row_bckg_m: Byte = $0b0;
pattern_block_bckg: Byte = $020;
pattern_line: Byte = $03;
pattern_line_p: Byte = $00;
pattern_line_m: Byte = $0b;
pattern_hi_line: Byte = $0b;
pattern_hi_line_m: Byte = $03;
pattern_note: Byte = $07;
pattern_hi_note: Byte = $0f;
pattern_note0: Byte = $03;
pattern_hi_note0: Byte = $0c;
pattern_note_hid: Byte = $09;
pattern_hi_note_h: Byte = $07;
pattern_inst: Byte = $02;
pattern_hi_inst: Byte = $0a;
pattern_inst0: Byte = $02;
pattern_hi_inst0: Byte = $0a;
pattern_cmnd: Byte = $07;
pattern_hi_cmnd: Byte = $0f;
pattern_cmnd0: Byte = $03;
pattern_hi_cmnd0: Byte = $0b;
pattern_note_m: Byte = $09;
pattern_note0_m: Byte = $09;
pattern_note_hid_m: Byte = $0d;
pattern_inst_m: Byte = $02;
pattern_inst0_m: Byte = $02;
pattern_cmnd_m: Byte = $09;
pattern_cmnd0_m: Byte = $09;
pattern_note_b: Byte = $0f;
pattern_note0_b: Byte = $0b;
pattern_note_hid_b: Byte = $05;
pattern_inst_b: Byte = $0a;
pattern_inst0_b: Byte = $0a;
pattern_cmnd_b: Byte = $0f;
pattern_cmnd0_b: Byte = $0b;
pattern_fix_note: Byte = $0b;
pattern_hi_fx_note: Byte = $0e;
pattern_fix_note_m: Byte = $0e;
pattern_fix_note_b: Byte = $0e;
pattern_cmnd_ctrl: Byte = $0d;
pattern_input_bckg: Byte = $0b0;
pattern_input: Byte = $00;
pattern_input_warn: Byte = $080;
debug_info_bckg: Byte = $040;
debug_info_bckg2: Byte = $090;
debug_info_border: Byte = $05;
debug_info_border2: Byte = $0f;
debug_info_title: Byte = $0b;
debug_info_topic: Byte = $0e;
debug_info_txt: Byte = $07;
debug_info_hi_txt: Byte = $0f;
debug_info_txt_hid: Byte = $06;
debug_info_mod: Byte = $02;
debug_info_hi_mod: Byte = $0a;
debug_info_car: Byte = $03;
debug_info_hi_car: Byte = $0b;
debug_info_4op: Byte = $08;
debug_info_perc: Byte = $08;
debug_info_bpm: Byte = $08;
help_background: Byte = $040;
help_title: Byte = $0b;
help_border: Byte = $0f;
help_topic: Byte = $0c;
help_text: Byte = $07;
help_hi_text: Byte = $0c;
help_keys: Byte = $0f;
help_indicators: Byte = $0e;
dialog_background: Byte = $040;
dialog_title: Byte = $0b;
dialog_border: Byte = $0f;
dialog_text: Byte = $0d;
dialog_hi_text: Byte = $0e;
dialog_hid: Byte = $06;
dialog_item: Byte = $0f;
dialog_short: Byte = $0e;
dialog_item_dis: Byte = $05;
dialog_sel_itm_bck: Byte = $070;
dialog_sel_itm: Byte = $00;
dialog_sel_short: Byte = $04;
dialog_context: Byte = $0e;
dialog_context_dis: Byte = $07;
dialog_contxt_dis2: Byte = $09;
dialog_input_bckg: Byte = $070;
dialog_input: Byte = $00;
dialog_def_bckg: Byte = $0c0;
dialog_def: Byte = $00;
dialog_prog_bar1: Byte = $09;
dialog_prog_bar2: Byte = $0b;
dialog_topic: Byte = $0d;
dialog_hi_topic: Byte = $0e;
dialog_mod_text: Byte = $0a;
dialog_car_text: Byte = $0b;
dialog_misc_indic: Byte = $08;
macro_background: Byte = $040;
macro_title: Byte = $0b;
macro_border: Byte = $0f;
macro_topic: Byte = $0c;
macro_topic2: Byte = $0d;
macro_hi_topic: Byte = $0e;
macro_text: Byte = $0d;
macro_hi_text: Byte = $0e;
macro_text_dis: Byte = $06;
macro_text_loop: Byte = $0c;
macro_text_keyoff: Byte = $03;
macro_current_bckg: Byte = $050;
macro_current: Byte = $0d;
macro_current_dis: Byte = $00;
macro_current_loop: Byte = $0c;
macro_current_koff: Byte = $0b;
macro_input_bckg: Byte = $070;
macro_input: Byte = $00;
macro_def_bckg: Byte = $0c0;
macro_def: Byte = $00;
macro_scrbar_bckg: Byte = $070;
macro_scrbar_text: Byte = $00;
macro_scrbar_mark: Byte = $0f;
macro_hint: Byte = $07;
macro_item: Byte = $0f;
macro_short: Byte = $0e;
macro_item_dis: Byte = $07;
macro_sel_itm_bck: Byte = $070;
macro_sel_itm: Byte = $00;
macro_sel_short: Byte = $04;
macro_context: Byte = $0e;
macro_context_dis: Byte = $07;
scrollbar_bckg: Byte = $030;
scrollbar_text: Byte = $00;
scrollbar_mark: Byte = $0b;
scrollbar_2nd_mark: Byte = $0f;
main_background: Byte = $010;
main_title: Byte = $0b;
main_border: Byte = $0b;
main_stat_line: Byte = $03;
main_hi_stat_line: Byte = $0b;
main_dis_stat_line: Byte = $05;
main_behavior: Byte = $0d;
main_behavior_dis: Byte = $05;
status_background: Byte = $010;
status_border: Byte = $0e;
status_static_txt: Byte = $0b;
status_dynamic_txt: Byte = $0f;
status_play_state: Byte = $07;
status_text_dis: Byte = $05;
order_background: Byte = $010;
order_hi_bckg: Byte = $050;
order_border: Byte = $0a;
order_entry: Byte = $03;
order_hi_entry: Byte = $0b;
order_pattn: Byte = $07;
order_pattn_jump: Byte = $02;
order_hi_pattn: Byte = $0f;
order_played_b: Byte = $0c0;
order_played: Byte = $00;
order_input_bckg: Byte = $0b0;
order_input: Byte = $00;
order_input_warn: Byte = $0c0;
instrument_bckg: Byte = $040;
instrument_title: Byte = $0b;
instrument_border: Byte = $0f;
instrument_text: Byte = $07;
instrument_hi_text: Byte = $0f;
instrument_glob: Byte = $0d;
instrument_hi_glob: Byte = $0f;
instrument_hid: Byte = $06;
instrument_mod: Byte = $02;
instrument_car: Byte = $03;
instrument_hi_mod: Byte = $0a;
instrument_hi_car: Byte = $0b;
instrument_context: Byte = $0e;
instrument_con_dis: Byte = $05;
instrument_adsr: Byte = $60;
instrument_ai_off: Byte = $06;
instrument_ai_on: Byte = $0d;
instrument_ai_trig: Byte = $0e;
{$IFDEF GO32V2}
const
rgb_color: array[0..15] of tRGB = (
(r: 00; g: 00; b: 00),
(r: 05; g: 10; b: 30),
(r: 00; g: 30; b: 30),
(r: 00; g: 30; b: 40),
(r: 00; g: 00; b: 20),
(r: 15; g: 25; b: 35),
(r: 00; g: 10; b: 25),
(r: 20; g: 30; b: 40),
(r: 45; g: 35; b: 50),
(r: 10; g: 20; b: 30),
(r: 20; g: 40; b: 40),
(r: 20; g: 40; b: 50),
(r: 25; g: 35; b: 50),
(r: 30; g: 35; b: 45),
(r: 35; g: 60; b: 60),
(r: 40; g: 50; b: 55));
{$ELSE}
const
rgb_color: array[0..15] of tRGB = (
(r: 00 SHL 2; g: 00 SHL 2; b: 00 SHL 2; a: 00),
(r: 05 SHL 2; g: 10 SHL 2; b: 30 SHL 2; a: 00),
(r: 00 SHL 2; g: 30 SHL 2; b: 30 SHL 2; a: 00),
(r: 00 SHL 2; g: 30 SHL 2; b: 40 SHL 2; a: 00),
(r: 00 SHL 2; g: 00 SHL 2; b: 20 SHL 2; a: 00),
(r: 15 SHL 2; g: 25 SHL 2; b: 35 SHL 2; a: 00),
(r: 00 SHL 2; g: 10 SHL 2; b: 25 SHL 2; a: 00),
(r: 20 SHL 2; g: 30 SHL 2; b: 40 SHL 2; a: 00),
(r: 45 SHL 2; g: 35 SHL 2; b: 50 SHL 2; a: 00),
(r: 10 SHL 2; g: 20 SHL 2; b: 30 SHL 2; a: 00),
(r: 20 SHL 2; g: 40 SHL 2; b: 40 SHL 2; a: 00),
(r: 20 SHL 2; g: 40 SHL 2; b: 50 SHL 2; a: 00),
(r: 25 SHL 2; g: 35 SHL 2; b: 50 SHL 2; a: 00),
(r: 30 SHL 2; g: 35 SHL 2; b: 45 SHL 2; a: 00),
(r: 35 SHL 2; g: 60 SHL 2; b: 60 SHL 2; a: 00),
(r: 40 SHL 2; g: 50 SHL 2; b: 55 SHL 2; a: 00));
const
vga_rgb_color: array[0..15] of tRGB = (
(r: $000; g: $000; b: $000; a: 00),
(r: $000; g: $000; b: $0aa; a: 00),
(r: $000; g: $0aa; b: $000; a: 00),
(r: $000; g: $0aa; b: $0aa; a: 00),
(r: $0aa; g: $000; b: $000; a: 00),
(r: $0aa; g: $000; b: $0aa; a: 00),
(r: $0aa; g: $055; b: $000; a: 00),
(r: $0aa; g: $0aa; b: $0aa; a: 00),
(r: $055; g: $055; b: $055; a: 00),
(r: $055; g: $055; b: $0ff; a: 00),
(r: $055; g: $0ff; b: $055; a: 00),
(r: $055; g: $0ff; b: $0ff; a: 00),
(r: $0ff; g: $055; b: $055; a: 00),
(r: $0ff; g: $055; b: $0ff; a: 00),
(r: $0ff; g: $0ff; b: $055; a: 00),
(r: $0ff; g: $0ff; b: $0ff; a: 00));
{$ENDIF}
adlibtracker2-2.4.24/adt2unit.pas 0000644 0000000 0000000 00000636413 13411003760 015261 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
unit AdT2unit;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
interface
{$IFDEF GO32V2}
const
___UNIT_DATA_START___: Dword = 0;
{$ENDIF}
const
MIN_IRQ_FREQ = 50;
MAX_IRQ_FREQ = 1000;
{$i typcons1.inc}
{$i typcons2.inc}
const
IRQ_freq: Word = 50;
IRQ_freq_shift: Integer = 0;
tempo: Byte = 50;
speed: Byte = 6;
macro_speedup: Word = 1;
timer_initialized: Boolean = FALSE;
repeat_pattern: Boolean = FALSE;
fast_forward: Boolean = FALSE;
rewind: Boolean = FALSE;
pattern_break: Boolean = FALSE;
pattern_delay: Boolean = FALSE;
next_line: Byte = 0;
start_order: Byte = BYTE_NULL;
start_pattern: Byte = BYTE_NULL;
start_line: Byte = BYTE_NULL;
replay_forbidden: Boolean = TRUE;
single_play: Boolean = FALSE;
calibrating: Boolean = FALSE;
no_status_refresh: Boolean = FALSE;
do_synchronize: Boolean = FALSE;
space_pressed: Boolean = FALSE;
module_archived: Boolean = FALSE;
force_scrollbars: Boolean = FALSE;
no_sync_playing: Boolean = FALSE;
no_step_debugging: Boolean = FALSE;
play_single_patt: Boolean = FALSE;
no_trace_pattord: Boolean = FALSE;
skip_macro_flag: Boolean = FALSE;
max_patterns: Byte = 128;
jump_mark_mode: Boolean = FALSE;
force_macro_keyon: Boolean = FALSE;
ins_trailing_flag: Boolean = FALSE;
const
def_vibtrem_speed_factor: Byte = 1;
def_vibtrem_table_size: Byte = 32;
def_vibtrem_table: array[0..255] of Byte = (
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,
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,
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,
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,
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,
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,
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,
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);
var
vibtrem_speed_factor: Byte;
vibtrem_table_size: Byte;
vibtrem_table: array[0..255] of Byte;
type
tVIBRATO_TREMOLO_TABLE =
array[1..20] of Record
pos: Byte;
dir: Byte;
speed: Byte;
depth: Byte;
fine: Boolean;
end;
var
vibr_table: tVIBRATO_TREMOLO_TABLE;
vibr_table2: tVIBRATO_TREMOLO_TABLE;
trem_table: tVIBRATO_TREMOLO_TABLE;
trem_table2: tVIBRATO_TREMOLO_TABLE;
const
macro_preview_indic_proc: procedure(state: Byte) = NIL;
seconds_counter: Longint = 0;
hundereds_counter: Longint = 0;
really_no_status_refresh: Boolean = FALSE;
const
keyoff_flag = $080;
fixed_note_flag = $090;
pattern_loop_flag = $0e0;
pattern_break_flag = $0f0;
var
fmpar_table: array[1..20] of tFM_PARAMETER_TABLE;
volume_lock: array[1..20] of Boolean;
vol4op_lock: array[1..20] of Boolean;
volume_table: array[1..20] of Word;
vscale_table: array[1..20] of Word;
peak_lock: array[1..20] of Boolean;
pan_lock: array[1..20] of Boolean;
modulator_vol: array[1..20] of Byte;
carrier_vol: array[1..20] of Byte;
decay_bar: array[1..20] of tDECAY_BAR;
volum_bar: array[1..20] of tVOLUM_BAR;
channel_flag: array[1..20] of Boolean;
event_table: array[1..20] of tCHUNK;
voice_table: array[1..20] of Byte;
freq_table: array[1..20] of Word;
zero_fq_table: array[1..20] of Word;
effect_table: array[1..20] of Word;
effect_table2: array[1..20] of Word;
fslide_table: array[1..20] of Byte;
fslide_table2: array[1..20] of Byte;
glfsld_table: array[1..20] of Word;
glfsld_table2: array[1..20] of Word;
porta_table: array[1..20] of Record freq: Word; speed: Byte; end;
porta_table2: array[1..20] of Record freq: Word; speed: Byte; end;
portaFK_table: array[1..20] of Boolean;
arpgg_table: array[1..20] of Record state,note,add1,add2: Byte; end;
arpgg_table2: array[1..20] of Record state,note,add1,add2: Byte; end;
retrig_table: array[1..20] of Byte;
retrig_table2: array[1..20] of Byte;
tremor_table: array[1..20] of Record pos: Integer; volume: Word; end;
tremor_table2: array[1..20] of Record pos: Integer; volume: Word; end;
panning_table: array[1..20] of Byte;
last_effect: array[1..20] of Word;
last_effect2: array[1..20] of Word;
volslide_type: array[1..20] of Byte;
event_new: array[1..20] of Boolean;
freqtable2: array[1..20] of Word;
notedel_table: array[1..20] of Byte;
notecut_table: array[1..20] of Byte;
ftune_table: array[1..20] of Shortint;
keyoff_loop: array[1..20] of Boolean;
macro_table: array[1..20] of Record
fmreg_pos,arpg_pos,vib_pos: Word;
fmreg_count,fmreg_duration,arpg_count,
vib_count,vib_delay: Byte;
vib_paused: Boolean;
fmreg_table,arpg_table,vib_table: Byte;
arpg_note: Byte;
vib_freq: Word;
end;
loopbck_table: array[1..20] of Byte;
loop_table: array[1..20,0..255] of Byte;
misc_register: Byte;
ai_table: array[1..255] of Byte;
const
overall_volume: Byte = 63;
global_volume: Byte = 63;
fade_out_volume: Byte = 63;
playback_speed_shift: Longint = 0;
play_status: tPLAY_STATUS = isStopped;
chan_pos: Byte = 1;
chpos: Byte = 1;
transpos: Byte = 1;
track_chan_start: Byte = 1;
nm_track_chan: Byte = 1;
play_pos_buf: array[1..9] of Word = (0,0,0,0,0,0,0,0,0);
rec_correction: Byte = 0;
const
MACRO_NOTE_RETRIG_FLAG = $80;
MACRO_ENVELOPE_RESTART_FLAG = $40;
MACRO_ZERO_FREQ_FLAG = $20;
const
current_order: Byte = 0;
current_pattern: Byte = 0;
current_line: Byte = 0;
current_tremolo_depth: Byte = 0;
current_vibrato_depth: Byte = 0;
current_inst: Byte = 1;
current_octave: Byte = 4;
var
adt2_title: array[0..36] of String[18];
var
songdata_source: String;
instdata_source: String;
songdata_title: String;
var
songdata_crc,songdata_crc_ord: Longint;
temp_instrument: tADTRACK2_INS;
temp_instrument2: tADTRACK2_INS;
temp_instrument_macro: tREGISTER_TABLE;
temp_instrument_macro2: tREGISTER_TABLE;
temp_instrument_dis_fmreg_col: tDIS_FMREG_COL;
temp_instrument_dis_fmreg_col2: tDIS_FMREG_COL;
temp_ins_type: Byte;
pattord_page,pattord_hpos,pattord_vpos: Byte;
instrum_page: Byte;
pattern_patt,pattern_page,pattern_hpos: Byte;
limit_exceeded: Boolean;
load_flag,load_flag_alt: Byte;
reset_chan: array[1..20] of Boolean;
reset_adsrw: array[1..20] of Boolean;
ignore_note_once: array[1..20] of Boolean;
track_notes_ins: Boolean;
seek_pattern_break: Boolean;
var
speed_update,lockvol,panlock,lockVP: Boolean;
tremolo_depth,vibrato_depth: Byte;
volume_scaling,percussion_mode: Boolean;
last_order: Byte;
var
buf1: tGENERIC_IO_BUFFER;
buf2: tGENERIC_IO_BUFFER;
buf3: array[WORD] of Byte;
buf4: array[WORD] of Byte;
const
pattdata: ^tPATTERN_DATA = NIL;
var
old_hash_buffer: tOLD_VARIABLE_DATA1;
hash_buffer: tOLD_VARIABLE_DATA2;
old_songdata: tOLD_FIXED_SONGDATA;
dos_memavail: Word;
var
songdata: tFIXED_SONGDATA;
songdata_bak: tFIXED_SONGDATA;
temp_songdata: tFIXED_SONGDATA;
clipboard: tCLIPBOARD;
const
ptr_songdata: Pointer = Addr(songdata);
ptr_songdata_bak: Pointer = Addr(songdata_bak);
ptr_temp_songdata: Pointer = Addr(ptr_temp_songdata);
ptr_clipboard: Pointer = Addr(clipboard);
var
song_timer,timer_temp: Longint;
song_timer_tenths: Longint;
ticks,tick0,tickD,tickXF: Longint;
time_playing,time_playing0: Real;
const
{$IFDEF GO32V2}
timer_determinator: Longint = 1;
timer_det2: Longint = 1;
scr_scroll_x: Word = 0;
old_scr_scroll_x: Word = 0;
scr_scroll_y: Word = 0;
old_scr_scroll_y: Word = 0;
{$ELSE}
screen_scroll_offset: Word = 0;
{$ENDIF}
var
common_flag_backup: Byte;
volume_scaling_backup: Boolean;
event_table_backup: array[1..20] of tCHUNK;
freq_table_backup,freqtable2_backup: array[1..20] of Word;
keyoff_loop_backup: array[1..20] of Boolean;
channel_flag_backup: array[1..20] of Boolean;
fmpar_table_backup: array[1..20] of tFM_PARAMETER_TABLE;
volume_table_backup: array[1..20] of Word;
pan_lock_backup: array[1..20] of Boolean;
volume_lock_backup: array[1..20] of Boolean;
peak_lock_backup: array[1..20] of Boolean;
panning_table_backup: array[1..20] of Byte;
voice_table_backup: array[1..20] of Byte;
flag_4op_backup: Byte;
status_backup: Record
replay_forbidden: Boolean;
play_status: tPLAY_STATUS;
end;
function nFreq(note: Byte): Word;
procedure change_freq(chan: Byte; freq: Word);
function calc_pattern_pos(pattern: Byte): Byte;
function concw(lo,hi: Byte): Word;
function ins_parameter(ins,param: Byte): Byte;
function is_chan_adsr_data_empty(chan: Byte): Boolean;
function is_ins_adsr_data_empty(ins: Byte): Boolean;
function scale_volume(volume,scale_factor: Byte): Byte;
function _macro_speedup: Word;
procedure calibrate_player(order,line: Byte; status_filter: Boolean;
line_dependent: Boolean);
procedure update_timer(Hz: Word);
procedure key_on(chan: Byte);
procedure key_off(chan: Byte);
procedure release_sustaining_sound(chan: Byte);
procedure init_macro_table(chan,note,ins: Byte; freq: Word);
procedure set_ins_volume(modulator,carrier,chan: Byte);
procedure update_modulator_adsrw(chan: Byte);
procedure update_carrier_adsrw(chan: Byte);
procedure update_fmpar(chan: Byte);
procedure reset_chan_data(chan: Byte);
procedure poll_proc;
procedure macro_poll_proc;
procedure init_buffers;
procedure init_player;
procedure reset_player;
procedure start_playing;
procedure stop_playing;
procedure update_song_position;
procedure change_frequency(chan: Byte; freq: Word);
procedure set_global_volume;
procedure set_ins_data(ins,chan: Byte);
procedure init_timer_proc;
procedure done_timer_proc;
procedure realtime_gfx_poll_proc;
procedure decay_bars_refresh;
procedure status_refresh;
procedure trace_update_proc;
function hscroll_bar(x,y: Byte; size: Byte; len1,len2,pos: Word;
atr1,atr2: Byte): Byte;
function vscroll_bar(x,y: Byte; size: Byte; len1,len2,pos: Word;
atr1,atr2: Byte): Byte;
procedure centered_frame(var xstart,ystart: Byte; hsize,vsize: Byte;
name: String; atr1,atr2: Byte; border: String);
procedure get_chunk(pattern,line,channel: Byte; var chunk: tCHUNK);
procedure put_chunk(pattern,line,channel: Byte; chunk: tCHUNK);
function get_chanpos(var data; channels,scancode: Byte): Byte;
function get_chanpos2(var data; channels,scancode: Byte): Byte;
function count_channel(hpos: Byte): Byte;
function count_pos(hpos: Byte): Byte;
function calc_max_speedup(tempo: Byte): Word;
function calc_bpm_speed(tempo,speed,rows_per_beat: Byte): Real;
function calc_realtime_bpm_speed(tempo,speed,rows_per_beat: Byte): Real;
function calc_order_jump: Integer;
function calc_following_order(order: Byte): Integer;
function is_4op_chan(chan: Byte): Boolean;
procedure count_order(var entries: Byte);
procedure count_patterns(var patterns: Byte);
procedure count_instruments(var instruments: Byte);
procedure init_old_songdata;
procedure init_songdata;
procedure update_instr_data(ins: Byte);
procedure load_instrument(var data; chan: Byte);
procedure output_note(note,ins,chan: Byte;
restart_macro,restart_adsr: Boolean);
function min(value: Longint; minimum: Longint): Longint;
function max(value: Longint; maximum: Longint): Longint;
function asciiz_string(str: String): String;
procedure TimerSetup(Hz: Longint);
const
block_xstart: Byte = 1;
block_ystart: Byte = 0;
const
block_x0: Byte = 0;
block_y0: Byte = 1;
block_x1: Byte = 0;
block_y1: Byte = 1;
function is_in_block(x0,y0,x1,y1: Byte): Boolean;
procedure fade_out_playback(fade_screen: Boolean);
const
ticklooper: Longint = 0;
macro_ticklooper: Longint = 0;
const
{$IFDEF GO32V2}
MAX_NUM_BANK_POSITIONS = 1000;
{$ELSE}
MAX_NUM_BANK_POSITIONS = 500;
{$ENDIF}
const
bank_position_list_size: Longint = 0;
var
bank_position_list:
array[1..MAX_NUM_BANK_POSITIONS] of Record
{$IFDEF GO32V2}
bank_name: String[50];
{$ELSE}
bank_name: String;
{$ENDIF}
bank_size: Longint;
bank_position: Longint;
end;
function get_bank_position(bank_name: String; bank_size: Longint): Longint;
procedure add_bank_position(bank_name: String; bank_size: Longint; bank_position: Longint);
{$IFDEF GO32V2}
const
___UNIT_DATA_END___: Dword = 0;
{$ENDIF}
implementation
uses
{$IFDEF GO32V2}
CRT,DOS,GO32,ISS_Tim,
{$ELSE}
DOS,SDL_Types,SDL_Timer,
{$ENDIF}
AdT2opl3,AdT2sys,AdT2extn,AdT2ext2,AdT2keyb,
TxtScrIO,StringIO,DialogIO,ParserIO;
{$IFDEF GO32V2}
const
___IRQ_DATA_START___: Dword = 0;
procedure ___IRQ_CODE_START___; begin end;
{$ENDIF}
const
FreqStart = $156;
FreqEnd = $2ae;
FreqRange = FreqEnd-FreqStart;
function nFreq(note: Byte): Word;
const
Fnum: array[0..11] of Word = (
$157,$16b,$181,$198,$1b0,$1ca,$1e5,$202,$220,$241,$263,$287);
var
result: Word;
begin
asm
xor ebx,ebx
mov al,[note]
xor ah,ah
cmp ax,12*8
jae @@1
push eax
mov bl,12
div bl
mov bl,ah
xor bh,bh
shl bx,1
pop eax
mov cl,12
div cl
xor ah,ah
shl ax,10
add ax,word ptr [Fnum+ebx]
jmp @@2
@@1: mov ax,7
shl ax,10
add ax,FreqEnd
@@2: mov result,ax
end;
nFreq := result;
end;
function calc_freq_shift_up(freq,shift: Word): Word;
var
result: Word;
begin
asm
mov cx,freq
mov ax,shift
mov bx,cx
and bx,0000001111111111b
mov dx,cx
and dx,0001110000000000b
add bx,ax
and cx,1110000000000000b
shr dx,10
cmp bx,FreqEnd
jb @@2
cmp dx,7
jnz @@1
mov bx,FreqEnd
jmp @@2
@@1: sub bx,FreqRange
inc dx
@@2: mov ax,cx
shl dx,10
add ax,dx
add ax,bx
mov result,ax
end;
calc_freq_shift_up := result;
end;
function calc_freq_shift_down(freq,shift: Word): Word;
var
result: Word;
begin
asm
mov cx,freq
mov ax,shift
mov bx,cx
and bx,0000001111111111b
mov dx,cx
and dx,0001110000000000b
sub bx,ax
and cx,1110000000000000b
shr dx,10
cmp bx,FreqStart
ja @@2
or dx,dx
jnz @@1
mov bx,FreqStart
jmp @@2
@@1: add bx,FreqRange
dec dx
@@2: mov ax,cx
shl dx,10
add ax,dx
add ax,bx
mov result,ax
end;
calc_freq_shift_down := result;
end;
function calc_vibtrem_shift(chan: Byte; var table_data): Word;
var
pos,dir,depth: Byte;
result: Word;
begin
pos := tVIBRATO_TREMOLO_TABLE(table_data)[chan].pos;
depth := tVIBRATO_TREMOLO_TABLE(table_data)[chan].depth;
asm
xor ebx,ebx
mov al,depth
xor ah,ah
mov bl,pos
xor bh,bh
mov dh,bl
mov cl,byte ptr [vibtrem_table_size]
dec cl
and bl,cl
mov dl,byte ptr [vibtrem_table+ebx]
mul dl
rol ax,1
xchg ah,al
and ah,1
mov dir,1
mov dl,byte ptr [vibtrem_table_size]
test dh,dl
jne @@1
mov dir,0
@@1: mov result,ax
end;
tVIBRATO_TREMOLO_TABLE(table_data)[chan].dir := dir;
calc_vibtrem_shift := result;
end;
procedure change_freq(chan: Byte; freq: Word);
begin
If is_4op_chan(chan) and (chan in _4op_tracks_hi) then
begin
freq_table[SUCC(chan)] := freq_table[chan];
freqtable2[SUCC(chan)] := freqtable2[chan];
chan := SUCC(chan);
end;
asm
xor ebx,ebx
mov bl,chan
dec ebx
shl ebx,1
mov ax,freq
and ax,1fffh
mov dx,word ptr [freq_table+ebx]
and dx,NOT 1fffh
add ax,dx
mov word ptr [freq_table+ebx],ax
mov word ptr [freqtable2+ebx],ax
shr ebx,1
cmp byte ptr [channel_flag+ebx],TRUE
jnz @@1
shl ebx,1
xor edx,edx
mov dx,word ptr [_chan_n+ebx]
add dx,0a0h
push edx
xor edx,edx
mov dl,al
push edx
mov dx,word ptr [_chan_n+ebx]
add dx,0b0h
push edx
xor edx,edx
mov dl,ah
push edx
call opl3out
call opl3out
@@1:
end;
If is_4op_chan(chan) then
begin
freq_table[PRED(chan)] := freq_table[chan];
freqtable2[PRED(chan)] := freqtable2[chan];
end;
end;
function ins_parameter(ins,param: Byte): Byte;
var
result: Byte;
begin
asm
xor ebx,ebx
lea esi,[songdata.instr_data]
mov bl,ins
dec ebx
mov eax,INSTRUMENT_SIZE
mul ebx
add esi,eax
mov bl,param
add esi,ebx
lodsb
mov result,al
end;
ins_parameter := result;
end;
function is_chan_adsr_data_empty(chan: Byte): Boolean;
begin
is_chan_adsr_data_empty :=
(fmpar_table[chan].adsrw_car.attck = 0) and
(fmpar_table[chan].adsrw_mod.attck = 0) and
(fmpar_table[chan].adsrw_car.dec = 0) and
(fmpar_table[chan].adsrw_mod.dec = 0) and
(fmpar_table[chan].adsrw_car.sustn = 0) and
(fmpar_table[chan].adsrw_mod.sustn = 0) and
(fmpar_table[chan].adsrw_car.rel = 0) and
(fmpar_table[chan].adsrw_mod.rel = 0);
end;
function is_ins_adsr_data_empty(ins: Byte): Boolean;
begin
is_ins_adsr_data_empty :=
(ins_parameter(ins,5) SHR 4 = 0) and
(ins_parameter(ins,4) SHR 4 = 0) and
(ins_parameter(ins,5) AND $0f = 0) and
(ins_parameter(ins,4) AND $0f = 0) and
(ins_parameter(ins,7) SHR 4 = 0) and
(ins_parameter(ins,6) SHR 4 = 0) and
(ins_parameter(ins,7) AND $0f = 0) and
(ins_parameter(ins,6) AND $0f = 0);
end;
function is_data_empty(var buf; size: Longint): Boolean;
var
result: Boolean;
begin
asm
xor edx,edx
mov eax,size
cmp eax,16
jb @@3
mov ecx,4
div ecx
mov ecx,eax
jecxz @@1
mov edi,[buf]
xor eax,eax
repz scasd
jnz @@2
mov ecx,edx
jecxz @@1
repz scasb
jnz @@2
@@1: mov result,TRUE
jmp @@6
@@2: mov result,FALSE
jmp @@6
@@3: mov ecx,size
jecxz @@4
mov edi,[buf]
xor eax,eax
repz scasb
jnz @@5
@@4: mov result,TRUE
jmp @@6
@@5: mov result,FALSE
@@6:
end;
is_data_empty := result;
end;
function min(value: Longint; minimum: Longint): Longint;
begin
If (value > minimum) then min := value
else min := minimum;
end;
function max(value: Longint; maximum: Longint): Longint;
begin
If (value < maximum) then max := value
else max := maximum;
end;
function asciiz_string(str: String): String;
begin
If (Pos(#0,str) <> 0) then asciiz_string := Copy(str,1,Pos(#0,str)-1)
else asciiz_string := '';
end;
function concw(lo,hi: Byte): Word;
begin
concw := lo+(hi SHL 8);
end;
procedure synchronize_song_timer;
begin
song_timer := TRUNC(time_playing);
song_timer_tenths := TRUNC(time_playing*100) MOD 100;
timer_temp := song_timer_tenths;
end;
procedure change_frequency(chan: Byte; freq: Word);
begin
macro_table[chan].vib_paused := TRUE;
change_freq(chan,freq);
If is_4op_chan(chan) then
If (chan in _4op_tracks_hi) then
begin
macro_table[SUCC(chan)].vib_count := 1;
macro_table[SUCC(chan)].vib_pos := 0;
macro_table[SUCC(chan)].vib_freq := freq;
macro_table[SUCC(chan)].vib_paused := FALSE;
end
else
begin
macro_table[PRED(chan)].vib_count := 1;
macro_table[PRED(chan)].vib_pos := 0;
macro_table[PRED(chan)].vib_freq := freq;
macro_table[PRED(chan)].vib_paused := FALSE;
end;
macro_table[chan].vib_count := 1;
macro_table[chan].vib_pos := 0;
macro_table[chan].vib_freq := freq;
macro_table[chan].vib_paused := FALSE;
end;
procedure update_timer(Hz: Word);
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:update_timer';
{$ENDIF}
If (Hz = 0) then begin TimerSetup(18); EXIT end
else tempo := Hz;
If (tempo = 18) and timer_fix then IRQ_freq := TRUNC((tempo+0.2)*20)
else IRQ_freq := 250;
While (IRQ_freq MOD (tempo*_macro_speedup) <> 0) do Inc(IRQ_freq);
If (IRQ_freq > MAX_IRQ_FREQ) then IRQ_freq := MAX_IRQ_FREQ;
While (IRQ_freq+IRQ_freq_shift+playback_speed_shift > MAX_IRQ_FREQ) and
(playback_speed_shift > 0) do
Dec(playback_speed_shift);
While (IRQ_freq+IRQ_freq_shift+playback_speed_shift > MAX_IRQ_FREQ) and
(IRQ_freq_shift > 0) do
Dec(IRQ_freq_shift);
TimerSetup(max(IRQ_freq+IRQ_freq_shift+playback_speed_shift,MAX_IRQ_FREQ));
end;
procedure update_playback_speed(speed_shift: Longint);
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:update_playback_speed';
{$ENDIF}
If (speed_shift = 0) then EXIT
else If (speed_shift > 0) and (IRQ_freq+playback_speed_shift+speed_shift > MAX_IRQ_FREQ) then
While (IRQ_freq+IRQ_freq_shift+playback_speed_shift+speed_shift > MAX_IRQ_FREQ) do
Dec(speed_shift)
else If (speed_shift < 0) and (IRQ_freq+IRQ_freq_shift+playback_speed_shift+speed_shift < MIN_IRQ_FREQ) then
While (IRQ_freq+IRQ_freq_shift+playback_speed_shift+speed_shift < MIN_IRQ_FREQ) do
Inc(speed_shift);
playback_speed_shift := playback_speed_shift+speed_shift;
update_timer(tempo);
end;
procedure key_on(chan: Byte);
begin
If NOT (is_4op_chan(chan) and (chan in _4op_tracks_hi)) then
opl3out($0b0+_chan_n[chan],0)
else opl3out($0b0+_chan_n[SUCC(chan)],0);
end;
procedure key_off(chan: Byte);
begin
freq_table[chan] := LO(freq_table[chan])+
(HI(freq_table[chan]) AND NOT $20) SHL 8;
change_freq(chan,freq_table[chan]);
event_table[chan].note := event_table[chan].note OR keyoff_flag;
end;
procedure release_sustaining_sound(chan: Byte);
begin
opl3out(_instr[02]+_chan_m[chan],63);
opl3out(_instr[03]+_chan_c[chan],63);
FillChar(fmpar_table[chan].adsrw_car,
SizeOf(fmpar_table[chan].adsrw_car),0);
FillChar(fmpar_table[chan].adsrw_mod,
SizeOf(fmpar_table[chan].adsrw_mod),0);
key_on(chan);
opl3out(_instr[04]+_chan_m[chan],BYTE_NULL);
opl3out(_instr[05]+_chan_c[chan],BYTE_NULL);
opl3out(_instr[06]+_chan_m[chan],BYTE_NULL);
opl3out(_instr[07]+_chan_c[chan],BYTE_NULL);
key_off(chan);
event_table[chan].instr_def := 0;
reset_chan[chan] := TRUE;
end;
function scale_volume(volume,scale_factor: Byte): Byte;
begin
scale_volume := 63-Round((63-volume)/63*
(63-scale_factor));
end;
function _4op_data_flag(chan: Byte): Dword;
var
_4op_conn: Byte;
_4op_mode: Boolean;
_4op_ch1,_4op_ch2: Byte;
_4op_ins1,_4op_ins2: Byte;
begin
_4op_mode := FALSE;
If is_4op_chan(chan) then
begin
_4op_mode := TRUE;
If (chan in _4op_tracks_hi) then
begin
_4op_ch1 := chan;
_4op_ch2 := SUCC(chan);
end
else
begin
_4op_ch1 := PRED(chan);
_4op_ch2 := chan;
end;
_4op_ins1 := event_table[_4op_ch1].instr_def;
If (_4op_ins1 = 0) then _4op_ins1 := voice_table[_4op_ch1];
_4op_ins2 := event_table[_4op_ch2].instr_def;
If (_4op_ins2 = 0) then _4op_ins2 := voice_table[_4op_ch2];
If (_4op_ins1 <> 0) and (_4op_ins2 <> 0) then
begin
_4op_mode := TRUE;
_4op_conn := (pBYTE(@Addr(songdata.instr_data[_4op_ins1])^)[_instr_data_ofs[11]] AND 1) SHL 1 +
(pBYTE(@Addr(songdata.instr_data[_4op_ins2])^)[_instr_data_ofs[11]] AND 1);
end;
end;
{------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---}
{ BIT |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0 }
{------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---}
{ DATA |..|..|..|..|..|F7|F6|F5|F4|F3|F2|F1|F0|E7|E6|E5|E4|E3|E2|E1|E0|D3|D2|D1|D0|C3|C2|C1|C0|B1|B0|A0 }
{------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---}
_4op_data_flag := ORD(_4op_mode) + {1-bit: A0}
(_4op_conn AND 3) SHL 1 + {2-bit: B1-B0}
(_4op_ch1 AND 15) SHL 3 + {4-bit: C3-C0}
(_4op_ch2 AND 15) SHL 7 + {4-bit: D3-D0}
_4op_ins1 SHL 11 + {8-bit: E7-E0}
_4op_ins2 SHL 19; {8-bit: F7-F0}
end;
function _4op_vol_valid_chan(chan: Byte): Boolean;
var
_4op_flag: Dword;
begin
_4op_flag := _4op_data_flag(chan);
_4op_vol_valid_chan := BOOLEAN(_4op_flag AND 1) and vol4op_lock[chan] and
(BYTE(_4op_flag SHR 11) <> 0) and
(BYTE(_4op_flag SHR 19) <> 0);
end;
procedure set_ins_volume(modulator,carrier,chan: Byte);
var
temp: Byte;
begin
{$IFNDEF GO32V2}
// ** OPL3 emulation workaround **
// force muted instrument volume with missing channel ADSR data
// when there is additionally no FM-reg macro defined for this instrument
If is_chan_adsr_data_empty(chan) and
NOT (songdata.instr_macros[voice_table[chan]].length <> 0) then
begin
modulator := 63;
carrier := 63;
end;
{$ENDIF}
If (modulator <> BYTE_NULL) then
begin
temp := modulator;
If volume_scaling then
If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
(percussion_mode and (chan in [17..20])) then
modulator := scale_volume(ins_parameter(voice_table[chan],2) AND $3f,modulator);
If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
(percussion_mode and (chan in [17..20])) then
opl3out(_instr[02]+_chan_m[chan],
scale_volume(scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+LO(vscale_table[chan]))
else
opl3out(_instr[02]+_chan_m[chan],
temp+LO(vscale_table[chan]));
volume_table[chan] := concw(temp,HI(volume_table[chan]));
If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
(percussion_mode and (chan in [17..20])) then
modulator_vol[chan] := 63-scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume))
else modulator_vol[chan] := 63-modulator;
end;
If (carrier <> BYTE_NULL) then
begin
temp := carrier;
If volume_scaling then
carrier := scale_volume(ins_parameter(voice_table[chan],3) AND $3f,carrier);
opl3out(_instr[03]+_chan_c[chan],
scale_volume(scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+HI(vscale_table[chan]));
volume_table[chan] := concw(LO(volume_table[chan]),temp);
carrier_vol[chan] := 63-scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume));
end;
end;
procedure set_ins_volume_4op(volume,chan: Byte);
var
_4op_flag: Dword;
_4op_conn: Byte;
_4op_ch1,_4op_ch2: Byte;
procedure set_volume(modulator,carrier,chan: Byte);
var
temp: Byte;
begin
{$IFNDEF GO32V2}
// OPL3 EMULATION WORKAROUND
// force muted instrument volume with missing channel ADSR data
// when there is additionally no FM-reg macro defined for this instrument
If is_chan_adsr_data_empty(chan) and
NOT (songdata.instr_macros[voice_table[chan]].length <> 0) then
begin
modulator := 63;
carrier := 63;
end;
{$ENDIF}
If (modulator <> BYTE_NULL) then
begin
temp := modulator;
modulator := scale_volume(ins_parameter(voice_table[chan],2) AND $3f,modulator);
opl3out(_instr[02]+_chan_m[chan],
scale_volume(scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+LO(vscale_table[chan]));
volume_table[chan] := concw(temp,HI(volume_table[chan]));
modulator_vol[chan] := 63-scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume))
end;
If (carrier <> BYTE_NULL) then
begin
temp := carrier;
carrier := scale_volume(ins_parameter(voice_table[chan],3) AND $3f,carrier);
opl3out(_instr[03]+_chan_c[chan],
scale_volume(scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+HI(vscale_table[chan]));
volume_table[chan] := concw(LO(volume_table[chan]),temp);
carrier_vol[chan] := 63-scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume));
end;
end;
begin
_4op_flag := _4op_data_flag(chan);
_4op_conn := (_4op_flag SHR 1) AND 3;
_4op_ch1 := (_4op_flag SHR 3) AND 15;
_4op_ch2 := (_4op_flag SHR 7) AND 15;
If _4op_vol_valid_chan(chan) then
Case _4op_conn of
// FM/FM
0: If (volume = BYTE_NULL) then
set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1)
else set_volume(BYTE_NULL,volume,_4op_ch1);
// FM/AM
1: If (volume = BYTE_NULL) then
begin
set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1);
set_volume(LO(volume_table[_4op_ch2]),BYTE_NULL,_4op_ch2);
end
else begin
set_volume(BYTE_NULL,volume,_4op_ch1);
set_volume(volume,BYTE_NULL,_4op_ch2);
end;
// AM/FM
2: If (volume = BYTE_NULL) then
begin
set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1);
set_volume(BYTE_NULL,HI(volume_table[_4op_ch2]),_4op_ch2);
end
else begin
set_volume(BYTE_NULL,volume,_4op_ch1);
set_volume(BYTE_NULL,volume,_4op_ch2);
end;
// AM/AM
3: If (volume = BYTE_NULL) then
begin
set_volume(LO(volume_table[_4op_ch1]),HI(volume_table[_4op_ch1]),_4op_ch1);
set_volume(LO(volume_table[_4op_ch2]),BYTE_NULL,_4op_ch2);
end
else begin
set_volume(volume,volume,_4op_ch1);
set_volume(volume,BYTE_NULL,_4op_ch2);
end;
end;
end;
procedure reset_ins_volume(chan: Byte);
begin
If NOT volume_scaling then
set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f,
ins_parameter(voice_table[chan],3) AND $3f,chan)
else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f,0,chan)
else set_ins_volume(0,0,chan);
end;
procedure set_ins_data(ins,chan: Byte);
var
old_ins: Byte;
begin
If (ins <> event_table[chan].instr_def) or reset_chan[chan] then
begin
opl3out(_instr[02]+_chan_m[chan],63);
opl3out(_instr[03]+_chan_c[chan],63);
If NOT pan_lock[chan] then
panning_table[chan] := ins_parameter(ins,11)
else panning_table[chan] := songdata.lock_flags[chan] AND 3;
opl3out(_instr[00]+_chan_m[chan],ins_parameter(ins,0));
opl3out(_instr[01]+_chan_c[chan],ins_parameter(ins,1));
opl3out(_instr[04]+_chan_m[chan],ins_parameter(ins,4));
opl3out(_instr[05]+_chan_c[chan],ins_parameter(ins,5));
opl3out(_instr[06]+_chan_m[chan],ins_parameter(ins,6));
opl3out(_instr[07]+_chan_c[chan],ins_parameter(ins,7));
opl3out(_instr[08]+_chan_m[chan],ins_parameter(ins,8));
opl3out(_instr[09]+_chan_c[chan],ins_parameter(ins,9));
opl3out(_instr[10]+_chan_n[chan],ins_parameter(ins,10) OR _panning[panning_table[chan]]);
fmpar_table[chan].connect := ins_parameter(ins,10) AND 1;
fmpar_table[chan].feedb := ins_parameter(ins,10) SHR 1 AND 7;
fmpar_table[chan].multipM := ins_parameter(ins,0) AND $0f;
fmpar_table[chan].kslM := ins_parameter(ins,2) SHR 6;
fmpar_table[chan].tremM := ins_parameter(ins,0) SHR 7;
fmpar_table[chan].vibrM := ins_parameter(ins,0) SHR 6 AND 1;
fmpar_table[chan].ksrM := ins_parameter(ins,0) SHR 4 AND 1;
fmpar_table[chan].sustM := ins_parameter(ins,0) SHR 5 AND 1;
fmpar_table[chan].multipC := ins_parameter(ins,1) AND $0f;
fmpar_table[chan].kslC := ins_parameter(ins,3) SHR 6;
fmpar_table[chan].tremC := ins_parameter(ins,1) SHR 7;
fmpar_table[chan].vibrC := ins_parameter(ins,1) SHR 6 AND 1;
fmpar_table[chan].ksrC := ins_parameter(ins,1) SHR 4 AND 1;
fmpar_table[chan].sustC := ins_parameter(ins,1) SHR 5 AND 1;
fmpar_table[chan].adsrw_car.attck := ins_parameter(ins,5) SHR 4;
fmpar_table[chan].adsrw_mod.attck := ins_parameter(ins,4) SHR 4;
fmpar_table[chan].adsrw_car.dec := ins_parameter(ins,5) AND $0f;
fmpar_table[chan].adsrw_mod.dec := ins_parameter(ins,4) AND $0f;
fmpar_table[chan].adsrw_car.sustn := ins_parameter(ins,7) SHR 4;
fmpar_table[chan].adsrw_mod.sustn := ins_parameter(ins,6) SHR 4;
fmpar_table[chan].adsrw_car.rel := ins_parameter(ins,7) AND $0f;
fmpar_table[chan].adsrw_mod.rel := ins_parameter(ins,6) AND $0f;
fmpar_table[chan].adsrw_car.wform := ins_parameter(ins,9) AND $07;
fmpar_table[chan].adsrw_mod.wform := ins_parameter(ins,8) AND $07;
If NOT reset_chan[chan] then
keyoff_loop[chan] := FALSE;
If reset_chan[chan] then
begin
voice_table[chan] := ins;
reset_ins_volume(chan);
reset_chan[chan] := FALSE;
end;
If (event_table[chan].note AND $7f in [1..12*8+1]) then
init_macro_table(chan,event_table[chan].note AND $7f,ins,freq_table[chan])
else init_macro_table(chan,0,ins,freq_table[chan]);
end;
vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6,
fmpar_table[chan].kslC SHL 6);
voice_table[chan] := ins;
old_ins := event_table[chan].instr_def;
event_table[chan].instr_def := ins;
If NOT volume_lock[chan] or (ins <> old_ins) then
reset_ins_volume(chan);
ai_table[ins] := 1;
end;
procedure update_modulator_adsrw(chan: Byte);
begin
opl3out(_instr[04]+_chan_m[chan],
fmpar_table[chan].adsrw_mod.attck SHL 4+
fmpar_table[chan].adsrw_mod.dec);
opl3out(_instr[06]+_chan_m[chan],
fmpar_table[chan].adsrw_mod.sustn SHL 4+
fmpar_table[chan].adsrw_mod.rel);
opl3out(_instr[08]+_chan_m[chan],
fmpar_table[chan].adsrw_mod.wform);
end;
procedure update_carrier_adsrw(chan: Byte);
begin
opl3out(_instr[05]+_chan_c[chan],
fmpar_table[chan].adsrw_car.attck SHL 4+
fmpar_table[chan].adsrw_car.dec);
opl3out(_instr[07]+_chan_c[chan],
fmpar_table[chan].adsrw_car.sustn SHL 4+
fmpar_table[chan].adsrw_car.rel);
opl3out(_instr[09]+_chan_c[chan],
fmpar_table[chan].adsrw_car.wform);
end;
procedure update_fmpar(chan: Byte);
begin
opl3out(_instr[00]+_chan_m[chan],fmpar_table[chan].multipM+
fmpar_table[chan].ksrM SHL 4+
fmpar_table[chan].sustM SHL 5+
fmpar_table[chan].vibrM SHL 6+
fmpar_table[chan].tremM SHL 7);
opl3out(_instr[01]+_chan_c[chan],fmpar_table[chan].multipC+
fmpar_table[chan].ksrC SHL 4+
fmpar_table[chan].sustC SHL 5+
fmpar_table[chan].vibrC SHL 6+
fmpar_table[chan].tremC SHL 7);
opl3out(_instr[10]+_chan_n[chan],(fmpar_table[chan].connect+
fmpar_table[chan].feedb SHL 1) OR
_panning[panning_table[chan]]);
vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6,
fmpar_table[chan].kslC SHL 6);
set_ins_volume(LO(volume_table[chan]),
HI(volume_table[chan]),chan);
end;
procedure reset_chan_data(chan: Byte);
begin
If (percussion_mode and (chan in [17..20])) then
If channel_flag[chan] then
reset_ins_volume(chan)
else set_ins_volume(0,0,chan)
else
begin
opl3out(_instr[02]+_chan_m[chan],63);
opl3out(_instr[03]+_chan_c[chan],63);
key_on(chan);
opl3out(_instr[04]+_chan_m[chan],BYTE_NULL);
opl3out(_instr[05]+_chan_c[chan],BYTE_NULL);
opl3out(_instr[06]+_chan_m[chan],BYTE_NULL);
opl3out(_instr[07]+_chan_c[chan],BYTE_NULL);
key_off(chan);
update_fmpar(chan);
end;
reset_adsrw[chan] := TRUE;
If (play_status <> isStopped) then
If (event_table[chan].note AND $7f in [1..12*8+1]) then
init_macro_table(chan,event_table[chan].note AND $7f,voice_table[chan],freq_table[chan])
else init_macro_table(chan,0,voice_table[chan],freq_table[chan]);
end;
procedure init_macro_table(chan,note,ins: Byte; freq: Word);
begin
macro_table[chan].fmreg_count := 1;
macro_table[chan].fmreg_pos := 0;
macro_table[chan].fmreg_duration := 0;
macro_table[chan].fmreg_table := ins;
macro_table[chan].arpg_count := 1;
macro_table[chan].arpg_pos := 0;
macro_table[chan].arpg_table := songdata.instr_macros[ins].arpeggio_table;
macro_table[chan].arpg_note := note;
macro_table[chan].vib_count := 1;
macro_table[chan].vib_paused := FALSE;
macro_table[chan].vib_pos := 0;
macro_table[chan].vib_table := songdata.instr_macros[ins].vibrato_table;
macro_table[chan].vib_freq := freq;
macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay;
zero_fq_table[chan] := 0;
end;
procedure output_note(note,ins,chan: Byte;
restart_macro,restart_adsr: Boolean);
var
freq: Word;
begin
If (note = 0) and (ftune_table[chan] = 0) then EXIT;
If NOT (note in [1..12*8+1]) then freq := freq_table[chan]
else begin
freq := nFreq(note-1)+SHORTINT(ins_parameter(ins,12));
If restart_adsr then key_on(chan);
freq_table[chan] := concw(LO(freq_table[chan]),
HI(freq_table[chan]) OR $20);
If channel_flag[chan] then
If is_4op_chan(chan) then
begin
If NOT (percussion_mode and (chan in [17..20])) then
If (ins_parameter(voice_table[chan],10) AND 1 = 1) then
If (volum_bar[chan].lvl < (carrier_vol[chan]+modulator_vol[chan]) DIV 2) then
volum_bar[chan].dir := 1
else
else If (volum_bar[chan].lvl < carrier_vol[chan]) then
volum_bar[chan].dir := 1
else
else If (volum_bar[chan].lvl < modulator_vol[chan]) then
volum_bar[chan].dir := 1;
If NOT (percussion_mode and (PRED(chan) in [17..20])) then
If (ins_parameter(voice_table[PRED(chan)],10) AND 1 = 1) then
If (volum_bar[PRED(chan)].lvl < (carrier_vol[PRED(chan)]+modulator_vol[PRED(chan)]) DIV 2) then
volum_bar[PRED(chan)].dir := 1
else
else If (volum_bar[PRED(chan)].lvl < carrier_vol[PRED(chan)]) then
volum_bar[PRED(chan)].dir := 1
else
else If (volum_bar[PRED(chan)].lvl < modulator_vol[PRED(chan)]) then
volum_bar[PRED(chan)].dir := 1;
If (decay_bar[chan].lvl1 < carrier_vol[chan]) then
decay_bar[chan].dir1 := 1;
If (decay_bar[chan].lvl2 < modulator_vol[chan]) then
decay_bar[chan].dir2 := 1;
If (decay_bar[PRED(chan)].lvl1 < carrier_vol[PRED(chan)]) then
decay_bar[PRED(chan)].dir1 := 1;
If (decay_bar[PRED(chan)].lvl2 < modulator_vol[PRED(chan)]) then
decay_bar[PRED(chan)].dir2 := 1;
If (play_status <> isPlaying) then
begin
volum_bar[chan].dir := -1;
decay_bar[chan].dir1 := -1;
decay_bar[chan].dir2 := -1;
decay_bar[PRED(chan)].dir1 := -1;
decay_bar[PRED(chan)].dir2 := -1;
end;
end
else begin
If NOT (percussion_mode and (chan in [17..20])) then
If (ins_parameter(voice_table[chan],10) AND 1 = 1) then
If (volum_bar[chan].lvl < (carrier_vol[chan]+modulator_vol[chan]) DIV 2) then
volum_bar[chan].dir := 1
else
else If (volum_bar[chan].lvl < carrier_vol[chan]) then
volum_bar[chan].dir := 1
else
else If (volum_bar[chan].lvl < modulator_vol[chan]) then
volum_bar[chan].dir := 1;
If (decay_bar[chan].lvl1 < carrier_vol[chan]) then
decay_bar[chan].dir1 := 1;
If (decay_bar[chan].lvl2 < modulator_vol[chan]) then
decay_bar[chan].dir2 := 1;
If (play_status <> isPlaying) then
begin
volum_bar[chan].dir := -1;
decay_bar[chan].dir1 := -1;
decay_bar[chan].dir2 := -1;
end;
end;
end;
If (ftune_table[chan] = -127) then ftune_table[chan] := 0;
freq := freq+ftune_table[chan];
change_frequency(chan,freq);
If (note <> 0) then
begin
event_table[chan].note := note;
If is_4op_chan(chan) then
event_table[PRED(chan)].note := note;
If restart_macro then
With event_table[chan] do
If NOT (((effect_def = ef_Extended) and
(effect DIV 16 = ef_ex_ExtendedCmd2) and
(effect MOD 16 = ef_ex_cmd2_NoRestart)) or
((effect_def2 = ef_Extended) and
(effect2 DIV 16 = ef_ex_ExtendedCmd2) and
(effect2 MOD 16 = ef_ex_cmd2_NoRestart))) then
init_macro_table(chan,note,ins,freq)
else macro_table[chan].arpg_note := note;
end;
end;
procedure generate_custom_vibrato(value: Byte);
const
vibtab_size: array[0..15] of Byte = (
16,16,16,16,32,32,32,32,64,64,64,64,128,128,128,128);
var
mul_r: Real;
mul_b: Byte;
idx,idx2: Byte;
function min0(value: Longint): Longint;
begin
If (value >= 0) then min0 := value
else min0 := 0;
end;
begin
Case value of
// set default speed table
0: begin
vibtrem_table_size := def_vibtrem_table_size;
Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table));
end;
// set custom speed table (fixed size = 32)
1..239:
begin
vibtrem_table_size := def_vibtrem_table_size;
mul_r := value/16;
For idx2 := 0 to 7 do
begin
vibtrem_table[idx2*32] := 0;
For idx := 1 to 16 do
vibtrem_table[idx2*32+idx] := ROUND(idx*mul_r);
For idx := 17 to 31 do
vibtrem_table[idx2*32+idx] := ROUND((32-idx)*mul_r);
end;
end;
// set custom speed table (speed factor = 1-4)
240..255:
begin
vibtrem_speed_factor := SUCC((value-240) MOD 4);
vibtrem_table_size := 2*vibtab_size[value-240];
mul_b := 256 DIV (vibtab_size[value-240]);
For idx2 := 0 to PRED(128 DIV vibtab_size[value-240]) do
begin
vibtrem_table[2*vibtab_size[value-240]*idx2] := 0;
For idx := 1 to vibtab_size[value-240] do
vibtrem_table[2*vibtab_size[value-240]*idx2+idx] :=
min0(idx*mul_b-1);
For idx := vibtab_size[value-240]+1 to
2*vibtab_size[value-240]-1 do
vibtrem_table[2*vibtab_size[value-240]*idx2+idx] :=
min0((2*vibtab_size[value-240]-idx)*mul_b-1);
end;
end;
end;
end;
procedure update_fine_effects(chan: Byte); forward;
procedure play_line;
var
chan,idx: Byte;
event: array[1..20] of tCHUNK;
eLo,eHi,eLo2,eHi2: array[1..20] of Byte;
tporta_flag: Boolean;
function no_loop(current_chan,current_line: Byte): Boolean;
var
result: Boolean;
chan: Byte;
begin
result := TRUE;
For chan := 1 to PRED(current_chan) do
If (loop_table[chan][current_line] <> 0) and
(loop_table[chan][current_line] <> BYTE_NULL) then
begin
result := FALSE;
BREAK;
end;
no_loop := result;
end;
begin
If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and
(current_order <> last_order) then
begin
FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL);
FillChar(loop_table,SizeOf(loop_table),BYTE_NULL);
last_order := current_order;
end;
For chan := 1 to songdata.nm_tracks do
If channel_flag[chan] and reset_adsrw[chan] then
begin
update_modulator_adsrw(chan);
update_carrier_adsrw(chan);
reset_adsrw[chan] := FALSE;
end;
For chan := 1 to songdata.nm_tracks do
begin
event[chan] := pattdata^[current_pattern DIV 8][current_pattern MOD 8]
[chan][current_line];
If (effect_table[chan] <> 0) then last_effect[chan] := effect_table[chan];
If (glfsld_table[chan] <> 0) then effect_table[chan] := glfsld_table[chan]
else effect_table[chan] := effect_table[chan] AND $0ff00;
If (effect_table2[chan] <> 0) then last_effect2[chan] := effect_table2[chan];
If (glfsld_table2[chan] <> 0) then effect_table2[chan] := glfsld_table2[chan]
else effect_table2[chan] := effect_table2[chan] AND $0ff00;
ftune_table[chan] := 0;
If (event[chan].note = BYTE_NULL) then
event[chan].note := event_table[chan].note OR keyoff_flag
else If (event[chan].note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then
event[chan].note := event[chan].note-fixed_note_flag;
If (event[chan].note <> 0) or
(event[chan].effect_def <> 0) or
(event[chan].effect_def2 <> 0) or
((event[chan].effect_def = 0) and (event[chan].effect <> 0)) or
((event[chan].effect_def2 = 0) and (event[chan].effect2 <> 0)) then
event_new[chan] := TRUE
else event_new[chan] := FALSE;
If (event[chan].note <> 0) or
(event[chan].instr_def <> 0) or
(event[chan].effect_def+event[chan].effect <> 0) or
(event[chan].effect_def2+event[chan].effect2 <> 0) then
begin
event_table[chan].effect_def := event[chan].effect_def;
event_table[chan].effect := event[chan].effect;
event_table[chan].effect_def2 := event[chan].effect_def2;
event_table[chan].effect2 := event[chan].effect2;
end;
If (event[chan].instr_def <> 0) then
If NOT is_data_empty(songdata.instr_data[event[chan].instr_def],
INSTRUMENT_SIZE) then
set_ins_data(event[chan].instr_def,chan)
else begin
release_sustaining_sound(chan);
set_ins_data(event[chan].instr_def,chan);
end;
If NOT (event[chan].effect_def in [ef_Vibrato,ef_ExtraFineVibrato,
ef_VibratoVolSlide,ef_VibratoVSlideFine]) then
FillChar(vibr_table[chan],SizeOf(vibr_table[chan]),0);
If NOT (event[chan].effect_def2 in [ef_Vibrato,ef_ExtraFineVibrato,
ef_VibratoVolSlide,ef_VibratoVSlideFine]) then
FillChar(vibr_table2[chan],SizeOf(vibr_table2[chan]),0);
If NOT (event[chan].effect_def in [ef_RetrigNote,ef_MultiRetrigNote]) then
FillChar(retrig_table[chan],SizeOf(retrig_table[chan]),0);
If NOT (event[chan].effect_def2 in [ef_RetrigNote,ef_MultiRetrigNote]) then
FillChar(retrig_table2[chan],SizeOf(retrig_table2[chan]),0);
If NOT (event[chan].effect_def in [ef_Tremolo,ef_ExtraFineTremolo]) then
FillChar(trem_table[chan],SizeOf(trem_table[chan]),0);
If NOT (event[chan].effect_def2 in [ef_Tremolo,ef_ExtraFineTremolo]) then
FillChar(trem_table2[chan],SizeOf(trem_table2[chan]),0);
If NOT (((event[chan].effect_def = ef_Arpeggio) and (event[chan].effect <> 0)) or
(event[chan].effect_def = ef_ExtraFineArpeggio)) and
(arpgg_table[chan].note <> 0) and (arpgg_table[chan].state <> 1) then
begin
arpgg_table[chan].state := 1;
change_frequency(chan,nFreq(arpgg_table[chan].note-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
end
else If NOT (((event[chan].effect_def2 = ef_Arpeggio) and (event[chan].effect2 <> 0)) or
(event[chan].effect_def2 = ef_ExtraFineArpeggio)) and
(arpgg_table2[chan].note <> 0) and (arpgg_table2[chan].state <> 1) then
begin
arpgg_table2[chan].state := 1;
change_frequency(chan,nFreq(arpgg_table2[chan].note-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
end;
If (event[chan].effect_def = ef_GlobalFSlideUp) or
(event[chan].effect_def = ef_GlobalFSlideDown) then
begin
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd*16+ef_ex_cmd_ForceBpmSld) then
begin
If (event[chan].effect_def = ef_GlobalFSlideUp) then
update_playback_speed(event[chan].effect)
else update_playback_speed(-event[chan].effect);
end
else
begin
Case event[chan].effect_def of
ef_GlobalFSlideUp:
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
event[chan].effect)
else If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
effect_table[chan] := concw(ef_FSlideUpFine,event[chan].effect)
else effect_table[chan] := concw(ef_FSlideUp,event[chan].effect);
ef_GlobalFSlideDown:
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
event[chan].effect)
else If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
effect_table[chan] := concw(ef_FSlideDownFine,event[chan].effect)
else effect_table[chan] := concw(ef_FSlideDown,event[chan].effect);
end;
For idx := chan to songdata.nm_tracks do
begin
fslide_table[idx] := event[chan].effect;
glfsld_table[idx] := effect_table[chan];
end;
end;
end;
If (event[chan].effect_def2 = ef_GlobalFSlideUp) or
(event[chan].effect_def2 = ef_GlobalFSlideDown) then
begin
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd*16+ef_ex_cmd_ForceBpmSld) then
begin
If (event[chan].effect_def2 = ef_GlobalFSlideUp) then
update_playback_speed(event[chan].effect2)
else update_playback_speed(-event[chan].effect2);
end
else
begin
Case event[chan].effect_def2 of
ef_GlobalFSlideUp:
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
event[chan].effect2)
else If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
effect_table2[chan] := concw(ef_FSlideUpFine,event[chan].effect2)
else effect_table2[chan] := concw(ef_FSlideUp,event[chan].effect2);
ef_GlobalFSlideDown:
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
event[chan].effect2)
else If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
effect_table2[chan] := concw(ef_FSlideDownFine,event[chan].effect2)
else effect_table2[chan] := concw(ef_FSlideDown,event[chan].effect2);
end;
For idx := chan to songdata.nm_tracks do
begin
fslide_table2[idx] := event[chan].effect2;
glfsld_table2[idx] := effect_table2[chan];
end;
end;
end;
end;
For chan := 1 to songdata.nm_tracks do
begin
If event_new[chan] and is_4op_chan(chan) then
If (chan in _4op_tracks_hi) then
event_new[SUCC(chan)] := TRUE
else event_new[PRED(chan)] := TRUE;
If (tremor_table[chan].pos <> 0) and
(event[chan].effect_def <> ef_Tremor) then
begin
tremor_table[chan].pos := 0;
set_ins_volume(LO(tremor_table[chan].volume),
HI(tremor_table[chan].volume),chan);
end;
If (tremor_table2[chan].pos <> 0) and
(event[chan].effect_def2 <> ef_Tremor) then
begin
tremor_table2[chan].pos := 0;
set_ins_volume(LO(tremor_table2[chan].volume),
HI(tremor_table2[chan].volume),chan);
end;
eLo[chan] := LO(last_effect[chan]);
eHi[chan] := HI(last_effect[chan]);
eLo2[chan] := LO(last_effect2[chan]);
eHi2[chan] := HI(last_effect2[chan]);
end;
For chan := 1 to songdata.nm_tracks do
Case event[chan].effect_def of
ef_Arpeggio,
ef_ExtraFineArpeggio,
ef_ArpggVSlide,
ef_ArpggVSlideFine:
If (event[chan].effect_def <> ef_Arpeggio) or
(event[chan].effect <> 0) then
begin
Case event[chan].effect_def of
ef_Arpeggio:
effect_table[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect);
ef_ExtraFineArpeggio:
effect_table[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect);
ef_ArpggVSlide,
ef_ArpggVSlideFine:
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
else effect_table[chan] := effect_table[chan] AND $0ff00;
end;
If (event[chan].note AND $7f in [1..12*8+1]) then
begin
arpgg_table[chan].state := 0;
arpgg_table[chan].note := event[chan].note AND $7f;
If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
begin
arpgg_table[chan].add1 := event[chan].effect DIV 16;
arpgg_table[chan].add2 := event[chan].effect MOD 16;
end;
end
else If (event[chan].note = 0) and
(event_table[chan].note AND $7f in [1..12*8+1]) then
begin
If NOT (eLo[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio,
ef_ArpggVSlide,ef_ArpggVSlideFine]) then
arpgg_table[chan].state := 0;
arpgg_table[chan].note := event_table[chan].note AND $7f;
If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
begin
arpgg_table[chan].add1 := event[chan].effect DIV 16;
arpgg_table[chan].add2 := event[chan].effect MOD 16;
end;
end
else effect_table[chan] := 0;
end;
ef_FSlideUp,
ef_FSlideDown,
ef_FSlideUpFine,
ef_FSlideDownFine:
begin
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect);
fslide_table[chan] := event[chan].effect;
end;
ef_FSlideUpVSlide,
ef_FSlUpVSlF,
ef_FSlideDownVSlide,
ef_FSlDownVSlF,
ef_FSlUpFineVSlide,
ef_FSlUpFineVSlF,
ef_FSlDownFineVSlide,
ef_FSlDownFineVSlF:
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide,
ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF,
ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
else effect_table[chan] := effect_table[chan] AND $0ff00;
ef_TonePortamento:
If (event[chan].note in [1..12*8+1]) then
begin
If (event[chan].effect <> 0) then
effect_table[chan] := concw(ef_TonePortamento,event[chan].effect)
else If (eLo[chan] = ef_TonePortamento) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(ef_TonePortamento,eHi[chan])
else effect_table[chan] := ef_TonePortamento;
porta_table[chan].speed := HI(effect_table[chan]);
porta_table[chan].freq := nFreq(event[chan].note-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12));
end
else If (eLo[chan] = ef_TonePortamento) then
begin
If (event[chan].effect <> 0) then
effect_table[chan] := concw(ef_TonePortamento,event[chan].effect)
else If (eLo[chan] = ef_TonePortamento) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(ef_TonePortamento,eHi[chan])
else effect_table[chan] := ef_TonePortamento;
porta_table[chan].speed := HI(effect_table[chan]);
end;
ef_TPortamVolSlide,
ef_TPortamVSlideFine:
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
else effect_table[chan] := effect_table[chan] AND $0ff00;
ef_Vibrato,
ef_ExtraFineVibrato:
begin
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
else effect_table[chan] := event[chan].effect_def;
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
vibr_table[chan].fine := TRUE;
vibr_table[chan].speed := HI(effect_table[chan]) DIV 16;
vibr_table[chan].depth := HI(effect_table[chan]) MOD 16;
end;
ef_Tremolo,
ef_ExtraFineTremolo:
begin
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and
(eHi[chan] <> 0) then
effect_table[chan] := concw(event[chan].effect_def,eHi[chan])
else effect_table[chan] := event[chan].effect_def;
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
trem_table[chan].fine := TRUE;
trem_table[chan].speed := HI(effect_table[chan]) DIV 16;
trem_table[chan].depth := HI(effect_table[chan]) MOD 16;
end;
ef_VibratoVolSlide,
ef_VibratoVSlideFine:
begin
If (event[chan].effect <> 0) then
effect_table[chan] := concw(event[chan].effect_def,event[chan].effect)
else If (eLo[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and
(HI(effect_table[chan]) <> 0) then
effect_table[chan] := concw(event[chan].effect_def,HI(effect_table[chan]))
else effect_table[chan] := effect_table[chan] AND $0ff00;
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
vibr_table[chan].fine := TRUE;
end;
ef_SetCarrierVol:
set_ins_volume(BYTE_NULL,63-event[chan].effect,chan);
ef_SetModulatorVol:
set_ins_volume(63-event[chan].effect,BYTE_NULL,chan);
ef_SetInsVolume:
If _4op_vol_valid_chan(chan) then
set_ins_volume_4op(63-event[chan].effect,chan)
else If percussion_mode and (chan in [17..20]) then
set_ins_volume(63-event[chan].effect,BYTE_NULL,chan)
else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(BYTE_NULL,63-event[chan].effect,chan)
else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan);
ef_ForceInsVolume:
If percussion_mode and (chan in [17..20]) then
set_ins_volume(63-event[chan].effect,BYTE_NULL,chan)
else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect),63-event[chan].effect,chan)
else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan);
ef_PositionJump:
If no_loop(chan,current_line) then
begin
pattern_break := TRUE;
next_line := pattern_break_flag+chan;
end;
ef_PatternBreak:
If no_loop(chan,current_line) then
begin
pattern_break := TRUE;
seek_pattern_break := TRUE;
next_line := max(event[chan].effect,PRED(songdata.patt_len));
end;
ef_SetSpeed:
speed := event[chan].effect;
ef_SetTempo:
update_timer(event[chan].effect);
ef_SetWaveform:
begin
If (event[chan].effect DIV 16 in [0..7]) then
begin
fmpar_table[chan].adsrw_car.wform := event[chan].effect DIV 16;
update_carrier_adsrw(chan);
end;
If (event[chan].effect MOD 16 in [0..7]) then
begin
fmpar_table[chan].adsrw_mod.wform := event[chan].effect MOD 16;
update_modulator_adsrw(chan);
end;
end;
ef_VolSlide:
effect_table[chan] := concw(ef_VolSlide,event[chan].effect);
ef_VolSlideFine:
effect_table[chan] := concw(ef_VolSlideFine,event[chan].effect);
ef_RetrigNote:
If (event[chan].effect <> 0) then
begin
If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
retrig_table[chan] := 1;
effect_table[chan] := concw(ef_RetrigNote,event[chan].effect);
end;
ef_SetGlobalVolume:
begin
global_volume := event[chan].effect;
set_global_volume;
end;
ef_MultiRetrigNote:
If (event[chan].effect DIV 16 <> 0) then
begin
If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
retrig_table[chan] := 1;
effect_table[chan] := concw(ef_MultiRetrigNote,event[chan].effect);
end;
ef_Tremor:
If (event[chan].effect DIV 16 <> 0) and
(event[chan].effect MOD 16 <> 0) then
begin
If (eLo[chan] <> ef_Tremor) then
begin
tremor_table[chan].pos := 0;
tremor_table[chan].volume := volume_table[chan];
end;
effect_table[chan] := concw(ef_Tremor,event[chan].effect);
end;
ef_Extended:
Case (event[chan].effect DIV 16) of
ef_ex_SetTremDepth:
Case (event[chan].effect MOD 16) of
0: begin
opl3out(_instr[11],misc_register AND $07f);
current_tremolo_depth := 0;
end;
1: begin
opl3out(_instr[11],misc_register OR $080);
current_tremolo_depth := 1;
end;
end;
ef_ex_SetVibDepth:
Case (event[chan].effect MOD 16) of
0: begin
opl3out(_instr[11],misc_register AND $0bf);
current_vibrato_depth := 0;
end;
1: begin
opl3out(_instr[11],misc_register OR $040);
current_vibrato_depth := 1;
end;
end;
ef_ex_SetAttckRateM:
begin
fmpar_table[chan].adsrw_mod.attck := event[chan].effect MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetDecayRateM:
begin
fmpar_table[chan].adsrw_mod.dec := event[chan].effect MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetSustnLevelM:
begin
fmpar_table[chan].adsrw_mod.sustn := event[chan].effect MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetRelRateM:
begin
fmpar_table[chan].adsrw_mod.rel := event[chan].effect MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetAttckRateC:
begin
fmpar_table[chan].adsrw_car.attck := event[chan].effect MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetDecayRateC:
begin
fmpar_table[chan].adsrw_car.dec := event[chan].effect MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetSustnLevelC:
begin
fmpar_table[chan].adsrw_car.sustn := event[chan].effect MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetRelRateC:
begin
fmpar_table[chan].adsrw_car.rel := event[chan].effect MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetFeedback:
begin
fmpar_table[chan].feedb := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex_SetPanningPos:
begin
panning_table[chan] := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex_PatternLoop,
ef_ex_PatternLoopRec:
If (event[chan].effect MOD 16 = 0) then
loopbck_table[chan] := current_line
else If (loopbck_table[chan] <> BYTE_NULL) then
begin
If (loop_table[chan][current_line] = BYTE_NULL) then
loop_table[chan][current_line] := event[chan].effect MOD 16;
If (loop_table[chan][current_line] <> 0) then
begin
pattern_break := TRUE;
next_line := pattern_loop_flag+chan;
end
else If (event[chan].effect DIV 16 = ef_ex_PatternLoopRec) then
loop_table[chan][current_line] := BYTE_NULL;
end;
ef_ex_ExtendedCmd:
Case (event[chan].effect MOD 16) of
ef_ex_cmd_MKOffLoopDi: keyoff_loop[chan] := FALSE;
ef_ex_cmd_MKOffLoopEn: keyoff_loop[chan] := TRUE;
ef_ex_cmd_TPortaFKdis: portaFK_table[chan] := FALSE;
ef_ex_cmd_TPortaFKenb: portaFK_table[chan] := TRUE;
ef_ex_cmd_RestartEnv:
begin
key_on(chan);
change_freq(chan,freq_table[chan]);
end;
ef_ex_cmd_4opVlockOff:
If is_4op_chan(chan) then
begin
vol4op_lock[chan] := FALSE;
If (chan in _4op_tracks_hi) then
vol4op_lock[SUCC(chan)] := FALSE
else vol4op_lock[PRED(chan)] := FALSE;
end;
ef_ex_cmd_4opVlockOn:
If is_4op_chan(chan) then
begin
vol4op_lock[chan] := TRUE;
If (chan in _4op_tracks_hi) then
vol4op_lock[SUCC(chan)] := TRUE
else vol4op_lock[PRED(chan)] := TRUE;
end;
end;
ef_ex_ExtendedCmd2:
Case (event[chan].effect MOD 16) of
ef_ex_cmd2_RSS: release_sustaining_sound(chan);
ef_ex_cmd2_ResetVol: reset_ins_volume(chan);
ef_ex_cmd2_LockVol: volume_lock [chan] := TRUE;
ef_ex_cmd2_UnlockVol: volume_lock [chan] := FALSE;
ef_ex_cmd2_LockVP: peak_lock [chan] := TRUE;
ef_ex_cmd2_UnlockVP: peak_lock [chan] := FALSE;
ef_ex_cmd2_VSlide_def: volslide_type[chan] := 0;
ef_ex_cmd2_LockPan: pan_lock [chan] := TRUE;
ef_ex_cmd2_UnlockPan: pan_lock [chan] := FALSE;
ef_ex_cmd2_VibrOff: change_frequency(chan,freq_table[chan]);
ef_ex_cmd2_TremOff:
If is_4op_chan(chan) then
set_ins_volume_4op(BYTE_NULL,chan)
else set_ins_volume(LO(volume_table[chan]),
HI(volume_table[chan]),chan);
ef_ex_cmd2_VSlide_car:
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+
ef_ex_cmd2_VSlide_mod) then
volslide_type[chan] := 3
else volslide_type[chan] := 1;
ef_ex_cmd2_VSlide_mod:
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 = ef_ex_ExtendedCmd2*16+
ef_ex_cmd2_VSlide_car) then
volslide_type[chan] := 3
else volslide_type[chan] := 2;
end;
end;
ef_Extended2:
Case (event[chan].effect DIV 16) of
ef_ex2_PatDelayFrame,
ef_ex2_PatDelayRow:
begin
pattern_delay := TRUE;
If (event[chan].effect DIV 16 = ef_ex2_PatDelayFrame) then
tickD := (event[chan].effect MOD 16)
else tickD := speed*(event[chan].effect MOD 16);
end;
ef_ex2_NoteDelay:
begin
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0);
notedel_table[chan] := event[chan].effect MOD 16;
end;
ef_ex2_NoteCut:
begin
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0);
notecut_table[chan] := event[chan].effect MOD 16;
end;
ef_ex2_FineTuneUp:
Inc(ftune_table[chan],event[chan].effect MOD 16);
ef_ex2_FineTuneDown:
Dec(ftune_table[chan],event[chan].effect MOD 16);
ef_ex2_GlVolSlideUp:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp,
event[chan].effect MOD 16);
ef_ex2_GlVolSlideDn:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn,
event[chan].effect MOD 16);
ef_ex2_GlVolSlideUpF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF,
event[chan].effect MOD 16);
ef_ex2_GlVolSlideDnF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF,
event[chan].effect MOD 16);
ef_ex2_GlVolSldUpXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF,
event[chan].effect MOD 16);
ef_ex2_GlVolSldDnXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF,
event[chan].effect MOD 16);
ef_ex2_VolSlideUpXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF,
event[chan].effect MOD 16);
ef_ex2_VolSlideDnXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF,
event[chan].effect MOD 16);
ef_ex2_FreqSlideUpXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
event[chan].effect MOD 16);
ef_ex2_FreqSlideDnXF:
effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
event[chan].effect MOD 16);
end;
ef_Extended3:
Case (event[chan].effect DIV 16) of
ef_ex3_SetConnection:
begin
fmpar_table[chan].connect := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetMultipM:
begin
fmpar_table[chan].multipM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKslM:
begin
fmpar_table[chan].kslM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetTremoloM:
begin
fmpar_table[chan].tremM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetVibratoM:
begin
fmpar_table[chan].vibrM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKsrM:
begin
fmpar_table[chan].ksrM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetSustainM:
begin
fmpar_table[chan].sustM := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetMultipC:
begin
fmpar_table[chan].multipC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKslC:
begin
fmpar_table[chan].kslC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetTremoloC:
begin
fmpar_table[chan].tremC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetVibratoC:
begin
fmpar_table[chan].vibrC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKsrC:
begin
fmpar_table[chan].ksrC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetSustainC:
begin
fmpar_table[chan].sustC := event[chan].effect MOD 16;
update_fmpar(chan);
end;
end;
end;
For chan := 1 to songdata.nm_tracks do
Case event[chan].effect_def2 of
ef_Arpeggio,
ef_ExtraFineArpeggio,
ef_ArpggVSlide,
ef_ArpggVSlideFine:
If (event[chan].effect_def2 <> ef_Arpeggio) or
(event[chan].effect2 <> 0) then
begin
Case event[chan].effect_def2 of
ef_Arpeggio:
effect_table2[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect2);
ef_ExtraFineArpeggio:
effect_table2[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect2);
ef_ArpggVSlide,
ef_ArpggVSlideFine:
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
else effect_table2[chan] := effect_table2[chan] AND $0ff00;
end;
If (event[chan].note AND $7f in [1..12*8+1]) then
begin
arpgg_table2[chan].state := 0;
arpgg_table2[chan].note := event[chan].note AND $7f;
If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
begin
arpgg_table2[chan].add1 := event[chan].effect2 DIV 16;
arpgg_table2[chan].add2 := event[chan].effect2 MOD 16;
end;
end
else If (event[chan].note = 0) and
(event_table[chan].note AND $7f in [1..12*8+1]) then
begin
If NOT (eLo2[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio,
ef_ArpggVSlide,ef_ArpggVSlideFine]) then
arpgg_table2[chan].state := 0;
arpgg_table2[chan].note := event_table[chan].note AND $7f;
If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then
begin
arpgg_table2[chan].add1 := event[chan].effect2 DIV 16;
arpgg_table2[chan].add2 := event[chan].effect2 MOD 16;
end;
end
else effect_table2[chan] := 0;
end;
ef_FSlideUp,
ef_FSlideDown,
ef_FSlideUpFine,
ef_FSlideDownFine:
begin
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2);
fslide_table2[chan] := event[chan].effect2;
end;
ef_FSlideUpVSlide,
ef_FSlUpVSlF,
ef_FSlideDownVSlide,
ef_FSlDownVSlF,
ef_FSlUpFineVSlide,
ef_FSlUpFineVSlF,
ef_FSlDownFineVSlide,
ef_FSlDownFineVSlF:
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide,
ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF,
ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
else effect_table2[chan] := effect_table2[chan] AND $0ff00;
ef_TonePortamento:
If (event[chan].note in [1..12*8+1]) then
begin
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2)
else If (eLo2[chan] = ef_TonePortamento) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan])
else effect_table2[chan] := ef_TonePortamento;
porta_table2[chan].speed := HI(effect_table2[chan]);
porta_table2[chan].freq := nFreq(event[chan].note-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12));
end
else If (eLo2[chan] = ef_TonePortamento) then
begin
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2)
else If (eLo2[chan] = ef_TonePortamento) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan])
else effect_table2[chan] := ef_TonePortamento;
porta_table2[chan].speed := HI(effect_table2[chan]);
end;
ef_TPortamVolSlide,
ef_TPortamVSlideFine:
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
else effect_table2[chan] := effect_table2[chan] AND $0ff00;
ef_Vibrato,
ef_ExtraFineVibrato:
begin
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
else effect_table2[chan] := event[chan].effect_def2;
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
vibr_table2[chan].fine := TRUE;
vibr_table2[chan].speed := HI(effect_table2[chan]) DIV 16;
vibr_table2[chan].depth := HI(effect_table2[chan]) MOD 16;
end;
ef_Tremolo,
ef_ExtraFineTremolo:
begin
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and
(eHi2[chan] <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan])
else effect_table2[chan] := event[chan].effect_def2;
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then
trem_table2[chan].fine := TRUE;
trem_table2[chan].speed := HI(effect_table2[chan]) DIV 16;
trem_table2[chan].depth := HI(effect_table2[chan]) MOD 16;
end;
ef_VibratoVolSlide,
ef_VibratoVSlideFine:
begin
If (event[chan].effect2 <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2)
else If (eLo2[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and
(HI(effect_table2[chan]) <> 0) then
effect_table2[chan] := concw(event[chan].effect_def2,HI(effect_table2[chan]))
else effect_table2[chan] := effect_table2[chan] AND $0ff00;
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then
vibr_table2[chan].fine := TRUE;
end;
ef_SetCarrierVol:
set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan);
ef_SetModulatorVol:
set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan);
ef_SetInsVolume:
If _4op_vol_valid_chan(chan) then
set_ins_volume_4op(63-event[chan].effect2,chan)
else If percussion_mode and (chan in [17..20]) then
set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan)
else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan)
else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan);
ef_ForceInsVolume:
If percussion_mode and (chan in [17..20]) then
set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan)
else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect2),63-event[chan].effect2,chan)
else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan);
ef_PositionJump:
If no_loop(chan,current_line) then
begin
pattern_break := TRUE;
next_line := pattern_break_flag+chan;
end;
ef_PatternBreak:
If no_loop(chan,current_line) then
begin
pattern_break := TRUE;
seek_pattern_break := TRUE;
next_line := max(event[chan].effect2,PRED(songdata.patt_len));
end;
ef_SetSpeed:
speed := event[chan].effect2;
ef_SetTempo:
update_timer(event[chan].effect2);
ef_SetWaveform:
begin
If (event[chan].effect2 DIV 16 in [0..7]) then
begin
fmpar_table[chan].adsrw_car.wform := event[chan].effect2 DIV 16;
update_carrier_adsrw(chan);
end;
If (event[chan].effect2 MOD 16 in [0..7]) then
begin
fmpar_table[chan].adsrw_mod.wform := event[chan].effect2 MOD 16;
update_modulator_adsrw(chan);
end;
end;
ef_VolSlide:
effect_table2[chan] := concw(ef_VolSlide,event[chan].effect2);
ef_VolSlideFine:
effect_table2[chan] := concw(ef_VolSlideFine,event[chan].effect2);
ef_RetrigNote:
If (event[chan].effect2 <> 0) then
begin
If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
retrig_table2[chan] := 1;
effect_table2[chan] := concw(ef_RetrigNote,event[chan].effect2);
end;
ef_SetGlobalVolume:
begin
global_volume := event[chan].effect2;
set_global_volume;
end;
ef_MultiRetrigNote:
If (event[chan].effect2 DIV 16 <> 0) then
begin
If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then
retrig_table2[chan] := 1;
effect_table2[chan] := concw(ef_MultiRetrigNote,event[chan].effect2);
end;
ef_Tremor:
If (event[chan].effect2 DIV 16 <> 0) and
(event[chan].effect2 MOD 16 <> 0) then
begin
If (eLo2[chan] <> ef_Tremor) then
begin
tremor_table2[chan].pos := 0;
tremor_table2[chan].volume := volume_table[chan];
end;
effect_table2[chan] := concw(ef_Tremor,event[chan].effect2);
end;
ef_Extended:
Case (event[chan].effect2 DIV 16) of
ef_ex_SetTremDepth:
Case (event[chan].effect2 MOD 16) of
0: begin
opl3out(_instr[11],misc_register AND $07f);
current_tremolo_depth := 0;
end;
1: begin
opl3out(_instr[11],misc_register OR $080);
current_tremolo_depth := 1;
end;
end;
ef_ex_SetVibDepth:
Case (event[chan].effect2 MOD 16) of
0: begin
opl3out(_instr[11],misc_register AND $0bf);
current_vibrato_depth := 0;
end;
1: begin
opl3out(_instr[11],misc_register OR $040);
current_vibrato_depth := 1;
end;
end;
ef_ex_SetAttckRateM:
begin
fmpar_table[chan].adsrw_mod.attck := event[chan].effect2 MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetDecayRateM:
begin
fmpar_table[chan].adsrw_mod.dec := event[chan].effect2 MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetSustnLevelM:
begin
fmpar_table[chan].adsrw_mod.sustn := event[chan].effect2 MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetRelRateM:
begin
fmpar_table[chan].adsrw_mod.rel := event[chan].effect2 MOD 16;
update_modulator_adsrw(chan);
end;
ef_ex_SetAttckRateC:
begin
fmpar_table[chan].adsrw_car.attck := event[chan].effect2 MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetDecayRateC:
begin
fmpar_table[chan].adsrw_car.dec := event[chan].effect2 MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetSustnLevelC:
begin
fmpar_table[chan].adsrw_car.sustn := event[chan].effect2 MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetRelRateC:
begin
fmpar_table[chan].adsrw_car.rel := event[chan].effect2 MOD 16;
update_carrier_adsrw(chan);
end;
ef_ex_SetFeedback:
begin
fmpar_table[chan].feedb := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex_SetPanningPos:
begin
panning_table[chan] := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex_PatternLoop,
ef_ex_PatternLoopRec:
If (event[chan].effect2 MOD 16 = 0) then
loopbck_table[chan] := current_line
else If (loopbck_table[chan] <> BYTE_NULL) then
begin
If (loop_table[chan][current_line] = BYTE_NULL) then
loop_table[chan][current_line] := event[chan].effect2 MOD 16;
If (loop_table[chan][current_line] <> 0) then
begin
pattern_break := TRUE;
next_line := pattern_loop_flag+chan;
end
else If (event[chan].effect2 DIV 16 = ef_ex_PatternLoopRec) then
loop_table[chan][current_line] := BYTE_NULL;
end;
ef_ex_ExtendedCmd:
Case (event[chan].effect2 MOD 16) of
ef_ex_cmd_MKOffLoopDi: keyoff_loop[chan] := FALSE;
ef_ex_cmd_MKOffLoopEn: keyoff_loop[chan] := TRUE;
ef_ex_cmd_TPortaFKdis: portaFK_table[chan] := FALSE;
ef_ex_cmd_TPortaFKenb: portaFK_table[chan] := TRUE;
ef_ex_cmd_RestartEnv:
begin
key_on(chan);
change_freq(chan,freq_table[chan]);
end;
ef_ex_cmd_4opVlockOff:
If is_4op_chan(chan) then
begin
vol4op_lock[chan] := FALSE;
If (chan in _4op_tracks_hi) then
vol4op_lock[SUCC(chan)] := FALSE
else vol4op_lock[PRED(chan)] := FALSE;
end;
ef_ex_cmd_4opVlockOn:
If is_4op_chan(chan) then
begin
vol4op_lock[chan] := TRUE;
If (chan in _4op_tracks_hi) then
vol4op_lock[SUCC(chan)] := TRUE
else vol4op_lock[PRED(chan)] := TRUE;
end;
end;
ef_ex_ExtendedCmd2:
Case (event[chan].effect2 MOD 16) of
ef_ex_cmd2_RSS: release_sustaining_sound(chan);
ef_ex_cmd2_ResetVol: reset_ins_volume(chan);
ef_ex_cmd2_LockVol: volume_lock [chan] := TRUE;
ef_ex_cmd2_UnlockVol: volume_lock [chan] := FALSE;
ef_ex_cmd2_LockVP: peak_lock [chan] := TRUE;
ef_ex_cmd2_UnlockVP: peak_lock [chan] := FALSE;
ef_ex_cmd2_VSlide_def: volslide_type[chan] := 0;
ef_ex_cmd2_LockPan: pan_lock [chan] := TRUE;
ef_ex_cmd2_UnlockPan: pan_lock [chan] := FALSE;
ef_ex_cmd2_VibrOff: change_frequency(chan,freq_table[chan]);
ef_ex_cmd2_TremOff:
If _4op_vol_valid_chan(chan) then
set_ins_volume_4op(BYTE_NULL,chan)
else set_ins_volume(LO(volume_table[chan]),
HI(volume_table[chan]),chan);
ef_ex_cmd2_VSlide_car:
If NOT ((event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+
ef_ex_cmd2_VSlide_mod)) then
volslide_type[chan] := 1;
ef_ex_cmd2_VSlide_mod:
If NOT ((event[chan].effect_def = ef_Extended) and
(event[chan].effect = ef_ex_ExtendedCmd2*16+
ef_ex_cmd2_VSlide_car)) then
volslide_type[chan] := 2;
end;
end;
ef_Extended2:
Case (event[chan].effect2 DIV 16) of
ef_ex2_PatDelayFrame,
ef_ex2_PatDelayRow:
begin
pattern_delay := TRUE;
If (event[chan].effect2 DIV 16 = ef_ex2_PatDelayFrame) then
tickD := (event[chan].effect2 MOD 16)
else tickD := speed*(event[chan].effect2 MOD 16);
end;
ef_ex2_NoteDelay:
begin
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0);
notedel_table[chan] := event[chan].effect2 MOD 16;
end;
ef_ex2_NoteCut:
begin
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0);
notecut_table[chan] := event[chan].effect2 MOD 16;
end;
ef_ex2_FineTuneUp:
Inc(ftune_table[chan],event[chan].effect2 MOD 16);
ef_ex2_FineTuneDown:
Dec(ftune_table[chan],event[chan].effect2 MOD 16);
ef_ex2_GlVolSlideUp:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp,
event[chan].effect2 MOD 16);
ef_ex2_GlVolSlideDn:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn,
event[chan].effect2 MOD 16);
ef_ex2_GlVolSlideUpF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF,
event[chan].effect2 MOD 16);
ef_ex2_GlVolSlideDnF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF,
event[chan].effect2 MOD 16);
ef_ex2_GlVolSldUpXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF,
event[chan].effect2 MOD 16);
ef_ex2_GlVolSldDnXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF,
event[chan].effect2 MOD 16);
ef_ex2_VolSlideUpXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF,
event[chan].effect2 MOD 16);
ef_ex2_VolSlideDnXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF,
event[chan].effect2 MOD 16);
ef_ex2_FreqSlideUpXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF,
event[chan].effect2 MOD 16);
ef_ex2_FreqSlideDnXF:
effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF,
event[chan].effect2 MOD 16);
end;
ef_Extended3:
Case (event[chan].effect2 DIV 16) of
ef_ex3_SetConnection:
begin
fmpar_table[chan].connect := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetMultipM:
begin
fmpar_table[chan].multipM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKslM:
begin
fmpar_table[chan].kslM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetTremoloM:
begin
fmpar_table[chan].tremM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetVibratoM:
begin
fmpar_table[chan].vibrM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKsrM:
begin
fmpar_table[chan].ksrM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetSustainM:
begin
fmpar_table[chan].sustM := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetMultipC:
begin
fmpar_table[chan].multipC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKslC:
begin
fmpar_table[chan].kslC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetTremoloC:
begin
fmpar_table[chan].tremC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetVibratoC:
begin
fmpar_table[chan].vibrC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetKsrC:
begin
fmpar_table[chan].ksrC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
ef_ex3_SetSustainC:
begin
fmpar_table[chan].sustC := event[chan].effect2 MOD 16;
update_fmpar(chan);
end;
end;
end;
For chan := 1 to songdata.nm_tracks do
begin
tporta_flag := (event[chan].effect_def in [ef_TonePortamento,
ef_TPortamVolSlide,
ef_TPortamVSlideFine]) or
(event[chan].effect_def2 in [ef_TonePortamento,
ef_TPortamVolSlide,
ef_TPortamVSlideFine]);
If (event[chan].effect_def+event[chan].effect = 0) then
If (glfsld_table[chan] = 0) then effect_table[chan] := 0
else
else begin
event_table[chan].effect_def := event[chan].effect_def;
event_table[chan].effect := event[chan].effect;
end;
If (event[chan].effect_def2+event[chan].effect2 = 0) then
If (glfsld_table2[chan] = 0) then effect_table2[chan] := 0
else
else begin
event_table[chan].effect_def2 := event[chan].effect_def2;
event_table[chan].effect2 := event[chan].effect2;
end;
// treat Tone Portamento based effects
// vs. note Key-Off's
// vs. step-playing with Spacebar in Pattern Editor window
If (event[chan].note = event[chan].note OR keyoff_flag) then key_off(chan)
else If NOT (LO(effect_table[chan]) in [ef_TonePortamento,
ef_TPortamVolSlide,
ef_TPortamVSlideFine,
ef_extended2+ef_fix2+ef_ex2_NoteDelay]) and
NOT (LO(effect_table2[chan]) in [ef_TonePortamento,
ef_TPortamVolSlide,
ef_TPortamVSlideFine,
ef_extended2+ef_fix2+ef_ex2_NoteDelay]) then
If NOT (((event[chan].effect_def2 = ef_SwapArpeggio) or
(event[chan].effect_def2 = ef_SwapVibrato)) and
(event[chan].effect_def = ef_Extended) and
(event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart)) and
NOT (((event[chan].effect_def = ef_SwapArpeggio) or
(event[chan].effect_def = ef_SwapVibrato)) and
(event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart)) then
If NOT ignore_note_once[chan] then
output_note(event[chan].note,voice_table[chan],chan,TRUE,TRUE)
else
else output_note(event[chan].note,voice_table[chan],chan,TRUE,FALSE)
else If NOT single_play and
(event[chan].note <> 0) and tporta_flag then
If (event_table[chan].note = event_table[chan].note OR keyoff_flag) then
If NOT ignore_note_once[chan] then
output_note(event_table[chan].note AND NOT keyoff_flag,voice_table[chan],chan,FALSE,TRUE)
else
else If portaFK_table[chan] then
output_note(event_table[chan].note AND NOT keyoff_flag,voice_table[chan],chan,FALSE,TRUE)
else If (event[chan].note <> 0) then
event_table[chan].note := event[chan].note
else
else If single_play and
NOT (event[chan].note = event[chan].note OR keyoff_flag) and
NOT (event_table[chan].note <> 0) and
(event[chan].instr_def <> 0) and tporta_flag then
output_note(event[chan].note,event[chan].instr_def,chan,FALSE,TRUE)
else If (event[chan].note <> 0) then
If portaFK_table[chan] and tporta_flag then
output_note(event[chan].note,event[chan].instr_def,chan,FALSE,TRUE)
else event_table[chan].note := event[chan].note;
Case event[chan].effect_def of
ef_SwapArpeggio:
begin
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart) then
begin
If (macro_table[chan].arpg_pos >
songdata.macro_table[event[chan].effect].arpeggio.length) then
macro_table[chan].arpg_pos :=
songdata.macro_table[event[chan].effect].arpeggio.length;
macro_table[chan].arpg_table := event[chan].effect;
end
else begin
macro_table[chan].arpg_count := 1;
macro_table[chan].arpg_pos := 0;
macro_table[chan].arpg_table := event[chan].effect;
macro_table[chan].arpg_note := event_table[chan].note;
end;
end;
ef_SwapVibrato:
begin
If (event[chan].effect_def2 = ef_Extended) and
(event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart) then
begin
If (macro_table[chan].vib_table >
songdata.macro_table[event[chan].effect].vibrato.length) then
macro_table[chan].vib_pos :=
songdata.macro_table[event[chan].effect].vibrato.length;
macro_table[chan].vib_table := event[chan].effect;
end
else begin
macro_table[chan].vib_count := 1;
macro_table[chan].vib_pos := 0;
macro_table[chan].vib_table := event[chan].effect;
macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay;
end;
end;
ef_SetCustomSpeedTab:
generate_custom_vibrato(event[chan].effect);
end;
Case event[chan].effect_def2 of
ef_SwapArpeggio:
begin
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart) then
begin
If (macro_table[chan].arpg_pos >
songdata.macro_table[event[chan].effect2].arpeggio.length) then
macro_table[chan].arpg_pos :=
songdata.macro_table[event[chan].effect2].arpeggio.length;
macro_table[chan].arpg_table := event[chan].effect2;
end
else begin
macro_table[chan].arpg_count := 1;
macro_table[chan].arpg_pos := 0;
macro_table[chan].arpg_table := event[chan].effect2;
macro_table[chan].arpg_note := event_table[chan].note;
end;
end;
ef_SwapVibrato:
begin
If (event[chan].effect_def = ef_Extended) and
(event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and
(event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart) then
begin
If (macro_table[chan].vib_table >
songdata.macro_table[event[chan].effect2].vibrato.length) then
macro_table[chan].vib_pos :=
songdata.macro_table[event[chan].effect2].vibrato.length;
macro_table[chan].vib_table := event[chan].effect2;
end
else begin
macro_table[chan].vib_count := 1;
macro_table[chan].vib_pos := 0;
macro_table[chan].vib_table := event[chan].effect2;
macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay;
end;
end;
ef_SetCustomSpeedTab:
generate_custom_vibrato(event[chan].effect2);
end;
update_fine_effects(chan);
end;
If pattern_delay then
begin
time_playing := time_playing+1/tempo*tickD;
If (time_playing > 3600-1) then time_playing := 0;
end
else begin
time_playing := time_playing+1/tempo*speed;
If (time_playing > 3600-1) then time_playing := 0;
end;
end;
procedure portamento_up(chan: Byte; slide: Word; limit: Word);
var
freq: Word;
begin
If (freq_table[chan] AND $1fff = 0) then EXIT;
freq := calc_freq_shift_up(freq_table[chan] AND $1fff,slide);
If (freq <= limit) then change_frequency(chan,freq)
else change_frequency(chan,limit);
end;
procedure portamento_down(chan: Byte; slide: Word; limit: Word);
var
freq: Word;
begin
If (freq_table[chan] AND $1fff = 0) then EXIT;
freq := calc_freq_shift_down(freq_table[chan] AND $1fff,slide);
If (freq >= limit) then change_frequency(chan,freq)
else change_frequency(chan,limit);
end;
procedure macro_vibrato__porta_up(chan: Byte; depth: Byte);
var
freq: Word;
begin
freq := calc_freq_shift_up(macro_table[chan].vib_freq AND $1fff,depth);
If (freq <= nFreq(12*8+1)) then change_freq(chan,freq)
else change_freq(chan,nFreq(12*8+1));
end;
procedure macro_vibrato__porta_down(chan: Byte; depth: Byte);
var
freq: Word;
begin
freq := calc_freq_shift_down(macro_table[chan].vib_freq AND $1fff,depth);
If (freq >= nFreq(0)) then change_freq(chan,freq)
else change_freq(chan,nFreq(0));
end;
procedure tone_portamento(chan: Byte);
begin
If (freq_table[chan] AND $1fff > porta_table[chan].freq) then
portamento_down(chan,porta_table[chan].speed,porta_table[chan].freq)
else If (freq_table[chan] AND $1fff < porta_table[chan].freq) then
portamento_up(chan,porta_table[chan].speed,porta_table[chan].freq);
end;
procedure tone_portamento2(chan: Byte);
begin
If (freq_table[chan] AND $1fff > porta_table2[chan].freq) then
portamento_down(chan,porta_table2[chan].speed,porta_table2[chan].freq)
else If (freq_table[chan] AND $1fff < porta_table2[chan].freq) then
portamento_up(chan,porta_table2[chan].speed,porta_table2[chan].freq);
end;
procedure slide_carrier_volume_up(chan: Byte; slide,limit: Byte);
var
vol: Word;
vLo,vHi: Byte;
begin
vLo := LO(volume_table[chan]);
vHi := HI(volume_table[chan]);
If (vHi-slide >= limit) then vol := concw(vLo,vHi-slide)
else vol := concw(vLo,limit);
set_ins_volume(BYTE_NULL,HI(vol),chan);
volume_table[chan] := vol;
end;
procedure slide_modulator_volume_up(chan: Byte; slide,limit: Byte);
var
vol: Word;
vLo,vHi: Byte;
begin
vLo := LO(volume_table[chan]);
vHi := HI(volume_table[chan]);
If (vLo-slide >= limit) then vol := concw(vLo-slide,vHi)
else vol := concw(limit,vHi);
set_ins_volume(LO(vol),BYTE_NULL,chan);
volume_table[chan] := vol;
end;
procedure slide_volume_up(chan,slide: Byte);
var
limit1,limit2: Byte;
limit1_4op,limit2_4op: Word;
_4op_flag: Dword;
_4op_conn: Byte;
_4op_ch1,_4op_ch2: Byte;
_4op_ins1,_4op_ins2: Byte;
begin
_4op_flag := _4op_data_flag(chan);
_4op_conn := (_4op_flag SHR 1) AND 3;
_4op_ch1 := (_4op_flag SHR 3) AND 15;
_4op_ch2 := (_4op_flag SHR 7) AND 15;
_4op_ins1 := BYTE(_4op_flag SHR 11);
_4op_ins2 := BYTE(_4op_flag SHR 19);
If _4op_vol_valid_chan(chan) then
begin
If NOT peak_lock[_4op_ch1] then limit1_4op := 0
else limit1_4op := ins_parameter(_4op_ins1,3) AND $3f SHL 16 +
ins_parameter(_4op_ins1,2) AND $3f;
If NOT peak_lock[_4op_ch2] then limit2_4op := 0
else limit2_4op := ins_parameter(_4op_ins2,3) AND $3f SHL 16 +
ins_parameter(_4op_ins2,2) AND $3f;
end
else begin
If NOT peak_lock[chan] then limit1 := 0
else limit1 := ins_parameter(event_table[chan].instr_def,3) AND $3f;
If NOT peak_lock[chan] then limit2 := 0
else limit2 := ins_parameter(event_table[chan].instr_def,2) AND $3f;
end;
Case volslide_type[chan] of
0: begin
If NOT _4op_vol_valid_chan(chan) then
begin
slide_carrier_volume_up(chan,slide,limit1);
If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
(percussion_mode and (chan in [17..20])) then
slide_modulator_volume_up(chan,slide,limit2);
end
else
Case _4op_conn of
// FM/FM
0: slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op));
// FM/AM
1: begin
slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op));
slide_modulator_volume_up(_4op_ch2,slide,LO(limit2_4op));
end;
// AM/FM
2: begin
slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op));
slide_carrier_volume_up(_4op_ch2,slide,HI(limit2_4op));
end;
// AM/AM
3: begin
slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op));
slide_modulator_volume_up(_4op_ch1,slide,LO(limit1_4op));
slide_modulator_volume_up(_4op_ch2,slide,LO(limit2_4op));
end;
end;
end;
1: slide_carrier_volume_up(chan,slide,limit1);
2: slide_modulator_volume_up(chan,slide,limit2);
3: begin
slide_carrier_volume_up(chan,slide,limit1);
slide_modulator_volume_up(chan,slide,limit2);
end;
end;
end;
procedure slide_carrier_volume_down(chan: Byte; slide: Byte);
var
vol: Word;
vLo,vHi: Byte;
begin
vLo := LO(volume_table[chan]);
vHi := HI(volume_table[chan]);
If (vHi+slide <= 63) then vol := concw(vLo,vHi+slide)
else vol := concw(vLo,63);
set_ins_volume(BYTE_NULL,HI(vol),chan);
volume_table[chan] := vol;
end;
procedure slide_modulator_volume_down(chan: Byte; slide: Byte);
var
vol: Word;
vLo,vHi: Byte;
begin
vLo := LO(volume_table[chan]);
vHi := HI(volume_table[chan]);
If (vLo+slide <= 63) then vol := concw(vLo+slide,vHi)
else vol := concw(63,vHi);
set_ins_volume(LO(vol),BYTE_NULL,chan);
volume_table[chan] := vol;
end;
procedure slide_volume_down(chan,slide: Byte);
var
_4op_flag: Dword;
_4op_conn: Byte;
_4op_ch1,_4op_ch2: Byte;
begin
_4op_flag := _4op_data_flag(chan);
_4op_conn := (_4op_flag SHR 1) AND 3;
_4op_ch1 := (_4op_flag SHR 3) AND 15;
_4op_ch2 := (_4op_flag SHR 7) AND 15;
Case volslide_type[chan] of
0: begin
If NOT _4op_vol_valid_chan(chan) then
begin
slide_carrier_volume_down(chan,slide);
If (ins_parameter(voice_table[chan],10) AND 1 = 1) or
(percussion_mode and (chan in [17..20])) then
slide_modulator_volume_down(chan,slide);
end
else
Case _4op_conn of
// FM/FM
0: slide_carrier_volume_down(_4op_ch1,slide);
// FM/AM
1: begin
slide_carrier_volume_down(_4op_ch1,slide);
slide_modulator_volume_down(_4op_ch2,slide);
end;
// AM/FM
2: begin
slide_carrier_volume_down(_4op_ch1,slide);
slide_carrier_volume_down(_4op_ch2,slide);
end;
// AM/AM
3: begin
slide_carrier_volume_down(_4op_ch1,slide);
slide_modulator_volume_down(_4op_ch1,slide);
slide_modulator_volume_down(_4op_ch2,slide);
end;
end;
end;
1: slide_carrier_volume_down(chan,slide);
2: slide_modulator_volume_down(chan,slide);
3: begin
slide_carrier_volume_down(chan,slide);
slide_modulator_volume_down(chan,slide);
end;
end;
end;
procedure volume_slide(chan,up_speed,down_speed: Byte);
begin
If (up_speed <> 0) then slide_volume_up(chan,up_speed)
else If (down_speed <> 0) then slide_volume_down(chan,down_speed);
end;
procedure global_volume_slide(up_speed,down_speed: Byte);
begin
If (up_speed <> BYTE_NULL) then
global_volume := max(global_volume+up_speed,63);
If (down_speed <> BYTE_NULL) then
If (global_volume >= down_speed) then Dec(global_volume,down_speed)
else global_volume := 0;
set_global_volume;
end;
procedure arpeggio(chan: Byte);
const
arpgg_state: array[0..2] of Byte = (1,2,0);
var
freq: Word;
begin
Case arpgg_table[chan].state of
0: freq := nFreq(arpgg_table[chan].note-1);
1: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add1);
2: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add2);
end;
arpgg_table[chan].state := arpgg_state[arpgg_table[chan].state];
change_frequency(chan,freq+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
end;
procedure arpeggio2(chan: Byte);
const
arpgg_state: array[0..2] of Byte = (1,2,0);
var
freq: Word;
begin
Case arpgg_table2[chan].state of
0: freq := nFreq(arpgg_table2[chan].note-1);
1: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add1);
2: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add2);
end;
arpgg_table2[chan].state := arpgg_state[arpgg_table2[chan].state];
change_frequency(chan,freq+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
end;
procedure vibrato(chan: Byte);
var
freq,old_freq: Word;
begin
Inc(vibr_table[chan].pos,vibr_table[chan].speed*vibtrem_speed_factor);
freq := calc_vibtrem_shift(chan,vibr_table);
old_freq := freq_table[chan];
If (vibr_table[chan].dir = 0) then portamento_down(chan,freq,nFreq(0))
else portamento_up(chan,freq,nFreq(12*8+1));
freq_table[chan] := old_freq;
end;
procedure vibrato2(chan: Byte);
var
freq,old_freq: Word;
begin
Inc(vibr_table2[chan].pos,vibr_table2[chan].speed*vibtrem_speed_factor);
freq := calc_vibtrem_shift(chan,vibr_table2);
old_freq := freq_table[chan];
If (vibr_table2[chan].dir = 0) then portamento_down(chan,freq,nFreq(0))
else portamento_up(chan,freq,nFreq(12*8+1));
freq_table[chan] := old_freq;
end;
procedure tremolo(chan: Byte);
var
vol,old_vol: Word;
begin
Inc(trem_table[chan].pos,trem_table[chan].speed*vibtrem_speed_factor);
vol := calc_vibtrem_shift(chan,trem_table);
old_vol := volume_table[chan];
If (trem_table[chan].dir = 0) then slide_volume_down(chan,vol)
else slide_volume_up(chan,vol);
volume_table[chan] := old_vol;
end;
procedure tremolo2(chan: Byte);
var
vol,old_vol: Word;
begin
Inc(trem_table2[chan].pos,trem_table2[chan].speed*vibtrem_speed_factor);
vol := calc_vibtrem_shift(chan,trem_table2);
old_vol := volume_table[chan];
If (trem_table2[chan].pos = 0) then slide_volume_down(chan,vol)
else slide_volume_up(chan,vol);
volume_table[chan] := old_vol;
end;
procedure update_effects;
var
chan,eLo,eHi,
eLo2,eHi2: Byte;
function chanvol(chan: Byte): Byte;
begin
If (ins_parameter(voice_table[chan],10) AND 1 = 0) then chanvol := 63-HI(volume_table[chan])
else chanvol := 63-Round((LO(volume_table[chan])+HI(volume_table[chan]))/2);
end;
begin
For chan := 1 to songdata.nm_tracks do
begin
eLo := LO(effect_table[chan]);
eHi := HI(effect_table[chan]);
eLo2 := LO(effect_table2[chan]);
eHi2 := HI(effect_table2[chan]);
Case eLo of
ef_Arpeggio+ef_fix1:
arpeggio(chan);
ef_ArpggVSlide:
begin
volume_slide(chan,eHi DIV 16,eHi MOD 16);
arpeggio(chan);
end;
ef_ArpggVSlideFine:
arpeggio(chan);
ef_FSlideUp:
portamento_up(chan,eHi,nFreq(12*8+1));
ef_FSlideDown:
portamento_down(chan,eHi,nFreq(0));
ef_FSlideUpVSlide:
begin
portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
volume_slide(chan,eHi DIV 16,eHi MOD 16);
end;
ef_FSlUpVSlF:
portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
ef_FSlideDownVSlide:
begin
portamento_down(chan,fslide_table[chan],nFreq(0));
volume_slide(chan,eHi DIV 16,eHi MOD 16);
end;
ef_FSlDownVSlF:
portamento_down(chan,fslide_table[chan],nFreq(0));
ef_FSlUpFineVSlide:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_FSlDownFineVSlide:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_TonePortamento:
tone_portamento(chan);
ef_TPortamVolSlide:
begin
volume_slide(chan,eHi DIV 16,eHi MOD 16);
tone_portamento(chan);
end;
ef_TPortamVSlideFine:
tone_portamento(chan);
ef_Vibrato:
If NOT vibr_table[chan].fine then
vibrato(chan);
ef_Tremolo:
If NOT trem_table[chan].fine then
tremolo(chan);
ef_VibratoVolSlide:
begin
volume_slide(chan,eHi DIV 16,eHi MOD 16);
If NOT vibr_table[chan].fine then
vibrato(chan);
end;
ef_VibratoVSlideFine:
If NOT vibr_table[chan].fine then
vibrato(chan);
ef_VolSlide:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_RetrigNote:
If (retrig_table[chan] >= eHi) then
begin
retrig_table[chan] := 0;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Inc(retrig_table[chan]);
ef_MultiRetrigNote:
If (retrig_table[chan] >= eHi DIV 16) then
begin
Case eHi MOD 16 of
0,8: ;
1: slide_volume_down(chan,1);
2: slide_volume_down(chan,2);
3: slide_volume_down(chan,4);
4: slide_volume_down(chan,8);
5: slide_volume_down(chan,16);
9: slide_volume_up(chan,1);
10: slide_volume_up(chan,2);
11: slide_volume_up(chan,4);
12: slide_volume_up(chan,8);
13: slide_volume_up(chan,16);
6: slide_volume_down(chan,chanvol(chan)-
Round(chanvol(chan)*2/3));
7: slide_volume_down(chan,chanvol(chan)-
Round(chanvol(chan)*1/2));
14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)-
chanvol(chan),63));
15: slide_volume_up(chan,max(Round(chanvol(chan)*2)-
chanvol(chan),63));
end;
retrig_table[chan] := 0;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Inc(retrig_table[chan]);
ef_Tremor:
If (tremor_table[chan].pos >= 0) then
begin
If (SUCC(tremor_table[chan].pos) <= eHi DIV 16) then
Inc(tremor_table[chan].pos)
else begin
slide_volume_down(chan,63);
tremor_table[chan].pos := -1;
end;
end
else If (PRED(tremor_table[chan].pos) >= -(eHi MOD 16)) then
Dec(tremor_table[chan].pos)
else begin
set_ins_volume(LO(tremor_table[chan].volume),
HI(tremor_table[chan].volume),chan);
tremor_table[chan].pos := 1;
end;
ef_extended2+ef_fix2+ef_ex2_NoteDelay:
If (notedel_table[chan] = 0) then
begin
notedel_table[chan] := BYTE_NULL;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Dec(notedel_table[chan]);
ef_extended2+ef_fix2+ef_ex2_NoteCut:
If (notecut_table[chan] = 0) then
begin
notecut_table[chan] := BYTE_NULL;
key_off(chan);
end
else Dec(notecut_table[chan]);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp:
global_volume_slide(eHi,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn:
global_volume_slide(BYTE_NULL,eHi);
end;
Case eLo2 of
ef_Arpeggio+ef_fix1:
arpeggio2(chan);
ef_ArpggVSlide:
begin
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
arpeggio2(chan);
end;
ef_ArpggVSlideFine:
arpeggio2(chan);
ef_FSlideUp:
portamento_up(chan,eHi2,nFreq(12*8+1));
ef_FSlideDown:
portamento_down(chan,eHi2,nFreq(0));
ef_FSlideUpVSlide:
begin
portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
end;
ef_FSlUpVSlF:
portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
ef_FSlideDownVSlide:
begin
portamento_down(chan,fslide_table2[chan],nFreq(0));
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
end;
ef_FSlDownVSlF:
portamento_down(chan,fslide_table2[chan],nFreq(0));
ef_FSlUpFineVSlide:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_FSlDownFineVSlide:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_TonePortamento:
tone_portamento2(chan);
ef_TPortamVolSlide:
begin
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
tone_portamento2(chan);
end;
ef_TPortamVSlideFine:
tone_portamento2(chan);
ef_Vibrato:
If NOT vibr_table2[chan].fine then
vibrato2(chan);
ef_Tremolo:
If NOT trem_table2[chan].fine then
tremolo2(chan);
ef_VibratoVolSlide:
begin
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
If NOT vibr_table2[chan].fine then
vibrato2(chan);
end;
ef_VibratoVSlideFine:
If NOT vibr_table2[chan].fine then
vibrato2(chan);
ef_VolSlide:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_RetrigNote:
If (retrig_table2[chan] >= eHi2) then
begin
retrig_table2[chan] := 0;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Inc(retrig_table2[chan]);
ef_MultiRetrigNote:
If (retrig_table2[chan] >= eHi2 DIV 16) then
begin
Case eHi2 MOD 16 of
0,8: ;
1: slide_volume_down(chan,1);
2: slide_volume_down(chan,2);
3: slide_volume_down(chan,4);
4: slide_volume_down(chan,8);
5: slide_volume_down(chan,16);
9: slide_volume_up(chan,1);
10: slide_volume_up(chan,2);
11: slide_volume_up(chan,4);
12: slide_volume_up(chan,8);
13: slide_volume_up(chan,16);
6: slide_volume_down(chan,chanvol(chan)-
Round(chanvol(chan)*2/3));
7: slide_volume_down(chan,chanvol(chan)-
Round(chanvol(chan)*1/2));
14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)-
chanvol(chan),63));
15: slide_volume_up(chan,max(Round(chanvol(chan)*2)-
chanvol(chan),63));
end;
retrig_table2[chan] := 0;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Inc(retrig_table2[chan]);
ef_Tremor:
If (tremor_table2[chan].pos >= 0) then
begin
If (SUCC(tremor_table2[chan].pos) <= eHi2 DIV 16) then
Inc(tremor_table2[chan].pos)
else begin
slide_volume_down(chan,63);
tremor_table2[chan].pos := -1;
end;
end
else If (PRED(tremor_table2[chan].pos) >= -(eHi2 MOD 16)) then
Dec(tremor_table2[chan].pos)
else begin
set_ins_volume(LO(tremor_table2[chan].volume),
HI(tremor_table2[chan].volume),chan);
tremor_table2[chan].pos := 1;
end;
ef_extended2+ef_fix2+ef_ex2_NoteDelay:
If (notedel_table[chan] = 0) then
begin
notedel_table[chan] := BYTE_NULL;
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,TRUE,TRUE);
end
else Dec(notedel_table[chan]);
ef_extended2+ef_fix2+ef_ex2_NoteCut:
If (notecut_table[chan] = 0) then
begin
notecut_table[chan] := BYTE_NULL;
key_off(chan);
end
else Dec(notecut_table[chan]);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp:
global_volume_slide(eHi2,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn:
global_volume_slide(BYTE_NULL,eHi2);
end;
end;
end;
procedure update_fine_effects(chan: Byte);
var
eLo,eHi,
eLo2,eHi2: Byte;
begin
eLo := LO(effect_table[chan]);
eHi := HI(effect_table[chan]);
eLo2 := LO(effect_table2[chan]);
eHi2 := HI(effect_table2[chan]);
Case eLo of
ef_ArpggVSlideFine:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_FSlideUpFine:
portamento_up(chan,eHi,nFreq(12*8+1));
ef_FSlideDownFine:
portamento_down(chan,eHi,nFreq(0));
ef_FSlUpVSlF:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_FSlDownVSlF:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_FSlUpFineVSlide:
portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
ef_FSlUpFineVSlF:
begin
portamento_up(chan,fslide_table[chan],nFreq(12*8+1));
volume_slide(chan,eHi DIV 16,eHi MOD 16);
end;
ef_FSlDownFineVSlide:
portamento_down(chan,fslide_table[chan],nFreq(0));
ef_FSlDownFineVSlF:
begin
portamento_down(chan,fslide_table[chan],nFreq(0));
volume_slide(chan,eHi DIV 16,eHi MOD 16);
end;
ef_TPortamVSlideFine:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_Vibrato:
If vibr_table[chan].fine then
vibrato(chan);
ef_Tremolo:
If trem_table[chan].fine then
tremolo(chan);
ef_VibratoVolSlide:
If vibr_table[chan].fine then
vibrato(chan);
ef_VibratoVSlideFine:
begin
volume_slide(chan,eHi DIV 16,eHi MOD 16);
If vibr_table[chan].fine then
vibrato(chan);
end;
ef_VolSlideFine:
volume_slide(chan,eHi DIV 16,eHi MOD 16);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF:
global_volume_slide(eHi,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF:
global_volume_slide(BYTE_NULL,eHi);
end;
Case eLo2 of
ef_ArpggVSlideFine:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_FSlideUpFine:
portamento_up(chan,eHi2,nFreq(12*8+1));
ef_FSlideDownFine:
portamento_down(chan,eHi2,nFreq(0));
ef_FSlUpVSlF:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_FSlDownVSlF:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_FSlUpFineVSlide:
portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
ef_FSlUpFineVSlF:
begin
portamento_up(chan,fslide_table2[chan],nFreq(12*8+1));
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
end;
ef_FSlDownFineVSlide:
portamento_down(chan,fslide_table2[chan],nFreq(0));
ef_FSlDownFineVSlF:
begin
portamento_down(chan,fslide_table2[chan],nFreq(0));
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
end;
ef_TPortamVSlideFine:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_Vibrato:
If vibr_table2[chan].fine then
vibrato2(chan);
ef_Tremolo:
If trem_table2[chan].fine then
tremolo2(chan);
ef_VibratoVolSlide:
If vibr_table2[chan].fine then
vibrato2(chan);
ef_VibratoVSlideFine:
begin
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
If vibr_table2[chan].fine then
vibrato2(chan);
end;
ef_VolSlideFine:
volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF:
global_volume_slide(eHi2,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF:
global_volume_slide(BYTE_NULL,eHi2);
end;
end;
procedure update_extra_fine_effects;
var
chan,eLo,eHi,
eLo2,eHi2: Byte;
begin
For chan := 1 to songdata.nm_tracks do
begin
eLo := LO(effect_table[chan]);
eHi := HI(effect_table[chan]);
eLo2 := LO(effect_table2[chan]);
eHi2 := HI(effect_table2[chan]);
Case eLo of
ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF:
global_volume_slide(eHi,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF:
global_volume_slide(BYTE_NULL,eHi);
ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF:
volume_slide(chan,eHi,0);
ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF:
volume_slide(chan,0,eHi);
ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF:
portamento_up(chan,eHi,nFreq(12*8+1));
ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF:
portamento_down(chan,eHi,nFreq(0));
ef_ExtraFineArpeggio:
arpeggio(chan);
ef_ExtraFineVibrato:
If NOT vibr_table[chan].fine then
vibrato(chan);
ef_ExtraFineTremolo:
If NOT trem_table[chan].fine then
tremolo(chan);
end;
Case eLo2 of
ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF:
global_volume_slide(eHi2,BYTE_NULL);
ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF:
global_volume_slide(BYTE_NULL,eHi2);
ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF:
volume_slide(chan,eHi2,0);
ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF:
volume_slide(chan,0,eHi2);
ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF:
portamento_up(chan,eHi2,nFreq(12*8+1));
ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF:
portamento_down(chan,eHi2,nFreq(0));
ef_ExtraFineArpeggio:
arpeggio2(chan);
ef_ExtraFineVibrato:
If NOT vibr_table2[chan].fine then
vibrato2(chan);
ef_ExtraFineTremolo:
If NOT trem_table2[chan].fine then
tremolo2(chan);
end;
end;
end;
function calc_following_order(order: Byte): Integer;
var
result: Integer;
index,jump_count: Byte;
begin
result := -1;
index := order;
jump_count := 0;
Repeat
If (songdata.pattern_order[index] < $80) then result := index
else begin
index := songdata.pattern_order[index]-$80;
Inc(jump_count);
end;
until (jump_count > $7f) or
(result <> -1);
calc_following_order := result;
end;
function calc_order_jump: Integer;
var
temp: Byte;
result: Integer;
begin
result := 0;
temp := 0;
Repeat
If (songdata.pattern_order[current_order] > $7f) then
current_order := songdata.pattern_order[current_order]-$80;
Inc(temp);
until (temp > $7f) or (songdata.pattern_order[current_order] < $80);
If (temp > $7f) then begin stop_playing; result := -1; end;
calc_order_jump := result;
end;
procedure update_song_position;
var
temp: Byte;
begin
For temp := 9 downto 2 do
play_pos_buf[temp] := play_pos_buf[temp-1];
play_pos_buf[1] := (current_pattern SHL 8)+current_line;
If NOT rewind then
begin
If (current_line < PRED(songdata.patt_len)) and NOT pattern_break then Inc(current_line)
else begin
If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and
repeat_pattern then
begin
FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL);
FillChar(loop_table,SizeOf(loop_table),BYTE_NULL);
current_line := 0;
pattern_break := FALSE;
end
else begin
If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and
(current_order < $7f) then
begin
FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL);
FillChar(loop_table,SizeOf(loop_table),BYTE_NULL);
Inc(current_order);
end;
If pattern_break and (next_line AND $0f0 = pattern_loop_flag) then
begin
temp := next_line-pattern_loop_flag;
next_line := loopbck_table[temp];
If (loop_table[temp][current_line] <> 0) then
Dec(loop_table[temp][current_line]);
end
else If pattern_break and (next_line AND $0f0 = pattern_break_flag) then
begin
If (event_table[next_line-pattern_break_flag].effect_def2 = ef_PositionJump) then
current_order := event_table[next_line-pattern_break_flag].effect2
else current_order := event_table[next_line-pattern_break_flag].effect;
pattern_break := FALSE;
end
else If (current_order > $7f) then
current_order := 0;
If NOT play_single_patt then
If (songdata.pattern_order[current_order] > $7f) then
If (calc_order_jump = -1) then EXIT;
If NOT play_single_patt then
current_pattern := songdata.pattern_order[current_order];
If NOT pattern_break then current_line := 0
else begin
pattern_break := FALSE;
current_line := next_line;
end;
end;
end;
end
else
If (current_line > 0) then Dec(current_line);
For temp := 1 to songdata.nm_tracks do
begin
ignore_note_once[temp] := FALSE;
glfsld_table[temp] := 0;
glfsld_table2[temp] := 0;
end;
If NOT play_single_patt then
If (current_line = 0) and
(current_order = calc_following_order(0)) and speed_update then
begin
tempo := songdata.tempo;
speed := songdata.speed;
update_timer(tempo);
end;
end;
procedure poll_proc;
var
temp: Byte;
factor: Real;
{$IFDEF GO32V2}
_debug_str_bak_: String;
{$ENDIF}
begin
{$IFDEF GO32V2}
_debug_str_bak_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:_poll_proc';
{$ENDIF}
If (NOT pattern_delay and (ticks-tick0+1 >= speed)) or
fast_forward or rewind or single_play then
begin
If debugging and
NOT single_play and NOT pattern_break and
(NOT space_pressed or no_step_debugging) then EXIT;
If NOT single_play and
NOT play_single_patt then
begin
If (songdata.pattern_order[current_order] > $7f) then
If (calc_order_jump = -1) then EXIT;
current_pattern := songdata.pattern_order[current_order];
end;
play_line;
If NOT single_play and NOT (fast_forward or rewind) then update_effects
else For temp := 1 to speed do
begin
update_effects;
If (temp MOD 4 = temp) then
update_extra_fine_effects;
Inc(ticks);
end;
tick0 := ticks;
If NOT single_play and (fast_forward or rewind or
NOT pattern_delay) then
update_song_position;
If fast_forward or rewind then
If NOT pattern_delay then synchronize_song_timer;
If (fast_forward or rewind) and pattern_delay then
begin
tickD := 0;
pattern_delay := FALSE;
end;
If fast_forward or rewind then
begin
{$IFDEF GO32V2}
keyboard_reset_buffer;
{$ENDIF}
If fast_forward then factor := 1/(5-fforward_factor+1)
else factor := 1/(5-rewind_factor+1);
If (Abs(time_playing-time_playing0) > factor*(1+(1/255*tempo))/speed) then
begin
fast_forward := FALSE;
rewind := FALSE;
time_playing0 := time_playing;
synchronize_song_timer;
end;
end;
end
else
begin
update_effects;
Inc(ticks);
If NOT (debugging and NOT single_play and (NOT space_pressed or no_step_debugging)) then
If pattern_delay and (tickD > 1) then Dec(tickD)
else begin
If pattern_delay and NOT single_play then
begin
tick0 := ticks;
update_song_position;
end;
pattern_delay := FALSE;
end;
end;
Inc(tickXF);
If (tickXF MOD 4 = 0) then
begin
update_extra_fine_effects;
Dec(tickXF,4);
end;
{$IFDEF GO32V2}
_debug_str_ := _debug_str_bak_;
{$ENDIF}
end;
procedure macro_poll_proc;
const
IDLE = $0fff;
FINISHED = $0ffff;
var
chan: Byte;
finished_flag: Word;
{$IFDEF GO32V2}
var
_debug_str_bak_: String;
{$ENDIF}
begin
{$IFDEF GO32V2}
_debug_str_bak_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:macro_poll_proc';
{$ENDIF}
For chan := 1 to songdata.nm_tracks do
begin
If NOT keyoff_loop[chan] then finished_flag := FINISHED
else finished_flag := IDLE;
With macro_table[chan] do
begin
With songdata.instr_macros[fmreg_table] do
If (fmreg_table <> 0) and (speed <> 0) then
If (fmreg_duration > 1) then Dec(fmreg_duration)
else begin
fmreg_count := 1;
If (fmreg_pos <= length) then
If (loop_begin <> 0) and (loop_length <> 0) then
If (fmreg_pos = loop_begin+PRED(loop_length)) then
fmreg_pos := loop_begin
else If (fmreg_pos < length) then Inc(fmreg_pos)
else fmreg_pos := finished_flag
else If (fmreg_pos < length) then Inc(fmreg_pos)
else fmreg_pos := finished_flag
else fmreg_pos := finished_flag;
If (freq_table[chan] OR $2000 = freq_table[chan]) and
(keyoff_pos <> 0) and
(fmreg_pos >= keyoff_pos) then
fmreg_pos := IDLE
else If (freq_table[chan] OR $2000 <> freq_table[chan]) and
(fmreg_pos <> 0) and (keyoff_pos <> 0) and
((fmreg_pos < keyoff_pos) or (fmreg_pos = IDLE)) then
fmreg_pos := keyoff_pos;
If (fmreg_pos <> 0) and
(fmreg_pos <> IDLE) and (fmreg_pos <> finished_flag) then
begin
fmreg_duration := data[fmreg_pos].duration;
If (fmreg_duration <> 0) then
With data[fmreg_pos] do
begin
// force KEY-ON with missing ADSR instrument data
force_macro_keyon := FALSE;
If (fmreg_pos = 1) then
If is_ins_adsr_data_empty(voice_table[chan]) and
NOT (songdata.dis_fmreg_col[fmreg_table][0] and
songdata.dis_fmreg_col[fmreg_table][1] and
songdata.dis_fmreg_col[fmreg_table][2] and
songdata.dis_fmreg_col[fmreg_table][3] and
songdata.dis_fmreg_col[fmreg_table][12] and
songdata.dis_fmreg_col[fmreg_table][13] and
songdata.dis_fmreg_col[fmreg_table][14] and
songdata.dis_fmreg_col[fmreg_table][15]) then
force_macro_keyon := TRUE;
If NOT songdata.dis_fmreg_col[fmreg_table][0] then
fmpar_table[chan].adsrw_mod.attck := fm_data.ATTCK_DEC_modulator SHR 4;
If NOT songdata.dis_fmreg_col[fmreg_table][1] then
fmpar_table[chan].adsrw_mod.dec := fm_data.ATTCK_DEC_modulator AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][2] then
fmpar_table[chan].adsrw_mod.sustn := fm_data.SUSTN_REL_modulator SHR 4;
If NOT songdata.dis_fmreg_col[fmreg_table][3] then
fmpar_table[chan].adsrw_mod.rel := fm_data.SUSTN_REL_modulator AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][4] then
fmpar_table[chan].adsrw_mod.wform := fm_data.WAVEFORM_modulator AND $07;
If NOT songdata.dis_fmreg_col[fmreg_table][6] then
fmpar_table[chan].kslM := fm_data.KSL_VOLUM_modulator SHR 6;
If NOT songdata.dis_fmreg_col[fmreg_table][7] then
fmpar_table[chan].multipM := fm_data.AM_VIB_EG_modulator AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][8] then
fmpar_table[chan].tremM := fm_data.AM_VIB_EG_modulator SHR 7;
If NOT songdata.dis_fmreg_col[fmreg_table][9] then
fmpar_table[chan].vibrM := fm_data.AM_VIB_EG_modulator SHR 6 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][10] then
fmpar_table[chan].ksrM := fm_data.AM_VIB_EG_modulator SHR 4 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][11] then
fmpar_table[chan].sustM := fm_data.AM_VIB_EG_modulator SHR 5 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][12] then
fmpar_table[chan].adsrw_car.attck := fm_data.ATTCK_DEC_carrier SHR 4;
If NOT songdata.dis_fmreg_col[fmreg_table][13] then
fmpar_table[chan].adsrw_car.dec := fm_data.ATTCK_DEC_carrier AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][14] then
fmpar_table[chan].adsrw_car.sustn := fm_data.SUSTN_REL_carrier SHR 4;
If NOT songdata.dis_fmreg_col[fmreg_table][15] then
fmpar_table[chan].adsrw_car.rel := fm_data.SUSTN_REL_carrier AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][16] then
fmpar_table[chan].adsrw_car.wform := fm_data.WAVEFORM_carrier AND $07;
If NOT songdata.dis_fmreg_col[fmreg_table][18] then
fmpar_table[chan].kslC := fm_data.KSL_VOLUM_carrier SHR 6;
If NOT songdata.dis_fmreg_col[fmreg_table][19] then
fmpar_table[chan].multipC := fm_data.AM_VIB_EG_carrier AND $0f;
If NOT songdata.dis_fmreg_col[fmreg_table][20] then
fmpar_table[chan].tremC := fm_data.AM_VIB_EG_carrier SHR 7;
If NOT songdata.dis_fmreg_col[fmreg_table][21] then
fmpar_table[chan].vibrC := fm_data.AM_VIB_EG_carrier SHR 6 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][22] then
fmpar_table[chan].ksrC := fm_data.AM_VIB_EG_carrier SHR 4 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][23] then
fmpar_table[chan].sustC := fm_data.AM_VIB_EG_carrier SHR 5 AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][24] then
fmpar_table[chan].connect := fm_data.FEEDBACK_FM AND 1;
If NOT songdata.dis_fmreg_col[fmreg_table][25] then
fmpar_table[chan].feedb := fm_data.FEEDBACK_FM SHR 1 AND 7;
If NOT songdata.dis_fmreg_col[fmreg_table][27] then
If NOT pan_lock[chan] then
panning_table[chan] := panning;
If NOT songdata.dis_fmreg_col[fmreg_table][5] then
set_ins_volume(63-fm_data.KSL_VOLUM_modulator AND $3f,
BYTE_NULL,chan);
If NOT songdata.dis_fmreg_col[fmreg_table][17] then
set_ins_volume(BYTE_NULL,
63-fm_data.KSL_VOLUM_carrier AND $3f,chan);
update_modulator_adsrw(chan);
update_carrier_adsrw(chan);
update_fmpar(chan);
If force_macro_keyon or
NOT (fm_data.FEEDBACK_FM OR MACRO_NOTE_RETRIG_FLAG <> fm_data.FEEDBACK_FM) then
begin
If NOT (is_4op_chan(chan) and (chan in _4op_tracks_hi)) then
begin
output_note(event_table[chan].note,
event_table[chan].instr_def,chan,FALSE,TRUE);
If (is_4op_chan(chan) and (chan in _4op_tracks_lo)) then
init_macro_table(PRED(chan),0,voice_table[PRED(chan)],0);
end;
end
else
If NOT (fm_data.FEEDBACK_FM OR MACRO_ENVELOPE_RESTART_FLAG <> fm_data.FEEDBACK_FM) then
begin
key_on(chan);
change_freq(chan,freq_table[chan]);
end
else
If NOT (fm_data.FEEDBACK_FM OR MACRO_ZERO_FREQ_FLAG <> fm_data.FEEDBACK_FM) then
If (freq_table[chan] <> 0) then
begin
zero_fq_table[chan] := freq_table[chan];
freq_table[chan] := freq_table[chan] AND NOT $1fff;
change_freq(chan,freq_table[chan]);
end
else
else
If (zero_fq_table[chan] <> 0) then
begin
freq_table[chan] := zero_fq_table[chan];
zero_fq_table[chan] := 0;
change_freq(chan,freq_table[chan]);
end;
If NOT songdata.dis_fmreg_col[fmreg_table][26] then
If (freq_slide > 0) then
portamento_up(chan,freq_slide,nFreq(12*8+1))
else If (freq_slide < 0) then
portamento_down(chan,Abs(freq_slide),nFreq(0));
end;
end;
end;
With songdata.macro_table[arpg_table].arpeggio do
If (arpg_table <> 0) and (speed <> 0) then
If (arpg_count = speed) then
begin
arpg_count := 1;
If (arpg_pos <= length) then
If (loop_begin <> 0) and (loop_length <> 0) then
If (arpg_pos = loop_begin+PRED(loop_length)) then
arpg_pos := loop_begin
else If (arpg_pos < length) then Inc(arpg_pos)
else arpg_pos := finished_flag
else If (arpg_pos < length) then Inc(arpg_pos)
else arpg_pos := finished_flag
else arpg_pos := finished_flag;
If (freq_table[chan] OR $2000 = freq_table[chan]) and
(keyoff_pos <> 0) and
(arpg_pos >= keyoff_pos) then
arpg_pos := IDLE
else If (freq_table[chan] OR $2000 <> freq_table[chan]) and
(keyoff_pos <> 0) and (keyoff_pos <> 0) and
((arpg_pos < keyoff_pos) or (arpg_pos = IDLE)) then
arpg_pos := keyoff_pos;
If (arpg_pos <> 0) and
(arpg_pos <> IDLE) and (arpg_pos <> finished_flag) then
Case data[arpg_pos] of
0: change_frequency(chan,
nFreq(arpg_note-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
1..96:
change_frequency(chan,
nFreq(max(arpg_note+data[arpg_pos],97)-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
$80..$80+12*8+1:
change_frequency(chan,nFreq(data[arpg_pos]-$80-1)+
SHORTINT(ins_parameter(event_table[chan].instr_def,12)));
end;
end
else Inc(arpg_count);
With songdata.macro_table[vib_table].vibrato do
If NOT vib_paused and
(vib_table <> 0) and (speed <> 0) then
If (vib_count = speed) then
If (vib_delay <> 0) then Dec(vib_delay)
else begin
vib_count := 1;
If (vib_pos <= length) then
If (loop_begin <> 0) and (loop_length <> 0) then
If (vib_pos = loop_begin+PRED(loop_length)) then
vib_pos := loop_begin
else If (vib_pos < length) then Inc(vib_pos)
else vib_pos := finished_flag
else If (vib_pos < length) then Inc(vib_pos)
else vib_pos := finished_flag
else vib_pos := finished_flag;
If (freq_table[chan] OR $2000 = freq_table[chan]) and
(keyoff_pos <> 0) and
(vib_pos >= keyoff_pos) then
vib_pos := IDLE
else If (freq_table[chan] OR $2000 <> freq_table[chan]) and
(vib_pos <> 0) and (keyoff_pos <> 0) and
((vib_pos < keyoff_pos) or (vib_pos = IDLE)) then
vib_pos := keyoff_pos;
If (vib_pos <> 0) and
(vib_pos <> IDLE) and (vib_pos <> finished_flag) then
If (data[vib_pos] > 0) then
macro_vibrato__porta_up(chan,data[vib_pos])
else If (data[vib_pos] < 0) then
macro_vibrato__porta_down(chan,Abs(data[vib_pos]))
else change_freq(chan,vib_freq);
end
else Inc(vib_count);
end;
end;
{$IFDEF GO32V2}
_debug_str_ := _debug_str_bak_;
{$ENDIF}
end;
procedure set_global_volume;
var
chan: Byte;
begin
For chan := 1 to songdata.nm_tracks do
If _4op_vol_valid_chan(chan) then
set_ins_volume_4op(BYTE_NULL,chan)
else If NOT ((carrier_vol[chan] = 0) and
(modulator_vol[chan] = 0)) then
If (ins_parameter(voice_table[chan],10) AND 1 = 0) then
set_ins_volume(BYTE_NULL,HI(volume_table[chan]),chan)
else set_ins_volume(LO(volume_table[chan]),HI(volume_table[chan]),chan);
end;
{$IFDEF GO32V2}
var
regs: tRealRegs;
procedure update_mouse_position;
begin
If mouse_active then
begin
FillChar(regs,SizeOf(regs),0);
regs.ax := $04;
regs.cx := scr_scroll_x;
regs.dx := scr_scroll_y;
RealIntr($33,regs);
end;
end;
{$ENDIF}
procedure synchronize_screen;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:synchronize_screen';
If mouse_active then
begin
FillChar(regs,SizeOf(regs),0);
regs.ax := $03;
RealIntr($33,regs);
scr_scroll_x := regs.cx;
scr_scroll_y := regs.dx;
end;
If (scr_scroll_x <> old_scr_scroll_x) or
(scr_scroll_y <> old_scr_scroll_y) then
begin
old_scr_scroll_x := scr_scroll_x;
old_scr_scroll_y := scr_scroll_y;
If (scr_scroll_x > scr_font_width*MaxCol-scr_font_width*hard_maxcol) then
begin
scr_scroll_x := scr_font_width*MaxCol-scr_font_width*hard_maxcol;
update_mouse_position;
end;
If (scr_scroll_y > scr_font_height*MaxLn-scr_font_height*hard_maxln) then
begin
scr_scroll_y := scr_font_height*MaxLn-scr_font_height*hard_maxln;
update_mouse_position;
end;
WaitRetrace;
If NOT is_VESA_emulated_mode then
SetTextDisp(scr_scroll_x,scr_scroll_y)
else virtual_screen__first_row := scr_scroll_y*800;
end;
{$ELSE}
If NOT is_default_screen_mode then EXIT;
If (screen_scroll_offset > 16*MaxLn-16*hard_maxln) then
screen_scroll_offset := 16*MaxLn-16*hard_maxln;
virtual_screen__first_row := screen_scroll_offset*SCREEN_RES_X;
{$ENDIF}
end;
function _macro_speedup: Word;
begin
If (macro_speedup > 0) then _macro_speedup := macro_speedup
else _macro_speedup := macro_speedup+1;
end;
procedure timer_poll_proc;
{$IFDEF GO32V2}
var
_debug_str_bak_: String;
{$ENDIF}
begin
{$IFDEF GO32V2}
_debug_str_bak_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:timer_poll_proc';
If (timer_determinator < IRQ_freq+IRQ_freq_shift+playback_speed_shift) then
Inc(timer_determinator)
else begin
timer_determinator := 1;
Inc(seconds_counter);
end;
If (timer_det2 < (IRQ_freq+IRQ_freq_shift+playback_speed_shift) DIV 100) then
Inc(timer_det2)
else begin
timer_det2 := 1;
Inc(hundereds_counter);
Inc(_cursor_blink_pending_frames);
Inc(_screen_refresh_pending_frames);
end;
{$ENDIF}
{$IFDEF GO32V2}
If NOT reset_gfx_ticks then Inc(gfx_ticks)
else begin
gfx_ticks := 0;
reset_gfx_ticks := FALSE;
end;
scroll_ticks := scroll_ticks+1/(IRQ_freq+IRQ_freq_shift+playback_speed_shift)*100;
If (scroll_ticks > 0.2) then
begin
If ctrl_tab_pressed then
begin
If scankey(SC_UP) then
If (scr_scroll_y > 0) then
begin
Dec(scr_scroll_y);
update_mouse_position;
end;
If scankey(SC_DOWN) then
If (scr_scroll_y < scr_font_height*MaxLn-scr_font_height*hard_maxln) then
begin
Inc(scr_scroll_y);
update_mouse_position;
end;
If scankey(SC_PAGEUP) then
begin
scr_scroll_y := 0;
update_mouse_position;
end;
If scankey(SC_PAGEDOWN) then
begin
scr_scroll_y := scr_font_height*MaxLn-scr_font_height*hard_maxln;
update_mouse_position;
end;
If scankey(SC_HOME) then
begin
scr_scroll_x := 0;
update_mouse_position;
end;
If scankey(SC_END) then
begin
scr_scroll_x := scr_font_width*MaxCol-scr_font_width*hard_maxcol;
update_mouse_position;
end;
If scankey(SC_LEFT) then
If (scr_scroll_x > 0) then
begin
Dec(scr_scroll_x);
update_mouse_position;
end;
If scankey(SC_RIGHT) then
If (scr_scroll_x < scr_font_width*MaxCol-scr_font_width*hard_maxcol) then
begin
Inc(scr_scroll_x);
update_mouse_position;
end;
end;
scroll_ticks := 0;
end;
{$ELSE}
Inc(blink_ticks);
If ((fast_forward or rewind or (space_pressed and debugging) or
(@macro_preview_indic_proc <> NIL)) and
(blink_ticks > 50)) or (blink_ticks > 50) then
begin
blink_flag := NOT blink_flag;
blink_ticks := 0;
end;
Inc(_WAVREC_blink_ticks);
If ((fast_forward or rewind or (space_pressed and debugging) or
(@macro_preview_indic_proc <> NIL)) and
(_WAVREC_blink_ticks > 50)) or (_WAVREC_blink_ticks > 50) then
begin
_WAVREC_blink_flag := NOT _WAVREC_blink_flag;
_WAVREC_blink_ticks := 0;
end;
Inc(_NRECM_blink_ticks);
If ((fast_forward or rewind or (space_pressed and debugging) or
(@macro_preview_indic_proc <> NIL)) and
(_NRECM_blink_ticks > 50)) or (_NRECM_blink_ticks > 50) then
begin
_NRECM_blink_flag := NOT _NRECM_blink_flag;
_NRECM_blink_ticks := 0;
end;
Inc(_IRQFREQ_blink_ticks);
If ((fast_forward or rewind or (space_pressed and debugging) or
(@macro_preview_indic_proc <> NIL)) and
(_IRQFREQ_blink_ticks > 25)) or (_IRQFREQ_blink_ticks > 25) then
begin
_IRQFREQ_blink_flag := NOT _IRQFREQ_blink_flag;
_IRQFREQ_blink_ticks := 0;
end;
If ctrl_tab_pressed then
begin
If scankey(SC_UP) then
If (screen_scroll_offset > 0) then
Dec(screen_scroll_offset,2);
If scankey(SC_DOWN) then
If (screen_scroll_offset < 16*MaxLn-16*hard_maxln) then
Inc(screen_scroll_offset,2);
If scankey(SC_PAGEUP) then
screen_scroll_offset := 0;
If scankey(SC_PAGEDOWN) then
screen_scroll_offset := 16*MaxLn-16*hard_maxln;
end;
{$ENDIF}
If (play_status = isPlaying) and
NOT (debugging and (NOT space_pressed or no_step_debugging)) then
begin
{$IFDEF GO32V2}
song_timer_tenths := Trunc(100/(IRQ_freq+IRQ_freq_shift+playback_speed_shift)*timer_temp);
{$ELSE}
song_timer_tenths := timer_temp;
{$ENDIF}
If (song_timer_tenths >= 100) then song_timer_tenths := 0;
{$IFDEF GO32V2}
If (timer_temp < IRQ_freq+IRQ_freq_shift+playback_speed_shift) then Inc(timer_temp)
{$ELSE}
If (timer_temp < 100) then Inc(timer_temp)
{$ENDIF}
else begin
Inc(song_timer);
timer_temp := 1;
end;
end
else If debugging and (NOT space_pressed or no_step_debugging) then
If NOT pattern_delay then synchronize_song_timer;
If (song_timer > 3600-1) then
begin
song_timer := 0;
timer_temp := 0;
song_timer_tenths := 0;
end;
{$IFDEF GO32V2}
If (ticklooper > 0) then
If (fast_forward or rewind) and NOT replay_forbidden then
poll_proc
else
else If NOT replay_forbidden then
poll_proc;
If (macro_ticklooper = 0) then
macro_poll_proc;
Inc(ticklooper);
If (ticklooper >= IRQ_freq DIV tempo) then
ticklooper := 0;
Inc(macro_ticklooper);
If (macro_ticklooper >= IRQ_freq DIV (tempo*_macro_speedup)) then
macro_ticklooper := 0;
_debug_str_ := _debug_str_bak_;
{$ENDIF}
end;
{$IFDEF GO32V2}
const
___IRQ_DATA_END___: Dword = 0;
procedure ___IRQ_CODE_END___; begin end;
procedure DisableTimerIRQ;
begin
asm
in al,21h
or al,1
out 21h,al
end;
end;
procedure EnableTimerIRQ;
begin
asm
in al,21h
and al,0feh
out 21h,al
end;
end;
const
timer_poll_proc_ptr: Pointer = NIL;
procedure TimerSetup(Hz: Longint);
begin
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:TimerSetup';
If (Hz < 19) then Hz := 19;
If (Hz > 1193180) then Hz := 1193180;
DisableTimerIRQ;
If (timer_poll_proc_ptr <> NIL) then ISS_StopTimer(timer_poll_proc_ptr);
timer_poll_proc_ptr := @timer_poll_proc;
ISS_StartTimer(timer_poll_proc_ptr,ISS_TimerSpeed DIV Hz);
EnableTimerIRQ;
end;
procedure TimerDone;
begin
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:TimerDone';
DisableTimerIRQ;
If (timer_poll_proc_ptr <> NIL) then ISS_StopTimer(timer_poll_proc_ptr);
timer_poll_proc_ptr := NIL;
EnableTimerIRQ;
end;
procedure TimerInstallHandler(handler: Pointer);
begin
end;
procedure TimerRemoveHandler;
begin
end;
{$ELSE}
const
timer_handler: Procedure = NIL;
TimerID: SDL_TimerID = NIL;
_interval: longint = 1000 DIV 50; // 1000 ms / Hz
function TimerCallback(interval: Uint32; param: Pointer):Uint32; cdecl;
begin
If (@timer_handler <> NIL) then timer_handler;
TimerCallback := _interval; // trick to alter delay rate on the fly
end;
procedure TimerSetup(Hz: Longint);
begin
_interval := 1000 DIV Hz;
// only activate timer once, later only alter delay rate
If (TimerID = NIL) then
begin
TimerID := SDL_AddTimer(_interval,SDL_NewTimerCallback(@TimerCallBack),NIL);
If (TimerID = NIL) then
Writeln('SDL: Error creating timer');
end;
snd_SetTimer(Hz);
end;
procedure TimerDone;
begin
end;
procedure TimerInstallHandler(handler: Pointer);
begin
@timer_handler := handler;
end;
procedure TimerRemoveHandler;
begin
@timer_handler := NIL;
end;
{$ENDIF}
procedure init_timer_proc;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:init_timer_proc';
scroll_ticks := 0;
{$ENDIF}
Randomize;
If timer_initialized then EXIT;
timer_initialized := TRUE;
{$IFNDEF GO32V2}
TimerInstallHandler(@timer_poll_proc);
{$ENDIF}
TimerSetup(50);
end;
procedure done_timer_proc;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:done_timer_proc';
{$ENDIF}
If NOT timer_initialized then EXIT;
timer_initialized := FALSE;
TimerDone;
TimerRemoveHandler;
end;
{$i realtime.inc}
function calc_pattern_pos(pattern: Byte): Byte;
var
index: Integer;
jump_count,pattern_pos: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:calc_pattern_pos';
{$ENDIF}
pattern_pos := BYTE_NULL;
jump_count := 0;
index := calc_following_order(0);
While (index <> -1) and (jump_count < $7f) do
If (songdata.pattern_order[index] <> pattern) then
If NOT (index < $7f) then BREAK
else begin
Inc(index);
index := calc_following_order(index);
Inc(jump_count);
end
else begin
pattern_pos := index;
BREAK;
end;
calc_pattern_pos := pattern_pos;
end;
procedure calibrate_player(order,line: Byte; status_filter: Boolean;
line_dependent: Boolean);
var
temp_channel_flag: array[1..20] of Boolean;
old_debugging,
old_repeat_pattern: Boolean;
jump_count,loop_count,
temp,previous_order,previous_line: Byte;
status_backup: Record
replay_forbidden: Boolean;
play_status: tPLAY_STATUS;
end;
procedure update_status;
var
temp: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:calibrate_player:update_status';
{$ENDIF}
temp := songdata.pattern_order[current_order];
If NOT (temp <= $7f) then temp := 0;
show_str(17,03,byte2hex(current_order),pattern_bckg+status_dynamic_txt);
show_str(20,03,byte2hex(temp),pattern_bckg+status_dynamic_txt);
show_str(17,04,'--',pattern_bckg+status_dynamic_txt);
{$IFNDEF GO32V2}
_draw_screen_without_delay := TRUE;
{$ENDIF}
draw_screen;
end;
var
_pattern_page,_pattord_page,
_pattord_hpos,_pattord_vpos: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:calibrate_player';
{$ENDIF}
If (calc_following_order(0) = -1) then EXIT;
calibrating := TRUE;
status_backup.replay_forbidden := replay_forbidden;
status_backup.play_status := play_status;
If status_filter then no_status_refresh := TRUE;
nul_volume_bars;
Move(channel_flag,temp_channel_flag,SizeOf(temp_channel_flag));
FillChar(channel_flag,SizeOf(channel_flag),BYTE(FALSE));
old_debugging := debugging;
old_repeat_pattern := repeat_pattern;
debugging := FALSE;
repeat_pattern := FALSE;
If (play_status = isStopped) or
(order < current_order) or
(order = calc_following_order(0)) then
begin
If NOT no_sync_playing then stop_playing
else begin
stop_playing;
no_sync_playing := TRUE;
end;
init_player;
speed := songdata.speed;
macro_speedup := songdata.macro_speedup;
update_timer(songdata.tempo);
current_order := calc_following_order(0);
current_pattern := songdata.pattern_order[current_order];
current_line := 0;
pattern_break := FALSE;
pattern_delay := FALSE;
last_order := 0;
next_line := 0;
song_timer := 0;
timer_temp := 0;
song_timer_tenths := 0;
time_playing := 0;
ticklooper := 0;
macro_ticklooper := 0;
ticks := 0;
tick0 := 0;
end;
If NOT no_sync_playing then
begin
show_str(13,07,' --:--.- ',status_background+status_border);
{$IFNDEF GO32V2}
_draw_screen_without_delay := TRUE;
{$ENDIF}
draw_screen;
end;
previous_order := current_order;
previous_line := current_line;
jump_count := 0;
loop_count := 0;
replay_forbidden := TRUE;
seek_pattern_break := FALSE;
If NOT no_sync_playing then
While (current_line <> line) or
(current_order <> order) do
begin
If scankey(SC_ESCAPE) then BREAK;
If NOT ((previous_order = current_order) and
(previous_line >= current_line) and NOT (pattern_break and
(next_line AND $0f0 = pattern_loop_flag))) then loop_count := 0
else begin
Inc(loop_count);
If (loop_count > 15) then BREAK;
end;
If (current_order = order) and (current_line >= line) and
NOT line_dependent then BREAK;
previous_order := current_order;
previous_line := current_line;
fast_forward := TRUE;
poll_proc;
If (macro_ticklooper = 0) then
macro_poll_proc;
fast_forward := FALSE;
Inc(ticklooper);
If (ticklooper >= IRQ_freq DIV tempo) then
ticklooper := 0;
Inc(macro_ticklooper);
If (macro_ticklooper >= IRQ_freq DIV (tempo*macro_speedup)) then
macro_ticklooper := 0;
If (previous_order <> current_order) then
begin
update_status;
Inc(jump_count);
If (jump_count > $7f) then BREAK;
end;
If seek_pattern_break then
If (current_order > order) or
((current_order = order) and
((current_line <> 0) or (line = 0))) then BREAK
else seek_pattern_break := FALSE;
keyboard_reset_buffer;
end
else
begin
start_playing;
current_order := order;
current_pattern := songdata.pattern_order[order];
current_line := line;
end;
fade_out_volume := 63;
Move(temp_channel_flag,channel_flag,SizeOf(channel_flag));
For temp := 1 to 20 do reset_chan_data(temp);
If (status_backup.play_status <> isStopped) then
begin
replay_forbidden := status_backup.replay_forbidden;
play_status := status_backup.play_status;
end
else begin
replay_forbidden := FALSE;
play_status := isPlaying;
end;
debugging := old_debugging;
repeat_pattern := old_repeat_pattern;
synchronize_song_timer;
calibrating := FALSE;
If status_filter then no_status_refresh := FALSE;
_pattern_page := line;
_pattord_page := 0;
_pattord_hpos := 1;
_pattord_vpos := 1;
While (current_order <> _pattord_vpos+4*(_pattord_hpos+_pattord_page-1)-1) do
If (_pattord_vpos < 4) then Inc(_pattord_vpos)
else If (_pattord_hpos < MAX_ORDER_COLS) then begin Inc(_pattord_hpos); _pattord_vpos := 1; end
else If (_pattord_page < 23-(MAX_ORDER_COLS-9)) then begin Inc(_pattord_page); _pattord_vpos := 1; end;
If tracing then
begin
PATTERN_ORDER_page_refresh(_pattord_page);
PATTERN_page_refresh(_pattern_page);
end;
keyboard_reset_buffer;
end;
procedure init_buffers;
var
temp: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:init_buffers';
{$ENDIF}
FillChar(fmpar_table,SizeOf(fmpar_table),0);
FillChar(pan_lock,SizeOf(pan_lock),BYTE(panlock));
FillChar(volume_table,SizeOf(volume_table),63);
FillChar(vscale_table,SizeOf(vscale_table),0);
FillChar(modulator_vol,SizeOf(modulator_vol),0);
FillChar(carrier_vol,SizeOf(carrier_vol),0);
FillChar(decay_bar,SizeOf(decay_bar),0);
FillChar(volum_bar,SizeOf(volum_bar),0);
FillChar(event_table,SizeOf(event_table),0);
FillChar(freq_table,SizeOf(freq_table),0);
FillChar(zero_fq_table,SizeOf(zero_fq_table),0);
FillChar(effect_table,SizeOf(effect_table),0);
FillChar(effect_table2,SizeOf(effect_table2),0);
FillChar(fslide_table,SizeOf(fslide_table),0);
FillChar(fslide_table2,SizeOf(fslide_table2),0);
FillChar(glfsld_table,SizeOf(glfsld_table),0);
FillChar(glfsld_table2,SizeOf(glfsld_table2),0);
FillChar(porta_table,SizeOf(porta_table),0);
FillChar(porta_table2,SizeOf(porta_table2),0);
FillChar(portaFK_table,SizeOf(portaFK_table),BYTE(FALSE));
FillChar(arpgg_table,SizeOf(arpgg_table),0);
FillChar(arpgg_table2,SizeOf(arpgg_table2),0);
FillChar(vibr_table,SizeOf(vibr_table),0);
FillChar(vibr_table2,SizeOf(vibr_table2),0);
FillChar(trem_table,SizeOf(trem_table),0);
FillChar(trem_table2,SizeOf(trem_table2),0);
FillChar(retrig_table,SizeOf(retrig_table),0);
FillChar(retrig_table2,SizeOf(retrig_table2),0);
FillChar(tremor_table,SizeOf(tremor_table),0);
FillChar(tremor_table2,SizeOf(tremor_table2),0);
FillChar(last_effect,SizeOf(last_effect),0);
FillChar(last_effect2,SizeOf(last_effect2),0);
FillChar(voice_table,SizeOf(voice_table),0);
FillChar(event_new,SizeOf(event_new),0);
FillChar(freqtable2,SizeOf(freqtable2),0);
FillChar(notedel_table,SizeOf(notedel_table),BYTE_NULL);
FillChar(notecut_table,SizeOf(notecut_table),BYTE_NULL);
FillChar(ftune_table,SizeOf(ftune_table),0);
FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL);
FillChar(loop_table,SizeOf(loop_table),BYTE_NULL);
FillChar(reset_chan,SizeOf(reset_chan),BYTE(FALSE));
FillChar(reset_adsrw,SizeOf(reset_adsrw),BYTE(FALSE));
FillChar(keyoff_loop,SizeOf(keyoff_loop),BYTE(FALSE));
FillChar(macro_table,SizeOf(macro_table),0);
FillChar(ignore_note_once,SizeOf(ignore_note_once),FALSE);
If NOT lockvol then FillChar(volume_lock,SizeOf(volume_lock),0)
else For temp := 1 to 20 do volume_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 4 AND 1);
If NOT panlock then FillChar(panning_table,SizeOf(panning_table),0)
else For temp := 1 to 20 do panning_table[temp] := songdata.lock_flags[temp] AND 3;
If NOT lockVP then FillChar(peak_lock,SizeOf(peak_lock),0)
else For temp := 1 to 20 do peak_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 5 AND 1);
FillChar(vol4op_lock,SizeOf(vol4op_lock),BYTE(FALSE));
For temp := 1 to 6 do
begin
vol4op_lock[_4op_main_chan[temp]] :=
(songdata.lock_flags[_4op_main_chan[temp]] OR $40 = songdata.lock_flags[_4op_main_chan[temp]]);
vol4op_lock[PRED(_4op_main_chan[temp])] :=
(songdata.lock_flags[PRED(_4op_main_chan[temp])] OR $40 = songdata.lock_flags[PRED(_4op_main_chan[temp])]);
end;
For temp := 1 to 20 do
volslide_type[temp] := songdata.lock_flags[temp] SHR 2 AND 3;
end;
procedure init_player;
var
temp: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:init_player';
{$ELSE}
opl3_init;
{$ENDIF}
FillChar(ai_table,SizeOf(ai_table),0);
opl2out($01,0);
For temp := 1 to 18 do opl2out($0b0+_chan_n[temp],0);
For temp := $080 to $08d do opl2out(temp,BYTE_NULL);
For temp := $090 to $095 do opl2out(temp,BYTE_NULL);
misc_register := tremolo_depth SHL 7+
vibrato_depth SHL 6+
BYTE(percussion_mode) SHL 5;
opl2out($01,$20);
opl2out($08,$40);
opl3exp($0105);
opl3exp($04+songdata.flag_4op SHL 8);
key_off(17);
key_off(18);
opl2out(_instr[11],misc_register);
init_buffers;
current_tremolo_depth := tremolo_depth;
current_vibrato_depth := vibrato_depth;
global_volume := 63;
macro_ticklooper := 0;
vibtrem_speed_factor := def_vibtrem_speed_factor;
vibtrem_table_size := def_vibtrem_table_size;
Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table));
For temp := 1 to 20 do
begin
arpgg_table[temp].state := 1;
arpgg_table2[temp].state := 1;
voice_table[temp] := temp;
end;
end;
procedure reset_player;
var
temp: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:reset_player';
{$ENDIF}
opl2out($01,0);
For temp := 1 to 18 do opl2out($0b0+_chan_n[temp],0);
For temp := $080 to $08d do opl2out(temp,BYTE_NULL);
For temp := $090 to $095 do opl2out(temp,BYTE_NULL);
misc_register := tremolo_depth SHL 7+
vibrato_depth SHL 6+
BYTE(percussion_mode) SHL 5;
opl2out($01,$20);
opl2out($08,$40);
opl3exp($0105);
opl3exp($04+songdata.flag_4op SHL 8);
key_off(17);
key_off(18);
opl2out(_instr[11],misc_register);
For temp := 1 to 20 do reset_chan_data(temp);
end;
procedure start_playing;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:start_playing';
{$ENDIF}
init_player;
If (start_pattern = BYTE_NULL) then current_order := 0
else If (start_order = BYTE_NULL) then
begin
If (calc_pattern_pos(start_pattern) <> BYTE_NULL) then
current_order := calc_pattern_pos(start_pattern)
else If NOT play_single_patt then
begin
start_pattern := BYTE_NULL;
current_order := 0;
EXIT;
end;
end
else begin
current_order := start_order;
current_pattern := start_pattern;
end;
If NOT play_single_patt then
If (songdata.pattern_order[current_order] > $7f) then
If (calc_order_jump = -1) then EXIT;
If NOT play_single_patt then
current_pattern := songdata.pattern_order[current_order]
else current_pattern := start_pattern;
If (start_line = BYTE_NULL) then current_line := 0
else current_line := start_line;
pattern_break := FALSE;
pattern_delay := FALSE;
tickXF := 0;
last_order := 0;
next_line := 0;
song_timer := 0;
timer_temp := 0;
song_timer_tenths := 0;
time_playing := 0;
ticklooper := 0;
macro_ticklooper := 0;
debugging := FALSE;
ticks := 0;
tick0 := 0;
fade_out_volume := 63;
playback_speed_shift := 0;
replay_forbidden := FALSE;
play_status := isPlaying;
speed := songdata.speed;
macro_speedup := songdata.macro_speedup;
update_timer(songdata.tempo);
no_status_refresh := FALSE;
really_no_status_refresh := FALSE;
FillChar(play_pos_buf,SizeOf(play_pos_buf),0);
end;
procedure stop_playing;
var
temp: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:stop_playing';
{$ELSE}
flush_WAV_data;
If NOT opl3_flushmode then
renew_wav_files_flag := TRUE;
{$ENDIF}
replay_forbidden := TRUE;
play_status := isStopped;
fade_out_volume := 63;
repeat_pattern := FALSE;
global_volume := 63;
no_sync_playing := FALSE;
play_single_patt := FALSE;
current_tremolo_depth := tremolo_depth;
current_vibrato_depth := vibrato_depth;
pattern_break := FALSE;
current_order := 0;
current_pattern := 0;
current_line := 0;
start_order := BYTE_NULL;
start_pattern := BYTE_NULL;
start_line := BYTE_NULL;
song_timer := 0;
timer_temp := 0;
song_timer_tenths := 0;
time_playing := 0;
playback_speed_shift := 0;
skip_macro_flag := TRUE;
For temp := 1 to 20 do reset_chan_data(temp);
opl2out(_instr[11],0);
init_buffers;
skip_macro_flag := FALSE;
speed := songdata.speed;
update_timer(songdata.tempo);
end;
function _partial(max,val: Byte; base: Byte): Byte;
var
temp1,temp2: Real;
temp3: Byte;
begin
temp1 := max/base;
temp2 := (max/base)/2;
temp3 := 0;
While (temp2 < val) do
begin
temp2 := temp2+temp1;
Inc(temp3);
end;
_partial := temp3;
end;
function hscroll_bar(x,y: Byte; size: Byte; len1,len2,pos: Word;
atr1,atr2: Byte): Byte;
var
temp: Byte;
begin
If (size > work_MaxCol-x) then size := work_MaxCol-x;
If (size < 5) then size := 5;
If (size-2-1 < 10) then temp := _partial(len1,len2,size-2-1)
else temp := _partial(len1,len2,size-2-1-2);
If (pos = temp) and NOT force_scrollbars then
begin
hscroll_bar := temp;
EXIT;
end;
If (size < len1*4) and (len1 > 4) then
begin
pos := temp;
show_str(x,y,#17+ExpStrL('',size-2,#176)+#16,atr1);
If (size-2-1 < 10) then show_str(x+1+temp,y,#178,atr2)
else show_str(x+1+temp,y,#178#178#178,atr2);
end
else show_Str(x,y,#17+ExpStrL('',size-2,#177)+#16,atr1);
hscroll_bar := pos;
end;
function vscroll_bar(x,y: Byte; size: Byte; len1,len2,pos: Word;
atr1,atr2: Byte): Byte;
var
temp: Byte;
begin
If (size > work_MaxLn-y) then size := work_MaxLn-y;
If (size < 5) then size := 5;
If (size-2-1 < 10) then temp := _partial(len1,len2,size-2-1)
else temp := _partial(len1,len2,size-2-1-2);
If (pos = temp) and NOT force_scrollbars then
begin
vscroll_bar := temp;
EXIT;
end;
If (size < len1*4) and (len1 > 5) then
begin
pos := temp;
show_vstr(x,y,#30+ExpStrL('',size-2,#176)+#31,atr1);
If (size-2-1 < 10) then show_str(x,y+1+temp,#178,atr2)
else show_vstr(x,y+1+temp,#178#178#178,atr2);
end
else show_vstr(x,y,#30+ExpStrL('',size-2,#177)+#31,atr1);
vscroll_bar := pos;
end;
procedure centered_frame(var xstart,ystart: Byte; hsize,vsize: Byte;
name: String; atr1,atr2: Byte; border: String);
begin
xstart := (work_MaxCol-hsize) DIV 2;
ystart := (work_MaxLn -vsize) DIV 2+(work_MaxLn-vsize) MOD 2;
Frame(centered_frame_vdest,xstart,ystart,xstart+hsize,ystart+vsize,
atr1,name,atr2,border);
end;
procedure get_chunk(pattern,line,channel: Byte; var chunk: tCHUNK);
begin
asm
mov esi,[pattdata]
mov edi,[chunk]
mov al,pattern
inc al
cmp al,max_patterns
jbe @@1
mov ecx,CHUNK_SIZE
xor al,al
rep stosb
jmp @@2
@@1: xor eax,eax
mov al,line
mov ebx,CHUNK_SIZE
mul ebx
mov ecx,eax
xor eax,eax
mov al,channel
dec eax
mov ebx,256*CHUNK_SIZE
mul ebx
add ecx,eax
xor eax,eax
mov al,pattern
mov ebx,8
div ebx
push eax
mov eax,edx
mov ebx,20*256*CHUNK_SIZE
mul ebx
add ecx,eax
pop eax
mov ebx,8*20*256*CHUNK_SIZE
mul ebx
add ecx,eax
add esi,ecx
mov ecx,CHUNK_SIZE
rep movsb
@@2:
end;
end;
procedure put_chunk(pattern,line,channel: Byte; chunk: tCHUNK);
begin
asm
lea esi,[chunk]
mov edi,[pattdata]
mov al,pattern
inc al
cmp al,max_patterns
jbe @@1
mov limit_exceeded,TRUE
jmp @@2
@@1: xor eax,eax
mov al,line
mov ebx,CHUNK_SIZE
mul ebx
mov ecx,eax
xor eax,eax
mov al,channel
dec eax
mov ebx,256*CHUNK_SIZE
mul ebx
add ecx,eax
xor eax,eax
mov al,pattern
mov ebx,8
div ebx
push eax
mov eax,edx
mov ebx,20*256*CHUNK_SIZE
mul ebx
add ecx,eax
pop eax
mov ebx,8*20*256*CHUNK_SIZE
mul ebx
add ecx,eax
add edi,ecx
mov ecx,CHUNK_SIZE
rep movsb
mov module_archived,FALSE
@@2:
end;
end;
function get_chanpos(var data; channels,scancode: Byte): Byte;
var
result: Byte;
begin
asm
xor ebx,ebx
@@1: mov edi,[data]
add edi,ebx
xor ecx,ecx
mov cl,channels
mov al,scancode
sub ecx,ebx
repnz scasb
jnz @@2
xor eax,eax
mov al,channels
sub eax,ecx
jmp @@3
@@2: xor eax,eax
jmp @@5
@@3: pusha
push eax
call is_4op_chan
or al,al
jz @@4
popa
inc ebx
jmp @@1
@@4: popa
@@5: mov result,al
end;
get_chanpos := result;
end;
function get_chanpos2(var data; channels,scancode: Byte): Byte;
var
result: Byte;
begin
asm
mov edi,[data]
xor ecx,ecx
mov cl,channels
mov al,scancode
repnz scasb
jnz @@1
xor eax,eax
mov al,channels
sub eax,ecx
jmp @@2
@@1: xor eax,eax
@@2: mov result,al
end;
get_chanpos2 := result;
end;
function count_channel(hpos: Byte): Byte;
var
result: Byte;
begin
asm
mov al,_pattedit_lastpos
xor ah,ah
mov bl,MAX_TRACKS
div bl
mov bl,al
mov al,hpos
xor ah,ah
div bl
or ah,ah
jz @@1
add al,chan_pos
jmp @@2
@@1: add al,chan_pos
dec al
@@2: mov result,al
end;
count_channel := result;
end;
function count_pos(hpos: Byte): Byte;
var
result: Byte;
begin
asm
mov al,_pattedit_lastpos
xor ah,ah
mov bl,MAX_TRACKS
div bl
mov bl,al
mov al,hpos
xor ah,ah
div bl
mov al,ah
dec al
or ah,ah
jnz @@1
dec bl
mov al,bl
@@1: mov result,al
end;
count_pos := result;
end;
procedure count_order(var entries: Byte);
var
index,
index2: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:count_order';
{$ENDIF}
index := 0;
index2 := 0;
Repeat
If (songdata.pattern_order[index] <> $80) then
begin
If (songdata.pattern_order[index] > $80) then
If (songdata.pattern_order[index]-$80 <> index2) then
begin
index := songdata.pattern_order[index]-$80;
index2 := index;
end
else BREAK;
end
else BREAK;
If (index < $80) then Inc(index);
until (index > $7f);
entries := index;
end;
procedure count_patterns(var patterns: Byte);
var
temp1: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:count_patterns';
{$ENDIF}
patterns := 0;
For temp1 := 0 to PRED(max_patterns) do
begin
realtime_gfx_poll_proc;
If NOT is_data_empty(pattdata^[temp1 DIV 8][temp1 MOD 8],PATTERN_SIZE) then
patterns := temp1+1;
end;
end;
procedure count_instruments(var instruments: Byte);
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:count_instruments';
{$ENDIF}
instruments := 255;
While (instruments > 0) and
Empty(songdata.instr_data[instruments],INSTRUMENT_SIZE) do
Dec(instruments);
end;
function calc_max_speedup(tempo: Byte): Word;
var
temp: Longint;
result: Word;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:calc_max_speedup';
{$ENDIF}
result := MAX_IRQ_FREQ DIV tempo;
Repeat
If (tempo = 18) and timer_fix then temp := TRUNC((tempo+0.2)*20)
else temp := 250;
While (temp MOD (tempo*result) <> 0) do Inc(temp);
If (temp <= MAX_IRQ_FREQ) then Inc(result);
until NOT (temp <= MAX_IRQ_FREQ);
calc_max_speedup := PRED(result);
end;
function calc_bpm_speed(tempo,speed,rows_per_beat: Byte): Real;
begin
{$IFDEF GO32V2}
calc_bpm_speed := tempo*60/speed/rows_per_beat*(1+(IRQ_freq_shift/IRQ_freq)-0.02);
{$ELSE}
calc_bpm_speed := tempo*60/speed/rows_per_beat*(1+(IRQ_freq_shift/IRQ_freq)-sdl_timer_slowdown/100);
{$ENDIF}
end;
function calc_realtime_bpm_speed(tempo,speed,rows_per_beat: Byte): Real;
begin
{$IFDEF GO32V2}
calc_realtime_bpm_speed := tempo*60/speed/rows_per_beat*(1+((IRQ_freq_shift+playback_speed_shift)/IRQ_freq)-0.02);
{$ELSE}
calc_realtime_bpm_speed := tempo*60/speed/rows_per_beat*(1+((IRQ_freq_shift+playback_speed_shift)/IRQ_freq)-sdl_timer_slowdown/100);
{$ENDIF}
end;
procedure init_old_songdata;
var
temp: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:init_old_songdata';
{$ENDIF}
FillChar(old_songdata,SizeOf(old_songdata),0);
FillChar(old_songdata.pattern_order,SizeOf(old_songdata.pattern_order),$080);
FillChar(old_songdata.instr_data,SizeOf(old_songdata.instr_data),0);
For temp := 1 to 250 do
old_songdata.instr_names[temp] :=
' iNS_'+byte2hex(temp)+#247' ';
end;
procedure init_songdata;
var
temp: Byte;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:init_songdata';
{$ENDIF}
If (play_status <> isStopped) then
begin
fade_out_playback(FALSE);
stop_playing;
end
else init_buffers;
FillChar(songdata,SizeOf(songdata),0);
FillChar(songdata.pattern_order,SizeOf(songdata.pattern_order),$080);
For temp := 1 to max_patterns DIV 8 do
FillChar(pattdata^[PRED(temp)],8*PATTERN_SIZE,0);
songdata.tempo := tempo;
songdata.speed := speed;
songdata.macro_speedup := init_macro_speedup;
speed_update := FALSE;
IRQ_freq_shift := 0;
playback_speed_shift := 0;
songdata.patt_len := patt_len;
songdata.nm_tracks := nm_tracks;
songdata.bpm_data.rows_per_beat := mark_line;
songdata.bpm_data.tempo_finetune := IRQ_freq_shift;
lockvol := FALSE;
panlock := FALSE;
lockVP := FALSE;
tremolo_depth := 0;
vibrato_depth := 0;
volume_scaling := FALSE;
old_chan_pos := 1;
old_hpos := 1;
old_page := 0;
old_block_chan_pos := 1;
old_block_patt_hpos := 1;
old_block_patt_page := 0;
marking := FALSE;
If (nm_tracks <= 18) then
begin
percussion_mode := FALSE;
_chan_n := _chmm_n;
_chan_m := _chmm_m;
_chan_c := _chmm_c;
end
else
begin
percussion_mode := TRUE;
_chan_n := _chpm_n;
_chan_m := _chpm_m;
_chan_c := _chpm_c;
end;
For temp := 1 to 255 do
songdata.instr_names[temp] := ' iNS_'+byte2hex(temp)+#247' ';
For temp := 0 to $7f do
songdata.pattern_names[temp] := ' PAT_'+byte2hex(temp)+' '#247' ';
songdata_crc_ord := Update32(songdata.pattern_order,
SizeOf(songdata.pattern_order),0);
module_archived := TRUE;
end;
procedure update_instr_data(ins: Byte);
var
temp: Byte;
begin
For temp := 1 to 20 do
If (voice_table[temp] = ins) then
begin
reset_chan[temp] := TRUE;
set_ins_data(ins,temp);
change_frequency(temp,nFreq(PRED(event_table[temp].note AND $7f))+
SHORTINT(ins_parameter(ins,12)));
end;
end;
procedure load_instrument(var data; chan: Byte);
begin
fmpar_table[chan].connect := pBYTE(@data)[10] AND 1;
fmpar_table[chan].feedb := pBYTE(@data)[10] SHR 1 AND 7;
fmpar_table[chan].multipM := pBYTE(@data)[0] AND $0f;
fmpar_table[chan].kslM := pBYTE(@data)[2] SHR 6;
fmpar_table[chan].tremM := pBYTE(@data)[0] SHR 7;
fmpar_table[chan].vibrM := pBYTE(@data)[0] SHR 6 AND 1;
fmpar_table[chan].ksrM := pBYTE(@data)[0] SHR 4 AND 1;
fmpar_table[chan].sustM := pBYTE(@data)[0] SHR 5 AND 1;
fmpar_table[chan].multipC := pBYTE(@data)[1] AND $0f;
fmpar_table[chan].kslC := pBYTE(@data)[3] SHR 6;
fmpar_table[chan].tremC := pBYTE(@data)[1] SHR 7;
fmpar_table[chan].vibrC := pBYTE(@data)[1] SHR 6 AND 1;
fmpar_table[chan].ksrC := pBYTE(@data)[1] SHR 4 AND 1;
fmpar_table[chan].sustC := pBYTE(@data)[1] SHR 5 AND 1;
fmpar_table[chan].adsrw_car.attck := pBYTE(@data)[5] SHR 4;
fmpar_table[chan].adsrw_mod.attck := pBYTE(@data)[4] SHR 4;
fmpar_table[chan].adsrw_car.dec := pBYTE(@data)[5] AND $0f;
fmpar_table[chan].adsrw_mod.dec := pBYTE(@data)[4] AND $0f;
fmpar_table[chan].adsrw_car.sustn := pBYTE(@data)[7] SHR 4;
fmpar_table[chan].adsrw_mod.sustn := pBYTE(@data)[6] SHR 4;
fmpar_table[chan].adsrw_car.rel := pBYTE(@data)[7] AND $0f;
fmpar_table[chan].adsrw_mod.rel := pBYTE(@data)[6] AND $0f;
fmpar_table[chan].adsrw_car.wform := pBYTE(@data)[9] AND $07;
fmpar_table[chan].adsrw_mod.wform := pBYTE(@data)[8] AND $07;
panning_table[chan] := pBYTE(@data)[11] AND 3;
volume_table[chan] := concw(pBYTE(@data)[2] AND $3f,
pBYTE(@data)[3] AND $3f);
update_modulator_adsrw(chan);
update_carrier_adsrw(chan);
update_fmpar(chan);
end;
function is_4op_chan(chan: Byte): Boolean;
var
result: Boolean;
begin
asm
mov al,byte ptr [songdata.flag_4op]
mov ah,chan
test al,1
jz @@1
cmp ah,1
jb @@1
cmp ah,2
ja @@1
mov result,TRUE
jmp @@7
@@1: test al,2
jz @@2
cmp ah,3
jb @@2
cmp ah,4
ja @@2
mov result,TRUE
jmp @@7
@@2: test al,4
jz @@3
cmp ah,5
jb @@3
cmp ah,6
ja @@3
mov result,TRUE
jmp @@7
@@3: test al,8
jz @@4
cmp ah,10
jb @@4
cmp ah,11
ja @@4
mov result,TRUE
jmp @@7
@@4: test al,10h
jz @@5
cmp ah,12
jb @@5
cmp ah,13
ja @@5
mov result,TRUE
jmp @@7
@@5: test al,20h
jz @@6
cmp ah,14
jb @@6
cmp ah,15
ja @@6
mov result,TRUE
jmp @@7
@@6: mov result,FALSE
@@7:
end;
is_4op_chan := result;
end;
function is_in_block(x0,y0,x1,y1: Byte): Boolean;
begin
block_x1 := x1;
block_x0 := block_xstart;
If (block_x0 > block_x1) then
begin
block_x1 := block_x0;
block_x0 := x1;
end;
block_y1 := y1;
block_y0 := block_ystart;
If (block_y0 > block_y1) then
begin
block_y1 := block_y0;
block_y0 := y1;
end;
is_in_block := (x0 >= block_x0) and (x0 <= block_x1) and
(y0 >= block_y0) and (y0 <= block_y1);
end;
procedure fade_out_playback(fade_screen: Boolean);
var
{$IFDEF GO32V2}
idx,idx2: Byte;
fade_buf: tFADE_BUF;
{$ELSE}
temp: Byte;
temp2,temp3: Byte;
factor: Byte;
{$ENDIF}
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:fade_out_playback';
If fade_screen then
begin
draw_screen;
fade_buf.action := first;
fade_speed := 32;
GetPalette(fade_buf.pal0,0,255);
For idx := fade_speed downto 0 do
begin
For idx2 := 0 to 255 do
begin
fade_buf.pal1[idx2].r := fade_buf.pal0[idx2].r * idx DIV fade_speed;
fade_buf.pal1[idx2].g := fade_buf.pal0[idx2].g * idx DIV fade_speed;
fade_buf.pal1[idx2].b := fade_buf.pal0[idx2].b * idx DIV fade_speed;
end;
SetPalette(fade_buf.pal1,0,255);
If (play_status <> isStopped) then
begin
fade_out_volume := idx*2;
set_global_volume;
CRT.Delay(fade_out_volume DIV 32);
end
else CRT.Delay(1);
realtime_gfx_poll_proc;
draw_screen;
keyboard_reset_buffer;
end;
fade_buf.action := fadeIn;
end
else If (play_status <> isStopped) then
For idx := 63 downto 0 do
begin
fade_out_volume := idx;
set_global_volume;
CRT.Delay(fade_out_volume DIV 32);
realtime_gfx_poll_proc;
keyboard_reset_buffer;
end;
{$ELSE}
If fade_screen then factor := 255
else factor := 63;
If (global_volume > 0) then temp2 := factor DIV global_volume
else temp2 := 0;
temp3 := 0;
fade_out_volume := 63;
If (play_status <> isStopped) then
For temp := 1 to factor do
begin
Inc(temp3);
If (temp3 > temp2) then
begin
temp3 := 0;
Dec(fade_out_volume);
set_global_volume;
If fade_screen or (temp MOD 5 = 0) then
begin
_draw_screen_without_delay := TRUE;
draw_screen;
keyboard_reset_buffer;
end;
end;
If fade_screen then
begin
vid_FadeOut;
SDL_Delay(1);
end;
end
else
For fade_out_volume := 1 to 255 do
If fade_screen then
begin
vid_FadeOut;
SDL_Delay(1);
end;
{$ENDIF}
end;
procedure realtime_gfx_poll_proc;
begin
If _realtime_gfx_no_update then EXIT;
{$IFDEF GO32V2}
If NOT reset_gfx_ticks and
(gfx_ticks > ((IRQ_freq+IRQ_freq_shift+playback_speed_shift) DIV 100)*SUCC(fps_down_factor)) then
begin
Inc(blink_ticks);
If (blink_ticks = 40) then
begin
blink_flag := NOT blink_flag;
blink_ticks := 0;
end;
Inc(_NRECM_blink_ticks);
If (_NRECM_blink_ticks = 40) then
begin
_NRECM_blink_flag := NOT _NRECM_blink_flag;
_NRECM_blink_ticks := 0;
end;
Inc(_IRQFREQ_blink_ticks);
If (_IRQFREQ_blink_ticks = 20) then
begin
_IRQFREQ_blink_flag := NOT _IRQFREQ_blink_flag;
_IRQFREQ_blink_ticks := 0;
end;
{$ENDIF}
If blink_flag then
begin
If debugging and (play_status = isStopped) then status_layout[isStopped][9] := #9
else status_layout[isStopped][9] := ' ';
If NOT debugging then status_layout[isPlaying][9] := #16
else status_layout[isPlaying][9] := #9;
status_layout[isPaused][8] := #8;
If (@macro_preview_indic_proc <> NIL) then
macro_preview_indic_proc(1);
end
else
begin
status_layout[isPlaying][9] := ' ';
status_layout[isPaused] [8] := ' ';
status_layout[isStopped][9] := ' ';
If (@macro_preview_indic_proc <> NIL) then
macro_preview_indic_proc(2);
end;
If (Addr(_show_bpm_realtime_proc) <> NIL) then
_show_bpm_realtime_proc;
decay_bars_refresh;
{$IFNDEF GO32V2}
If opl3_channel_recording_mode then update_recorded_channels;
{$ENDIF}
If do_synchronize then synchronize_screen;
{$IFNDEF GO32V2}
If (_name_scrl_pending_frames > 0) then Dec(_name_scrl_pending_frames);
Inc(_cursor_blink_pending_frames);
{$ENDIF}
status_refresh;
STATUS_LINE_refresh;
{$IFDEF GO32V2}
reset_gfx_ticks := TRUE;
{$ENDIF}
trace_update_proc;
If (@mn_environment.ext_proc_rt <> NIL) then
mn_environment.ext_proc_rt;
{$IFDEF GO32V2}
end;
{$ENDIF}
end;
function get_bank_position(bank_name: String; bank_size: Longint): Longint;
var
idx: Longint;
result: Longint;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:get_bank_position';
{$ENDIF}
result := 0;
bank_name := CutStr(Upper_filename(bank_name));
For idx := 1 to bank_position_list_size do
If (bank_position_list[idx].bank_name = bank_name) and
((bank_position_list[idx].bank_size = bank_size) or
(bank_size = -1)) then
begin
result := bank_position_list[idx].bank_position;
BREAK;
end;
get_bank_position := result;
end;
procedure add_bank_position(bank_name: String; bank_size: Longint; bank_position: Longint);
var
idx,idx2: Longint;
found_flag: Boolean;
begin
{$IFDEF GO32V2}
_last_debug_str_ := _debug_str_;
_debug_str_ := 'ADT2UNIT.PAS:add_bank_position';
{$ENDIF}
found_flag := FALSE;
bank_name := CutStr(Upper_filename(bank_name));
For idx := 1 to bank_position_list_size do
If (bank_position_list[idx].bank_name = bank_name) and
((bank_position_list[idx].bank_size = bank_size) or
(bank_size = -1)) then
begin
found_flag := TRUE;
idx2 := idx;
BREAK;
end;
If found_flag then
begin
bank_position_list[idx2].bank_position := bank_position;
EXIT;
end;
If (bank_position_list_size < MAX_NUM_BANK_POSITIONS) then
Inc(bank_position_list_size)
else
begin
bank_position_list_size := MAX_NUM_BANK_POSITIONS;
For idx := 1 to PRED(bank_position_list_size) do
bank_position_list[idx] := bank_position_list[idx+1];
end;
bank_position_list[bank_position_list_size].bank_name := bank_name;
bank_position_list[bank_position_list_size].bank_size := bank_size;
bank_position_list[bank_position_list_size].bank_position := bank_position;
end;
{$IFDEF GO32V2}
var
old_exit_proc: procedure;
procedure new_exit_proc;
begin
Unlock_Data(___UNIT_DATA_START___,DWORD(Addr(___UNIT_DATA_END___))-DWORD(Addr(___UNIT_DATA_START___)));
Unlock_Data(___IRQ_DATA_START___,DWORD(Addr(___IRQ_DATA_END___))-DWORD(Addr(___IRQ_DATA_START___)));
Unlock_Code(@___IRQ_CODE_START___,DWORD(@___IRQ_CODE_END___)-DWORD(@___IRQ_CODE_START___));
ExitProc := @old_exit_proc;
end;
begin
Lock_Data(___UNIT_DATA_START___,DWORD(Addr(___UNIT_DATA_END___))-DWORD(Addr(___UNIT_DATA_START___)));
Lock_Data(___IRQ_DATA_START___,DWORD(Addr(___IRQ_DATA_END___))-DWORD(Addr(___IRQ_DATA_START___)));
Lock_Code(@___IRQ_CODE_START___,DWORD(@___IRQ_CODE_END___)-DWORD(@___IRQ_CODE_START___));
@old_exit_proc := ExitProc;
ExitProc := @new_exit_proc;
{$ENDIF}
end.
adlibtracker2-2.4.24/adt2vesa.pas 0000644 0000000 0000000 00000027211 13411003760 015226 0 ustar root root // This file is part of Adlib Tracker II (AT2).
//
// AT2 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AT2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AT2. If not, see .
unit Adt2VESA;
{$S-,Q-,R-,V-,B-,X+}
{$PACKRECORDS 1}
interface
const
VESA_640x480 = $101;
VESA_800x600 = $103;
VESA_1024x768 = $105;
const
VESA_GraphicsSysInited: Boolean = FALSE;
type
tModeInfo = Record
ModeNumber: Word;
XResolution: Word;
YResolution: Word;
BufferAddress: Pointer;
end;
var
VESA_NumberOfModes: Byte; (* Total LFB videomodes supported *)
VESA_FrameBuffer: Pointer; (* LFB address for current mode *)
VESA_ModeList: array[0..255] of tModeInfo;
VESA_Version: Word; (* VESA version *)
VESA_OEM_String: String; (* VESA OEM string *)
VESA_Capabilities: Dword; (* Hardware capabilities *)
VESA_VideoMemory: Word; (* Videomemory amount in Kb *)
VESA_OEM_SoftwareRevision: Word; (* VESA implementation revision *)
VESA_OEM_VendorName: String; (* VESA vendor name *)
VESA_OEM_ProductName: String; (* VESA OEM product name *)
VESA_OEM_ProductRevision: String; (* VESA OEM product revision *)
VESA_Mode: Word; (* Current videomode *)
VESA_ModeIndex: Byte; (* Current mode index in VESA_ModeList *)
VESA_XResolution, (* Current X resolution *)
VESA_YResolution: Word; (* Current Y resolution *)
type
tPaletteArray = array[0..767] of Byte;
var
VESA_SegLFB: Word;
StepWorkPalette: tPaletteArray;
StepRealPal,StepDelta: array[0..767] of Single;
FadeSteps: Word;
procedure VESA_Init;
function VESA_SetMode(Mode: Word): Integer;
procedure VESA_GetPalette(var Palette);
procedure VESA_SetPalette(var Palette);
procedure VESA_InitStepFade(var StartPalette,EndPalette; Speed: Single);
procedure VESA_StepFade;
procedure VESA_SwitchBank(Bank: Byte);
implementation
uses
GO32;
type
tModeInfoBlock = Record
ModeAttributes: Word;
WinAAttributes: Byte;
WinBAttributes: Byte;
WinGranularity: Word;
WinSize: Word;
WinASegment: Word;
WinBSegment: Word;
WinFuncPtr: Pointer;
BytesPerScanLine: Word;
// VESA 1.2+ specific
XResolution: Word;
YResolution: Word;
XCharSize: Byte;
YCharSize: Byte;
NumberOfPlanes: Byte;
BitsPerPixel: Byte;
NumberOfBanks: Byte;
MemoryModel: Byte;
BankSize: Byte;
NumberOfImagePages: Byte;
Reserved1: Byte;
// direct color data
RedMaskSize: Byte;
RedFieldPosition: Byte;
GreenMaskSize: Byte;
GreenFieldPosition: Byte;
BlueMaskSize: Byte;
BlueFieldPosition: Byte;
RsvdMaskSize: Byte;
RsvdFieldPosition: Byte;
DirectColorModeInfo: Byte;
// VESA 2.0+ specific
PhysBasePtr: Pointer;
OffScreenMemOffset: Dword;
OffScreenMemSize: Word;
Reserved2: array[0..205] of Byte;
end;
type
tModeList = array[0..127] of Word;
tVESA_Info = Record
Signature: array[0..3] of Char;
Version: Word;
OEM_StringPtr: Dword;
Capabilities: Dword;
ModeListPtr: Dword;
VideoMemory: Word;
OEM_SoftwareRevision: Word;
OEM_VendorNamePtr: Dword;
OEM_ProductNamePtr: Dword;
OEM_ProductRevisionPtr: Dword;
Reserved: array[0..221] of Byte;
OEM_Data: array[0..255] of Byte;
end;
var
ModeList: tModeList;
VESA_Info: tVESA_Info;
ModeInfoBlock: tModeInfoBlock;
procedure VESA_Init;
var
idx,idx2: Byte;
regs: tRealRegs;
dos_sel,dos_seg: Word;
dos_mem_adr: Dword;
function GetVESAInfoStr(dpmiStrPtr: Dword): String;
begin
GetVESAInfoStr := StrPas(PCHAR(POINTER(Ofs(VESA_Info)+WORD(dpmiStrPtr))));
end;
begin
If VESA_GraphicsSysInited then EXIT;
With VESA_ModeList[0] do
begin
ModeNumber := $13;
XResolution := 320;
YResolution := 200;
BufferAddress := POINTER($A0000);
end;
dos_mem_adr := global_dos_alloc(SizeOf(tVESA_Info));
dos_sel := WORD(dos_mem_adr);
dos_seg := WORD(dos_mem_adr SHR 16);
FillChar(VESA_Info,SizeOf(tVESA_Info),0);
VESA_Info.Signature := 'VBE2';
dosmemput(dos_seg,0,VESA_Info,4);
regs.ax := $4f00;
regs.ds := dos_seg;
regs.es := dos_seg;
regs.di := 0;
RealIntr($10,regs);
dosmemget(dos_seg,0,VESA_Info,SizeOf(tVESA_Info));
global_dos_free(dos_sel);
If (VESA_Info.Signature <> 'VESA') then
EXIT; // ERROR: VESA BIOS extensions not found!
VESA_Version := VESA_Info.Version;
If (HI(VESA_Version) < 2) then
EXIT; // ERROR: VESA 2.0 required!
VESA_OEM_String := GetVESAInfoStr(VESA_Info.OEM_StringPtr);
VESA_Capabilities := VESA_Info.Capabilities;
VESA_VideoMemory := VESA_Info.VideoMemory SHL 6;
VESA_OEM_SoftwareRevision := VESA_Info.OEM_SoftwareRevision;
VESA_OEM_VendorName := GetVESAInfoStr(VESA_Info.OEM_VendorNamePtr);
VESA_OEM_ProductName := GetVESAInfoStr(VESA_Info.OEM_ProductNamePtr);
VESA_OEM_ProductRevision := GetVESAInfoStr(VESA_Info.OEM_ProductRevisionPtr);
dpmi_dosmemget(WORD(VESA_Info.ModeListPtr SHR 16),
WORD(VESA_Info.ModeListPtr),
ModeList,
SizeOf(tModeList));
dos_mem_adr := global_dos_alloc(SizeOf(tModeInfoBlock));
dos_sel := WORD(dos_mem_adr);
dos_seg := WORD(dos_mem_adr SHR 16);
idx := 0;
idx2 := 1;
Repeat
regs.ax := $4f01;
regs.cx := ModeList[idx];
regs.ds := dos_seg;
regs.es := dos_seg;
regs.di := 0;
RealIntr($10,regs);
dosmemget(dos_seg,0,ModeInfoBlock,SizeOf(tModeInfoBlock));
Inc(idx);
until ((ModeInfoBlock.ModeAttributes AND $0091 = $0091) and
(ModeInfoBlock.NumberOfPlanes = 1) and
(ModeInfoBlock.BitsPerPixel = 8)) or (ModeList[idx-1] = $FFFF);
If (ModeList[idx-1] <> $FFFF) then
begin
Inc(idx2);
With VESA_ModeList[1] do
begin
ModeNumber := ModeList[idx-1];
XResolution := ModeInfoBlock.XResolution;
YResolution := ModeInfoBlock.YResolution;
BufferAddress := ModeInfoBlock.PhysBasePtr;
end;
While (idx <= 127) and (ModeList[idx] <> $FFFF) do
begin
regs.ax := $4f01;
regs.cx := ModeList[idx];
regs.ds := dos_seg;
regs.es := dos_seg;
regs.di := 0;
RealIntr($10,regs);
dosmemget(dos_seg,0,ModeInfoBlock,SizeOf(tModeInfoBlock));
If (ModeInfoBlock.ModeAttributes AND $0091 = $0091) and
(ModeInfoBlock.NumberOfPlanes = 1) and
(ModeInfoBlock.BitsPerPixel = 8) then
begin
With VESA_ModeList[idx2] do
begin
ModeNumber := ModeList[idx];
XResolution := ModeInfoBlock.XResolution;
YResolution := ModeInfoBlock.YResolution;
end;
Inc(idx2);
end;
Inc(idx);
end;
end;
global_dos_free(dos_sel);
VESA_NumberOfModes := idx2-1;
If (VESA_NumberOfModes >= 1) then
begin
VESA_ModeList[1].BufferAddress :=
POINTER(DWORD(Get_Linear_Addr(DWORD(VESA_ModeList[1].BufferAddress),4096*1024)));
If (VESA_ModeList[1].BufferAddress = NIL) then
EXIT; // ERROR: Cannot remap LFB to linear address space!
For idx := 2 to VESA_NumberOfModes do
VESA_ModeList[idx].BufferAddress := VESA_ModeList[1].BufferAddress;
end;
VESA_Mode := 0;
VESA_GraphicsSysInited := TRUE;
end;
function VESA_SetMode(Mode: Word): Integer;
var
idx: Byte;
result: Integer;
begin
If NOT VESA_GraphicsSysInited then
begin
VESA_SetMode := -1;
EXIT;
end;
VESA_ModeIndex := VESA_NumberOfModes+1;
For idx := 0 to VESA_NumberOfModes do
If (VESA_ModeList[idx].ModeNumber = Mode) then
begin
Write(VESA_ModeList[idx].ModeNumber,',');
VESA_ModeIndex := idx;
BREAK;
end;
If (VESA_ModeIndex = VESA_NumberOfModes+1) then
begin
VESA_SetMode := -1;
EXIT;
end;
If (Mode <> 19) then Mode := Mode OR $4000;
asm
mov ax,4f02h
mov bx,Mode
int 10h
mov result,0
cmp ax,4fh
je @@1
mov result,-1
@@1:
end;
VESA_SetMode := result;
If (result <> 0) then EXIT;
VESA_Mode := Mode;
VESA_XResolution := VESA_ModeList[VESA_ModeIndex].XResolution;
VESA_YResolution := VESA_ModeList[VESA_ModeIndex].YResolution;
VESA_Framebuffer := VESA_ModeList[VESA_ModeIndex].BufferAddress;
end;
procedure VESA_GetPalette(var Palette); assembler;
asm
mov dx,3c7h
xor al,al
out dx,al
mov edi,Palette
inc dx
inc dx
mov ecx,768
rep insb
end;
procedure VESA_SetPalette(var Palette); assembler;
asm
mov dx,3dah
@@1: in al,dx
test al,8
jz @@1
mov dx,3c8h
xor al,al
out dx,al
mov esi,Palette
inc dx
mov ecx,768
rep outsb
end;
procedure VESA_InitStepFade(var StartPalette,EndPalette; Speed: Single);
var
EndRealPal: array[0..767] of Single;
idx: Word;
begin
For idx := 0 to 767 do
begin
StepRealPal[idx] := tPaletteArray(StartPalette)[idx];
StepWorkPalette[idx] := tPaletteArray(StartPalette)[idx];
EndRealPal[idx] := tPaletteArray(EndPalette)[idx];
StepDelta[idx] := (EndRealPal[idx]-StepRealPal[idx])/Speed;
end;
VESA_SetPalette(StartPalette);
FadeSteps := TRUNC(Speed);
end;
procedure VESA_StepFade;
var
idx: Word;
begin
For idx := 0 to 767 do
begin
StepRealPal[idx] := StepRealPal[idx]+StepDelta[idx];
StepWorkPalette[idx] := ROUND(StepRealPal[idx]);
end;
VESA_SetPalette(StepWorkPalette);
end;
procedure VESA_SwitchBank(Bank: Byte);
var
regs: tRealRegs;
granularity: Byte;
begin
regs.ax := $4f05;
regs.bx := 0;
Case ModeInfoBlock.WinGranularity of
32: granularity := 5;
16: granularity := 4;
8: granularity := 3;
4: granularity := 2;
2: granularity := 1;
1: granularity := 0;
end;
regs.dx := bank SHL granularity;
RealIntr($10,regs);
end;
end.
adlibtracker2-2.4.24/progicon.ico 0000644 0000000 0000000 00000014656 13411003760 015335 0 ustar root root è F 0 . ¨ ^ ¨
( @ € € € €€ € € € €€ €€€ ÀÀÀ ÿ ÿ ÿÿ ÿ ÿ ÿ ÿÿ ÿÿÿ ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ÌDC DDDDDDDDDD³DDK0DDDDDDDDD³DDK³ DDDDDDDDD³DDD»0DDDDDDDD³DDDK³ DDDDDDDD³DDDD»0DDDDDDD³DDDDK³ DDD@ ³DDDDD»0DDC333³DDDDDK³ DDK»»»³DDDDDD»0DDDDD³DDDDDDK³ DDDDD³DDDDDDD»0 DDDD³D ³ ³ »0 ³ ³ ³ »0 ³ ³ ³ ³ ³ ³ ³ ³ ( @ Î Ø ((( ÿÿÿ 0 0 0 0 0 0 0 0 0 0 0 0 0 0€ 0 Àð `ð 0 0 0 0 0 0 €0 À0 0 0 0 0 0 0 0 ( @ € T€ Œ8( ¨˜€ 0¨À °p @ „ÔÌ D L